Rename JsonIsPredicate.value_type, fix JSON backend/nodes/ infrastructure.
authorTom Lane
Fri, 13 May 2022 15:40:01 +0000 (11:40 -0400)
committerTom Lane
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;