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

Commit fdef26e

Browse files
author
Nikita Glukhov
committed
Add JSON_TABLE
1 parent d7d23f6 commit fdef26e

29 files changed

+3640
-103
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,9 +2912,11 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
29122912
{
29132913
TableFunc *tablefunc = (TableFunc *) node;
29142914

2915+
APP_JUMB(tablefunc->functype);
29152916
JumbleExpr(jstate, tablefunc->docexpr);
29162917
JumbleExpr(jstate, tablefunc->rowexpr);
29172918
JumbleExpr(jstate, (Node *) tablefunc->colexprs);
2919+
JumbleExpr(jstate, (Node *) tablefunc->colvalexprs);
29182920
}
29192921
break;
29202922
case T_TableSampleClause:

src/backend/commands/explain.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2694,7 +2694,9 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
26942694
break;
26952695
case T_TableFuncScan:
26962696
Assert(rte->rtekind == RTE_TABLEFUNC);
2697-
objectname = "xmltable";
2697+
objectname = rte->tablefunc ?
2698+
rte->tablefunc->functype == TFT_XMLTABLE ?
2699+
"xmltable" : "json_table" : NULL;
26982700
objecttag = "Table Function Name";
26992701
break;
27002702
case T_ValuesScan:

src/backend/executor/execExpr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,7 @@ ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
20872087
var->var.cb_arg = var;
20882088
var->estate = ExecInitExpr(argexpr, parent);
20892089
var->econtext = NULL;
2090+
var->mcxt = NULL;
20902091
var->evaluated = false;
20912092
var->value = (Datum) 0;
20922093
var->isnull = true;

src/backend/executor/execExprInterp.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3593,7 +3593,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
35933593
*op->resnull = false;
35943594
}
35953595

3596-
static Datum
3596+
Datum
35973597
ExecEvalExprPassingCaseValue(ExprState *estate, ExprContext *econtext,
35983598
bool *isnull,
35993599
Datum caseval_datum, bool caseval_isnull)
@@ -3650,6 +3650,7 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
36503650

36513651
case JSON_BEHAVIOR_NULL:
36523652
case JSON_BEHAVIOR_UNKNOWN:
3653+
case JSON_BEHAVIOR_EMPTY:
36533654
*is_null = true;
36543655
return (Datum) 0;
36553656

@@ -3702,8 +3703,14 @@ EvalJsonPathVar(void *cxt, bool *isnull)
37023703

37033704
if (!ecxt->evaluated)
37043705
{
3706+
MemoryContext oldcxt = ecxt->mcxt ?
3707+
MemoryContextSwitchTo(ecxt->mcxt) : NULL;
3708+
37053709
ecxt->value = ExecEvalExpr(ecxt->estate, ecxt->econtext, &ecxt->isnull);
37063710
ecxt->evaluated = true;
3711+
3712+
if (oldcxt)
3713+
MemoryContextSwitchTo(oldcxt);
37073714
}
37083715

37093716
*isnull = ecxt->isnull;
@@ -3960,6 +3967,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39603967
*op->resnull = false;
39613968
break;
39623969

3970+
case IS_JSON_TABLE:
3971+
res = item;
3972+
*op->resnull = false;
3973+
break;
3974+
39633975
default:
39643976
elog(ERROR, "unrecognized SQL/JSON expression op %d",
39653977
jexpr->op);
@@ -3979,6 +3991,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39793991
}
39803992

39813993
if (jexpr->op != IS_JSON_EXISTS &&
3994+
jexpr->op != IS_JSON_TABLE &&
39823995
(!empty ? jexpr->op != IS_JSON_VALUE :
39833996
/* already coerced in DEFAULT case */
39843997
jexpr->on_empty.btype != JSON_BEHAVIOR_DEFAULT))

src/backend/executor/nodeTableFuncscan.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "executor/tablefunc.h"
2929
#include "miscadmin.h"
3030
#include "utils/builtins.h"
31+
#include "utils/jsonpath.h"
3132
#include "utils/lsyscache.h"
3233
#include "utils/memutils.h"
3334
#include "utils/xml.h"
@@ -167,8 +168,9 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
167168
ExecAssignResultTypeFromTL(&scanstate->ss.ps);
168169
ExecAssignScanProjectionInfo(&scanstate->ss);
169170

170-
/* Only XMLTABLE is supported currently */
171-
scanstate->routine = &XmlTableRoutine;
171+
/* Only XMLTABLE and JSON_TABLE are supported currently */
172+
scanstate->routine =
173+
tf->functype == TFT_XMLTABLE ? &XmlTableRoutine : &JsonbTableRoutine;
172174

173175
scanstate->perValueCxt =
174176
AllocSetContextCreate(CurrentMemoryContext,
@@ -371,14 +373,17 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc)
371373
routine->SetNamespace(tstate, ns_name, ns_uri);
372374
}
373375

374-
/* Install the row filter expression into the table builder context */
375-
value = ExecEvalExpr(tstate->rowexpr, econtext, &isnull);
376-
if (isnull)
377-
ereport(ERROR,
378-
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
379-
errmsg("row filter expression must not be null")));
376+
if (routine->SetRowFilter)
377+
{
378+
/* Install the row filter expression into the table builder context */
379+
value = ExecEvalExpr(tstate->rowexpr, econtext, &isnull);
380+
if (isnull)
381+
ereport(ERROR,
382+
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
383+
errmsg("row filter expression must not be null")));
380384

381-
routine->SetRowFilter(tstate, TextDatumGetCString(value));
385+
routine->SetRowFilter(tstate, TextDatumGetCString(value));
386+
}
382387

383388
/*
384389
* Install the column filter expressions into the table builder context.

src/backend/nodes/copyfuncs.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,7 @@ _copyTableFunc(const TableFunc *from)
12221222
{
12231223
TableFunc *newnode = makeNode(TableFunc);
12241224

1225+
COPY_SCALAR_FIELD(functype);
12251226
COPY_NODE_FIELD(ns_uris);
12261227
COPY_NODE_FIELD(ns_names);
12271228
COPY_NODE_FIELD(docexpr);
@@ -1232,7 +1233,9 @@ _copyTableFunc(const TableFunc *from)
12321233
COPY_NODE_FIELD(colcollations);
12331234
COPY_NODE_FIELD(colexprs);
12341235
COPY_NODE_FIELD(coldefexprs);
1236+
COPY_NODE_FIELD(colvalexprs);
12351237
COPY_BITMAPSET_FIELD(notnulls);
1238+
COPY_NODE_FIELD(plan);
12361239
COPY_SCALAR_FIELD(ordinalitycol);
12371240
COPY_LOCATION_FIELD(location);
12381241

@@ -2363,6 +2366,99 @@ _copyJsonArgument(const JsonArgument *from)
23632366
return newnode;
23642367
}
23652368

2369+
/*
2370+
* _copyJsonTable
2371+
*/
2372+
static JsonTable *
2373+
_copyJsonTable(const JsonTable *from)
2374+
{
2375+
JsonTable *newnode = makeNode(JsonTable);
2376+
2377+
COPY_NODE_FIELD(common);
2378+
COPY_NODE_FIELD(columns);
2379+
COPY_NODE_FIELD(plan);
2380+
COPY_NODE_FIELD(on_error);
2381+
COPY_NODE_FIELD(alias);
2382+
COPY_SCALAR_FIELD(location);
2383+
2384+
return newnode;
2385+
}
2386+
2387+
/*
2388+
* _copyJsonTableColumn
2389+
*/
2390+
static JsonTableColumn *
2391+
_copyJsonTableColumn(const JsonTableColumn *from)
2392+
{
2393+
JsonTableColumn *newnode = makeNode(JsonTableColumn);
2394+
2395+
COPY_SCALAR_FIELD(coltype);
2396+
COPY_STRING_FIELD(name);
2397+
COPY_NODE_FIELD(typename);
2398+
COPY_STRING_FIELD(pathspec);
2399+
COPY_STRING_FIELD(pathname);
2400+
COPY_SCALAR_FIELD(format);
2401+
COPY_SCALAR_FIELD(wrapper);
2402+
COPY_SCALAR_FIELD(omit_quotes);
2403+
COPY_NODE_FIELD(columns);
2404+
COPY_NODE_FIELD(on_empty);
2405+
COPY_NODE_FIELD(on_error);
2406+
COPY_SCALAR_FIELD(location);
2407+
2408+
return newnode;
2409+
}
2410+
2411+
/*
2412+
* _copyJsonTablePlan
2413+
*/
2414+
static JsonTablePlan *
2415+
_copyJsonTablePlan(const JsonTablePlan *from)
2416+
{
2417+
JsonTablePlan *newnode = makeNode(JsonTablePlan);
2418+
2419+
COPY_SCALAR_FIELD(plan_type);
2420+
COPY_SCALAR_FIELD(join_type);
2421+
COPY_STRING_FIELD(pathname);
2422+
COPY_NODE_FIELD(plan1);
2423+
COPY_NODE_FIELD(plan2);
2424+
COPY_SCALAR_FIELD(location);
2425+
2426+
return newnode;
2427+
}
2428+
2429+
/*
2430+
* _copyJsonTableParentNode
2431+
*/
2432+
static JsonTableParentNode *
2433+
_copyJsonTableParentNode(const JsonTableParentNode *from)
2434+
{
2435+
JsonTableParentNode *newnode = makeNode(JsonTableParentNode);
2436+
2437+
COPY_NODE_FIELD(path);
2438+
COPY_STRING_FIELD(name);
2439+
COPY_NODE_FIELD(child);
2440+
COPY_SCALAR_FIELD(outerJoin);
2441+
COPY_SCALAR_FIELD(colMin);
2442+
COPY_SCALAR_FIELD(colMax);
2443+
2444+
return newnode;
2445+
}
2446+
2447+
/*
2448+
* _copyJsonTableSiblingNode
2449+
*/
2450+
static JsonTableSiblingNode *
2451+
_copyJsonTableSiblingNode(const JsonTableSiblingNode *from)
2452+
{
2453+
JsonTableSiblingNode *newnode = makeNode(JsonTableSiblingNode);
2454+
2455+
COPY_NODE_FIELD(larg);
2456+
COPY_NODE_FIELD(rarg);
2457+
COPY_SCALAR_FIELD(cross);
2458+
2459+
return newnode;
2460+
}
2461+
23662462
/* ****************************************************************
23672463
* relation.h copy functions
23682464
*
@@ -5257,6 +5353,21 @@ copyObjectImpl(const void *from)
52575353
case T_JsonArgument:
52585354
retval = _copyJsonArgument(from);
52595355
break;
5356+
case T_JsonTable:
5357+
retval = _copyJsonTable(from);
5358+
break;
5359+
case T_JsonTableColumn:
5360+
retval = _copyJsonTableColumn(from);
5361+
break;
5362+
case T_JsonTablePlan:
5363+
retval = _copyJsonTablePlan(from);
5364+
break;
5365+
case T_JsonTableParentNode:
5366+
retval = _copyJsonTableParentNode(from);
5367+
break;
5368+
case T_JsonTableSiblingNode:
5369+
retval = _copyJsonTableSiblingNode(from);
5370+
break;
52605371

52615372
/*
52625373
* RELATION NODES

src/backend/nodes/equalfuncs.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ _equalRangeVar(const RangeVar *a, const RangeVar *b)
119119
static bool
120120
_equalTableFunc(const TableFunc *a, const TableFunc *b)
121121
{
122+
COMPARE_SCALAR_FIELD(functype);
122123
COMPARE_NODE_FIELD(ns_uris);
123124
COMPARE_NODE_FIELD(ns_names);
124125
COMPARE_NODE_FIELD(docexpr);
@@ -129,13 +130,38 @@ _equalTableFunc(const TableFunc *a, const TableFunc *b)
129130
COMPARE_NODE_FIELD(colcollations);
130131
COMPARE_NODE_FIELD(colexprs);
131132
COMPARE_NODE_FIELD(coldefexprs);
133+
COMPARE_NODE_FIELD(colvalexprs);
132134
COMPARE_BITMAPSET_FIELD(notnulls);
135+
COMPARE_NODE_FIELD(plan);
133136
COMPARE_SCALAR_FIELD(ordinalitycol);
134137
COMPARE_LOCATION_FIELD(location);
135138

136139
return true;
137140
}
138141

142+
static bool
143+
_equalJsonTableParentNode(const JsonTableParentNode *a, const JsonTableParentNode *b)
144+
{
145+
COMPARE_NODE_FIELD(path);
146+
COMPARE_STRING_FIELD(name);
147+
COMPARE_NODE_FIELD(child);
148+
COMPARE_SCALAR_FIELD(outerJoin);
149+
COMPARE_SCALAR_FIELD(colMin);
150+
COMPARE_SCALAR_FIELD(colMax);
151+
152+
return true;
153+
}
154+
155+
static bool
156+
_equalJsonTableSiblingNode(const JsonTableSiblingNode *a, const JsonTableSiblingNode *b)
157+
{
158+
COMPARE_NODE_FIELD(larg);
159+
COMPARE_NODE_FIELD(rarg);
160+
COMPARE_SCALAR_FIELD(cross);
161+
162+
return true;
163+
}
164+
139165
static bool
140166
_equalIntoClause(const IntoClause *a, const IntoClause *b)
141167
{
@@ -3173,6 +3199,12 @@ equal(const void *a, const void *b)
31733199
case T_JsonExpr:
31743200
retval = _equalJsonExpr(a, b);
31753201
break;
3202+
case T_JsonTableParentNode:
3203+
retval = _equalJsonTableParentNode(a, b);
3204+
break;
3205+
case T_JsonTableSiblingNode:
3206+
retval = _equalJsonTableSiblingNode(a, b);
3207+
break;
31763208

31773209
/*
31783210
* RELATION NODES

src/backend/nodes/makefuncs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,21 @@ makeJsonBehavior(JsonBehaviorType type, Node *expr)
624624
return behavior;
625625
}
626626

627+
Node *
628+
makeJsonTableJoinedPlan(JsonTablePlanJoinType type, Node *plan1, Node *plan2,
629+
int location)
630+
{
631+
JsonTablePlan *n = makeNode(JsonTablePlan);
632+
633+
n->plan_type = JSTP_JOINED;
634+
n->join_type = type;
635+
n->plan1 = castNode(JsonTablePlan, plan1);
636+
n->plan2 = castNode(JsonTablePlan, plan2);
637+
n->location = location;
638+
639+
return (Node *) n;
640+
}
641+
627642
JsonEncoding
628643
makeJsonEncoding(char *name)
629644
{

src/backend/nodes/nodeFuncs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,6 +2254,8 @@ expression_tree_walker(Node *node,
22542254
return true;
22552255
if (walker(tf->coldefexprs, context))
22562256
return true;
2257+
if (walker(tf->colvalexprs, context))
2258+
return true;
22572259
}
22582260
break;
22592261
case T_JsonExpr:
@@ -3088,6 +3090,7 @@ expression_tree_mutator(Node *node,
30883090
MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
30893091
MUTATE(newnode->colexprs, tf->colexprs, List *);
30903092
MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3093+
MUTATE(newnode->colvalexprs, tf->colvalexprs, List *);
30913094
return (Node *) newnode;
30923095
}
30933096
break;

0 commit comments

Comments
 (0)