summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorAndrew Dunstan2022-03-03 18:00:49 +0000
committerAndrew Dunstan2022-03-27 21:03:33 +0000
commitf79b803dcc98d707450e158db3638dc67ff8380b (patch)
treea9c33df51b967eeb99b86af92008f7f0bc1e3d6e /src/backend/utils
parentb64c3bd62ea7064a1a36fbd921e8955fa76faa3e (diff)
Common SQL/JSON clauses
This introduces some of the building blocks used by the SQL/JSON constructor and query functions. Specifically, it provides node executor and grammar support for the FORMAT JSON [ENCODING foo] clause, and values decorated with it, and for the RETURNING clause. The following SQL/JSON patches will leverage these. Nikita Glukhov (who probably deserves an award for perseverance). Reviewers have included (in no particular order) Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby. Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/ruleutils.c56
-rw-r--r--src/backend/utils/misc/queryjumble.c26
2 files changed, 82 insertions, 0 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 7f4f3f73699..c7860a75801 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8266,6 +8266,11 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
return false;
}
+ case T_JsonValueExpr:
+ /* maybe simple, check args */
+ return isSimpleNode((Node *) ((JsonValueExpr *) node)->raw_expr,
+ node, prettyFlags);
+
default:
break;
}
@@ -8371,6 +8376,48 @@ get_rule_expr_paren(Node *node, deparse_context *context,
appendStringInfoChar(context->buf, ')');
}
+/*
+ * get_json_format - Parse back a JsonFormat node
+ */
+static void
+get_json_format(JsonFormat *format, deparse_context *context)
+{
+ if (format->format_type == JS_FORMAT_DEFAULT)
+ return;
+
+ appendStringInfoString(context->buf,
+ format->format_type == JS_FORMAT_JSONB ?
+ " FORMAT JSONB" : " FORMAT JSON");
+
+ if (format->encoding != JS_ENC_DEFAULT)
+ {
+ const char *encoding =
+ format->encoding == JS_ENC_UTF16 ? "UTF16" :
+ format->encoding == JS_ENC_UTF32 ? "UTF32" : "UTF8";
+
+ appendStringInfo(context->buf, " ENCODING %s", encoding);
+ }
+}
+
+/*
+ * get_json_returning - Parse back a JsonReturning structure
+ */
+static void
+get_json_returning(JsonReturning *returning, deparse_context *context,
+ bool json_format_by_default)
+{
+ if (!OidIsValid(returning->typid))
+ return;
+
+ appendStringInfo(context->buf, " RETURNING %s",
+ format_type_with_typemod(returning->typid,
+ returning->typmod));
+
+ if (!json_format_by_default ||
+ returning->format->format_type !=
+ (returning->typid == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON))
+ get_json_format(returning->format, context);
+}
/* ----------
* get_rule_expr - Parse back an expression
@@ -9531,6 +9578,15 @@ get_rule_expr(Node *node, deparse_context *context,
}
break;
+ case T_JsonValueExpr:
+ {
+ JsonValueExpr *jve = (JsonValueExpr *) node;
+
+ get_rule_expr((Node *) jve->raw_expr, context, false);
+ get_json_format(jve->format, context);
+ }
+ break;
+
case T_List:
{
char *sep;
diff --git a/src/backend/utils/misc/queryjumble.c b/src/backend/utils/misc/queryjumble.c
index a67487e5fe8..84435420e4c 100644
--- a/src/backend/utils/misc/queryjumble.c
+++ b/src/backend/utils/misc/queryjumble.c
@@ -737,6 +737,32 @@ JumbleExpr(JumbleState *jstate, Node *node)
JumbleExpr(jstate, (Node *) conf->exclRelTlist);
}
break;
+ case T_JsonFormat:
+ {
+ JsonFormat *format = (JsonFormat *) node;
+
+ APP_JUMB(format->type);
+ APP_JUMB(format->encoding);
+ }
+ break;
+ case T_JsonReturning:
+ {
+ JsonReturning *returning = (JsonReturning *) node;
+
+ JumbleExpr(jstate, (Node *) returning->format);
+ APP_JUMB(returning->typid);
+ APP_JUMB(returning->typmod);
+ }
+ break;
+ case T_JsonValueExpr:
+ {
+ JsonValueExpr *expr = (JsonValueExpr *) node;
+
+ JumbleExpr(jstate, (Node *) expr->raw_expr);
+ JumbleExpr(jstate, (Node *) expr->formatted_expr);
+ JumbleExpr(jstate, (Node *) expr->format);
+ }
+ break;
case T_List:
foreach(temp, (List *) node)
{