Coverage Report

Created: 2026-11-09 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/nodes/nodeFuncs.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * nodeFuncs.c
4
 *    Various general-purpose manipulations of Node trees
5
 *
6
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 *
10
 * IDENTIFICATION
11
 *    src/backend/nodes/nodeFuncs.c
12
 *
13
 *-------------------------------------------------------------------------
14
 */
15
#include "postgres.h"
16
17
#include "catalog/pg_collation.h"
18
#include "catalog/pg_type.h"
19
#include "miscadmin.h"
20
#include "nodes/execnodes.h"
21
#include "nodes/nodeFuncs.h"
22
#include "nodes/pathnodes.h"
23
#include "utils/builtins.h"
24
#include "utils/lsyscache.h"
25
26
static bool expression_returns_set_walker(Node *node, void *context);
27
static int  leftmostLoc(int loc1, int loc2);
28
static bool fix_opfuncids_walker(Node *node, void *context);
29
static bool planstate_walk_subplans(List *plans,
30
                  planstate_tree_walker_callback walker,
31
                  void *context);
32
static bool planstate_walk_members(PlanState **planstates, int nplans,
33
                   planstate_tree_walker_callback walker,
34
                   void *context);
35
36
37
/*
38
 *  exprType -
39
 *    returns the Oid of the type of the expression's result.
40
 */
41
Oid
42
exprType(const Node *expr)
43
0
{
44
0
  Oid     type;
45
46
0
  if (!expr)
47
0
    return InvalidOid;
48
49
0
  switch (nodeTag(expr))
50
0
  {
51
0
    case T_Var:
52
0
      type = ((const Var *) expr)->vartype;
53
0
      break;
54
0
    case T_Const:
55
0
      type = ((const Const *) expr)->consttype;
56
0
      break;
57
0
    case T_Param:
58
0
      type = ((const Param *) expr)->paramtype;
59
0
      break;
60
0
    case T_Aggref:
61
0
      type = ((const Aggref *) expr)->aggtype;
62
0
      break;
63
0
    case T_GroupingFunc:
64
0
      type = INT4OID;
65
0
      break;
66
0
    case T_WindowFunc:
67
0
      type = ((const WindowFunc *) expr)->wintype;
68
0
      break;
69
0
    case T_MergeSupportFunc:
70
0
      type = ((const MergeSupportFunc *) expr)->msftype;
71
0
      break;
72
0
    case T_SubscriptingRef:
73
0
      type = ((const SubscriptingRef *) expr)->refrestype;
74
0
      break;
75
0
    case T_FuncExpr:
76
0
      type = ((const FuncExpr *) expr)->funcresulttype;
77
0
      break;
78
0
    case T_NamedArgExpr:
79
0
      type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
80
0
      break;
81
0
    case T_OpExpr:
82
0
      type = ((const OpExpr *) expr)->opresulttype;
83
0
      break;
84
0
    case T_DistinctExpr:
85
0
      type = ((const DistinctExpr *) expr)->opresulttype;
86
0
      break;
87
0
    case T_NullIfExpr:
88
0
      type = ((const NullIfExpr *) expr)->opresulttype;
89
0
      break;
90
0
    case T_ScalarArrayOpExpr:
91
0
      type = BOOLOID;
92
0
      break;
93
0
    case T_BoolExpr:
94
0
      type = BOOLOID;
95
0
      break;
96
0
    case T_SubLink:
97
0
      {
98
0
        const SubLink *sublink = (const SubLink *) expr;
99
100
0
        if (sublink->subLinkType == EXPR_SUBLINK ||
101
0
          sublink->subLinkType == ARRAY_SUBLINK)
102
0
        {
103
          /* get the type of the subselect's first target column */
104
0
          Query    *qtree = (Query *) sublink->subselect;
105
0
          TargetEntry *tent;
106
107
0
          if (!qtree || !IsA(qtree, Query))
108
0
            elog(ERROR, "cannot get type for untransformed sublink");
109
0
          tent = linitial_node(TargetEntry, qtree->targetList);
110
0
          Assert(!tent->resjunk);
111
0
          type = exprType((Node *) tent->expr);
112
0
          if (sublink->subLinkType == ARRAY_SUBLINK)
113
0
          {
114
0
            type = get_promoted_array_type(type);
115
0
            if (!OidIsValid(type))
116
0
              ereport(ERROR,
117
0
                  (errcode(ERRCODE_UNDEFINED_OBJECT),
118
0
                   errmsg("could not find array type for data type %s",
119
0
                      format_type_be(exprType((Node *) tent->expr)))));
120
0
          }
121
0
        }
122
0
        else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
123
0
        {
124
          /* MULTIEXPR is always considered to return RECORD */
125
0
          type = RECORDOID;
126
0
        }
127
0
        else
128
0
        {
129
          /* for all other sublink types, result is boolean */
130
0
          type = BOOLOID;
131
0
        }
132
0
      }
133
0
      break;
134
0
    case T_SubPlan:
135
0
      {
136
0
        const SubPlan *subplan = (const SubPlan *) expr;
137
138
0
        if (subplan->subLinkType == EXPR_SUBLINK ||
139
0
          subplan->subLinkType == ARRAY_SUBLINK)
140
0
        {
141
          /* get the type of the subselect's first target column */
142
0
          type = subplan->firstColType;
143
0
          if (subplan->subLinkType == ARRAY_SUBLINK)
144
0
          {
145
0
            type = get_promoted_array_type(type);
146
0
            if (!OidIsValid(type))
147
0
              ereport(ERROR,
148
0
                  (errcode(ERRCODE_UNDEFINED_OBJECT),
149
0
                   errmsg("could not find array type for data type %s",
150
0
                      format_type_be(subplan->firstColType))));
151
0
          }
152
0
        }
153
0
        else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
154
0
        {
155
          /* MULTIEXPR is always considered to return RECORD */
156
0
          type = RECORDOID;
157
0
        }
158
0
        else
159
0
        {
160
          /* for all other subplan types, result is boolean */
161
0
          type = BOOLOID;
162
0
        }
163
0
      }
164
0
      break;
165
0
    case T_AlternativeSubPlan:
166
0
      {
167
0
        const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
168
169
        /* subplans should all return the same thing */
170
0
        type = exprType((Node *) linitial(asplan->subplans));
171
0
      }
172
0
      break;
173
0
    case T_FieldSelect:
174
0
      type = ((const FieldSelect *) expr)->resulttype;
175
0
      break;
176
0
    case T_FieldStore:
177
0
      type = ((const FieldStore *) expr)->resulttype;
178
0
      break;
179
0
    case T_RelabelType:
180
0
      type = ((const RelabelType *) expr)->resulttype;
181
0
      break;
182
0
    case T_CoerceViaIO:
183
0
      type = ((const CoerceViaIO *) expr)->resulttype;
184
0
      break;
185
0
    case T_ArrayCoerceExpr:
186
0
      type = ((const ArrayCoerceExpr *) expr)->resulttype;
187
0
      break;
188
0
    case T_ConvertRowtypeExpr:
189
0
      type = ((const ConvertRowtypeExpr *) expr)->resulttype;
190
0
      break;
191
0
    case T_CollateExpr:
192
0
      type = exprType((Node *) ((const CollateExpr *) expr)->arg);
193
0
      break;
194
0
    case T_CaseExpr:
195
0
      type = ((const CaseExpr *) expr)->casetype;
196
0
      break;
197
0
    case T_CaseTestExpr:
198
0
      type = ((const CaseTestExpr *) expr)->typeId;
199
0
      break;
200
0
    case T_ArrayExpr:
201
0
      type = ((const ArrayExpr *) expr)->array_typeid;
202
0
      break;
203
0
    case T_RowExpr:
204
0
      type = ((const RowExpr *) expr)->row_typeid;
205
0
      break;
206
0
    case T_RowCompareExpr:
207
0
      type = BOOLOID;
208
0
      break;
209
0
    case T_CoalesceExpr:
210
0
      type = ((const CoalesceExpr *) expr)->coalescetype;
211
0
      break;
212
0
    case T_MinMaxExpr:
213
0
      type = ((const MinMaxExpr *) expr)->minmaxtype;
214
0
      break;
215
0
    case T_SQLValueFunction:
216
0
      type = ((const SQLValueFunction *) expr)->type;
217
0
      break;
218
0
    case T_XmlExpr:
219
0
      if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
220
0
        type = BOOLOID;
221
0
      else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
222
0
        type = TEXTOID;
223
0
      else
224
0
        type = XMLOID;
225
0
      break;
226
0
    case T_JsonValueExpr:
227
0
      {
228
0
        const JsonValueExpr *jve = (const JsonValueExpr *) expr;
229
230
0
        type = exprType((Node *) jve->formatted_expr);
231
0
      }
232
0
      break;
233
0
    case T_JsonConstructorExpr:
234
0
      type = ((const JsonConstructorExpr *) expr)->returning->typid;
235
0
      break;
236
0
    case T_JsonIsPredicate:
237
0
      type = BOOLOID;
238
0
      break;
239
0
    case T_JsonExpr:
240
0
      {
241
0
        const JsonExpr *jexpr = (const JsonExpr *) expr;
242
243
0
        type = jexpr->returning->typid;
244
0
        break;
245
0
      }
246
0
    case T_JsonBehavior:
247
0
      {
248
0
        const JsonBehavior *behavior = (const JsonBehavior *) expr;
249
250
0
        type = exprType(behavior->expr);
251
0
        break;
252
0
      }
253
0
    case T_NullTest:
254
0
      type = BOOLOID;
255
0
      break;
256
0
    case T_BooleanTest:
257
0
      type = BOOLOID;
258
0
      break;
259
0
    case T_CoerceToDomain:
260
0
      type = ((const CoerceToDomain *) expr)->resulttype;
261
0
      break;
262
0
    case T_CoerceToDomainValue:
263
0
      type = ((const CoerceToDomainValue *) expr)->typeId;
264
0
      break;
265
0
    case T_SetToDefault:
266
0
      type = ((const SetToDefault *) expr)->typeId;
267
0
      break;
268
0
    case T_CurrentOfExpr:
269
0
      type = BOOLOID;
270
0
      break;
271
0
    case T_NextValueExpr:
272
0
      type = ((const NextValueExpr *) expr)->typeId;
273
0
      break;
274
0
    case T_InferenceElem:
275
0
      {
276
0
        const InferenceElem *n = (const InferenceElem *) expr;
277
278
0
        type = exprType((Node *) n->expr);
279
0
      }
280
0
      break;
281
0
    case T_ReturningExpr:
282
0
      type = exprType((Node *) ((const ReturningExpr *) expr)->retexpr);
283
0
      break;
284
0
    case T_PlaceHolderVar:
285
0
      type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
286
0
      break;
287
0
    default:
288
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
289
0
      type = InvalidOid; /* keep compiler quiet */
290
0
      break;
291
0
  }
292
0
  return type;
293
0
}
294
295
/*
296
 *  exprTypmod -
297
 *    returns the type-specific modifier of the expression's result type,
298
 *    if it can be determined.  In many cases, it can't and we return -1.
299
 */
300
int32
301
exprTypmod(const Node *expr)
302
0
{
303
0
  if (!expr)
304
0
    return -1;
305
306
0
  switch (nodeTag(expr))
307
0
  {
308
0
    case T_Var:
309
0
      return ((const Var *) expr)->vartypmod;
310
0
    case T_Const:
311
0
      return ((const Const *) expr)->consttypmod;
312
0
    case T_Param:
313
0
      return ((const Param *) expr)->paramtypmod;
314
0
    case T_SubscriptingRef:
315
0
      return ((const SubscriptingRef *) expr)->reftypmod;
316
0
    case T_FuncExpr:
317
0
      {
318
0
        int32   coercedTypmod;
319
320
        /* Be smart about length-coercion functions... */
321
0
        if (exprIsLengthCoercion(expr, &coercedTypmod))
322
0
          return coercedTypmod;
323
0
      }
324
0
      break;
325
0
    case T_NamedArgExpr:
326
0
      return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
327
0
    case T_NullIfExpr:
328
0
      {
329
        /*
330
         * Result is either first argument or NULL, so we can report
331
         * first argument's typmod if known.
332
         */
333
0
        const NullIfExpr *nexpr = (const NullIfExpr *) expr;
334
335
0
        return exprTypmod((Node *) linitial(nexpr->args));
336
0
      }
337
0
      break;
338
0
    case T_SubLink:
339
0
      {
340
0
        const SubLink *sublink = (const SubLink *) expr;
341
342
0
        if (sublink->subLinkType == EXPR_SUBLINK ||
343
0
          sublink->subLinkType == ARRAY_SUBLINK)
344
0
        {
345
          /* get the typmod of the subselect's first target column */
346
0
          Query    *qtree = (Query *) sublink->subselect;
347
0
          TargetEntry *tent;
348
349
0
          if (!qtree || !IsA(qtree, Query))
350
0
            elog(ERROR, "cannot get type for untransformed sublink");
351
0
          tent = linitial_node(TargetEntry, qtree->targetList);
352
0
          Assert(!tent->resjunk);
353
0
          return exprTypmod((Node *) tent->expr);
354
          /* note we don't need to care if it's an array */
355
0
        }
356
        /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
357
0
      }
358
0
      break;
359
0
    case T_SubPlan:
360
0
      {
361
0
        const SubPlan *subplan = (const SubPlan *) expr;
362
363
0
        if (subplan->subLinkType == EXPR_SUBLINK ||
364
0
          subplan->subLinkType == ARRAY_SUBLINK)
365
0
        {
366
          /* get the typmod of the subselect's first target column */
367
          /* note we don't need to care if it's an array */
368
0
          return subplan->firstColTypmod;
369
0
        }
370
        /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
371
0
      }
372
0
      break;
373
0
    case T_AlternativeSubPlan:
374
0
      {
375
0
        const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
376
377
        /* subplans should all return the same thing */
378
0
        return exprTypmod((Node *) linitial(asplan->subplans));
379
0
      }
380
0
      break;
381
0
    case T_FieldSelect:
382
0
      return ((const FieldSelect *) expr)->resulttypmod;
383
0
    case T_RelabelType:
384
0
      return ((const RelabelType *) expr)->resulttypmod;
385
0
    case T_ArrayCoerceExpr:
386
0
      return ((const ArrayCoerceExpr *) expr)->resulttypmod;
387
0
    case T_CollateExpr:
388
0
      return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
389
0
    case T_CaseExpr:
390
0
      {
391
        /*
392
         * If all the alternatives agree on type/typmod, return that
393
         * typmod, else use -1
394
         */
395
0
        const CaseExpr *cexpr = (const CaseExpr *) expr;
396
0
        Oid     casetype = cexpr->casetype;
397
0
        int32   typmod;
398
0
        ListCell   *arg;
399
400
0
        if (!cexpr->defresult)
401
0
          return -1;
402
0
        if (exprType((Node *) cexpr->defresult) != casetype)
403
0
          return -1;
404
0
        typmod = exprTypmod((Node *) cexpr->defresult);
405
0
        if (typmod < 0)
406
0
          return -1; /* no point in trying harder */
407
0
        foreach(arg, cexpr->args)
408
0
        {
409
0
          CaseWhen   *w = lfirst_node(CaseWhen, arg);
410
411
0
          if (exprType((Node *) w->result) != casetype)
412
0
            return -1;
413
0
          if (exprTypmod((Node *) w->result) != typmod)
414
0
            return -1;
415
0
        }
416
0
        return typmod;
417
0
      }
418
0
      break;
419
0
    case T_CaseTestExpr:
420
0
      return ((const CaseTestExpr *) expr)->typeMod;
421
0
    case T_ArrayExpr:
422
0
      {
423
        /*
424
         * If all the elements agree on type/typmod, return that
425
         * typmod, else use -1
426
         */
427
0
        const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
428
0
        Oid     commontype;
429
0
        int32   typmod;
430
0
        ListCell   *elem;
431
432
0
        if (arrayexpr->elements == NIL)
433
0
          return -1;
434
0
        typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
435
0
        if (typmod < 0)
436
0
          return -1; /* no point in trying harder */
437
0
        if (arrayexpr->multidims)
438
0
          commontype = arrayexpr->array_typeid;
439
0
        else
440
0
          commontype = arrayexpr->element_typeid;
441
0
        foreach(elem, arrayexpr->elements)
442
0
        {
443
0
          Node     *e = (Node *) lfirst(elem);
444
445
0
          if (exprType(e) != commontype)
446
0
            return -1;
447
0
          if (exprTypmod(e) != typmod)
448
0
            return -1;
449
0
        }
450
0
        return typmod;
451
0
      }
452
0
      break;
453
0
    case T_CoalesceExpr:
454
0
      {
455
        /*
456
         * If all the alternatives agree on type/typmod, return that
457
         * typmod, else use -1
458
         */
459
0
        const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
460
0
        Oid     coalescetype = cexpr->coalescetype;
461
0
        int32   typmod;
462
0
        ListCell   *arg;
463
464
0
        if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
465
0
          return -1;
466
0
        typmod = exprTypmod((Node *) linitial(cexpr->args));
467
0
        if (typmod < 0)
468
0
          return -1; /* no point in trying harder */
469
0
        for_each_from(arg, cexpr->args, 1)
470
0
        {
471
0
          Node     *e = (Node *) lfirst(arg);
472
473
0
          if (exprType(e) != coalescetype)
474
0
            return -1;
475
0
          if (exprTypmod(e) != typmod)
476
0
            return -1;
477
0
        }
478
0
        return typmod;
479
0
      }
480
0
      break;
481
0
    case T_MinMaxExpr:
482
0
      {
483
        /*
484
         * If all the alternatives agree on type/typmod, return that
485
         * typmod, else use -1
486
         */
487
0
        const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
488
0
        Oid     minmaxtype = mexpr->minmaxtype;
489
0
        int32   typmod;
490
0
        ListCell   *arg;
491
492
0
        if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
493
0
          return -1;
494
0
        typmod = exprTypmod((Node *) linitial(mexpr->args));
495
0
        if (typmod < 0)
496
0
          return -1; /* no point in trying harder */
497
0
        for_each_from(arg, mexpr->args, 1)
498
0
        {
499
0
          Node     *e = (Node *) lfirst(arg);
500
501
0
          if (exprType(e) != minmaxtype)
502
0
            return -1;
503
0
          if (exprTypmod(e) != typmod)
504
0
            return -1;
505
0
        }
506
0
        return typmod;
507
0
      }
508
0
      break;
509
0
    case T_SQLValueFunction:
510
0
      return ((const SQLValueFunction *) expr)->typmod;
511
0
    case T_JsonValueExpr:
512
0
      return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
513
0
    case T_JsonConstructorExpr:
514
0
      return ((const JsonConstructorExpr *) expr)->returning->typmod;
515
0
    case T_JsonExpr:
516
0
      {
517
0
        const JsonExpr *jexpr = (const JsonExpr *) expr;
518
519
0
        return jexpr->returning->typmod;
520
0
      }
521
0
      break;
522
0
    case T_JsonBehavior:
523
0
      {
524
0
        const JsonBehavior *behavior = (const JsonBehavior *) expr;
525
526
0
        return exprTypmod(behavior->expr);
527
0
      }
528
0
      break;
529
0
    case T_CoerceToDomain:
530
0
      return ((const CoerceToDomain *) expr)->resulttypmod;
531
0
    case T_CoerceToDomainValue:
532
0
      return ((const CoerceToDomainValue *) expr)->typeMod;
533
0
    case T_SetToDefault:
534
0
      return ((const SetToDefault *) expr)->typeMod;
535
0
    case T_ReturningExpr:
536
0
      return exprTypmod((Node *) ((const ReturningExpr *) expr)->retexpr);
537
0
    case T_PlaceHolderVar:
538
0
      return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
539
0
    default:
540
0
      break;
541
0
  }
542
0
  return -1;
543
0
}
544
545
/*
546
 * exprIsLengthCoercion
547
 *    Detect whether an expression tree is an application of a datatype's
548
 *    typmod-coercion function.  Optionally extract the result's typmod.
549
 *
550
 * If coercedTypmod is not NULL, the typmod is stored there if the expression
551
 * is a length-coercion function, else -1 is stored there.
552
 *
553
 * Note that a combined type-and-length coercion will be treated as a
554
 * length coercion by this routine.
555
 */
556
bool
557
exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
558
0
{
559
0
  if (coercedTypmod != NULL)
560
0
    *coercedTypmod = -1; /* default result on failure */
561
562
  /*
563
   * Scalar-type length coercions are FuncExprs, array-type length coercions
564
   * are ArrayCoerceExprs
565
   */
566
0
  if (expr && IsA(expr, FuncExpr))
567
0
  {
568
0
    const FuncExpr *func = (const FuncExpr *) expr;
569
0
    int     nargs;
570
0
    Const    *second_arg;
571
572
    /*
573
     * If it didn't come from a coercion context, reject.
574
     */
575
0
    if (func->funcformat != COERCE_EXPLICIT_CAST &&
576
0
      func->funcformat != COERCE_IMPLICIT_CAST)
577
0
      return false;
578
579
    /*
580
     * If it's not a two-argument or three-argument function with the
581
     * second argument being an int4 constant, it can't have been created
582
     * from a length coercion (it must be a type coercion, instead).
583
     */
584
0
    nargs = list_length(func->args);
585
0
    if (nargs < 2 || nargs > 3)
586
0
      return false;
587
588
0
    second_arg = (Const *) lsecond(func->args);
589
0
    if (!IsA(second_arg, Const) ||
590
0
      second_arg->consttype != INT4OID ||
591
0
      second_arg->constisnull)
592
0
      return false;
593
594
    /*
595
     * OK, it is indeed a length-coercion function.
596
     */
597
0
    if (coercedTypmod != NULL)
598
0
      *coercedTypmod = DatumGetInt32(second_arg->constvalue);
599
600
0
    return true;
601
0
  }
602
603
0
  if (expr && IsA(expr, ArrayCoerceExpr))
604
0
  {
605
0
    const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
606
607
    /* It's not a length coercion unless there's a nondefault typmod */
608
0
    if (acoerce->resulttypmod < 0)
609
0
      return false;
610
611
    /*
612
     * OK, it is indeed a length-coercion expression.
613
     */
614
0
    if (coercedTypmod != NULL)
615
0
      *coercedTypmod = acoerce->resulttypmod;
616
617
0
    return true;
618
0
  }
619
620
0
  return false;
621
0
}
622
623
/*
624
 * applyRelabelType
625
 *    Add a RelabelType node if needed to make the expression expose
626
 *    the specified type, typmod, and collation.
627
 *
628
 * This is primarily intended to be used during planning.  Therefore, it must
629
 * maintain the post-eval_const_expressions invariants that there are not
630
 * adjacent RelabelTypes, and that the tree is fully const-folded (hence,
631
 * we mustn't return a RelabelType atop a Const).  If we do find a Const,
632
 * we'll modify it in-place if "overwrite_ok" is true; that should only be
633
 * passed as true if caller knows the Const is newly generated.
634
 */
635
Node *
636
applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid,
637
         CoercionForm rformat, int rlocation, bool overwrite_ok)
638
0
{
639
  /*
640
   * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
641
   * all but the top one, and must do so to ensure that semantically
642
   * equivalent expressions are equal().
643
   */
644
0
  while (arg && IsA(arg, RelabelType))
645
0
    arg = (Node *) ((RelabelType *) arg)->arg;
646
647
0
  if (arg && IsA(arg, Const))
648
0
  {
649
    /* Modify the Const directly to preserve const-flatness. */
650
0
    Const    *con = (Const *) arg;
651
652
0
    if (!overwrite_ok)
653
0
      con = copyObject(con);
654
0
    con->consttype = rtype;
655
0
    con->consttypmod = rtypmod;
656
0
    con->constcollid = rcollid;
657
    /* We keep the Const's original location. */
658
0
    return (Node *) con;
659
0
  }
660
0
  else if (exprType(arg) == rtype &&
661
0
       exprTypmod(arg) == rtypmod &&
662
0
       exprCollation(arg) == rcollid)
663
0
  {
664
    /* Sometimes we find a nest of relabels that net out to nothing. */
665
0
    return arg;
666
0
  }
667
0
  else
668
0
  {
669
    /* Nope, gotta have a RelabelType. */
670
0
    RelabelType *newrelabel = makeNode(RelabelType);
671
672
0
    newrelabel->arg = (Expr *) arg;
673
0
    newrelabel->resulttype = rtype;
674
0
    newrelabel->resulttypmod = rtypmod;
675
0
    newrelabel->resultcollid = rcollid;
676
0
    newrelabel->relabelformat = rformat;
677
0
    newrelabel->location = rlocation;
678
0
    return (Node *) newrelabel;
679
0
  }
680
0
}
681
682
/*
683
 * relabel_to_typmod
684
 *    Add a RelabelType node that changes just the typmod of the expression.
685
 *
686
 * Convenience function for a common usage of applyRelabelType.
687
 */
688
Node *
689
relabel_to_typmod(Node *expr, int32 typmod)
690
0
{
691
0
  return applyRelabelType(expr, exprType(expr), typmod, exprCollation(expr),
692
0
              COERCE_EXPLICIT_CAST, -1, false);
693
0
}
694
695
/*
696
 * strip_implicit_coercions: remove implicit coercions at top level of tree
697
 *
698
 * This doesn't modify or copy the input expression tree, just return a
699
 * pointer to a suitable place within it.
700
 *
701
 * Note: there isn't any useful thing we can do with a RowExpr here, so
702
 * just return it unchanged, even if it's marked as an implicit coercion.
703
 */
704
Node *
705
strip_implicit_coercions(Node *node)
706
0
{
707
0
  if (node == NULL)
708
0
    return NULL;
709
0
  if (IsA(node, FuncExpr))
710
0
  {
711
0
    FuncExpr   *f = (FuncExpr *) node;
712
713
0
    if (f->funcformat == COERCE_IMPLICIT_CAST)
714
0
      return strip_implicit_coercions(linitial(f->args));
715
0
  }
716
0
  else if (IsA(node, RelabelType))
717
0
  {
718
0
    RelabelType *r = (RelabelType *) node;
719
720
0
    if (r->relabelformat == COERCE_IMPLICIT_CAST)
721
0
      return strip_implicit_coercions((Node *) r->arg);
722
0
  }
723
0
  else if (IsA(node, CoerceViaIO))
724
0
  {
725
0
    CoerceViaIO *c = (CoerceViaIO *) node;
726
727
0
    if (c->coerceformat == COERCE_IMPLICIT_CAST)
728
0
      return strip_implicit_coercions((Node *) c->arg);
729
0
  }
730
0
  else if (IsA(node, ArrayCoerceExpr))
731
0
  {
732
0
    ArrayCoerceExpr *c = (ArrayCoerceExpr *) node;
733
734
0
    if (c->coerceformat == COERCE_IMPLICIT_CAST)
735
0
      return strip_implicit_coercions((Node *) c->arg);
736
0
  }
737
0
  else if (IsA(node, ConvertRowtypeExpr))
738
0
  {
739
0
    ConvertRowtypeExpr *c = (ConvertRowtypeExpr *) node;
740
741
0
    if (c->convertformat == COERCE_IMPLICIT_CAST)
742
0
      return strip_implicit_coercions((Node *) c->arg);
743
0
  }
744
0
  else if (IsA(node, CoerceToDomain))
745
0
  {
746
0
    CoerceToDomain *c = (CoerceToDomain *) node;
747
748
0
    if (c->coercionformat == COERCE_IMPLICIT_CAST)
749
0
      return strip_implicit_coercions((Node *) c->arg);
750
0
  }
751
0
  return node;
752
0
}
753
754
/*
755
 * expression_returns_set
756
 *    Test whether an expression returns a set result.
757
 *
758
 * Because we use expression_tree_walker(), this can also be applied to
759
 * whole targetlists; it'll produce true if any one of the tlist items
760
 * returns a set.
761
 */
762
bool
763
expression_returns_set(Node *clause)
764
0
{
765
0
  return expression_returns_set_walker(clause, NULL);
766
0
}
767
768
static bool
769
expression_returns_set_walker(Node *node, void *context)
770
0
{
771
0
  if (node == NULL)
772
0
    return false;
773
0
  if (IsA(node, FuncExpr))
774
0
  {
775
0
    FuncExpr   *expr = (FuncExpr *) node;
776
777
0
    if (expr->funcretset)
778
0
      return true;
779
    /* else fall through to check args */
780
0
  }
781
0
  if (IsA(node, OpExpr))
782
0
  {
783
0
    OpExpr     *expr = (OpExpr *) node;
784
785
0
    if (expr->opretset)
786
0
      return true;
787
    /* else fall through to check args */
788
0
  }
789
790
  /*
791
   * If you add any more cases that return sets, also fix
792
   * expression_returns_set_rows() in clauses.c and IS_SRF_CALL() in
793
   * tlist.c.
794
   */
795
796
  /* Avoid recursion for some cases that parser checks not to return a set */
797
0
  if (IsA(node, Aggref))
798
0
    return false;
799
0
  if (IsA(node, GroupingFunc))
800
0
    return false;
801
0
  if (IsA(node, WindowFunc))
802
0
    return false;
803
804
0
  return expression_tree_walker(node, expression_returns_set_walker,
805
0
                  context);
806
0
}
807
808
809
/*
810
 *  exprCollation -
811
 *    returns the Oid of the collation of the expression's result.
812
 *
813
 * Note: expression nodes that can invoke functions generally have an
814
 * "inputcollid" field, which is what the function should use as collation.
815
 * That is the resolved common collation of the node's inputs.  It is often
816
 * but not always the same as the result collation; in particular, if the
817
 * function produces a non-collatable result type from collatable inputs
818
 * or vice versa, the two are different.
819
 */
820
Oid
821
exprCollation(const Node *expr)
822
0
{
823
0
  Oid     coll;
824
825
0
  if (!expr)
826
0
    return InvalidOid;
827
828
0
  switch (nodeTag(expr))
829
0
  {
830
0
    case T_Var:
831
0
      coll = ((const Var *) expr)->varcollid;
832
0
      break;
833
0
    case T_Const:
834
0
      coll = ((const Const *) expr)->constcollid;
835
0
      break;
836
0
    case T_Param:
837
0
      coll = ((const Param *) expr)->paramcollid;
838
0
      break;
839
0
    case T_Aggref:
840
0
      coll = ((const Aggref *) expr)->aggcollid;
841
0
      break;
842
0
    case T_GroupingFunc:
843
0
      coll = InvalidOid;
844
0
      break;
845
0
    case T_WindowFunc:
846
0
      coll = ((const WindowFunc *) expr)->wincollid;
847
0
      break;
848
0
    case T_MergeSupportFunc:
849
0
      coll = ((const MergeSupportFunc *) expr)->msfcollid;
850
0
      break;
851
0
    case T_SubscriptingRef:
852
0
      coll = ((const SubscriptingRef *) expr)->refcollid;
853
0
      break;
854
0
    case T_FuncExpr:
855
0
      coll = ((const FuncExpr *) expr)->funccollid;
856
0
      break;
857
0
    case T_NamedArgExpr:
858
0
      coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
859
0
      break;
860
0
    case T_OpExpr:
861
0
      coll = ((const OpExpr *) expr)->opcollid;
862
0
      break;
863
0
    case T_DistinctExpr:
864
0
      coll = ((const DistinctExpr *) expr)->opcollid;
865
0
      break;
866
0
    case T_NullIfExpr:
867
0
      coll = ((const NullIfExpr *) expr)->opcollid;
868
0
      break;
869
0
    case T_ScalarArrayOpExpr:
870
      /* ScalarArrayOpExpr's result is boolean ... */
871
0
      coll = InvalidOid; /* ... so it has no collation */
872
0
      break;
873
0
    case T_BoolExpr:
874
      /* BoolExpr's result is boolean ... */
875
0
      coll = InvalidOid; /* ... so it has no collation */
876
0
      break;
877
0
    case T_SubLink:
878
0
      {
879
0
        const SubLink *sublink = (const SubLink *) expr;
880
881
0
        if (sublink->subLinkType == EXPR_SUBLINK ||
882
0
          sublink->subLinkType == ARRAY_SUBLINK)
883
0
        {
884
          /* get the collation of subselect's first target column */
885
0
          Query    *qtree = (Query *) sublink->subselect;
886
0
          TargetEntry *tent;
887
888
0
          if (!qtree || !IsA(qtree, Query))
889
0
            elog(ERROR, "cannot get collation for untransformed sublink");
890
0
          tent = linitial_node(TargetEntry, qtree->targetList);
891
0
          Assert(!tent->resjunk);
892
0
          coll = exprCollation((Node *) tent->expr);
893
          /* collation doesn't change if it's converted to array */
894
0
        }
895
0
        else
896
0
        {
897
          /* otherwise, SubLink's result is RECORD or BOOLEAN */
898
0
          coll = InvalidOid; /* ... so it has no collation */
899
0
        }
900
0
      }
901
0
      break;
902
0
    case T_SubPlan:
903
0
      {
904
0
        const SubPlan *subplan = (const SubPlan *) expr;
905
906
0
        if (subplan->subLinkType == EXPR_SUBLINK ||
907
0
          subplan->subLinkType == ARRAY_SUBLINK)
908
0
        {
909
          /* get the collation of subselect's first target column */
910
0
          coll = subplan->firstColCollation;
911
          /* collation doesn't change if it's converted to array */
912
0
        }
913
0
        else
914
0
        {
915
          /* otherwise, SubPlan's result is RECORD or BOOLEAN */
916
0
          coll = InvalidOid; /* ... so it has no collation */
917
0
        }
918
0
      }
919
0
      break;
920
0
    case T_AlternativeSubPlan:
921
0
      {
922
0
        const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
923
924
        /* subplans should all return the same thing */
925
0
        coll = exprCollation((Node *) linitial(asplan->subplans));
926
0
      }
927
0
      break;
928
0
    case T_FieldSelect:
929
0
      coll = ((const FieldSelect *) expr)->resultcollid;
930
0
      break;
931
0
    case T_FieldStore:
932
      /* FieldStore's result is composite ... */
933
0
      coll = InvalidOid; /* ... so it has no collation */
934
0
      break;
935
0
    case T_RelabelType:
936
0
      coll = ((const RelabelType *) expr)->resultcollid;
937
0
      break;
938
0
    case T_CoerceViaIO:
939
0
      coll = ((const CoerceViaIO *) expr)->resultcollid;
940
0
      break;
941
0
    case T_ArrayCoerceExpr:
942
0
      coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
943
0
      break;
944
0
    case T_ConvertRowtypeExpr:
945
      /* ConvertRowtypeExpr's result is composite ... */
946
0
      coll = InvalidOid; /* ... so it has no collation */
947
0
      break;
948
0
    case T_CollateExpr:
949
0
      coll = ((const CollateExpr *) expr)->collOid;
950
0
      break;
951
0
    case T_CaseExpr:
952
0
      coll = ((const CaseExpr *) expr)->casecollid;
953
0
      break;
954
0
    case T_CaseTestExpr:
955
0
      coll = ((const CaseTestExpr *) expr)->collation;
956
0
      break;
957
0
    case T_ArrayExpr:
958
0
      coll = ((const ArrayExpr *) expr)->array_collid;
959
0
      break;
960
0
    case T_RowExpr:
961
      /* RowExpr's result is composite ... */
962
0
      coll = InvalidOid; /* ... so it has no collation */
963
0
      break;
964
0
    case T_RowCompareExpr:
965
      /* RowCompareExpr's result is boolean ... */
966
0
      coll = InvalidOid; /* ... so it has no collation */
967
0
      break;
968
0
    case T_CoalesceExpr:
969
0
      coll = ((const CoalesceExpr *) expr)->coalescecollid;
970
0
      break;
971
0
    case T_MinMaxExpr:
972
0
      coll = ((const MinMaxExpr *) expr)->minmaxcollid;
973
0
      break;
974
0
    case T_SQLValueFunction:
975
      /* Returns either NAME or a non-collatable type */
976
0
      if (((const SQLValueFunction *) expr)->type == NAMEOID)
977
0
        coll = C_COLLATION_OID;
978
0
      else
979
0
        coll = InvalidOid;
980
0
      break;
981
0
    case T_XmlExpr:
982
983
      /*
984
       * XMLSERIALIZE returns text from non-collatable inputs, so its
985
       * collation is always default.  The other cases return boolean or
986
       * XML, which are non-collatable.
987
       */
988
0
      if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
989
0
        coll = DEFAULT_COLLATION_OID;
990
0
      else
991
0
        coll = InvalidOid;
992
0
      break;
993
0
    case T_JsonValueExpr:
994
0
      coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
995
0
      break;
996
0
    case T_JsonConstructorExpr:
997
0
      {
998
0
        const JsonConstructorExpr *ctor = (const JsonConstructorExpr *) expr;
999
1000
        /*
1001
         * Collation comes from coercion if present, otherwise from
1002
         * func.  The func fallback is needed in cases where func
1003
         * already produces the final output type and no coercion is
1004
         * needed (cf. the JSCTOR_JSON_ARRAY_QUERY case).
1005
         */
1006
0
        if (ctor->coercion)
1007
0
          coll = exprCollation((Node *) ctor->coercion);
1008
0
        else if (ctor->func)
1009
0
          coll = exprCollation((Node *) ctor->func);
1010
0
        else
1011
0
          coll = InvalidOid;
1012
0
      }
1013
0
      break;
1014
0
    case T_JsonIsPredicate:
1015
      /* IS JSON's result is boolean ... */
1016
0
      coll = InvalidOid; /* ... so it has no collation */
1017
0
      break;
1018
0
    case T_JsonExpr:
1019
0
      {
1020
0
        const JsonExpr *jsexpr = (const JsonExpr *) expr;
1021
1022
0
        coll = jsexpr->collation;
1023
0
      }
1024
0
      break;
1025
0
    case T_JsonBehavior:
1026
0
      {
1027
0
        const JsonBehavior *behavior = (const JsonBehavior *) expr;
1028
1029
0
        if (behavior->expr)
1030
0
          coll = exprCollation(behavior->expr);
1031
0
        else
1032
0
          coll = InvalidOid;
1033
0
      }
1034
0
      break;
1035
0
    case T_NullTest:
1036
      /* NullTest's result is boolean ... */
1037
0
      coll = InvalidOid; /* ... so it has no collation */
1038
0
      break;
1039
0
    case T_BooleanTest:
1040
      /* BooleanTest's result is boolean ... */
1041
0
      coll = InvalidOid; /* ... so it has no collation */
1042
0
      break;
1043
0
    case T_CoerceToDomain:
1044
0
      coll = ((const CoerceToDomain *) expr)->resultcollid;
1045
0
      break;
1046
0
    case T_CoerceToDomainValue:
1047
0
      coll = ((const CoerceToDomainValue *) expr)->collation;
1048
0
      break;
1049
0
    case T_SetToDefault:
1050
0
      coll = ((const SetToDefault *) expr)->collation;
1051
0
      break;
1052
0
    case T_CurrentOfExpr:
1053
      /* CurrentOfExpr's result is boolean ... */
1054
0
      coll = InvalidOid; /* ... so it has no collation */
1055
0
      break;
1056
0
    case T_NextValueExpr:
1057
      /* NextValueExpr's result is an integer type ... */
1058
0
      coll = InvalidOid; /* ... so it has no collation */
1059
0
      break;
1060
0
    case T_InferenceElem:
1061
0
      coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
1062
0
      break;
1063
0
    case T_ReturningExpr:
1064
0
      coll = exprCollation((Node *) ((const ReturningExpr *) expr)->retexpr);
1065
0
      break;
1066
0
    case T_PlaceHolderVar:
1067
0
      coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1068
0
      break;
1069
0
    default:
1070
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1071
0
      coll = InvalidOid; /* keep compiler quiet */
1072
0
      break;
1073
0
  }
1074
0
  return coll;
1075
0
}
1076
1077
/*
1078
 *  exprInputCollation -
1079
 *    returns the Oid of the collation a function should use, if available.
1080
 *
1081
 * Result is InvalidOid if the node type doesn't store this information.
1082
 */
1083
Oid
1084
exprInputCollation(const Node *expr)
1085
0
{
1086
0
  Oid     coll;
1087
1088
0
  if (!expr)
1089
0
    return InvalidOid;
1090
1091
0
  switch (nodeTag(expr))
1092
0
  {
1093
0
    case T_Aggref:
1094
0
      coll = ((const Aggref *) expr)->inputcollid;
1095
0
      break;
1096
0
    case T_WindowFunc:
1097
0
      coll = ((const WindowFunc *) expr)->inputcollid;
1098
0
      break;
1099
0
    case T_FuncExpr:
1100
0
      coll = ((const FuncExpr *) expr)->inputcollid;
1101
0
      break;
1102
0
    case T_OpExpr:
1103
0
      coll = ((const OpExpr *) expr)->inputcollid;
1104
0
      break;
1105
0
    case T_DistinctExpr:
1106
0
      coll = ((const DistinctExpr *) expr)->inputcollid;
1107
0
      break;
1108
0
    case T_NullIfExpr:
1109
0
      coll = ((const NullIfExpr *) expr)->inputcollid;
1110
0
      break;
1111
0
    case T_ScalarArrayOpExpr:
1112
0
      coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
1113
0
      break;
1114
0
    case T_MinMaxExpr:
1115
0
      coll = ((const MinMaxExpr *) expr)->inputcollid;
1116
0
      break;
1117
0
    default:
1118
0
      coll = InvalidOid;
1119
0
      break;
1120
0
  }
1121
0
  return coll;
1122
0
}
1123
1124
/*
1125
 *  exprSetCollation -
1126
 *    Assign collation information to an expression tree node.
1127
 *
1128
 * Note: since this is only used during parse analysis, we don't need to
1129
 * worry about subplans, PlaceHolderVars, or ReturningExprs.
1130
 */
1131
void
1132
exprSetCollation(Node *expr, Oid collation)
1133
0
{
1134
0
  switch (nodeTag(expr))
1135
0
  {
1136
0
    case T_Var:
1137
0
      ((Var *) expr)->varcollid = collation;
1138
0
      break;
1139
0
    case T_Const:
1140
0
      ((Const *) expr)->constcollid = collation;
1141
0
      break;
1142
0
    case T_Param:
1143
0
      ((Param *) expr)->paramcollid = collation;
1144
0
      break;
1145
0
    case T_Aggref:
1146
0
      ((Aggref *) expr)->aggcollid = collation;
1147
0
      break;
1148
0
    case T_GroupingFunc:
1149
0
      Assert(!OidIsValid(collation));
1150
0
      break;
1151
0
    case T_WindowFunc:
1152
0
      ((WindowFunc *) expr)->wincollid = collation;
1153
0
      break;
1154
0
    case T_MergeSupportFunc:
1155
0
      ((MergeSupportFunc *) expr)->msfcollid = collation;
1156
0
      break;
1157
0
    case T_SubscriptingRef:
1158
0
      ((SubscriptingRef *) expr)->refcollid = collation;
1159
0
      break;
1160
0
    case T_FuncExpr:
1161
0
      ((FuncExpr *) expr)->funccollid = collation;
1162
0
      break;
1163
0
    case T_NamedArgExpr:
1164
0
      Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1165
0
      break;
1166
0
    case T_OpExpr:
1167
0
      ((OpExpr *) expr)->opcollid = collation;
1168
0
      break;
1169
0
    case T_DistinctExpr:
1170
0
      ((DistinctExpr *) expr)->opcollid = collation;
1171
0
      break;
1172
0
    case T_NullIfExpr:
1173
0
      ((NullIfExpr *) expr)->opcollid = collation;
1174
0
      break;
1175
0
    case T_ScalarArrayOpExpr:
1176
      /* ScalarArrayOpExpr's result is boolean ... */
1177
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1178
0
      break;
1179
0
    case T_BoolExpr:
1180
      /* BoolExpr's result is boolean ... */
1181
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1182
0
      break;
1183
0
    case T_SubLink:
1184
#ifdef USE_ASSERT_CHECKING
1185
      {
1186
        SubLink    *sublink = (SubLink *) expr;
1187
1188
        if (sublink->subLinkType == EXPR_SUBLINK ||
1189
          sublink->subLinkType == ARRAY_SUBLINK)
1190
        {
1191
          /* get the collation of subselect's first target column */
1192
          Query    *qtree = (Query *) sublink->subselect;
1193
          TargetEntry *tent;
1194
1195
          if (!qtree || !IsA(qtree, Query))
1196
            elog(ERROR, "cannot set collation for untransformed sublink");
1197
          tent = linitial_node(TargetEntry, qtree->targetList);
1198
          Assert(!tent->resjunk);
1199
          Assert(collation == exprCollation((Node *) tent->expr));
1200
        }
1201
        else
1202
        {
1203
          /* otherwise, result is RECORD or BOOLEAN */
1204
          Assert(!OidIsValid(collation));
1205
        }
1206
      }
1207
#endif              /* USE_ASSERT_CHECKING */
1208
0
      break;
1209
0
    case T_FieldSelect:
1210
0
      ((FieldSelect *) expr)->resultcollid = collation;
1211
0
      break;
1212
0
    case T_FieldStore:
1213
      /* FieldStore's result is composite ... */
1214
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1215
0
      break;
1216
0
    case T_RelabelType:
1217
0
      ((RelabelType *) expr)->resultcollid = collation;
1218
0
      break;
1219
0
    case T_CoerceViaIO:
1220
0
      ((CoerceViaIO *) expr)->resultcollid = collation;
1221
0
      break;
1222
0
    case T_ArrayCoerceExpr:
1223
0
      ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1224
0
      break;
1225
0
    case T_ConvertRowtypeExpr:
1226
      /* ConvertRowtypeExpr's result is composite ... */
1227
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1228
0
      break;
1229
0
    case T_CaseExpr:
1230
0
      ((CaseExpr *) expr)->casecollid = collation;
1231
0
      break;
1232
0
    case T_ArrayExpr:
1233
0
      ((ArrayExpr *) expr)->array_collid = collation;
1234
0
      break;
1235
0
    case T_RowExpr:
1236
      /* RowExpr's result is composite ... */
1237
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1238
0
      break;
1239
0
    case T_RowCompareExpr:
1240
      /* RowCompareExpr's result is boolean ... */
1241
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1242
0
      break;
1243
0
    case T_CoalesceExpr:
1244
0
      ((CoalesceExpr *) expr)->coalescecollid = collation;
1245
0
      break;
1246
0
    case T_MinMaxExpr:
1247
0
      ((MinMaxExpr *) expr)->minmaxcollid = collation;
1248
0
      break;
1249
0
    case T_SQLValueFunction:
1250
0
      Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1251
0
           (collation == C_COLLATION_OID) :
1252
0
           (collation == InvalidOid));
1253
0
      break;
1254
0
    case T_XmlExpr:
1255
0
      Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1256
0
           (collation == DEFAULT_COLLATION_OID) :
1257
0
           (collation == InvalidOid));
1258
0
      break;
1259
0
    case T_JsonValueExpr:
1260
0
      exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
1261
0
               collation);
1262
0
      break;
1263
0
    case T_JsonConstructorExpr:
1264
0
      {
1265
0
        JsonConstructorExpr *ctor = (JsonConstructorExpr *) expr;
1266
1267
        /* See comment in exprCollation() */
1268
0
        if (ctor->coercion)
1269
0
          exprSetCollation((Node *) ctor->coercion, collation);
1270
0
        else if (ctor->func)
1271
0
          exprSetCollation((Node *) ctor->func, collation);
1272
0
        else
1273
0
          Assert(!OidIsValid(collation)); /* result is always a
1274
                           * json[b] type */
1275
0
      }
1276
0
      break;
1277
0
    case T_JsonIsPredicate:
1278
0
      Assert(!OidIsValid(collation)); /* result is always boolean */
1279
0
      break;
1280
0
    case T_JsonExpr:
1281
0
      {
1282
0
        JsonExpr   *jexpr = (JsonExpr *) expr;
1283
1284
0
        jexpr->collation = collation;
1285
0
      }
1286
0
      break;
1287
0
    case T_JsonBehavior:
1288
0
      Assert(((JsonBehavior *) expr)->expr == NULL ||
1289
0
           exprCollation(((JsonBehavior *) expr)->expr) == collation);
1290
0
      break;
1291
0
    case T_NullTest:
1292
      /* NullTest's result is boolean ... */
1293
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1294
0
      break;
1295
0
    case T_BooleanTest:
1296
      /* BooleanTest's result is boolean ... */
1297
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1298
0
      break;
1299
0
    case T_CoerceToDomain:
1300
0
      ((CoerceToDomain *) expr)->resultcollid = collation;
1301
0
      break;
1302
0
    case T_CoerceToDomainValue:
1303
0
      ((CoerceToDomainValue *) expr)->collation = collation;
1304
0
      break;
1305
0
    case T_SetToDefault:
1306
0
      ((SetToDefault *) expr)->collation = collation;
1307
0
      break;
1308
0
    case T_CurrentOfExpr:
1309
      /* CurrentOfExpr's result is boolean ... */
1310
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1311
0
      break;
1312
0
    case T_NextValueExpr:
1313
      /* NextValueExpr's result is an integer type ... */
1314
0
      Assert(!OidIsValid(collation)); /* ... so never set a collation */
1315
0
      break;
1316
0
    default:
1317
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1318
0
      break;
1319
0
  }
1320
0
}
1321
1322
/*
1323
 *  exprSetInputCollation -
1324
 *    Assign input-collation information to an expression tree node.
1325
 *
1326
 * This is a no-op for node types that don't store their input collation.
1327
 * Note we omit RowCompareExpr, which needs special treatment since it
1328
 * contains multiple input collation OIDs.
1329
 */
1330
void
1331
exprSetInputCollation(Node *expr, Oid inputcollation)
1332
0
{
1333
0
  switch (nodeTag(expr))
1334
0
  {
1335
0
    case T_Aggref:
1336
0
      ((Aggref *) expr)->inputcollid = inputcollation;
1337
0
      break;
1338
0
    case T_WindowFunc:
1339
0
      ((WindowFunc *) expr)->inputcollid = inputcollation;
1340
0
      break;
1341
0
    case T_FuncExpr:
1342
0
      ((FuncExpr *) expr)->inputcollid = inputcollation;
1343
0
      break;
1344
0
    case T_OpExpr:
1345
0
      ((OpExpr *) expr)->inputcollid = inputcollation;
1346
0
      break;
1347
0
    case T_DistinctExpr:
1348
0
      ((DistinctExpr *) expr)->inputcollid = inputcollation;
1349
0
      break;
1350
0
    case T_NullIfExpr:
1351
0
      ((NullIfExpr *) expr)->inputcollid = inputcollation;
1352
0
      break;
1353
0
    case T_ScalarArrayOpExpr:
1354
0
      ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1355
0
      break;
1356
0
    case T_MinMaxExpr:
1357
0
      ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1358
0
      break;
1359
0
    default:
1360
0
      break;
1361
0
  }
1362
0
}
1363
1364
1365
/*
1366
 *  exprLocation -
1367
 *    returns the parse location of an expression tree, for error reports
1368
 *
1369
 * -1 is returned if the location can't be determined.
1370
 *
1371
 * For expressions larger than a single token, the intent here is to
1372
 * return the location of the expression's leftmost token, not necessarily
1373
 * the topmost Node's location field.  For example, an OpExpr's location
1374
 * field will point at the operator name, but if it is not a prefix operator
1375
 * then we should return the location of the left-hand operand instead.
1376
 * The reason is that we want to reference the entire expression not just
1377
 * that operator, and pointing to its start seems to be the most natural way.
1378
 *
1379
 * The location is not perfect --- for example, since the grammar doesn't
1380
 * explicitly represent parentheses in the parsetree, given something that
1381
 * had been written "(a + b) * c" we are going to point at "a" not "(".
1382
 * But it should be plenty good enough for error reporting purposes.
1383
 *
1384
 * You might think that this code is overly general, for instance why check
1385
 * the operands of a FuncExpr node, when the function name can be expected
1386
 * to be to the left of them?  There are a couple of reasons.  The grammar
1387
 * sometimes builds expressions that aren't quite what the user wrote;
1388
 * for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
1389
 * pointer is to the right of its leftmost argument.  Also, nodes that were
1390
 * inserted implicitly by parse analysis (such as FuncExprs for implicit
1391
 * coercions) will have location -1, and so we can have odd combinations of
1392
 * known and unknown locations in a tree.
1393
 */
1394
int
1395
exprLocation(const Node *expr)
1396
0
{
1397
0
  int     loc;
1398
1399
0
  if (expr == NULL)
1400
0
    return -1;
1401
0
  switch (nodeTag(expr))
1402
0
  {
1403
0
    case T_RangeVar:
1404
0
      loc = ((const RangeVar *) expr)->location;
1405
0
      break;
1406
0
    case T_TableFunc:
1407
0
      loc = ((const TableFunc *) expr)->location;
1408
0
      break;
1409
0
    case T_Var:
1410
0
      loc = ((const Var *) expr)->location;
1411
0
      break;
1412
0
    case T_Const:
1413
0
      loc = ((const Const *) expr)->location;
1414
0
      break;
1415
0
    case T_Param:
1416
0
      loc = ((const Param *) expr)->location;
1417
0
      break;
1418
0
    case T_Aggref:
1419
      /* function name should always be the first thing */
1420
0
      loc = ((const Aggref *) expr)->location;
1421
0
      break;
1422
0
    case T_GroupingFunc:
1423
0
      loc = ((const GroupingFunc *) expr)->location;
1424
0
      break;
1425
0
    case T_WindowFunc:
1426
      /* function name should always be the first thing */
1427
0
      loc = ((const WindowFunc *) expr)->location;
1428
0
      break;
1429
0
    case T_MergeSupportFunc:
1430
0
      loc = ((const MergeSupportFunc *) expr)->location;
1431
0
      break;
1432
0
    case T_SubscriptingRef:
1433
      /* just use container argument's location */
1434
0
      loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
1435
0
      break;
1436
0
    case T_FuncExpr:
1437
0
      {
1438
0
        const FuncExpr *fexpr = (const FuncExpr *) expr;
1439
1440
        /* consider both function name and leftmost arg */
1441
0
        loc = leftmostLoc(fexpr->location,
1442
0
                  exprLocation((Node *) fexpr->args));
1443
0
      }
1444
0
      break;
1445
0
    case T_NamedArgExpr:
1446
0
      {
1447
0
        const NamedArgExpr *na = (const NamedArgExpr *) expr;
1448
1449
        /* consider both argument name and value */
1450
0
        loc = leftmostLoc(na->location,
1451
0
                  exprLocation((Node *) na->arg));
1452
0
      }
1453
0
      break;
1454
0
    case T_OpExpr:
1455
0
    case T_DistinctExpr:  /* struct-equivalent to OpExpr */
1456
0
    case T_NullIfExpr:    /* struct-equivalent to OpExpr */
1457
0
      {
1458
0
        const OpExpr *opexpr = (const OpExpr *) expr;
1459
1460
        /* consider both operator name and leftmost arg */
1461
0
        loc = leftmostLoc(opexpr->location,
1462
0
                  exprLocation((Node *) opexpr->args));
1463
0
      }
1464
0
      break;
1465
0
    case T_ScalarArrayOpExpr:
1466
0
      {
1467
0
        const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1468
1469
        /* consider both operator name and leftmost arg */
1470
0
        loc = leftmostLoc(saopexpr->location,
1471
0
                  exprLocation((Node *) saopexpr->args));
1472
0
      }
1473
0
      break;
1474
0
    case T_BoolExpr:
1475
0
      {
1476
0
        const BoolExpr *bexpr = (const BoolExpr *) expr;
1477
1478
        /*
1479
         * Same as above, to handle either NOT or AND/OR.  We can't
1480
         * special-case NOT because of the way that it's used for
1481
         * things like IS NOT BETWEEN.
1482
         */
1483
0
        loc = leftmostLoc(bexpr->location,
1484
0
                  exprLocation((Node *) bexpr->args));
1485
0
      }
1486
0
      break;
1487
0
    case T_SubLink:
1488
0
      {
1489
0
        const SubLink *sublink = (const SubLink *) expr;
1490
1491
        /* check the testexpr, if any, and the operator/keyword */
1492
0
        loc = leftmostLoc(exprLocation(sublink->testexpr),
1493
0
                  sublink->location);
1494
0
      }
1495
0
      break;
1496
0
    case T_FieldSelect:
1497
      /* just use argument's location */
1498
0
      loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1499
0
      break;
1500
0
    case T_FieldStore:
1501
      /* just use argument's location */
1502
0
      loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1503
0
      break;
1504
0
    case T_RelabelType:
1505
0
      {
1506
0
        const RelabelType *rexpr = (const RelabelType *) expr;
1507
1508
        /* Much as above */
1509
0
        loc = leftmostLoc(rexpr->location,
1510
0
                  exprLocation((Node *) rexpr->arg));
1511
0
      }
1512
0
      break;
1513
0
    case T_CoerceViaIO:
1514
0
      {
1515
0
        const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1516
1517
        /* Much as above */
1518
0
        loc = leftmostLoc(cexpr->location,
1519
0
                  exprLocation((Node *) cexpr->arg));
1520
0
      }
1521
0
      break;
1522
0
    case T_ArrayCoerceExpr:
1523
0
      {
1524
0
        const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1525
1526
        /* Much as above */
1527
0
        loc = leftmostLoc(cexpr->location,
1528
0
                  exprLocation((Node *) cexpr->arg));
1529
0
      }
1530
0
      break;
1531
0
    case T_ConvertRowtypeExpr:
1532
0
      {
1533
0
        const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1534
1535
        /* Much as above */
1536
0
        loc = leftmostLoc(cexpr->location,
1537
0
                  exprLocation((Node *) cexpr->arg));
1538
0
      }
1539
0
      break;
1540
0
    case T_CollateExpr:
1541
      /* just use argument's location */
1542
0
      loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1543
0
      break;
1544
0
    case T_CaseExpr:
1545
      /* CASE keyword should always be the first thing */
1546
0
      loc = ((const CaseExpr *) expr)->location;
1547
0
      break;
1548
0
    case T_CaseWhen:
1549
      /* WHEN keyword should always be the first thing */
1550
0
      loc = ((const CaseWhen *) expr)->location;
1551
0
      break;
1552
0
    case T_ArrayExpr:
1553
      /* the location points at ARRAY or [, which must be leftmost */
1554
0
      loc = ((const ArrayExpr *) expr)->location;
1555
0
      break;
1556
0
    case T_RowExpr:
1557
      /* the location points at ROW or (, which must be leftmost */
1558
0
      loc = ((const RowExpr *) expr)->location;
1559
0
      break;
1560
0
    case T_RowCompareExpr:
1561
      /* just use leftmost argument's location */
1562
0
      loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1563
0
      break;
1564
0
    case T_CoalesceExpr:
1565
      /* COALESCE keyword should always be the first thing */
1566
0
      loc = ((const CoalesceExpr *) expr)->location;
1567
0
      break;
1568
0
    case T_MinMaxExpr:
1569
      /* GREATEST/LEAST keyword should always be the first thing */
1570
0
      loc = ((const MinMaxExpr *) expr)->location;
1571
0
      break;
1572
0
    case T_SQLValueFunction:
1573
      /* function keyword should always be the first thing */
1574
0
      loc = ((const SQLValueFunction *) expr)->location;
1575
0
      break;
1576
0
    case T_XmlExpr:
1577
0
      {
1578
0
        const XmlExpr *xexpr = (const XmlExpr *) expr;
1579
1580
        /* consider both function name and leftmost arg */
1581
0
        loc = leftmostLoc(xexpr->location,
1582
0
                  exprLocation((Node *) xexpr->args));
1583
0
      }
1584
0
      break;
1585
0
    case T_JsonFormat:
1586
0
      loc = ((const JsonFormat *) expr)->location;
1587
0
      break;
1588
0
    case T_JsonValueExpr:
1589
0
      loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
1590
0
      break;
1591
0
    case T_JsonConstructorExpr:
1592
0
      loc = ((const JsonConstructorExpr *) expr)->location;
1593
0
      break;
1594
0
    case T_JsonIsPredicate:
1595
0
      loc = ((const JsonIsPredicate *) expr)->location;
1596
0
      break;
1597
0
    case T_JsonExpr:
1598
0
      {
1599
0
        const JsonExpr *jsexpr = (const JsonExpr *) expr;
1600
1601
        /* consider both function name and leftmost arg */
1602
0
        loc = leftmostLoc(jsexpr->location,
1603
0
                  exprLocation(jsexpr->formatted_expr));
1604
0
      }
1605
0
      break;
1606
0
    case T_JsonBehavior:
1607
0
      loc = exprLocation(((const JsonBehavior *) expr)->expr);
1608
0
      break;
1609
0
    case T_NullTest:
1610
0
      {
1611
0
        const NullTest *nexpr = (const NullTest *) expr;
1612
1613
        /* Much as above */
1614
0
        loc = leftmostLoc(nexpr->location,
1615
0
                  exprLocation((Node *) nexpr->arg));
1616
0
      }
1617
0
      break;
1618
0
    case T_BooleanTest:
1619
0
      {
1620
0
        const BooleanTest *bexpr = (const BooleanTest *) expr;
1621
1622
        /* Much as above */
1623
0
        loc = leftmostLoc(bexpr->location,
1624
0
                  exprLocation((Node *) bexpr->arg));
1625
0
      }
1626
0
      break;
1627
0
    case T_CoerceToDomain:
1628
0
      {
1629
0
        const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1630
1631
        /* Much as above */
1632
0
        loc = leftmostLoc(cexpr->location,
1633
0
                  exprLocation((Node *) cexpr->arg));
1634
0
      }
1635
0
      break;
1636
0
    case T_CoerceToDomainValue:
1637
0
      loc = ((const CoerceToDomainValue *) expr)->location;
1638
0
      break;
1639
0
    case T_SetToDefault:
1640
0
      loc = ((const SetToDefault *) expr)->location;
1641
0
      break;
1642
0
    case T_ReturningExpr:
1643
0
      loc = exprLocation((Node *) ((const ReturningExpr *) expr)->retexpr);
1644
0
      break;
1645
0
    case T_TargetEntry:
1646
      /* just use argument's location */
1647
0
      loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1648
0
      break;
1649
0
    case T_IntoClause:
1650
      /* use the contained RangeVar's location --- close enough */
1651
0
      loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1652
0
      break;
1653
0
    case T_List:
1654
0
      {
1655
        /* report location of first list member that has a location */
1656
0
        ListCell   *lc;
1657
1658
0
        loc = -1;   /* just to suppress compiler warning */
1659
0
        foreach(lc, (const List *) expr)
1660
0
        {
1661
0
          loc = exprLocation((Node *) lfirst(lc));
1662
0
          if (loc >= 0)
1663
0
            break;
1664
0
        }
1665
0
      }
1666
0
      break;
1667
0
    case T_A_Expr:
1668
0
      {
1669
0
        const A_Expr *aexpr = (const A_Expr *) expr;
1670
1671
        /* use leftmost of operator or left operand (if any) */
1672
        /* we assume right operand can't be to left of operator */
1673
0
        loc = leftmostLoc(aexpr->location,
1674
0
                  exprLocation(aexpr->lexpr));
1675
0
      }
1676
0
      break;
1677
0
    case T_ColumnRef:
1678
0
      loc = ((const ColumnRef *) expr)->location;
1679
0
      break;
1680
0
    case T_ParamRef:
1681
0
      loc = ((const ParamRef *) expr)->location;
1682
0
      break;
1683
0
    case T_A_Const:
1684
0
      loc = ((const A_Const *) expr)->location;
1685
0
      break;
1686
0
    case T_FuncCall:
1687
0
      {
1688
0
        const FuncCall *fc = (const FuncCall *) expr;
1689
1690
        /* consider both function name and leftmost arg */
1691
        /* (we assume any ORDER BY nodes must be to right of name) */
1692
0
        loc = leftmostLoc(fc->location,
1693
0
                  exprLocation((Node *) fc->args));
1694
0
      }
1695
0
      break;
1696
0
    case T_A_ArrayExpr:
1697
      /* the location points at ARRAY or [, which must be leftmost */
1698
0
      loc = ((const A_ArrayExpr *) expr)->location;
1699
0
      break;
1700
0
    case T_ResTarget:
1701
      /* we need not examine the contained expression (if any) */
1702
0
      loc = ((const ResTarget *) expr)->location;
1703
0
      break;
1704
0
    case T_MultiAssignRef:
1705
0
      loc = exprLocation(((const MultiAssignRef *) expr)->source);
1706
0
      break;
1707
0
    case T_TypeCast:
1708
0
      {
1709
0
        const TypeCast *tc = (const TypeCast *) expr;
1710
1711
        /*
1712
         * This could represent CAST(), ::, or TypeName 'literal', so
1713
         * any of the components might be leftmost.
1714
         */
1715
0
        loc = exprLocation(tc->arg);
1716
0
        loc = leftmostLoc(loc, tc->typeName->location);
1717
0
        loc = leftmostLoc(loc, tc->location);
1718
0
      }
1719
0
      break;
1720
0
    case T_CollateClause:
1721
      /* just use argument's location */
1722
0
      loc = exprLocation(((const CollateClause *) expr)->arg);
1723
0
      break;
1724
0
    case T_SortBy:
1725
      /* just use argument's location (ignore operator, if any) */
1726
0
      loc = exprLocation(((const SortBy *) expr)->node);
1727
0
      break;
1728
0
    case T_WindowDef:
1729
0
      loc = ((const WindowDef *) expr)->location;
1730
0
      break;
1731
0
    case T_RangeTableSample:
1732
0
      loc = ((const RangeTableSample *) expr)->location;
1733
0
      break;
1734
0
    case T_TypeName:
1735
0
      loc = ((const TypeName *) expr)->location;
1736
0
      break;
1737
0
    case T_ColumnDef:
1738
0
      loc = ((const ColumnDef *) expr)->location;
1739
0
      break;
1740
0
    case T_IndexElem:
1741
0
      loc = ((const IndexElem *) expr)->location;
1742
0
      break;
1743
0
    case T_Constraint:
1744
0
      loc = ((const Constraint *) expr)->location;
1745
0
      break;
1746
0
    case T_FunctionParameter:
1747
0
      loc = ((const FunctionParameter *) expr)->location;
1748
0
      break;
1749
0
    case T_XmlSerialize:
1750
      /* XMLSERIALIZE keyword should always be the first thing */
1751
0
      loc = ((const XmlSerialize *) expr)->location;
1752
0
      break;
1753
0
    case T_GroupingSet:
1754
0
      loc = ((const GroupingSet *) expr)->location;
1755
0
      break;
1756
0
    case T_WithClause:
1757
0
      loc = ((const WithClause *) expr)->location;
1758
0
      break;
1759
0
    case T_InferClause:
1760
0
      loc = ((const InferClause *) expr)->location;
1761
0
      break;
1762
0
    case T_OnConflictClause:
1763
0
      loc = ((const OnConflictClause *) expr)->location;
1764
0
      break;
1765
0
    case T_CTESearchClause:
1766
0
      loc = ((const CTESearchClause *) expr)->location;
1767
0
      break;
1768
0
    case T_CTECycleClause:
1769
0
      loc = ((const CTECycleClause *) expr)->location;
1770
0
      break;
1771
0
    case T_CommonTableExpr:
1772
0
      loc = ((const CommonTableExpr *) expr)->location;
1773
0
      break;
1774
0
    case T_JsonKeyValue:
1775
      /* just use the key's location */
1776
0
      loc = exprLocation((Node *) ((const JsonKeyValue *) expr)->key);
1777
0
      break;
1778
0
    case T_JsonObjectConstructor:
1779
0
      loc = ((const JsonObjectConstructor *) expr)->location;
1780
0
      break;
1781
0
    case T_JsonArrayConstructor:
1782
0
      loc = ((const JsonArrayConstructor *) expr)->location;
1783
0
      break;
1784
0
    case T_JsonArrayQueryConstructor:
1785
0
      loc = ((const JsonArrayQueryConstructor *) expr)->location;
1786
0
      break;
1787
0
    case T_JsonAggConstructor:
1788
0
      loc = ((const JsonAggConstructor *) expr)->location;
1789
0
      break;
1790
0
    case T_JsonObjectAgg:
1791
0
      loc = exprLocation((Node *) ((const JsonObjectAgg *) expr)->constructor);
1792
0
      break;
1793
0
    case T_JsonArrayAgg:
1794
0
      loc = exprLocation((Node *) ((const JsonArrayAgg *) expr)->constructor);
1795
0
      break;
1796
0
    case T_PlaceHolderVar:
1797
      /* just use argument's location */
1798
0
      loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1799
0
      break;
1800
0
    case T_InferenceElem:
1801
      /* just use nested expr's location */
1802
0
      loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1803
0
      break;
1804
0
    case T_PartitionElem:
1805
0
      loc = ((const PartitionElem *) expr)->location;
1806
0
      break;
1807
0
    case T_PartitionSpec:
1808
0
      loc = ((const PartitionSpec *) expr)->location;
1809
0
      break;
1810
0
    case T_PartitionBoundSpec:
1811
0
      loc = ((const PartitionBoundSpec *) expr)->location;
1812
0
      break;
1813
0
    case T_PartitionRangeDatum:
1814
0
      loc = ((const PartitionRangeDatum *) expr)->location;
1815
0
      break;
1816
0
    default:
1817
      /* for any other node type it's just unknown... */
1818
0
      loc = -1;
1819
0
      break;
1820
0
  }
1821
0
  return loc;
1822
0
}
1823
1824
/*
1825
 * leftmostLoc - support for exprLocation
1826
 *
1827
 * Take the minimum of two parse location values, but ignore unknowns
1828
 */
1829
static int
1830
leftmostLoc(int loc1, int loc2)
1831
0
{
1832
0
  if (loc1 < 0)
1833
0
    return loc2;
1834
0
  else if (loc2 < 0)
1835
0
    return loc1;
1836
0
  else
1837
0
    return Min(loc1, loc2);
1838
0
}
1839
1840
1841
/*
1842
 * fix_opfuncids
1843
 *    Calculate opfuncid field from opno for each OpExpr node in given tree.
1844
 *    The given tree can be anything expression_tree_walker handles.
1845
 *
1846
 * The argument is modified in-place.  (This is OK since we'd want the
1847
 * same change for any node, even if it gets visited more than once due to
1848
 * shared structure.)
1849
 */
1850
void
1851
fix_opfuncids(Node *node)
1852
0
{
1853
  /* This tree walk requires no special setup, so away we go... */
1854
0
  fix_opfuncids_walker(node, NULL);
1855
0
}
1856
1857
static bool
1858
fix_opfuncids_walker(Node *node, void *context)
1859
0
{
1860
0
  if (node == NULL)
1861
0
    return false;
1862
0
  if (IsA(node, OpExpr))
1863
0
    set_opfuncid((OpExpr *) node);
1864
0
  else if (IsA(node, DistinctExpr))
1865
0
    set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1866
0
  else if (IsA(node, NullIfExpr))
1867
0
    set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1868
0
  else if (IsA(node, ScalarArrayOpExpr))
1869
0
    set_sa_opfuncid((ScalarArrayOpExpr *) node);
1870
0
  return expression_tree_walker(node, fix_opfuncids_walker, context);
1871
0
}
1872
1873
/*
1874
 * set_opfuncid
1875
 *    Set the opfuncid (procedure OID) in an OpExpr node,
1876
 *    if it hasn't been set already.
1877
 *
1878
 * Because of struct equivalence, this can also be used for
1879
 * DistinctExpr and NullIfExpr nodes.
1880
 */
1881
void
1882
set_opfuncid(OpExpr *opexpr)
1883
0
{
1884
0
  if (opexpr->opfuncid == InvalidOid)
1885
0
    opexpr->opfuncid = get_opcode(opexpr->opno);
1886
0
}
1887
1888
/*
1889
 * set_sa_opfuncid
1890
 *    As above, for ScalarArrayOpExpr nodes.
1891
 */
1892
void
1893
set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
1894
0
{
1895
0
  if (opexpr->opfuncid == InvalidOid)
1896
0
    opexpr->opfuncid = get_opcode(opexpr->opno);
1897
0
}
1898
1899
1900
/*
1901
 *  check_functions_in_node -
1902
 *    apply checker() to each function OID contained in given expression node
1903
 *
1904
 * Returns true if the checker() function does; for nodes representing more
1905
 * than one function call, returns true if the checker() function does so
1906
 * for any of those functions.  Returns false if node does not invoke any
1907
 * SQL-visible function.  Caller must not pass node == NULL.
1908
 *
1909
 * This function examines only the given node; it does not recurse into any
1910
 * sub-expressions.  Callers typically prefer to keep control of the recursion
1911
 * for themselves, in case additional checks should be made, or because they
1912
 * have special rules about which parts of the tree need to be visited.
1913
 *
1914
 * Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
1915
 * and NextValueExpr nodes, because they do not contain SQL function OIDs.
1916
 * However, they can invoke SQL-visible functions, so callers should take
1917
 * thought about how to treat them.
1918
 */
1919
bool
1920
check_functions_in_node(Node *node, check_function_callback checker,
1921
            void *context)
1922
0
{
1923
0
  switch (nodeTag(node))
1924
0
  {
1925
0
    case T_Aggref:
1926
0
      {
1927
0
        Aggref     *expr = (Aggref *) node;
1928
1929
0
        if (checker(expr->aggfnoid, context))
1930
0
          return true;
1931
0
      }
1932
0
      break;
1933
0
    case T_WindowFunc:
1934
0
      {
1935
0
        WindowFunc *expr = (WindowFunc *) node;
1936
1937
0
        if (checker(expr->winfnoid, context))
1938
0
          return true;
1939
0
      }
1940
0
      break;
1941
0
    case T_FuncExpr:
1942
0
      {
1943
0
        FuncExpr   *expr = (FuncExpr *) node;
1944
1945
0
        if (checker(expr->funcid, context))
1946
0
          return true;
1947
0
      }
1948
0
      break;
1949
0
    case T_OpExpr:
1950
0
    case T_DistinctExpr:  /* struct-equivalent to OpExpr */
1951
0
    case T_NullIfExpr:    /* struct-equivalent to OpExpr */
1952
0
      {
1953
0
        OpExpr     *expr = (OpExpr *) node;
1954
1955
        /* Set opfuncid if it wasn't set already */
1956
0
        set_opfuncid(expr);
1957
0
        if (checker(expr->opfuncid, context))
1958
0
          return true;
1959
0
      }
1960
0
      break;
1961
0
    case T_ScalarArrayOpExpr:
1962
0
      {
1963
0
        ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1964
1965
0
        set_sa_opfuncid(expr);
1966
0
        if (checker(expr->opfuncid, context))
1967
0
          return true;
1968
0
      }
1969
0
      break;
1970
0
    case T_CoerceViaIO:
1971
0
      {
1972
0
        CoerceViaIO *expr = (CoerceViaIO *) node;
1973
0
        Oid     iofunc;
1974
0
        Oid     typioparam;
1975
0
        bool    typisvarlena;
1976
1977
        /* check the result type's input function */
1978
0
        getTypeInputInfo(expr->resulttype,
1979
0
                 &iofunc, &typioparam);
1980
0
        if (checker(iofunc, context))
1981
0
          return true;
1982
        /* check the input type's output function */
1983
0
        getTypeOutputInfo(exprType((Node *) expr->arg),
1984
0
                  &iofunc, &typisvarlena);
1985
0
        if (checker(iofunc, context))
1986
0
          return true;
1987
0
      }
1988
0
      break;
1989
0
    case T_RowCompareExpr:
1990
0
      {
1991
0
        RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1992
0
        ListCell   *opid;
1993
1994
0
        foreach(opid, rcexpr->opnos)
1995
0
        {
1996
0
          Oid     opfuncid = get_opcode(lfirst_oid(opid));
1997
1998
0
          if (checker(opfuncid, context))
1999
0
            return true;
2000
0
        }
2001
0
      }
2002
0
      break;
2003
0
    default:
2004
0
      break;
2005
0
  }
2006
0
  return false;
2007
0
}
2008
2009
2010
/*
2011
 * Standard expression-tree walking support
2012
 *
2013
 * We used to have near-duplicate code in many different routines that
2014
 * understood how to recurse through an expression node tree.  That was
2015
 * a pain to maintain, and we frequently had bugs due to some particular
2016
 * routine neglecting to support a particular node type.  In most cases,
2017
 * these routines only actually care about certain node types, and don't
2018
 * care about other types except insofar as they have to recurse through
2019
 * non-primitive node types.  Therefore, we now provide generic tree-walking
2020
 * logic to consolidate the redundant "boilerplate" code.  There are
2021
 * two versions: expression_tree_walker() and expression_tree_mutator().
2022
 */
2023
2024
/*
2025
 * expression_tree_walker() is designed to support routines that traverse
2026
 * a tree in a read-only fashion (although it will also work for routines
2027
 * that modify nodes in-place but never add/delete/replace nodes).
2028
 * A walker routine should look like this:
2029
 *
2030
 * bool my_walker (Node *node, my_struct *context)
2031
 * {
2032
 *    if (node == NULL)
2033
 *      return false;
2034
 *    // check for nodes that special work is required for, eg:
2035
 *    if (IsA(node, Var))
2036
 *    {
2037
 *      ... do special actions for Var nodes
2038
 *    }
2039
 *    else if (IsA(node, ...))
2040
 *    {
2041
 *      ... do special actions for other node types
2042
 *    }
2043
 *    // for any node type not specially processed, do:
2044
 *    return expression_tree_walker(node, my_walker, context);
2045
 * }
2046
 *
2047
 * The "context" argument points to a struct that holds whatever context
2048
 * information the walker routine needs --- it can be used to return data
2049
 * gathered by the walker, too.  This argument is not touched by
2050
 * expression_tree_walker, but it is passed down to recursive sub-invocations
2051
 * of my_walker.  The tree walk is started from a setup routine that
2052
 * fills in the appropriate context struct, calls my_walker with the top-level
2053
 * node of the tree, and then examines the results.
2054
 *
2055
 * The walker routine should return "false" to continue the tree walk, or
2056
 * "true" to abort the walk and immediately return "true" to the top-level
2057
 * caller.  This can be used to short-circuit the traversal if the walker
2058
 * has found what it came for.  "false" is returned to the top-level caller
2059
 * iff no invocation of the walker returned "true".
2060
 *
2061
 * The node types handled by expression_tree_walker include all those
2062
 * normally found in target lists and qualifier clauses during the planning
2063
 * stage.  In particular, it handles List nodes since a cnf-ified qual clause
2064
 * will have List structure at the top level, and it handles TargetEntry nodes
2065
 * so that a scan of a target list can be handled without additional code.
2066
 * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
2067
 * handled, so that query jointrees and setOperation trees can be processed
2068
 * without additional code.
2069
 *
2070
 * expression_tree_walker will handle SubLink nodes by recursing normally
2071
 * into the "testexpr" subtree (which is an expression belonging to the outer
2072
 * plan).  It will also call the walker on the sub-Query node; however, when
2073
 * expression_tree_walker itself is called on a Query node, it does nothing
2074
 * and returns "false".  The net effect is that unless the walker does
2075
 * something special at a Query node, sub-selects will not be visited during
2076
 * an expression tree walk. This is exactly the behavior wanted in many cases
2077
 * --- and for those walkers that do want to recurse into sub-selects, special
2078
 * behavior is typically needed anyway at the entry to a sub-select (such as
2079
 * incrementing a depth counter). A walker that wants to examine sub-selects
2080
 * should include code along the lines of:
2081
 *
2082
 *    if (IsA(node, Query))
2083
 *    {
2084
 *      adjust context for subquery;
2085
 *      result = query_tree_walker((Query *) node, my_walker, context,
2086
 *                     0); // adjust flags as needed
2087
 *      restore context if needed;
2088
 *      return result;
2089
 *    }
2090
 *
2091
 * query_tree_walker is a convenience routine (see below) that calls the
2092
 * walker on all the expression subtrees of the given Query node.
2093
 *
2094
 * expression_tree_walker will handle SubPlan nodes by recursing normally
2095
 * into the "testexpr" and the "args" list (which are expressions belonging to
2096
 * the outer plan).  It will not touch the completed subplan, however.  Since
2097
 * there is no link to the original Query, it is not possible to recurse into
2098
 * subselects of an already-planned expression tree.  This is OK for current
2099
 * uses, but may need to be revisited in future.
2100
 */
2101
2102
pg_attribute_no_sanitize_function()
2103
bool
2104
expression_tree_walker_impl(Node *node,
2105
              tree_walker_callback walker,
2106
              void *context)
2107
0
{
2108
0
  ListCell   *temp;
2109
2110
  /*
2111
   * The walker has already visited the current node, and so we need only
2112
   * recurse into any sub-nodes it has.
2113
   *
2114
   * We assume that the walker is not interested in List nodes per se, so
2115
   * when we expect a List we just recurse directly to self without
2116
   * bothering to call the walker.
2117
   */
2118
0
#define WALK(n) walker((Node *) (n), context)
2119
2120
0
#define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
2121
2122
0
  if (node == NULL)
2123
0
    return false;
2124
2125
  /* Guard against stack overflow due to overly complex expressions */
2126
0
  check_stack_depth();
2127
2128
0
  switch (nodeTag(node))
2129
0
  {
2130
0
    case T_Var:
2131
0
    case T_Const:
2132
0
    case T_Param:
2133
0
    case T_CaseTestExpr:
2134
0
    case T_SQLValueFunction:
2135
0
    case T_CoerceToDomainValue:
2136
0
    case T_SetToDefault:
2137
0
    case T_CurrentOfExpr:
2138
0
    case T_NextValueExpr:
2139
0
    case T_RangeTblRef:
2140
0
    case T_SortGroupClause:
2141
0
    case T_CTESearchClause:
2142
0
    case T_MergeSupportFunc:
2143
      /* primitive node types with no expression subnodes */
2144
0
      break;
2145
0
    case T_WithCheckOption:
2146
0
      return WALK(((WithCheckOption *) node)->qual);
2147
0
    case T_Aggref:
2148
0
      {
2149
0
        Aggref     *expr = (Aggref *) node;
2150
2151
        /* recurse directly on Lists */
2152
0
        if (LIST_WALK(expr->aggdirectargs))
2153
0
          return true;
2154
0
        if (LIST_WALK(expr->args))
2155
0
          return true;
2156
0
        if (LIST_WALK(expr->aggorder))
2157
0
          return true;
2158
0
        if (LIST_WALK(expr->aggdistinct))
2159
0
          return true;
2160
0
        if (WALK(expr->aggfilter))
2161
0
          return true;
2162
0
      }
2163
0
      break;
2164
0
    case T_GroupingFunc:
2165
0
      {
2166
0
        GroupingFunc *grouping = (GroupingFunc *) node;
2167
2168
0
        if (LIST_WALK(grouping->args))
2169
0
          return true;
2170
0
      }
2171
0
      break;
2172
0
    case T_WindowFunc:
2173
0
      {
2174
0
        WindowFunc *expr = (WindowFunc *) node;
2175
2176
        /* recurse directly on List */
2177
0
        if (LIST_WALK(expr->args))
2178
0
          return true;
2179
0
        if (WALK(expr->aggfilter))
2180
0
          return true;
2181
0
        if (WALK(expr->runCondition))
2182
0
          return true;
2183
0
      }
2184
0
      break;
2185
0
    case T_WindowFuncRunCondition:
2186
0
      {
2187
0
        WindowFuncRunCondition *expr = (WindowFuncRunCondition *) node;
2188
2189
0
        if (WALK(expr->arg))
2190
0
          return true;
2191
0
      }
2192
0
      break;
2193
0
    case T_SubscriptingRef:
2194
0
      {
2195
0
        SubscriptingRef *sbsref = (SubscriptingRef *) node;
2196
2197
        /* recurse directly for upper/lower container index lists */
2198
0
        if (LIST_WALK(sbsref->refupperindexpr))
2199
0
          return true;
2200
0
        if (LIST_WALK(sbsref->reflowerindexpr))
2201
0
          return true;
2202
        /* walker must see the refexpr and refassgnexpr, however */
2203
0
        if (WALK(sbsref->refexpr))
2204
0
          return true;
2205
2206
0
        if (WALK(sbsref->refassgnexpr))
2207
0
          return true;
2208
0
      }
2209
0
      break;
2210
0
    case T_FuncExpr:
2211
0
      {
2212
0
        FuncExpr   *expr = (FuncExpr *) node;
2213
2214
0
        if (LIST_WALK(expr->args))
2215
0
          return true;
2216
0
      }
2217
0
      break;
2218
0
    case T_NamedArgExpr:
2219
0
      return WALK(((NamedArgExpr *) node)->arg);
2220
0
    case T_OpExpr:
2221
0
    case T_DistinctExpr:  /* struct-equivalent to OpExpr */
2222
0
    case T_NullIfExpr:    /* struct-equivalent to OpExpr */
2223
0
      {
2224
0
        OpExpr     *expr = (OpExpr *) node;
2225
2226
0
        if (LIST_WALK(expr->args))
2227
0
          return true;
2228
0
      }
2229
0
      break;
2230
0
    case T_ScalarArrayOpExpr:
2231
0
      {
2232
0
        ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2233
2234
0
        if (LIST_WALK(expr->args))
2235
0
          return true;
2236
0
      }
2237
0
      break;
2238
0
    case T_BoolExpr:
2239
0
      {
2240
0
        BoolExpr   *expr = (BoolExpr *) node;
2241
2242
0
        if (LIST_WALK(expr->args))
2243
0
          return true;
2244
0
      }
2245
0
      break;
2246
0
    case T_SubLink:
2247
0
      {
2248
0
        SubLink    *sublink = (SubLink *) node;
2249
2250
0
        if (WALK(sublink->testexpr))
2251
0
          return true;
2252
2253
        /*
2254
         * Also invoke the walker on the sublink's Query node, so it
2255
         * can recurse into the sub-query if it wants to.
2256
         */
2257
0
        return WALK(sublink->subselect);
2258
0
      }
2259
0
      break;
2260
0
    case T_SubPlan:
2261
0
      {
2262
0
        SubPlan    *subplan = (SubPlan *) node;
2263
2264
        /* recurse into the testexpr, but not into the Plan */
2265
0
        if (WALK(subplan->testexpr))
2266
0
          return true;
2267
        /* also examine args list */
2268
0
        if (LIST_WALK(subplan->args))
2269
0
          return true;
2270
0
      }
2271
0
      break;
2272
0
    case T_AlternativeSubPlan:
2273
0
      return LIST_WALK(((AlternativeSubPlan *) node)->subplans);
2274
0
    case T_FieldSelect:
2275
0
      return WALK(((FieldSelect *) node)->arg);
2276
0
    case T_FieldStore:
2277
0
      {
2278
0
        FieldStore *fstore = (FieldStore *) node;
2279
2280
0
        if (WALK(fstore->arg))
2281
0
          return true;
2282
0
        if (WALK(fstore->newvals))
2283
0
          return true;
2284
0
      }
2285
0
      break;
2286
0
    case T_RelabelType:
2287
0
      return WALK(((RelabelType *) node)->arg);
2288
0
    case T_CoerceViaIO:
2289
0
      return WALK(((CoerceViaIO *) node)->arg);
2290
0
    case T_ArrayCoerceExpr:
2291
0
      {
2292
0
        ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2293
2294
0
        if (WALK(acoerce->arg))
2295
0
          return true;
2296
0
        if (WALK(acoerce->elemexpr))
2297
0
          return true;
2298
0
      }
2299
0
      break;
2300
0
    case T_ConvertRowtypeExpr:
2301
0
      return WALK(((ConvertRowtypeExpr *) node)->arg);
2302
0
    case T_CollateExpr:
2303
0
      return WALK(((CollateExpr *) node)->arg);
2304
0
    case T_CaseExpr:
2305
0
      {
2306
0
        CaseExpr   *caseexpr = (CaseExpr *) node;
2307
2308
0
        if (WALK(caseexpr->arg))
2309
0
          return true;
2310
        /* we assume walker doesn't care about CaseWhens, either */
2311
0
        foreach(temp, caseexpr->args)
2312
0
        {
2313
0
          CaseWhen   *when = lfirst_node(CaseWhen, temp);
2314
2315
0
          if (WALK(when->expr))
2316
0
            return true;
2317
0
          if (WALK(when->result))
2318
0
            return true;
2319
0
        }
2320
0
        if (WALK(caseexpr->defresult))
2321
0
          return true;
2322
0
      }
2323
0
      break;
2324
0
    case T_ArrayExpr:
2325
0
      return WALK(((ArrayExpr *) node)->elements);
2326
0
    case T_RowExpr:
2327
      /* Assume colnames isn't interesting */
2328
0
      return WALK(((RowExpr *) node)->args);
2329
0
    case T_RowCompareExpr:
2330
0
      {
2331
0
        RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2332
2333
0
        if (WALK(rcexpr->largs))
2334
0
          return true;
2335
0
        if (WALK(rcexpr->rargs))
2336
0
          return true;
2337
0
      }
2338
0
      break;
2339
0
    case T_CoalesceExpr:
2340
0
      return WALK(((CoalesceExpr *) node)->args);
2341
0
    case T_MinMaxExpr:
2342
0
      return WALK(((MinMaxExpr *) node)->args);
2343
0
    case T_XmlExpr:
2344
0
      {
2345
0
        XmlExpr    *xexpr = (XmlExpr *) node;
2346
2347
0
        if (WALK(xexpr->named_args))
2348
0
          return true;
2349
        /* we assume walker doesn't care about arg_names */
2350
0
        if (WALK(xexpr->args))
2351
0
          return true;
2352
0
      }
2353
0
      break;
2354
0
    case T_JsonValueExpr:
2355
0
      {
2356
0
        JsonValueExpr *jve = (JsonValueExpr *) node;
2357
2358
0
        if (WALK(jve->raw_expr))
2359
0
          return true;
2360
0
        if (WALK(jve->formatted_expr))
2361
0
          return true;
2362
0
      }
2363
0
      break;
2364
0
    case T_JsonConstructorExpr:
2365
0
      {
2366
0
        JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
2367
2368
0
        if (WALK(ctor->args))
2369
0
          return true;
2370
0
        if (WALK(ctor->func))
2371
0
          return true;
2372
0
        if (WALK(ctor->coercion))
2373
0
          return true;
2374
0
      }
2375
0
      break;
2376
0
    case T_JsonIsPredicate:
2377
0
      return WALK(((JsonIsPredicate *) node)->expr);
2378
0
    case T_JsonExpr:
2379
0
      {
2380
0
        JsonExpr   *jexpr = (JsonExpr *) node;
2381
2382
0
        if (WALK(jexpr->formatted_expr))
2383
0
          return true;
2384
0
        if (WALK(jexpr->path_spec))
2385
0
          return true;
2386
0
        if (WALK(jexpr->passing_values))
2387
0
          return true;
2388
        /* we assume walker doesn't care about passing_names */
2389
0
        if (WALK(jexpr->on_empty))
2390
0
          return true;
2391
0
        if (WALK(jexpr->on_error))
2392
0
          return true;
2393
0
      }
2394
0
      break;
2395
0
    case T_JsonBehavior:
2396
0
      {
2397
0
        JsonBehavior *behavior = (JsonBehavior *) node;
2398
2399
0
        if (WALK(behavior->expr))
2400
0
          return true;
2401
0
      }
2402
0
      break;
2403
0
    case T_NullTest:
2404
0
      return WALK(((NullTest *) node)->arg);
2405
0
    case T_BooleanTest:
2406
0
      return WALK(((BooleanTest *) node)->arg);
2407
0
    case T_CoerceToDomain:
2408
0
      return WALK(((CoerceToDomain *) node)->arg);
2409
0
    case T_TargetEntry:
2410
0
      return WALK(((TargetEntry *) node)->expr);
2411
0
    case T_Query:
2412
      /* Do nothing with a sub-Query, per discussion above */
2413
0
      break;
2414
0
    case T_WindowClause:
2415
0
      {
2416
0
        WindowClause *wc = (WindowClause *) node;
2417
2418
0
        if (WALK(wc->partitionClause))
2419
0
          return true;
2420
0
        if (WALK(wc->orderClause))
2421
0
          return true;
2422
0
        if (WALK(wc->startOffset))
2423
0
          return true;
2424
0
        if (WALK(wc->endOffset))
2425
0
          return true;
2426
0
      }
2427
0
      break;
2428
0
    case T_CTECycleClause:
2429
0
      {
2430
0
        CTECycleClause *cc = (CTECycleClause *) node;
2431
2432
0
        if (WALK(cc->cycle_mark_value))
2433
0
          return true;
2434
0
        if (WALK(cc->cycle_mark_default))
2435
0
          return true;
2436
0
      }
2437
0
      break;
2438
0
    case T_CommonTableExpr:
2439
0
      {
2440
0
        CommonTableExpr *cte = (CommonTableExpr *) node;
2441
2442
        /*
2443
         * Invoke the walker on the CTE's Query node, so it can
2444
         * recurse into the sub-query if it wants to.
2445
         */
2446
0
        if (WALK(cte->ctequery))
2447
0
          return true;
2448
2449
0
        if (WALK(cte->search_clause))
2450
0
          return true;
2451
0
        if (WALK(cte->cycle_clause))
2452
0
          return true;
2453
0
      }
2454
0
      break;
2455
0
    case T_JsonKeyValue:
2456
0
      {
2457
0
        JsonKeyValue *kv = (JsonKeyValue *) node;
2458
2459
0
        if (WALK(kv->key))
2460
0
          return true;
2461
0
        if (WALK(kv->value))
2462
0
          return true;
2463
0
      }
2464
0
      break;
2465
0
    case T_JsonObjectConstructor:
2466
0
      {
2467
0
        JsonObjectConstructor *ctor = (JsonObjectConstructor *) node;
2468
2469
0
        if (LIST_WALK(ctor->exprs))
2470
0
          return true;
2471
0
      }
2472
0
      break;
2473
0
    case T_JsonArrayConstructor:
2474
0
      {
2475
0
        JsonArrayConstructor *ctor = (JsonArrayConstructor *) node;
2476
2477
0
        if (LIST_WALK(ctor->exprs))
2478
0
          return true;
2479
0
      }
2480
0
      break;
2481
0
    case T_JsonArrayQueryConstructor:
2482
0
      {
2483
0
        JsonArrayQueryConstructor *ctor = (JsonArrayQueryConstructor *) node;
2484
2485
0
        if (WALK(ctor->query))
2486
0
          return true;
2487
0
      }
2488
0
      break;
2489
0
    case T_JsonAggConstructor:
2490
0
      {
2491
0
        JsonAggConstructor *ctor = (JsonAggConstructor *) node;
2492
2493
0
        if (WALK(ctor->agg_filter))
2494
0
          return true;
2495
0
        if (WALK(ctor->agg_order))
2496
0
          return true;
2497
0
        if (WALK(ctor->over))
2498
0
          return true;
2499
0
      }
2500
0
      break;
2501
0
    case T_JsonObjectAgg:
2502
0
      {
2503
0
        JsonObjectAgg *ctor = (JsonObjectAgg *) node;
2504
2505
0
        if (WALK(ctor->constructor))
2506
0
          return true;
2507
0
        if (WALK(ctor->arg))
2508
0
          return true;
2509
0
      }
2510
0
      break;
2511
0
    case T_JsonArrayAgg:
2512
0
      {
2513
0
        JsonArrayAgg *ctor = (JsonArrayAgg *) node;
2514
2515
0
        if (WALK(ctor->constructor))
2516
0
          return true;
2517
0
        if (WALK(ctor->arg))
2518
0
          return true;
2519
0
      }
2520
0
      break;
2521
2522
0
    case T_PartitionBoundSpec:
2523
0
      {
2524
0
        PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
2525
2526
0
        if (WALK(pbs->listdatums))
2527
0
          return true;
2528
0
        if (WALK(pbs->lowerdatums))
2529
0
          return true;
2530
0
        if (WALK(pbs->upperdatums))
2531
0
          return true;
2532
0
      }
2533
0
      break;
2534
0
    case T_PartitionRangeDatum:
2535
0
      {
2536
0
        PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
2537
2538
0
        if (WALK(prd->value))
2539
0
          return true;
2540
0
      }
2541
0
      break;
2542
0
    case T_List:
2543
0
      foreach(temp, (List *) node)
2544
0
      {
2545
0
        if (WALK(lfirst(temp)))
2546
0
          return true;
2547
0
      }
2548
0
      break;
2549
0
    case T_FromExpr:
2550
0
      {
2551
0
        FromExpr   *from = (FromExpr *) node;
2552
2553
0
        if (LIST_WALK(from->fromlist))
2554
0
          return true;
2555
0
        if (WALK(from->quals))
2556
0
          return true;
2557
0
      }
2558
0
      break;
2559
0
    case T_OnConflictExpr:
2560
0
      {
2561
0
        OnConflictExpr *onconflict = (OnConflictExpr *) node;
2562
2563
0
        if (WALK(onconflict->arbiterElems))
2564
0
          return true;
2565
0
        if (WALK(onconflict->arbiterWhere))
2566
0
          return true;
2567
0
        if (WALK(onconflict->onConflictSet))
2568
0
          return true;
2569
0
        if (WALK(onconflict->onConflictWhere))
2570
0
          return true;
2571
0
        if (WALK(onconflict->exclRelTlist))
2572
0
          return true;
2573
0
      }
2574
0
      break;
2575
0
    case T_MergeAction:
2576
0
      {
2577
0
        MergeAction *action = (MergeAction *) node;
2578
2579
0
        if (WALK(action->qual))
2580
0
          return true;
2581
0
        if (WALK(action->targetList))
2582
0
          return true;
2583
0
      }
2584
0
      break;
2585
0
    case T_PartitionPruneStepOp:
2586
0
      {
2587
0
        PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2588
2589
0
        if (WALK(opstep->exprs))
2590
0
          return true;
2591
0
      }
2592
0
      break;
2593
0
    case T_PartitionPruneStepCombine:
2594
      /* no expression subnodes */
2595
0
      break;
2596
0
    case T_JoinExpr:
2597
0
      {
2598
0
        JoinExpr   *join = (JoinExpr *) node;
2599
2600
0
        if (WALK(join->larg))
2601
0
          return true;
2602
0
        if (WALK(join->rarg))
2603
0
          return true;
2604
0
        if (WALK(join->quals))
2605
0
          return true;
2606
2607
        /*
2608
         * alias clause, using list are deemed uninteresting.
2609
         */
2610
0
      }
2611
0
      break;
2612
0
    case T_SetOperationStmt:
2613
0
      {
2614
0
        SetOperationStmt *setop = (SetOperationStmt *) node;
2615
2616
0
        if (WALK(setop->larg))
2617
0
          return true;
2618
0
        if (WALK(setop->rarg))
2619
0
          return true;
2620
2621
        /* groupClauses are deemed uninteresting */
2622
0
      }
2623
0
      break;
2624
0
    case T_IndexClause:
2625
0
      {
2626
0
        IndexClause *iclause = (IndexClause *) node;
2627
2628
0
        if (WALK(iclause->rinfo))
2629
0
          return true;
2630
0
        if (LIST_WALK(iclause->indexquals))
2631
0
          return true;
2632
0
      }
2633
0
      break;
2634
0
    case T_PlaceHolderVar:
2635
0
      return WALK(((PlaceHolderVar *) node)->phexpr);
2636
0
    case T_InferenceElem:
2637
0
      return WALK(((InferenceElem *) node)->expr);
2638
0
    case T_ReturningExpr:
2639
0
      return WALK(((ReturningExpr *) node)->retexpr);
2640
0
    case T_AppendRelInfo:
2641
0
      {
2642
0
        AppendRelInfo *appinfo = (AppendRelInfo *) node;
2643
2644
0
        if (LIST_WALK(appinfo->translated_vars))
2645
0
          return true;
2646
0
      }
2647
0
      break;
2648
0
    case T_PlaceHolderInfo:
2649
0
      return WALK(((PlaceHolderInfo *) node)->ph_var);
2650
0
    case T_RangeTblFunction:
2651
0
      return WALK(((RangeTblFunction *) node)->funcexpr);
2652
0
    case T_TableSampleClause:
2653
0
      {
2654
0
        TableSampleClause *tsc = (TableSampleClause *) node;
2655
2656
0
        if (LIST_WALK(tsc->args))
2657
0
          return true;
2658
0
        if (WALK(tsc->repeatable))
2659
0
          return true;
2660
0
      }
2661
0
      break;
2662
0
    case T_TableFunc:
2663
0
      {
2664
0
        TableFunc  *tf = (TableFunc *) node;
2665
2666
0
        if (WALK(tf->ns_uris))
2667
0
          return true;
2668
0
        if (WALK(tf->docexpr))
2669
0
          return true;
2670
0
        if (WALK(tf->rowexpr))
2671
0
          return true;
2672
0
        if (WALK(tf->colexprs))
2673
0
          return true;
2674
0
        if (WALK(tf->coldefexprs))
2675
0
          return true;
2676
0
        if (WALK(tf->colvalexprs))
2677
0
          return true;
2678
0
        if (WALK(tf->passingvalexprs))
2679
0
          return true;
2680
0
      }
2681
0
      break;
2682
0
    default:
2683
0
      elog(ERROR, "unrecognized node type: %d",
2684
0
         (int) nodeTag(node));
2685
0
      break;
2686
0
  }
2687
0
  return false;
2688
2689
  /* The WALK() macro can be re-used below, but LIST_WALK() not so much */
2690
0
#undef LIST_WALK
2691
0
}
2692
2693
/*
2694
 * query_tree_walker --- initiate a walk of a Query's expressions
2695
 *
2696
 * This routine exists just to reduce the number of places that need to know
2697
 * where all the expression subtrees of a Query are.  Note it can be used
2698
 * for starting a walk at top level of a Query regardless of whether the
2699
 * walker intends to descend into subqueries.  It is also useful for
2700
 * descending into subqueries within a walker.
2701
 *
2702
 * Some callers want to suppress visitation of certain items in the sub-Query,
2703
 * typically because they need to process them specially, or don't actually
2704
 * want to recurse into subqueries.  This is supported by the flags argument,
2705
 * which is the bitwise OR of flag values to add or suppress visitation of
2706
 * indicated items.  (More flag bits may be added as needed.)
2707
 */
2708
pg_attribute_no_sanitize_function()
2709
bool
2710
query_tree_walker_impl(Query *query,
2711
             tree_walker_callback walker,
2712
             void *context,
2713
             int flags)
2714
0
{
2715
0
  Assert(query != NULL && IsA(query, Query));
2716
2717
  /*
2718
   * We don't walk any utilityStmt here. However, we can't easily assert
2719
   * that it is absent, since there are at least two code paths by which
2720
   * action statements from CREATE RULE end up here, and NOTIFY is allowed
2721
   * in a rule action.
2722
   */
2723
2724
0
  if (WALK(query->targetList))
2725
0
    return true;
2726
0
  if (WALK(query->withCheckOptions))
2727
0
    return true;
2728
0
  if (WALK(query->onConflict))
2729
0
    return true;
2730
0
  if (WALK(query->mergeActionList))
2731
0
    return true;
2732
0
  if (WALK(query->mergeJoinCondition))
2733
0
    return true;
2734
0
  if (WALK(query->returningList))
2735
0
    return true;
2736
0
  if (WALK(query->jointree))
2737
0
    return true;
2738
0
  if (WALK(query->setOperations))
2739
0
    return true;
2740
0
  if (WALK(query->havingQual))
2741
0
    return true;
2742
0
  if (WALK(query->limitOffset))
2743
0
    return true;
2744
0
  if (WALK(query->limitCount))
2745
0
    return true;
2746
2747
  /*
2748
   * Most callers aren't interested in SortGroupClause nodes since those
2749
   * don't contain actual expressions. However they do contain OIDs which
2750
   * may be needed by dependency walkers etc.
2751
   */
2752
0
  if ((flags & QTW_EXAMINE_SORTGROUP))
2753
0
  {
2754
0
    if (WALK(query->groupClause))
2755
0
      return true;
2756
0
    if (WALK(query->windowClause))
2757
0
      return true;
2758
0
    if (WALK(query->sortClause))
2759
0
      return true;
2760
0
    if (WALK(query->distinctClause))
2761
0
      return true;
2762
0
  }
2763
0
  else
2764
0
  {
2765
    /*
2766
     * But we need to walk the expressions under WindowClause nodes even
2767
     * if we're not interested in SortGroupClause nodes.
2768
     */
2769
0
    ListCell   *lc;
2770
2771
0
    foreach(lc, query->windowClause)
2772
0
    {
2773
0
      WindowClause *wc = lfirst_node(WindowClause, lc);
2774
2775
0
      if (WALK(wc->startOffset))
2776
0
        return true;
2777
0
      if (WALK(wc->endOffset))
2778
0
        return true;
2779
0
    }
2780
0
  }
2781
2782
  /*
2783
   * groupingSets and rowMarks are not walked:
2784
   *
2785
   * groupingSets contain only ressortgrouprefs (integers) which are
2786
   * meaningless without the corresponding groupClause or tlist.
2787
   * Accordingly, any walker that needs to care about them needs to handle
2788
   * them itself in its Query processing.
2789
   *
2790
   * rowMarks is not walked because it contains only rangetable indexes (and
2791
   * flags etc.) and therefore should be handled at Query level similarly.
2792
   */
2793
2794
0
  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2795
0
  {
2796
0
    if (WALK(query->cteList))
2797
0
      return true;
2798
0
  }
2799
0
  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2800
0
  {
2801
0
    if (range_table_walker(query->rtable, walker, context, flags))
2802
0
      return true;
2803
0
  }
2804
0
  return false;
2805
0
}
2806
2807
/*
2808
 * range_table_walker is just the part of query_tree_walker that scans
2809
 * a query's rangetable.  This is split out since it can be useful on
2810
 * its own.
2811
 */
2812
bool
2813
range_table_walker_impl(List *rtable,
2814
            tree_walker_callback walker,
2815
            void *context,
2816
            int flags)
2817
0
{
2818
0
  ListCell   *rt;
2819
2820
0
  foreach(rt, rtable)
2821
0
  {
2822
0
    RangeTblEntry *rte = lfirst_node(RangeTblEntry, rt);
2823
2824
0
    if (range_table_entry_walker(rte, walker, context, flags))
2825
0
      return true;
2826
0
  }
2827
0
  return false;
2828
0
}
2829
2830
/*
2831
 * Some callers even want to scan the expressions in individual RTEs.
2832
 */
2833
pg_attribute_no_sanitize_function()
2834
bool
2835
range_table_entry_walker_impl(RangeTblEntry *rte,
2836
                tree_walker_callback walker,
2837
                void *context,
2838
                int flags)
2839
0
{
2840
  /*
2841
   * Walkers might need to examine the RTE node itself either before or
2842
   * after visiting its contents (or, conceivably, both).  Note that if you
2843
   * specify neither flag, the walker won't be called on the RTE at all.
2844
   */
2845
0
  if (flags & QTW_EXAMINE_RTES_BEFORE)
2846
0
    if (WALK(rte))
2847
0
      return true;
2848
2849
0
  switch (rte->rtekind)
2850
0
  {
2851
0
    case RTE_RELATION:
2852
0
      if (WALK(rte->tablesample))
2853
0
        return true;
2854
0
      break;
2855
0
    case RTE_SUBQUERY:
2856
0
      if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2857
0
        if (WALK(rte->subquery))
2858
0
          return true;
2859
0
      break;
2860
0
    case RTE_JOIN:
2861
0
      if (!(flags & QTW_IGNORE_JOINALIASES))
2862
0
        if (WALK(rte->joinaliasvars))
2863
0
          return true;
2864
0
      break;
2865
0
    case RTE_FUNCTION:
2866
0
      if (WALK(rte->functions))
2867
0
        return true;
2868
0
      break;
2869
0
    case RTE_TABLEFUNC:
2870
0
      if (WALK(rte->tablefunc))
2871
0
        return true;
2872
0
      break;
2873
0
    case RTE_VALUES:
2874
0
      if (WALK(rte->values_lists))
2875
0
        return true;
2876
0
      break;
2877
0
    case RTE_CTE:
2878
0
    case RTE_NAMEDTUPLESTORE:
2879
0
    case RTE_RESULT:
2880
      /* nothing to do */
2881
0
      break;
2882
0
    case RTE_GROUP:
2883
0
      if (!(flags & QTW_IGNORE_GROUPEXPRS))
2884
0
        if (WALK(rte->groupexprs))
2885
0
          return true;
2886
0
      break;
2887
0
  }
2888
2889
0
  if (WALK(rte->securityQuals))
2890
0
    return true;
2891
2892
0
  if (flags & QTW_EXAMINE_RTES_AFTER)
2893
0
    if (WALK(rte))
2894
0
      return true;
2895
2896
0
  return false;
2897
0
}
2898
2899
2900
/*
2901
 * expression_tree_mutator() is designed to support routines that make a
2902
 * modified copy of an expression tree, with some nodes being added,
2903
 * removed, or replaced by new subtrees.  The original tree is (normally)
2904
 * not changed.  Each recursion level is responsible for returning a copy of
2905
 * (or appropriately modified substitute for) the subtree it is handed.
2906
 * A mutator routine should look like this:
2907
 *
2908
 * Node * my_mutator (Node *node, my_struct *context)
2909
 * {
2910
 *    if (node == NULL)
2911
 *      return NULL;
2912
 *    // check for nodes that special work is required for, eg:
2913
 *    if (IsA(node, Var))
2914
 *    {
2915
 *      ... create and return modified copy of Var node
2916
 *    }
2917
 *    else if (IsA(node, ...))
2918
 *    {
2919
 *      ... do special transformations of other node types
2920
 *    }
2921
 *    // for any node type not specially processed, do:
2922
 *    return expression_tree_mutator(node, my_mutator, context);
2923
 * }
2924
 *
2925
 * The "context" argument points to a struct that holds whatever context
2926
 * information the mutator routine needs --- it can be used to return extra
2927
 * data gathered by the mutator, too.  This argument is not touched by
2928
 * expression_tree_mutator, but it is passed down to recursive sub-invocations
2929
 * of my_mutator.  The tree walk is started from a setup routine that
2930
 * fills in the appropriate context struct, calls my_mutator with the
2931
 * top-level node of the tree, and does any required post-processing.
2932
 *
2933
 * Each level of recursion must return an appropriately modified Node.
2934
 * If expression_tree_mutator() is called, it will make an exact copy
2935
 * of the given Node, but invoke my_mutator() to copy the sub-node(s)
2936
 * of that Node.  In this way, my_mutator() has full control over the
2937
 * copying process but need not directly deal with expression trees
2938
 * that it has no interest in.
2939
 *
2940
 * Just as for expression_tree_walker, the node types handled by
2941
 * expression_tree_mutator include all those normally found in target lists
2942
 * and qualifier clauses during the planning stage.
2943
 *
2944
 * expression_tree_mutator will handle SubLink nodes by recursing normally
2945
 * into the "testexpr" subtree (which is an expression belonging to the outer
2946
 * plan).  It will also call the mutator on the sub-Query node; however, when
2947
 * expression_tree_mutator itself is called on a Query node, it does nothing
2948
 * and returns the unmodified Query node.  The net effect is that unless the
2949
 * mutator does something special at a Query node, sub-selects will not be
2950
 * visited or modified; the original sub-select will be linked to by the new
2951
 * SubLink node.  Mutators that want to descend into sub-selects will usually
2952
 * do so by recognizing Query nodes and calling query_tree_mutator (below).
2953
 *
2954
 * expression_tree_mutator will handle a SubPlan node by recursing into the
2955
 * "testexpr" and the "args" list (which belong to the outer plan), but it
2956
 * will simply copy the link to the inner plan, since that's typically what
2957
 * expression tree mutators want.  A mutator that wants to modify the subplan
2958
 * can force appropriate behavior by recognizing SubPlan expression nodes
2959
 * and doing the right thing.
2960
 */
2961
2962
pg_attribute_no_sanitize_function()
2963
Node *
2964
expression_tree_mutator_impl(Node *node,
2965
               tree_mutator_callback mutator,
2966
               void *context)
2967
0
{
2968
  /*
2969
   * The mutator has already decided not to modify the current node, but we
2970
   * must call the mutator for any sub-nodes.
2971
   */
2972
2973
0
#define FLATCOPY(newnode, node, nodetype)  \
2974
0
  ( (newnode) = palloc_object(nodetype), \
2975
0
    memcpy((newnode), (node), sizeof(nodetype)) )
2976
2977
0
#define MUTATE(newfield, oldfield, fieldtype)  \
2978
0
    ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2979
2980
0
  if (node == NULL)
2981
0
    return NULL;
2982
2983
  /* Guard against stack overflow due to overly complex expressions */
2984
0
  check_stack_depth();
2985
2986
0
  switch (nodeTag(node))
2987
0
  {
2988
      /*
2989
       * Primitive node types with no expression subnodes.  Var and
2990
       * Const are frequent enough to deserve special cases, the others
2991
       * we just use copyObject for.
2992
       */
2993
0
    case T_Var:
2994
0
      {
2995
0
        Var      *var = (Var *) node;
2996
0
        Var      *newnode;
2997
2998
0
        FLATCOPY(newnode, var, Var);
2999
        /* Assume we need not copy the varnullingrels bitmapset */
3000
0
        return (Node *) newnode;
3001
0
      }
3002
0
      break;
3003
0
    case T_Const:
3004
0
      {
3005
0
        Const    *oldnode = (Const *) node;
3006
0
        Const    *newnode;
3007
3008
0
        FLATCOPY(newnode, oldnode, Const);
3009
        /* XXX we don't bother with datumCopy; should we? */
3010
0
        return (Node *) newnode;
3011
0
      }
3012
0
      break;
3013
0
    case T_Param:
3014
0
    case T_CaseTestExpr:
3015
0
    case T_SQLValueFunction:
3016
0
    case T_JsonFormat:
3017
0
    case T_CoerceToDomainValue:
3018
0
    case T_SetToDefault:
3019
0
    case T_CurrentOfExpr:
3020
0
    case T_NextValueExpr:
3021
0
    case T_RangeTblRef:
3022
0
    case T_SortGroupClause:
3023
0
    case T_CTESearchClause:
3024
0
    case T_MergeSupportFunc:
3025
0
      return copyObject(node);
3026
0
    case T_WithCheckOption:
3027
0
      {
3028
0
        WithCheckOption *wco = (WithCheckOption *) node;
3029
0
        WithCheckOption *newnode;
3030
3031
0
        FLATCOPY(newnode, wco, WithCheckOption);
3032
0
        MUTATE(newnode->qual, wco->qual, Node *);
3033
0
        return (Node *) newnode;
3034
0
      }
3035
0
    case T_Aggref:
3036
0
      {
3037
0
        Aggref     *aggref = (Aggref *) node;
3038
0
        Aggref     *newnode;
3039
3040
0
        FLATCOPY(newnode, aggref, Aggref);
3041
        /* assume mutation doesn't change types of arguments */
3042
0
        newnode->aggargtypes = list_copy(aggref->aggargtypes);
3043
0
        MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
3044
0
        MUTATE(newnode->args, aggref->args, List *);
3045
0
        MUTATE(newnode->aggorder, aggref->aggorder, List *);
3046
0
        MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
3047
0
        MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
3048
0
        return (Node *) newnode;
3049
0
      }
3050
0
      break;
3051
0
    case T_GroupingFunc:
3052
0
      {
3053
0
        GroupingFunc *grouping = (GroupingFunc *) node;
3054
0
        GroupingFunc *newnode;
3055
3056
0
        FLATCOPY(newnode, grouping, GroupingFunc);
3057
0
        MUTATE(newnode->args, grouping->args, List *);
3058
3059
        /*
3060
         * We assume here that mutating the arguments does not change
3061
         * the semantics, i.e. that the arguments are not mutated in a
3062
         * way that makes them semantically different from their
3063
         * previously matching expressions in the GROUP BY clause.
3064
         *
3065
         * If a mutator somehow wanted to do this, it would have to
3066
         * handle the refs and cols lists itself as appropriate.
3067
         */
3068
0
        newnode->refs = list_copy(grouping->refs);
3069
0
        newnode->cols = list_copy(grouping->cols);
3070
3071
0
        return (Node *) newnode;
3072
0
      }
3073
0
      break;
3074
0
    case T_WindowFunc:
3075
0
      {
3076
0
        WindowFunc *wfunc = (WindowFunc *) node;
3077
0
        WindowFunc *newnode;
3078
3079
0
        FLATCOPY(newnode, wfunc, WindowFunc);
3080
0
        MUTATE(newnode->args, wfunc->args, List *);
3081
0
        MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
3082
0
        return (Node *) newnode;
3083
0
      }
3084
0
      break;
3085
0
    case T_WindowFuncRunCondition:
3086
0
      {
3087
0
        WindowFuncRunCondition *wfuncrc = (WindowFuncRunCondition *) node;
3088
0
        WindowFuncRunCondition *newnode;
3089
3090
0
        FLATCOPY(newnode, wfuncrc, WindowFuncRunCondition);
3091
0
        MUTATE(newnode->arg, wfuncrc->arg, Expr *);
3092
0
        return (Node *) newnode;
3093
0
      }
3094
0
      break;
3095
0
    case T_SubscriptingRef:
3096
0
      {
3097
0
        SubscriptingRef *sbsref = (SubscriptingRef *) node;
3098
0
        SubscriptingRef *newnode;
3099
3100
0
        FLATCOPY(newnode, sbsref, SubscriptingRef);
3101
0
        MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
3102
0
             List *);
3103
0
        MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
3104
0
             List *);
3105
0
        MUTATE(newnode->refexpr, sbsref->refexpr,
3106
0
             Expr *);
3107
0
        MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
3108
0
             Expr *);
3109
3110
0
        return (Node *) newnode;
3111
0
      }
3112
0
      break;
3113
0
    case T_FuncExpr:
3114
0
      {
3115
0
        FuncExpr   *expr = (FuncExpr *) node;
3116
0
        FuncExpr   *newnode;
3117
3118
0
        FLATCOPY(newnode, expr, FuncExpr);
3119
0
        MUTATE(newnode->args, expr->args, List *);
3120
0
        return (Node *) newnode;
3121
0
      }
3122
0
      break;
3123
0
    case T_NamedArgExpr:
3124
0
      {
3125
0
        NamedArgExpr *nexpr = (NamedArgExpr *) node;
3126
0
        NamedArgExpr *newnode;
3127
3128
0
        FLATCOPY(newnode, nexpr, NamedArgExpr);
3129
0
        MUTATE(newnode->arg, nexpr->arg, Expr *);
3130
0
        return (Node *) newnode;
3131
0
      }
3132
0
      break;
3133
0
    case T_OpExpr:
3134
0
      {
3135
0
        OpExpr     *expr = (OpExpr *) node;
3136
0
        OpExpr     *newnode;
3137
3138
0
        FLATCOPY(newnode, expr, OpExpr);
3139
0
        MUTATE(newnode->args, expr->args, List *);
3140
0
        return (Node *) newnode;
3141
0
      }
3142
0
      break;
3143
0
    case T_DistinctExpr:
3144
0
      {
3145
0
        DistinctExpr *expr = (DistinctExpr *) node;
3146
0
        DistinctExpr *newnode;
3147
3148
0
        FLATCOPY(newnode, expr, DistinctExpr);
3149
0
        MUTATE(newnode->args, expr->args, List *);
3150
0
        return (Node *) newnode;
3151
0
      }
3152
0
      break;
3153
0
    case T_NullIfExpr:
3154
0
      {
3155
0
        NullIfExpr *expr = (NullIfExpr *) node;
3156
0
        NullIfExpr *newnode;
3157
3158
0
        FLATCOPY(newnode, expr, NullIfExpr);
3159
0
        MUTATE(newnode->args, expr->args, List *);
3160
0
        return (Node *) newnode;
3161
0
      }
3162
0
      break;
3163
0
    case T_ScalarArrayOpExpr:
3164
0
      {
3165
0
        ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
3166
0
        ScalarArrayOpExpr *newnode;
3167
3168
0
        FLATCOPY(newnode, expr, ScalarArrayOpExpr);
3169
0
        MUTATE(newnode->args, expr->args, List *);
3170
0
        return (Node *) newnode;
3171
0
      }
3172
0
      break;
3173
0
    case T_BoolExpr:
3174
0
      {
3175
0
        BoolExpr   *expr = (BoolExpr *) node;
3176
0
        BoolExpr   *newnode;
3177
3178
0
        FLATCOPY(newnode, expr, BoolExpr);
3179
0
        MUTATE(newnode->args, expr->args, List *);
3180
0
        return (Node *) newnode;
3181
0
      }
3182
0
      break;
3183
0
    case T_SubLink:
3184
0
      {
3185
0
        SubLink    *sublink = (SubLink *) node;
3186
0
        SubLink    *newnode;
3187
3188
0
        FLATCOPY(newnode, sublink, SubLink);
3189
0
        MUTATE(newnode->testexpr, sublink->testexpr, Node *);
3190
3191
        /*
3192
         * Also invoke the mutator on the sublink's Query node, so it
3193
         * can recurse into the sub-query if it wants to.
3194
         */
3195
0
        MUTATE(newnode->subselect, sublink->subselect, Node *);
3196
0
        return (Node *) newnode;
3197
0
      }
3198
0
      break;
3199
0
    case T_SubPlan:
3200
0
      {
3201
0
        SubPlan    *subplan = (SubPlan *) node;
3202
0
        SubPlan    *newnode;
3203
3204
0
        FLATCOPY(newnode, subplan, SubPlan);
3205
        /* transform testexpr */
3206
0
        MUTATE(newnode->testexpr, subplan->testexpr, Node *);
3207
        /* transform args list (params to be passed to subplan) */
3208
0
        MUTATE(newnode->args, subplan->args, List *);
3209
        /* but not the sub-Plan itself, which is referenced as-is */
3210
0
        return (Node *) newnode;
3211
0
      }
3212
0
      break;
3213
0
    case T_AlternativeSubPlan:
3214
0
      {
3215
0
        AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
3216
0
        AlternativeSubPlan *newnode;
3217
3218
0
        FLATCOPY(newnode, asplan, AlternativeSubPlan);
3219
0
        MUTATE(newnode->subplans, asplan->subplans, List *);
3220
0
        return (Node *) newnode;
3221
0
      }
3222
0
      break;
3223
0
    case T_FieldSelect:
3224
0
      {
3225
0
        FieldSelect *fselect = (FieldSelect *) node;
3226
0
        FieldSelect *newnode;
3227
3228
0
        FLATCOPY(newnode, fselect, FieldSelect);
3229
0
        MUTATE(newnode->arg, fselect->arg, Expr *);
3230
0
        return (Node *) newnode;
3231
0
      }
3232
0
      break;
3233
0
    case T_FieldStore:
3234
0
      {
3235
0
        FieldStore *fstore = (FieldStore *) node;
3236
0
        FieldStore *newnode;
3237
3238
0
        FLATCOPY(newnode, fstore, FieldStore);
3239
0
        MUTATE(newnode->arg, fstore->arg, Expr *);
3240
0
        MUTATE(newnode->newvals, fstore->newvals, List *);
3241
0
        newnode->fieldnums = list_copy(fstore->fieldnums);
3242
0
        return (Node *) newnode;
3243
0
      }
3244
0
      break;
3245
0
    case T_RelabelType:
3246
0
      {
3247
0
        RelabelType *relabel = (RelabelType *) node;
3248
0
        RelabelType *newnode;
3249
3250
0
        FLATCOPY(newnode, relabel, RelabelType);
3251
0
        MUTATE(newnode->arg, relabel->arg, Expr *);
3252
0
        return (Node *) newnode;
3253
0
      }
3254
0
      break;
3255
0
    case T_CoerceViaIO:
3256
0
      {
3257
0
        CoerceViaIO *iocoerce = (CoerceViaIO *) node;
3258
0
        CoerceViaIO *newnode;
3259
3260
0
        FLATCOPY(newnode, iocoerce, CoerceViaIO);
3261
0
        MUTATE(newnode->arg, iocoerce->arg, Expr *);
3262
0
        return (Node *) newnode;
3263
0
      }
3264
0
      break;
3265
0
    case T_ArrayCoerceExpr:
3266
0
      {
3267
0
        ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
3268
0
        ArrayCoerceExpr *newnode;
3269
3270
0
        FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
3271
0
        MUTATE(newnode->arg, acoerce->arg, Expr *);
3272
0
        MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
3273
0
        return (Node *) newnode;
3274
0
      }
3275
0
      break;
3276
0
    case T_ConvertRowtypeExpr:
3277
0
      {
3278
0
        ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
3279
0
        ConvertRowtypeExpr *newnode;
3280
3281
0
        FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
3282
0
        MUTATE(newnode->arg, convexpr->arg, Expr *);
3283
0
        return (Node *) newnode;
3284
0
      }
3285
0
      break;
3286
0
    case T_CollateExpr:
3287
0
      {
3288
0
        CollateExpr *collate = (CollateExpr *) node;
3289
0
        CollateExpr *newnode;
3290
3291
0
        FLATCOPY(newnode, collate, CollateExpr);
3292
0
        MUTATE(newnode->arg, collate->arg, Expr *);
3293
0
        return (Node *) newnode;
3294
0
      }
3295
0
      break;
3296
0
    case T_CaseExpr:
3297
0
      {
3298
0
        CaseExpr   *caseexpr = (CaseExpr *) node;
3299
0
        CaseExpr   *newnode;
3300
3301
0
        FLATCOPY(newnode, caseexpr, CaseExpr);
3302
0
        MUTATE(newnode->arg, caseexpr->arg, Expr *);
3303
0
        MUTATE(newnode->args, caseexpr->args, List *);
3304
0
        MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
3305
0
        return (Node *) newnode;
3306
0
      }
3307
0
      break;
3308
0
    case T_CaseWhen:
3309
0
      {
3310
0
        CaseWhen   *casewhen = (CaseWhen *) node;
3311
0
        CaseWhen   *newnode;
3312
3313
0
        FLATCOPY(newnode, casewhen, CaseWhen);
3314
0
        MUTATE(newnode->expr, casewhen->expr, Expr *);
3315
0
        MUTATE(newnode->result, casewhen->result, Expr *);
3316
0
        return (Node *) newnode;
3317
0
      }
3318
0
      break;
3319
0
    case T_ArrayExpr:
3320
0
      {
3321
0
        ArrayExpr  *arrayexpr = (ArrayExpr *) node;
3322
0
        ArrayExpr  *newnode;
3323
3324
0
        FLATCOPY(newnode, arrayexpr, ArrayExpr);
3325
0
        MUTATE(newnode->elements, arrayexpr->elements, List *);
3326
0
        return (Node *) newnode;
3327
0
      }
3328
0
      break;
3329
0
    case T_RowExpr:
3330
0
      {
3331
0
        RowExpr    *rowexpr = (RowExpr *) node;
3332
0
        RowExpr    *newnode;
3333
3334
0
        FLATCOPY(newnode, rowexpr, RowExpr);
3335
0
        MUTATE(newnode->args, rowexpr->args, List *);
3336
        /* Assume colnames needn't be duplicated */
3337
0
        return (Node *) newnode;
3338
0
      }
3339
0
      break;
3340
0
    case T_RowCompareExpr:
3341
0
      {
3342
0
        RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3343
0
        RowCompareExpr *newnode;
3344
3345
0
        FLATCOPY(newnode, rcexpr, RowCompareExpr);
3346
0
        MUTATE(newnode->largs, rcexpr->largs, List *);
3347
0
        MUTATE(newnode->rargs, rcexpr->rargs, List *);
3348
0
        return (Node *) newnode;
3349
0
      }
3350
0
      break;
3351
0
    case T_CoalesceExpr:
3352
0
      {
3353
0
        CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3354
0
        CoalesceExpr *newnode;
3355
3356
0
        FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
3357
0
        MUTATE(newnode->args, coalesceexpr->args, List *);
3358
0
        return (Node *) newnode;
3359
0
      }
3360
0
      break;
3361
0
    case T_MinMaxExpr:
3362
0
      {
3363
0
        MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
3364
0
        MinMaxExpr *newnode;
3365
3366
0
        FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
3367
0
        MUTATE(newnode->args, minmaxexpr->args, List *);
3368
0
        return (Node *) newnode;
3369
0
      }
3370
0
      break;
3371
0
    case T_XmlExpr:
3372
0
      {
3373
0
        XmlExpr    *xexpr = (XmlExpr *) node;
3374
0
        XmlExpr    *newnode;
3375
3376
0
        FLATCOPY(newnode, xexpr, XmlExpr);
3377
0
        MUTATE(newnode->named_args, xexpr->named_args, List *);
3378
        /* assume mutator does not care about arg_names */
3379
0
        MUTATE(newnode->args, xexpr->args, List *);
3380
0
        return (Node *) newnode;
3381
0
      }
3382
0
      break;
3383
0
    case T_JsonReturning:
3384
0
      {
3385
0
        JsonReturning *jr = (JsonReturning *) node;
3386
0
        JsonReturning *newnode;
3387
3388
0
        FLATCOPY(newnode, jr, JsonReturning);
3389
0
        MUTATE(newnode->format, jr->format, JsonFormat *);
3390
3391
0
        return (Node *) newnode;
3392
0
      }
3393
0
    case T_JsonValueExpr:
3394
0
      {
3395
0
        JsonValueExpr *jve = (JsonValueExpr *) node;
3396
0
        JsonValueExpr *newnode;
3397
3398
0
        FLATCOPY(newnode, jve, JsonValueExpr);
3399
0
        MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3400
0
        MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
3401
0
        MUTATE(newnode->format, jve->format, JsonFormat *);
3402
3403
0
        return (Node *) newnode;
3404
0
      }
3405
0
    case T_JsonConstructorExpr:
3406
0
      {
3407
0
        JsonConstructorExpr *jce = (JsonConstructorExpr *) node;
3408
0
        JsonConstructorExpr *newnode;
3409
3410
0
        FLATCOPY(newnode, jce, JsonConstructorExpr);
3411
0
        MUTATE(newnode->args, jce->args, List *);
3412
0
        MUTATE(newnode->func, jce->func, Expr *);
3413
0
        MUTATE(newnode->coercion, jce->coercion, Expr *);
3414
0
        MUTATE(newnode->returning, jce->returning, JsonReturning *);
3415
3416
0
        return (Node *) newnode;
3417
0
      }
3418
0
    case T_JsonIsPredicate:
3419
0
      {
3420
0
        JsonIsPredicate *pred = (JsonIsPredicate *) node;
3421
0
        JsonIsPredicate *newnode;
3422
3423
0
        FLATCOPY(newnode, pred, JsonIsPredicate);
3424
0
        MUTATE(newnode->expr, pred->expr, Node *);
3425
0
        MUTATE(newnode->format, pred->format, JsonFormat *);
3426
3427
0
        return (Node *) newnode;
3428
0
      }
3429
0
    case T_JsonExpr:
3430
0
      {
3431
0
        JsonExpr   *jexpr = (JsonExpr *) node;
3432
0
        JsonExpr   *newnode;
3433
3434
0
        FLATCOPY(newnode, jexpr, JsonExpr);
3435
0
        MUTATE(newnode->formatted_expr, jexpr->formatted_expr, Node *);
3436
0
        MUTATE(newnode->path_spec, jexpr->path_spec, Node *);
3437
0
        MUTATE(newnode->passing_values, jexpr->passing_values, List *);
3438
        /* assume mutator does not care about passing_names */
3439
0
        MUTATE(newnode->on_empty, jexpr->on_empty, JsonBehavior *);
3440
0
        MUTATE(newnode->on_error, jexpr->on_error, JsonBehavior *);
3441
0
        return (Node *) newnode;
3442
0
      }
3443
0
      break;
3444
0
    case T_JsonBehavior:
3445
0
      {
3446
0
        JsonBehavior *behavior = (JsonBehavior *) node;
3447
0
        JsonBehavior *newnode;
3448
3449
0
        FLATCOPY(newnode, behavior, JsonBehavior);
3450
0
        MUTATE(newnode->expr, behavior->expr, Node *);
3451
0
        return (Node *) newnode;
3452
0
      }
3453
0
      break;
3454
0
    case T_NullTest:
3455
0
      {
3456
0
        NullTest   *ntest = (NullTest *) node;
3457
0
        NullTest   *newnode;
3458
3459
0
        FLATCOPY(newnode, ntest, NullTest);
3460
0
        MUTATE(newnode->arg, ntest->arg, Expr *);
3461
0
        return (Node *) newnode;
3462
0
      }
3463
0
      break;
3464
0
    case T_BooleanTest:
3465
0
      {
3466
0
        BooleanTest *btest = (BooleanTest *) node;
3467
0
        BooleanTest *newnode;
3468
3469
0
        FLATCOPY(newnode, btest, BooleanTest);
3470
0
        MUTATE(newnode->arg, btest->arg, Expr *);
3471
0
        return (Node *) newnode;
3472
0
      }
3473
0
      break;
3474
0
    case T_CoerceToDomain:
3475
0
      {
3476
0
        CoerceToDomain *ctest = (CoerceToDomain *) node;
3477
0
        CoerceToDomain *newnode;
3478
3479
0
        FLATCOPY(newnode, ctest, CoerceToDomain);
3480
0
        MUTATE(newnode->arg, ctest->arg, Expr *);
3481
0
        return (Node *) newnode;
3482
0
      }
3483
0
      break;
3484
0
    case T_ReturningExpr:
3485
0
      {
3486
0
        ReturningExpr *rexpr = (ReturningExpr *) node;
3487
0
        ReturningExpr *newnode;
3488
3489
0
        FLATCOPY(newnode, rexpr, ReturningExpr);
3490
0
        MUTATE(newnode->retexpr, rexpr->retexpr, Expr *);
3491
0
        return (Node *) newnode;
3492
0
      }
3493
0
      break;
3494
0
    case T_TargetEntry:
3495
0
      {
3496
0
        TargetEntry *targetentry = (TargetEntry *) node;
3497
0
        TargetEntry *newnode;
3498
3499
0
        FLATCOPY(newnode, targetentry, TargetEntry);
3500
0
        MUTATE(newnode->expr, targetentry->expr, Expr *);
3501
0
        return (Node *) newnode;
3502
0
      }
3503
0
      break;
3504
0
    case T_Query:
3505
      /* Do nothing with a sub-Query, per discussion above */
3506
0
      return node;
3507
0
    case T_WindowClause:
3508
0
      {
3509
0
        WindowClause *wc = (WindowClause *) node;
3510
0
        WindowClause *newnode;
3511
3512
0
        FLATCOPY(newnode, wc, WindowClause);
3513
0
        MUTATE(newnode->partitionClause, wc->partitionClause, List *);
3514
0
        MUTATE(newnode->orderClause, wc->orderClause, List *);
3515
0
        MUTATE(newnode->startOffset, wc->startOffset, Node *);
3516
0
        MUTATE(newnode->endOffset, wc->endOffset, Node *);
3517
0
        return (Node *) newnode;
3518
0
      }
3519
0
      break;
3520
0
    case T_CTECycleClause:
3521
0
      {
3522
0
        CTECycleClause *cc = (CTECycleClause *) node;
3523
0
        CTECycleClause *newnode;
3524
3525
0
        FLATCOPY(newnode, cc, CTECycleClause);
3526
0
        MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
3527
0
        MUTATE(newnode->cycle_mark_default, cc->cycle_mark_default, Node *);
3528
0
        return (Node *) newnode;
3529
0
      }
3530
0
      break;
3531
0
    case T_CommonTableExpr:
3532
0
      {
3533
0
        CommonTableExpr *cte = (CommonTableExpr *) node;
3534
0
        CommonTableExpr *newnode;
3535
3536
0
        FLATCOPY(newnode, cte, CommonTableExpr);
3537
3538
        /*
3539
         * Also invoke the mutator on the CTE's Query node, so it can
3540
         * recurse into the sub-query if it wants to.
3541
         */
3542
0
        MUTATE(newnode->ctequery, cte->ctequery, Node *);
3543
3544
0
        MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *);
3545
0
        MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
3546
3547
0
        return (Node *) newnode;
3548
0
      }
3549
0
      break;
3550
0
    case T_PartitionBoundSpec:
3551
0
      {
3552
0
        PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
3553
0
        PartitionBoundSpec *newnode;
3554
3555
0
        FLATCOPY(newnode, pbs, PartitionBoundSpec);
3556
0
        MUTATE(newnode->listdatums, pbs->listdatums, List *);
3557
0
        MUTATE(newnode->lowerdatums, pbs->lowerdatums, List *);
3558
0
        MUTATE(newnode->upperdatums, pbs->upperdatums, List *);
3559
0
        return (Node *) newnode;
3560
0
      }
3561
0
      break;
3562
0
    case T_PartitionRangeDatum:
3563
0
      {
3564
0
        PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
3565
0
        PartitionRangeDatum *newnode;
3566
3567
0
        FLATCOPY(newnode, prd, PartitionRangeDatum);
3568
0
        MUTATE(newnode->value, prd->value, Node *);
3569
0
        return (Node *) newnode;
3570
0
      }
3571
0
      break;
3572
0
    case T_List:
3573
0
      {
3574
        /*
3575
         * We assume the mutator isn't interested in the list nodes
3576
         * per se, so just invoke it on each list element. NOTE: this
3577
         * would fail badly on a list with integer elements!
3578
         */
3579
0
        List     *resultlist;
3580
0
        ListCell   *temp;
3581
3582
0
        resultlist = NIL;
3583
0
        foreach(temp, (List *) node)
3584
0
        {
3585
0
          resultlist = lappend(resultlist,
3586
0
                     mutator((Node *) lfirst(temp),
3587
0
                         context));
3588
0
        }
3589
0
        return (Node *) resultlist;
3590
0
      }
3591
0
      break;
3592
0
    case T_FromExpr:
3593
0
      {
3594
0
        FromExpr   *from = (FromExpr *) node;
3595
0
        FromExpr   *newnode;
3596
3597
0
        FLATCOPY(newnode, from, FromExpr);
3598
0
        MUTATE(newnode->fromlist, from->fromlist, List *);
3599
0
        MUTATE(newnode->quals, from->quals, Node *);
3600
0
        return (Node *) newnode;
3601
0
      }
3602
0
      break;
3603
0
    case T_OnConflictExpr:
3604
0
      {
3605
0
        OnConflictExpr *oc = (OnConflictExpr *) node;
3606
0
        OnConflictExpr *newnode;
3607
3608
0
        FLATCOPY(newnode, oc, OnConflictExpr);
3609
0
        MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3610
0
        MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3611
0
        MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3612
0
        MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3613
0
        MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3614
3615
0
        return (Node *) newnode;
3616
0
      }
3617
0
      break;
3618
0
    case T_MergeAction:
3619
0
      {
3620
0
        MergeAction *action = (MergeAction *) node;
3621
0
        MergeAction *newnode;
3622
3623
0
        FLATCOPY(newnode, action, MergeAction);
3624
0
        MUTATE(newnode->qual, action->qual, Node *);
3625
0
        MUTATE(newnode->targetList, action->targetList, List *);
3626
3627
0
        return (Node *) newnode;
3628
0
      }
3629
0
      break;
3630
0
    case T_PartitionPruneStepOp:
3631
0
      {
3632
0
        PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3633
0
        PartitionPruneStepOp *newnode;
3634
3635
0
        FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3636
0
        MUTATE(newnode->exprs, opstep->exprs, List *);
3637
3638
0
        return (Node *) newnode;
3639
0
      }
3640
0
      break;
3641
0
    case T_PartitionPruneStepCombine:
3642
      /* no expression sub-nodes */
3643
0
      return copyObject(node);
3644
0
    case T_JoinExpr:
3645
0
      {
3646
0
        JoinExpr   *join = (JoinExpr *) node;
3647
0
        JoinExpr   *newnode;
3648
3649
0
        FLATCOPY(newnode, join, JoinExpr);
3650
0
        MUTATE(newnode->larg, join->larg, Node *);
3651
0
        MUTATE(newnode->rarg, join->rarg, Node *);
3652
0
        MUTATE(newnode->quals, join->quals, Node *);
3653
        /* We do not mutate alias or using by default */
3654
0
        return (Node *) newnode;
3655
0
      }
3656
0
      break;
3657
0
    case T_SetOperationStmt:
3658
0
      {
3659
0
        SetOperationStmt *setop = (SetOperationStmt *) node;
3660
0
        SetOperationStmt *newnode;
3661
3662
0
        FLATCOPY(newnode, setop, SetOperationStmt);
3663
0
        MUTATE(newnode->larg, setop->larg, Node *);
3664
0
        MUTATE(newnode->rarg, setop->rarg, Node *);
3665
        /* We do not mutate groupClauses by default */
3666
0
        return (Node *) newnode;
3667
0
      }
3668
0
      break;
3669
0
    case T_IndexClause:
3670
0
      {
3671
0
        IndexClause *iclause = (IndexClause *) node;
3672
0
        IndexClause *newnode;
3673
3674
0
        FLATCOPY(newnode, iclause, IndexClause);
3675
0
        MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3676
0
        MUTATE(newnode->indexquals, iclause->indexquals, List *);
3677
0
        return (Node *) newnode;
3678
0
      }
3679
0
      break;
3680
0
    case T_PlaceHolderVar:
3681
0
      {
3682
0
        PlaceHolderVar *phv = (PlaceHolderVar *) node;
3683
0
        PlaceHolderVar *newnode;
3684
3685
0
        FLATCOPY(newnode, phv, PlaceHolderVar);
3686
0
        MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3687
        /* Assume we need not copy the relids bitmapsets */
3688
0
        return (Node *) newnode;
3689
0
      }
3690
0
      break;
3691
0
    case T_InferenceElem:
3692
0
      {
3693
0
        InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3694
0
        InferenceElem *newnode;
3695
3696
0
        FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3697
0
        MUTATE(newnode->expr, newnode->expr, Node *);
3698
0
        return (Node *) newnode;
3699
0
      }
3700
0
      break;
3701
0
    case T_AppendRelInfo:
3702
0
      {
3703
0
        AppendRelInfo *appinfo = (AppendRelInfo *) node;
3704
0
        AppendRelInfo *newnode;
3705
3706
0
        FLATCOPY(newnode, appinfo, AppendRelInfo);
3707
0
        MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3708
        /* Assume nothing need be done with parent_colnos[] */
3709
0
        return (Node *) newnode;
3710
0
      }
3711
0
      break;
3712
0
    case T_PlaceHolderInfo:
3713
0
      {
3714
0
        PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3715
0
        PlaceHolderInfo *newnode;
3716
3717
0
        FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3718
0
        MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3719
        /* Assume we need not copy the relids bitmapsets */
3720
0
        return (Node *) newnode;
3721
0
      }
3722
0
      break;
3723
0
    case T_RangeTblFunction:
3724
0
      {
3725
0
        RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3726
0
        RangeTblFunction *newnode;
3727
3728
0
        FLATCOPY(newnode, rtfunc, RangeTblFunction);
3729
0
        MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3730
        /* Assume we need not copy the coldef info lists */
3731
0
        return (Node *) newnode;
3732
0
      }
3733
0
      break;
3734
0
    case T_TableSampleClause:
3735
0
      {
3736
0
        TableSampleClause *tsc = (TableSampleClause *) node;
3737
0
        TableSampleClause *newnode;
3738
3739
0
        FLATCOPY(newnode, tsc, TableSampleClause);
3740
0
        MUTATE(newnode->args, tsc->args, List *);
3741
0
        MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3742
0
        return (Node *) newnode;
3743
0
      }
3744
0
      break;
3745
0
    case T_TableFunc:
3746
0
      {
3747
0
        TableFunc  *tf = (TableFunc *) node;
3748
0
        TableFunc  *newnode;
3749
3750
0
        FLATCOPY(newnode, tf, TableFunc);
3751
0
        MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3752
0
        MUTATE(newnode->docexpr, tf->docexpr, Node *);
3753
0
        MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3754
0
        MUTATE(newnode->colexprs, tf->colexprs, List *);
3755
0
        MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3756
0
        MUTATE(newnode->colvalexprs, tf->colvalexprs, List *);
3757
0
        MUTATE(newnode->passingvalexprs, tf->passingvalexprs, List *);
3758
0
        return (Node *) newnode;
3759
0
      }
3760
0
      break;
3761
0
    default:
3762
0
      elog(ERROR, "unrecognized node type: %d",
3763
0
         (int) nodeTag(node));
3764
0
      break;
3765
0
  }
3766
  /* can't get here, but keep compiler happy */
3767
0
  return NULL;
3768
0
}
3769
3770
3771
/*
3772
 * query_tree_mutator --- initiate modification of a Query's expressions
3773
 *
3774
 * This routine exists just to reduce the number of places that need to know
3775
 * where all the expression subtrees of a Query are.  Note it can be used
3776
 * for starting a walk at top level of a Query regardless of whether the
3777
 * mutator intends to descend into subqueries.  It is also useful for
3778
 * descending into subqueries within a mutator.
3779
 *
3780
 * Some callers want to suppress mutating of certain items in the Query,
3781
 * typically because they need to process them specially, or don't actually
3782
 * want to recurse into subqueries.  This is supported by the flags argument,
3783
 * which is the bitwise OR of flag values to suppress mutating of
3784
 * indicated items.  (More flag bits may be added as needed.)
3785
 *
3786
 * Normally the top-level Query node itself is copied, but some callers want
3787
 * it to be modified in-place; they must pass QTW_DONT_COPY_QUERY in flags.
3788
 * All modified substructure is safely copied in any case.
3789
 */
3790
pg_attribute_no_sanitize_function()
3791
Query *
3792
query_tree_mutator_impl(Query *query,
3793
            tree_mutator_callback mutator,
3794
            void *context,
3795
            int flags)
3796
0
{
3797
0
  Assert(query != NULL && IsA(query, Query));
3798
3799
0
  if (!(flags & QTW_DONT_COPY_QUERY))
3800
0
  {
3801
0
    Query    *newquery;
3802
3803
0
    FLATCOPY(newquery, query, Query);
3804
0
    query = newquery;
3805
0
  }
3806
3807
0
  MUTATE(query->targetList, query->targetList, List *);
3808
0
  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3809
0
  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3810
0
  MUTATE(query->mergeActionList, query->mergeActionList, List *);
3811
0
  MUTATE(query->mergeJoinCondition, query->mergeJoinCondition, Node *);
3812
0
  MUTATE(query->returningList, query->returningList, List *);
3813
0
  MUTATE(query->jointree, query->jointree, FromExpr *);
3814
0
  MUTATE(query->setOperations, query->setOperations, Node *);
3815
0
  MUTATE(query->havingQual, query->havingQual, Node *);
3816
0
  MUTATE(query->limitOffset, query->limitOffset, Node *);
3817
0
  MUTATE(query->limitCount, query->limitCount, Node *);
3818
3819
  /*
3820
   * Most callers aren't interested in SortGroupClause nodes since those
3821
   * don't contain actual expressions. However they do contain OIDs, which
3822
   * may be of interest to some mutators.
3823
   */
3824
3825
0
  if ((flags & QTW_EXAMINE_SORTGROUP))
3826
0
  {
3827
0
    MUTATE(query->groupClause, query->groupClause, List *);
3828
0
    MUTATE(query->windowClause, query->windowClause, List *);
3829
0
    MUTATE(query->sortClause, query->sortClause, List *);
3830
0
    MUTATE(query->distinctClause, query->distinctClause, List *);
3831
0
  }
3832
0
  else
3833
0
  {
3834
    /*
3835
     * But we need to mutate the expressions under WindowClause nodes even
3836
     * if we're not interested in SortGroupClause nodes.
3837
     */
3838
0
    List     *resultlist;
3839
0
    ListCell   *temp;
3840
3841
0
    resultlist = NIL;
3842
0
    foreach(temp, query->windowClause)
3843
0
    {
3844
0
      WindowClause *wc = lfirst_node(WindowClause, temp);
3845
0
      WindowClause *newnode;
3846
3847
0
      FLATCOPY(newnode, wc, WindowClause);
3848
0
      MUTATE(newnode->startOffset, wc->startOffset, Node *);
3849
0
      MUTATE(newnode->endOffset, wc->endOffset, Node *);
3850
3851
0
      resultlist = lappend(resultlist, (Node *) newnode);
3852
0
    }
3853
0
    query->windowClause = resultlist;
3854
0
  }
3855
3856
  /*
3857
   * groupingSets and rowMarks are not mutated:
3858
   *
3859
   * groupingSets contain only ressortgroup refs (integers) which are
3860
   * meaningless without the groupClause or tlist. Accordingly, any mutator
3861
   * that needs to care about them needs to handle them itself in its Query
3862
   * processing.
3863
   *
3864
   * rowMarks contains only rangetable indexes (and flags etc.) and
3865
   * therefore should be handled at Query level similarly.
3866
   */
3867
3868
0
  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3869
0
    MUTATE(query->cteList, query->cteList, List *);
3870
0
  else            /* else copy CTE list as-is */
3871
0
    query->cteList = copyObject(query->cteList);
3872
0
  query->rtable = range_table_mutator(query->rtable,
3873
0
                    mutator, context, flags);
3874
0
  return query;
3875
0
}
3876
3877
/*
3878
 * range_table_mutator is just the part of query_tree_mutator that processes
3879
 * a query's rangetable.  This is split out since it can be useful on
3880
 * its own.
3881
 */
3882
pg_attribute_no_sanitize_function()
3883
List *
3884
range_table_mutator_impl(List *rtable,
3885
             tree_mutator_callback mutator,
3886
             void *context,
3887
             int flags)
3888
0
{
3889
0
  List     *newrt = NIL;
3890
0
  ListCell   *rt;
3891
3892
0
  foreach(rt, rtable)
3893
0
  {
3894
0
    RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3895
0
    RangeTblEntry *newrte;
3896
3897
0
    FLATCOPY(newrte, rte, RangeTblEntry);
3898
0
    switch (rte->rtekind)
3899
0
    {
3900
0
      case RTE_RELATION:
3901
0
        MUTATE(newrte->tablesample, rte->tablesample,
3902
0
             TableSampleClause *);
3903
        /* we don't bother to copy eref, aliases, etc; OK? */
3904
0
        break;
3905
0
      case RTE_SUBQUERY:
3906
0
        if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3907
0
          MUTATE(newrte->subquery, rte->subquery, Query *);
3908
0
        else
3909
0
        {
3910
          /* else, copy RT subqueries as-is */
3911
0
          newrte->subquery = copyObject(rte->subquery);
3912
0
        }
3913
0
        break;
3914
0
      case RTE_JOIN:
3915
0
        if (!(flags & QTW_IGNORE_JOINALIASES))
3916
0
          MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3917
0
        else
3918
0
        {
3919
          /* else, copy join aliases as-is */
3920
0
          newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3921
0
        }
3922
0
        break;
3923
0
      case RTE_FUNCTION:
3924
0
        MUTATE(newrte->functions, rte->functions, List *);
3925
0
        break;
3926
0
      case RTE_TABLEFUNC:
3927
0
        MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3928
0
        break;
3929
0
      case RTE_VALUES:
3930
0
        MUTATE(newrte->values_lists, rte->values_lists, List *);
3931
0
        break;
3932
0
      case RTE_CTE:
3933
0
      case RTE_NAMEDTUPLESTORE:
3934
0
      case RTE_RESULT:
3935
        /* nothing to do */
3936
0
        break;
3937
0
      case RTE_GROUP:
3938
0
        if (!(flags & QTW_IGNORE_GROUPEXPRS))
3939
0
          MUTATE(newrte->groupexprs, rte->groupexprs, List *);
3940
0
        else
3941
0
        {
3942
          /* else, copy grouping exprs as-is */
3943
0
          newrte->groupexprs = copyObject(rte->groupexprs);
3944
0
        }
3945
0
        break;
3946
0
    }
3947
0
    MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3948
0
    newrt = lappend(newrt, newrte);
3949
0
  }
3950
0
  return newrt;
3951
0
}
3952
3953
/*
3954
 * query_or_expression_tree_walker --- hybrid form
3955
 *
3956
 * This routine will invoke query_tree_walker if called on a Query node,
3957
 * else will invoke the walker directly.  This is a useful way of starting
3958
 * the recursion when the walker's normal change of state is not appropriate
3959
 * for the outermost Query node.
3960
 */
3961
pg_attribute_no_sanitize_function()
3962
bool
3963
query_or_expression_tree_walker_impl(Node *node,
3964
                   tree_walker_callback walker,
3965
                   void *context,
3966
                   int flags)
3967
0
{
3968
0
  if (node && IsA(node, Query))
3969
0
    return query_tree_walker((Query *) node,
3970
0
                 walker,
3971
0
                 context,
3972
0
                 flags);
3973
0
  else
3974
0
    return WALK(node);
3975
0
}
3976
3977
/*
3978
 * query_or_expression_tree_mutator --- hybrid form
3979
 *
3980
 * This routine will invoke query_tree_mutator if called on a Query node,
3981
 * else will invoke the mutator directly.  This is a useful way of starting
3982
 * the recursion when the mutator's normal change of state is not appropriate
3983
 * for the outermost Query node.
3984
 */
3985
pg_attribute_no_sanitize_function()
3986
Node *
3987
query_or_expression_tree_mutator_impl(Node *node,
3988
                    tree_mutator_callback mutator,
3989
                    void *context,
3990
                    int flags)
3991
0
{
3992
0
  if (node && IsA(node, Query))
3993
0
    return (Node *) query_tree_mutator((Query *) node,
3994
0
                       mutator,
3995
0
                       context,
3996
0
                       flags);
3997
0
  else
3998
0
    return mutator(node, context);
3999
0
}
4000
4001
4002
/*
4003
 * raw_expression_tree_walker --- walk raw parse trees
4004
 *
4005
 * This has exactly the same API as expression_tree_walker, but instead of
4006
 * walking post-analysis parse trees, it knows how to walk the node types
4007
 * found in raw grammar output.  (There is not currently any need for a
4008
 * combined walker, so we keep them separate in the name of efficiency.)
4009
 * Unlike expression_tree_walker, there is no special rule about query
4010
 * boundaries: we descend to everything that's possibly interesting.
4011
 *
4012
 * Currently, the node type coverage here extends only to DML statements
4013
 * (SELECT/INSERT/UPDATE/DELETE/MERGE) and nodes that can appear in them,
4014
 * because this is used mainly during analysis of CTEs, and only DML
4015
 * statements can appear in CTEs.
4016
 */
4017
pg_attribute_no_sanitize_function()
4018
bool
4019
raw_expression_tree_walker_impl(Node *node,
4020
                tree_walker_callback walker,
4021
                void *context)
4022
0
{
4023
0
  ListCell   *temp;
4024
4025
  /*
4026
   * The walker has already visited the current node, and so we need only
4027
   * recurse into any sub-nodes it has.
4028
   */
4029
0
  if (node == NULL)
4030
0
    return false;
4031
4032
  /* Guard against stack overflow due to overly complex expressions */
4033
0
  check_stack_depth();
4034
4035
0
  switch (nodeTag(node))
4036
0
  {
4037
0
    case T_JsonFormat:
4038
0
    case T_SetToDefault:
4039
0
    case T_CurrentOfExpr:
4040
0
    case T_SQLValueFunction:
4041
0
    case T_Integer:
4042
0
    case T_Float:
4043
0
    case T_Boolean:
4044
0
    case T_String:
4045
0
    case T_BitString:
4046
0
    case T_ParamRef:
4047
0
    case T_A_Const:
4048
0
    case T_A_Star:
4049
0
    case T_MergeSupportFunc:
4050
0
    case T_ReturningOption:
4051
      /* primitive node types with no subnodes */
4052
0
      break;
4053
0
    case T_Alias:
4054
      /* we assume the colnames list isn't interesting */
4055
0
      break;
4056
0
    case T_RangeVar:
4057
0
      return WALK(((RangeVar *) node)->alias);
4058
0
    case T_GroupingFunc:
4059
0
      return WALK(((GroupingFunc *) node)->args);
4060
0
    case T_SubLink:
4061
0
      {
4062
0
        SubLink    *sublink = (SubLink *) node;
4063
4064
0
        if (WALK(sublink->testexpr))
4065
0
          return true;
4066
        /* we assume the operName is not interesting */
4067
0
        if (WALK(sublink->subselect))
4068
0
          return true;
4069
0
      }
4070
0
      break;
4071
0
    case T_CaseExpr:
4072
0
      {
4073
0
        CaseExpr   *caseexpr = (CaseExpr *) node;
4074
4075
0
        if (WALK(caseexpr->arg))
4076
0
          return true;
4077
        /* we assume walker doesn't care about CaseWhens, either */
4078
0
        foreach(temp, caseexpr->args)
4079
0
        {
4080
0
          CaseWhen   *when = lfirst_node(CaseWhen, temp);
4081
4082
0
          if (WALK(when->expr))
4083
0
            return true;
4084
0
          if (WALK(when->result))
4085
0
            return true;
4086
0
        }
4087
0
        if (WALK(caseexpr->defresult))
4088
0
          return true;
4089
0
      }
4090
0
      break;
4091
0
    case T_RowExpr:
4092
      /* Assume colnames isn't interesting */
4093
0
      return WALK(((RowExpr *) node)->args);
4094
0
    case T_CoalesceExpr:
4095
0
      return WALK(((CoalesceExpr *) node)->args);
4096
0
    case T_MinMaxExpr:
4097
0
      return WALK(((MinMaxExpr *) node)->args);
4098
0
    case T_XmlExpr:
4099
0
      {
4100
0
        XmlExpr    *xexpr = (XmlExpr *) node;
4101
4102
0
        if (WALK(xexpr->named_args))
4103
0
          return true;
4104
        /* we assume walker doesn't care about arg_names */
4105
0
        if (WALK(xexpr->args))
4106
0
          return true;
4107
0
      }
4108
0
      break;
4109
0
    case T_JsonReturning:
4110
0
      return WALK(((JsonReturning *) node)->format);
4111
0
    case T_JsonValueExpr:
4112
0
      {
4113
0
        JsonValueExpr *jve = (JsonValueExpr *) node;
4114
4115
0
        if (WALK(jve->raw_expr))
4116
0
          return true;
4117
0
        if (WALK(jve->formatted_expr))
4118
0
          return true;
4119
0
        if (WALK(jve->format))
4120
0
          return true;
4121
0
      }
4122
0
      break;
4123
0
    case T_JsonParseExpr:
4124
0
      {
4125
0
        JsonParseExpr *jpe = (JsonParseExpr *) node;
4126
4127
0
        if (WALK(jpe->expr))
4128
0
          return true;
4129
0
        if (WALK(jpe->output))
4130
0
          return true;
4131
0
      }
4132
0
      break;
4133
0
    case T_JsonScalarExpr:
4134
0
      {
4135
0
        JsonScalarExpr *jse = (JsonScalarExpr *) node;
4136
4137
0
        if (WALK(jse->expr))
4138
0
          return true;
4139
0
        if (WALK(jse->output))
4140
0
          return true;
4141
0
      }
4142
0
      break;
4143
0
    case T_JsonSerializeExpr:
4144
0
      {
4145
0
        JsonSerializeExpr *jse = (JsonSerializeExpr *) node;
4146
4147
0
        if (WALK(jse->expr))
4148
0
          return true;
4149
0
        if (WALK(jse->output))
4150
0
          return true;
4151
0
      }
4152
0
      break;
4153
0
    case T_JsonConstructorExpr:
4154
0
      {
4155
0
        JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
4156
4157
0
        if (WALK(ctor->args))
4158
0
          return true;
4159
0
        if (WALK(ctor->func))
4160
0
          return true;
4161
0
        if (WALK(ctor->coercion))
4162
0
          return true;
4163
0
        if (WALK(ctor->returning))
4164
0
          return true;
4165
0
      }
4166
0
      break;
4167
0
    case T_JsonIsPredicate:
4168
0
      return WALK(((JsonIsPredicate *) node)->expr);
4169
0
    case T_JsonArgument:
4170
0
      return WALK(((JsonArgument *) node)->val);
4171
0
    case T_JsonFuncExpr:
4172
0
      {
4173
0
        JsonFuncExpr *jfe = (JsonFuncExpr *) node;
4174
4175
0
        if (WALK(jfe->context_item))
4176
0
          return true;
4177
0
        if (WALK(jfe->pathspec))
4178
0
          return true;
4179
0
        if (WALK(jfe->passing))
4180
0
          return true;
4181
0
        if (WALK(jfe->output))
4182
0
          return true;
4183
0
        if (WALK(jfe->on_empty))
4184
0
          return true;
4185
0
        if (WALK(jfe->on_error))
4186
0
          return true;
4187
0
      }
4188
0
      break;
4189
0
    case T_JsonBehavior:
4190
0
      {
4191
0
        JsonBehavior *jb = (JsonBehavior *) node;
4192
4193
0
        if (WALK(jb->expr))
4194
0
          return true;
4195
0
      }
4196
0
      break;
4197
0
    case T_JsonTable:
4198
0
      {
4199
0
        JsonTable  *jt = (JsonTable *) node;
4200
4201
0
        if (WALK(jt->context_item))
4202
0
          return true;
4203
0
        if (WALK(jt->pathspec))
4204
0
          return true;
4205
0
        if (WALK(jt->passing))
4206
0
          return true;
4207
0
        if (WALK(jt->columns))
4208
0
          return true;
4209
0
        if (WALK(jt->on_error))
4210
0
          return true;
4211
0
      }
4212
0
      break;
4213
0
    case T_JsonTableColumn:
4214
0
      {
4215
0
        JsonTableColumn *jtc = (JsonTableColumn *) node;
4216
4217
0
        if (WALK(jtc->typeName))
4218
0
          return true;
4219
0
        if (WALK(jtc->on_empty))
4220
0
          return true;
4221
0
        if (WALK(jtc->on_error))
4222
0
          return true;
4223
0
        if (WALK(jtc->columns))
4224
0
          return true;
4225
0
      }
4226
0
      break;
4227
0
    case T_JsonTablePathSpec:
4228
0
      return WALK(((JsonTablePathSpec *) node)->string);
4229
0
    case T_NullTest:
4230
0
      return WALK(((NullTest *) node)->arg);
4231
0
    case T_BooleanTest:
4232
0
      return WALK(((BooleanTest *) node)->arg);
4233
0
    case T_JoinExpr:
4234
0
      {
4235
0
        JoinExpr   *join = (JoinExpr *) node;
4236
4237
0
        if (WALK(join->larg))
4238
0
          return true;
4239
0
        if (WALK(join->rarg))
4240
0
          return true;
4241
0
        if (WALK(join->quals))
4242
0
          return true;
4243
0
        if (WALK(join->alias))
4244
0
          return true;
4245
        /* using list is deemed uninteresting */
4246
0
      }
4247
0
      break;
4248
0
    case T_IntoClause:
4249
0
      {
4250
0
        IntoClause *into = (IntoClause *) node;
4251
4252
0
        if (WALK(into->rel))
4253
0
          return true;
4254
        /* colNames, options are deemed uninteresting */
4255
        /* viewQuery should be null in raw parsetree, but check it */
4256
0
        if (WALK(into->viewQuery))
4257
0
          return true;
4258
0
      }
4259
0
      break;
4260
0
    case T_List:
4261
0
      foreach(temp, (List *) node)
4262
0
      {
4263
0
        if (WALK((Node *) lfirst(temp)))
4264
0
          return true;
4265
0
      }
4266
0
      break;
4267
0
    case T_InsertStmt:
4268
0
      {
4269
0
        InsertStmt *stmt = (InsertStmt *) node;
4270
4271
0
        if (WALK(stmt->relation))
4272
0
          return true;
4273
0
        if (WALK(stmt->cols))
4274
0
          return true;
4275
0
        if (WALK(stmt->selectStmt))
4276
0
          return true;
4277
0
        if (WALK(stmt->onConflictClause))
4278
0
          return true;
4279
0
        if (WALK(stmt->returningClause))
4280
0
          return true;
4281
0
        if (WALK(stmt->withClause))
4282
0
          return true;
4283
0
      }
4284
0
      break;
4285
0
    case T_DeleteStmt:
4286
0
      {
4287
0
        DeleteStmt *stmt = (DeleteStmt *) node;
4288
4289
0
        if (WALK(stmt->relation))
4290
0
          return true;
4291
0
        if (WALK(stmt->usingClause))
4292
0
          return true;
4293
0
        if (WALK(stmt->whereClause))
4294
0
          return true;
4295
0
        if (WALK(stmt->returningClause))
4296
0
          return true;
4297
0
        if (WALK(stmt->withClause))
4298
0
          return true;
4299
0
      }
4300
0
      break;
4301
0
    case T_UpdateStmt:
4302
0
      {
4303
0
        UpdateStmt *stmt = (UpdateStmt *) node;
4304
4305
0
        if (WALK(stmt->relation))
4306
0
          return true;
4307
0
        if (WALK(stmt->targetList))
4308
0
          return true;
4309
0
        if (WALK(stmt->whereClause))
4310
0
          return true;
4311
0
        if (WALK(stmt->fromClause))
4312
0
          return true;
4313
0
        if (WALK(stmt->returningClause))
4314
0
          return true;
4315
0
        if (WALK(stmt->withClause))
4316
0
          return true;
4317
0
      }
4318
0
      break;
4319
0
    case T_MergeStmt:
4320
0
      {
4321
0
        MergeStmt  *stmt = (MergeStmt *) node;
4322
4323
0
        if (WALK(stmt->relation))
4324
0
          return true;
4325
0
        if (WALK(stmt->sourceRelation))
4326
0
          return true;
4327
0
        if (WALK(stmt->joinCondition))
4328
0
          return true;
4329
0
        if (WALK(stmt->mergeWhenClauses))
4330
0
          return true;
4331
0
        if (WALK(stmt->returningClause))
4332
0
          return true;
4333
0
        if (WALK(stmt->withClause))
4334
0
          return true;
4335
0
      }
4336
0
      break;
4337
0
    case T_MergeWhenClause:
4338
0
      {
4339
0
        MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
4340
4341
0
        if (WALK(mergeWhenClause->condition))
4342
0
          return true;
4343
0
        if (WALK(mergeWhenClause->targetList))
4344
0
          return true;
4345
0
        if (WALK(mergeWhenClause->values))
4346
0
          return true;
4347
0
      }
4348
0
      break;
4349
0
    case T_ReturningClause:
4350
0
      {
4351
0
        ReturningClause *returning = (ReturningClause *) node;
4352
4353
0
        if (WALK(returning->options))
4354
0
          return true;
4355
0
        if (WALK(returning->exprs))
4356
0
          return true;
4357
0
      }
4358
0
      break;
4359
0
    case T_SelectStmt:
4360
0
      {
4361
0
        SelectStmt *stmt = (SelectStmt *) node;
4362
4363
0
        if (WALK(stmt->distinctClause))
4364
0
          return true;
4365
0
        if (WALK(stmt->intoClause))
4366
0
          return true;
4367
0
        if (WALK(stmt->targetList))
4368
0
          return true;
4369
0
        if (WALK(stmt->fromClause))
4370
0
          return true;
4371
0
        if (WALK(stmt->whereClause))
4372
0
          return true;
4373
0
        if (WALK(stmt->groupClause))
4374
0
          return true;
4375
0
        if (WALK(stmt->havingClause))
4376
0
          return true;
4377
0
        if (WALK(stmt->windowClause))
4378
0
          return true;
4379
0
        if (WALK(stmt->valuesLists))
4380
0
          return true;
4381
0
        if (WALK(stmt->sortClause))
4382
0
          return true;
4383
0
        if (WALK(stmt->limitOffset))
4384
0
          return true;
4385
0
        if (WALK(stmt->limitCount))
4386
0
          return true;
4387
0
        if (WALK(stmt->lockingClause))
4388
0
          return true;
4389
0
        if (WALK(stmt->withClause))
4390
0
          return true;
4391
0
        if (WALK(stmt->larg))
4392
0
          return true;
4393
0
        if (WALK(stmt->rarg))
4394
0
          return true;
4395
0
      }
4396
0
      break;
4397
0
    case T_PLAssignStmt:
4398
0
      {
4399
0
        PLAssignStmt *stmt = (PLAssignStmt *) node;
4400
4401
0
        if (WALK(stmt->indirection))
4402
0
          return true;
4403
0
        if (WALK(stmt->val))
4404
0
          return true;
4405
0
      }
4406
0
      break;
4407
0
    case T_A_Expr:
4408
0
      {
4409
0
        A_Expr     *expr = (A_Expr *) node;
4410
4411
0
        if (WALK(expr->lexpr))
4412
0
          return true;
4413
0
        if (WALK(expr->rexpr))
4414
0
          return true;
4415
        /* operator name is deemed uninteresting */
4416
0
      }
4417
0
      break;
4418
0
    case T_BoolExpr:
4419
0
      {
4420
0
        BoolExpr   *expr = (BoolExpr *) node;
4421
4422
0
        if (WALK(expr->args))
4423
0
          return true;
4424
0
      }
4425
0
      break;
4426
0
    case T_ColumnRef:
4427
      /* we assume the fields contain nothing interesting */
4428
0
      break;
4429
0
    case T_FuncCall:
4430
0
      {
4431
0
        FuncCall   *fcall = (FuncCall *) node;
4432
4433
0
        if (WALK(fcall->args))
4434
0
          return true;
4435
0
        if (WALK(fcall->agg_order))
4436
0
          return true;
4437
0
        if (WALK(fcall->agg_filter))
4438
0
          return true;
4439
0
        if (WALK(fcall->over))
4440
0
          return true;
4441
        /* function name is deemed uninteresting */
4442
0
      }
4443
0
      break;
4444
0
    case T_NamedArgExpr:
4445
0
      return WALK(((NamedArgExpr *) node)->arg);
4446
0
    case T_A_Indices:
4447
0
      {
4448
0
        A_Indices  *indices = (A_Indices *) node;
4449
4450
0
        if (WALK(indices->lidx))
4451
0
          return true;
4452
0
        if (WALK(indices->uidx))
4453
0
          return true;
4454
0
      }
4455
0
      break;
4456
0
    case T_A_Indirection:
4457
0
      {
4458
0
        A_Indirection *indir = (A_Indirection *) node;
4459
4460
0
        if (WALK(indir->arg))
4461
0
          return true;
4462
0
        if (WALK(indir->indirection))
4463
0
          return true;
4464
0
      }
4465
0
      break;
4466
0
    case T_A_ArrayExpr:
4467
0
      return WALK(((A_ArrayExpr *) node)->elements);
4468
0
    case T_ResTarget:
4469
0
      {
4470
0
        ResTarget  *rt = (ResTarget *) node;
4471
4472
0
        if (WALK(rt->indirection))
4473
0
          return true;
4474
0
        if (WALK(rt->val))
4475
0
          return true;
4476
0
      }
4477
0
      break;
4478
0
    case T_MultiAssignRef:
4479
0
      return WALK(((MultiAssignRef *) node)->source);
4480
0
    case T_TypeCast:
4481
0
      {
4482
0
        TypeCast   *tc = (TypeCast *) node;
4483
4484
0
        if (WALK(tc->arg))
4485
0
          return true;
4486
0
        if (WALK(tc->typeName))
4487
0
          return true;
4488
0
      }
4489
0
      break;
4490
0
    case T_CollateClause:
4491
0
      return WALK(((CollateClause *) node)->arg);
4492
0
    case T_SortBy:
4493
0
      return WALK(((SortBy *) node)->node);
4494
0
    case T_WindowDef:
4495
0
      {
4496
0
        WindowDef  *wd = (WindowDef *) node;
4497
4498
0
        if (WALK(wd->partitionClause))
4499
0
          return true;
4500
0
        if (WALK(wd->orderClause))
4501
0
          return true;
4502
0
        if (WALK(wd->startOffset))
4503
0
          return true;
4504
0
        if (WALK(wd->endOffset))
4505
0
          return true;
4506
0
      }
4507
0
      break;
4508
0
    case T_RangeSubselect:
4509
0
      {
4510
0
        RangeSubselect *rs = (RangeSubselect *) node;
4511
4512
0
        if (WALK(rs->subquery))
4513
0
          return true;
4514
0
        if (WALK(rs->alias))
4515
0
          return true;
4516
0
      }
4517
0
      break;
4518
0
    case T_RangeFunction:
4519
0
      {
4520
0
        RangeFunction *rf = (RangeFunction *) node;
4521
4522
0
        if (WALK(rf->functions))
4523
0
          return true;
4524
0
        if (WALK(rf->alias))
4525
0
          return true;
4526
0
        if (WALK(rf->coldeflist))
4527
0
          return true;
4528
0
      }
4529
0
      break;
4530
0
    case T_RangeTableSample:
4531
0
      {
4532
0
        RangeTableSample *rts = (RangeTableSample *) node;
4533
4534
0
        if (WALK(rts->relation))
4535
0
          return true;
4536
        /* method name is deemed uninteresting */
4537
0
        if (WALK(rts->args))
4538
0
          return true;
4539
0
        if (WALK(rts->repeatable))
4540
0
          return true;
4541
0
      }
4542
0
      break;
4543
0
    case T_RangeTableFunc:
4544
0
      {
4545
0
        RangeTableFunc *rtf = (RangeTableFunc *) node;
4546
4547
0
        if (WALK(rtf->docexpr))
4548
0
          return true;
4549
0
        if (WALK(rtf->rowexpr))
4550
0
          return true;
4551
0
        if (WALK(rtf->namespaces))
4552
0
          return true;
4553
0
        if (WALK(rtf->columns))
4554
0
          return true;
4555
0
        if (WALK(rtf->alias))
4556
0
          return true;
4557
0
      }
4558
0
      break;
4559
0
    case T_RangeTableFuncCol:
4560
0
      {
4561
0
        RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
4562
4563
0
        if (WALK(rtfc->colexpr))
4564
0
          return true;
4565
0
        if (WALK(rtfc->coldefexpr))
4566
0
          return true;
4567
0
      }
4568
0
      break;
4569
0
    case T_TypeName:
4570
0
      {
4571
0
        TypeName   *tn = (TypeName *) node;
4572
4573
0
        if (WALK(tn->typmods))
4574
0
          return true;
4575
0
        if (WALK(tn->arrayBounds))
4576
0
          return true;
4577
        /* type name itself is deemed uninteresting */
4578
0
      }
4579
0
      break;
4580
0
    case T_ColumnDef:
4581
0
      {
4582
0
        ColumnDef  *coldef = (ColumnDef *) node;
4583
4584
0
        if (WALK(coldef->typeName))
4585
0
          return true;
4586
0
        if (WALK(coldef->raw_default))
4587
0
          return true;
4588
0
        if (WALK(coldef->collClause))
4589
0
          return true;
4590
        /* for now, constraints are ignored */
4591
0
      }
4592
0
      break;
4593
0
    case T_IndexElem:
4594
0
      {
4595
0
        IndexElem  *indelem = (IndexElem *) node;
4596
4597
0
        if (WALK(indelem->expr))
4598
0
          return true;
4599
        /* collation and opclass names are deemed uninteresting */
4600
0
      }
4601
0
      break;
4602
0
    case T_GroupingSet:
4603
0
      return WALK(((GroupingSet *) node)->content);
4604
0
    case T_LockingClause:
4605
0
      return WALK(((LockingClause *) node)->lockedRels);
4606
0
    case T_XmlSerialize:
4607
0
      {
4608
0
        XmlSerialize *xs = (XmlSerialize *) node;
4609
4610
0
        if (WALK(xs->expr))
4611
0
          return true;
4612
0
        if (WALK(xs->typeName))
4613
0
          return true;
4614
0
      }
4615
0
      break;
4616
0
    case T_WithClause:
4617
0
      return WALK(((WithClause *) node)->ctes);
4618
0
    case T_InferClause:
4619
0
      {
4620
0
        InferClause *stmt = (InferClause *) node;
4621
4622
0
        if (WALK(stmt->indexElems))
4623
0
          return true;
4624
0
        if (WALK(stmt->whereClause))
4625
0
          return true;
4626
0
      }
4627
0
      break;
4628
0
    case T_OnConflictClause:
4629
0
      {
4630
0
        OnConflictClause *stmt = (OnConflictClause *) node;
4631
4632
0
        if (WALK(stmt->infer))
4633
0
          return true;
4634
0
        if (WALK(stmt->targetList))
4635
0
          return true;
4636
0
        if (WALK(stmt->whereClause))
4637
0
          return true;
4638
0
      }
4639
0
      break;
4640
0
    case T_CommonTableExpr:
4641
      /* search_clause and cycle_clause are not interesting here */
4642
0
      return WALK(((CommonTableExpr *) node)->ctequery);
4643
0
    case T_JsonOutput:
4644
0
      {
4645
0
        JsonOutput *out = (JsonOutput *) node;
4646
4647
0
        if (WALK(out->typeName))
4648
0
          return true;
4649
0
        if (WALK(out->returning))
4650
0
          return true;
4651
0
      }
4652
0
      break;
4653
0
    case T_JsonKeyValue:
4654
0
      {
4655
0
        JsonKeyValue *jkv = (JsonKeyValue *) node;
4656
4657
0
        if (WALK(jkv->key))
4658
0
          return true;
4659
0
        if (WALK(jkv->value))
4660
0
          return true;
4661
0
      }
4662
0
      break;
4663
0
    case T_JsonObjectConstructor:
4664
0
      {
4665
0
        JsonObjectConstructor *joc = (JsonObjectConstructor *) node;
4666
4667
0
        if (WALK(joc->output))
4668
0
          return true;
4669
0
        if (WALK(joc->exprs))
4670
0
          return true;
4671
0
      }
4672
0
      break;
4673
0
    case T_JsonArrayConstructor:
4674
0
      {
4675
0
        JsonArrayConstructor *jac = (JsonArrayConstructor *) node;
4676
4677
0
        if (WALK(jac->output))
4678
0
          return true;
4679
0
        if (WALK(jac->exprs))
4680
0
          return true;
4681
0
      }
4682
0
      break;
4683
0
    case T_JsonAggConstructor:
4684
0
      {
4685
0
        JsonAggConstructor *ctor = (JsonAggConstructor *) node;
4686
4687
0
        if (WALK(ctor->output))
4688
0
          return true;
4689
0
        if (WALK(ctor->agg_order))
4690
0
          return true;
4691
0
        if (WALK(ctor->agg_filter))
4692
0
          return true;
4693
0
        if (WALK(ctor->over))
4694
0
          return true;
4695
0
      }
4696
0
      break;
4697
0
    case T_JsonObjectAgg:
4698
0
      {
4699
0
        JsonObjectAgg *joa = (JsonObjectAgg *) node;
4700
4701
0
        if (WALK(joa->constructor))
4702
0
          return true;
4703
0
        if (WALK(joa->arg))
4704
0
          return true;
4705
0
      }
4706
0
      break;
4707
0
    case T_JsonArrayAgg:
4708
0
      {
4709
0
        JsonArrayAgg *jaa = (JsonArrayAgg *) node;
4710
4711
0
        if (WALK(jaa->constructor))
4712
0
          return true;
4713
0
        if (WALK(jaa->arg))
4714
0
          return true;
4715
0
      }
4716
0
      break;
4717
0
    case T_JsonArrayQueryConstructor:
4718
0
      {
4719
0
        JsonArrayQueryConstructor *jaqc = (JsonArrayQueryConstructor *) node;
4720
4721
0
        if (WALK(jaqc->output))
4722
0
          return true;
4723
0
        if (WALK(jaqc->query))
4724
0
          return true;
4725
0
      }
4726
0
      break;
4727
0
    default:
4728
0
      elog(ERROR, "unrecognized node type: %d",
4729
0
         (int) nodeTag(node));
4730
0
      break;
4731
0
  }
4732
0
  return false;
4733
0
}
4734
4735
/*
4736
 * planstate_tree_walker --- walk plan state trees
4737
 *
4738
 * The walker has already visited the current node, and so we need only
4739
 * recurse into any sub-nodes it has.
4740
 */
4741
pg_attribute_no_sanitize_function()
4742
bool
4743
planstate_tree_walker_impl(PlanState *planstate,
4744
               planstate_tree_walker_callback walker,
4745
               void *context)
4746
0
{
4747
0
  Plan     *plan = planstate->plan;
4748
0
  ListCell   *lc;
4749
4750
  /* We don't need implicit coercions to Node here */
4751
0
#define PSWALK(n) walker(n, context)
4752
4753
  /* Guard against stack overflow due to overly complex plan trees */
4754
0
  check_stack_depth();
4755
4756
  /* initPlan-s */
4757
0
  if (planstate_walk_subplans(planstate->initPlan, walker, context))
4758
0
    return true;
4759
4760
  /* lefttree */
4761
0
  if (outerPlanState(planstate))
4762
0
  {
4763
0
    if (PSWALK(outerPlanState(planstate)))
4764
0
      return true;
4765
0
  }
4766
4767
  /* righttree */
4768
0
  if (innerPlanState(planstate))
4769
0
  {
4770
0
    if (PSWALK(innerPlanState(planstate)))
4771
0
      return true;
4772
0
  }
4773
4774
  /* special child plans */
4775
0
  switch (nodeTag(plan))
4776
0
  {
4777
0
    case T_Append:
4778
0
      if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4779
0
                     ((AppendState *) planstate)->as_nplans,
4780
0
                     walker, context))
4781
0
        return true;
4782
0
      break;
4783
0
    case T_MergeAppend:
4784
0
      if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4785
0
                     ((MergeAppendState *) planstate)->ms_nplans,
4786
0
                     walker, context))
4787
0
        return true;
4788
0
      break;
4789
0
    case T_BitmapAnd:
4790
0
      if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4791
0
                     ((BitmapAndState *) planstate)->nplans,
4792
0
                     walker, context))
4793
0
        return true;
4794
0
      break;
4795
0
    case T_BitmapOr:
4796
0
      if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4797
0
                     ((BitmapOrState *) planstate)->nplans,
4798
0
                     walker, context))
4799
0
        return true;
4800
0
      break;
4801
0
    case T_SubqueryScan:
4802
0
      if (PSWALK(((SubqueryScanState *) planstate)->subplan))
4803
0
        return true;
4804
0
      break;
4805
0
    case T_CustomScan:
4806
0
      foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4807
0
      {
4808
0
        if (PSWALK(lfirst(lc)))
4809
0
          return true;
4810
0
      }
4811
0
      break;
4812
0
    default:
4813
0
      break;
4814
0
  }
4815
4816
  /* subPlan-s */
4817
0
  if (planstate_walk_subplans(planstate->subPlan, walker, context))
4818
0
    return true;
4819
4820
0
  return false;
4821
0
}
4822
4823
/*
4824
 * Walk a list of SubPlans (or initPlans, which also use SubPlan nodes).
4825
 */
4826
pg_attribute_no_sanitize_function()
4827
static bool
4828
planstate_walk_subplans(List *plans,
4829
            planstate_tree_walker_callback walker,
4830
            void *context)
4831
0
{
4832
0
  ListCell   *lc;
4833
4834
0
  foreach(lc, plans)
4835
0
  {
4836
0
    SubPlanState *sps = lfirst_node(SubPlanState, lc);
4837
4838
0
    if (PSWALK(sps->planstate))
4839
0
      return true;
4840
0
  }
4841
4842
0
  return false;
4843
0
}
4844
4845
/*
4846
 * Walk the constituent plans of a ModifyTable, Append, MergeAppend,
4847
 * BitmapAnd, or BitmapOr node.
4848
 */
4849
pg_attribute_no_sanitize_function()
4850
static bool
4851
planstate_walk_members(PlanState **planstates, int nplans,
4852
             planstate_tree_walker_callback walker,
4853
             void *context)
4854
0
{
4855
0
  for (int j = 0; j < nplans; j++)
4856
0
  {
4857
0
    if (PSWALK(planstates[j]))
4858
0
      return true;
4859
0
  }
4860
4861
0
  return false;
4862
0
}