Rename JsonIsPredicate.value_type, fix JSON backend/nodes/ infrastructure.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 13 May 2022 15:40:01 +0000 (11:40 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 13 May 2022 15:40:08 +0000 (11:40 -0400)
I started out with the intention to rename value_type to item_type to
avoid a collision with a typedef name that appears on some platforms.

Along the way, I noticed that the adjacent field "format" was not being
correctly handled by the backend/nodes/ infrastructure functions:
copyfuncs.c erroneously treated it as a scalar, while equalfuncs,
outfuncs, and readfuncs omitted handling it at all.  This looks like
it might be cosmetic at the moment because the field is always NULL
after parse analysis; but that's likely a bug in itself, and the code's
certainly not very future-proof.  Let's fix it while we can still do so
without forcing an initdb on beta testers.

Further study found a few other inconsistencies in the backend/nodes/
infrastructure for the recently-added JSON node types, so fix those too.

catversion bumped because of potential change in stored rules.

Discussion: https://postgr.es/m/526703.1652385613@sss.pgh.pa.us

12 files changed:
src/backend/executor/execExprInterp.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/parse_expr.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/misc/queryjumble.c
src/include/catalog/catversion.h
src/include/nodes/makefuncs.h
src/include/nodes/primnodes.h

index e024611aa5438daebae0bc35bcbd69cf6ea16025..e44ad68cda166f7bb66c72ccbcafbbbb46ae84f4 100644 (file)
@@ -3952,24 +3952,24 @@ ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op)
        {
                text       *json = DatumGetTextP(js);
 
-               if (pred->value_type == JS_TYPE_ANY)
+               if (pred->item_type == JS_TYPE_ANY)
                        res = true;
                else
                {
                        switch (json_get_first_token(json, false))
                        {
                                case JSON_TOKEN_OBJECT_START:
-                                       res = pred->value_type == JS_TYPE_OBJECT;
+                                       res = pred->item_type == JS_TYPE_OBJECT;
                                        break;
                                case JSON_TOKEN_ARRAY_START:
-                                       res = pred->value_type == JS_TYPE_ARRAY;
+                                       res = pred->item_type == JS_TYPE_ARRAY;
                                        break;
                                case JSON_TOKEN_STRING:
                                case JSON_TOKEN_NUMBER:
                                case JSON_TOKEN_TRUE:
                                case JSON_TOKEN_FALSE:
                                case JSON_TOKEN_NULL:
-                                       res = pred->value_type == JS_TYPE_SCALAR;
+                                       res = pred->item_type == JS_TYPE_SCALAR;
                                        break;
                                default:
                                        res = false;
@@ -3986,13 +3986,13 @@ ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op)
        }
        else if (exprtype == JSONBOID)
        {
-               if (pred->value_type == JS_TYPE_ANY)
+               if (pred->item_type == JS_TYPE_ANY)
                        res = true;
                else
                {
                        Jsonb      *jb = DatumGetJsonbP(js);
 
-                       switch (pred->value_type)
+                       switch (pred->item_type)
                        {
                                case JS_TYPE_OBJECT:
                                        res = JB_ROOT_IS_OBJECT(jb);
index 205506305b04951e61abb284f17d2a135e8c3018..51d630fa8925e04db5a8a95abf6745c4545f1624 100644 (file)
@@ -2557,11 +2557,11 @@ _copyJsonExpr(const JsonExpr *from)
        COPY_NODE_FIELD(result_coercion);
        COPY_NODE_FIELD(format);
        COPY_NODE_FIELD(path_spec);
-       COPY_NODE_FIELD(passing_values);
        COPY_NODE_FIELD(passing_names);
+       COPY_NODE_FIELD(passing_values);
        COPY_NODE_FIELD(returning);
-       COPY_NODE_FIELD(on_error);
        COPY_NODE_FIELD(on_empty);
+       COPY_NODE_FIELD(on_error);
        COPY_NODE_FIELD(coercions);
        COPY_SCALAR_FIELD(wrapper);
        COPY_SCALAR_FIELD(omit_quotes);
@@ -2637,8 +2637,8 @@ _copyJsonIsPredicate(const JsonIsPredicate *from)
        JsonIsPredicate *newnode = makeNode(JsonIsPredicate);
 
        COPY_NODE_FIELD(expr);
-       COPY_SCALAR_FIELD(format);
-       COPY_SCALAR_FIELD(value_type);
+       COPY_NODE_FIELD(format);
+       COPY_SCALAR_FIELD(item_type);
        COPY_SCALAR_FIELD(unique_keys);
        COPY_LOCATION_FIELD(location);
 
@@ -2764,6 +2764,7 @@ _copyJsonTableParent(const JsonTableParent *from)
        COPY_SCALAR_FIELD(outerJoin);
        COPY_SCALAR_FIELD(colMin);
        COPY_SCALAR_FIELD(colMax);
+       COPY_SCALAR_FIELD(errorOnError);
 
        return newnode;
 }
index 9688b22a4b99086c983ac30c0f5a37e7634d777a..e747e1667d01252ea841808fa1cfea066b72fd36 100644 (file)
@@ -186,6 +186,7 @@ _equalJsonTableParent(const JsonTableParent *a, const JsonTableParent *b)
        COMPARE_SCALAR_FIELD(outerJoin);
        COMPARE_SCALAR_FIELD(colMin);
        COMPARE_SCALAR_FIELD(colMax);
+       COMPARE_SCALAR_FIELD(errorOnError);
 
        return true;
 }
@@ -1104,7 +1105,8 @@ _equalJsonIsPredicate(const JsonIsPredicate *a,
                                          const JsonIsPredicate *b)
 {
        COMPARE_NODE_FIELD(expr);
-       COMPARE_SCALAR_FIELD(value_type);
+       COMPARE_NODE_FIELD(format);
+       COMPARE_SCALAR_FIELD(item_type);
        COMPARE_SCALAR_FIELD(unique_keys);
        COMPARE_LOCATION_FIELD(location);
 
@@ -1134,11 +1136,11 @@ _equalJsonExpr(const JsonExpr *a, const JsonExpr *b)
        COMPARE_NODE_FIELD(result_coercion);
        COMPARE_NODE_FIELD(format);
        COMPARE_NODE_FIELD(path_spec);
-       COMPARE_NODE_FIELD(passing_values);
        COMPARE_NODE_FIELD(passing_names);
+       COMPARE_NODE_FIELD(passing_values);
        COMPARE_NODE_FIELD(returning);
-       COMPARE_NODE_FIELD(on_error);
        COMPARE_NODE_FIELD(on_empty);
+       COMPARE_NODE_FIELD(on_error);
        COMPARE_NODE_FIELD(coercions);
        COMPARE_SCALAR_FIELD(wrapper);
        COMPARE_SCALAR_FIELD(omit_quotes);
index 41e26a0fe679a35c5c6b759e274a84d5f6355fa8..28288dcfc101c0530f80c506fc164ad90f9530cf 100644 (file)
@@ -927,14 +927,14 @@ makeJsonKeyValue(Node *key, Node *value)
  *       creates a JsonIsPredicate node
  */
 Node *
-makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType value_type,
+makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type,
                                        bool unique_keys, int location)
 {
        JsonIsPredicate *n = makeNode(JsonIsPredicate);
 
        n->expr = expr;
        n->format = format;
-       n->value_type = value_type;
+       n->item_type = item_type;
        n->unique_keys = unique_keys;
        n->location = location;
 
index 0271ea9d7869dd615d018f592911efd51455bacc..ce129155925965903e168a327384cbb71da8f178 100644 (file)
@@ -1801,13 +1801,13 @@ _outJsonConstructorExpr(StringInfo str, const JsonConstructorExpr *node)
 {
        WRITE_NODE_TYPE("JSONCONSTRUCTOREXPR");
 
+       WRITE_ENUM_FIELD(type, JsonConstructorType);
        WRITE_NODE_FIELD(args);
        WRITE_NODE_FIELD(func);
        WRITE_NODE_FIELD(coercion);
-       WRITE_ENUM_FIELD(type, JsonConstructorType);
        WRITE_NODE_FIELD(returning);
-       WRITE_BOOL_FIELD(unique);
        WRITE_BOOL_FIELD(absent_on_null);
+       WRITE_BOOL_FIELD(unique);
        WRITE_LOCATION_FIELD(location);
 }
 
@@ -1817,7 +1817,8 @@ _outJsonIsPredicate(StringInfo str, const JsonIsPredicate *node)
        WRITE_NODE_TYPE("JSONISPREDICATE");
 
        WRITE_NODE_FIELD(expr);
-       WRITE_ENUM_FIELD(value_type, JsonValueType);
+       WRITE_NODE_FIELD(format);
+       WRITE_ENUM_FIELD(item_type, JsonValueType);
        WRITE_BOOL_FIELD(unique_keys);
        WRITE_LOCATION_FIELD(location);
 }
@@ -1841,11 +1842,11 @@ _outJsonExpr(StringInfo str, const JsonExpr *node)
        WRITE_NODE_FIELD(result_coercion);
        WRITE_NODE_FIELD(format);
        WRITE_NODE_FIELD(path_spec);
-       WRITE_NODE_FIELD(passing_values);
        WRITE_NODE_FIELD(passing_names);
+       WRITE_NODE_FIELD(passing_values);
        WRITE_NODE_FIELD(returning);
-       WRITE_NODE_FIELD(on_error);
        WRITE_NODE_FIELD(on_empty);
+       WRITE_NODE_FIELD(on_error);
        WRITE_NODE_FIELD(coercions);
        WRITE_ENUM_FIELD(wrapper, JsonWrapper);
        WRITE_BOOL_FIELD(omit_quotes);
@@ -1883,7 +1884,7 @@ _outJsonItemCoercions(StringInfo str, const JsonItemCoercions *node)
 static void
 _outJsonTableParent(StringInfo str, const JsonTableParent *node)
 {
-       WRITE_NODE_TYPE("JSONTABPNODE");
+       WRITE_NODE_TYPE("JSONTABLEPARENT");
 
        WRITE_NODE_FIELD(path);
        WRITE_STRING_FIELD(name);
@@ -1891,12 +1892,13 @@ _outJsonTableParent(StringInfo str, const JsonTableParent *node)
        WRITE_BOOL_FIELD(outerJoin);
        WRITE_INT_FIELD(colMin);
        WRITE_INT_FIELD(colMax);
+       WRITE_BOOL_FIELD(errorOnError);
 }
 
 static void
 _outJsonTableSibling(StringInfo str, const JsonTableSibling *node)
 {
-       WRITE_NODE_TYPE("JSONTABSNODE");
+       WRITE_NODE_TYPE("JSONTABLESIBLING");
 
        WRITE_NODE_FIELD(larg);
        WRITE_NODE_FIELD(rarg);
index ddf76ac778fd9e363b1e196b9016115da0f3f8c2..6a05b694152444118319ff77eaffeb11bc9555d1 100644 (file)
@@ -1484,13 +1484,13 @@ _readJsonConstructorExpr(void)
 {
        READ_LOCALS(JsonConstructorExpr);
 
+       READ_ENUM_FIELD(type, JsonConstructorType);
        READ_NODE_FIELD(args);
        READ_NODE_FIELD(func);
        READ_NODE_FIELD(coercion);
-       READ_INT_FIELD(type);
        READ_NODE_FIELD(returning);
-       READ_BOOL_FIELD(unique);
        READ_BOOL_FIELD(absent_on_null);
+       READ_BOOL_FIELD(unique);
        READ_LOCATION_FIELD(location);
 
        READ_DONE();
@@ -1523,11 +1523,11 @@ _readJsonExpr(void)
        READ_NODE_FIELD(result_coercion);
        READ_NODE_FIELD(format);
        READ_NODE_FIELD(path_spec);
-       READ_NODE_FIELD(passing_values);
        READ_NODE_FIELD(passing_names);
+       READ_NODE_FIELD(passing_values);
        READ_NODE_FIELD(returning);
-       READ_NODE_FIELD(on_error);
        READ_NODE_FIELD(on_empty);
+       READ_NODE_FIELD(on_error);
        READ_NODE_FIELD(coercions);
        READ_ENUM_FIELD(wrapper, JsonWrapper);
        READ_BOOL_FIELD(omit_quotes);
@@ -1547,6 +1547,7 @@ _readJsonTableParent(void)
        READ_BOOL_FIELD(outerJoin);
        READ_INT_FIELD(colMin);
        READ_INT_FIELD(colMax);
+       READ_BOOL_FIELD(errorOnError);
 
        READ_DONE();
 }
@@ -1610,7 +1611,8 @@ _readJsonIsPredicate()
        READ_LOCALS(JsonIsPredicate);
 
        READ_NODE_FIELD(expr);
-       READ_ENUM_FIELD(value_type, JsonValueType);
+       READ_NODE_FIELD(format);
+       READ_ENUM_FIELD(item_type, JsonValueType);
        READ_BOOL_FIELD(unique_keys);
        READ_LOCATION_FIELD(location);
 
@@ -3229,9 +3231,9 @@ parseNodeString(void)
                return_value = _readJsonCoercion();
        else if (MATCH("JSONITEMCOERCIONS", 17))
                return_value = _readJsonItemCoercions();
-       else if (MATCH("JSONTABPNODE", 12))
+       else if (MATCH("JSONTABLEPARENT", 15))
                return_value = _readJsonTableParent();
-       else if (MATCH("JSONTABSNODE", 12))
+       else if (MATCH("JSONTABLESIBLING", 16))
                return_value = _readJsonTableSibling();
        else
        {
index 17709c3416bc62035e3f879940c193f608853176..0dc2fc472e58020821d9f521d555d6d585daf578 100644 (file)
@@ -4018,8 +4018,7 @@ transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format,
 }
 
 /*
- * Transform IS JSON predicate into
- * json[b]_is_valid(json, value_type [, check_key_uniqueness]) call.
+ * Transform IS JSON predicate.
  */
 static Node *
 transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
@@ -4035,7 +4034,8 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
                                 errmsg("cannot use type %s in IS JSON predicate",
                                                format_type_be(exprtype))));
 
-       return makeJsonIsPredicate(expr, NULL, pred->value_type,
+       /* This intentionally(?) drops the format clause. */
+       return makeJsonIsPredicate(expr, NULL, pred->item_type,
                                                           pred->unique_keys, pred->location);
 }
 
index f22ecfc58323d6805e861e163a14dc5e426f8df9..49c4201dde6b2b36b460bb9c86bdb4bdb8541b58 100644 (file)
@@ -9730,7 +9730,9 @@ get_rule_expr(Node *node, deparse_context *context,
 
                                appendStringInfoString(context->buf, " IS JSON");
 
-                               switch (pred->value_type)
+                               /* TODO: handle FORMAT clause */
+
+                               switch (pred->item_type)
                                {
                                        case JS_TYPE_SCALAR:
                                                appendStringInfoString(context->buf, " SCALAR");
index d35027275f173086c297bcb21458d5f6e4d79c74..eeaa0b31fe231dbc5d28399f5646fe7b7e7a4836 100644 (file)
@@ -741,7 +741,7 @@ JumbleExpr(JumbleState *jstate, Node *node)
                        {
                                JsonFormat *format = (JsonFormat *) node;
 
-                               APP_JUMB(format->type);
+                               APP_JUMB(format->format_type);
                                APP_JUMB(format->encoding);
                        }
                        break;
@@ -767,12 +767,13 @@ JumbleExpr(JumbleState *jstate, Node *node)
                        {
                                JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
 
+                               APP_JUMB(ctor->type);
+                               JumbleExpr(jstate, (Node *) ctor->args);
                                JumbleExpr(jstate, (Node *) ctor->func);
                                JumbleExpr(jstate, (Node *) ctor->coercion);
                                JumbleExpr(jstate, (Node *) ctor->returning);
-                               APP_JUMB(ctor->type);
-                               APP_JUMB(ctor->unique);
                                APP_JUMB(ctor->absent_on_null);
+                               APP_JUMB(ctor->unique);
                        }
                        break;
                case T_JsonIsPredicate:
@@ -781,8 +782,8 @@ JumbleExpr(JumbleState *jstate, Node *node)
 
                                JumbleExpr(jstate, (Node *) pred->expr);
                                JumbleExpr(jstate, (Node *) pred->format);
+                               APP_JUMB(pred->item_type);
                                APP_JUMB(pred->unique_keys);
-                               APP_JUMB(pred->value_type);
                        }
                        break;
                case T_JsonExpr:
index 805e870842e70ac4609141d286d494b1177bb03e..2cdcfa667a80165c70ebb136a113103142b7409c 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202205121
+#define CATALOG_VERSION_NO     202205131
 
 #endif
index c717468eb391c3ce18753783c492e80950895ade..06e6369026a4962cfc923a1dcbe3bdef52277458 100644 (file)
@@ -114,7 +114,7 @@ extern Node *makeJsonTableJoinedPlan(JsonTablePlanJoinType type,
                                                                         Node *plan1, Node *plan2, int location);
 extern Node *makeJsonKeyValue(Node *key, Node *value);
 extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format,
-                                                                JsonValueType vtype, bool unique_keys,
+                                                                JsonValueType item_type, bool unique_keys,
                                                                 int location);
 extern JsonEncoding makeJsonEncoding(char *name);
 
index 66e179c4356766d5c8c2d17e4c5217baa2eaa3c1..51505eee85dfff7446defaf4d4e401e96f3f7d1a 100644 (file)
@@ -1387,14 +1387,14 @@ typedef enum JsonValueType
 
 /*
  * JsonIsPredicate -
- *             untransformed representation of IS JSON predicate
+ *             representation of IS JSON predicate
  */
 typedef struct JsonIsPredicate
 {
        NodeTag         type;
-       Node       *expr;                       /* untransformed expression */
+       Node       *expr;                       /* subject expression */
        JsonFormat *format;                     /* FORMAT clause, if specified */
-       JsonValueType value_type;       /* JSON item type */
+       JsonValueType item_type;        /* JSON item type */
        bool            unique_keys;    /* check key uniqueness? */
        int                     location;               /* token location, or -1 if unknown */
 } JsonIsPredicate;