diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 5abb1c46fb..73524a756d 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -9688,7 +9688,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - reduce each string value in the document to a tsvector, and then + reduce each string or numeric value in the document to a tsvector, and then concatenate those in document order to produce a single tsvector to_tsvector('english', '{"a": "The Fat Rats"}'::json) diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index fa78451613..cab0011d62 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -4939,8 +4939,8 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, } /* - * Iterate over jsonb string values or elements, and pass them together with an - * iteration state to a specified JsonIterateStringValuesAction. + * Iterate over jsonb string/numeric values or elements, and pass them together + * with an iteration state to a specified JsonIterateStringValuesAction. */ void iterate_jsonb_string_values(Jsonb *jb, void *state, JsonIterateStringValuesAction action) @@ -4953,15 +4953,23 @@ iterate_jsonb_string_values(Jsonb *jb, void *state, JsonIterateStringValuesActio while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) { - if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString) + if (type == WJB_VALUE || type == WJB_ELEM) { - action(state, v.val.string.val, v.val.string.len); + if (v.type == jbvString) + action(state, v.val.string.val, v.val.string.len); + + if (v.type == jbvNumeric) + { + char *val = DatumGetCString(DirectFunctionCall1(numeric_out, + NumericGetDatum(v.val.numeric))); + action(state, val, strlen(val)); + } } } } /* - * Iterate over json string values or elements, and pass them together with an + * Iterate over json string/numeric values or elements, and pass them together with an * iteration state to a specified JsonIterateStringValuesAction. */ void @@ -4990,7 +4998,7 @@ iterate_string_values_scalar(void *state, char *token, JsonTokenType tokentype) { IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state; - if (tokentype == JSON_TOKEN_STRING) + if (tokentype == JSON_TOKEN_STRING || tokentype == JSON_TOKEN_NUMBER) _state->action(_state->action_state, token, strlen(token)); } diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index 06c728e363..5948cbe82b 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -2324,6 +2324,13 @@ 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 (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 +------------------------------------------------- + '123':7 '456':9 'aaa':1 'bbb':3 'ccc':5 'ddd':4 +(1 row) + -- ts_vector corner cases select to_tsvector('""'::json); to_tsvector diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index f8d6e6f7cc..ce262421c5 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -4122,6 +4122,13 @@ 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 (1 row) +-- json to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb); + to_tsvector +------------------------------------------------- + '123':7 '456':9 'aaa':1 'bbb':3 'ccc':5 'ddd':4 +(1 row) + -- ts_vector corner cases select to_tsvector('""'::jsonb); to_tsvector diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index 256652c41f..d0d3a0dd1c 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -763,6 +763,9 @@ select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c" -- 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); +-- json to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json); + -- ts_vector corner cases select to_tsvector('""'::json); select to_tsvector('{}'::json); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index 2439f949bd..9f09eff8cb 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -1089,6 +1089,9 @@ select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c" -- 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); +-- json to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb); + -- ts_vector corner cases select to_tsvector('""'::jsonb); select to_tsvector('{}'::jsonb);