summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/copyfuncs.c150
-rw-r--r--src/backend/nodes/equalfuncs.c127
-rw-r--r--src/backend/nodes/makefuncs.c15
-rw-r--r--src/backend/nodes/nodeFuncs.c186
-rw-r--r--src/backend/nodes/outfuncs.c70
-rw-r--r--src/backend/nodes/readfuncs.c86
6 files changed, 633 insertions, 1 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index cb4b4d01f8..c42d2ed814 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2492,6 +2492,90 @@ _copyJsonArrayQueryConstructor(const JsonArrayQueryConstructor *from)
}
/*
+ * _copyJsonExpr
+ */
+static JsonExpr *
+_copyJsonExpr(const JsonExpr *from)
+{
+ JsonExpr *newnode = makeNode(JsonExpr);
+
+ COPY_SCALAR_FIELD(op);
+ COPY_NODE_FIELD(formatted_expr);
+ 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(returning);
+ COPY_NODE_FIELD(on_error);
+ COPY_NODE_FIELD(on_empty);
+ COPY_NODE_FIELD(coercions);
+ COPY_SCALAR_FIELD(wrapper);
+ COPY_SCALAR_FIELD(omit_quotes);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+/*
+ * _copyJsonCoercion
+ */
+static JsonCoercion *
+_copyJsonCoercion(const JsonCoercion *from)
+{
+ JsonCoercion *newnode = makeNode(JsonCoercion);
+
+ COPY_NODE_FIELD(expr);
+ COPY_SCALAR_FIELD(via_populate);
+ COPY_SCALAR_FIELD(via_io);
+ COPY_SCALAR_FIELD(collation);
+
+ return newnode;
+}
+
+/*
+ * _copyJsonItemCoercions
+ */
+static JsonItemCoercions *
+_copyJsonItemCoercions(const JsonItemCoercions *from)
+{
+ JsonItemCoercions *newnode = makeNode(JsonItemCoercions);
+
+ COPY_NODE_FIELD(null);
+ COPY_NODE_FIELD(string);
+ COPY_NODE_FIELD(numeric);
+ COPY_NODE_FIELD(boolean);
+ COPY_NODE_FIELD(date);
+ COPY_NODE_FIELD(time);
+ COPY_NODE_FIELD(timetz);
+ COPY_NODE_FIELD(timestamp);
+ COPY_NODE_FIELD(timestamptz);
+ COPY_NODE_FIELD(composite);
+
+ return newnode;
+}
+
+/*
+ * _copyJsonFuncExpr
+ */
+static JsonFuncExpr *
+_copyJsonFuncExpr(const JsonFuncExpr *from)
+{
+ JsonFuncExpr *newnode = makeNode(JsonFuncExpr);
+
+ COPY_SCALAR_FIELD(op);
+ COPY_NODE_FIELD(common);
+ COPY_NODE_FIELD(output);
+ COPY_NODE_FIELD(on_empty);
+ COPY_NODE_FIELD(on_error);
+ COPY_SCALAR_FIELD(wrapper);
+ COPY_SCALAR_FIELD(omit_quotes);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+/*
* _copyJsonIsPredicate
*/
static JsonIsPredicate *
@@ -2508,6 +2592,51 @@ _copyJsonIsPredicate(const JsonIsPredicate *from)
return newnode;
}
+/*
+ * _copyJsonBehavior
+ */
+static JsonBehavior *
+_copyJsonBehavior(const JsonBehavior *from)
+{
+ JsonBehavior *newnode = makeNode(JsonBehavior);
+
+ COPY_SCALAR_FIELD(btype);
+ COPY_NODE_FIELD(default_expr);
+
+ return newnode;
+}
+
+/*
+ * _copyJsonCommon
+ */
+static JsonCommon *
+_copyJsonCommon(const JsonCommon *from)
+{
+ JsonCommon *newnode = makeNode(JsonCommon);
+
+ COPY_NODE_FIELD(expr);
+ COPY_NODE_FIELD(pathspec);
+ COPY_STRING_FIELD(pathname);
+ COPY_NODE_FIELD(passing);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+/*
+ * _copyJsonArgument
+ */
+static JsonArgument *
+_copyJsonArgument(const JsonArgument *from)
+{
+ JsonArgument *newnode = makeNode(JsonArgument);
+
+ COPY_NODE_FIELD(val);
+ COPY_STRING_FIELD(name);
+
+ return newnode;
+}
+
/* ****************************************************************
* pathnodes.h copy functions
*
@@ -5645,6 +5774,27 @@ copyObjectImpl(const void *from)
case T_JsonIsPredicate:
retval = _copyJsonIsPredicate(from);
break;
+ case T_JsonFuncExpr:
+ retval = _copyJsonFuncExpr(from);
+ break;
+ case T_JsonExpr:
+ retval = _copyJsonExpr(from);
+ break;
+ case T_JsonCommon:
+ retval = _copyJsonCommon(from);
+ break;
+ case T_JsonBehavior:
+ retval = _copyJsonBehavior(from);
+ break;
+ case T_JsonArgument:
+ retval = _copyJsonArgument(from);
+ break;
+ case T_JsonCoercion:
+ retval = _copyJsonCoercion(from);
+ break;
+ case T_JsonItemCoercions:
+ retval = _copyJsonItemCoercions(from);
+ break;
/*
* RELATION NODES
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 084d98b34c..f6dd61370c 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -977,6 +977,42 @@ _equalJsonArrayQueryConstructor(const JsonArrayQueryConstructor *a,
}
static bool
+_equalJsonFuncExpr(const JsonFuncExpr *a, const JsonFuncExpr *b)
+{
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_NODE_FIELD(common);
+ COMPARE_NODE_FIELD(output);
+ COMPARE_NODE_FIELD(on_empty);
+ COMPARE_NODE_FIELD(on_error);
+ COMPARE_SCALAR_FIELD(wrapper);
+ COMPARE_SCALAR_FIELD(omit_quotes);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalJsonCommon(const JsonCommon *a, const JsonCommon *b)
+{
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_NODE_FIELD(pathspec);
+ COMPARE_STRING_FIELD(pathname);
+ COMPARE_NODE_FIELD(passing);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalJsonArgument(const JsonArgument *a, const JsonArgument *b)
+{
+ COMPARE_NODE_FIELD(val);
+ COMPARE_STRING_FIELD(name);
+
+ return true;
+}
+
+static bool
_equalJsonIsPredicate(const JsonIsPredicate *a,
const JsonIsPredicate *b)
{
@@ -989,6 +1025,76 @@ _equalJsonIsPredicate(const JsonIsPredicate *a,
}
/*
+ * _equalJsonBehavior
+ */
+static bool
+_equalJsonBehavior(const JsonBehavior *a, const JsonBehavior *b)
+{
+ COMPARE_SCALAR_FIELD(btype);
+ COMPARE_NODE_FIELD(default_expr);
+
+ return true;
+}
+
+/*
+ * _equalJsonExpr
+ */
+static bool
+_equalJsonExpr(const JsonExpr *a, const JsonExpr *b)
+{
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_NODE_FIELD(formatted_expr);
+ 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(returning);
+ COMPARE_NODE_FIELD(on_error);
+ COMPARE_NODE_FIELD(on_empty);
+ COMPARE_NODE_FIELD(coercions);
+ COMPARE_SCALAR_FIELD(wrapper);
+ COMPARE_SCALAR_FIELD(omit_quotes);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+/*
+ * _equalJsonCoercion
+ */
+static bool
+_equalJsonCoercion(const JsonCoercion *a, const JsonCoercion *b)
+{
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_SCALAR_FIELD(via_populate);
+ COMPARE_SCALAR_FIELD(via_io);
+ COMPARE_SCALAR_FIELD(collation);
+
+ return true;
+}
+
+/*
+ * _equalJsonItemCoercions
+ */
+static bool
+_equalJsonItemCoercions(const JsonItemCoercions *a, const JsonItemCoercions *b)
+{
+ COMPARE_NODE_FIELD(null);
+ COMPARE_NODE_FIELD(string);
+ COMPARE_NODE_FIELD(numeric);
+ COMPARE_NODE_FIELD(boolean);
+ COMPARE_NODE_FIELD(date);
+ COMPARE_NODE_FIELD(time);
+ COMPARE_NODE_FIELD(timetz);
+ COMPARE_NODE_FIELD(timestamp);
+ COMPARE_NODE_FIELD(timestamptz);
+ COMPARE_NODE_FIELD(composite);
+
+ return true;
+}
+
+/*
* Stuff from pathnodes.h
*/
@@ -3561,6 +3667,18 @@ equal(const void *a, const void *b)
case T_JsonIsPredicate:
retval = _equalJsonIsPredicate(a, b);
break;
+ case T_JsonBehavior:
+ retval = _equalJsonBehavior(a, b);
+ break;
+ case T_JsonExpr:
+ retval = _equalJsonExpr(a, b);
+ break;
+ case T_JsonCoercion:
+ retval = _equalJsonCoercion(a, b);
+ break;
+ case T_JsonItemCoercions:
+ retval = _equalJsonItemCoercions(a, b);
+ break;
/*
* RELATION NODES
@@ -4174,6 +4292,15 @@ equal(const void *a, const void *b)
case T_JsonArrayAgg:
retval = _equalJsonArrayAgg(a, b);
break;
+ case T_JsonFuncExpr:
+ retval = _equalJsonFuncExpr(a, b);
+ break;
+ case T_JsonCommon:
+ retval = _equalJsonCommon(a, b);
+ break;
+ case T_JsonArgument:
+ retval = _equalJsonArgument(a, b);
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index b67e7c5297..cd6c300e7b 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -853,6 +853,21 @@ makeJsonValueExpr(Expr *expr, JsonFormat *format)
}
/*
+ * makeJsonBehavior -
+ * creates a JsonBehavior node
+ */
+JsonBehavior *
+makeJsonBehavior(JsonBehaviorType type, Node *default_expr)
+{
+ JsonBehavior *behavior = makeNode(JsonBehavior);
+
+ behavior->btype = type;
+ behavior->default_expr = default_expr;
+
+ return behavior;
+}
+
+/*
* makeJsonEncoding -
* converts JSON encoding name to enum JsonEncoding
*/
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index d697c7abd8..c0a83471e1 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -263,6 +263,12 @@ exprType(const Node *expr)
case T_JsonIsPredicate:
type = BOOLOID;
break;
+ case T_JsonExpr:
+ type = ((const JsonExpr *) expr)->returning->typid;
+ break;
+ case T_JsonCoercion:
+ type = exprType(((const JsonCoercion *) expr)->expr);
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
type = InvalidOid; /* keep compiler quiet */
@@ -498,7 +504,11 @@ exprTypmod(const Node *expr)
case T_JsonValueExpr:
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
case T_JsonConstructorExpr:
- return -1; /* ((const JsonConstructorExpr *) expr)->returning->typmod; */
+ return ((const JsonConstructorExpr *) expr)->returning->typmod;
+ case T_JsonExpr:
+ return ((JsonExpr *) expr)->returning->typmod;
+ case T_JsonCoercion:
+ return exprTypmod(((const JsonCoercion *) expr)->expr);
default:
break;
}
@@ -991,6 +1001,21 @@ exprCollation(const Node *expr)
case T_JsonIsPredicate:
coll = InvalidOid; /* result is always an boolean type */
break;
+ case T_JsonExpr:
+ {
+ JsonExpr *jexpr = (JsonExpr *) expr;
+ JsonCoercion *coercion = jexpr->result_coercion;
+
+ if (!coercion)
+ coll = InvalidOid;
+ else if (coercion->expr)
+ coll = exprCollation(coercion->expr);
+ else if (coercion->via_io || coercion->via_populate)
+ coll = coercion->collation;
+ else
+ coll = InvalidOid;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
coll = InvalidOid; /* keep compiler quiet */
@@ -1220,6 +1245,21 @@ exprSetCollation(Node *expr, Oid collation)
case T_JsonIsPredicate:
Assert(!OidIsValid(collation)); /* result is always boolean */
break;
+ case T_JsonExpr:
+ {
+ JsonExpr *jexpr = (JsonExpr *) expr;
+ JsonCoercion *coercion = jexpr->result_coercion;
+
+ if (!coercion)
+ Assert(!OidIsValid(collation));
+ else if (coercion->expr)
+ exprSetCollation(coercion->expr, collation);
+ else if (coercion->via_io || coercion->via_populate)
+ coercion->collation = collation;
+ else
+ Assert(!OidIsValid(collation));
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
break;
@@ -1675,6 +1715,15 @@ exprLocation(const Node *expr)
case T_JsonIsPredicate:
loc = ((const JsonIsPredicate *) expr)->location;
break;
+ case T_JsonExpr:
+ {
+ const JsonExpr *jsexpr = (const JsonExpr *) expr;
+
+ /* consider both function name and leftmost arg */
+ loc = leftmostLoc(jsexpr->location,
+ exprLocation(jsexpr->formatted_expr));
+ }
+ break;
default:
/* for any other node type it's just unknown... */
loc = -1;
@@ -2443,6 +2492,54 @@ expression_tree_walker(Node *node,
break;
case T_JsonIsPredicate:
return walker(((JsonIsPredicate *) node)->expr, context);
+ case T_JsonExpr:
+ {
+ JsonExpr *jexpr = (JsonExpr *) node;
+
+ if (walker(jexpr->formatted_expr, context))
+ return true;
+ if (walker(jexpr->result_coercion, context))
+ return true;
+ if (walker(jexpr->passing_values, context))
+ return true;
+ /* we assume walker doesn't care about passing_names */
+ if (jexpr->on_empty &&
+ walker(jexpr->on_empty->default_expr, context))
+ return true;
+ if (walker(jexpr->on_error->default_expr, context))
+ return true;
+ if (walker(jexpr->coercions, context))
+ return true;
+ }
+ break;
+ case T_JsonCoercion:
+ return walker(((JsonCoercion *) node)->expr, context);
+ case T_JsonItemCoercions:
+ {
+ JsonItemCoercions *coercions = (JsonItemCoercions *) node;
+
+ if (walker(coercions->null, context))
+ return true;
+ if (walker(coercions->string, context))
+ return true;
+ if (walker(coercions->numeric, context))
+ return true;
+ if (walker(coercions->boolean, context))
+ return true;
+ if (walker(coercions->date, context))
+ return true;
+ if (walker(coercions->time, context))
+ return true;
+ if (walker(coercions->timetz, context))
+ return true;
+ if (walker(coercions->timestamp, context))
+ return true;
+ if (walker(coercions->timestamptz, context))
+ return true;
+ if (walker(coercions->composite, context))
+ return true;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -3454,6 +3551,7 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
+ break;
case T_JsonIsPredicate:
{
JsonIsPredicate *pred = (JsonIsPredicate *) node;
@@ -3464,6 +3562,55 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
+ break;
+ case T_JsonExpr:
+ {
+ JsonExpr *jexpr = (JsonExpr *) node;
+ JsonExpr *newnode;
+
+ FLATCOPY(newnode, jexpr, JsonExpr);
+ MUTATE(newnode->path_spec, jexpr->path_spec, Node *);
+ MUTATE(newnode->formatted_expr, jexpr->formatted_expr, Node *);
+ MUTATE(newnode->result_coercion, jexpr->result_coercion, JsonCoercion *);
+ MUTATE(newnode->passing_values, jexpr->passing_values, List *);
+ /* assume mutator does not care about passing_names */
+ if (newnode->on_empty)
+ MUTATE(newnode->on_empty->default_expr,
+ jexpr->on_empty->default_expr, Node *);
+ MUTATE(newnode->on_error->default_expr,
+ jexpr->on_error->default_expr, Node *);
+ return (Node *) newnode;
+ }
+ break;
+ case T_JsonCoercion:
+ {
+ JsonCoercion *coercion = (JsonCoercion *) node;
+ JsonCoercion *newnode;
+
+ FLATCOPY(newnode, coercion, JsonCoercion);
+ MUTATE(newnode->expr, coercion->expr, Node *);
+ return (Node *) newnode;
+ }
+ break;
+ case T_JsonItemCoercions:
+ {
+ JsonItemCoercions *coercions = (JsonItemCoercions *) node;
+ JsonItemCoercions *newnode;
+
+ FLATCOPY(newnode, coercions, JsonItemCoercions);
+ MUTATE(newnode->null, coercions->null, JsonCoercion *);
+ MUTATE(newnode->string, coercions->string, JsonCoercion *);
+ MUTATE(newnode->numeric, coercions->numeric, JsonCoercion *);
+ MUTATE(newnode->boolean, coercions->boolean, JsonCoercion *);
+ MUTATE(newnode->date, coercions->date, JsonCoercion *);
+ MUTATE(newnode->time, coercions->time, JsonCoercion *);
+ MUTATE(newnode->timetz, coercions->timetz, JsonCoercion *);
+ MUTATE(newnode->timestamp, coercions->timestamp, JsonCoercion *);
+ MUTATE(newnode->timestamptz, coercions->timestamptz, JsonCoercion *);
+ MUTATE(newnode->composite, coercions->composite, JsonCoercion *);
+ return (Node *) newnode;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -4316,6 +4463,43 @@ raw_expression_tree_walker(Node *node,
break;
case T_JsonIsPredicate:
return walker(((JsonIsPredicate *) node)->expr, context);
+ case T_JsonArgument:
+ return walker(((JsonArgument *) node)->val, context);
+ case T_JsonCommon:
+ {
+ JsonCommon *jc = (JsonCommon *) node;
+
+ if (walker(jc->expr, context))
+ return true;
+ if (walker(jc->pathspec, context))
+ return true;
+ if (walker(jc->passing, context))
+ return true;
+ }
+ break;
+ case T_JsonBehavior:
+ {
+ JsonBehavior *jb = (JsonBehavior *) node;
+
+ if (jb->btype == JSON_BEHAVIOR_DEFAULT &&
+ walker(jb->default_expr, context))
+ return true;
+ }
+ break;
+ case T_JsonFuncExpr:
+ {
+ JsonFuncExpr *jfe = (JsonFuncExpr *) node;
+
+ if (walker(jfe->common, context))
+ return true;
+ if (jfe->output && walker(jfe->output, context))
+ return true;
+ if (walker(jfe->on_empty, context))
+ return true;
+ if (walker(jfe->on_error, context))
+ return true;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 278e87259d..6e39590730 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1808,6 +1808,64 @@ _outJsonIsPredicate(StringInfo str, const JsonIsPredicate *node)
WRITE_LOCATION_FIELD(location);
}
+static void
+_outJsonBehavior(StringInfo str, const JsonBehavior *node)
+{
+ WRITE_NODE_TYPE("JSONBEHAVIOR");
+
+ WRITE_ENUM_FIELD(btype, JsonBehaviorType);
+ WRITE_NODE_FIELD(default_expr);
+}
+
+static void
+_outJsonExpr(StringInfo str, const JsonExpr *node)
+{
+ WRITE_NODE_TYPE("JSONEXPR");
+
+ WRITE_ENUM_FIELD(op, JsonExprOp);
+ WRITE_NODE_FIELD(formatted_expr);
+ 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(returning);
+ WRITE_NODE_FIELD(on_error);
+ WRITE_NODE_FIELD(on_empty);
+ WRITE_NODE_FIELD(coercions);
+ WRITE_ENUM_FIELD(wrapper, JsonWrapper);
+ WRITE_BOOL_FIELD(omit_quotes);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outJsonCoercion(StringInfo str, const JsonCoercion *node)
+{
+ WRITE_NODE_TYPE("JSONCOERCION");
+
+ WRITE_NODE_FIELD(expr);
+ WRITE_BOOL_FIELD(via_populate);
+ WRITE_BOOL_FIELD(via_io);
+ WRITE_OID_FIELD(collation);
+}
+
+static void
+_outJsonItemCoercions(StringInfo str, const JsonItemCoercions *node)
+{
+ WRITE_NODE_TYPE("JSONITEMCOERCIONS");
+
+ WRITE_NODE_FIELD(null);
+ WRITE_NODE_FIELD(string);
+ WRITE_NODE_FIELD(numeric);
+ WRITE_NODE_FIELD(boolean);
+ WRITE_NODE_FIELD(date);
+ WRITE_NODE_FIELD(time);
+ WRITE_NODE_FIELD(timetz);
+ WRITE_NODE_FIELD(timestamp);
+ WRITE_NODE_FIELD(timestamptz);
+ WRITE_NODE_FIELD(composite);
+}
+
/*****************************************************************************
*
* Stuff from pathnodes.h.
@@ -4644,6 +4702,18 @@ outNode(StringInfo str, const void *obj)
case T_JsonIsPredicate:
_outJsonIsPredicate(str, obj);
break;
+ case T_JsonBehavior:
+ _outJsonBehavior(str, obj);
+ break;
+ case T_JsonExpr:
+ _outJsonExpr(str, obj);
+ break;
+ case T_JsonCoercion:
+ _outJsonCoercion(str, obj);
+ break;
+ case T_JsonItemCoercions:
+ _outJsonItemCoercions(str, obj);
+ break;
default:
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 5b9e235e9a..c94b2561f0 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1493,6 +1493,84 @@ _readJsonConstructorExpr(void)
}
/*
+ * _readJsonBehavior
+ */
+static JsonBehavior *
+_readJsonBehavior(void)
+{
+ READ_LOCALS(JsonBehavior);
+
+ READ_ENUM_FIELD(btype, JsonBehaviorType);
+ READ_NODE_FIELD(default_expr);
+
+ READ_DONE();
+}
+
+/*
+ * _readJsonExpr
+ */
+static JsonExpr *
+_readJsonExpr(void)
+{
+ READ_LOCALS(JsonExpr);
+
+ READ_ENUM_FIELD(op, JsonExprOp);
+ READ_NODE_FIELD(formatted_expr);
+ 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(returning);
+ READ_NODE_FIELD(on_error);
+ READ_NODE_FIELD(on_empty);
+ READ_NODE_FIELD(coercions);
+ READ_ENUM_FIELD(wrapper, JsonWrapper);
+ READ_BOOL_FIELD(omit_quotes);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readJsonCoercion
+ */
+static JsonCoercion *
+_readJsonCoercion(void)
+{
+ READ_LOCALS(JsonCoercion);
+
+ READ_NODE_FIELD(expr);
+ READ_BOOL_FIELD(via_populate);
+ READ_BOOL_FIELD(via_io);
+ READ_OID_FIELD(collation);
+
+ READ_DONE();
+}
+
+/*
+ * _readJsonItemCoercions
+ */
+static JsonItemCoercions *
+_readJsonItemCoercions(void)
+{
+ READ_LOCALS(JsonItemCoercions);
+
+ READ_NODE_FIELD(null);
+ READ_NODE_FIELD(string);
+ READ_NODE_FIELD(numeric);
+ READ_NODE_FIELD(boolean);
+ READ_NODE_FIELD(date);
+ READ_NODE_FIELD(time);
+ READ_NODE_FIELD(timetz);
+ READ_NODE_FIELD(timestamp);
+ READ_NODE_FIELD(timestamptz);
+ READ_NODE_FIELD(composite);
+
+ READ_DONE();
+}
+
+/*
* _readJsonIsPredicate
*/
static JsonIsPredicate *
@@ -3108,6 +3186,14 @@ parseNodeString(void)
return_value = _readJsonConstructorExpr();
else if (MATCH("JSONISPREDICATE", 15))
return_value = _readJsonIsPredicate();
+ else if (MATCH("JSONBEHAVIOR", 12))
+ return_value = _readJsonBehavior();
+ else if (MATCH("JSONEXPR", 8))
+ return_value = _readJsonExpr();
+ else if (MATCH("JSONCOERCION", 12))
+ return_value = _readJsonCoercion();
+ else if (MATCH("JSONITEMCOERCIONS", 17))
+ return_value = _readJsonItemCoercions();
else
{
elog(ERROR, "badly formatted node string \"%.32s\"...", token);