Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 865fe4d

Browse files
committed
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 and Himanshu Upadhyaya. Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
1 parent a3b071b commit 865fe4d

File tree

17 files changed

+758
-2
lines changed

17 files changed

+758
-2
lines changed

src/backend/executor/execExpr.c

+22
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,28 @@ ExecInitExprRec(Expr *node, ExprState *state,
24282428
break;
24292429
}
24302430

2431+
case T_JsonValueExpr:
2432+
{
2433+
JsonValueExpr *jve = (JsonValueExpr *) node;
2434+
2435+
ExecInitExprRec(jve->raw_expr, state, resv, resnull);
2436+
2437+
if (jve->formatted_expr)
2438+
{
2439+
Datum *innermost_caseval = state->innermost_caseval;
2440+
bool *innermost_isnull = state->innermost_casenull;
2441+
2442+
state->innermost_caseval = resv;
2443+
state->innermost_casenull = resnull;
2444+
2445+
ExecInitExprRec(jve->formatted_expr, state, resv, resnull);
2446+
2447+
state->innermost_caseval = innermost_caseval;
2448+
state->innermost_casenull = innermost_isnull;
2449+
}
2450+
break;
2451+
}
2452+
24312453
default:
24322454
elog(ERROR, "unrecognized node type: %d",
24332455
(int) nodeTag(node));

src/backend/nodes/copyfuncs.c

+55
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,52 @@ _copyOnConflictExpr(const OnConflictExpr *from)
22982298
return newnode;
22992299
}
23002300

2301+
2302+
/*
2303+
* _copyJsonFormat
2304+
*/
2305+
static JsonFormat *
2306+
_copyJsonFormat(const JsonFormat *from)
2307+
{
2308+
JsonFormat *newnode = makeNode(JsonFormat);
2309+
2310+
COPY_SCALAR_FIELD(format_type);
2311+
COPY_SCALAR_FIELD(encoding);
2312+
COPY_LOCATION_FIELD(location);
2313+
2314+
return newnode;
2315+
}
2316+
2317+
/*
2318+
* _copyJsonReturning
2319+
*/
2320+
static JsonReturning *
2321+
_copyJsonReturning(const JsonReturning *from)
2322+
{
2323+
JsonReturning *newnode = makeNode(JsonReturning);
2324+
2325+
COPY_NODE_FIELD(format);
2326+
COPY_SCALAR_FIELD(typid);
2327+
COPY_SCALAR_FIELD(typmod);
2328+
2329+
return newnode;
2330+
}
2331+
2332+
/*
2333+
* _copyJsonValueExpr
2334+
*/
2335+
static JsonValueExpr *
2336+
_copyJsonValueExpr(const JsonValueExpr *from)
2337+
{
2338+
JsonValueExpr *newnode = makeNode(JsonValueExpr);
2339+
2340+
COPY_NODE_FIELD(raw_expr);
2341+
COPY_NODE_FIELD(formatted_expr);
2342+
COPY_NODE_FIELD(format);
2343+
2344+
return newnode;
2345+
}
2346+
23012347
/* ****************************************************************
23022348
* pathnodes.h copy functions
23032349
*
@@ -5350,6 +5396,15 @@ copyObjectImpl(const void *from)
53505396
case T_OnConflictExpr:
53515397
retval = _copyOnConflictExpr(from);
53525398
break;
5399+
case T_JsonFormat:
5400+
retval = _copyJsonFormat(from);
5401+
break;
5402+
case T_JsonReturning:
5403+
retval = _copyJsonReturning(from);
5404+
break;
5405+
case T_JsonValueExpr:
5406+
retval = _copyJsonValueExpr(from);
5407+
break;
53535408

53545409
/*
53555410
* RELATION NODES

src/backend/nodes/equalfuncs.c

+39
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,36 @@ _equalOnConflictExpr(const OnConflictExpr *a, const OnConflictExpr *b)
841841
return true;
842842
}
843843

844+
static bool
845+
_equalJsonFormat(const JsonFormat *a, const JsonFormat *b)
846+
{
847+
COMPARE_SCALAR_FIELD(format_type);
848+
COMPARE_SCALAR_FIELD(encoding);
849+
COMPARE_LOCATION_FIELD(location);
850+
851+
return true;
852+
}
853+
854+
static bool
855+
_equalJsonReturning(const JsonReturning *a, const JsonReturning *b)
856+
{
857+
COMPARE_NODE_FIELD(format);
858+
COMPARE_SCALAR_FIELD(typid);
859+
COMPARE_SCALAR_FIELD(typmod);
860+
861+
return true;
862+
}
863+
864+
static bool
865+
_equalJsonValueExpr(const JsonValueExpr *a, const JsonValueExpr *b)
866+
{
867+
COMPARE_NODE_FIELD(raw_expr);
868+
COMPARE_NODE_FIELD(formatted_expr);
869+
COMPARE_NODE_FIELD(format);
870+
871+
return true;
872+
}
873+
844874
/*
845875
* Stuff from pathnodes.h
846876
*/
@@ -3358,6 +3388,15 @@ equal(const void *a, const void *b)
33583388
case T_JoinExpr:
33593389
retval = _equalJoinExpr(a, b);
33603390
break;
3391+
case T_JsonFormat:
3392+
retval = _equalJsonFormat(a, b);
3393+
break;
3394+
case T_JsonReturning:
3395+
retval = _equalJsonReturning(a, b);
3396+
break;
3397+
case T_JsonValueExpr:
3398+
retval = _equalJsonValueExpr(a, b);
3399+
break;
33613400

33623401
/*
33633402
* RELATION NODES

src/backend/nodes/makefuncs.c

+54
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "catalog/pg_type.h"
2020
#include "nodes/makefuncs.h"
2121
#include "nodes/nodeFuncs.h"
22+
#include "utils/errcodes.h"
2223
#include "utils/lsyscache.h"
2324

2425

@@ -818,3 +819,56 @@ makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
818819
v->va_cols = va_cols;
819820
return v;
820821
}
822+
823+
/*
824+
* makeJsonFormat -
825+
* creates a JsonFormat node
826+
*/
827+
JsonFormat *
828+
makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
829+
{
830+
JsonFormat *jf = makeNode(JsonFormat);
831+
832+
jf->format_type = type;
833+
jf->encoding = encoding;
834+
jf->location = location;
835+
836+
return jf;
837+
}
838+
839+
/*
840+
* makeJsonValueExpr -
841+
* creates a JsonValueExpr node
842+
*/
843+
JsonValueExpr *
844+
makeJsonValueExpr(Expr *expr, JsonFormat *format)
845+
{
846+
JsonValueExpr *jve = makeNode(JsonValueExpr);
847+
848+
jve->raw_expr = expr;
849+
jve->formatted_expr = NULL;
850+
jve->format = format;
851+
852+
return jve;
853+
}
854+
855+
/*
856+
* makeJsonEncoding -
857+
* converts JSON encoding name to enum JsonEncoding
858+
*/
859+
JsonEncoding
860+
makeJsonEncoding(char *name)
861+
{
862+
if (!pg_strcasecmp(name, "utf8"))
863+
return JS_ENC_UTF8;
864+
if (!pg_strcasecmp(name, "utf16"))
865+
return JS_ENC_UTF16;
866+
if (!pg_strcasecmp(name, "utf32"))
867+
return JS_ENC_UTF32;
868+
869+
ereport(ERROR,
870+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
871+
errmsg("unrecognized JSON encoding: %s", name)));
872+
873+
return JS_ENC_DEFAULT;
874+
}

src/backend/nodes/nodeFuncs.c

+66
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ exprType(const Node *expr)
250250
case T_PlaceHolderVar:
251251
type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
252252
break;
253+
case T_JsonValueExpr:
254+
{
255+
const JsonValueExpr *jve = (const JsonValueExpr *) expr;
256+
257+
type = exprType((Node *) (jve->formatted_expr ? jve->formatted_expr : jve->raw_expr));
258+
}
259+
break;
253260
default:
254261
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
255262
type = InvalidOid; /* keep compiler quiet */
@@ -482,6 +489,8 @@ exprTypmod(const Node *expr)
482489
return ((const SetToDefault *) expr)->typeMod;
483490
case T_PlaceHolderVar:
484491
return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
492+
case T_JsonValueExpr:
493+
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
485494
default:
486495
break;
487496
}
@@ -958,6 +967,9 @@ exprCollation(const Node *expr)
958967
case T_PlaceHolderVar:
959968
coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
960969
break;
970+
case T_JsonValueExpr:
971+
coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
972+
break;
961973
default:
962974
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
963975
coll = InvalidOid; /* keep compiler quiet */
@@ -1170,6 +1182,10 @@ exprSetCollation(Node *expr, Oid collation)
11701182
/* NextValueExpr's result is an integer type ... */
11711183
Assert(!OidIsValid(collation)); /* ... so never set a collation */
11721184
break;
1185+
case T_JsonValueExpr:
1186+
exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
1187+
collation);
1188+
break;
11731189
default:
11741190
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
11751191
break;
@@ -1616,6 +1632,9 @@ exprLocation(const Node *expr)
16161632
case T_PartitionRangeDatum:
16171633
loc = ((const PartitionRangeDatum *) expr)->location;
16181634
break;
1635+
case T_JsonValueExpr:
1636+
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
1637+
break;
16191638
default:
16201639
/* for any other node type it's just unknown... */
16211640
loc = -1;
@@ -2350,6 +2369,16 @@ expression_tree_walker(Node *node,
23502369
return true;
23512370
}
23522371
break;
2372+
case T_JsonValueExpr:
2373+
{
2374+
JsonValueExpr *jve = (JsonValueExpr *) node;
2375+
2376+
if (walker(jve->raw_expr, context))
2377+
return true;
2378+
if (walker(jve->formatted_expr, context))
2379+
return true;
2380+
}
2381+
break;
23532382
default:
23542383
elog(ERROR, "unrecognized node type: %d",
23552384
(int) nodeTag(node));
@@ -2680,6 +2709,7 @@ expression_tree_mutator(Node *node,
26802709
case T_RangeTblRef:
26812710
case T_SortGroupClause:
26822711
case T_CTESearchClause:
2712+
case T_JsonFormat:
26832713
return (Node *) copyObject(node);
26842714
case T_WithCheckOption:
26852715
{
@@ -3311,6 +3341,28 @@ expression_tree_mutator(Node *node,
33113341
return (Node *) newnode;
33123342
}
33133343
break;
3344+
case T_JsonReturning:
3345+
{
3346+
JsonReturning *jr = (JsonReturning *) node;
3347+
JsonReturning *newnode;
3348+
3349+
FLATCOPY(newnode, jr, JsonReturning);
3350+
MUTATE(newnode->format, jr->format, JsonFormat *);
3351+
3352+
return (Node *) newnode;
3353+
}
3354+
case T_JsonValueExpr:
3355+
{
3356+
JsonValueExpr *jve = (JsonValueExpr *) node;
3357+
JsonValueExpr *newnode;
3358+
3359+
FLATCOPY(newnode, jve, JsonValueExpr);
3360+
MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3361+
MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
3362+
MUTATE(newnode->format, jve->format, JsonFormat *);
3363+
3364+
return (Node *) newnode;
3365+
}
33143366
default:
33153367
elog(ERROR, "unrecognized node type: %d",
33163368
(int) nodeTag(node));
@@ -4019,6 +4071,20 @@ raw_expression_tree_walker(Node *node,
40194071
case T_CommonTableExpr:
40204072
/* search_clause and cycle_clause are not interesting here */
40214073
return walker(((CommonTableExpr *) node)->ctequery, context);
4074+
case T_JsonReturning:
4075+
return walker(((JsonReturning *) node)->format, context);
4076+
case T_JsonValueExpr:
4077+
{
4078+
JsonValueExpr *jve = (JsonValueExpr *) node;
4079+
4080+
if (walker(jve->raw_expr, context))
4081+
return true;
4082+
if (walker(jve->formatted_expr, context))
4083+
return true;
4084+
if (walker(jve->format, context))
4085+
return true;
4086+
}
4087+
break;
40224088
default:
40234089
elog(ERROR, "unrecognized node type: %d",
40244090
(int) nodeTag(node));

src/backend/nodes/outfuncs.c

+39
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,36 @@ _outOnConflictExpr(StringInfo str, const OnConflictExpr *node)
17511751
WRITE_NODE_FIELD(exclRelTlist);
17521752
}
17531753

1754+
static void
1755+
_outJsonFormat(StringInfo str, const JsonFormat *node)
1756+
{
1757+
WRITE_NODE_TYPE("JSONFORMAT");
1758+
1759+
WRITE_ENUM_FIELD(format_type, JsonFormatType);
1760+
WRITE_ENUM_FIELD(encoding, JsonEncoding);
1761+
WRITE_LOCATION_FIELD(location);
1762+
}
1763+
1764+
static void
1765+
_outJsonReturning(StringInfo str, const JsonReturning *node)
1766+
{
1767+
WRITE_NODE_TYPE("JSONRETURNING");
1768+
1769+
WRITE_NODE_FIELD(format);
1770+
WRITE_OID_FIELD(typid);
1771+
WRITE_INT_FIELD(typmod);
1772+
}
1773+
1774+
static void
1775+
_outJsonValueExpr(StringInfo str, const JsonValueExpr *node)
1776+
{
1777+
WRITE_NODE_TYPE("JSONVALUEEXPR");
1778+
1779+
WRITE_NODE_FIELD(raw_expr);
1780+
WRITE_NODE_FIELD(formatted_expr);
1781+
WRITE_NODE_FIELD(format);
1782+
}
1783+
17541784
/*****************************************************************************
17551785
*
17561786
* Stuff from pathnodes.h.
@@ -4537,6 +4567,15 @@ outNode(StringInfo str, const void *obj)
45374567
case T_PartitionRangeDatum:
45384568
_outPartitionRangeDatum(str, obj);
45394569
break;
4570+
case T_JsonFormat:
4571+
_outJsonFormat(str, obj);
4572+
break;
4573+
case T_JsonReturning:
4574+
_outJsonReturning(str, obj);
4575+
break;
4576+
case T_JsonValueExpr:
4577+
_outJsonValueExpr(str, obj);
4578+
break;
45404579

45414580
default:
45424581

0 commit comments

Comments
 (0)