summaryrefslogtreecommitdiff
path: root/src/backend/tsearch/to_tsany.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tsearch/to_tsany.c')
-rw-r--r--src/backend/tsearch/to_tsany.c166
1 files changed, 154 insertions, 12 deletions
diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
index 80d80f2451..18368d118e 100644
--- a/src/backend/tsearch/to_tsany.c
+++ b/src/backend/tsearch/to_tsany.c
@@ -3,7 +3,7 @@
* to_tsany.c
* to_ts* function definitions
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
@@ -16,6 +16,7 @@
#include "tsearch/ts_cache.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
+#include "utils/jsonapi.h"
typedef struct MorphOpaque
@@ -24,6 +25,14 @@ typedef struct MorphOpaque
int qoperator; /* query operator */
} MorphOpaque;
+typedef struct TSVectorBuildState
+{
+ ParsedText *prs;
+ TSVector result;
+ Oid cfgId;
+} TSVectorBuildState;
+
+static void add_to_tsvector(void *state, char *elem_value, int elem_len);
Datum
get_current_ts_config(PG_FUNCTION_ARGS)
@@ -216,19 +225,19 @@ Datum
to_tsvector_byid(PG_FUNCTION_ARGS)
{
Oid cfgId = PG_GETARG_OID(0);
- text *in = PG_GETARG_TEXT_P(1);
+ text *in = PG_GETARG_TEXT_PP(1);
ParsedText prs;
TSVector out;
- prs.lenwords = (VARSIZE(in) - VARHDRSZ) / 6; /* just estimation of
- * word's number */
+ prs.lenwords = VARSIZE_ANY_EXHDR(in) / 6; /* just estimation of word's
+ * number */
if (prs.lenwords == 0)
prs.lenwords = 2;
prs.curwords = 0;
prs.pos = 0;
prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);
- parsetext(cfgId, &prs, VARDATA(in), VARSIZE(in) - VARHDRSZ);
+ parsetext(cfgId, &prs, VARDATA_ANY(in), VARSIZE_ANY_EXHDR(in));
PG_FREE_IF_COPY(in, 1);
if (prs.curwords)
@@ -247,7 +256,7 @@ to_tsvector_byid(PG_FUNCTION_ARGS)
Datum
to_tsvector(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(0);
+ text *in = PG_GETARG_TEXT_PP(0);
Oid cfgId;
cfgId = getTSCurrentConfig(true);
@@ -256,6 +265,139 @@ to_tsvector(PG_FUNCTION_ARGS)
PointerGetDatum(in)));
}
+Datum
+jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
+{
+ Oid cfgId = PG_GETARG_OID(0);
+ Jsonb *jb = PG_GETARG_JSONB(1);
+ TSVectorBuildState state;
+ ParsedText *prs = (ParsedText *) palloc(sizeof(ParsedText));
+
+ prs->words = NULL;
+ state.result = NULL;
+ state.cfgId = cfgId;
+ state.prs = prs;
+
+ iterate_jsonb_string_values(jb, &state, (JsonIterateStringValuesAction) add_to_tsvector);
+
+ PG_FREE_IF_COPY(jb, 1);
+
+ if (state.result == NULL)
+ {
+ /*
+ * There weren't any string elements in jsonb, so wee need to return
+ * an empty vector
+ */
+
+ if (prs->words != NULL)
+ pfree(prs->words);
+
+ state.result = palloc(CALCDATASIZE(0, 0));
+ SET_VARSIZE(state.result, CALCDATASIZE(0, 0));
+ state.result->size = 0;
+ }
+
+ PG_RETURN_TSVECTOR(state.result);
+}
+
+Datum
+jsonb_to_tsvector(PG_FUNCTION_ARGS)
+{
+ Jsonb *jb = PG_GETARG_JSONB(0);
+ Oid cfgId;
+
+ cfgId = getTSCurrentConfig(true);
+ PG_RETURN_DATUM(DirectFunctionCall2(jsonb_to_tsvector_byid,
+ ObjectIdGetDatum(cfgId),
+ JsonbGetDatum(jb)));
+}
+
+Datum
+json_to_tsvector_byid(PG_FUNCTION_ARGS)
+{
+ Oid cfgId = PG_GETARG_OID(0);
+ text *json = PG_GETARG_TEXT_P(1);
+ TSVectorBuildState state;
+ ParsedText *prs = (ParsedText *) palloc(sizeof(ParsedText));
+
+ prs->words = NULL;
+ state.result = NULL;
+ state.cfgId = cfgId;
+ state.prs = prs;
+
+ iterate_json_string_values(json, &state, (JsonIterateStringValuesAction) add_to_tsvector);
+
+ PG_FREE_IF_COPY(json, 1);
+ if (state.result == NULL)
+ {
+ /*
+ * There weren't any string elements in json, so wee need to return an
+ * empty vector
+ */
+
+ if (prs->words != NULL)
+ pfree(prs->words);
+
+ state.result = palloc(CALCDATASIZE(0, 0));
+ SET_VARSIZE(state.result, CALCDATASIZE(0, 0));
+ state.result->size = 0;
+ }
+
+ PG_RETURN_TSVECTOR(state.result);
+}
+
+Datum
+json_to_tsvector(PG_FUNCTION_ARGS)
+{
+ text *json = PG_GETARG_TEXT_P(0);
+ Oid cfgId;
+
+ cfgId = getTSCurrentConfig(true);
+ PG_RETURN_DATUM(DirectFunctionCall2(json_to_tsvector_byid,
+ ObjectIdGetDatum(cfgId),
+ PointerGetDatum(json)));
+}
+
+/*
+ * Extend current TSVector from _state with a new one,
+ * build over a json(b) element.
+ */
+static void
+add_to_tsvector(void *_state, char *elem_value, int elem_len)
+{
+ TSVectorBuildState *state = (TSVectorBuildState *) _state;
+ ParsedText *prs = state->prs;
+ TSVector item_vector;
+ int i;
+
+ prs->lenwords = elem_len / 6;
+ if (prs->lenwords == 0)
+ prs->lenwords = 2;
+
+ prs->words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs->lenwords);
+ prs->curwords = 0;
+ prs->pos = 0;
+
+ parsetext(state->cfgId, prs, elem_value, elem_len);
+
+ if (prs->curwords)
+ {
+ if (state->result != NULL)
+ {
+ for (i = 0; i < prs->curwords; i++)
+ prs->words[i].pos.pos = prs->words[i].pos.pos + TS_JUMP;
+
+ item_vector = make_tsvector(prs);
+
+ state->result = (TSVector) DirectFunctionCall2(tsvector_concat,
+ TSVectorGetDatum(state->result),
+ PointerGetDatum(item_vector));
+ }
+ else
+ state->result = make_tsvector(prs);
+ }
+}
+
/*
* to_tsquery
*/
@@ -362,7 +504,7 @@ pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval,
Datum
to_tsquery_byid(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(1);
+ text *in = PG_GETARG_TEXT_PP(1);
TSQuery query;
MorphOpaque data;
@@ -380,7 +522,7 @@ to_tsquery_byid(PG_FUNCTION_ARGS)
Datum
to_tsquery(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(0);
+ text *in = PG_GETARG_TEXT_PP(0);
Oid cfgId;
cfgId = getTSCurrentConfig(true);
@@ -392,7 +534,7 @@ to_tsquery(PG_FUNCTION_ARGS)
Datum
plainto_tsquery_byid(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(1);
+ text *in = PG_GETARG_TEXT_PP(1);
TSQuery query;
MorphOpaque data;
@@ -410,7 +552,7 @@ plainto_tsquery_byid(PG_FUNCTION_ARGS)
Datum
plainto_tsquery(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(0);
+ text *in = PG_GETARG_TEXT_PP(0);
Oid cfgId;
cfgId = getTSCurrentConfig(true);
@@ -423,7 +565,7 @@ plainto_tsquery(PG_FUNCTION_ARGS)
Datum
phraseto_tsquery_byid(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(1);
+ text *in = PG_GETARG_TEXT_PP(1);
TSQuery query;
MorphOpaque data;
@@ -441,7 +583,7 @@ phraseto_tsquery_byid(PG_FUNCTION_ARGS)
Datum
phraseto_tsquery(PG_FUNCTION_ARGS)
{
- text *in = PG_GETARG_TEXT_P(0);
+ text *in = PG_GETARG_TEXT_PP(0);
Oid cfgId;
cfgId = getTSCurrentConfig(true);