Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)