mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Add json(b)_to_tsvector function
Jsonb has a complex nature so there isn't best-for-everything way to convert it to tsvector for full text search. Current to_tsvector(json(b)) suggests to convert only string values, but it's possible to index keys, numerics and even booleans value. To solve that json(b)_to_tsvector has a second required argument contained a list of desired types of json fields. Second argument is a jsonb scalar or array right now with possibility to add new options in a future. Bump catalog version Author: Dmitry Dolgov with some editorization by me Reviewed by: Teodor Sigaev Discussion: https://www.postgresql.org/message-id/CA+q6zcXJQbS1b4kJ_HeAOoOc=unfnOrUEL=KGgE32QKDww7d8g@mail.gmail.com
This commit is contained in:
		
							parent
							
								
									529ab7bd1f
								
							
						
					
					
						commit
						1c1791e000
					
				@ -9727,6 +9727,26 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 | 
				
			|||||||
        <entry><literal>to_tsvector('english', '{"a": "The Fat Rats"}'::json)</literal></entry>
 | 
					        <entry><literal>to_tsvector('english', '{"a": "The Fat Rats"}'::json)</literal></entry>
 | 
				
			||||||
        <entry><literal>'fat':2 'rat':3</literal></entry>
 | 
					        <entry><literal>'fat':2 'rat':3</literal></entry>
 | 
				
			||||||
       </row>
 | 
					       </row>
 | 
				
			||||||
 | 
					       <row>
 | 
				
			||||||
 | 
					        <entry>
 | 
				
			||||||
 | 
					         <literal><function>json(b)_to_tsvector(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>,
 | 
				
			||||||
 | 
					         </optional> <replaceable class="parameter">document</replaceable> <type>json(b)</type>,
 | 
				
			||||||
 | 
					         <replaceable class="parameter">filter</replaceable> <type>json(b)</type>)</function></literal>
 | 
				
			||||||
 | 
					        </entry>
 | 
				
			||||||
 | 
					        <entry><type>tsvector</type></entry>
 | 
				
			||||||
 | 
					        <entry>
 | 
				
			||||||
 | 
					          reduce each value in the document, specified by <replaceable class="parameter">filter</replaceable> to a <type>tsvector</type>,
 | 
				
			||||||
 | 
					          and then concatenate those in document order to produce a single <type>tsvector</type>.
 | 
				
			||||||
 | 
					          <replaceable class="parameter">filter</replaceable> is a jsonb array, that enumerates what kind of elements need to be included
 | 
				
			||||||
 | 
					          into the resulting <type>tsvector</type>. Possible values for <replaceable class="parameter">filter</replaceable> are
 | 
				
			||||||
 | 
					          <literal>"string"</literal> (to include all string values), <literal>"numeric"</literal> (to include all numeric values in the string format),
 | 
				
			||||||
 | 
					          <literal>"boolean"</literal> (to include all boolean values in the string format "true"/"false"),
 | 
				
			||||||
 | 
					          <literal>"key"</literal> (to include all keys) or <literal>"all"</literal> (to include all above). These values
 | 
				
			||||||
 | 
					          can be combined together to include, e.g. all string and numeric values.
 | 
				
			||||||
 | 
					        </entry>
 | 
				
			||||||
 | 
					        <entry><literal>json_to_tsvector('english', '{"a": "The Fat Rats", "b": 123}'::json, '["string", "numeric"]')</literal></entry>
 | 
				
			||||||
 | 
					        <entry><literal>'123':5 'fat':2 'rat':3</literal></entry>
 | 
				
			||||||
 | 
					       </row>
 | 
				
			||||||
       <row>
 | 
					       <row>
 | 
				
			||||||
        <entry>
 | 
					        <entry>
 | 
				
			||||||
         <indexterm>
 | 
					         <indexterm>
 | 
				
			||||||
 | 
				
			|||||||
@ -267,12 +267,12 @@ to_tsvector(PG_FUNCTION_ARGS)
 | 
				
			|||||||
										PointerGetDatum(in)));
 | 
															PointerGetDatum(in)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Datum
 | 
					/*
 | 
				
			||||||
jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
					 * Worker function for jsonb(_string)_to_tsvector(_byid)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static TSVector
 | 
				
			||||||
 | 
					jsonb_to_tsvector_worker(Oid cfgId, Jsonb *jb, uint32 flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Oid			cfgId = PG_GETARG_OID(0);
 | 
					 | 
				
			||||||
	Jsonb	   *jb = PG_GETARG_JSONB_P(1);
 | 
					 | 
				
			||||||
	TSVector	result;
 | 
					 | 
				
			||||||
	TSVectorBuildState state;
 | 
						TSVectorBuildState state;
 | 
				
			||||||
	ParsedText	prs;
 | 
						ParsedText	prs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -281,11 +281,50 @@ jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			|||||||
	state.prs = &prs;
 | 
						state.prs = &prs;
 | 
				
			||||||
	state.cfgId = cfgId;
 | 
						state.cfgId = cfgId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iterate_jsonb_string_values(jb, &state, add_to_tsvector);
 | 
						iterate_jsonb_values(jb, flags, &state, add_to_tsvector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return make_tsvector(&prs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					jsonb_string_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Oid			cfgId = PG_GETARG_OID(0);
 | 
				
			||||||
 | 
						Jsonb	   *jb = PG_GETARG_JSONB_P(1);
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = jsonb_to_tsvector_worker(cfgId, jb, jtiString);
 | 
				
			||||||
	PG_FREE_IF_COPY(jb, 1);
 | 
						PG_FREE_IF_COPY(jb, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = make_tsvector(&prs);
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					jsonb_string_to_tsvector(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Jsonb	   *jb = PG_GETARG_JSONB_P(0);
 | 
				
			||||||
 | 
						Oid			cfgId;
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfgId = getTSCurrentConfig(true);
 | 
				
			||||||
 | 
						result = jsonb_to_tsvector_worker(cfgId, jb, jtiString);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(jb, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Oid			cfgId = PG_GETARG_OID(0);
 | 
				
			||||||
 | 
						Jsonb	   *jb = PG_GETARG_JSONB_P(1);
 | 
				
			||||||
 | 
						Jsonb	   *jbFlags = PG_GETARG_JSONB_P(2);
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
						uint32		flags = parse_jsonb_index_flags(jbFlags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = jsonb_to_tsvector_worker(cfgId, jb, flags);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(jb, 1);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(jbFlags, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PG_RETURN_TSVECTOR(result);
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -294,20 +333,25 @@ Datum
 | 
				
			|||||||
jsonb_to_tsvector(PG_FUNCTION_ARGS)
 | 
					jsonb_to_tsvector(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Jsonb	   *jb = PG_GETARG_JSONB_P(0);
 | 
						Jsonb	   *jb = PG_GETARG_JSONB_P(0);
 | 
				
			||||||
 | 
						Jsonb	   *jbFlags = PG_GETARG_JSONB_P(1);
 | 
				
			||||||
	Oid			cfgId;
 | 
						Oid			cfgId;
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
						uint32		flags = parse_jsonb_index_flags(jbFlags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgId = getTSCurrentConfig(true);
 | 
						cfgId = getTSCurrentConfig(true);
 | 
				
			||||||
	PG_RETURN_DATUM(DirectFunctionCall2(jsonb_to_tsvector_byid,
 | 
						result = jsonb_to_tsvector_worker(cfgId, jb, flags);
 | 
				
			||||||
										ObjectIdGetDatum(cfgId),
 | 
						PG_FREE_IF_COPY(jb, 0);
 | 
				
			||||||
										JsonbPGetDatum(jb)));
 | 
						PG_FREE_IF_COPY(jbFlags, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Datum
 | 
					/*
 | 
				
			||||||
json_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
					 * Worker function for json(_string)_to_tsvector(_byid)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static TSVector
 | 
				
			||||||
 | 
					json_to_tsvector_worker(Oid cfgId, text *json, uint32 flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Oid			cfgId = PG_GETARG_OID(0);
 | 
					 | 
				
			||||||
	text	   *json = PG_GETARG_TEXT_P(1);
 | 
					 | 
				
			||||||
	TSVector	result;
 | 
					 | 
				
			||||||
	TSVectorBuildState state;
 | 
						TSVectorBuildState state;
 | 
				
			||||||
	ParsedText	prs;
 | 
						ParsedText	prs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -316,11 +360,50 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			|||||||
	state.prs = &prs;
 | 
						state.prs = &prs;
 | 
				
			||||||
	state.cfgId = cfgId;
 | 
						state.cfgId = cfgId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iterate_json_string_values(json, &state, add_to_tsvector);
 | 
						iterate_json_values(json, flags, &state, add_to_tsvector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return make_tsvector(&prs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					json_string_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Oid			cfgId = PG_GETARG_OID(0);
 | 
				
			||||||
 | 
						text	   *json = PG_GETARG_TEXT_P(1);
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = json_to_tsvector_worker(cfgId, json, jtiString);
 | 
				
			||||||
	PG_FREE_IF_COPY(json, 1);
 | 
						PG_FREE_IF_COPY(json, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = make_tsvector(&prs);
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					json_string_to_tsvector(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						text	   *json = PG_GETARG_TEXT_P(0);
 | 
				
			||||||
 | 
						Oid			cfgId;
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfgId = getTSCurrentConfig(true);
 | 
				
			||||||
 | 
						result = json_to_tsvector_worker(cfgId, json, jtiString);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(json, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					json_to_tsvector_byid(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Oid			cfgId = PG_GETARG_OID(0);
 | 
				
			||||||
 | 
						text	   *json = PG_GETARG_TEXT_P(1);
 | 
				
			||||||
 | 
						Jsonb	   *jbFlags = PG_GETARG_JSONB_P(2);
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
						uint32		flags = parse_jsonb_index_flags(jbFlags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = json_to_tsvector_worker(cfgId, json, flags);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(json, 1);
 | 
				
			||||||
 | 
						PG_FREE_IF_COPY(jbFlags, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PG_RETURN_TSVECTOR(result);
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -329,12 +412,17 @@ Datum
 | 
				
			|||||||
json_to_tsvector(PG_FUNCTION_ARGS)
 | 
					json_to_tsvector(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	text	   *json = PG_GETARG_TEXT_P(0);
 | 
						text	   *json = PG_GETARG_TEXT_P(0);
 | 
				
			||||||
 | 
						Jsonb	   *jbFlags = PG_GETARG_JSONB_P(1);
 | 
				
			||||||
	Oid			cfgId;
 | 
						Oid			cfgId;
 | 
				
			||||||
 | 
						TSVector	result;
 | 
				
			||||||
 | 
						uint32		flags = parse_jsonb_index_flags(jbFlags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgId = getTSCurrentConfig(true);
 | 
						cfgId = getTSCurrentConfig(true);
 | 
				
			||||||
	PG_RETURN_DATUM(DirectFunctionCall2(json_to_tsvector_byid,
 | 
						result = json_to_tsvector_worker(cfgId, json, flags);
 | 
				
			||||||
										ObjectIdGetDatum(cfgId),
 | 
						PG_FREE_IF_COPY(json, 0);
 | 
				
			||||||
										PointerGetDatum(json)));
 | 
						PG_FREE_IF_COPY(jbFlags, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PG_RETURN_TSVECTOR(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@ -353,7 +441,7 @@ add_to_tsvector(void *_state, char *elem_value, int elem_len)
 | 
				
			|||||||
		 * First time through: initialize words array to a reasonable size.
 | 
							 * First time through: initialize words array to a reasonable size.
 | 
				
			||||||
		 * (parsetext() will realloc it bigger as needed.)
 | 
							 * (parsetext() will realloc it bigger as needed.)
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		prs->lenwords = Max(elem_len / 6, 64);
 | 
							prs->lenwords = 16;
 | 
				
			||||||
		prs->words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs->lenwords);
 | 
							prs->words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs->lenwords);
 | 
				
			||||||
		prs->curwords = 0;
 | 
							prs->curwords = 0;
 | 
				
			||||||
		prs->pos = 0;
 | 
							prs->pos = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ typedef struct IterateJsonStringValuesState
 | 
				
			|||||||
	JsonIterateStringValuesAction action;	/* an action that will be applied
 | 
						JsonIterateStringValuesAction action;	/* an action that will be applied
 | 
				
			||||||
											 * to each json value */
 | 
																 * to each json value */
 | 
				
			||||||
	void	   *action_state;	/* any necessary context for iteration */
 | 
						void	   *action_state;	/* any necessary context for iteration */
 | 
				
			||||||
 | 
						uint32      flags;			/* what kind of elements from a json we want to iterate */
 | 
				
			||||||
} IterateJsonStringValuesState;
 | 
					} IterateJsonStringValuesState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* state for transform_json_string_values function */
 | 
					/* state for transform_json_string_values function */
 | 
				
			||||||
@ -474,8 +475,9 @@ static void setPathArray(JsonbIterator **it, Datum *path_elems,
 | 
				
			|||||||
			 int level, Jsonb *newval, uint32 nelems, int op_type);
 | 
								 int level, Jsonb *newval, uint32 nelems, int op_type);
 | 
				
			||||||
static void addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb);
 | 
					static void addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* function supporting iterate_json_string_values */
 | 
					/* function supporting iterate_json_values */
 | 
				
			||||||
static void iterate_string_values_scalar(void *state, char *token, JsonTokenType tokentype);
 | 
					static void iterate_values_scalar(void *state, char *token, JsonTokenType tokentype);
 | 
				
			||||||
 | 
					static void iterate_values_object_field_start(void *state, char *fname, bool isnull);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* functions supporting transform_json_string_values */
 | 
					/* functions supporting transform_json_string_values */
 | 
				
			||||||
static void transform_string_values_object_start(void *state);
 | 
					static void transform_string_values_object_start(void *state);
 | 
				
			||||||
@ -4939,11 +4941,79 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Iterate over jsonb string values or elements, and pass them together with an
 | 
					 * Parse information about what elements of a jsonb document we want to iterate
 | 
				
			||||||
 * iteration state to a specified JsonIterateStringValuesAction.
 | 
					 * in functions iterate_json(b)_values. This information is presented in jsonb
 | 
				
			||||||
 | 
					 * format, so that it can be easily extended in the future.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32
 | 
				
			||||||
 | 
					parse_jsonb_index_flags(Jsonb *jb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						JsonbIterator	   *it;
 | 
				
			||||||
 | 
						JsonbValue			v;
 | 
				
			||||||
 | 
						JsonbIteratorToken	type;
 | 
				
			||||||
 | 
						uint32				flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						it = JsonbIteratorInit(&jb->root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type = JsonbIteratorNext(&it, &v, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * We iterate over array (scalar internally is represented as array, so, we
 | 
				
			||||||
 | 
						 * will accept it too) to check all its elements. Flag's names are choosen
 | 
				
			||||||
 | 
						 * the same as jsonb_typeof uses.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (type != WJB_BEGIN_ARRAY)
 | 
				
			||||||
 | 
							ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 | 
				
			||||||
 | 
											errmsg("wrong flag type, only arrays and scalars are allowed")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((type = JsonbIteratorNext(&it, &v, false)) == WJB_ELEM)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (v.type != jbvString)
 | 
				
			||||||
 | 
								ereport(ERROR,
 | 
				
			||||||
 | 
										(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 | 
				
			||||||
 | 
										 errmsg("flag array element is not a string"),
 | 
				
			||||||
 | 
										 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\" and \"all\"")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (v.val.string.len == 3 &&
 | 
				
			||||||
 | 
									 pg_strncasecmp(v.val.string.val, "all", 3) == 0)
 | 
				
			||||||
 | 
								flags |= jtiAll;
 | 
				
			||||||
 | 
							else if (v.val.string.len == 3 &&
 | 
				
			||||||
 | 
									 pg_strncasecmp(v.val.string.val, "key", 3) == 0)
 | 
				
			||||||
 | 
								flags |= jtiKey;
 | 
				
			||||||
 | 
							else if (v.val.string.len == 6 &&
 | 
				
			||||||
 | 
									 pg_strncasecmp(v.val.string.val, "string", 5) == 0)
 | 
				
			||||||
 | 
								flags |= jtiString;
 | 
				
			||||||
 | 
							else if (v.val.string.len == 7 &&
 | 
				
			||||||
 | 
									 pg_strncasecmp(v.val.string.val, "numeric", 7) == 0)
 | 
				
			||||||
 | 
								flags |= jtiNumeric;
 | 
				
			||||||
 | 
							else if (v.val.string.len == 7 &&
 | 
				
			||||||
 | 
									 pg_strncasecmp(v.val.string.val, "boolean", 7) == 0)
 | 
				
			||||||
 | 
								flags |= jtiBool;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ereport(ERROR,
 | 
				
			||||||
 | 
										(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 | 
				
			||||||
 | 
										 errmsg("wrong flag in flag array: \"%s\"",
 | 
				
			||||||
 | 
												pnstrdup(v.val.string.val, v.val.string.len)),
 | 
				
			||||||
 | 
										 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\" and \"all\"")));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* user should not get it */
 | 
				
			||||||
 | 
						if (type != WJB_END_ARRAY)
 | 
				
			||||||
 | 
							elog(ERROR, "unexpected end of flag array");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* get final WJB_DONE and free iterator */
 | 
				
			||||||
 | 
						JsonbIteratorNext(&it, &v, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return flags;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Iterate over jsonb values or elements, specified by flags, and pass them
 | 
				
			||||||
 | 
					 * together with an iteration state to a specified JsonIterateStringValuesAction.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
iterate_jsonb_string_values(Jsonb *jb, void *state, JsonIterateStringValuesAction action)
 | 
					iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 | 
				
			||||||
 | 
										 JsonIterateStringValuesAction action)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	JsonbIterator *it;
 | 
						JsonbIterator *it;
 | 
				
			||||||
	JsonbValue	v;
 | 
						JsonbValue	v;
 | 
				
			||||||
@ -4951,21 +5021,67 @@ iterate_jsonb_string_values(Jsonb *jb, void *state, JsonIterateStringValuesActio
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	it = JsonbIteratorInit(&jb->root);
 | 
						it = JsonbIteratorInit(&jb->root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Just recursively iterating over jsonb and call callback on all
 | 
				
			||||||
 | 
						 * correspoding elements
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
 | 
						while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
 | 
							if (type == WJB_KEY)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								if (flags & jtiKey)
 | 
				
			||||||
				action(state, v.val.string.val, v.val.string.len);
 | 
									action(state, v.val.string.val, v.val.string.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (!(type == WJB_VALUE || type == WJB_ELEM))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* do not call callback for composite JsonbValue */
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* JsonbValue is a value of object or element of array */
 | 
				
			||||||
 | 
							switch(v.type)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case jbvString:
 | 
				
			||||||
 | 
									if (flags & jtiString)
 | 
				
			||||||
 | 
										action(state, v.val.string.val, v.val.string.len);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case jbvNumeric:
 | 
				
			||||||
 | 
									if (flags & jtiNumeric)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										char *val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										val = DatumGetCString(DirectFunctionCall1(numeric_out,
 | 
				
			||||||
 | 
													NumericGetDatum(v.val.numeric)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										action(state, val, strlen(val));
 | 
				
			||||||
 | 
										pfree(val);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case jbvBool:
 | 
				
			||||||
 | 
									if (flags & jtiBool)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if (v.val.boolean)
 | 
				
			||||||
 | 
											action(state, "true", 4);
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											action(state, "false", 5);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									/* do not call callback for composite JsonbValue */
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Iterate over json string values or elements, and pass them together with an
 | 
					 * Iterate over json values and elements, specified by flags, and pass them
 | 
				
			||||||
 * iteration state to a specified JsonIterateStringValuesAction.
 | 
					 * together with an iteration state to a specified JsonIterateStringValuesAction.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
iterate_json_string_values(text *json, void *action_state, JsonIterateStringValuesAction action)
 | 
					iterate_json_values(text *json, uint32 flags, void *action_state,
 | 
				
			||||||
 | 
										JsonIterateStringValuesAction action)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	JsonLexContext *lex = makeJsonLexContext(json, true);
 | 
						JsonLexContext *lex = makeJsonLexContext(json, true);
 | 
				
			||||||
	JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
 | 
						JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
 | 
				
			||||||
@ -4974,24 +5090,55 @@ iterate_json_string_values(text *json, void *action_state, JsonIterateStringValu
 | 
				
			|||||||
	state->lex = lex;
 | 
						state->lex = lex;
 | 
				
			||||||
	state->action = action;
 | 
						state->action = action;
 | 
				
			||||||
	state->action_state = action_state;
 | 
						state->action_state = action_state;
 | 
				
			||||||
 | 
						state->flags = flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sem->semstate = (void *) state;
 | 
						sem->semstate = (void *) state;
 | 
				
			||||||
	sem->scalar = iterate_string_values_scalar;
 | 
						sem->scalar = iterate_values_scalar;
 | 
				
			||||||
 | 
						sem->object_field_start = iterate_values_object_field_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pg_parse_json(lex, sem);
 | 
						pg_parse_json(lex, sem);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * An auxiliary function for iterate_json_string_values to invoke a specified
 | 
					 * An auxiliary function for iterate_json_values to invoke a specified
 | 
				
			||||||
 * JsonIterateStringValuesAction.
 | 
					 * JsonIterateStringValuesAction for specified values.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
iterate_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
 | 
					iterate_values_scalar(void *state, char *token, JsonTokenType tokentype)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state;
 | 
						IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tokentype == JSON_TOKEN_STRING)
 | 
						switch(tokentype)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case JSON_TOKEN_STRING:
 | 
				
			||||||
 | 
								if (_state->flags & jtiString)
 | 
				
			||||||
				_state->action(_state->action_state, token, strlen(token));
 | 
									_state->action(_state->action_state, token, strlen(token));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case JSON_TOKEN_NUMBER:
 | 
				
			||||||
 | 
								if (_state->flags & jtiNumeric)
 | 
				
			||||||
 | 
									_state->action(_state->action_state, token, strlen(token));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case JSON_TOKEN_TRUE:
 | 
				
			||||||
 | 
							case JSON_TOKEN_FALSE:
 | 
				
			||||||
 | 
								if (_state->flags & jtiBool)
 | 
				
			||||||
 | 
									_state->action(_state->action_state, token, strlen(token));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								/* do not call callback for any other token */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					iterate_values_object_field_start(void *state, char *fname, bool isnull)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_state->flags & jtiKey)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char *val = pstrdup(fname);
 | 
				
			||||||
 | 
							_state->action(_state->action_state, val, strlen(val));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
				
			|||||||
@ -53,6 +53,6 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*							yyyymmddN */
 | 
					/*							yyyymmddN */
 | 
				
			||||||
#define CATALOG_VERSION_NO	201804071
 | 
					#define CATALOG_VERSION_NO	201804072
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -4987,14 +4987,22 @@ DATA(insert OID = 5001 (  phraseto_tsquery	PGNSP PGUID 12 100 0 0 0 f f f t f s
 | 
				
			|||||||
DESCR("transform to tsquery");
 | 
					DESCR("transform to tsquery");
 | 
				
			||||||
DATA(insert OID = 8890 (  websearch_to_tsquery	PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3615 "25" _null_ _null_ _null_ _null_ _null_ websearch_to_tsquery _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 8890 (  websearch_to_tsquery	PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3615 "25" _null_ _null_ _null_ _null_ _null_ websearch_to_tsquery _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("transform to tsquery");
 | 
					DESCR("transform to tsquery");
 | 
				
			||||||
DATA(insert OID = 4209 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3614 "3802" _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 4209 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3614 "3802" _null_ _null_ _null_ _null_ _null_ jsonb_string_to_tsvector _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("transform jsonb to tsvector");
 | 
					DESCR("transform string values from jsonb to tsvector");
 | 
				
			||||||
DATA(insert OID = 4210 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3614 "114" _null_ _null_ _null_ _null_ _null_ json_to_tsvector _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 4213 (  jsonb_to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 2 0 3614 "3802 3802" _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("transform json to tsvector");
 | 
					DESCR("transform specified values from jsonb to tsvector");
 | 
				
			||||||
DATA(insert OID = 4211 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 2 0 3614 "3734 3802" _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector_byid _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 4210 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 1 0 3614 "114" _null_ _null_ _null_ _null_ _null_ json_string_to_tsvector _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("transform jsonb to tsvector");
 | 
					DESCR("transform string values from json to tsvector");
 | 
				
			||||||
DATA(insert OID = 4212 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 2 0 3614 "3734 114" _null_ _null_ _null_ _null_ _null_ json_to_tsvector_byid _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 4215 (  json_to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f s s 2 0 3614 "114 3802" _null_ _null_ _null_ _null_ _null_ json_to_tsvector _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("transform json to tsvector");
 | 
					DESCR("transform specified values from json to tsvector");
 | 
				
			||||||
 | 
					DATA(insert OID = 4211 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 2 0 3614 "3734 3802" _null_ _null_ _null_ _null_ _null_ jsonb_string_to_tsvector_byid _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("transform string values from jsonb to tsvector");
 | 
				
			||||||
 | 
					DATA(insert OID = 4214 (  jsonb_to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 3 0 3614 "3734 3802 3802" _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector_byid _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("transform specified values from jsonb to tsvector");
 | 
				
			||||||
 | 
					DATA(insert OID = 4212 (  to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 2 0 3614 "3734 114" _null_ _null_ _null_ _null_ _null_ json_string_to_tsvector_byid _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("transform string values from json to tsvector");
 | 
				
			||||||
 | 
					DATA(insert OID = 4216 (  json_to_tsvector		PGNSP PGUID 12 100 0 0 0 f f f t f i s 3 0 3614 "3734 114 3802" _null_ _null_ _null_ _null_ _null_ json_to_tsvector_byid _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("transform specified values from json to tsvector");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DATA(insert OID = 3752 (  tsvector_update_trigger			PGNSP PGUID 12 1 0 0 0 f f f f f v s 0 0 2279 "" _null_ _null_ _null_ _null_ _null_ tsvector_update_trigger_byid _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 3752 (  tsvector_update_trigger			PGNSP PGUID 12 1 0 0 0 f f f f f v s 0 0 2279 "" _null_ _null_ _null_ _null_ _null_ tsvector_update_trigger_byid _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("trigger for automatic update of tsvector column");
 | 
					DESCR("trigger for automatic update of tsvector column");
 | 
				
			||||||
 | 
				
			|||||||
@ -132,15 +132,28 @@ extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
extern bool IsValidJsonNumber(const char *str, int len);
 | 
					extern bool IsValidJsonNumber(const char *str, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* an action that will be applied to each value in iterate_json(b)_string_vaues functions */
 | 
					/*
 | 
				
			||||||
 | 
					 * Flag types for iterate_json(b)_values to specify what elements from a
 | 
				
			||||||
 | 
					 * json(b) document we want to iterate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef enum JsonToIndex {
 | 
				
			||||||
 | 
						jtiKey		= 0x01,
 | 
				
			||||||
 | 
						jtiString	= 0x02,
 | 
				
			||||||
 | 
						jtiNumeric	= 0x04,
 | 
				
			||||||
 | 
						jtiBool		= 0x08,
 | 
				
			||||||
 | 
						jtiAll		= jtiKey | jtiString | jtiNumeric | jtiBool
 | 
				
			||||||
 | 
					} JsonToIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* an action that will be applied to each value in iterate_json(b)_vaues functions */
 | 
				
			||||||
typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len);
 | 
					typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* an action that will be applied to each value in transform_json(b)_string_values functions */
 | 
					/* an action that will be applied to each value in transform_json(b)_values functions */
 | 
				
			||||||
typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len);
 | 
					typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void iterate_jsonb_string_values(Jsonb *jb, void *state,
 | 
					extern uint32 parse_jsonb_index_flags(Jsonb *jb);
 | 
				
			||||||
 | 
					extern void iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 | 
				
			||||||
							JsonIterateStringValuesAction action);
 | 
												JsonIterateStringValuesAction action);
 | 
				
			||||||
extern void iterate_json_string_values(text *json, void *action_state,
 | 
					extern void iterate_json_values(text *json, uint32 flags, void *action_state,
 | 
				
			||||||
						   JsonIterateStringValuesAction action);
 | 
											   JsonIterateStringValuesAction action);
 | 
				
			||||||
extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state,
 | 
					extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state,
 | 
				
			||||||
							  JsonTransformStringValuesAction transform_action);
 | 
												  JsonTransformStringValuesAction transform_action);
 | 
				
			||||||
 | 
				
			|||||||
@ -2324,6 +2324,86 @@ select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff gg
 | 
				
			|||||||
 'aaa':1 'bbb':3 'ccc':5 'ddd':4 'eee':8 'fff':9 'ggg':10 'hhh':12 'iii':13
 | 
					 'aaa':1 'bbb':3 'ccc':5 'ddd':4 'eee':8 'fff':9 'ggg':10 'hhh':12 'iii':13
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json to tsvector with numeric values
 | 
				
			||||||
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json);
 | 
				
			||||||
 | 
					           to_tsvector           
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3 'ccc':5 'ddd':4
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json_to_tsvector
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"');
 | 
				
			||||||
 | 
					                                    json_to_tsvector                                    
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 '123':8 '456':12 'aaa':2 'b':6 'bbb':4 'c':10 'd':14 'f':18 'fals':20 'g':22 'true':16
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"');
 | 
				
			||||||
 | 
					        json_to_tsvector        
 | 
				
			||||||
 | 
					--------------------------------
 | 
				
			||||||
 | 
					 'b':2 'c':4 'd':6 'f':8 'g':10
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 '123':1 '456':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"');
 | 
				
			||||||
 | 
					 json_to_tsvector  
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'fals':3 'true':1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]');
 | 
				
			||||||
 | 
					        json_to_tsvector         
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 '123':5 '456':7 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"');
 | 
				
			||||||
 | 
					                                    json_to_tsvector                                    
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 '123':8 '456':12 'aaa':2 'b':6 'bbb':4 'c':10 'd':14 'f':18 'fals':20 'g':22 'true':16
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"');
 | 
				
			||||||
 | 
					        json_to_tsvector        
 | 
				
			||||||
 | 
					--------------------------------
 | 
				
			||||||
 | 
					 'b':2 'c':4 'd':6 'f':8 'g':10
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 '123':1 '456':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"');
 | 
				
			||||||
 | 
					 json_to_tsvector  
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'fals':3 'true':1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]');
 | 
				
			||||||
 | 
					        json_to_tsvector         
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 '123':5 '456':7 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_vector corner cases
 | 
					-- ts_vector corner cases
 | 
				
			||||||
select to_tsvector('""'::json);
 | 
					select to_tsvector('""'::json);
 | 
				
			||||||
 to_tsvector 
 | 
					 to_tsvector 
 | 
				
			||||||
@ -2349,6 +2429,48 @@ select to_tsvector('null'::json);
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json_to_tsvector corner cases
 | 
				
			||||||
 | 
					select json_to_tsvector('""'::json, '"all"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{}'::json, '"all"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('[]'::json, '"all"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('null'::json, '"all"');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""');
 | 
				
			||||||
 | 
					ERROR:  wrong flag in flag array: ""
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}');
 | 
				
			||||||
 | 
					ERROR:  wrong flag type, only arrays and scalars are allowed
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]');
 | 
				
			||||||
 | 
					 json_to_tsvector 
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null');
 | 
				
			||||||
 | 
					ERROR:  flag array element is not a string
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]');
 | 
				
			||||||
 | 
					ERROR:  flag array element is not a string
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
-- ts_headline for json
 | 
					-- ts_headline for json
 | 
				
			||||||
select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
                                               ts_headline                                               
 | 
					                                               ts_headline                                               
 | 
				
			||||||
 | 
				
			|||||||
@ -4122,6 +4122,86 @@ select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff gg
 | 
				
			|||||||
 'aaa':1 'bbb':3 'ccc':5 'ddd':4 'eee':8 'fff':9 'ggg':10 'hhh':12 'iii':13
 | 
					 'aaa':1 'bbb':3 'ccc':5 'ddd':4 'eee':8 'fff':9 'ggg':10 'hhh':12 'iii':13
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb to tsvector with numeric values
 | 
				
			||||||
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb);
 | 
				
			||||||
 | 
					           to_tsvector           
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3 'ccc':5 'ddd':4
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb_to_tsvector
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					                                   jsonb_to_tsvector                                    
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 '123':8 '456':12 'aaa':2 'b':6 'bbb':4 'c':10 'd':14 'f':18 'fals':20 'g':22 'true':16
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"');
 | 
				
			||||||
 | 
					       jsonb_to_tsvector        
 | 
				
			||||||
 | 
					--------------------------------
 | 
				
			||||||
 | 
					 'b':2 'c':4 'd':6 'f':8 'g':10
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 '123':1 '456':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'fals':3 'true':1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]');
 | 
				
			||||||
 | 
					        jsonb_to_tsvector        
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 '123':5 '456':7 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					                                   jsonb_to_tsvector                                    
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 '123':8 '456':12 'aaa':2 'b':6 'bbb':4 'c':10 'd':14 'f':18 'fals':20 'g':22 'true':16
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"');
 | 
				
			||||||
 | 
					       jsonb_to_tsvector        
 | 
				
			||||||
 | 
					--------------------------------
 | 
				
			||||||
 | 
					 'b':2 'c':4 'd':6 'f':8 'g':10
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 '123':1 '456':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 'fals':3 'true':1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]');
 | 
				
			||||||
 | 
					        jsonb_to_tsvector        
 | 
				
			||||||
 | 
					---------------------------------
 | 
				
			||||||
 | 
					 '123':5 '456':7 'aaa':1 'bbb':3
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_vector corner cases
 | 
					-- ts_vector corner cases
 | 
				
			||||||
select to_tsvector('""'::jsonb);
 | 
					select to_tsvector('""'::jsonb);
 | 
				
			||||||
 to_tsvector 
 | 
					 to_tsvector 
 | 
				
			||||||
@ -4147,6 +4227,48 @@ select to_tsvector('null'::jsonb);
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb_to_tsvector corner cases
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('""'::jsonb, '"all"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('[]'::jsonb, '"all"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('null'::jsonb, '"all"');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""');
 | 
				
			||||||
 | 
					ERROR:  wrong flag in flag array: ""
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}');
 | 
				
			||||||
 | 
					ERROR:  wrong flag type, only arrays and scalars are allowed
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]');
 | 
				
			||||||
 | 
					 jsonb_to_tsvector 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null');
 | 
				
			||||||
 | 
					ERROR:  flag array element is not a string
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]');
 | 
				
			||||||
 | 
					ERROR:  flag array element is not a string
 | 
				
			||||||
 | 
					HINT:  Possible values are: "string", "numeric", "boolean", "key" and "all"
 | 
				
			||||||
-- ts_headline for jsonb
 | 
					-- ts_headline for jsonb
 | 
				
			||||||
select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
                                                   ts_headline                                                    
 | 
					                                                   ts_headline                                                    
 | 
				
			||||||
 | 
				
			|||||||
@ -763,12 +763,42 @@ select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c"
 | 
				
			|||||||
-- json to tsvector with stop words
 | 
					-- json to tsvector with stop words
 | 
				
			||||||
select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::json);
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json to tsvector with numeric values
 | 
				
			||||||
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json_to_tsvector
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"');
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"');
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"');
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"');
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"');
 | 
				
			||||||
 | 
					select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_vector corner cases
 | 
					-- ts_vector corner cases
 | 
				
			||||||
select to_tsvector('""'::json);
 | 
					select to_tsvector('""'::json);
 | 
				
			||||||
select to_tsvector('{}'::json);
 | 
					select to_tsvector('{}'::json);
 | 
				
			||||||
select to_tsvector('[]'::json);
 | 
					select to_tsvector('[]'::json);
 | 
				
			||||||
select to_tsvector('null'::json);
 | 
					select to_tsvector('null'::json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- json_to_tsvector corner cases
 | 
				
			||||||
 | 
					select json_to_tsvector('""'::json, '"all"');
 | 
				
			||||||
 | 
					select json_to_tsvector('{}'::json, '"all"');
 | 
				
			||||||
 | 
					select json_to_tsvector('[]'::json, '"all"');
 | 
				
			||||||
 | 
					select json_to_tsvector('null'::json, '"all"');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null');
 | 
				
			||||||
 | 
					select json_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_headline for json
 | 
					-- ts_headline for json
 | 
				
			||||||
select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
 | 
				
			|||||||
@ -1089,12 +1089,42 @@ select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c"
 | 
				
			|||||||
-- jsonb to tsvector with stop words
 | 
					-- jsonb to tsvector with stop words
 | 
				
			||||||
select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::jsonb);
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::jsonb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb to tsvector with numeric values
 | 
				
			||||||
 | 
					select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb_to_tsvector
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_vector corner cases
 | 
					-- ts_vector corner cases
 | 
				
			||||||
select to_tsvector('""'::jsonb);
 | 
					select to_tsvector('""'::jsonb);
 | 
				
			||||||
select to_tsvector('{}'::jsonb);
 | 
					select to_tsvector('{}'::jsonb);
 | 
				
			||||||
select to_tsvector('[]'::jsonb);
 | 
					select to_tsvector('[]'::jsonb);
 | 
				
			||||||
select to_tsvector('null'::jsonb);
 | 
					select to_tsvector('null'::jsonb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- jsonb_to_tsvector corner cases
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('""'::jsonb, '"all"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{}'::jsonb, '"all"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('[]'::jsonb, '"all"');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('null'::jsonb, '"all"');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null');
 | 
				
			||||||
 | 
					select jsonb_to_tsvector('{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- ts_headline for jsonb
 | 
					-- ts_headline for jsonb
 | 
				
			||||||
select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
					select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'));
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user