SQL/JSON: Respect OMIT QUOTES when RETURNING domains over jsonb
authorAmit Langote <[email protected]>
Fri, 26 Jul 2024 07:08:13 +0000 (16:08 +0900)
committerAmit Langote <[email protected]>
Fri, 26 Jul 2024 07:08:13 +0000 (16:08 +0900)
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 <[email protected]>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17

src/backend/utils/adt/jsonfuncs.c
src/test/regress/expected/sqljson_queryfuncs.out
src/test/regress/sql/sqljson_queryfuncs.sql

index 48c3f88140337096b34b234f61106bae5c498245..1b681eff5f1c02e3443385b9e899f4601c946117 100644 (file)
@@ -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);
index ab045e13590764bc08f3a8e0bc8cc9b0f60f182c..bdadf4b788e645608091817e9c113f10554f1cc5 100644 (file)
@@ -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 
 ------------
index be5593b33248770bcfe03a495bbe3120be102d2d..e9005d3d4eb0d9089fbf2e93675c3eada6abd683 100644 (file)
@@ -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);