diff options
author | Amit Langote <amitlan@postgresql.org> | 2024-07-26 16:08:13 +0900 |
---|---|---|
committer | Amit Langote <amitlan@postgresql.org> | 2024-07-26 16:08:13 +0900 |
commit | 4fc6a555606de003690d46e900339e78214ee363 (patch) | |
tree | 47191123995c74c1b86a07dcf4e9785c78c5424a | |
parent | 231b7d670b218d6a5cde0574cf160c8157ab91fb (diff) | |
download | postgresql-4fc6a555606de003690d46e900339e78214ee363.tar.gz postgresql-4fc6a555606de003690d46e900339e78214ee363.zip |
SQL/JSON: Respect OMIT QUOTES when RETURNING domains over jsonb
populate_domain() didn't take into account the omit_quotes flag passed
down to json_populate_type() by ExecEvalJsonCoercion() and that led
to incorrect behavior when the RETURNING type is a domain over
jsonb. Fix that by passing the flag by adding a new function
parameter to populate_domain().
Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
-rw-r--r-- | src/backend/utils/adt/jsonfuncs.c | 11 | ||||
-rw-r--r-- | src/test/regress/expected/sqljson_queryfuncs.out | 15 | ||||
-rw-r--r-- | src/test/regress/sql/sqljson_queryfuncs.sql | 5 |
3 files changed, 26 insertions, 5 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 48c3f881403..1b681eff5f1 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -453,7 +453,7 @@ static void prepare_column_cache(ColumnIOData *column, Oid typid, int32 typmod, static Datum populate_record_field(ColumnIOData *col, Oid typid, int32 typmod, const char *colname, MemoryContext mcxt, Datum defaultval, JsValue *jsv, bool *isnull, Node *escontext, - bool omit_quotes); + bool omit_scalar_quotes); static RecordIOData *allocate_record_info(MemoryContext mcxt, int ncolumns); static bool JsObjectGetField(JsObject *obj, char *field, JsValue *jsv); static void populate_recordset_record(PopulateRecordsetState *state, JsObject *obj); @@ -470,7 +470,7 @@ static Datum populate_array(ArrayIOData *aio, const char *colname, Node *escontext); static Datum populate_domain(DomainIOData *io, Oid typid, const char *colname, MemoryContext mcxt, JsValue *jsv, bool *isnull, - Node *escontext); + Node *escontext, bool omit_quotes); /* functions supporting jsonb_delete, jsonb_set and jsonb_concat */ static JsonbValue *IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, @@ -3218,7 +3218,8 @@ populate_domain(DomainIOData *io, MemoryContext mcxt, JsValue *jsv, bool *isnull, - Node *escontext) + Node *escontext, + bool omit_quotes) { Datum res; @@ -3229,7 +3230,7 @@ populate_domain(DomainIOData *io, res = populate_record_field(io->base_io, io->base_typid, io->base_typmod, colname, mcxt, PointerGetDatum(NULL), - jsv, isnull, escontext, false); + jsv, isnull, escontext, omit_quotes); Assert(!*isnull || SOFT_ERROR_OCCURRED(escontext)); } @@ -3461,7 +3462,7 @@ populate_record_field(ColumnIOData *col, case TYPECAT_DOMAIN: return populate_domain(&col->io.domain, typid, colname, mcxt, - jsv, isnull, escontext); + jsv, isnull, escontext, omit_scalar_quotes); default: elog(ERROR, "unrecognized type category '%c'", typcat); diff --git a/src/test/regress/expected/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index ab045e13590..bdadf4b788e 100644 --- a/src/test/regress/expected/sqljson_queryfuncs.out +++ b/src/test/regress/expected/sqljson_queryfuncs.out @@ -734,6 +734,21 @@ SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quot SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes error on error); ERROR: malformed range literal: ""[1,2]"" DETAIL: Missing left parenthesis or bracket. +CREATE DOMAIN qf_char_domain AS char(1); +CREATE DOMAIN qf_jsonb_domain AS jsonb; +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR); + json_query +------------ + 1 +(1 row) + +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR); + json_query +------------ + 1 +(1 row) + +DROP DOMAIN qf_char_domain, qf_jsonb_domain; SELECT JSON_QUERY(jsonb '[]', '$[*]'); json_query ------------ diff --git a/src/test/regress/sql/sqljson_queryfuncs.sql b/src/test/regress/sql/sqljson_queryfuncs.sql index be5593b3324..e9005d3d4eb 100644 --- a/src/test/regress/sql/sqljson_queryfuncs.sql +++ b/src/test/regress/sql/sqljson_queryfuncs.sql @@ -214,6 +214,11 @@ SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes); SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes); SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes error on error); +CREATE DOMAIN qf_char_domain AS char(1); +CREATE DOMAIN qf_jsonb_domain AS jsonb; +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR); +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR); +DROP DOMAIN qf_char_domain, qf_jsonb_domain; SELECT JSON_QUERY(jsonb '[]', '$[*]'); SELECT JSON_QUERY(jsonb '[]', '$[*]' NULL ON EMPTY); |