pg_query 6.2.2 → 6.2.5

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.
@@ -18,6 +18,96 @@
18
18
  #include "utils/timestamp.h"
19
19
  #include "utils/xml.h"
20
20
 
21
+ /*
22
+ * Strict structural checking of the input tree (on by default).
23
+ *
24
+ * The deparser receives its parse tree from the caller (in libpg_query, from
25
+ * an arbitrary protobuf), so the tree may not have the shape a given deparse
26
+ * path expects. The stock code documents those expectations with Assert(),
27
+ * which is a no-op in a release build, so a malformed tree instead triggers
28
+ * out-of-bounds reads that can leak adjacent heap memory or crash. Two cases:
29
+ *
30
+ * - A node's actual type not matching what a path expects. The stock
31
+ * castNode() is a bare cast with no runtime check, so intVal()/strVal()/
32
+ * boolVal()/floatVal() read the wrong union member.
33
+ *
34
+ * - A list being shorter than a path assumes. The stock linitial()/lsecond()/
35
+ * lthird()/lfourth()/llast() index past the end of the ListCell array.
36
+ *
37
+ * By default we redefine those macros here to check and raise a normal error
38
+ * on violation, caught by libpg_query's surrounding PG_TRY and returned as a
39
+ * PgQueryError. Redefining castNode() covers intVal()/strVal()/etc., since
40
+ * they are all defined in terms of it; redefining the positional list
41
+ * accessors covers every fixed-index access.
42
+ *
43
+ * Define PG_QUERY_DEPARSE_NO_STRICT_CHECKS to opt out and keep the stock
44
+ * unchecked macros -- e.g. if you feed the deparser only trees you have
45
+ * already validated and want to avoid the per-access checks.
46
+ */
47
+ #ifndef PG_QUERY_DEPARSE_NO_STRICT_CHECKS
48
+ static inline void *
49
+ pg_query_strict_cast_node(NodeTag type, void *ptr, const char *file, int line)
50
+ {
51
+ if (ptr != NULL && nodeTag(ptr) != type)
52
+ elog(ERROR, "deparse: unexpected node type %d, expected %d (%s:%d)",
53
+ (int) nodeTag(ptr), (int) type, file, line);
54
+ return ptr;
55
+ }
56
+ #undef castNode
57
+ #define castNode(_type_, nodeptr) \
58
+ ((_type_ *) pg_query_strict_cast_node(T_##_type_, (nodeptr), __FILE__, __LINE__))
59
+
60
+ /*
61
+ * intVal()/strVal()/boolVal()/floatVal() extract a scalar from a value node, so
62
+ * a NULL node is always a bug (a genuinely-absent value is handled by the
63
+ * caller before extraction, e.g. "PASSWORD NULL"). Reject NULL here rather than
64
+ * dereferencing it. castNode()'s own check then covers a wrong node type.
65
+ */
66
+ static inline void *
67
+ pg_query_require_value_node(void *ptr, const char *file, int line)
68
+ {
69
+ if (ptr == NULL)
70
+ elog(ERROR, "deparse: value extraction from NULL node (%s:%d)", file, line);
71
+ return ptr;
72
+ }
73
+ #undef intVal
74
+ #undef floatVal
75
+ #undef boolVal
76
+ #undef strVal
77
+ #define intVal(v) (castNode(Integer, pg_query_require_value_node((v), __FILE__, __LINE__))->ival)
78
+ #define floatVal(v) atof(castNode(Float, pg_query_require_value_node((v), __FILE__, __LINE__))->fval)
79
+ #define boolVal(v) (castNode(Boolean, pg_query_require_value_node((v), __FILE__, __LINE__))->boolval)
80
+ #define strVal(v) (castNode(String, pg_query_require_value_node((v), __FILE__, __LINE__))->sval)
81
+
82
+ static inline void *
83
+ pg_query_checked_list_nth(const List *l, int n, const char *file, int line)
84
+ {
85
+ if (l == NIL || n < 0 || n >= list_length(l))
86
+ elog(ERROR, "deparse: list index %d out of range for length %d (%s:%d)",
87
+ n, list_length(l), file, line);
88
+ return list_nth(l, n);
89
+ }
90
+
91
+ static inline void *
92
+ pg_query_checked_list_last(const List *l, const char *file, int line)
93
+ {
94
+ if (l == NIL)
95
+ elog(ERROR, "deparse: llast() on empty list (%s:%d)", file, line);
96
+ return list_nth(l, list_length(l) - 1);
97
+ }
98
+
99
+ #undef linitial
100
+ #undef lsecond
101
+ #undef lthird
102
+ #undef lfourth
103
+ #undef llast
104
+ #define linitial(l) pg_query_checked_list_nth((l), 0, __FILE__, __LINE__)
105
+ #define lsecond(l) pg_query_checked_list_nth((l), 1, __FILE__, __LINE__)
106
+ #define lthird(l) pg_query_checked_list_nth((l), 2, __FILE__, __LINE__)
107
+ #define lfourth(l) pg_query_checked_list_nth((l), 3, __FILE__, __LINE__)
108
+ #define llast(l) pg_query_checked_list_last((l), __FILE__, __LINE__)
109
+ #endif
110
+
21
111
  /*
22
112
  * # Deparser overview
23
113
  *
@@ -93,6 +183,7 @@ typedef enum DeparseNodeContext {
93
183
  DEPARSE_NODE_CONTEXT_A_EXPR,
94
184
  DEPARSE_NODE_CONTEXT_CREATE_TYPE,
95
185
  DEPARSE_NODE_CONTEXT_ALTER_TYPE,
186
+ DEPARSE_NODE_CONTEXT_ALTER_DOMAIN,
96
187
  DEPARSE_NODE_CONTEXT_SET_STATEMENT,
97
188
  DEPARSE_NODE_CONTEXT_FUNC_EXPR,
98
189
  DEPARSE_NODE_CONTEXT_SELECT_SETOP,
@@ -231,7 +322,7 @@ static void deparseJsonFuncExpr(DeparseState *state, JsonFuncExpr *json_func_exp
231
322
  static void deparseJsonQuotesClauseOpt(DeparseState *state, JsonQuotes quotes);
232
323
  static void deparseJsonOnErrorClauseOpt(DeparseState *state, JsonBehavior *behavior);
233
324
  static void deparseJsonOnEmptyClauseOpt(DeparseState *state, JsonBehavior *behavior);
234
- static void deparseConstraint(DeparseState *state, Constraint *constraint);
325
+ static void deparseConstraint(DeparseState *state, Constraint *constraint, DeparseNodeContext context);
235
326
  static void deparseSchemaStmt(DeparseState *state, Node *node);
236
327
  static void deparseExecuteStmt(DeparseState *state, ExecuteStmt *execute_stmt);
237
328
  static void deparseTriggerTransition(DeparseState *state, TriggerTransition *trigger_transition);
@@ -735,6 +826,9 @@ static void deparseAnyNameSkipLast(DeparseState *state, List *parts)
735
826
  // "func_expr" in gram.y
736
827
  static void deparseFuncExpr(DeparseState *state, Node *node, DeparseNodeContext context)
737
828
  {
829
+ if (node == NULL)
830
+ elog(ERROR, "deparse: unexpected NULL node");
831
+
738
832
  switch (nodeTag(node))
739
833
  {
740
834
  case T_FuncCall:
@@ -784,6 +878,7 @@ static void deparseExpr(DeparseState *state, Node *node, DeparseNodeContext cont
784
878
  {
785
879
  if (node == NULL)
786
880
  return;
881
+
787
882
  switch (nodeTag(node))
788
883
  {
789
884
  case T_ColumnRef:
@@ -860,6 +955,9 @@ static void deparseExpr(DeparseState *state, Node *node, DeparseNodeContext cont
860
955
  // "b_expr" in gram.y
861
956
  static void deparseBExpr(DeparseState *state, Node *node)
862
957
  {
958
+ if (node == NULL)
959
+ elog(ERROR, "deparse: unexpected NULL node in deparseBExpr");
960
+
863
961
  if (IsA(node, XmlExpr)) {
864
962
  deparseXmlExpr(state, castNode(XmlExpr, node), DEPARSE_NODE_CONTEXT_NONE);
865
963
  return;
@@ -888,6 +986,9 @@ static void deparseBExpr(DeparseState *state, Node *node)
888
986
  // "AexprConst" in gram.y
889
987
  static void deparseAexprConst(DeparseState *state, Node *node)
890
988
  {
989
+ if (node == NULL)
990
+ elog(ERROR, "deparse: unexpected NULL node");
991
+
891
992
  switch (nodeTag(node))
892
993
  {
893
994
  case T_A_Const:
@@ -906,6 +1007,9 @@ static void deparseAexprConst(DeparseState *state, Node *node)
906
1007
  // "c_expr" in gram.y
907
1008
  static void deparseCExpr(DeparseState *state, Node *node)
908
1009
  {
1010
+ if (node == NULL)
1011
+ elog(ERROR, "deparse: unexpected NULL node");
1012
+
909
1013
  switch (nodeTag(node))
910
1014
  {
911
1015
  case T_ColumnRef:
@@ -1041,6 +1145,9 @@ static void deparseSimpleTypename(DeparseState *state, Node *node)
1041
1145
  // "NumericOnly" in gram.y
1042
1146
  static void deparseNumericOnly(DeparseState *state, union ValUnion *value)
1043
1147
  {
1148
+ if (value == NULL)
1149
+ elog(ERROR, "deparse: unexpected NULL value in deparseNumericOnly");
1150
+
1044
1151
  switch (nodeTag(value))
1045
1152
  {
1046
1153
  case T_Integer:
@@ -1422,7 +1529,7 @@ static void deparseCommonFuncOptItem(DeparseState *state, DefElem *def_elem)
1422
1529
  deparseAppendStringInfoString(state, "SUPPORT ");
1423
1530
  deparseAnyName(state, castNode(List, def_elem->arg));
1424
1531
  }
1425
- else if (strcmp(def_elem->defname, "set") == 0 && IsA(def_elem->arg, VariableSetStmt)) // FunctionSetResetClause
1532
+ else if (strcmp(def_elem->defname, "set") == 0 && def_elem->arg != NULL && IsA(def_elem->arg, VariableSetStmt)) // FunctionSetResetClause
1426
1533
  {
1427
1534
  deparseVariableSetStmt(state, castNode(VariableSetStmt, def_elem->arg));
1428
1535
  }
@@ -1571,6 +1678,9 @@ static void deparseFuncName(DeparseState *state, List *func_name)
1571
1678
  // "function_with_argtypes" in gram.y
1572
1679
  static void deparseFunctionWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1573
1680
  {
1681
+ if (object_with_args == NULL)
1682
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1683
+
1574
1684
  ListCell *lc;
1575
1685
  deparseFuncName(state, object_with_args->objname);
1576
1686
 
@@ -1610,6 +1720,9 @@ static void deparseFunctionWithArgtypesList(DeparseState *state, List *l)
1610
1720
  // "operator_with_argtypes" in gram.y
1611
1721
  static void deparseOperatorWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1612
1722
  {
1723
+ if (object_with_args == NULL)
1724
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1725
+
1613
1726
  deparseAnyOperator(state, object_with_args->objname);
1614
1727
 
1615
1728
  Assert(list_length(object_with_args->objargs) == 2);
@@ -1672,6 +1785,9 @@ static void deparseAggrArgs(DeparseState *state, List *aggr_args)
1672
1785
  // "aggregate_with_argtypes" in gram.y
1673
1786
  static void deparseAggregateWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1674
1787
  {
1788
+ if (object_with_args == NULL)
1789
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1790
+
1675
1791
  ListCell *lc = NULL;
1676
1792
 
1677
1793
  deparseFuncName(state, object_with_args->objname);
@@ -2151,6 +2267,9 @@ static void deparseXmlNamespaceList(DeparseState *state, List *l)
2151
2267
  // "table_ref" in gram.y
2152
2268
  static void deparseTableRef(DeparseState *state, Node *node)
2153
2269
  {
2270
+ if (node == NULL)
2271
+ elog(ERROR, "deparse: unexpected NULL node");
2272
+
2154
2273
  switch (nodeTag(node))
2155
2274
  {
2156
2275
  case T_RangeVar:
@@ -2356,7 +2475,8 @@ static void deparseSetClauseList(DeparseState *state, List *target_list)
2356
2475
  deparseAppendCommaAndPart(state);
2357
2476
 
2358
2477
  ResTarget *res_target = castNode(ResTarget, lfirst(lc));
2359
- Assert(res_target->val != NULL);
2478
+ if (res_target->val == NULL)
2479
+ elog(ERROR, "deparse: unexpected NULL val in SET clause ResTarget");
2360
2480
 
2361
2481
  if (IsA(res_target->val, MultiAssignRef))
2362
2482
  {
@@ -2386,6 +2506,9 @@ static void deparseSetClauseList(DeparseState *state, List *target_list)
2386
2506
  // "func_expr_windowless" in gram.y
2387
2507
  static void deparseFuncExprWindowless(DeparseState *state, Node* node)
2388
2508
  {
2509
+ if (node == NULL)
2510
+ elog(ERROR, "deparse: unexpected NULL node");
2511
+
2389
2512
  switch (nodeTag(node))
2390
2513
  {
2391
2514
  case T_FuncCall:
@@ -2730,6 +2853,9 @@ static void deparseUtilityOptionList(DeparseState *state, List *options)
2730
2853
 
2731
2854
  static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNodeContext context)
2732
2855
  {
2856
+ if (stmt == NULL)
2857
+ elog(ERROR, "deparse: unexpected NULL SelectStmt");
2858
+
2733
2859
  const ListCell *lc = NULL;
2734
2860
  const ListCell *lc2 = NULL;
2735
2861
  bool need_parens = context == DEPARSE_NODE_CONTEXT_SELECT_SETOP && (
@@ -2798,6 +2924,8 @@ static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNode
2798
2924
 
2799
2925
  if (stmt->intoClause != NULL)
2800
2926
  {
2927
+ if (stmt->intoClause->rel == NULL)
2928
+ elog(ERROR, "deparse: unexpected NULL rel in IntoClause");
2801
2929
  deparseAppendPartGroup(state, "INTO", DEPARSE_PART_INDENT);
2802
2930
  deparseOptTemp(state, stmt->intoClause->rel->relpersistence);
2803
2931
  deparseIntoClause(state, stmt->intoClause);
@@ -2974,6 +3102,9 @@ static void deparseIntoClause(DeparseState *state, IntoClause *into_clause)
2974
3102
 
2975
3103
  static void deparseRangeVar(DeparseState *state, RangeVar *range_var, DeparseNodeContext context)
2976
3104
  {
3105
+ if (range_var == NULL)
3106
+ elog(ERROR, "deparse: unexpected NULL RangeVar");
3107
+
2977
3108
  if (!range_var->inh && context != DEPARSE_NODE_CONTEXT_CREATE_TYPE && context != DEPARSE_NODE_CONTEXT_ALTER_TYPE)
2978
3109
  deparseAppendStringInfoString(state, "ONLY ");
2979
3110
 
@@ -3073,6 +3204,9 @@ static void deparseAConst(DeparseState *state, A_Const *a_const)
3073
3204
 
3074
3205
  static void deparseFuncCall(DeparseState *state, FuncCall *func_call, DeparseNodeContext context)
3075
3206
  {
3207
+ if (func_call == NULL)
3208
+ elog(ERROR, "deparse: unexpected NULL FuncCall");
3209
+
3076
3210
  const ListCell *lc = NULL;
3077
3211
 
3078
3212
  Assert(list_length(func_call->funcname) > 0);
@@ -3606,6 +3740,9 @@ needsParensAsBExpr(Node *node)
3606
3740
  // This handles "A_Expr" parse tree objects, which are a subset of the rules in "a_expr" (handled by deparseExpr)
3607
3741
  static void deparseAExpr(DeparseState *state, A_Expr* a_expr, DeparseNodeContext context)
3608
3742
  {
3743
+ if (a_expr->rexpr == NULL)
3744
+ elog(ERROR, "deparse: unexpected NULL rexpr in A_Expr");
3745
+
3609
3746
  ListCell *lc;
3610
3747
  char *name;
3611
3748
 
@@ -3997,6 +4134,9 @@ static void deparseWithClause(DeparseState *state, WithClause *with_clause)
3997
4134
  // "joined_table" in gram.y
3998
4135
  static void deparseJoinExpr(DeparseState *state, JoinExpr *join_expr)
3999
4136
  {
4137
+ if (join_expr->larg == NULL || join_expr->rarg == NULL)
4138
+ elog(ERROR, "deparse: unexpected NULL larg/rarg in JoinExpr");
4139
+
4000
4140
  ListCell *lc;
4001
4141
  bool need_alias_parens = join_expr->alias != NULL;
4002
4142
  bool need_rarg_parens = IsA(join_expr->rarg, JoinExpr) && castNode(JoinExpr, join_expr->rarg)->alias == NULL;
@@ -4272,9 +4412,12 @@ static void deparseRowExpr(DeparseState *state, RowExpr *row_expr)
4272
4412
 
4273
4413
  static void deparseTypeCast(DeparseState *state, TypeCast *type_cast, DeparseNodeContext context)
4274
4414
  {
4275
- bool need_parens = needsParensAsBExpr(type_cast->arg);
4415
+ bool need_parens;
4276
4416
 
4277
- Assert(type_cast->typeName != NULL);
4417
+ if (type_cast->arg == NULL || type_cast->typeName == NULL)
4418
+ elog(ERROR, "deparse: unexpected NULL arg/typeName in TypeCast");
4419
+
4420
+ need_parens = needsParensAsBExpr(type_cast->arg);
4278
4421
 
4279
4422
  if (context == DEPARSE_NODE_CONTEXT_FUNC_EXPR)
4280
4423
  {
@@ -4356,6 +4499,9 @@ static void deparseTypeCast(DeparseState *state, TypeCast *type_cast, DeparseNod
4356
4499
 
4357
4500
  static void deparseTypeName(DeparseState *state, TypeName *type_name)
4358
4501
  {
4502
+ if (type_name == NULL)
4503
+ elog(ERROR, "deparse: unexpected NULL TypeName");
4504
+
4359
4505
  ListCell *lc;
4360
4506
  bool skip_typmods = false;
4361
4507
 
@@ -4631,6 +4777,9 @@ static void deparseCaseWhen(DeparseState *state, CaseWhen *case_when)
4631
4777
 
4632
4778
  static void deparseAIndirection(DeparseState *state, A_Indirection *a_indirection)
4633
4779
  {
4780
+ if (a_indirection->arg == NULL)
4781
+ elog(ERROR, "deparse: unexpected NULL arg in A_Indirection");
4782
+
4634
4783
  ListCell *lc;
4635
4784
  bool need_parens =
4636
4785
  IsA(a_indirection->arg, A_Indirection) ||
@@ -4638,6 +4787,7 @@ static void deparseAIndirection(DeparseState *state, A_Indirection *a_indirectio
4638
4787
  IsA(a_indirection->arg, A_Expr) ||
4639
4788
  IsA(a_indirection->arg, TypeCast) ||
4640
4789
  IsA(a_indirection->arg, RowExpr) ||
4790
+ IsA(a_indirection->arg, A_ArrayExpr) ||
4641
4791
  (IsA(a_indirection->arg, ColumnRef) && !IsA(linitial(a_indirection->indirection), A_Indices)) ||
4642
4792
  IsA(a_indirection->arg, JsonFuncExpr);
4643
4793
 
@@ -4688,6 +4838,9 @@ static void deparseMinMaxExpr(DeparseState *state, MinMaxExpr *min_max_expr)
4688
4838
 
4689
4839
  static void deparseBooleanTest(DeparseState *state, BooleanTest *boolean_test)
4690
4840
  {
4841
+ if (boolean_test->arg == NULL)
4842
+ elog(ERROR, "deparse: unexpected NULL arg in BooleanTest");
4843
+
4691
4844
  bool need_parens = IsA(boolean_test->arg, BoolExpr);
4692
4845
 
4693
4846
  if (need_parens)
@@ -4726,6 +4879,9 @@ static void deparseBooleanTest(DeparseState *state, BooleanTest *boolean_test)
4726
4879
  // "columnDef" and "alter_table_cmd" in gram.y
4727
4880
  static void deparseColumnDef(DeparseState *state, ColumnDef *column_def)
4728
4881
  {
4882
+ if (column_def == NULL)
4883
+ elog(ERROR, "deparse: unexpected NULL ColumnDef");
4884
+
4729
4885
  ListCell *lc;
4730
4886
 
4731
4887
  if (column_def->colname != NULL)
@@ -4769,7 +4925,7 @@ static void deparseColumnDef(DeparseState *state, ColumnDef *column_def)
4769
4925
 
4770
4926
  foreach(lc, column_def->constraints)
4771
4927
  {
4772
- deparseConstraint(state, castNode(Constraint, lfirst(lc)));
4928
+ deparseConstraint(state, castNode(Constraint, lfirst(lc)), DEPARSE_NODE_CONTEXT_NONE);
4773
4929
  deparseAppendStringInfoChar(state, ' ');
4774
4930
  }
4775
4931
 
@@ -5332,7 +5488,7 @@ static void deparseCreateDomainStmt(DeparseState *state, CreateDomainStmt *creat
5332
5488
 
5333
5489
  foreach(lc, create_domain_stmt->constraints)
5334
5490
  {
5335
- deparseConstraint(state, castNode(Constraint, lfirst(lc)));
5491
+ deparseConstraint(state, castNode(Constraint, lfirst(lc)), DEPARSE_NODE_CONTEXT_NONE);
5336
5492
  deparseAppendStringInfoChar(state, ' ');
5337
5493
  }
5338
5494
 
@@ -5381,8 +5537,11 @@ static void deparseCreateExtensionStmt(DeparseState *state, CreateExtensionStmt
5381
5537
  }
5382
5538
 
5383
5539
  // "ColConstraintElem" and "ConstraintElem" in gram.y
5384
- static void deparseConstraint(DeparseState *state, Constraint *constraint)
5540
+ static void deparseConstraint(DeparseState *state, Constraint *constraint, DeparseNodeContext context)
5385
5541
  {
5542
+ if (constraint == NULL)
5543
+ elog(ERROR, "deparse: unexpected NULL Constraint");
5544
+
5386
5545
  ListCell *lc;
5387
5546
 
5388
5547
  if (constraint->conname != NULL)
@@ -5487,7 +5646,7 @@ static void deparseConstraint(DeparseState *state, Constraint *constraint)
5487
5646
  {
5488
5647
  bool valueOnly = false;
5489
5648
 
5490
- if (list_length(constraint->keys) == 1) {
5649
+ if (context == DEPARSE_NODE_CONTEXT_ALTER_DOMAIN && list_length(constraint->keys) == 1) {
5491
5650
  Node* firstKey = constraint->keys->elements[0].ptr_value;
5492
5651
  valueOnly = IsA(firstKey, String) && !strcmp("value", ((String*)firstKey)->sval);
5493
5652
  }
@@ -5864,6 +6023,9 @@ static void deparseCreateConversionStmt(DeparseState *state, CreateConversionStm
5864
6023
 
5865
6024
  static void deparseRoleSpec(DeparseState *state, RoleSpec *role_spec)
5866
6025
  {
6026
+ if (role_spec == NULL)
6027
+ elog(ERROR, "deparse: unexpected NULL RoleSpec");
6028
+
5867
6029
  switch (role_spec->roletype)
5868
6030
  {
5869
6031
  case ROLESPEC_CSTRING:
@@ -5974,6 +6136,9 @@ static void deparsePartitionBoundSpec(DeparseState *state, PartitionBoundSpec *p
5974
6136
 
5975
6137
  static void deparsePartitionCmd(DeparseState *state, PartitionCmd *partition_cmd)
5976
6138
  {
6139
+ if (partition_cmd == NULL)
6140
+ elog(ERROR, "deparse: unexpected NULL PartitionCmd");
6141
+
5977
6142
  deparseRangeVar(state, partition_cmd->name, DEPARSE_NODE_CONTEXT_NONE);
5978
6143
 
5979
6144
  if (partition_cmd->bound != NULL)
@@ -5988,6 +6153,9 @@ static void deparsePartitionCmd(DeparseState *state, PartitionCmd *partition_cmd
5988
6153
  // "TableElement" in gram.y
5989
6154
  static void deparseTableElement(DeparseState *state, Node *node)
5990
6155
  {
6156
+ if (node == NULL)
6157
+ elog(ERROR, "deparse: unexpected NULL node");
6158
+
5991
6159
  switch (nodeTag(node))
5992
6160
  {
5993
6161
  case T_ColumnDef:
@@ -5997,7 +6165,7 @@ static void deparseTableElement(DeparseState *state, Node *node)
5997
6165
  deparseTableLikeClause(state, castNode(TableLikeClause, node));
5998
6166
  break;
5999
6167
  case T_Constraint:
6000
- deparseConstraint(state, castNode(Constraint, node));
6168
+ deparseConstraint(state, castNode(Constraint, node), DEPARSE_NODE_CONTEXT_NONE);
6001
6169
  break;
6002
6170
  default:
6003
6171
  Assert(false);
@@ -6006,6 +6174,9 @@ static void deparseTableElement(DeparseState *state, Node *node)
6006
6174
 
6007
6175
  static void deparseCreateStmt(DeparseState *state, CreateStmt *create_stmt, bool is_foreign_table)
6008
6176
  {
6177
+ if (create_stmt->relation == NULL)
6178
+ elog(ERROR, "deparse: unexpected NULL relation in CreateStmt");
6179
+
6009
6180
  ListCell *lc;
6010
6181
 
6011
6182
  deparseAppendStringInfoString(state, "CREATE ");
@@ -6429,6 +6600,10 @@ static void deparseImportForeignSchemaStmt(DeparseState *state, ImportForeignSch
6429
6600
 
6430
6601
  static void deparseCreateTableAsStmt(DeparseState *state, CreateTableAsStmt *create_table_as_stmt)
6431
6602
  {
6603
+ if (create_table_as_stmt->into == NULL || create_table_as_stmt->into->rel == NULL ||
6604
+ create_table_as_stmt->query == NULL)
6605
+ elog(ERROR, "deparse: unexpected NULL into/query in CreateTableAsStmt");
6606
+
6432
6607
  ListCell *lc;
6433
6608
  deparseAppendStringInfoString(state, "CREATE ");
6434
6609
 
@@ -6469,6 +6644,9 @@ static void deparseCreateTableAsStmt(DeparseState *state, CreateTableAsStmt *cre
6469
6644
 
6470
6645
  static void deparseViewStmt(DeparseState *state, ViewStmt *view_stmt)
6471
6646
  {
6647
+ if (view_stmt->view == NULL)
6648
+ elog(ERROR, "deparse: unexpected NULL view in ViewStmt");
6649
+
6472
6650
  ListCell *lc;
6473
6651
 
6474
6652
  deparseAppendStringInfoString(state, "CREATE ");
@@ -7286,7 +7464,7 @@ static void deparseAlterTableCmd(DeparseState *state, AlterTableCmd *alter_table
7286
7464
  case AT_AddIdentity:
7287
7465
  case AT_AddConstraint:
7288
7466
  case AT_AlterConstraint:
7289
- deparseConstraint(state, castNode(Constraint, alter_table_cmd->def));
7467
+ deparseConstraint(state, castNode(Constraint, alter_table_cmd->def), DEPARSE_NODE_CONTEXT_NONE);
7290
7468
  deparseAppendStringInfoChar(state, ' ');
7291
7469
  break;
7292
7470
  case AT_SetIdentity:
@@ -7452,7 +7630,7 @@ static void deparseAlterDomainStmt(DeparseState *state, AlterDomainStmt *alter_d
7452
7630
  break;
7453
7631
  case 'C':
7454
7632
  deparseAppendStringInfoString(state, "ADD ");
7455
- deparseConstraint(state, castNode(Constraint, alter_domain_stmt->def));
7633
+ deparseConstraint(state, castNode(Constraint, alter_domain_stmt->def), DEPARSE_NODE_CONTEXT_ALTER_DOMAIN);
7456
7634
  break;
7457
7635
  case 'X':
7458
7636
  deparseAppendStringInfoString(state, "DROP CONSTRAINT ");
@@ -7794,6 +7972,9 @@ static bool isSetTimeZoneInterval(VariableSetStmt* stmt)
7794
7972
 
7795
7973
  static void deparseVariableSetStmt(DeparseState *state, VariableSetStmt* variable_set_stmt)
7796
7974
  {
7975
+ if (variable_set_stmt == NULL)
7976
+ elog(ERROR, "deparse: unexpected NULL VariableSetStmt");
7977
+
7797
7978
  ListCell *lc;
7798
7979
 
7799
7980
  switch (variable_set_stmt->kind)
@@ -8186,6 +8367,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8186
8367
  else if (strcmp(def_elem->defname, "force_quote") == 0)
8187
8368
  {
8188
8369
  deparseAppendStringInfoString(state, "FORCE_QUOTE ");
8370
+ if (def_elem->arg == NULL)
8371
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_QUOTE");
8189
8372
  if (IsA(def_elem->arg, A_Star))
8190
8373
  {
8191
8374
  deparseAppendStringInfoChar(state, '*');
@@ -8205,6 +8388,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8205
8388
  {
8206
8389
  deparseAppendStringInfoString(state, "FORCE_NOT_NULL ");
8207
8390
 
8391
+ if (def_elem->arg == NULL)
8392
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_NOT_NULL");
8208
8393
  if (IsA(def_elem->arg, A_Star))
8209
8394
  deparseAStar(state, castNode(A_Star, def_elem->arg));
8210
8395
  else
@@ -8218,6 +8403,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8218
8403
  {
8219
8404
  deparseAppendStringInfoString(state, "FORCE_NULL ");
8220
8405
 
8406
+ if (def_elem->arg == NULL)
8407
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_NULL");
8221
8408
  if (IsA(def_elem->arg, A_Star))
8222
8409
  deparseAStar(state, castNode(A_Star, def_elem->arg));
8223
8410
  else
@@ -8735,6 +8922,9 @@ static void deparseAccessPriv(DeparseState *state, AccessPriv *access_priv)
8735
8922
 
8736
8923
  static void deparseGrantStmt(DeparseState *state, GrantStmt *grant_stmt)
8737
8924
  {
8925
+ if (grant_stmt == NULL)
8926
+ elog(ERROR, "deparse: unexpected NULL GrantStmt");
8927
+
8738
8928
  ListCell *lc;
8739
8929
  if (grant_stmt->is_grant)
8740
8930
  deparseAppendStringInfoString(state, "GRANT ");
@@ -8802,6 +8992,8 @@ static void deparseGrantRoleStmt(DeparseState *state, GrantRoleStmt *grant_role_
8802
8992
 
8803
8993
  if (!grant_role_stmt->is_grant && list_length(grant_role_stmt->opt)) {
8804
8994
  DefElem *defelem = castNode(DefElem, linitial(grant_role_stmt->opt));
8995
+ if (defelem->arg == NULL)
8996
+ elog(ERROR, "deparse: unexpected NULL arg in GRANT role option");
8805
8997
  Assert(!castNode(Boolean, defelem->arg)->boolval);
8806
8998
 
8807
8999
  if (strcmp("admin", defelem->defname) == 0) {
@@ -8838,6 +9030,8 @@ static void deparseGrantRoleStmt(DeparseState *state, GrantRoleStmt *grant_role_
8838
9030
 
8839
9031
  foreach(lc, grant_role_stmt->opt) {
8840
9032
  DefElem *defelem = castNode(DefElem, lfirst(lc));
9033
+ if (defelem->arg == NULL)
9034
+ elog(ERROR, "deparse: unexpected NULL arg in GRANT role option");
8841
9035
  if (strcmp("admin", defelem->defname) == 0) {
8842
9036
  deparseAppendStringInfoString(state, "ADMIN ");
8843
9037
  deparseAppendStringInfoString(state, castNode(Boolean, defelem->arg)->boolval ? "OPTION" : "FALSE");
@@ -9500,6 +9694,9 @@ static void deparseUnlistenStmt(DeparseState *state, UnlistenStmt *unlisten_stmt
9500
9694
 
9501
9695
  static void deparseCreateSeqStmt(DeparseState *state, CreateSeqStmt *create_seq_stmt)
9502
9696
  {
9697
+ if (create_seq_stmt->sequence == NULL)
9698
+ elog(ERROR, "deparse: unexpected NULL sequence in CreateSeqStmt");
9699
+
9503
9700
  ListCell *lc;
9504
9701
 
9505
9702
  deparseAppendStringInfoString(state, "CREATE ");
@@ -9651,6 +9848,9 @@ static void deparseRefreshMatViewStmt(DeparseState *state, RefreshMatViewStmt *r
9651
9848
 
9652
9849
  static void deparseReplicaIdentityStmt(DeparseState *state, ReplicaIdentityStmt *replica_identity_stmt)
9653
9850
  {
9851
+ if (replica_identity_stmt == NULL)
9852
+ elog(ERROR, "deparse: unexpected NULL ReplicaIdentityStmt");
9853
+
9654
9854
  switch (replica_identity_stmt->identity_type)
9655
9855
  {
9656
9856
  case REPLICA_IDENTITY_NOTHING:
@@ -9837,6 +10037,8 @@ static void deparsePublicationObjectList(DeparseState *state, List *pubobjects)
9837
10037
 
9838
10038
  switch (obj->pubobjtype) {
9839
10039
  case PUBLICATIONOBJ_TABLE:
10040
+ if (obj->pubtable == NULL)
10041
+ elog(ERROR, "deparse: unexpected NULL pubtable in PublicationObjSpec");
9840
10042
  deparseAppendStringInfoString(state, "TABLE ");
9841
10043
  deparseRangeVar(state, obj->pubtable->relation, DEPARSE_NODE_CONTEXT_NONE);
9842
10044
 
@@ -11061,6 +11263,9 @@ static void deparseJsonIsPredicate(DeparseState *state, JsonIsPredicate *j)
11061
11263
  // "json_value_expr" in gram.y
11062
11264
  static void deparseJsonValueExpr(DeparseState *state, JsonValueExpr *json_value_expr)
11063
11265
  {
11266
+ if (json_value_expr == NULL)
11267
+ elog(ERROR, "deparse: unexpected NULL JsonValueExpr");
11268
+
11064
11269
  deparseExpr(state, (Node *) json_value_expr->raw_expr, DEPARSE_NODE_CONTEXT_A_EXPR);
11065
11270
  deparseAppendStringInfoChar(state, ' ');
11066
11271
  deparseJsonFormat(state, json_value_expr->format);
@@ -11107,7 +11312,8 @@ static void deparseJsonOutput(DeparseState *state, JsonOutput *json_output)
11107
11312
  if (json_output == NULL)
11108
11313
  return;
11109
11314
 
11110
- Assert(json_output->returning != NULL);
11315
+ if (json_output->returning == NULL)
11316
+ elog(ERROR, "deparse: unexpected NULL returning in JsonOutput");
11111
11317
 
11112
11318
  deparseAppendStringInfoString(state, "RETURNING ");
11113
11319
  deparseTypeName(state, json_output->typeName);
@@ -11610,6 +11816,9 @@ static void deparseValue(DeparseState *state, union ValUnion *value, DeparseNode
11610
11816
  // "PrepareableStmt" in gram.y
11611
11817
  static void deparsePreparableStmt(DeparseState *state, Node *node)
11612
11818
  {
11819
+ if (node == NULL)
11820
+ elog(ERROR, "deparse: unexpected NULL node");
11821
+
11613
11822
  switch (nodeTag(node))
11614
11823
  {
11615
11824
  case T_SelectStmt:
@@ -11635,6 +11844,9 @@ static void deparsePreparableStmt(DeparseState *state, Node *node)
11635
11844
  // "RuleActionStmt" in gram.y
11636
11845
  static void deparseRuleActionStmt(DeparseState *state, Node *node)
11637
11846
  {
11847
+ if (node == NULL)
11848
+ elog(ERROR, "deparse: unexpected NULL node");
11849
+
11638
11850
  switch (nodeTag(node))
11639
11851
  {
11640
11852
  case T_SelectStmt:
@@ -11660,6 +11872,9 @@ static void deparseRuleActionStmt(DeparseState *state, Node *node)
11660
11872
  // "ExplainableStmt" in gram.y
11661
11873
  static void deparseExplainableStmt(DeparseState *state, Node *node)
11662
11874
  {
11875
+ if (node == NULL)
11876
+ elog(ERROR, "deparse: unexpected NULL node");
11877
+
11663
11878
  switch (nodeTag(node))
11664
11879
  {
11665
11880
  case T_SelectStmt:
@@ -11697,6 +11912,9 @@ static void deparseExplainableStmt(DeparseState *state, Node *node)
11697
11912
  // "schema_stmt" in gram.y
11698
11913
  static void deparseSchemaStmt(DeparseState *state, Node *node)
11699
11914
  {
11915
+ if (node == NULL)
11916
+ elog(ERROR, "deparse: unexpected NULL node");
11917
+
11700
11918
  switch (nodeTag(node))
11701
11919
  {
11702
11920
  case T_CreateStmt:
@@ -11762,6 +11980,9 @@ static void deparseStmt(DeparseState *state, Node *node)
11762
11980
  //
11763
11981
  // And the following grammar names error out in the parser:
11764
11982
  // - CreateAssertionStmt (not supported yet)
11983
+ if (node == NULL)
11984
+ elog(ERROR, "deparse: unexpected NULL node");
11985
+
11765
11986
  switch (nodeTag(node))
11766
11987
  {
11767
11988
  case T_AlterEventTrigStmt:
@@ -302,6 +302,7 @@ makeDefElem(char *name, Node *arg, int location)
302
302
  res->arg = arg;
303
303
  res->defaction = DEFELEM_UNSPEC;
304
304
  res->location = location;
305
+ res->arg_location = -1;
305
306
 
306
307
  return res;
307
308
  }
@@ -321,6 +322,7 @@ makeDefElemExtended(char *nameSpace, char *name, Node *arg,
321
322
  res->arg = arg;
322
323
  res->defaction = defaction;
323
324
  res->location = location;
325
+ res->arg_location = -1;
324
326
 
325
327
  return res;
326
328
  }