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

Commit 2a13e6c

Browse files
author
Nikita Glukhov
committed
Add JSON_TABLE
1 parent c227874 commit 2a13e6c

29 files changed

+3660
-27
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

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

2951+
APP_JUMB(tablefunc->functype);
29512952
JumbleExpr(jstate, tablefunc->docexpr);
29522953
JumbleExpr(jstate, tablefunc->rowexpr);
29532954
JumbleExpr(jstate, (Node *) tablefunc->colexprs);
2955+
JumbleExpr(jstate, (Node *) tablefunc->colvalexprs);
29542956
}
29552957
break;
29562958
case T_TableSampleClause:

src/backend/commands/explain.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2707,7 +2707,9 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
27072707
break;
27082708
case T_TableFuncScan:
27092709
Assert(rte->rtekind == RTE_TABLEFUNC);
2710-
objectname = "xmltable";
2710+
objectname = rte->tablefunc ?
2711+
rte->tablefunc->functype == TFT_XMLTABLE ?
2712+
"xmltable" : "json_table" : NULL;
27112713
objecttag = "Table Function Name";
27122714
break;
27132715
case T_ValuesScan:

src/backend/executor/execExpr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,6 +2095,7 @@ ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
20952095
var->var.cb_arg = var;
20962096
var->estate = ExecInitExpr(argexpr, parent);
20972097
var->econtext = NULL;
2098+
var->mcxt = NULL;
20982099
var->evaluated = false;
20992100
var->value = (Datum) 0;
21002101
var->isnull = true;

src/backend/executor/execExprInterp.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3596,7 +3596,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
35963596
/*
35973597
* Evaluate a expression substituting specified value in its CaseTestExpr nodes.
35983598
*/
3599-
static Datum
3599+
Datum
36003600
ExecEvalExprPassingCaseValue(ExprState *estate, ExprContext *econtext,
36013601
bool *isnull,
36023602
Datum caseval_datum, bool caseval_isnull)
@@ -3656,6 +3656,7 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
36563656

36573657
case JSON_BEHAVIOR_NULL:
36583658
case JSON_BEHAVIOR_UNKNOWN:
3659+
case JSON_BEHAVIOR_EMPTY:
36593660
*is_null = true;
36603661
return (Datum) 0;
36613662

@@ -3717,8 +3718,14 @@ EvalJsonPathVar(void *cxt, bool *isnull)
37173718

37183719
if (!ecxt->evaluated)
37193720
{
3721+
MemoryContext oldcxt = ecxt->mcxt ?
3722+
MemoryContextSwitchTo(ecxt->mcxt) : NULL;
3723+
37203724
ecxt->value = ExecEvalExpr(ecxt->estate, ecxt->econtext, &ecxt->isnull);
37213725
ecxt->evaluated = true;
3726+
3727+
if (oldcxt)
3728+
MemoryContextSwitchTo(oldcxt);
37223729
}
37233730

37243731
*isnull = ecxt->isnull;
@@ -3906,6 +3913,11 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
39063913
*resnull = false;
39073914
break;
39083915

3916+
case IS_JSON_TABLE:
3917+
res = item;
3918+
*resnull = false;
3919+
break;
3920+
39093921
default:
39103922
elog(ERROR, "unrecognized SQL/JSON expression op %d",
39113923
jexpr->op);
@@ -3926,6 +3938,7 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
39263938
}
39273939

39283940
if (jexpr->op != IS_JSON_EXISTS &&
3941+
jexpr->op != IS_JSON_TABLE &&
39293942
(!empty ? jexpr->op != IS_JSON_VALUE :
39303943
/* result is already coerced in DEFAULT behavior case */
39313944
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
@@ -1224,6 +1224,7 @@ _copyTableFunc(const TableFunc *from)
12241224
{
12251225
TableFunc *newnode = makeNode(TableFunc);
12261226

1227+
COPY_SCALAR_FIELD(functype);
12271228
COPY_NODE_FIELD(ns_uris);
12281229
COPY_NODE_FIELD(ns_names);
12291230
COPY_NODE_FIELD(docexpr);
@@ -1234,7 +1235,9 @@ _copyTableFunc(const TableFunc *from)
12341235
COPY_NODE_FIELD(colcollations);
12351236
COPY_NODE_FIELD(colexprs);
12361237
COPY_NODE_FIELD(coldefexprs);
1238+
COPY_NODE_FIELD(colvalexprs);
12371239
COPY_BITMAPSET_FIELD(notnulls);
1240+
COPY_NODE_FIELD(plan);
12381241
COPY_SCALAR_FIELD(ordinalitycol);
12391242
COPY_LOCATION_FIELD(location);
12401243

@@ -2442,6 +2445,99 @@ _copyJsonArgument(const JsonArgument *from)
24422445
return newnode;
24432446
}
24442447

2448+
/*
2449+
* _copyJsonTable
2450+
*/
2451+
static JsonTable *
2452+
_copyJsonTable(const JsonTable *from)
2453+
{
2454+
JsonTable *newnode = makeNode(JsonTable);
2455+
2456+
COPY_NODE_FIELD(common);
2457+
COPY_NODE_FIELD(columns);
2458+
COPY_NODE_FIELD(plan);
2459+
COPY_NODE_FIELD(on_error);
2460+
COPY_NODE_FIELD(alias);
2461+
COPY_SCALAR_FIELD(location);
2462+
2463+
return newnode;
2464+
}
2465+
2466+
/*
2467+
* _copyJsonTableColumn
2468+
*/
2469+
static JsonTableColumn *
2470+
_copyJsonTableColumn(const JsonTableColumn *from)
2471+
{
2472+
JsonTableColumn *newnode = makeNode(JsonTableColumn);
2473+
2474+
COPY_SCALAR_FIELD(coltype);
2475+
COPY_STRING_FIELD(name);
2476+
COPY_NODE_FIELD(typename);
2477+
COPY_STRING_FIELD(pathspec);
2478+
COPY_STRING_FIELD(pathname);
2479+
COPY_SCALAR_FIELD(format);
2480+
COPY_SCALAR_FIELD(wrapper);
2481+
COPY_SCALAR_FIELD(omit_quotes);
2482+
COPY_NODE_FIELD(columns);
2483+
COPY_NODE_FIELD(on_empty);
2484+
COPY_NODE_FIELD(on_error);
2485+
COPY_SCALAR_FIELD(location);
2486+
2487+
return newnode;
2488+
}
2489+
2490+
/*
2491+
* _copyJsonTablePlan
2492+
*/
2493+
static JsonTablePlan *
2494+
_copyJsonTablePlan(const JsonTablePlan *from)
2495+
{
2496+
JsonTablePlan *newnode = makeNode(JsonTablePlan);
2497+
2498+
COPY_SCALAR_FIELD(plan_type);
2499+
COPY_SCALAR_FIELD(join_type);
2500+
COPY_STRING_FIELD(pathname);
2501+
COPY_NODE_FIELD(plan1);
2502+
COPY_NODE_FIELD(plan2);
2503+
COPY_SCALAR_FIELD(location);
2504+
2505+
return newnode;
2506+
}
2507+
2508+
/*
2509+
* _copyJsonTableParentNode
2510+
*/
2511+
static JsonTableParentNode *
2512+
_copyJsonTableParentNode(const JsonTableParentNode *from)
2513+
{
2514+
JsonTableParentNode *newnode = makeNode(JsonTableParentNode);
2515+
2516+
COPY_NODE_FIELD(path);
2517+
COPY_STRING_FIELD(name);
2518+
COPY_NODE_FIELD(child);
2519+
COPY_SCALAR_FIELD(outerJoin);
2520+
COPY_SCALAR_FIELD(colMin);
2521+
COPY_SCALAR_FIELD(colMax);
2522+
2523+
return newnode;
2524+
}
2525+
2526+
/*
2527+
* _copyJsonTableSiblingNode
2528+
*/
2529+
static JsonTableSiblingNode *
2530+
_copyJsonTableSiblingNode(const JsonTableSiblingNode *from)
2531+
{
2532+
JsonTableSiblingNode *newnode = makeNode(JsonTableSiblingNode);
2533+
2534+
COPY_NODE_FIELD(larg);
2535+
COPY_NODE_FIELD(rarg);
2536+
COPY_SCALAR_FIELD(cross);
2537+
2538+
return newnode;
2539+
}
2540+
24452541
/* ****************************************************************
24462542
* relation.h copy functions
24472543
*
@@ -5348,6 +5444,21 @@ copyObjectImpl(const void *from)
53485444
case T_JsonItemCoercions:
53495445
retval = _copyJsonItemCoercions(from);
53505446
break;
5447+
case T_JsonTable:
5448+
retval = _copyJsonTable(from);
5449+
break;
5450+
case T_JsonTableColumn:
5451+
retval = _copyJsonTableColumn(from);
5452+
break;
5453+
case T_JsonTablePlan:
5454+
retval = _copyJsonTablePlan(from);
5455+
break;
5456+
case T_JsonTableParentNode:
5457+
retval = _copyJsonTableParentNode(from);
5458+
break;
5459+
case T_JsonTableSiblingNode:
5460+
retval = _copyJsonTableSiblingNode(from);
5461+
break;
53515462

53525463
/*
53535464
* 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
{
@@ -3262,6 +3288,12 @@ equal(const void *a, const void *b)
32623288
case T_JsonItemCoercions:
32633289
retval = _equalJsonItemCoercions(a, b);
32643290
break;
3291+
case T_JsonTableParentNode:
3292+
retval = _equalJsonTableParentNode(a, b);
3293+
break;
3294+
case T_JsonTableSiblingNode:
3295+
retval = _equalJsonTableSiblingNode(a, b);
3296+
break;
32653297

32663298
/*
32673299
* RELATION NODES

src/backend/nodes/makefuncs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,25 @@ makeJsonBehavior(JsonBehaviorType type, Node *default_expr)
643643
return behavior;
644644
}
645645

646+
/*
647+
* makeJsonTableJoinedPlan -
648+
* creates a joined JsonTablePlan node
649+
*/
650+
Node *
651+
makeJsonTableJoinedPlan(JsonTablePlanJoinType type, Node *plan1, Node *plan2,
652+
int location)
653+
{
654+
JsonTablePlan *n = makeNode(JsonTablePlan);
655+
656+
n->plan_type = JSTP_JOINED;
657+
n->join_type = type;
658+
n->plan1 = castNode(JsonTablePlan, plan1);
659+
n->plan2 = castNode(JsonTablePlan, plan2);
660+
n->location = location;
661+
662+
return (Node *) n;
663+
}
664+
646665
/*
647666
* makeJsonEncoding -
648667
* converts JSON encoding name to enum JsonEncoding

0 commit comments

Comments
 (0)