pg_query 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Rakefile +4 -4
  4. data/ext/pg_query/ext_symbols_freebsd_with_ruby_abi_version.sym +2 -0
  5. data/ext/pg_query/ext_symbols_openbsd.sym +1 -0
  6. data/ext/pg_query/ext_symbols_openbsd_with_ruby_abi_version.sym +2 -0
  7. data/ext/pg_query/ext_symbols_with_ruby_abi_version.sym +2 -0
  8. data/ext/pg_query/extconf.rb +20 -6
  9. data/ext/pg_query/include/pg_query.h +2 -2
  10. data/ext/pg_query/include/postgres/access/amapi.h +4 -0
  11. data/ext/pg_query/include/postgres/access/genam.h +9 -0
  12. data/ext/pg_query/include/postgres/access/slru.h +3 -6
  13. data/ext/pg_query/include/postgres/access/tableam.h +2 -1
  14. data/ext/pg_query/include/postgres/access/transam.h +43 -0
  15. data/ext/pg_query/include/postgres/c.h +1 -1
  16. data/ext/pg_query/include/postgres/catalog/objectaddress.h +4 -0
  17. data/ext/pg_query/include/postgres/commands/event_trigger.h +6 -0
  18. data/ext/pg_query/include/postgres/common/hashfn_unstable.h +6 -52
  19. data/ext/pg_query/include/postgres/datatype/timestamp.h +1 -1
  20. data/ext/pg_query/include/postgres/executor/execdesc.h +1 -1
  21. data/ext/pg_query/include/postgres/libpq/libpq-be.h +6 -3
  22. data/ext/pg_query/include/postgres/mb/pg_wchar.h +1 -0
  23. data/ext/pg_query/include/postgres/miscadmin.h +10 -2
  24. data/ext/pg_query/include/postgres/nodes/execnodes.h +3 -0
  25. data/ext/pg_query/include/postgres/nodes/pathnodes.h +4 -1
  26. data/ext/pg_query/include/postgres/nodes/pg_list.h +1 -1
  27. data/ext/pg_query/include/postgres/nodes/primnodes.h +9 -5
  28. data/ext/pg_query/include/postgres/parser/parse_coerce.h +3 -0
  29. data/ext/pg_query/include/postgres/pg_config.h +28 -20
  30. data/ext/pg_query/include/postgres/port/pg_iovec.h +2 -2
  31. data/ext/pg_query/include/postgres/port/win32_port.h +0 -2
  32. data/ext/pg_query/include/postgres/port.h +32 -1
  33. data/ext/pg_query/include/postgres/replication/reorderbuffer.h +9 -18
  34. data/ext/pg_query/include/postgres/replication/slot.h +5 -1
  35. data/ext/pg_query/include/postgres/storage/lockdefs.h +2 -0
  36. data/ext/pg_query/include/postgres/storage/proc.h +13 -16
  37. data/ext/pg_query/include/postgres/storage/smgr.h +5 -2
  38. data/ext/pg_query/include/postgres/utils/catcache.h +1 -0
  39. data/ext/pg_query/include/postgres/utils/pgstat_internal.h +19 -0
  40. data/ext/pg_query/include/postgres/utils/portal.h +1 -1
  41. data/ext/pg_query/include/postgres/utils/syscache.h +5 -0
  42. data/ext/pg_query/postgres_deparse.c +197 -156
  43. data/ext/pg_query/src_backend_parser_gram.c +1 -1
  44. data/ext/pg_query/src_common_wchar.c +47 -1
  45. data/ext/pg_query/src_port_snprintf.c +14 -17
  46. data/lib/pg_query/fingerprint.rb +3 -5
  47. data/lib/pg_query/param_refs.rb +1 -1
  48. data/lib/pg_query/parse.rb +5 -7
  49. data/lib/pg_query/parse_error.rb +1 -0
  50. data/lib/pg_query/pg_query_pb.rb +1 -22
  51. data/lib/pg_query/scan.rb +1 -0
  52. data/lib/pg_query/treewalker.rb +2 -6
  53. data/lib/pg_query/truncate.rb +17 -19
  54. data/lib/pg_query/version.rb +1 -1
  55. metadata +15 -80
  56. /data/ext/pg_query/{pg_query_ruby.sym → ext_symbols.sym} +0 -0
  57. /data/ext/pg_query/{pg_query_ruby_freebsd.sym → ext_symbols_freebsd.sym} +0 -0
@@ -20,12 +20,7 @@ typedef enum DeparseNodeContext {
20
20
  DEPARSE_NODE_CONTEXT_NONE,
21
21
  // Parent node type (and sometimes field)
22
22
  DEPARSE_NODE_CONTEXT_INSERT_RELATION,
23
- DEPARSE_NODE_CONTEXT_INSERT_ON_CONFLICT,
24
- DEPARSE_NODE_CONTEXT_UPDATE,
25
- DEPARSE_NODE_CONTEXT_RETURNING,
26
23
  DEPARSE_NODE_CONTEXT_A_EXPR,
27
- DEPARSE_NODE_CONTEXT_XMLATTRIBUTES,
28
- DEPARSE_NODE_CONTEXT_XMLNAMESPACES,
29
24
  DEPARSE_NODE_CONTEXT_CREATE_TYPE,
30
25
  DEPARSE_NODE_CONTEXT_ALTER_TYPE,
31
26
  DEPARSE_NODE_CONTEXT_SET_STATEMENT,
@@ -186,9 +181,9 @@ static void deparseReplicaIdentityStmt(StringInfo str, ReplicaIdentityStmt *repl
186
181
  static void deparseRangeTableSample(StringInfo str, RangeTableSample *range_table_sample);
187
182
  static void deparseRangeTableFunc(StringInfo str, RangeTableFunc* range_table_func);
188
183
  static void deparseGroupingSet(StringInfo str, GroupingSet *grouping_set);
189
- static void deparseFuncCall(StringInfo str, FuncCall *func_call);
184
+ static void deparseFuncCall(StringInfo str, FuncCall *func_call, DeparseNodeContext context);
190
185
  static void deparseMinMaxExpr(StringInfo str, MinMaxExpr *min_max_expr);
191
- static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr);
186
+ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr, DeparseNodeContext context);
192
187
  static void deparseXmlSerialize(StringInfo str, XmlSerialize *xml_serialize);
193
188
  static void deparseJsonIsPredicate(StringInfo str, JsonIsPredicate *json_is_predicate);
194
189
  static void deparseJsonObjectAgg(StringInfo str, JsonObjectAgg *json_object_agg);
@@ -266,12 +261,12 @@ static void deparseAnyNameSkipLast(StringInfo str, List *parts)
266
261
  }
267
262
 
268
263
  // "func_expr" in gram.y
269
- static void deparseFuncExpr(StringInfo str, Node *node)
264
+ static void deparseFuncExpr(StringInfo str, Node *node, DeparseNodeContext context)
270
265
  {
271
266
  switch (nodeTag(node))
272
267
  {
273
268
  case T_FuncCall:
274
- deparseFuncCall(str, castNode(FuncCall, node));
269
+ deparseFuncCall(str, castNode(FuncCall, node), context);
275
270
  break;
276
271
  case T_SQLValueFunction:
277
272
  deparseSQLValueFunction(str, castNode(SQLValueFunction, node));
@@ -283,7 +278,7 @@ static void deparseFuncExpr(StringInfo str, Node *node)
283
278
  deparseCoalesceExpr(str, castNode(CoalesceExpr, node));
284
279
  break;
285
280
  case T_XmlExpr:
286
- deparseXmlExpr(str, castNode(XmlExpr, node));
281
+ deparseXmlExpr(str, castNode(XmlExpr, node), context);
287
282
  break;
288
283
  case T_XmlSerialize:
289
284
  deparseXmlSerialize(str, castNode(XmlSerialize, node));
@@ -313,7 +308,7 @@ static void deparseFuncExpr(StringInfo str, Node *node)
313
308
  static void deparseCExpr(StringInfo str, Node *node);
314
309
 
315
310
  // "a_expr" in gram.y
316
- static void deparseExpr(StringInfo str, Node *node)
311
+ static void deparseExpr(StringInfo str, Node *node, DeparseNodeContext context)
317
312
  {
318
313
  if (node == NULL)
319
314
  return;
@@ -337,7 +332,7 @@ static void deparseExpr(StringInfo str, Node *node)
337
332
  deparseCollateClause(str, castNode(CollateClause, node));
338
333
  break;
339
334
  case T_A_Expr:
340
- deparseAExpr(str, castNode(A_Expr, node), DEPARSE_NODE_CONTEXT_NONE);
335
+ deparseAExpr(str, castNode(A_Expr, node), DEPARSE_NODE_CONTEXT_A_EXPR);
341
336
  break;
342
337
  case T_BoolExpr:
343
338
  deparseBoolExpr(str, castNode(BoolExpr, node));
@@ -380,7 +375,7 @@ static void deparseExpr(StringInfo str, Node *node)
380
375
  case T_JsonObjectConstructor:
381
376
  case T_JsonArrayConstructor:
382
377
  case T_JsonArrayQueryConstructor:
383
- deparseFuncExpr(str, node);
378
+ deparseFuncExpr(str, node, context);
384
379
  break;
385
380
  default:
386
381
  // Note that this is also the fallthrough for deparseBExpr and deparseCExpr
@@ -394,7 +389,7 @@ static void deparseExpr(StringInfo str, Node *node)
394
389
  static void deparseBExpr(StringInfo str, Node *node)
395
390
  {
396
391
  if (IsA(node, XmlExpr)) {
397
- deparseXmlExpr(str, castNode(XmlExpr, node));
392
+ deparseXmlExpr(str, castNode(XmlExpr, node), DEPARSE_NODE_CONTEXT_NONE);
398
393
  return;
399
394
  }
400
395
 
@@ -418,6 +413,24 @@ static void deparseBExpr(StringInfo str, Node *node)
418
413
  deparseCExpr(str, node);
419
414
  }
420
415
 
416
+ // "AexprConst" in gram.y
417
+ static void deparseAexprConst(StringInfo str, Node *node)
418
+ {
419
+ switch (nodeTag(node))
420
+ {
421
+ case T_A_Const:
422
+ deparseAConst(str, castNode(A_Const, node));
423
+ break;
424
+ case T_TypeCast:
425
+ deparseTypeCast(str, castNode(TypeCast, node), DEPARSE_NODE_CONTEXT_NONE);
426
+ break;
427
+ default:
428
+ elog(ERROR, "deparse: unpermitted node type in AexprConst: %d",
429
+ (int) nodeTag(node));
430
+ break;
431
+ }
432
+ }
433
+
421
434
  // "c_expr" in gram.y
422
435
  static void deparseCExpr(StringInfo str, Node *node)
423
436
  {
@@ -461,11 +474,12 @@ static void deparseCExpr(StringInfo str, Node *node)
461
474
  case T_JsonObjectConstructor:
462
475
  case T_JsonArrayConstructor:
463
476
  case T_JsonArrayQueryConstructor:
464
- deparseFuncExpr(str, node);
477
+ deparseFuncExpr(str, node, DEPARSE_NODE_CONTEXT_NONE);
465
478
  break;
466
479
  default:
467
480
  appendStringInfoChar(str, '(');
468
- deparseExpr(str, node);
481
+ // Because we wrap this in parenthesis, the expression inside follows "a_expr" parser rules
482
+ deparseExpr(str, node, DEPARSE_NODE_CONTEXT_A_EXPR);
469
483
  appendStringInfoChar(str, ')');
470
484
  break;
471
485
  }
@@ -477,7 +491,7 @@ static void deparseExprList(StringInfo str, List *exprs)
477
491
  ListCell *lc;
478
492
  foreach(lc, exprs)
479
493
  {
480
- deparseExpr(str, lfirst(lc));
494
+ deparseExpr(str, lfirst(lc), DEPARSE_NODE_CONTEXT_A_EXPR);
481
495
  if (lnext(exprs, lc))
482
496
  appendStringInfoString(str, ", ");
483
497
  }
@@ -1583,7 +1597,7 @@ static void deparseTargetList(StringInfo str, List *l)
1583
1597
  else if (IsA(res_target->val, ColumnRef))
1584
1598
  deparseColumnRef(str, castNode(ColumnRef, res_target->val));
1585
1599
  else
1586
- deparseExpr(str, res_target->val);
1600
+ deparseExpr(str, res_target->val, DEPARSE_NODE_CONTEXT_A_EXPR);
1587
1601
 
1588
1602
  if (res_target->name != NULL) {
1589
1603
  appendStringInfoString(str, " AS ");
@@ -1621,7 +1635,7 @@ static void deparseXmlAttributeList(StringInfo str, List *l)
1621
1635
  ResTarget *res_target = castNode(ResTarget, lfirst(lc));
1622
1636
  Assert(res_target->val != NULL);
1623
1637
 
1624
- deparseExpr(str, res_target->val);
1638
+ deparseExpr(str, res_target->val, DEPARSE_NODE_CONTEXT_A_EXPR);
1625
1639
 
1626
1640
  if (res_target->name != NULL)
1627
1641
  {
@@ -1647,7 +1661,7 @@ static void deparseXmlNamespaceList(StringInfo str, List *l)
1647
1661
  if (res_target->name == NULL)
1648
1662
  appendStringInfoString(str, "DEFAULT ");
1649
1663
 
1650
- deparseExpr(str, res_target->val);
1664
+ deparseExpr(str, res_target->val, DEPARSE_NODE_CONTEXT_NONE /* b_expr */);
1651
1665
 
1652
1666
  if (res_target->name != NULL)
1653
1667
  {
@@ -1725,7 +1739,7 @@ static void deparseWhereClause(StringInfo str, Node *node)
1725
1739
  if (node != NULL)
1726
1740
  {
1727
1741
  appendStringInfoString(str, "WHERE ");
1728
- deparseExpr(str, node);
1742
+ deparseExpr(str, node, DEPARSE_NODE_CONTEXT_A_EXPR);
1729
1743
  appendStringInfoChar(str, ' ');
1730
1744
  }
1731
1745
  }
@@ -1745,7 +1759,7 @@ static void deparseWhereOrCurrentClause(StringInfo str, Node *node)
1745
1759
  appendStringInfoString(str, "CURRENT OF ");
1746
1760
  appendStringInfoString(str, quote_identifier(current_of_expr->cursor_name));
1747
1761
  } else {
1748
- deparseExpr(str, node);
1762
+ deparseExpr(str, node, DEPARSE_NODE_CONTEXT_A_EXPR);
1749
1763
  }
1750
1764
 
1751
1765
  appendStringInfoChar(str, ' ');
@@ -1761,7 +1775,7 @@ static void deparseGroupByList(StringInfo str, List *l)
1761
1775
  if (IsA(lfirst(lc), GroupingSet))
1762
1776
  deparseGroupingSet(str, castNode(GroupingSet, lfirst(lc)));
1763
1777
  else
1764
- deparseExpr(str, lfirst(lc));
1778
+ deparseExpr(str, lfirst(lc), DEPARSE_NODE_CONTEXT_A_EXPR);
1765
1779
 
1766
1780
  if (lnext(l, lc))
1767
1781
  appendStringInfoString(str, ", ");
@@ -1831,11 +1845,11 @@ static void deparseFuncArgExpr(StringInfo str, Node *node)
1831
1845
  NamedArgExpr *named_arg_expr = castNode(NamedArgExpr, node);
1832
1846
  appendStringInfoString(str, named_arg_expr->name);
1833
1847
  appendStringInfoString(str, " := ");
1834
- deparseExpr(str, (Node *) named_arg_expr->arg);
1848
+ deparseExpr(str, (Node *) named_arg_expr->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
1835
1849
  }
1836
1850
  else
1837
1851
  {
1838
- deparseExpr(str, node);
1852
+ deparseExpr(str, node, DEPARSE_NODE_CONTEXT_A_EXPR);
1839
1853
  }
1840
1854
  }
1841
1855
 
@@ -1875,14 +1889,14 @@ static void deparseSetClauseList(StringInfo str, List *target_list)
1875
1889
  appendStringInfoString(str, ", ");
1876
1890
  }
1877
1891
  appendStringInfoString(str, ") = ");
1878
- deparseExpr(str, r->source);
1892
+ deparseExpr(str, r->source, DEPARSE_NODE_CONTEXT_A_EXPR);
1879
1893
  skip_next_n_elems = r->ncolumns - 1;
1880
1894
  }
1881
1895
  else
1882
1896
  {
1883
1897
  deparseSetTarget(str, res_target);
1884
1898
  appendStringInfoString(str, " = ");
1885
- deparseExpr(str, res_target->val);
1899
+ deparseExpr(str, res_target->val, DEPARSE_NODE_CONTEXT_A_EXPR);
1886
1900
  }
1887
1901
  }
1888
1902
  }
@@ -1893,7 +1907,7 @@ static void deparseFuncExprWindowless(StringInfo str, Node* node)
1893
1907
  switch (nodeTag(node))
1894
1908
  {
1895
1909
  case T_FuncCall:
1896
- deparseFuncCall(str, castNode(FuncCall, node));
1910
+ deparseFuncCall(str, castNode(FuncCall, node), DEPARSE_NODE_CONTEXT_NONE /* we don't know which kind of expression */);
1897
1911
  break;
1898
1912
  case T_SQLValueFunction:
1899
1913
  deparseSQLValueFunction(str, castNode(SQLValueFunction, node));
@@ -1908,7 +1922,7 @@ static void deparseFuncExprWindowless(StringInfo str, Node* node)
1908
1922
  deparseMinMaxExpr(str, castNode(MinMaxExpr, node));
1909
1923
  break;
1910
1924
  case T_XmlExpr:
1911
- deparseXmlExpr(str, castNode(XmlExpr, node));
1925
+ deparseXmlExpr(str, castNode(XmlExpr, node), DEPARSE_NODE_CONTEXT_NONE /* we don't know which kind of expression */);
1912
1926
  break;
1913
1927
  case T_XmlSerialize:
1914
1928
  deparseXmlSerialize(str, castNode(XmlSerialize, node));
@@ -1955,7 +1969,7 @@ static void deparseIndexElem(StringInfo str, IndexElem* index_elem)
1955
1969
  break;
1956
1970
  default:
1957
1971
  appendStringInfoChar(str, '(');
1958
- deparseExpr(str, index_elem->expr);
1972
+ deparseExpr(str, index_elem->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
1959
1973
  appendStringInfoString(str, ") ");
1960
1974
  }
1961
1975
  }
@@ -2305,7 +2319,7 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2305
2319
  if (stmt->havingClause != NULL)
2306
2320
  {
2307
2321
  appendStringInfoString(str, "HAVING ");
2308
- deparseExpr(str, stmt->havingClause);
2322
+ deparseExpr(str, stmt->havingClause, DEPARSE_NODE_CONTEXT_A_EXPR);
2309
2323
  appendStringInfoChar(str, ' ');
2310
2324
  }
2311
2325
 
@@ -2388,7 +2402,7 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2388
2402
  else if (stmt->limitOption == LIMIT_OPTION_WITH_TIES)
2389
2403
  deparseCExpr(str, stmt->limitCount);
2390
2404
  else
2391
- deparseExpr(str, stmt->limitCount);
2405
+ deparseExpr(str, stmt->limitCount, DEPARSE_NODE_CONTEXT_NONE /* c_expr */);
2392
2406
 
2393
2407
  appendStringInfoChar(str, ' ');
2394
2408
 
@@ -2399,7 +2413,7 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2399
2413
  if (stmt->limitOffset != NULL)
2400
2414
  {
2401
2415
  appendStringInfoString(str, "OFFSET ");
2402
- deparseExpr(str, stmt->limitOffset);
2416
+ deparseExpr(str, stmt->limitOffset, DEPARSE_NODE_CONTEXT_A_EXPR);
2403
2417
  appendStringInfoChar(str, ' ');
2404
2418
  }
2405
2419
 
@@ -2525,7 +2539,7 @@ static void deparseAConst(StringInfo str, A_Const *a_const)
2525
2539
  deparseValue(str, val, DEPARSE_NODE_CONTEXT_CONSTANT);
2526
2540
  }
2527
2541
 
2528
- static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2542
+ static void deparseFuncCall(StringInfo str, FuncCall *func_call, DeparseNodeContext context)
2529
2543
  {
2530
2544
  const ListCell *lc = NULL;
2531
2545
 
@@ -2541,13 +2555,13 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2541
2555
  * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2542
2556
  */
2543
2557
  appendStringInfoString(str, "OVERLAY(");
2544
- deparseExpr(str, linitial(func_call->args));
2558
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2545
2559
  appendStringInfoString(str, " PLACING ");
2546
- deparseExpr(str, lsecond(func_call->args));
2560
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2547
2561
  appendStringInfoString(str, " FROM ");
2548
- deparseExpr(str, lthird(func_call->args));
2562
+ deparseExpr(str, lthird(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2549
2563
  appendStringInfoString(str, " FOR ");
2550
- deparseExpr(str, lfourth(func_call->args));
2564
+ deparseExpr(str, lfourth(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2551
2565
  appendStringInfoChar(str, ')');
2552
2566
  return;
2553
2567
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2561,13 +2575,13 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2561
2575
  */
2562
2576
  Assert(list_length(func_call->args) == 2 || list_length(func_call->args) == 3);
2563
2577
  appendStringInfoString(str, "SUBSTRING(");
2564
- deparseExpr(str, linitial(func_call->args));
2578
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2565
2579
  appendStringInfoString(str, " FROM ");
2566
- deparseExpr(str, lsecond(func_call->args));
2580
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2567
2581
  if (list_length(func_call->args) == 3)
2568
2582
  {
2569
2583
  appendStringInfoString(str, " FOR ");
2570
- deparseExpr(str, lthird(func_call->args));
2584
+ deparseExpr(str, lthird(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2571
2585
  }
2572
2586
  appendStringInfoChar(str, ')');
2573
2587
  return;
@@ -2599,11 +2613,11 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2599
2613
  * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2600
2614
  */
2601
2615
  appendStringInfoString(str, "overlay(");
2602
- deparseExpr(str, linitial(func_call->args));
2616
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2603
2617
  appendStringInfoString(str, " placing ");
2604
- deparseExpr(str, lsecond(func_call->args));
2618
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2605
2619
  appendStringInfoString(str, " from ");
2606
- deparseExpr(str, lthird(func_call->args));
2620
+ deparseExpr(str, lthird(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2607
2621
  appendStringInfoChar(str, ')');
2608
2622
  return;
2609
2623
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2617,7 +2631,7 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2617
2631
  * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2618
2632
  */
2619
2633
  appendStringInfoString(str, "collation for (");
2620
- deparseExpr(str, linitial(func_call->args));
2634
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2621
2635
  appendStringInfoChar(str, ')');
2622
2636
  return;
2623
2637
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2631,9 +2645,9 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2631
2645
  * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.extract)
2632
2646
  */
2633
2647
  appendStringInfoString(str, "extract (");
2634
- deparseExpr(str, linitial(func_call->args));
2648
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2635
2649
  appendStringInfoString(str, " FROM ");
2636
- deparseExpr(str, lsecond(func_call->args));
2650
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2637
2651
  appendStringInfoChar(str, ')');
2638
2652
  return;
2639
2653
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2648,16 +2662,16 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2648
2662
  * format: (start_1, end_1) overlaps (start_2, end_2)
2649
2663
  */
2650
2664
  appendStringInfoChar(str, '(');
2651
- deparseExpr(str, linitial(func_call->args));
2665
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2652
2666
  appendStringInfoString(str, ", ");
2653
- deparseExpr(str, lsecond(func_call->args));
2667
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2654
2668
  appendStringInfoString(str, ") ");
2655
2669
 
2656
2670
  appendStringInfoString(str, "overlaps ");
2657
2671
  appendStringInfoChar(str, '(');
2658
- deparseExpr(str, lthird(func_call->args));
2672
+ deparseExpr(str, lthird(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2659
2673
  appendStringInfoString(str, ", ");
2660
- deparseExpr(str, lfourth(func_call->args));
2674
+ deparseExpr(str, lfourth(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2661
2675
  appendStringInfoString(str, ") ");
2662
2676
  return;
2663
2677
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2684,9 +2698,9 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2684
2698
  appendStringInfoString(str, "TRAILING ");
2685
2699
 
2686
2700
  if (list_length(func_call->args) == 2)
2687
- deparseExpr(str, lsecond(func_call->args));
2701
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2688
2702
  appendStringInfoString(str, " FROM ");
2689
- deparseExpr(str, linitial(func_call->args));
2703
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2690
2704
  appendStringInfoChar(str, ')');
2691
2705
  return;
2692
2706
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2709,11 +2723,16 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2709
2723
  else
2710
2724
  e = lsecond(func_call->args);
2711
2725
 
2726
+ // If we're not inside an a_expr context, we must add wrapping parenthesis around the AT ... syntax
2727
+ if (context != DEPARSE_NODE_CONTEXT_A_EXPR) {
2728
+ appendStringInfoChar(str, '(');
2729
+ }
2730
+
2712
2731
  if (IsA(e, A_Expr)) {
2713
2732
  appendStringInfoChar(str, '(');
2714
2733
  }
2715
2734
 
2716
- deparseExpr(str, (Node*) e);
2735
+ deparseExpr(str, (Node*) e, DEPARSE_NODE_CONTEXT_A_EXPR);
2717
2736
 
2718
2737
  if (IsA(e, A_Expr)) {
2719
2738
  appendStringInfoChar(str, ')');
@@ -2723,8 +2742,13 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2723
2742
  appendStringInfoString(str, " AT LOCAL");
2724
2743
  else {
2725
2744
  appendStringInfoString(str, " AT TIME ZONE ");
2726
- deparseExpr(str, linitial(func_call->args));
2745
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2746
+ }
2747
+
2748
+ if (context != DEPARSE_NODE_CONTEXT_A_EXPR) {
2749
+ appendStringInfoChar(str, ')');
2727
2750
  }
2751
+
2728
2752
  return;
2729
2753
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2730
2754
  list_length(func_call->funcname) == 2 &&
@@ -2738,7 +2762,7 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2738
2762
  Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2739
2763
  appendStringInfoString(str, "normalize (");
2740
2764
 
2741
- deparseExpr(str, linitial(func_call->args));
2765
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2742
2766
  if (list_length(func_call->args) == 2)
2743
2767
  {
2744
2768
  appendStringInfoString(str, ", ");
@@ -2759,7 +2783,7 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2759
2783
  */
2760
2784
  Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2761
2785
 
2762
- deparseExpr(str, linitial(func_call->args));
2786
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
2763
2787
  appendStringInfoString(str, " IS ");
2764
2788
  if (list_length(func_call->args) == 2)
2765
2789
  {
@@ -2776,9 +2800,9 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2776
2800
  list_length(func_call->args) == 2)
2777
2801
  {
2778
2802
  appendStringInfoString(str, "xmlexists (");
2779
- deparseExpr(str, linitial(func_call->args));
2803
+ deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_NONE /* c_expr */);
2780
2804
  appendStringInfoString(str, " PASSING ");
2781
- deparseExpr(str, lsecond(func_call->args));
2805
+ deparseExpr(str, lsecond(func_call->args), DEPARSE_NODE_CONTEXT_NONE /* c_expr */);
2782
2806
  appendStringInfoChar(str, ')');
2783
2807
  return;
2784
2808
  } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
@@ -2832,7 +2856,7 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2832
2856
  if (func_call->agg_filter)
2833
2857
  {
2834
2858
  appendStringInfoString(str, "FILTER (WHERE ");
2835
- deparseExpr(str, func_call->agg_filter);
2859
+ deparseExpr(str, func_call->agg_filter, DEPARSE_NODE_CONTEXT_A_EXPR);
2836
2860
  appendStringInfoString(str, ") ");
2837
2861
  }
2838
2862
 
@@ -2899,13 +2923,13 @@ static void deparseWindowDef(StringInfo str, WindowDef* window_def)
2899
2923
  else if (window_def->frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING)
2900
2924
  {
2901
2925
  Assert(window_def->startOffset != NULL);
2902
- deparseExpr(str, window_def->startOffset);
2926
+ deparseExpr(str, window_def->startOffset, DEPARSE_NODE_CONTEXT_A_EXPR);
2903
2927
  appendStringInfoString(str, " PRECEDING ");
2904
2928
  }
2905
2929
  else if (window_def->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING)
2906
2930
  {
2907
2931
  Assert(window_def->startOffset != NULL);
2908
- deparseExpr(str, window_def->startOffset);
2932
+ deparseExpr(str, window_def->startOffset, DEPARSE_NODE_CONTEXT_A_EXPR);
2909
2933
  appendStringInfoString(str, " FOLLOWING ");
2910
2934
  }
2911
2935
 
@@ -2929,13 +2953,13 @@ static void deparseWindowDef(StringInfo str, WindowDef* window_def)
2929
2953
  else if (window_def->frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)
2930
2954
  {
2931
2955
  Assert(window_def->endOffset != NULL);
2932
- deparseExpr(str, window_def->endOffset);
2956
+ deparseExpr(str, window_def->endOffset, DEPARSE_NODE_CONTEXT_A_EXPR);
2933
2957
  appendStringInfoString(str, " PRECEDING ");
2934
2958
  }
2935
2959
  else if (window_def->frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING)
2936
2960
  {
2937
2961
  Assert(window_def->endOffset != NULL);
2938
- deparseExpr(str, window_def->endOffset);
2962
+ deparseExpr(str, window_def->endOffset, DEPARSE_NODE_CONTEXT_A_EXPR);
2939
2963
  appendStringInfoString(str, " FOLLOWING ");
2940
2964
  }
2941
2965
  }
@@ -2973,7 +2997,7 @@ static void deparseSubLink(StringInfo str, SubLink* sub_link)
2973
2997
  appendStringInfoChar(str, ')');
2974
2998
  return;
2975
2999
  case ALL_SUBLINK:
2976
- deparseExpr(str, sub_link->testexpr);
3000
+ deparseExpr(str, sub_link->testexpr, DEPARSE_NODE_CONTEXT_A_EXPR);
2977
3001
  appendStringInfoChar(str, ' ');
2978
3002
  deparseSubqueryOp(str, sub_link->operName);
2979
3003
  appendStringInfoString(str, " ALL (");
@@ -2981,7 +3005,7 @@ static void deparseSubLink(StringInfo str, SubLink* sub_link)
2981
3005
  appendStringInfoChar(str, ')');
2982
3006
  return;
2983
3007
  case ANY_SUBLINK:
2984
- deparseExpr(str, sub_link->testexpr);
3008
+ deparseExpr(str, sub_link->testexpr, DEPARSE_NODE_CONTEXT_A_EXPR);
2985
3009
  if (list_length(sub_link->operName) > 0)
2986
3010
  {
2987
3011
  appendStringInfoChar(str, ' ');
@@ -3021,6 +3045,7 @@ static void deparseSubLink(StringInfo str, SubLink* sub_link)
3021
3045
  }
3022
3046
  }
3023
3047
 
3048
+ // This handles "A_Expr" parse tree objects, which are a subset of the rules in "a_expr" (handled by deparseExpr)
3024
3049
  static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext context)
3025
3050
  {
3026
3051
  ListCell *lc;
@@ -3032,15 +3057,11 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3032
3057
  switch (a_expr->kind) {
3033
3058
  case AEXPR_OP: /* normal operator */
3034
3059
  {
3035
- bool need_outer_parens = context == DEPARSE_NODE_CONTEXT_A_EXPR;
3036
-
3037
- if (need_outer_parens)
3038
- appendStringInfoChar(str, '(');
3039
3060
  if (a_expr->lexpr != NULL)
3040
3061
  {
3041
3062
  if (need_lexpr_parens)
3042
3063
  appendStringInfoChar(str, '(');
3043
- deparseExpr(str, a_expr->lexpr);
3064
+ deparseExpr(str, a_expr->lexpr, context);
3044
3065
  if (need_lexpr_parens)
3045
3066
  appendStringInfoChar(str, ')');
3046
3067
  appendStringInfoChar(str, ' ');
@@ -3051,29 +3072,26 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3051
3072
  appendStringInfoChar(str, ' ');
3052
3073
  if (need_rexpr_parens)
3053
3074
  appendStringInfoChar(str, '(');
3054
- deparseExpr(str, a_expr->rexpr);
3075
+ deparseExpr(str, a_expr->rexpr, context);
3055
3076
  if (need_rexpr_parens)
3056
3077
  appendStringInfoChar(str, ')');
3057
3078
  }
3058
-
3059
- if (need_outer_parens)
3060
- appendStringInfoChar(str, ')');
3061
3079
  }
3062
3080
  return;
3063
3081
  case AEXPR_OP_ANY: /* scalar op ANY (array) */
3064
- deparseExpr(str, a_expr->lexpr);
3082
+ deparseExpr(str, a_expr->lexpr, context);
3065
3083
  appendStringInfoChar(str, ' ');
3066
3084
  deparseSubqueryOp(str, a_expr->name);
3067
3085
  appendStringInfoString(str, " ANY(");
3068
- deparseExpr(str, a_expr->rexpr);
3086
+ deparseExpr(str, a_expr->rexpr, context);
3069
3087
  appendStringInfoChar(str, ')');
3070
3088
  return;
3071
3089
  case AEXPR_OP_ALL: /* scalar op ALL (array) */
3072
- deparseExpr(str, a_expr->lexpr);
3090
+ deparseExpr(str, a_expr->lexpr, context);
3073
3091
  appendStringInfoChar(str, ' ');
3074
3092
  deparseSubqueryOp(str, a_expr->name);
3075
3093
  appendStringInfoString(str, " ALL(");
3076
- deparseExpr(str, a_expr->rexpr);
3094
+ deparseExpr(str, a_expr->rexpr, context);
3077
3095
  appendStringInfoChar(str, ')');
3078
3096
  return;
3079
3097
  case AEXPR_DISTINCT: /* IS DISTINCT FROM - name must be "=" */
@@ -3083,13 +3101,13 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3083
3101
 
3084
3102
  if (need_lexpr_parens)
3085
3103
  appendStringInfoChar(str, '(');
3086
- deparseExpr(str, a_expr->lexpr);
3104
+ deparseExpr(str, a_expr->lexpr, context);
3087
3105
  if (need_lexpr_parens)
3088
3106
  appendStringInfoChar(str, ')');
3089
3107
  appendStringInfoString(str, " IS DISTINCT FROM ");
3090
3108
  if (need_rexpr_parens)
3091
3109
  appendStringInfoChar(str, '(');
3092
- deparseExpr(str, a_expr->rexpr);
3110
+ deparseExpr(str, a_expr->rexpr, context);
3093
3111
  if (need_rexpr_parens)
3094
3112
  appendStringInfoChar(str, ')');
3095
3113
  return;
@@ -3098,9 +3116,9 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3098
3116
  Assert(IsA(linitial(a_expr->name), String));
3099
3117
  Assert(strcmp(strVal(linitial(a_expr->name)), "=") == 0);
3100
3118
 
3101
- deparseExpr(str, a_expr->lexpr);
3119
+ deparseExpr(str, a_expr->lexpr, context);
3102
3120
  appendStringInfoString(str, " IS NOT DISTINCT FROM ");
3103
- deparseExpr(str, a_expr->rexpr);
3121
+ deparseExpr(str, a_expr->rexpr, context);
3104
3122
  return;
3105
3123
  case AEXPR_NULLIF: /* NULLIF - name must be "=" */
3106
3124
  Assert(list_length(a_expr->name) == 1);
@@ -3108,16 +3126,16 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3108
3126
  Assert(strcmp(strVal(linitial(a_expr->name)), "=") == 0);
3109
3127
 
3110
3128
  appendStringInfoString(str, "NULLIF(");
3111
- deparseExpr(str, a_expr->lexpr);
3129
+ deparseExpr(str, a_expr->lexpr, context);
3112
3130
  appendStringInfoString(str, ", ");
3113
- deparseExpr(str, a_expr->rexpr);
3131
+ deparseExpr(str, a_expr->rexpr, context);
3114
3132
  appendStringInfoChar(str, ')');
3115
3133
  return;
3116
3134
  case AEXPR_IN: /* [NOT] IN - name must be "=" or "<>" */
3117
3135
  Assert(list_length(a_expr->name) == 1);
3118
3136
  Assert(IsA(linitial(a_expr->name), String));
3119
3137
  Assert(IsA(a_expr->rexpr, List));
3120
- deparseExpr(str, a_expr->lexpr);
3138
+ deparseExpr(str, a_expr->lexpr, context);
3121
3139
  appendStringInfoChar(str, ' ');
3122
3140
  name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
3123
3141
  if (strcmp(name, "=") == 0) {
@@ -3137,7 +3155,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3137
3155
  case AEXPR_LIKE: /* [NOT] LIKE - name must be "~~" or "!~~" */
3138
3156
  Assert(list_length(a_expr->name) == 1);
3139
3157
  Assert(IsA(linitial(a_expr->name), String));
3140
- deparseExpr(str, a_expr->lexpr);
3158
+ deparseExpr(str, a_expr->lexpr, context);
3141
3159
  appendStringInfoChar(str, ' ');
3142
3160
 
3143
3161
  name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
@@ -3149,12 +3167,12 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3149
3167
  Assert(false);
3150
3168
  }
3151
3169
 
3152
- deparseExpr(str, a_expr->rexpr);
3170
+ deparseExpr(str, a_expr->rexpr, context);
3153
3171
  return;
3154
3172
  case AEXPR_ILIKE: /* [NOT] ILIKE - name must be "~~*" or "!~~*" */
3155
3173
  Assert(list_length(a_expr->name) == 1);
3156
3174
  Assert(IsA(linitial(a_expr->name), String));
3157
- deparseExpr(str, a_expr->lexpr);
3175
+ deparseExpr(str, a_expr->lexpr, context);
3158
3176
  appendStringInfoChar(str, ' ');
3159
3177
 
3160
3178
  name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
@@ -3166,12 +3184,12 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3166
3184
  Assert(false);
3167
3185
  }
3168
3186
 
3169
- deparseExpr(str, a_expr->rexpr);
3187
+ deparseExpr(str, a_expr->rexpr, context);
3170
3188
  return;
3171
3189
  case AEXPR_SIMILAR: /* [NOT] SIMILAR - name must be "~" or "!~" */
3172
3190
  Assert(list_length(a_expr->name) == 1);
3173
3191
  Assert(IsA(linitial(a_expr->name), String));
3174
- deparseExpr(str, a_expr->lexpr);
3192
+ deparseExpr(str, a_expr->lexpr, context);
3175
3193
  appendStringInfoChar(str, ' ');
3176
3194
 
3177
3195
  name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
@@ -3189,11 +3207,11 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3189
3207
  Assert(strcmp(strVal(lsecond(n->funcname)), "similar_to_escape") == 0);
3190
3208
  Assert(list_length(n->args) == 1 || list_length(n->args) == 2);
3191
3209
 
3192
- deparseExpr(str, linitial(n->args));
3210
+ deparseExpr(str, linitial(n->args), context);
3193
3211
  if (list_length(n->args) == 2)
3194
3212
  {
3195
3213
  appendStringInfoString(str, " ESCAPE ");
3196
- deparseExpr(str, lsecond(n->args));
3214
+ deparseExpr(str, lsecond(n->args), context);
3197
3215
  }
3198
3216
 
3199
3217
  return;
@@ -3205,13 +3223,13 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
3205
3223
  Assert(IsA(linitial(a_expr->name), String));
3206
3224
  Assert(IsA(a_expr->rexpr, List));
3207
3225
 
3208
- deparseExpr(str, a_expr->lexpr);
3226
+ deparseExpr(str, a_expr->lexpr, context);
3209
3227
  appendStringInfoChar(str, ' ');
3210
3228
  appendStringInfoString(str, strVal(linitial(a_expr->name)));
3211
3229
  appendStringInfoChar(str, ' ');
3212
3230
 
3213
3231
  foreach(lc, castNode(List, a_expr->rexpr)) {
3214
- deparseExpr(str, lfirst(lc));
3232
+ deparseExpr(str, lfirst(lc), context);
3215
3233
  if (lnext(castNode(List, a_expr->rexpr), lc))
3216
3234
  appendStringInfoString(str, " AND ");
3217
3235
  }
@@ -3233,7 +3251,7 @@ static void deparseBoolExpr(StringInfo str, BoolExpr *bool_expr)
3233
3251
  if (need_parens)
3234
3252
  appendStringInfoChar(str, '(');
3235
3253
 
3236
- deparseExpr(str, lfirst(lc));
3254
+ deparseExpr(str, lfirst(lc), DEPARSE_NODE_CONTEXT_A_EXPR);
3237
3255
 
3238
3256
  if (need_parens)
3239
3257
  appendStringInfoChar(str, ')');
@@ -3251,7 +3269,7 @@ static void deparseBoolExpr(StringInfo str, BoolExpr *bool_expr)
3251
3269
  if (need_parens)
3252
3270
  appendStringInfoChar(str, '(');
3253
3271
 
3254
- deparseExpr(str, lfirst(lc));
3272
+ deparseExpr(str, lfirst(lc), DEPARSE_NODE_CONTEXT_A_EXPR);
3255
3273
 
3256
3274
  if (need_parens)
3257
3275
  appendStringInfoChar(str, ')');
@@ -3266,7 +3284,7 @@ static void deparseBoolExpr(StringInfo str, BoolExpr *bool_expr)
3266
3284
  appendStringInfoString(str, "NOT ");
3267
3285
  if (need_parens)
3268
3286
  appendStringInfoChar(str, '(');
3269
- deparseExpr(str, linitial(bool_expr->args));
3287
+ deparseExpr(str, linitial(bool_expr->args), DEPARSE_NODE_CONTEXT_A_EXPR);
3270
3288
  if (need_parens)
3271
3289
  appendStringInfoChar(str, ')');
3272
3290
  return;
@@ -3286,7 +3304,7 @@ static void deparseCollateClause(StringInfo str, CollateClause* collate_clause)
3286
3304
  bool need_parens = IsA(collate_clause->arg, A_Expr);
3287
3305
  if (need_parens)
3288
3306
  appendStringInfoChar(str, '(');
3289
- deparseExpr(str, collate_clause->arg);
3307
+ deparseExpr(str, collate_clause->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
3290
3308
  if (need_parens)
3291
3309
  appendStringInfoChar(str, ')');
3292
3310
  appendStringInfoChar(str, ' ');
@@ -3295,9 +3313,10 @@ static void deparseCollateClause(StringInfo str, CollateClause* collate_clause)
3295
3313
  deparseAnyName(str, collate_clause->collname);
3296
3314
  }
3297
3315
 
3316
+ // "sortby" in gram.y
3298
3317
  static void deparseSortBy(StringInfo str, SortBy* sort_by)
3299
3318
  {
3300
- deparseExpr(str, sort_by->node);
3319
+ deparseExpr(str, sort_by->node, DEPARSE_NODE_CONTEXT_A_EXPR);
3301
3320
  appendStringInfoChar(str, ' ');
3302
3321
 
3303
3322
  switch (sort_by->sortby_dir)
@@ -3414,6 +3433,7 @@ static void deparseWithClause(StringInfo str, WithClause *with_clause)
3414
3433
  removeTrailingSpace(str);
3415
3434
  }
3416
3435
 
3436
+ // "joined_table" in gram.y
3417
3437
  static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3418
3438
  {
3419
3439
  ListCell *lc;
@@ -3467,7 +3487,7 @@ static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3467
3487
  if (join_expr->quals != NULL)
3468
3488
  {
3469
3489
  appendStringInfoString(str, "ON ");
3470
- deparseExpr(str, join_expr->quals);
3490
+ deparseExpr(str, join_expr->quals, DEPARSE_NODE_CONTEXT_A_EXPR);
3471
3491
  appendStringInfoChar(str, ' ');
3472
3492
  }
3473
3493
 
@@ -3510,6 +3530,7 @@ static void deparseCTESearchClause(StringInfo str, CTESearchClause *search_claus
3510
3530
  appendStringInfoString(str, quote_identifier(search_clause->search_seq_column));
3511
3531
  }
3512
3532
 
3533
+ // "opt_cycle_clause" in gram.y
3513
3534
  static void deparseCTECycleClause(StringInfo str, CTECycleClause *cycle_clause)
3514
3535
  {
3515
3536
  appendStringInfoString(str, " CYCLE ");
@@ -3523,15 +3544,15 @@ static void deparseCTECycleClause(StringInfo str, CTECycleClause *cycle_clause)
3523
3544
  if (cycle_clause->cycle_mark_value)
3524
3545
  {
3525
3546
  appendStringInfoString(str, " TO ");
3526
- deparseExpr(str, cycle_clause->cycle_mark_value);
3547
+ deparseAexprConst(str, cycle_clause->cycle_mark_value);
3527
3548
  }
3528
-
3549
+
3529
3550
  if (cycle_clause->cycle_mark_default)
3530
3551
  {
3531
3552
  appendStringInfoString(str, " DEFAULT ");
3532
- deparseExpr(str, cycle_clause->cycle_mark_default);
3553
+ deparseAexprConst(str, cycle_clause->cycle_mark_default);
3533
3554
  }
3534
-
3555
+
3535
3556
  appendStringInfoString(str, " USING ");
3536
3557
  appendStringInfoString(str, quote_identifier(cycle_clause->cycle_path_column));
3537
3558
  }
@@ -3696,7 +3717,7 @@ static void deparseTypeCast(StringInfo str, TypeCast *type_cast, DeparseNodeCont
3696
3717
  if (IsA(type_cast->arg, A_Expr) || context == DEPARSE_NODE_CONTEXT_FUNC_EXPR)
3697
3718
  {
3698
3719
  appendStringInfoString(str, "CAST(");
3699
- deparseExpr(str, type_cast->arg);
3720
+ deparseExpr(str, type_cast->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
3700
3721
  appendStringInfoString(str, " AS ");
3701
3722
  deparseTypeName(str, type_cast->typeName);
3702
3723
  appendStringInfoChar(str, ')');
@@ -3763,7 +3784,7 @@ static void deparseTypeCast(StringInfo str, TypeCast *type_cast, DeparseNodeCont
3763
3784
 
3764
3785
  if (need_parens)
3765
3786
  appendStringInfoChar(str, '(');
3766
- deparseExpr(str, type_cast->arg);
3787
+ deparseExpr(str, type_cast->arg, DEPARSE_NODE_CONTEXT_NONE /* could be either a_expr or b_expr (we could pass this down, but that'd require two kinds of contexts most likely) */);
3767
3788
  if (need_parens)
3768
3789
  appendStringInfoChar(str, ')');
3769
3790
 
@@ -3992,7 +4013,7 @@ static void deparseNullTest(StringInfo str, NullTest *null_test)
3992
4013
  // argisrow is always false in raw parser output
3993
4014
  Assert(null_test->argisrow == false);
3994
4015
 
3995
- deparseExpr(str, (Node *) null_test->arg);
4016
+ deparseExpr(str, (Node *) null_test->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
3996
4017
  switch (null_test->nulltesttype)
3997
4018
  {
3998
4019
  case IS_NULL:
@@ -4004,6 +4025,7 @@ static void deparseNullTest(StringInfo str, NullTest *null_test)
4004
4025
  }
4005
4026
  }
4006
4027
 
4028
+ // "case_expr" in gram.y
4007
4029
  static void deparseCaseExpr(StringInfo str, CaseExpr *case_expr)
4008
4030
  {
4009
4031
  ListCell *lc;
@@ -4012,7 +4034,7 @@ static void deparseCaseExpr(StringInfo str, CaseExpr *case_expr)
4012
4034
 
4013
4035
  if (case_expr->arg != NULL)
4014
4036
  {
4015
- deparseExpr(str, (Node *) case_expr->arg);
4037
+ deparseExpr(str, (Node *) case_expr->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
4016
4038
  appendStringInfoChar(str, ' ');
4017
4039
  }
4018
4040
 
@@ -4025,19 +4047,20 @@ static void deparseCaseExpr(StringInfo str, CaseExpr *case_expr)
4025
4047
  if (case_expr->defresult != NULL)
4026
4048
  {
4027
4049
  appendStringInfoString(str, "ELSE ");
4028
- deparseExpr(str, (Node *) case_expr->defresult);
4050
+ deparseExpr(str, (Node *) case_expr->defresult, DEPARSE_NODE_CONTEXT_A_EXPR);
4029
4051
  appendStringInfoChar(str, ' ');
4030
4052
  }
4031
4053
 
4032
4054
  appendStringInfoString(str, "END");
4033
4055
  }
4034
4056
 
4057
+ // "when_clause" in gram.y
4035
4058
  static void deparseCaseWhen(StringInfo str, CaseWhen *case_when)
4036
4059
  {
4037
4060
  appendStringInfoString(str, "WHEN ");
4038
- deparseExpr(str, (Node *) case_when->expr);
4061
+ deparseExpr(str, (Node *) case_when->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
4039
4062
  appendStringInfoString(str, " THEN ");
4040
- deparseExpr(str, (Node *) case_when->result);
4063
+ deparseExpr(str, (Node *) case_when->result, DEPARSE_NODE_CONTEXT_A_EXPR);
4041
4064
  }
4042
4065
 
4043
4066
  static void deparseAIndirection(StringInfo str, A_Indirection *a_indirection)
@@ -4055,7 +4078,7 @@ static void deparseAIndirection(StringInfo str, A_Indirection *a_indirection)
4055
4078
  if (need_parens)
4056
4079
  appendStringInfoChar(str, '(');
4057
4080
 
4058
- deparseExpr(str, a_indirection->arg);
4081
+ deparseExpr(str, a_indirection->arg, need_parens ? DEPARSE_NODE_CONTEXT_A_EXPR : DEPARSE_NODE_CONTEXT_NONE);
4059
4082
 
4060
4083
  if (need_parens)
4061
4084
  appendStringInfoChar(str, ')');
@@ -4067,11 +4090,11 @@ static void deparseAIndices(StringInfo str, A_Indices *a_indices)
4067
4090
  {
4068
4091
  appendStringInfoChar(str, '[');
4069
4092
  if (a_indices->lidx != NULL)
4070
- deparseExpr(str, a_indices->lidx);
4093
+ deparseExpr(str, a_indices->lidx, DEPARSE_NODE_CONTEXT_A_EXPR);
4071
4094
  if (a_indices->is_slice)
4072
4095
  appendStringInfoChar(str, ':');
4073
4096
  if (a_indices->uidx != NULL)
4074
- deparseExpr(str, a_indices->uidx);
4097
+ deparseExpr(str, a_indices->uidx, DEPARSE_NODE_CONTEXT_A_EXPR);
4075
4098
  appendStringInfoChar(str, ']');
4076
4099
  }
4077
4100
 
@@ -4104,7 +4127,7 @@ static void deparseBooleanTest(StringInfo str, BooleanTest *boolean_test)
4104
4127
  if (need_parens)
4105
4128
  appendStringInfoChar(str, '(');
4106
4129
 
4107
- deparseExpr(str, (Node *) boolean_test->arg);
4130
+ deparseExpr(str, (Node *) boolean_test->arg, DEPARSE_NODE_CONTEXT_A_EXPR);
4108
4131
 
4109
4132
  if (need_parens)
4110
4133
  appendStringInfoChar(str, ')');
@@ -4134,6 +4157,7 @@ static void deparseBooleanTest(StringInfo str, BooleanTest *boolean_test)
4134
4157
  }
4135
4158
  }
4136
4159
 
4160
+ // "columnDef" and "alter_table_cmd" in gram.y
4137
4161
  static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
4138
4162
  {
4139
4163
  ListCell *lc;
@@ -4160,7 +4184,7 @@ static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
4160
4184
  if (column_def->raw_default != NULL)
4161
4185
  {
4162
4186
  appendStringInfoString(str, "USING ");
4163
- deparseExpr(str, column_def->raw_default);
4187
+ deparseExpr(str, column_def->raw_default, DEPARSE_NODE_CONTEXT_A_EXPR);
4164
4188
  appendStringInfoChar(str, ' ');
4165
4189
  }
4166
4190
 
@@ -4356,6 +4380,7 @@ static void deparseUpdateStmt(StringInfo str, UpdateStmt *update_stmt)
4356
4380
  removeTrailingSpace(str);
4357
4381
  }
4358
4382
 
4383
+ // "MergeStmt" in gram.y
4359
4384
  static void deparseMergeStmt(StringInfo str, MergeStmt *merge_stmt)
4360
4385
  {
4361
4386
  if (merge_stmt->withClause != NULL)
@@ -4373,7 +4398,7 @@ static void deparseMergeStmt(StringInfo str, MergeStmt *merge_stmt)
4373
4398
  appendStringInfoChar(str, ' ');
4374
4399
 
4375
4400
  appendStringInfoString(str, "ON ");
4376
- deparseExpr(str, merge_stmt->joinCondition);
4401
+ deparseExpr(str, merge_stmt->joinCondition, DEPARSE_NODE_CONTEXT_A_EXPR);
4377
4402
  appendStringInfoChar(str, ' ');
4378
4403
 
4379
4404
  ListCell *lc;
@@ -4399,7 +4424,7 @@ static void deparseMergeStmt(StringInfo str, MergeStmt *merge_stmt)
4399
4424
  if (clause->condition)
4400
4425
  {
4401
4426
  appendStringInfoString(str, "AND ");
4402
- deparseExpr(str, clause->condition);
4427
+ deparseExpr(str, clause->condition, DEPARSE_NODE_CONTEXT_A_EXPR);
4403
4428
  appendStringInfoChar(str, ' ');
4404
4429
  }
4405
4430
 
@@ -4775,6 +4800,7 @@ static void deparseCreateExtensionStmt(StringInfo str, CreateExtensionStmt *crea
4775
4800
  removeTrailingSpace(str);
4776
4801
  }
4777
4802
 
4803
+ // "ColConstraintElem" and "ConstraintElem" in gram.y
4778
4804
  static void deparseConstraint(StringInfo str, Constraint *constraint)
4779
4805
  {
4780
4806
  ListCell *lc;
@@ -4816,12 +4842,12 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4816
4842
  case CONSTR_GENERATED:
4817
4843
  Assert(constraint->generated_when == ATTRIBUTE_IDENTITY_ALWAYS);
4818
4844
  appendStringInfoString(str, "GENERATED ALWAYS AS (");
4819
- deparseExpr(str, constraint->raw_expr);
4845
+ deparseExpr(str, constraint->raw_expr, DEPARSE_NODE_CONTEXT_A_EXPR);
4820
4846
  appendStringInfoString(str, ") STORED ");
4821
4847
  break;
4822
4848
  case CONSTR_CHECK:
4823
4849
  appendStringInfoString(str, "CHECK (");
4824
- deparseExpr(str, constraint->raw_expr);
4850
+ deparseExpr(str, constraint->raw_expr, DEPARSE_NODE_CONTEXT_A_EXPR);
4825
4851
  appendStringInfoString(str, ") ");
4826
4852
  break;
4827
4853
  case CONSTR_PRIMARY:
@@ -4855,7 +4881,7 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4855
4881
  if (constraint->where_clause != NULL)
4856
4882
  {
4857
4883
  appendStringInfoString(str, "WHERE (");
4858
- deparseExpr(str, constraint->where_clause);
4884
+ deparseExpr(str, constraint->where_clause, DEPARSE_NODE_CONTEXT_A_EXPR);
4859
4885
  appendStringInfoString(str, ") ");
4860
4886
  }
4861
4887
  break;
@@ -5027,10 +5053,11 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
5027
5053
  removeTrailingSpace(str);
5028
5054
  }
5029
5055
 
5056
+ // "ReturnStmt" in gram.y
5030
5057
  static void deparseReturnStmt(StringInfo str, ReturnStmt *return_stmt)
5031
5058
  {
5032
5059
  appendStringInfoString(str, "RETURN ");
5033
- deparseExpr(str, return_stmt->returnval);
5060
+ deparseExpr(str, return_stmt->returnval, DEPARSE_NODE_CONTEXT_A_EXPR);
5034
5061
  }
5035
5062
 
5036
5063
  static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create_function_stmt)
@@ -5129,6 +5156,7 @@ static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create
5129
5156
  removeTrailingSpace(str);
5130
5157
  }
5131
5158
 
5159
+ // "func_arg", "func_arg_with_default" and other places in gram.y
5132
5160
  static void deparseFunctionParameter(StringInfo str, FunctionParameter *function_parameter)
5133
5161
  {
5134
5162
  switch (function_parameter->mode)
@@ -5169,7 +5197,7 @@ static void deparseFunctionParameter(StringInfo str, FunctionParameter *function
5169
5197
  if (function_parameter->defexpr != NULL)
5170
5198
  {
5171
5199
  appendStringInfoString(str, "= ");
5172
- deparseExpr(str, function_parameter->defexpr);
5200
+ deparseExpr(str, function_parameter->defexpr, DEPARSE_NODE_CONTEXT_A_EXPR);
5173
5201
  }
5174
5202
 
5175
5203
  removeTrailingSpace(str);
@@ -5290,7 +5318,7 @@ static void deparsePartitionElem(StringInfo str, PartitionElem *partition_elem)
5290
5318
  else if (partition_elem->expr != NULL)
5291
5319
  {
5292
5320
  appendStringInfoChar(str, '(');
5293
- deparseExpr(str, partition_elem->expr);
5321
+ deparseExpr(str, partition_elem->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
5294
5322
  appendStringInfoString(str, ") ");
5295
5323
  }
5296
5324
 
@@ -6352,6 +6380,7 @@ static void deparseAlterObjectSchemaStmt(StringInfo str, AlterObjectSchemaStmt *
6352
6380
  appendStringInfoString(str, quote_identifier(alter_object_schema_stmt->newschema));
6353
6381
  }
6354
6382
 
6383
+ // "alter_table_cmd" in gram.y
6355
6384
  static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd, DeparseNodeContext context)
6356
6385
  {
6357
6386
  ListCell *lc = NULL;
@@ -6643,7 +6672,7 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
6643
6672
  case AT_ColumnDefault:
6644
6673
  if (alter_table_cmd->def != NULL)
6645
6674
  {
6646
- deparseExpr(str, alter_table_cmd->def);
6675
+ deparseExpr(str, alter_table_cmd->def, DEPARSE_NODE_CONTEXT_A_EXPR);
6647
6676
  appendStringInfoChar(str, ' ');
6648
6677
  }
6649
6678
  break;
@@ -6699,7 +6728,7 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
6699
6728
  break;
6700
6729
  case AT_SetExpression:
6701
6730
  appendStringInfoString(str, "SET EXPRESSION AS (");
6702
- deparseExpr(str, alter_table_cmd->def);
6731
+ deparseExpr(str, alter_table_cmd->def, DEPARSE_NODE_CONTEXT_A_EXPR);
6703
6732
  appendStringInfoChar(str, ')');
6704
6733
  break;
6705
6734
  default:
@@ -6807,6 +6836,7 @@ static void deparseAlterTableSpaceOptionsStmt(StringInfo str, AlterTableSpaceOpt
6807
6836
  deparseRelOptions(str, alter_table_space_options_stmt->options);
6808
6837
  }
6809
6838
 
6839
+ // "AlterDomainStmt" in gram.y
6810
6840
  static void deparseAlterDomainStmt(StringInfo str, AlterDomainStmt *alter_domain_stmt)
6811
6841
  {
6812
6842
  appendStringInfoString(str, "ALTER DOMAIN ");
@@ -6819,7 +6849,7 @@ static void deparseAlterDomainStmt(StringInfo str, AlterDomainStmt *alter_domain
6819
6849
  if (alter_domain_stmt->def != NULL)
6820
6850
  {
6821
6851
  appendStringInfoString(str, "SET DEFAULT ");
6822
- deparseExpr(str, alter_domain_stmt->def);
6852
+ deparseExpr(str, alter_domain_stmt->def, DEPARSE_NODE_CONTEXT_A_EXPR);
6823
6853
  }
6824
6854
  else
6825
6855
  {
@@ -9045,6 +9075,7 @@ static void deparseReplicaIdentityStmt(StringInfo str, ReplicaIdentityStmt *repl
9045
9075
  }
9046
9076
  }
9047
9077
 
9078
+ // "CreatePolicyStmt" in gram.y
9048
9079
  static void deparseCreatePolicyStmt(StringInfo str, CreatePolicyStmt *create_policy_stmt)
9049
9080
  {
9050
9081
  ListCell *lc = NULL;
@@ -9078,18 +9109,19 @@ static void deparseCreatePolicyStmt(StringInfo str, CreatePolicyStmt *create_pol
9078
9109
  if (create_policy_stmt->qual != NULL)
9079
9110
  {
9080
9111
  appendStringInfoString(str, "USING (");
9081
- deparseExpr(str, create_policy_stmt->qual);
9112
+ deparseExpr(str, create_policy_stmt->qual, DEPARSE_NODE_CONTEXT_A_EXPR);
9082
9113
  appendStringInfoString(str, ") ");
9083
9114
  }
9084
9115
 
9085
9116
  if (create_policy_stmt->with_check != NULL)
9086
9117
  {
9087
9118
  appendStringInfoString(str, "WITH CHECK (");
9088
- deparseExpr(str, create_policy_stmt->with_check);
9119
+ deparseExpr(str, create_policy_stmt->with_check, DEPARSE_NODE_CONTEXT_A_EXPR);
9089
9120
  appendStringInfoString(str, ") ");
9090
9121
  }
9091
9122
  }
9092
9123
 
9124
+ // "AlterPolicyStmt" in gram.y
9093
9125
  static void deparseAlterPolicyStmt(StringInfo str, AlterPolicyStmt *alter_policy_stmt)
9094
9126
  {
9095
9127
  appendStringInfoString(str, "ALTER POLICY ");
@@ -9108,14 +9140,14 @@ static void deparseAlterPolicyStmt(StringInfo str, AlterPolicyStmt *alter_policy
9108
9140
  if (alter_policy_stmt->qual != NULL)
9109
9141
  {
9110
9142
  appendStringInfoString(str, "USING (");
9111
- deparseExpr(str, alter_policy_stmt->qual);
9143
+ deparseExpr(str, alter_policy_stmt->qual, DEPARSE_NODE_CONTEXT_A_EXPR);
9112
9144
  appendStringInfoString(str, ") ");
9113
9145
  }
9114
9146
 
9115
9147
  if (alter_policy_stmt->with_check != NULL)
9116
9148
  {
9117
9149
  appendStringInfoString(str, "WITH CHECK (");
9118
- deparseExpr(str, alter_policy_stmt->with_check);
9150
+ deparseExpr(str, alter_policy_stmt->with_check, DEPARSE_NODE_CONTEXT_A_EXPR);
9119
9151
  appendStringInfoString(str, ") ");
9120
9152
  }
9121
9153
  }
@@ -9202,6 +9234,7 @@ static void deparseCreateAmStmt(StringInfo str, CreateAmStmt *create_am_stmt)
9202
9234
  deparseHandlerName(str, create_am_stmt->handler_name);
9203
9235
  }
9204
9236
 
9237
+ // "pub_obj_list" in gram.y
9205
9238
  static void deparsePublicationObjectList(StringInfo str, List *pubobjects) {
9206
9239
  const ListCell *lc;
9207
9240
  foreach(lc, pubobjects) {
@@ -9222,7 +9255,7 @@ static void deparsePublicationObjectList(StringInfo str, List *pubobjects) {
9222
9255
  if (obj->pubtable->whereClause)
9223
9256
  {
9224
9257
  appendStringInfoString(str, " WHERE (");
9225
- deparseExpr(str, obj->pubtable->whereClause);
9258
+ deparseExpr(str, obj->pubtable->whereClause, DEPARSE_NODE_CONTEXT_A_EXPR);
9226
9259
  appendStringInfoString(str, ")");
9227
9260
  }
9228
9261
 
@@ -9571,6 +9604,7 @@ static void deparseCommentStmt(StringInfo str, CommentStmt *comment_stmt)
9571
9604
  appendStringInfoString(str, "NULL");
9572
9605
  }
9573
9606
 
9607
+ // "stats_param" in gram.y
9574
9608
  static void deparseStatsElem(StringInfo str, StatsElem *stats_elem)
9575
9609
  {
9576
9610
  // only one of stats_elem->name or stats_elem->expr can be non-null
@@ -9579,7 +9613,7 @@ static void deparseStatsElem(StringInfo str, StatsElem *stats_elem)
9579
9613
  else if (stats_elem->expr)
9580
9614
  {
9581
9615
  appendStringInfoChar(str, '(');
9582
- deparseExpr(str, stats_elem->expr);
9616
+ deparseExpr(str, stats_elem->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
9583
9617
  appendStringInfoChar(str, ')');
9584
9618
  }
9585
9619
  }
@@ -9727,6 +9761,7 @@ static void deparseVariableShowStmt(StringInfo str, VariableShowStmt *variable_s
9727
9761
  appendStringInfoString(str, quote_identifier(variable_show_stmt->name));
9728
9762
  }
9729
9763
 
9764
+ // "tablesample_clause" in gram.y
9730
9765
  static void deparseRangeTableSample(StringInfo str, RangeTableSample *range_table_sample)
9731
9766
  {
9732
9767
  deparseRangeVar(str, castNode(RangeVar, range_table_sample->relation), DEPARSE_NODE_CONTEXT_NONE);
@@ -9741,7 +9776,7 @@ static void deparseRangeTableSample(StringInfo str, RangeTableSample *range_tabl
9741
9776
  if (range_table_sample->repeatable != NULL)
9742
9777
  {
9743
9778
  appendStringInfoString(str, "REPEATABLE (");
9744
- deparseExpr(str, range_table_sample->repeatable);
9779
+ deparseExpr(str, range_table_sample->repeatable, DEPARSE_NODE_CONTEXT_A_EXPR);
9745
9780
  appendStringInfoString(str, ") ");
9746
9781
  }
9747
9782
 
@@ -9866,7 +9901,7 @@ static void deparseDropSubscriptionStmt(StringInfo str, DropSubscriptionStmt *dr
9866
9901
  static void deparseCallStmt(StringInfo str, CallStmt *call_stmt)
9867
9902
  {
9868
9903
  appendStringInfoString(str, "CALL ");
9869
- deparseFuncCall(str, call_stmt->funccall);
9904
+ deparseFuncCall(str, call_stmt->funccall, DEPARSE_NODE_CONTEXT_NONE);
9870
9905
  }
9871
9906
 
9872
9907
  static void deparseAlterOwnerStmt(StringInfo str, AlterOwnerStmt *alter_owner_stmt)
@@ -10058,6 +10093,7 @@ static void deparseClosePortalStmt(StringInfo str, ClosePortalStmt *close_portal
10058
10093
  }
10059
10094
  }
10060
10095
 
10096
+ // "CreateTrigStmt" in gram.y
10061
10097
  static void deparseCreateTrigStmt(StringInfo str, CreateTrigStmt *create_trig_stmt)
10062
10098
  {
10063
10099
  ListCell *lc;
@@ -10153,7 +10189,7 @@ static void deparseCreateTrigStmt(StringInfo str, CreateTrigStmt *create_trig_st
10153
10189
  if (create_trig_stmt->whenClause)
10154
10190
  {
10155
10191
  appendStringInfoString(str, "WHEN (");
10156
- deparseExpr(str, create_trig_stmt->whenClause);
10192
+ deparseExpr(str, create_trig_stmt->whenClause, DEPARSE_NODE_CONTEXT_A_EXPR);
10157
10193
  appendStringInfoString(str, ") ");
10158
10194
  }
10159
10195
 
@@ -10184,7 +10220,7 @@ static void deparseTriggerTransition(StringInfo str, TriggerTransition *trigger_
10184
10220
  appendStringInfoString(str, quote_identifier(trigger_transition->name));
10185
10221
  }
10186
10222
 
10187
- static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
10223
+ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr, DeparseNodeContext context)
10188
10224
  {
10189
10225
  switch (xml_expr->op)
10190
10226
  {
@@ -10228,7 +10264,7 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
10228
10264
  default:
10229
10265
  Assert(false);
10230
10266
  }
10231
- deparseExpr(str, linitial(xml_expr->args));
10267
+ deparseExpr(str, linitial(xml_expr->args), DEPARSE_NODE_CONTEXT_A_EXPR);
10232
10268
  appendStringInfoChar(str, ')');
10233
10269
  break;
10234
10270
  case IS_XMLPI: /* XMLPI(name [, args]) */
@@ -10237,18 +10273,18 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
10237
10273
  if (xml_expr->args != NULL)
10238
10274
  {
10239
10275
  appendStringInfoString(str, ", ");
10240
- deparseExpr(str, linitial(xml_expr->args));
10276
+ deparseExpr(str, linitial(xml_expr->args), DEPARSE_NODE_CONTEXT_A_EXPR);
10241
10277
  }
10242
10278
  appendStringInfoChar(str, ')');
10243
10279
  break;
10244
10280
  case IS_XMLROOT: /* XMLROOT(xml, version, standalone) */
10245
10281
  appendStringInfoString(str, "xmlroot(");
10246
- deparseExpr(str, linitial(xml_expr->args));
10282
+ deparseExpr(str, linitial(xml_expr->args), DEPARSE_NODE_CONTEXT_A_EXPR);
10247
10283
  appendStringInfoString(str, ", version ");
10248
10284
  if (castNode(A_Const, lsecond(xml_expr->args))->isnull)
10249
10285
  appendStringInfoString(str, "NO VALUE");
10250
10286
  else
10251
- deparseExpr(str, lsecond(xml_expr->args));
10287
+ deparseExpr(str, lsecond(xml_expr->args), DEPARSE_NODE_CONTEXT_A_EXPR);
10252
10288
  if (intVal(&castNode(A_Const, lthird(xml_expr->args))->val) == XML_STANDALONE_YES)
10253
10289
  appendStringInfoString(str, ", STANDALONE YES");
10254
10290
  else if (intVal(&castNode(A_Const, lthird(xml_expr->args))->val) == XML_STANDALONE_NO)
@@ -10263,12 +10299,13 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
10263
10299
  break;
10264
10300
  case IS_DOCUMENT: /* xmlval IS DOCUMENT */
10265
10301
  Assert(list_length(xml_expr->args) == 1);
10266
- deparseExpr(str, linitial(xml_expr->args));
10302
+ deparseExpr(str, linitial(xml_expr->args), context);
10267
10303
  appendStringInfoString(str, " IS DOCUMENT");
10268
10304
  break;
10269
10305
  }
10270
10306
  }
10271
10307
 
10308
+ // "xmltable_column_el" in gram.y
10272
10309
  static void deparseRangeTableFuncCol(StringInfo str, RangeTableFuncCol* range_table_func_col)
10273
10310
  {
10274
10311
  appendStringInfoString(str, quote_identifier(range_table_func_col->colname));
@@ -10286,14 +10323,14 @@ static void deparseRangeTableFuncCol(StringInfo str, RangeTableFuncCol* range_ta
10286
10323
  if (range_table_func_col->colexpr)
10287
10324
  {
10288
10325
  appendStringInfoString(str, "PATH ");
10289
- deparseExpr(str, range_table_func_col->colexpr);
10326
+ deparseExpr(str, range_table_func_col->colexpr, DEPARSE_NODE_CONTEXT_NONE /* b_expr */);
10290
10327
  appendStringInfoChar(str, ' ');
10291
10328
  }
10292
10329
 
10293
10330
  if (range_table_func_col->coldefexpr)
10294
10331
  {
10295
10332
  appendStringInfoString(str, "DEFAULT ");
10296
- deparseExpr(str, range_table_func_col->coldefexpr);
10333
+ deparseExpr(str, range_table_func_col->coldefexpr, DEPARSE_NODE_CONTEXT_NONE /* b_expr */);
10297
10334
  appendStringInfoChar(str, ' ');
10298
10335
  }
10299
10336
 
@@ -10304,6 +10341,7 @@ static void deparseRangeTableFuncCol(StringInfo str, RangeTableFuncCol* range_ta
10304
10341
  removeTrailingSpace(str);
10305
10342
  }
10306
10343
 
10344
+ // "table_ref" and "xmltable" in gram.y
10307
10345
  static void deparseRangeTableFunc(StringInfo str, RangeTableFunc* range_table_func)
10308
10346
  {
10309
10347
  ListCell *lc;
@@ -10320,11 +10358,11 @@ static void deparseRangeTableFunc(StringInfo str, RangeTableFunc* range_table_fu
10320
10358
  }
10321
10359
 
10322
10360
  appendStringInfoChar(str, '(');
10323
- deparseExpr(str, range_table_func->rowexpr);
10361
+ deparseExpr(str, range_table_func->rowexpr, DEPARSE_NODE_CONTEXT_NONE /* c_expr */);
10324
10362
  appendStringInfoChar(str, ')');
10325
10363
 
10326
10364
  appendStringInfoString(str, " PASSING ");
10327
- deparseExpr(str, range_table_func->docexpr);
10365
+ deparseExpr(str, range_table_func->docexpr, DEPARSE_NODE_CONTEXT_NONE /* c_expr */);
10328
10366
 
10329
10367
  appendStringInfoString(str, " COLUMNS ");
10330
10368
  foreach(lc, range_table_func->columns)
@@ -10359,7 +10397,7 @@ static void deparseXmlSerialize(StringInfo str, XmlSerialize *xml_serialize)
10359
10397
  default:
10360
10398
  Assert(false);
10361
10399
  }
10362
- deparseExpr(str, xml_serialize->expr);
10400
+ deparseExpr(str, xml_serialize->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
10363
10401
  appendStringInfoString(str, " AS ");
10364
10402
  deparseTypeName(str, xml_serialize->typeName);
10365
10403
 
@@ -10396,7 +10434,7 @@ static void deparseJsonFormat(StringInfo str, JsonFormat *json_format)
10396
10434
 
10397
10435
  static void deparseJsonIsPredicate(StringInfo str, JsonIsPredicate *j)
10398
10436
  {
10399
- deparseExpr(str, j->expr);
10437
+ deparseExpr(str, j->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
10400
10438
  appendStringInfoChar(str, ' ');
10401
10439
 
10402
10440
  deparseJsonFormat(str, castNode(JsonFormat, j->format));
@@ -10428,7 +10466,7 @@ static void deparseJsonIsPredicate(StringInfo str, JsonIsPredicate *j)
10428
10466
  // "json_value_expr" in gram.y
10429
10467
  static void deparseJsonValueExpr(StringInfo str, JsonValueExpr *json_value_expr)
10430
10468
  {
10431
- deparseExpr(str, (Node *) json_value_expr->raw_expr);
10469
+ deparseExpr(str, (Node *) json_value_expr->raw_expr, DEPARSE_NODE_CONTEXT_A_EXPR);
10432
10470
  appendStringInfoChar(str, ' ');
10433
10471
  deparseJsonFormat(str, json_value_expr->format);
10434
10472
  }
@@ -10450,7 +10488,7 @@ static void deparseJsonValueExprList(StringInfo str, List *exprs)
10450
10488
  // "json_name_and_value" in gram.y
10451
10489
  static void deparseJsonKeyValue(StringInfo str, JsonKeyValue *json_key_value)
10452
10490
  {
10453
- deparseExpr(str, (Node *) json_key_value->key);
10491
+ deparseExpr(str, (Node *) json_key_value->key, DEPARSE_NODE_CONTEXT_A_EXPR);
10454
10492
  appendStringInfoString(str, ": ");
10455
10493
  deparseJsonValueExpr(str, json_key_value->value);
10456
10494
  }
@@ -10482,6 +10520,7 @@ static void deparseJsonOutput(StringInfo str, JsonOutput *json_output)
10482
10520
  deparseJsonFormat(str, json_output->returning->format);
10483
10521
  }
10484
10522
 
10523
+ // "json_aggregate_func" and "func_expr" in gram.y
10485
10524
  static void deparseJsonObjectAgg(StringInfo str, JsonObjectAgg *json_object_agg)
10486
10525
  {
10487
10526
  Assert(json_object_agg->constructor != NULL);
@@ -10503,7 +10542,7 @@ static void deparseJsonObjectAgg(StringInfo str, JsonObjectAgg *json_object_agg)
10503
10542
  if (json_object_agg->constructor->agg_filter)
10504
10543
  {
10505
10544
  appendStringInfoString(str, "FILTER (WHERE ");
10506
- deparseExpr(str, json_object_agg->constructor->agg_filter);
10545
+ deparseExpr(str, json_object_agg->constructor->agg_filter, DEPARSE_NODE_CONTEXT_A_EXPR);
10507
10546
  appendStringInfoString(str, ") ");
10508
10547
  }
10509
10548
 
@@ -10520,6 +10559,7 @@ static void deparseJsonObjectAgg(StringInfo str, JsonObjectAgg *json_object_agg)
10520
10559
  removeTrailingSpace(str);
10521
10560
  }
10522
10561
 
10562
+ // "json_aggregate_func" and "func_expr" in gram.y
10523
10563
  static void deparseJsonArrayAgg(StringInfo str, JsonArrayAgg *json_array_agg)
10524
10564
  {
10525
10565
  Assert(json_array_agg->constructor != NULL);
@@ -10539,7 +10579,7 @@ static void deparseJsonArrayAgg(StringInfo str, JsonArrayAgg *json_array_agg)
10539
10579
  if (json_array_agg->constructor->agg_filter)
10540
10580
  {
10541
10581
  appendStringInfoString(str, "FILTER (WHERE ");
10542
- deparseExpr(str, json_array_agg->constructor->agg_filter);
10582
+ deparseExpr(str, json_array_agg->constructor->agg_filter, DEPARSE_NODE_CONTEXT_A_EXPR);
10543
10583
  appendStringInfoString(str, ") ");
10544
10584
  }
10545
10585
 
@@ -10614,7 +10654,7 @@ static void deparseJsonParseExpr(StringInfo str, JsonParseExpr *json_parse_expr)
10614
10654
  static void deparseJsonScalarExpr(StringInfo str, JsonScalarExpr *json_scalar_expr)
10615
10655
  {
10616
10656
  appendStringInfoString(str, "JSON_SCALAR(");
10617
- deparseExpr(str, (Node*) json_scalar_expr->expr);
10657
+ deparseExpr(str, (Node*) json_scalar_expr->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
10618
10658
  appendStringInfoString(str, ")");
10619
10659
  }
10620
10660
 
@@ -10685,7 +10725,7 @@ static void deparseJsonFuncExpr(StringInfo str, JsonFuncExpr *json_func_expr)
10685
10725
 
10686
10726
  deparseJsonValueExpr(str, json_func_expr->context_item);
10687
10727
  appendStringInfoString(str, ", ");
10688
- deparseExpr(str, json_func_expr->pathspec);
10728
+ deparseExpr(str, json_func_expr->pathspec, DEPARSE_NODE_CONTEXT_A_EXPR);
10689
10729
 
10690
10730
  if (json_func_expr->passing)
10691
10731
  appendStringInfoString(str, " PASSING ");
@@ -10741,6 +10781,7 @@ static void deparseJsonTablePathSpec(StringInfo str, JsonTablePathSpec *json_tab
10741
10781
  }
10742
10782
  }
10743
10783
 
10784
+ // "json_behavior" in gram.y
10744
10785
  static void deparseJsonBehavior(StringInfo str, JsonBehavior *json_behavior)
10745
10786
  {
10746
10787
  switch (json_behavior->btype)
@@ -10768,7 +10809,7 @@ static void deparseJsonBehavior(StringInfo str, JsonBehavior *json_behavior)
10768
10809
  break;
10769
10810
  case JSON_BEHAVIOR_DEFAULT:
10770
10811
  appendStringInfoString(str, "DEFAULT ");
10771
- deparseExpr(str, (Node*) json_behavior->expr);
10812
+ deparseExpr(str, (Node*) json_behavior->expr, DEPARSE_NODE_CONTEXT_A_EXPR);
10772
10813
  break;
10773
10814
  case JSON_BEHAVIOR_UNKNOWN:
10774
10815
  appendStringInfoString(str, "UNKNOWN");