PostgreSQL Source Code  git master
parse_jsontable.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * parse_jsontable.c
4  * parsing of JSON_TABLE
5  *
6  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/parser/parse_jsontable.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "catalog/pg_collation.h"
19 #include "catalog/pg_type.h"
20 #include "miscadmin.h"
21 #include "nodes/makefuncs.h"
22 #include "nodes/nodeFuncs.h"
23 #include "optimizer/optimizer.h"
24 #include "parser/parse_clause.h"
25 #include "parser/parse_collate.h"
26 #include "parser/parse_expr.h"
27 #include "parser/parse_relation.h"
28 #include "parser/parse_type.h"
29 #include "utils/builtins.h"
30 #include "utils/json.h"
31 #include "utils/lsyscache.h"
32 
33 /* Context for JSON_TABLE transformation */
34 typedef struct JsonTableContext
35 {
36  ParseState *pstate; /* parsing state */
37  JsonTable *table; /* untransformed node */
38  TableFunc *tablefunc; /* transformed node */
39  List *pathNames; /* list of all path and columns names */
40  int pathNameId; /* path name id counter */
41  Oid contextItemTypid; /* type oid of context item (json/jsonb) */
43 
45  JsonTablePlan *plan,
46  List *columns,
47  char *pathSpec,
48  char **pathName,
49  int location);
50 
51 static Node *
52 makeStringConst(char *str, int location)
53 {
54  A_Const *n = makeNode(A_Const);
55 
56  n->val.node.type = T_String;
57  n->val.sval.sval = str;
58  n->location = location;
59 
60  return (Node *) n;
61 }
62 
63 /*
64  * Transform JSON_TABLE column
65  * - regular column into JSON_VALUE()
66  * - FORMAT JSON column into JSON_QUERY()
67  * - EXISTS column into JSON_EXISTS()
68  */
69 static Node *
71  List *passingArgs, bool errorOnError)
72 {
74  JsonCommon *common = makeNode(JsonCommon);
76  char *pathspec;
77  JsonFormat *default_format;
78 
79  jfexpr->op =
82  jfexpr->common = common;
83  jfexpr->output = output;
84  jfexpr->on_empty = jtc->on_empty;
85  jfexpr->on_error = jtc->on_error;
86  if (!jfexpr->on_error && errorOnError)
88  jfexpr->omit_quotes = jtc->omit_quotes;
89  jfexpr->wrapper = jtc->wrapper;
90  jfexpr->location = jtc->location;
91 
92  output->typeName = jtc->typeName;
93  output->returning = makeNode(JsonReturning);
94  output->returning->format = jtc->format;
95 
96  default_format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
97 
98  common->pathname = NULL;
99  common->expr = makeJsonValueExpr((Expr *) contextItemExpr, default_format);
100  common->passing = passingArgs;
101 
102  if (jtc->pathspec)
103  pathspec = jtc->pathspec;
104  else
105  {
106  /* Construct default path as '$."column_name"' */
107  StringInfoData path;
108 
109  initStringInfo(&path);
110 
111  appendStringInfoString(&path, "$.");
112  escape_json(&path, jtc->name);
113 
114  pathspec = path.data;
115  }
116 
117  common->pathspec = makeStringConst(pathspec, -1);
118 
119  return (Node *) jfexpr;
120 }
121 
122 static bool
124 {
125  ListCell *lc;
126 
127  foreach(lc, cxt->pathNames)
128  {
129  if (!strcmp(pathname, (const char *) lfirst(lc)))
130  return true;
131  }
132 
133  return false;
134 }
135 
136 /* Register the column name in the path name list. */
137 static void
139 {
140  if (isJsonTablePathNameDuplicate(cxt, colname))
141  ereport(ERROR,
142  (errcode(ERRCODE_DUPLICATE_ALIAS),
143  errmsg("duplicate JSON_TABLE column name: %s", colname),
144  errhint("JSON_TABLE column names must be distinct from one another")));
145 
146  cxt->pathNames = lappend(cxt->pathNames, colname);
147 }
148 
149 /* Recursively register all nested column names in the path name list. */
150 static void
152 {
153  ListCell *lc;
154 
155  foreach(lc, columns)
156  {
158 
159  if (jtc->coltype == JTC_NESTED)
160  {
161  if (jtc->pathname)
163 
165  }
166  else
167  {
168  registerJsonTableColumn(cxt, jtc->name);
169  }
170  }
171 }
172 
173 /* Generate a new unique JSON_TABLE path name. */
174 static char *
176 {
177  char namebuf[32];
178  char *name = namebuf;
179 
180  do
181  {
182  snprintf(namebuf, sizeof(namebuf), "json_table_path_%d",
183  ++cxt->pathNameId);
184  } while (isJsonTablePathNameDuplicate(cxt, name));
185 
186  name = pstrdup(name);
187  cxt->pathNames = lappend(cxt->pathNames, name);
188 
189  return name;
190 }
191 
192 /* Collect sibling path names from plan to the specified list. */
193 static void
195 {
196  if (plan->plan_type == JSTP_SIMPLE)
197  *paths = lappend(*paths, plan->pathname);
198  else if (plan->plan_type == JSTP_JOINED)
199  {
200  if (plan->join_type == JSTPJ_INNER ||
201  plan->join_type == JSTPJ_OUTER)
202  {
203  Assert(plan->plan1->plan_type == JSTP_SIMPLE);
204  *paths = lappend(*paths, plan->plan1->pathname);
205  }
206  else if (plan->join_type == JSTPJ_CROSS ||
207  plan->join_type == JSTPJ_UNION)
208  {
211  }
212  else
213  elog(ERROR, "invalid JSON_TABLE join type %d",
214  plan->join_type);
215  }
216 }
217 
218 /*
219  * Validate child JSON_TABLE plan by checking that:
220  * - all nested columns have path names specified
221  * - all nested columns have corresponding node in the sibling plan
222  * - plan does not contain duplicate or extra nodes
223  */
224 static void
226  List *columns)
227 {
228  ListCell *lc1;
229  List *siblings = NIL;
230  int nchildren = 0;
231 
232  if (plan)
233  collectSiblingPathsInJsonTablePlan(plan, &siblings);
234 
235  foreach(lc1, columns)
236  {
238 
239  if (jtc->coltype == JTC_NESTED)
240  {
241  ListCell *lc2;
242  bool found = false;
243 
244  if (!jtc->pathname)
245  ereport(ERROR,
246  (errcode(ERRCODE_SYNTAX_ERROR),
247  errmsg("nested JSON_TABLE columns must contain an explicit AS pathname specification if an explicit PLAN clause is used"),
248  parser_errposition(pstate, jtc->location)));
249 
250  /* find nested path name in the list of sibling path names */
251  foreach(lc2, siblings)
252  {
253  if ((found = !strcmp(jtc->pathname, lfirst(lc2))))
254  break;
255  }
256 
257  if (!found)
258  ereport(ERROR,
259  (errcode(ERRCODE_SYNTAX_ERROR),
260  errmsg("invalid JSON_TABLE plan"),
261  errdetail("plan node for nested path %s was not found in plan", jtc->pathname),
262  parser_errposition(pstate, jtc->location)));
263 
264  nchildren++;
265  }
266  }
267 
268  if (list_length(siblings) > nchildren)
269  ereport(ERROR,
270  (errcode(ERRCODE_SYNTAX_ERROR),
271  errmsg("invalid JSON_TABLE plan"),
272  errdetail("plan node contains some extra or duplicate sibling nodes"),
273  parser_errposition(pstate, plan ? plan->location : -1)));
274 }
275 
276 static JsonTableColumn *
277 findNestedJsonTableColumn(List *columns, const char *pathname)
278 {
279  ListCell *lc;
280 
281  foreach(lc, columns)
282  {
284 
285  if (jtc->coltype == JTC_NESTED &&
286  jtc->pathname &&
287  !strcmp(jtc->pathname, pathname))
288  return jtc;
289  }
290 
291  return NULL;
292 }
293 
294 static Node *
296  JsonTablePlan *plan)
297 {
298  JsonTableParent *node;
299  char *pathname = jtc->pathname;
300 
301  node = transformJsonTableColumns(cxt, plan, jtc->columns, jtc->pathspec,
302  &pathname, jtc->location);
303  node->name = pstrdup(pathname);
304 
305  return (Node *) node;
306 }
307 
308 static Node *
309 makeJsonTableSiblingJoin(bool cross, Node *lnode, Node *rnode)
310 {
312 
313  join->larg = lnode;
314  join->rarg = rnode;
315  join->cross = cross;
316 
317  return (Node *) join;
318 }
319 
320 /*
321  * Recursively transform child JSON_TABLE plan.
322  *
323  * Default plan is transformed into a cross/union join of its nested columns.
324  * Simple and outer/inner plans are transformed into a JsonTableParent by
325  * finding and transforming corresponding nested column.
326  * Sibling plans are recursively transformed into a JsonTableSibling.
327  */
328 static Node *
330  List *columns)
331 {
332  JsonTableColumn *jtc = NULL;
333 
334  if (!plan || plan->plan_type == JSTP_DEFAULT)
335  {
336  /* unspecified or default plan */
337  Node *res = NULL;
338  ListCell *lc;
339  bool cross = plan && (plan->join_type & JSTPJ_CROSS);
340 
341  /* transform all nested columns into cross/union join */
342  foreach(lc, columns)
343  {
345  Node *node;
346 
347  if (jtc->coltype != JTC_NESTED)
348  continue;
349 
350  node = transformNestedJsonTableColumn(cxt, jtc, plan);
351 
352  /* join transformed node with previous sibling nodes */
353  res = res ? makeJsonTableSiblingJoin(cross, res, node) : node;
354  }
355 
356  return res;
357  }
358  else if (plan->plan_type == JSTP_SIMPLE)
359  {
360  jtc = findNestedJsonTableColumn(columns, plan->pathname);
361  }
362  else if (plan->plan_type == JSTP_JOINED)
363  {
364  if (plan->join_type == JSTPJ_INNER ||
365  plan->join_type == JSTPJ_OUTER)
366  {
367  Assert(plan->plan1->plan_type == JSTP_SIMPLE);
368  jtc = findNestedJsonTableColumn(columns, plan->plan1->pathname);
369  }
370  else
371  {
372  Node *node1 = transformJsonTableChildPlan(cxt, plan->plan1,
373  columns);
374  Node *node2 = transformJsonTableChildPlan(cxt, plan->plan2,
375  columns);
376 
378  node1, node2);
379  }
380  }
381  else
382  elog(ERROR, "invalid JSON_TABLE plan type %d", plan->plan_type);
383 
384  if (!jtc)
385  ereport(ERROR,
386  (errcode(ERRCODE_SYNTAX_ERROR),
387  errmsg("invalid JSON_TABLE plan"),
388  errdetail("path name was %s not found in nested columns list",
389  plan->pathname),
390  parser_errposition(cxt->pstate, plan->location)));
391 
392  return transformNestedJsonTableColumn(cxt, jtc, plan);
393 }
394 
395 /* Check whether type is json/jsonb, array, or record. */
396 static bool
398 {
399  char typtype;
400 
401  if (typid == JSONOID ||
402  typid == JSONBOID ||
403  typid == RECORDOID ||
404  type_is_array(typid))
405  return true;
406 
407  typtype = get_typtype(typid);
408 
409  if (typtype == TYPTYPE_COMPOSITE)
410  return true;
411 
412  if (typtype == TYPTYPE_DOMAIN)
413  return typeIsComposite(getBaseType(typid));
414 
415  return false;
416 }
417 
418 /* Append transformed non-nested JSON_TABLE columns to the TableFunc node */
419 static void
421 {
422  ListCell *col;
423  ParseState *pstate = cxt->pstate;
424  JsonTable *jt = cxt->table;
425  TableFunc *tf = cxt->tablefunc;
426  bool errorOnError = jt->on_error &&
428 
429  foreach(col, columns)
430  {
432  Oid typid;
433  int32 typmod;
434  Node *colexpr;
435 
436  if (rawc->name)
437  {
438  /* make sure column names are unique */
439  ListCell *colname;
440 
441  foreach(colname, tf->colnames)
442  if (!strcmp((const char *) colname, rawc->name))
443  ereport(ERROR,
444  (errcode(ERRCODE_SYNTAX_ERROR),
445  errmsg("column name \"%s\" is not unique",
446  rawc->name),
447  parser_errposition(pstate, rawc->location)));
448 
449  tf->colnames = lappend(tf->colnames,
450  makeString(pstrdup(rawc->name)));
451  }
452 
453  /*
454  * Determine the type and typmod for the new column. FOR ORDINALITY
455  * columns are INTEGER by standard; the others are user-specified.
456  */
457  switch (rawc->coltype)
458  {
459  case JTC_FOR_ORDINALITY:
460  colexpr = NULL;
461  typid = INT4OID;
462  typmod = -1;
463  break;
464 
465  case JTC_REGULAR:
466  typenameTypeIdAndMod(pstate, rawc->typeName, &typid, &typmod);
467 
468  /*
469  * Use implicit FORMAT JSON for composite types (arrays and
470  * records)
471  */
472  if (typeIsComposite(typid))
473  rawc->coltype = JTC_FORMATTED;
474  else if (rawc->wrapper != JSW_NONE)
475  ereport(ERROR,
476  (errcode(ERRCODE_SYNTAX_ERROR),
477  errmsg("cannot use WITH WRAPPER clause with scalar columns"),
478  parser_errposition(pstate, rawc->location)));
479  else if (rawc->omit_quotes)
480  ereport(ERROR,
481  (errcode(ERRCODE_SYNTAX_ERROR),
482  errmsg("cannot use OMIT QUOTES clause with scalar columns"),
483  parser_errposition(pstate, rawc->location)));
484 
485  /* FALLTHROUGH */
486  case JTC_EXISTS:
487  case JTC_FORMATTED:
488  {
489  Node *je;
491 
492  param->collation = InvalidOid;
493  param->typeId = cxt->contextItemTypid;
494  param->typeMod = -1;
495 
496  je = transformJsonTableColumn(rawc, (Node *) param,
497  NIL, errorOnError);
498 
499  colexpr = transformExpr(pstate, je, EXPR_KIND_FROM_FUNCTION);
500  assign_expr_collations(pstate, colexpr);
501 
502  typid = exprType(colexpr);
503  typmod = exprTypmod(colexpr);
504  break;
505  }
506 
507  case JTC_NESTED:
508  continue;
509 
510  default:
511  elog(ERROR, "unknown JSON_TABLE column type: %d", rawc->coltype);
512  break;
513  }
514 
515  tf->coltypes = lappend_oid(tf->coltypes, typid);
516  tf->coltypmods = lappend_int(tf->coltypmods, typmod);
518  tf->colvalexprs = lappend(tf->colvalexprs, colexpr);
519  }
520 }
521 
522 /*
523  * Create transformed JSON_TABLE parent plan node by appending all non-nested
524  * columns to the TableFunc node and remembering their indices in the
525  * colvalexprs list.
526  */
527 static JsonTableParent *
528 makeParentJsonTableNode(JsonTableContext *cxt, char *pathSpec, List *columns)
529 {
531 
532  node->path = makeConst(JSONPATHOID, -1, InvalidOid, -1,
534  CStringGetDatum(pathSpec)),
535  false, false);
536 
537  /* save start of column range */
538  node->colMin = list_length(cxt->tablefunc->colvalexprs);
539 
540  appendJsonTableColumns(cxt, columns);
541 
542  /* save end of column range */
543  node->colMax = list_length(cxt->tablefunc->colvalexprs) - 1;
544 
545  node->errorOnError =
546  cxt->table->on_error &&
548 
549  return node;
550 }
551 
552 static JsonTableParent *
554  List *columns, char *pathSpec, char **pathName,
555  int location)
556 {
557  JsonTableParent *node;
558  JsonTablePlan *childPlan;
559  bool defaultPlan = !plan || plan->plan_type == JSTP_DEFAULT;
560 
561  if (!*pathName)
562  {
563  if (cxt->table->plan)
564  ereport(ERROR,
565  (errcode(ERRCODE_SYNTAX_ERROR),
566  errmsg("invalid JSON_TABLE expression"),
567  errdetail("JSON_TABLE columns must contain "
568  "explicit AS pathname specification if "
569  "explicit PLAN clause is used"),
570  parser_errposition(cxt->pstate, location)));
571 
572  *pathName = generateJsonTablePathName(cxt);
573  }
574 
575  if (defaultPlan)
576  childPlan = plan;
577  else
578  {
579  /* validate parent and child plans */
580  JsonTablePlan *parentPlan;
581 
582  if (plan->plan_type == JSTP_JOINED)
583  {
584  if (plan->join_type != JSTPJ_INNER &&
585  plan->join_type != JSTPJ_OUTER)
586  ereport(ERROR,
587  (errcode(ERRCODE_SYNTAX_ERROR),
588  errmsg("invalid JSON_TABLE plan"),
589  errdetail("expected INNER or OUTER JSON_TABLE plan node"),
590  parser_errposition(cxt->pstate, plan->location)));
591 
592  parentPlan = plan->plan1;
593  childPlan = plan->plan2;
594 
595  Assert(parentPlan->plan_type != JSTP_JOINED);
596  Assert(parentPlan->pathname);
597  }
598  else
599  {
600  parentPlan = plan;
601  childPlan = NULL;
602  }
603 
604  if (strcmp(parentPlan->pathname, *pathName))
605  ereport(ERROR,
606  (errcode(ERRCODE_SYNTAX_ERROR),
607  errmsg("invalid JSON_TABLE plan"),
608  errdetail("path name mismatch: expected %s but %s is given",
609  *pathName, parentPlan->pathname),
610  parser_errposition(cxt->pstate, plan->location)));
611 
612  validateJsonTableChildPlan(cxt->pstate, childPlan, columns);
613  }
614 
615  /* transform only non-nested columns */
616  node = makeParentJsonTableNode(cxt, pathSpec, columns);
617  node->name = pstrdup(*pathName);
618 
619  if (childPlan || defaultPlan)
620  {
621  /* transform recursively nested columns */
622  node->child = transformJsonTableChildPlan(cxt, childPlan, columns);
623  if (node->child)
624  node->outerJoin = !plan || (plan->join_type & JSTPJ_OUTER);
625  /* else: default plan case, no children found */
626  }
627 
628  return node;
629 }
630 
631 /*
632  * transformJsonTable -
633  * Transform a raw JsonTable into TableFunc.
634  *
635  * Transform the document-generating expression, the row-generating expression,
636  * the column-generating expressions, and the default value expressions.
637  */
640 {
641  JsonTableContext cxt;
644  JsonTablePlan *plan = jt->plan;
645  JsonCommon *jscommon;
646  char *rootPathName = jt->common->pathname;
647  char *rootPath;
648  bool is_lateral;
649 
650  cxt.pstate = pstate;
651  cxt.table = jt;
652  cxt.tablefunc = tf;
653  cxt.pathNames = NIL;
654  cxt.pathNameId = 0;
655 
656  if (rootPathName)
657  registerJsonTableColumn(&cxt, rootPathName);
658 
660 
661 #if 0 /* XXX it' unclear from the standard whether
662  * root path name is mandatory or not */
663  if (plan && plan->plan_type != JSTP_DEFAULT && !rootPathName)
664  {
665  /* Assign root path name and create corresponding plan node */
666  JsonTablePlan *rootNode = makeNode(JsonTablePlan);
667  JsonTablePlan *rootPlan = (JsonTablePlan *)
669  (Node *) plan, jt->location);
670 
671  rootPathName = generateJsonTablePathName(&cxt);
672 
673  rootNode->plan_type = JSTP_SIMPLE;
674  rootNode->pathname = rootPathName;
675 
676  plan = rootPlan;
677  }
678 #endif
679 
680  jscommon = copyObject(jt->common);
681  jscommon->pathspec = makeStringConst(pstrdup("$"), -1);
682 
683  jfe->op = JSON_TABLE_OP;
684  jfe->common = jscommon;
685  jfe->on_error = jt->on_error;
686  jfe->location = jt->common->location;
687 
688  /*
689  * We make lateral_only names of this level visible, whether or not the
690  * RangeTableFunc is explicitly marked LATERAL. This is needed for SQL
691  * spec compliance and seems useful on convenience grounds for all
692  * functions in FROM.
693  *
694  * (LATERAL can't nest within a single pstate level, so we don't need
695  * save/restore logic here.)
696  */
697  Assert(!pstate->p_lateral_active);
698  pstate->p_lateral_active = true;
699 
700  tf->functype = TFT_JSON_TABLE;
701  tf->docexpr = transformExpr(pstate, (Node *) jfe, EXPR_KIND_FROM_FUNCTION);
702 
703  cxt.contextItemTypid = exprType(tf->docexpr);
704 
705  if (!IsA(jt->common->pathspec, A_Const) ||
706  castNode(A_Const, jt->common->pathspec)->val.node.type != T_String)
707  ereport(ERROR,
708  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
709  errmsg("only string constants supported in JSON_TABLE path specification"),
710  parser_errposition(pstate,
711  exprLocation(jt->common->pathspec))));
712 
713  rootPath = castNode(A_Const, jt->common->pathspec)->val.sval.sval;
714 
715  tf->plan = (Node *) transformJsonTableColumns(&cxt, plan, jt->columns,
716  rootPath, &rootPathName,
717  jt->common->location);
718 
719  tf->ordinalitycol = -1; /* undefine ordinality column number */
720  tf->location = jt->location;
721 
722  pstate->p_lateral_active = false;
723 
724  /*
725  * Mark the RTE as LATERAL if the user said LATERAL explicitly, or if
726  * there are any lateral cross-references in it.
727  */
728  is_lateral = jt->lateral || contain_vars_of_level((Node *) tf, 0);
729 
730  return addRangeTableEntryForTableFunc(pstate,
731  tf, jt->alias, is_lateral, true);
732 }
signed int int32
Definition: c.h:429
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int errhint(const char *fmt,...)
Definition: elog.c:1151
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
#define ereport(elevel,...)
Definition: elog.h:143
const char * name
Definition: encode.c:561
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:631
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1587
Datum jsonpath_in(PG_FUNCTION_ARGS)
Definition: jsonpath.c:95
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:336
List * lappend_int(List *list, int datum)
Definition: list.c:354
List * lappend_oid(List *list, Oid datum)
Definition: list.c:372
Oid get_typcollation(Oid typid)
Definition: lsyscache.c:3013
char get_typtype(Oid typid)
Definition: lsyscache.c:2586
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2478
#define type_is_array(typid)
Definition: lsyscache.h:202
JsonBehavior * makeJsonBehavior(JsonBehaviorType type, Node *default_expr)
Definition: makefuncs.c:860
JsonValueExpr * makeJsonValueExpr(Expr *expr, JsonFormat *format)
Definition: makefuncs.c:844
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:300
JsonFormat * makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
Definition: makefuncs.c:828
Node * makeJsonTableJoinedPlan(JsonTablePlanJoinType type, Node *plan1, Node *plan2, int location)
Definition: makefuncs.c:875
char * pstrdup(const char *in)
Definition: mcxt.c:1305
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:286
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1343
#define IsA(nodeptr, _type_)
Definition: nodes.h:624
#define copyObject(obj)
Definition: nodes.h:689
@ T_String
Definition: nodes.h:311
#define makeNode(_type_)
Definition: nodes.h:621
#define castNode(_type_, nodeptr)
Definition: nodes.h:642
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:112
static JsonTableParent * makeParentJsonTableNode(JsonTableContext *cxt, char *pathSpec, List *columns)
static Node * makeStringConst(char *str, int location)
static bool typeIsComposite(Oid typid)
static bool isJsonTablePathNameDuplicate(JsonTableContext *cxt, const char *pathname)
static Node * transformJsonTableChildPlan(JsonTableContext *cxt, JsonTablePlan *plan, List *columns)
static Node * transformJsonTableColumn(JsonTableColumn *jtc, Node *contextItemExpr, List *passingArgs, bool errorOnError)
static void registerJsonTableColumn(JsonTableContext *cxt, char *colname)
static JsonTableParent * transformJsonTableColumns(JsonTableContext *cxt, JsonTablePlan *plan, List *columns, char *pathSpec, char **pathName, int location)
static void collectSiblingPathsInJsonTablePlan(JsonTablePlan *plan, List **paths)
static Node * makeJsonTableSiblingJoin(bool cross, Node *lnode, Node *rnode)
static JsonTableColumn * findNestedJsonTableColumn(List *columns, const char *pathname)
static void appendJsonTableColumns(JsonTableContext *cxt, List *columns)
ParseNamespaceItem * transformJsonTable(ParseState *pstate, JsonTable *jt)
static void registerAllJsonTableColumns(JsonTableContext *cxt, List *columns)
static char * generateJsonTablePathName(JsonTableContext *cxt)
static void validateJsonTableChildPlan(ParseState *pstate, JsonTablePlan *plan, List *columns)
static Node * transformNestedJsonTableColumn(JsonTableContext *cxt, JsonTableColumn *jtc, JsonTablePlan *plan)
struct JsonTableContext JsonTableContext
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
@ EXPR_KIND_FROM_FUNCTION
Definition: parse_node.h:45
ParseNamespaceItem * addRangeTableEntryForTableFunc(ParseState *pstate, TableFunc *tf, Alias *alias, bool lateral, bool inFromCl)
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition: parse_type.c:310
@ JTC_FORMATTED
Definition: parsenodes.h:1619
@ JTC_FOR_ORDINALITY
Definition: parsenodes.h:1616
@ JTC_NESTED
Definition: parsenodes.h:1620
@ JTC_EXISTS
Definition: parsenodes.h:1618
@ JTC_REGULAR
Definition: parsenodes.h:1617
@ JSTP_JOINED
Definition: parsenodes.h:1705
@ JSTP_DEFAULT
Definition: parsenodes.h:1703
@ JSTP_SIMPLE
Definition: parsenodes.h:1704
@ JSTPJ_INNER
Definition: parsenodes.h:1714
@ JSTPJ_UNION
Definition: parsenodes.h:1717
@ JSTPJ_OUTER
Definition: parsenodes.h:1715
@ JSTPJ_CROSS
Definition: parsenodes.h:1716
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
#define NIL
Definition: pg_list.h:65
static void output(uint64 loop_count)
#define snprintf
Definition: port.h:225
#define CStringGetDatum(X)
Definition: postgres.h:622
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ JS_FORMAT_DEFAULT
Definition: primnodes.h:1275
@ TFT_JSON_TABLE
Definition: primnodes.h:79
@ JS_ENC_DEFAULT
Definition: primnodes.h:1263
@ JSW_NONE
Definition: primnodes.h:1307
@ JSON_BEHAVIOR_ERROR
Definition: primnodes.h:1291
@ JSON_QUERY_OP
Definition: primnodes.h:1252
@ JSON_TABLE_OP
Definition: primnodes.h:1254
@ JSON_EXISTS_OP
Definition: primnodes.h:1253
@ JSON_VALUE_OP
Definition: primnodes.h:1251
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int location
Definition: parsenodes.h:318
union A_Const::ValUnion val
int32 typeMod
Definition: primnodes.h:1028
JsonBehaviorType btype
Definition: primnodes.h:1409
char * pathname
Definition: parsenodes.h:1654
JsonValueExpr * expr
Definition: parsenodes.h:1652
List * passing
Definition: parsenodes.h:1655
Node * pathspec
Definition: parsenodes.h:1653
JsonOutput * output
Definition: parsenodes.h:1668
bool omit_quotes
Definition: parsenodes.h:1672
JsonWrapper wrapper
Definition: parsenodes.h:1671
JsonExprOp op
Definition: parsenodes.h:1666
JsonBehavior * on_empty
Definition: parsenodes.h:1669
JsonBehavior * on_error
Definition: parsenodes.h:1670
JsonCommon * common
Definition: parsenodes.h:1667
JsonTableColumnType coltype
Definition: parsenodes.h:1683
JsonBehavior * on_empty
Definition: parsenodes.h:1692
JsonWrapper wrapper
Definition: parsenodes.h:1689
JsonBehavior * on_error
Definition: parsenodes.h:1693
JsonFormat * format
Definition: parsenodes.h:1688
TypeName * typeName
Definition: parsenodes.h:1685
ParseState * pstate
TableFunc * tablefunc
JsonTable * table
JsonTablePlanJoinType join_type
Definition: parsenodes.h:1730
JsonTablePlan * plan1
Definition: parsenodes.h:1731
JsonTablePlan * plan2
Definition: parsenodes.h:1732
char * pathname
Definition: parsenodes.h:1733
JsonTablePlanType plan_type
Definition: parsenodes.h:1729
JsonBehavior * on_error
Definition: parsenodes.h:1747
List * columns
Definition: parsenodes.h:1745
JsonCommon * common
Definition: parsenodes.h:1744
Alias * alias
Definition: parsenodes.h:1748
bool lateral
Definition: parsenodes.h:1749
JsonTablePlan * plan
Definition: parsenodes.h:1746
int location
Definition: parsenodes.h:1750
Definition: pg_list.h:51
Definition: nodes.h:574
NodeTag type
Definition: nodes.h:575
bool p_lateral_active
Definition: parse_node.h:189
char * sval
Definition: value.h:60
List * colvalexprs
Definition: primnodes.h:102
Node * docexpr
Definition: primnodes.h:94
List * coltypmods
Definition: primnodes.h:98
Node * plan
Definition: primnodes.h:104
List * coltypes
Definition: primnodes.h:97
List * colnames
Definition: primnodes.h:96
int location
Definition: primnodes.h:106
List * colcollations
Definition: primnodes.h:99
TableFuncType functype
Definition: primnodes.h:91
int ordinalitycol
Definition: primnodes.h:105
String * makeString(char *str)
Definition: value.c:63
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:438