Skip to content

Commit a13e77d

Browse files
author
Nikita Glukhov
committed
Add JSON_OBJECT() transformation
1 parent 21e8d2a commit a13e77d

File tree

22 files changed

+1188
-25
lines changed

22 files changed

+1188
-25
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,6 +3112,17 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
31123112
JumbleExpr(jstate, (Node *) expr->format);
31133113
}
31143114
break;
3115+
case T_JsonCtorExpr:
3116+
{
3117+
JsonCtorExpr *ctor = (JsonCtorExpr *) node;
3118+
3119+
JumbleExpr(jstate, (Node *) ctor->func);
3120+
JumbleExpr(jstate, (Node *) ctor->returning);
3121+
APP_JUMB(ctor->type);
3122+
APP_JUMB(ctor->unique);
3123+
APP_JUMB(ctor->absent_on_null);
3124+
}
3125+
break;
31153126
case T_List:
31163127
foreach(temp, (List *) node)
31173128
{

src/backend/executor/execExpr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,6 +2130,11 @@ ExecInitExprRec(Expr *node, ExprState *state,
21302130
break;
21312131
}
21322132

2133+
case T_JsonCtorExpr:
2134+
ExecInitExprRec(&((JsonCtorExpr *) node)->func->xpr, state, resv,
2135+
resnull);
2136+
break;
2137+
21332138
default:
21342139
elog(ERROR, "unrecognized node type: %d",
21352140
(int) nodeTag(node));

src/backend/nodes/copyfuncs.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,72 @@ _copyJsonValueExpr(const JsonValueExpr *from)
22942294
return newnode;
22952295
}
22962296

2297+
/*
2298+
* _copyJsonCtorExpr
2299+
*/
2300+
static JsonCtorExpr *
2301+
_copyJsonCtorExpr(const JsonCtorExpr *from)
2302+
{
2303+
JsonCtorExpr *newnode = makeNode(JsonCtorExpr);
2304+
2305+
COPY_NODE_FIELD(func);
2306+
COPY_SCALAR_FIELD(type);
2307+
COPY_SCALAR_FIELD(returning.format.type);
2308+
COPY_SCALAR_FIELD(returning.format.encoding);
2309+
COPY_LOCATION_FIELD(returning.format.location);
2310+
COPY_SCALAR_FIELD(returning.typid);
2311+
COPY_SCALAR_FIELD(returning.typmod);
2312+
COPY_SCALAR_FIELD(absent_on_null);
2313+
COPY_SCALAR_FIELD(unique);
2314+
2315+
return newnode;
2316+
}
2317+
2318+
/*
2319+
* _copyJsonKeyValue
2320+
*/
2321+
static JsonKeyValue *
2322+
_copyJsonKeyValue(const JsonKeyValue *from)
2323+
{
2324+
JsonKeyValue *newnode = makeNode(JsonKeyValue);
2325+
2326+
COPY_NODE_FIELD(key);
2327+
COPY_NODE_FIELD(value);
2328+
2329+
return newnode;
2330+
}
2331+
2332+
/*
2333+
* _copyJsonObjectCtor
2334+
*/
2335+
static JsonObjectCtor *
2336+
_copyJsonObjectCtor(const JsonObjectCtor *from)
2337+
{
2338+
JsonObjectCtor *newnode = makeNode(JsonObjectCtor);
2339+
2340+
COPY_NODE_FIELD(exprs);
2341+
COPY_NODE_FIELD(output);
2342+
COPY_SCALAR_FIELD(absent_on_null);
2343+
COPY_SCALAR_FIELD(unique);
2344+
COPY_LOCATION_FIELD(location);
2345+
2346+
return newnode;
2347+
}
2348+
2349+
/*
2350+
* _copyJsonOutput
2351+
*/
2352+
static JsonOutput *
2353+
_copyJsonOutput(const JsonOutput *from)
2354+
{
2355+
JsonOutput *newnode = makeNode(JsonOutput);
2356+
2357+
COPY_NODE_FIELD(typeName);
2358+
COPY_SCALAR_FIELD(returning);
2359+
2360+
return newnode;
2361+
}
2362+
22972363
/* ****************************************************************
22982364
* pathnodes.h copy functions
22992365
*
@@ -5200,6 +5266,18 @@ copyObjectImpl(const void *from)
52005266
case T_JsonValueExpr:
52015267
retval = _copyJsonValueExpr(from);
52025268
break;
5269+
case T_JsonKeyValue:
5270+
retval = _copyJsonKeyValue(from);
5271+
break;
5272+
case T_JsonCtorExpr:
5273+
retval = _copyJsonCtorExpr(from);
5274+
break;
5275+
case T_JsonObjectCtor:
5276+
retval = _copyJsonObjectCtor(from);
5277+
break;
5278+
case T_JsonOutput:
5279+
retval = _copyJsonOutput(from);
5280+
break;
52035281

52045282
/*
52055283
* RELATION NODES

src/backend/nodes/equalfuncs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,22 @@ _equalJsonValueExpr(const JsonValueExpr *a, const JsonValueExpr *b)
848848
return true;
849849
}
850850

851+
static bool
852+
_equalJsonCtorExpr(const JsonCtorExpr *a, const JsonCtorExpr *b)
853+
{
854+
COMPARE_NODE_FIELD(func);
855+
COMPARE_SCALAR_FIELD(type);
856+
COMPARE_SCALAR_FIELD(returning.format.type);
857+
COMPARE_SCALAR_FIELD(returning.format.encoding);
858+
COMPARE_LOCATION_FIELD(returning.format.location);
859+
COMPARE_SCALAR_FIELD(returning.typid);
860+
COMPARE_SCALAR_FIELD(returning.typmod);
861+
COMPARE_SCALAR_FIELD(absent_on_null);
862+
COMPARE_SCALAR_FIELD(unique);
863+
864+
return true;
865+
}
866+
851867
/*
852868
* Stuff from pathnodes.h
853869
*/
@@ -3249,6 +3265,9 @@ equal(const void *a, const void *b)
32493265
case T_JsonValueExpr:
32503266
retval = _equalJsonValueExpr(a, b);
32513267
break;
3268+
case T_JsonCtorExpr:
3269+
retval = _equalJsonCtorExpr(a, b);
3270+
break;
32523271

32533272
/*
32543273
* RELATION NODES

src/backend/nodes/nodeFuncs.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ exprType(const Node *expr)
265265
type = exprType((Node *) (jve->formatted_expr ? jve->formatted_expr : jve->raw_expr));
266266
}
267267
break;
268+
case T_JsonCtorExpr:
269+
type = exprType((Node *) ((const JsonCtorExpr *) expr)->func);
270+
break;
268271
default:
269272
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
270273
type = InvalidOid; /* keep compiler quiet */
@@ -500,6 +503,8 @@ exprTypmod(const Node *expr)
500503
return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
501504
case T_JsonValueExpr:
502505
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
506+
case T_JsonCtorExpr:
507+
return exprTypmod((Node *) ((const JsonCtorExpr *) expr)->func);
503508
default:
504509
break;
505510
}
@@ -918,6 +923,9 @@ exprCollation(const Node *expr)
918923
case T_JsonValueExpr:
919924
coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
920925
break;
926+
case T_JsonCtorExpr:
927+
coll = exprCollation((Node *) ((const JsonCtorExpr *) expr)->func);
928+
break;
921929
default:
922930
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
923931
coll = InvalidOid; /* keep compiler quiet */
@@ -1125,6 +1133,10 @@ exprSetCollation(Node *expr, Oid collation)
11251133
exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
11261134
collation);
11271135
break;
1136+
case T_JsonCtorExpr:
1137+
exprSetCollation((Node *) ((const JsonCtorExpr *) expr)->func,
1138+
collation);
1139+
break;
11281140
default:
11291141
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
11301142
break;
@@ -1568,6 +1580,9 @@ exprLocation(const Node *expr)
15681580
case T_JsonValueExpr:
15691581
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
15701582
break;
1583+
case T_JsonCtorExpr:
1584+
loc = exprLocation((Node *) ((const JsonCtorExpr *) expr)->func);
1585+
break;
15711586
default:
15721587
/* for any other node type it's just unknown... */
15731588
loc = -1;
@@ -2275,6 +2290,8 @@ expression_tree_walker(Node *node,
22752290
return true;
22762291
}
22772292
break;
2293+
case T_JsonCtorExpr:
2294+
return walker(((JsonCtorExpr *) node)->func, context);
22782295
default:
22792296
elog(ERROR, "unrecognized node type: %d",
22802297
(int) nodeTag(node));
@@ -3219,6 +3236,16 @@ expression_tree_mutator(Node *node,
32193236
MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
32203237
MUTATE(newnode->format, jve->format, JsonFormat *);
32213238

3239+
return (Node *) newnode;
3240+
}
3241+
case T_JsonCtorExpr:
3242+
{
3243+
JsonCtorExpr *jve = (JsonCtorExpr *) node;
3244+
JsonCtorExpr *newnode;
3245+
3246+
FLATCOPY(newnode, jve, JsonCtorExpr);
3247+
MUTATE(newnode->func, jve->func, FuncExpr *);
3248+
32223249
return (Node *) newnode;
32233250
}
32243251
default:
@@ -3930,6 +3957,30 @@ raw_expression_tree_walker(Node *node,
39303957
return true;
39313958
}
39323959
break;
3960+
case T_JsonCtorExpr:
3961+
return walker(((JsonCtorExpr *) node)->func, context);
3962+
case T_JsonOutput:
3963+
return walker(((JsonOutput *) node)->typeName, context);
3964+
case T_JsonKeyValue:
3965+
{
3966+
JsonKeyValue *jkv = (JsonKeyValue *) node;
3967+
3968+
if (walker(jkv->key, context))
3969+
return true;
3970+
if (walker(jkv->value, context))
3971+
return true;
3972+
}
3973+
break;
3974+
case T_JsonObjectCtor:
3975+
{
3976+
JsonObjectCtor *joc = (JsonObjectCtor *) node;
3977+
3978+
if (walker(joc->output, context))
3979+
return true;
3980+
if (walker(joc->exprs, context))
3981+
return true;
3982+
}
3983+
break;
39333984
default:
39343985
elog(ERROR, "unrecognized node type: %d",
39353986
(int) nodeTag(node));

src/backend/nodes/outfuncs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,22 @@ _outJsonValueExpr(StringInfo str, const JsonValueExpr *node)
17391739
WRITE_NODE_FIELD(format);
17401740
}
17411741

1742+
static void
1743+
_outJsonCtorExpr(StringInfo str, const JsonCtorExpr *node)
1744+
{
1745+
WRITE_NODE_TYPE("JSONCTOREXPR");
1746+
1747+
WRITE_NODE_FIELD(func);
1748+
WRITE_INT_FIELD(type);
1749+
WRITE_ENUM_FIELD(returning.format.type, JsonFormatType);
1750+
WRITE_ENUM_FIELD(returning.format.encoding, JsonEncoding);
1751+
WRITE_LOCATION_FIELD(returning.format.location);
1752+
WRITE_OID_FIELD(returning.typid);
1753+
WRITE_INT_FIELD(returning.typmod);
1754+
WRITE_BOOL_FIELD(unique);
1755+
WRITE_BOOL_FIELD(absent_on_null);
1756+
}
1757+
17421758
/*****************************************************************************
17431759
*
17441760
* Stuff from pathnodes.h.
@@ -4376,6 +4392,9 @@ outNode(StringInfo str, const void *obj)
43764392
case T_JsonValueExpr:
43774393
_outJsonValueExpr(str, obj);
43784394
break;
4395+
case T_JsonCtorExpr:
4396+
_outJsonCtorExpr(str, obj);
4397+
break;
43794398

43804399
default:
43814400

src/backend/nodes/readfuncs.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,27 @@ _readJsonValueExpr(void)
13881388
READ_DONE();
13891389
}
13901390

1391+
/*
1392+
* _readJsonCtorExpr
1393+
*/
1394+
static JsonCtorExpr *
1395+
_readJsonCtorExpr(void)
1396+
{
1397+
READ_LOCALS(JsonCtorExpr);
1398+
1399+
READ_NODE_FIELD(func);
1400+
READ_INT_FIELD(type);
1401+
READ_ENUM_FIELD(returning.format.type, JsonFormatType);
1402+
READ_ENUM_FIELD(returning.format.encoding, JsonEncoding);
1403+
READ_LOCATION_FIELD(returning.format.location);
1404+
READ_OID_FIELD(returning.typid);
1405+
READ_INT_FIELD(returning.typmod);
1406+
READ_BOOL_FIELD(unique);
1407+
READ_BOOL_FIELD(absent_on_null);
1408+
1409+
READ_DONE();
1410+
}
1411+
13911412
/*
13921413
* Stuff from pathnodes.h.
13931414
*
@@ -2931,6 +2952,8 @@ parseNodeString(void)
29312952
return_value = _readJsonReturning();
29322953
else if (MATCH("JSONVALUEEXPR", 13))
29332954
return_value = _readJsonValueExpr();
2955+
else if (MATCH("JSONCTOREXPR", 12))
2956+
return_value = _readJsonCtorExpr();
29342957
else
29352958
{
29362959
elog(ERROR, "badly formatted node string \"%.32s\"...", token);

src/backend/optimizer/util/clauses.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,12 @@ contain_mutable_functions_walker(Node *node, void *context)
677677
return true;
678678
}
679679

680+
if (IsA(node, JsonCtorExpr))
681+
{
682+
/* JsonCtorExpr is stable */
683+
return true;
684+
}
685+
680686
/*
681687
* It should be safe to treat MinMaxExpr as immutable, because it will
682688
* depend on a non-cross-type btree comparison function, and those should

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy