pg_query 6.2.3 → 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
  *
@@ -736,6 +826,9 @@ static void deparseAnyNameSkipLast(DeparseState *state, List *parts)
736
826
  // "func_expr" in gram.y
737
827
  static void deparseFuncExpr(DeparseState *state, Node *node, DeparseNodeContext context)
738
828
  {
829
+ if (node == NULL)
830
+ elog(ERROR, "deparse: unexpected NULL node");
831
+
739
832
  switch (nodeTag(node))
740
833
  {
741
834
  case T_FuncCall:
@@ -785,6 +878,7 @@ static void deparseExpr(DeparseState *state, Node *node, DeparseNodeContext cont
785
878
  {
786
879
  if (node == NULL)
787
880
  return;
881
+
788
882
  switch (nodeTag(node))
789
883
  {
790
884
  case T_ColumnRef:
@@ -861,6 +955,9 @@ static void deparseExpr(DeparseState *state, Node *node, DeparseNodeContext cont
861
955
  // "b_expr" in gram.y
862
956
  static void deparseBExpr(DeparseState *state, Node *node)
863
957
  {
958
+ if (node == NULL)
959
+ elog(ERROR, "deparse: unexpected NULL node in deparseBExpr");
960
+
864
961
  if (IsA(node, XmlExpr)) {
865
962
  deparseXmlExpr(state, castNode(XmlExpr, node), DEPARSE_NODE_CONTEXT_NONE);
866
963
  return;
@@ -889,6 +986,9 @@ static void deparseBExpr(DeparseState *state, Node *node)
889
986
  // "AexprConst" in gram.y
890
987
  static void deparseAexprConst(DeparseState *state, Node *node)
891
988
  {
989
+ if (node == NULL)
990
+ elog(ERROR, "deparse: unexpected NULL node");
991
+
892
992
  switch (nodeTag(node))
893
993
  {
894
994
  case T_A_Const:
@@ -907,6 +1007,9 @@ static void deparseAexprConst(DeparseState *state, Node *node)
907
1007
  // "c_expr" in gram.y
908
1008
  static void deparseCExpr(DeparseState *state, Node *node)
909
1009
  {
1010
+ if (node == NULL)
1011
+ elog(ERROR, "deparse: unexpected NULL node");
1012
+
910
1013
  switch (nodeTag(node))
911
1014
  {
912
1015
  case T_ColumnRef:
@@ -1042,6 +1145,9 @@ static void deparseSimpleTypename(DeparseState *state, Node *node)
1042
1145
  // "NumericOnly" in gram.y
1043
1146
  static void deparseNumericOnly(DeparseState *state, union ValUnion *value)
1044
1147
  {
1148
+ if (value == NULL)
1149
+ elog(ERROR, "deparse: unexpected NULL value in deparseNumericOnly");
1150
+
1045
1151
  switch (nodeTag(value))
1046
1152
  {
1047
1153
  case T_Integer:
@@ -1423,7 +1529,7 @@ static void deparseCommonFuncOptItem(DeparseState *state, DefElem *def_elem)
1423
1529
  deparseAppendStringInfoString(state, "SUPPORT ");
1424
1530
  deparseAnyName(state, castNode(List, def_elem->arg));
1425
1531
  }
1426
- 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
1427
1533
  {
1428
1534
  deparseVariableSetStmt(state, castNode(VariableSetStmt, def_elem->arg));
1429
1535
  }
@@ -1572,6 +1678,9 @@ static void deparseFuncName(DeparseState *state, List *func_name)
1572
1678
  // "function_with_argtypes" in gram.y
1573
1679
  static void deparseFunctionWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1574
1680
  {
1681
+ if (object_with_args == NULL)
1682
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1683
+
1575
1684
  ListCell *lc;
1576
1685
  deparseFuncName(state, object_with_args->objname);
1577
1686
 
@@ -1611,6 +1720,9 @@ static void deparseFunctionWithArgtypesList(DeparseState *state, List *l)
1611
1720
  // "operator_with_argtypes" in gram.y
1612
1721
  static void deparseOperatorWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1613
1722
  {
1723
+ if (object_with_args == NULL)
1724
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1725
+
1614
1726
  deparseAnyOperator(state, object_with_args->objname);
1615
1727
 
1616
1728
  Assert(list_length(object_with_args->objargs) == 2);
@@ -1673,6 +1785,9 @@ static void deparseAggrArgs(DeparseState *state, List *aggr_args)
1673
1785
  // "aggregate_with_argtypes" in gram.y
1674
1786
  static void deparseAggregateWithArgtypes(DeparseState *state, ObjectWithArgs *object_with_args)
1675
1787
  {
1788
+ if (object_with_args == NULL)
1789
+ elog(ERROR, "deparse: unexpected NULL ObjectWithArgs");
1790
+
1676
1791
  ListCell *lc = NULL;
1677
1792
 
1678
1793
  deparseFuncName(state, object_with_args->objname);
@@ -2152,6 +2267,9 @@ static void deparseXmlNamespaceList(DeparseState *state, List *l)
2152
2267
  // "table_ref" in gram.y
2153
2268
  static void deparseTableRef(DeparseState *state, Node *node)
2154
2269
  {
2270
+ if (node == NULL)
2271
+ elog(ERROR, "deparse: unexpected NULL node");
2272
+
2155
2273
  switch (nodeTag(node))
2156
2274
  {
2157
2275
  case T_RangeVar:
@@ -2357,7 +2475,8 @@ static void deparseSetClauseList(DeparseState *state, List *target_list)
2357
2475
  deparseAppendCommaAndPart(state);
2358
2476
 
2359
2477
  ResTarget *res_target = castNode(ResTarget, lfirst(lc));
2360
- Assert(res_target->val != NULL);
2478
+ if (res_target->val == NULL)
2479
+ elog(ERROR, "deparse: unexpected NULL val in SET clause ResTarget");
2361
2480
 
2362
2481
  if (IsA(res_target->val, MultiAssignRef))
2363
2482
  {
@@ -2387,6 +2506,9 @@ static void deparseSetClauseList(DeparseState *state, List *target_list)
2387
2506
  // "func_expr_windowless" in gram.y
2388
2507
  static void deparseFuncExprWindowless(DeparseState *state, Node* node)
2389
2508
  {
2509
+ if (node == NULL)
2510
+ elog(ERROR, "deparse: unexpected NULL node");
2511
+
2390
2512
  switch (nodeTag(node))
2391
2513
  {
2392
2514
  case T_FuncCall:
@@ -2731,6 +2853,9 @@ static void deparseUtilityOptionList(DeparseState *state, List *options)
2731
2853
 
2732
2854
  static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNodeContext context)
2733
2855
  {
2856
+ if (stmt == NULL)
2857
+ elog(ERROR, "deparse: unexpected NULL SelectStmt");
2858
+
2734
2859
  const ListCell *lc = NULL;
2735
2860
  const ListCell *lc2 = NULL;
2736
2861
  bool need_parens = context == DEPARSE_NODE_CONTEXT_SELECT_SETOP && (
@@ -2799,6 +2924,8 @@ static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNode
2799
2924
 
2800
2925
  if (stmt->intoClause != NULL)
2801
2926
  {
2927
+ if (stmt->intoClause->rel == NULL)
2928
+ elog(ERROR, "deparse: unexpected NULL rel in IntoClause");
2802
2929
  deparseAppendPartGroup(state, "INTO", DEPARSE_PART_INDENT);
2803
2930
  deparseOptTemp(state, stmt->intoClause->rel->relpersistence);
2804
2931
  deparseIntoClause(state, stmt->intoClause);
@@ -2975,6 +3102,9 @@ static void deparseIntoClause(DeparseState *state, IntoClause *into_clause)
2975
3102
 
2976
3103
  static void deparseRangeVar(DeparseState *state, RangeVar *range_var, DeparseNodeContext context)
2977
3104
  {
3105
+ if (range_var == NULL)
3106
+ elog(ERROR, "deparse: unexpected NULL RangeVar");
3107
+
2978
3108
  if (!range_var->inh && context != DEPARSE_NODE_CONTEXT_CREATE_TYPE && context != DEPARSE_NODE_CONTEXT_ALTER_TYPE)
2979
3109
  deparseAppendStringInfoString(state, "ONLY ");
2980
3110
 
@@ -3074,6 +3204,9 @@ static void deparseAConst(DeparseState *state, A_Const *a_const)
3074
3204
 
3075
3205
  static void deparseFuncCall(DeparseState *state, FuncCall *func_call, DeparseNodeContext context)
3076
3206
  {
3207
+ if (func_call == NULL)
3208
+ elog(ERROR, "deparse: unexpected NULL FuncCall");
3209
+
3077
3210
  const ListCell *lc = NULL;
3078
3211
 
3079
3212
  Assert(list_length(func_call->funcname) > 0);
@@ -3607,6 +3740,9 @@ needsParensAsBExpr(Node *node)
3607
3740
  // This handles "A_Expr" parse tree objects, which are a subset of the rules in "a_expr" (handled by deparseExpr)
3608
3741
  static void deparseAExpr(DeparseState *state, A_Expr* a_expr, DeparseNodeContext context)
3609
3742
  {
3743
+ if (a_expr->rexpr == NULL)
3744
+ elog(ERROR, "deparse: unexpected NULL rexpr in A_Expr");
3745
+
3610
3746
  ListCell *lc;
3611
3747
  char *name;
3612
3748
 
@@ -3998,6 +4134,9 @@ static void deparseWithClause(DeparseState *state, WithClause *with_clause)
3998
4134
  // "joined_table" in gram.y
3999
4135
  static void deparseJoinExpr(DeparseState *state, JoinExpr *join_expr)
4000
4136
  {
4137
+ if (join_expr->larg == NULL || join_expr->rarg == NULL)
4138
+ elog(ERROR, "deparse: unexpected NULL larg/rarg in JoinExpr");
4139
+
4001
4140
  ListCell *lc;
4002
4141
  bool need_alias_parens = join_expr->alias != NULL;
4003
4142
  bool need_rarg_parens = IsA(join_expr->rarg, JoinExpr) && castNode(JoinExpr, join_expr->rarg)->alias == NULL;
@@ -4273,9 +4412,12 @@ static void deparseRowExpr(DeparseState *state, RowExpr *row_expr)
4273
4412
 
4274
4413
  static void deparseTypeCast(DeparseState *state, TypeCast *type_cast, DeparseNodeContext context)
4275
4414
  {
4276
- bool need_parens = needsParensAsBExpr(type_cast->arg);
4415
+ bool need_parens;
4277
4416
 
4278
- 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);
4279
4421
 
4280
4422
  if (context == DEPARSE_NODE_CONTEXT_FUNC_EXPR)
4281
4423
  {
@@ -4357,6 +4499,9 @@ static void deparseTypeCast(DeparseState *state, TypeCast *type_cast, DeparseNod
4357
4499
 
4358
4500
  static void deparseTypeName(DeparseState *state, TypeName *type_name)
4359
4501
  {
4502
+ if (type_name == NULL)
4503
+ elog(ERROR, "deparse: unexpected NULL TypeName");
4504
+
4360
4505
  ListCell *lc;
4361
4506
  bool skip_typmods = false;
4362
4507
 
@@ -4632,6 +4777,9 @@ static void deparseCaseWhen(DeparseState *state, CaseWhen *case_when)
4632
4777
 
4633
4778
  static void deparseAIndirection(DeparseState *state, A_Indirection *a_indirection)
4634
4779
  {
4780
+ if (a_indirection->arg == NULL)
4781
+ elog(ERROR, "deparse: unexpected NULL arg in A_Indirection");
4782
+
4635
4783
  ListCell *lc;
4636
4784
  bool need_parens =
4637
4785
  IsA(a_indirection->arg, A_Indirection) ||
@@ -4690,6 +4838,9 @@ static void deparseMinMaxExpr(DeparseState *state, MinMaxExpr *min_max_expr)
4690
4838
 
4691
4839
  static void deparseBooleanTest(DeparseState *state, BooleanTest *boolean_test)
4692
4840
  {
4841
+ if (boolean_test->arg == NULL)
4842
+ elog(ERROR, "deparse: unexpected NULL arg in BooleanTest");
4843
+
4693
4844
  bool need_parens = IsA(boolean_test->arg, BoolExpr);
4694
4845
 
4695
4846
  if (need_parens)
@@ -4728,6 +4879,9 @@ static void deparseBooleanTest(DeparseState *state, BooleanTest *boolean_test)
4728
4879
  // "columnDef" and "alter_table_cmd" in gram.y
4729
4880
  static void deparseColumnDef(DeparseState *state, ColumnDef *column_def)
4730
4881
  {
4882
+ if (column_def == NULL)
4883
+ elog(ERROR, "deparse: unexpected NULL ColumnDef");
4884
+
4731
4885
  ListCell *lc;
4732
4886
 
4733
4887
  if (column_def->colname != NULL)
@@ -5385,6 +5539,9 @@ static void deparseCreateExtensionStmt(DeparseState *state, CreateExtensionStmt
5385
5539
  // "ColConstraintElem" and "ConstraintElem" in gram.y
5386
5540
  static void deparseConstraint(DeparseState *state, Constraint *constraint, DeparseNodeContext context)
5387
5541
  {
5542
+ if (constraint == NULL)
5543
+ elog(ERROR, "deparse: unexpected NULL Constraint");
5544
+
5388
5545
  ListCell *lc;
5389
5546
 
5390
5547
  if (constraint->conname != NULL)
@@ -5866,6 +6023,9 @@ static void deparseCreateConversionStmt(DeparseState *state, CreateConversionStm
5866
6023
 
5867
6024
  static void deparseRoleSpec(DeparseState *state, RoleSpec *role_spec)
5868
6025
  {
6026
+ if (role_spec == NULL)
6027
+ elog(ERROR, "deparse: unexpected NULL RoleSpec");
6028
+
5869
6029
  switch (role_spec->roletype)
5870
6030
  {
5871
6031
  case ROLESPEC_CSTRING:
@@ -5976,6 +6136,9 @@ static void deparsePartitionBoundSpec(DeparseState *state, PartitionBoundSpec *p
5976
6136
 
5977
6137
  static void deparsePartitionCmd(DeparseState *state, PartitionCmd *partition_cmd)
5978
6138
  {
6139
+ if (partition_cmd == NULL)
6140
+ elog(ERROR, "deparse: unexpected NULL PartitionCmd");
6141
+
5979
6142
  deparseRangeVar(state, partition_cmd->name, DEPARSE_NODE_CONTEXT_NONE);
5980
6143
 
5981
6144
  if (partition_cmd->bound != NULL)
@@ -5990,6 +6153,9 @@ static void deparsePartitionCmd(DeparseState *state, PartitionCmd *partition_cmd
5990
6153
  // "TableElement" in gram.y
5991
6154
  static void deparseTableElement(DeparseState *state, Node *node)
5992
6155
  {
6156
+ if (node == NULL)
6157
+ elog(ERROR, "deparse: unexpected NULL node");
6158
+
5993
6159
  switch (nodeTag(node))
5994
6160
  {
5995
6161
  case T_ColumnDef:
@@ -6008,6 +6174,9 @@ static void deparseTableElement(DeparseState *state, Node *node)
6008
6174
 
6009
6175
  static void deparseCreateStmt(DeparseState *state, CreateStmt *create_stmt, bool is_foreign_table)
6010
6176
  {
6177
+ if (create_stmt->relation == NULL)
6178
+ elog(ERROR, "deparse: unexpected NULL relation in CreateStmt");
6179
+
6011
6180
  ListCell *lc;
6012
6181
 
6013
6182
  deparseAppendStringInfoString(state, "CREATE ");
@@ -6431,6 +6600,10 @@ static void deparseImportForeignSchemaStmt(DeparseState *state, ImportForeignSch
6431
6600
 
6432
6601
  static void deparseCreateTableAsStmt(DeparseState *state, CreateTableAsStmt *create_table_as_stmt)
6433
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
+
6434
6607
  ListCell *lc;
6435
6608
  deparseAppendStringInfoString(state, "CREATE ");
6436
6609
 
@@ -6471,6 +6644,9 @@ static void deparseCreateTableAsStmt(DeparseState *state, CreateTableAsStmt *cre
6471
6644
 
6472
6645
  static void deparseViewStmt(DeparseState *state, ViewStmt *view_stmt)
6473
6646
  {
6647
+ if (view_stmt->view == NULL)
6648
+ elog(ERROR, "deparse: unexpected NULL view in ViewStmt");
6649
+
6474
6650
  ListCell *lc;
6475
6651
 
6476
6652
  deparseAppendStringInfoString(state, "CREATE ");
@@ -7796,6 +7972,9 @@ static bool isSetTimeZoneInterval(VariableSetStmt* stmt)
7796
7972
 
7797
7973
  static void deparseVariableSetStmt(DeparseState *state, VariableSetStmt* variable_set_stmt)
7798
7974
  {
7975
+ if (variable_set_stmt == NULL)
7976
+ elog(ERROR, "deparse: unexpected NULL VariableSetStmt");
7977
+
7799
7978
  ListCell *lc;
7800
7979
 
7801
7980
  switch (variable_set_stmt->kind)
@@ -8188,6 +8367,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8188
8367
  else if (strcmp(def_elem->defname, "force_quote") == 0)
8189
8368
  {
8190
8369
  deparseAppendStringInfoString(state, "FORCE_QUOTE ");
8370
+ if (def_elem->arg == NULL)
8371
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_QUOTE");
8191
8372
  if (IsA(def_elem->arg, A_Star))
8192
8373
  {
8193
8374
  deparseAppendStringInfoChar(state, '*');
@@ -8207,6 +8388,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8207
8388
  {
8208
8389
  deparseAppendStringInfoString(state, "FORCE_NOT_NULL ");
8209
8390
 
8391
+ if (def_elem->arg == NULL)
8392
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_NOT_NULL");
8210
8393
  if (IsA(def_elem->arg, A_Star))
8211
8394
  deparseAStar(state, castNode(A_Star, def_elem->arg));
8212
8395
  else
@@ -8220,6 +8403,8 @@ static void deparseCopyStmt(DeparseState *state, CopyStmt *copy_stmt)
8220
8403
  {
8221
8404
  deparseAppendStringInfoString(state, "FORCE_NULL ");
8222
8405
 
8406
+ if (def_elem->arg == NULL)
8407
+ elog(ERROR, "deparse: unexpected NULL arg for FORCE_NULL");
8223
8408
  if (IsA(def_elem->arg, A_Star))
8224
8409
  deparseAStar(state, castNode(A_Star, def_elem->arg));
8225
8410
  else
@@ -8737,6 +8922,9 @@ static void deparseAccessPriv(DeparseState *state, AccessPriv *access_priv)
8737
8922
 
8738
8923
  static void deparseGrantStmt(DeparseState *state, GrantStmt *grant_stmt)
8739
8924
  {
8925
+ if (grant_stmt == NULL)
8926
+ elog(ERROR, "deparse: unexpected NULL GrantStmt");
8927
+
8740
8928
  ListCell *lc;
8741
8929
  if (grant_stmt->is_grant)
8742
8930
  deparseAppendStringInfoString(state, "GRANT ");
@@ -8804,6 +8992,8 @@ static void deparseGrantRoleStmt(DeparseState *state, GrantRoleStmt *grant_role_
8804
8992
 
8805
8993
  if (!grant_role_stmt->is_grant && list_length(grant_role_stmt->opt)) {
8806
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");
8807
8997
  Assert(!castNode(Boolean, defelem->arg)->boolval);
8808
8998
 
8809
8999
  if (strcmp("admin", defelem->defname) == 0) {
@@ -8840,6 +9030,8 @@ static void deparseGrantRoleStmt(DeparseState *state, GrantRoleStmt *grant_role_
8840
9030
 
8841
9031
  foreach(lc, grant_role_stmt->opt) {
8842
9032
  DefElem *defelem = castNode(DefElem, lfirst(lc));
9033
+ if (defelem->arg == NULL)
9034
+ elog(ERROR, "deparse: unexpected NULL arg in GRANT role option");
8843
9035
  if (strcmp("admin", defelem->defname) == 0) {
8844
9036
  deparseAppendStringInfoString(state, "ADMIN ");
8845
9037
  deparseAppendStringInfoString(state, castNode(Boolean, defelem->arg)->boolval ? "OPTION" : "FALSE");
@@ -9502,6 +9694,9 @@ static void deparseUnlistenStmt(DeparseState *state, UnlistenStmt *unlisten_stmt
9502
9694
 
9503
9695
  static void deparseCreateSeqStmt(DeparseState *state, CreateSeqStmt *create_seq_stmt)
9504
9696
  {
9697
+ if (create_seq_stmt->sequence == NULL)
9698
+ elog(ERROR, "deparse: unexpected NULL sequence in CreateSeqStmt");
9699
+
9505
9700
  ListCell *lc;
9506
9701
 
9507
9702
  deparseAppendStringInfoString(state, "CREATE ");
@@ -9653,6 +9848,9 @@ static void deparseRefreshMatViewStmt(DeparseState *state, RefreshMatViewStmt *r
9653
9848
 
9654
9849
  static void deparseReplicaIdentityStmt(DeparseState *state, ReplicaIdentityStmt *replica_identity_stmt)
9655
9850
  {
9851
+ if (replica_identity_stmt == NULL)
9852
+ elog(ERROR, "deparse: unexpected NULL ReplicaIdentityStmt");
9853
+
9656
9854
  switch (replica_identity_stmt->identity_type)
9657
9855
  {
9658
9856
  case REPLICA_IDENTITY_NOTHING:
@@ -9839,6 +10037,8 @@ static void deparsePublicationObjectList(DeparseState *state, List *pubobjects)
9839
10037
 
9840
10038
  switch (obj->pubobjtype) {
9841
10039
  case PUBLICATIONOBJ_TABLE:
10040
+ if (obj->pubtable == NULL)
10041
+ elog(ERROR, "deparse: unexpected NULL pubtable in PublicationObjSpec");
9842
10042
  deparseAppendStringInfoString(state, "TABLE ");
9843
10043
  deparseRangeVar(state, obj->pubtable->relation, DEPARSE_NODE_CONTEXT_NONE);
9844
10044
 
@@ -11063,6 +11263,9 @@ static void deparseJsonIsPredicate(DeparseState *state, JsonIsPredicate *j)
11063
11263
  // "json_value_expr" in gram.y
11064
11264
  static void deparseJsonValueExpr(DeparseState *state, JsonValueExpr *json_value_expr)
11065
11265
  {
11266
+ if (json_value_expr == NULL)
11267
+ elog(ERROR, "deparse: unexpected NULL JsonValueExpr");
11268
+
11066
11269
  deparseExpr(state, (Node *) json_value_expr->raw_expr, DEPARSE_NODE_CONTEXT_A_EXPR);
11067
11270
  deparseAppendStringInfoChar(state, ' ');
11068
11271
  deparseJsonFormat(state, json_value_expr->format);
@@ -11109,7 +11312,8 @@ static void deparseJsonOutput(DeparseState *state, JsonOutput *json_output)
11109
11312
  if (json_output == NULL)
11110
11313
  return;
11111
11314
 
11112
- Assert(json_output->returning != NULL);
11315
+ if (json_output->returning == NULL)
11316
+ elog(ERROR, "deparse: unexpected NULL returning in JsonOutput");
11113
11317
 
11114
11318
  deparseAppendStringInfoString(state, "RETURNING ");
11115
11319
  deparseTypeName(state, json_output->typeName);
@@ -11612,6 +11816,9 @@ static void deparseValue(DeparseState *state, union ValUnion *value, DeparseNode
11612
11816
  // "PrepareableStmt" in gram.y
11613
11817
  static void deparsePreparableStmt(DeparseState *state, Node *node)
11614
11818
  {
11819
+ if (node == NULL)
11820
+ elog(ERROR, "deparse: unexpected NULL node");
11821
+
11615
11822
  switch (nodeTag(node))
11616
11823
  {
11617
11824
  case T_SelectStmt:
@@ -11637,6 +11844,9 @@ static void deparsePreparableStmt(DeparseState *state, Node *node)
11637
11844
  // "RuleActionStmt" in gram.y
11638
11845
  static void deparseRuleActionStmt(DeparseState *state, Node *node)
11639
11846
  {
11847
+ if (node == NULL)
11848
+ elog(ERROR, "deparse: unexpected NULL node");
11849
+
11640
11850
  switch (nodeTag(node))
11641
11851
  {
11642
11852
  case T_SelectStmt:
@@ -11662,6 +11872,9 @@ static void deparseRuleActionStmt(DeparseState *state, Node *node)
11662
11872
  // "ExplainableStmt" in gram.y
11663
11873
  static void deparseExplainableStmt(DeparseState *state, Node *node)
11664
11874
  {
11875
+ if (node == NULL)
11876
+ elog(ERROR, "deparse: unexpected NULL node");
11877
+
11665
11878
  switch (nodeTag(node))
11666
11879
  {
11667
11880
  case T_SelectStmt:
@@ -11699,6 +11912,9 @@ static void deparseExplainableStmt(DeparseState *state, Node *node)
11699
11912
  // "schema_stmt" in gram.y
11700
11913
  static void deparseSchemaStmt(DeparseState *state, Node *node)
11701
11914
  {
11915
+ if (node == NULL)
11916
+ elog(ERROR, "deparse: unexpected NULL node");
11917
+
11702
11918
  switch (nodeTag(node))
11703
11919
  {
11704
11920
  case T_CreateStmt:
@@ -11764,6 +11980,9 @@ static void deparseStmt(DeparseState *state, Node *node)
11764
11980
  //
11765
11981
  // And the following grammar names error out in the parser:
11766
11982
  // - CreateAssertionStmt (not supported yet)
11983
+ if (node == NULL)
11984
+ elog(ERROR, "deparse: unexpected NULL node");
11985
+
11767
11986
  switch (nodeTag(node))
11768
11987
  {
11769
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
  }