Coverage Report

Created: 2026-08-13 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/nodes/makefuncs.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * makefuncs.c
4
 *    creator functions for various nodes. The functions here are for the
5
 *    most frequently created nodes.
6
 *
7
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8
 * Portions Copyright (c) 1994, Regents of the University of California
9
 *
10
 *
11
 * IDENTIFICATION
12
 *    src/backend/nodes/makefuncs.c
13
 *
14
 *-------------------------------------------------------------------------
15
 */
16
#include "postgres.h"
17
18
#include "catalog/pg_class.h"
19
#include "catalog/pg_type.h"
20
#include "nodes/makefuncs.h"
21
#include "nodes/nodeFuncs.h"
22
#include "utils/lsyscache.h"
23
24
25
/*
26
 * makeA_Expr -
27
 *    makes an A_Expr node
28
 */
29
A_Expr *
30
makeA_Expr(A_Expr_Kind kind, List *name,
31
       Node *lexpr, Node *rexpr, int location)
32
12.1k
{
33
12.1k
  A_Expr     *a = makeNode(A_Expr);
34
35
12.1k
  a->kind = kind;
36
12.1k
  a->name = name;
37
12.1k
  a->lexpr = lexpr;
38
12.1k
  a->rexpr = rexpr;
39
12.1k
  a->location = location;
40
12.1k
  return a;
41
12.1k
}
42
43
/*
44
 * makeSimpleA_Expr -
45
 *    As above, given a simple (unqualified) operator name
46
 */
47
A_Expr *
48
makeSimpleA_Expr(A_Expr_Kind kind, char *name,
49
         Node *lexpr, Node *rexpr, int location)
50
146k
{
51
146k
  A_Expr     *a = makeNode(A_Expr);
52
53
146k
  a->kind = kind;
54
146k
  a->name = list_make1(makeString(name));
55
146k
  a->lexpr = lexpr;
56
146k
  a->rexpr = rexpr;
57
146k
  a->location = location;
58
146k
  return a;
59
146k
}
60
61
/*
62
 * makeVar -
63
 *    creates a Var node
64
 */
65
Var *
66
makeVar(int varno,
67
    AttrNumber varattno,
68
    Oid vartype,
69
    int32 vartypmod,
70
    Oid varcollid,
71
    Index varlevelsup)
72
0
{
73
0
  Var      *var = makeNode(Var);
74
75
0
  var->varno = varno;
76
0
  var->varattno = varattno;
77
0
  var->vartype = vartype;
78
0
  var->vartypmod = vartypmod;
79
0
  var->varcollid = varcollid;
80
0
  var->varlevelsup = varlevelsup;
81
82
  /*
83
   * Only a few callers need to make Var nodes with varreturningtype
84
   * different from VAR_RETURNING_DEFAULT, non-null varnullingrels, or with
85
   * varnosyn/varattnosyn different from varno/varattno.  We don't provide
86
   * separate arguments for them, but just initialize them to sensible
87
   * default values.  This reduces code clutter and chance of error for most
88
   * callers.
89
   */
90
0
  var->varreturningtype = VAR_RETURNING_DEFAULT;
91
0
  var->varnullingrels = NULL;
92
0
  var->varnosyn = (Index) varno;
93
0
  var->varattnosyn = varattno;
94
95
  /* Likewise, we just set location to "unknown" here */
96
0
  var->location = -1;
97
98
0
  return var;
99
0
}
100
101
/*
102
 * makeVarFromTargetEntry -
103
 *    convenience function to create a same-level Var node from a
104
 *    TargetEntry
105
 */
106
Var *
107
makeVarFromTargetEntry(int varno,
108
             TargetEntry *tle)
109
0
{
110
0
  return makeVar(varno,
111
0
           tle->resno,
112
0
           exprType((Node *) tle->expr),
113
0
           exprTypmod((Node *) tle->expr),
114
0
           exprCollation((Node *) tle->expr),
115
0
           0);
116
0
}
117
118
/*
119
 * makeWholeRowVar -
120
 *    creates a Var node representing a whole row of the specified RTE
121
 *
122
 * A whole-row reference is a Var with varno set to the correct range
123
 * table entry, and varattno == 0 to signal that it references the whole
124
 * tuple.  (Use of zero here is unclean, since it could easily be confused
125
 * with error cases, but it's not worth changing now.)  The vartype indicates
126
 * a rowtype; either a named composite type, or a domain over a named
127
 * composite type (only possible if the RTE is a function returning that),
128
 * or RECORD.  This function encapsulates the logic for determining the
129
 * correct rowtype OID to use.
130
 *
131
 * If allowScalar is true, then for the case where the RTE is a single function
132
 * returning a non-composite result type, we produce a normal Var referencing
133
 * the function's result directly, instead of the single-column composite
134
 * value that the whole-row notation might otherwise suggest.
135
 */
136
Var *
137
makeWholeRowVar(RangeTblEntry *rte,
138
        int varno,
139
        Index varlevelsup,
140
        bool allowScalar)
141
0
{
142
0
  Var      *result;
143
0
  Oid     toid;
144
0
  Node     *fexpr;
145
146
0
  switch (rte->rtekind)
147
0
  {
148
0
    case RTE_RELATION:
149
      /* relation: the rowtype is a named composite type */
150
0
      toid = get_rel_type_id(rte->relid);
151
0
      if (!OidIsValid(toid))
152
0
        ereport(ERROR,
153
0
            (errcode(ERRCODE_WRONG_OBJECT_TYPE),
154
0
             errmsg("relation \"%s\" does not have a composite type",
155
0
                get_rel_name(rte->relid))));
156
0
      result = makeVar(varno,
157
0
               InvalidAttrNumber,
158
0
               toid,
159
0
               -1,
160
0
               InvalidOid,
161
0
               varlevelsup);
162
0
      break;
163
164
0
    case RTE_SUBQUERY:
165
166
      /*
167
       * For a standard subquery, the Var should be of RECORD type.
168
       * However, if we're looking at a subquery that was expanded from
169
       * a view or SRF (only possible during planning), we must use the
170
       * appropriate rowtype, so that the resulting Var has the same
171
       * type that we would have produced from the original RTE.
172
       */
173
0
      if (OidIsValid(rte->relid))
174
0
      {
175
        /* Subquery was expanded from a view */
176
0
        toid = get_rel_type_id(rte->relid);
177
0
        if (!OidIsValid(toid))
178
0
          ereport(ERROR,
179
0
              (errcode(ERRCODE_WRONG_OBJECT_TYPE),
180
0
               errmsg("relation \"%s\" does not have a composite type",
181
0
                  get_rel_name(rte->relid))));
182
0
      }
183
0
      else if (rte->functions)
184
0
      {
185
        /*
186
         * Subquery was expanded from a set-returning function.  That
187
         * would not have happened if there's more than one function
188
         * or ordinality was requested.  We also needn't worry about
189
         * the allowScalar case, since the planner doesn't use that.
190
         * Otherwise this must match the RTE_FUNCTION code below.
191
         */
192
0
        Assert(!allowScalar);
193
0
        fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
194
0
        toid = exprType(fexpr);
195
0
        if (!type_is_rowtype(toid))
196
0
          toid = RECORDOID;
197
0
      }
198
0
      else
199
0
      {
200
        /* Normal subquery-in-FROM */
201
0
        toid = RECORDOID;
202
0
      }
203
0
      result = makeVar(varno,
204
0
               InvalidAttrNumber,
205
0
               toid,
206
0
               -1,
207
0
               InvalidOid,
208
0
               varlevelsup);
209
0
      break;
210
211
0
    case RTE_FUNCTION:
212
213
      /*
214
       * If there's more than one function, or ordinality is requested,
215
       * force a RECORD result, since there's certainly more than one
216
       * column involved and it can't be a known named type.
217
       */
218
0
      if (rte->funcordinality || list_length(rte->functions) != 1)
219
0
      {
220
        /* always produces an anonymous RECORD result */
221
0
        result = makeVar(varno,
222
0
                 InvalidAttrNumber,
223
0
                 RECORDOID,
224
0
                 -1,
225
0
                 InvalidOid,
226
0
                 varlevelsup);
227
0
        break;
228
0
      }
229
230
0
      fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
231
0
      toid = exprType(fexpr);
232
0
      if (type_is_rowtype(toid))
233
0
      {
234
        /* func returns composite; same as relation case */
235
0
        result = makeVar(varno,
236
0
                 InvalidAttrNumber,
237
0
                 toid,
238
0
                 -1,
239
0
                 InvalidOid,
240
0
                 varlevelsup);
241
0
      }
242
0
      else if (allowScalar)
243
0
      {
244
        /* func returns scalar; just return its output as-is */
245
0
        result = makeVar(varno,
246
0
                 1,
247
0
                 toid,
248
0
                 -1,
249
0
                 exprCollation(fexpr),
250
0
                 varlevelsup);
251
0
      }
252
0
      else
253
0
      {
254
        /* func returns scalar, but we want a composite result */
255
0
        result = makeVar(varno,
256
0
                 InvalidAttrNumber,
257
0
                 RECORDOID,
258
0
                 -1,
259
0
                 InvalidOid,
260
0
                 varlevelsup);
261
0
      }
262
0
      break;
263
264
0
    default:
265
266
      /*
267
       * RTE is a join, tablefunc, VALUES, CTE, etc.  We represent these
268
       * cases as a whole-row Var of RECORD type.  (Note that in most
269
       * cases the Var will be expanded to a RowExpr during planning,
270
       * but that is not our concern here.)
271
       */
272
0
      result = makeVar(varno,
273
0
               InvalidAttrNumber,
274
0
               RECORDOID,
275
0
               -1,
276
0
               InvalidOid,
277
0
               varlevelsup);
278
0
      break;
279
0
  }
280
281
0
  return result;
282
0
}
283
284
/*
285
 * makeTargetEntry -
286
 *    creates a TargetEntry node
287
 */
288
TargetEntry *
289
makeTargetEntry(Expr *expr,
290
        AttrNumber resno,
291
        char *resname,
292
        bool resjunk)
293
0
{
294
0
  TargetEntry *tle = makeNode(TargetEntry);
295
296
0
  tle->expr = expr;
297
0
  tle->resno = resno;
298
0
  tle->resname = resname;
299
300
  /*
301
   * We always set these fields to 0. If the caller wants to change them he
302
   * must do so explicitly.  Few callers do that, so omitting these
303
   * arguments reduces the chance of error.
304
   */
305
0
  tle->ressortgroupref = 0;
306
0
  tle->resorigtbl = InvalidOid;
307
0
  tle->resorigcol = 0;
308
309
0
  tle->resjunk = resjunk;
310
311
0
  return tle;
312
0
}
313
314
/*
315
 * flatCopyTargetEntry -
316
 *    duplicate a TargetEntry, but don't copy substructure
317
 *
318
 * This is commonly used when we just want to modify the resno or substitute
319
 * a new expression.
320
 */
321
TargetEntry *
322
flatCopyTargetEntry(TargetEntry *src_tle)
323
0
{
324
0
  TargetEntry *tle = makeNode(TargetEntry);
325
326
0
  Assert(IsA(src_tle, TargetEntry));
327
0
  memcpy(tle, src_tle, sizeof(TargetEntry));
328
0
  return tle;
329
0
}
330
331
/*
332
 * makeFromExpr -
333
 *    creates a FromExpr node
334
 */
335
FromExpr *
336
makeFromExpr(List *fromlist, Node *quals)
337
0
{
338
0
  FromExpr   *f = makeNode(FromExpr);
339
340
0
  f->fromlist = fromlist;
341
0
  f->quals = quals;
342
0
  return f;
343
0
}
344
345
/*
346
 * makeConst -
347
 *    creates a Const node
348
 */
349
Const *
350
makeConst(Oid consttype,
351
      int32 consttypmod,
352
      Oid constcollid,
353
      int constlen,
354
      Datum constvalue,
355
      bool constisnull,
356
      bool constbyval)
357
0
{
358
0
  Const    *cnst = makeNode(Const);
359
360
  /*
361
   * If it's a varlena value, force it to be in non-expanded (non-toasted)
362
   * format; this avoids any possible dependency on external values and
363
   * improves consistency of representation, which is important for equal().
364
   */
365
0
  if (!constisnull && constlen == -1)
366
0
    constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
367
368
0
  cnst->consttype = consttype;
369
0
  cnst->consttypmod = consttypmod;
370
0
  cnst->constcollid = constcollid;
371
0
  cnst->constlen = constlen;
372
0
  cnst->constvalue = constvalue;
373
0
  cnst->constisnull = constisnull;
374
0
  cnst->constbyval = constbyval;
375
0
  cnst->location = -1;    /* "unknown" */
376
377
0
  return cnst;
378
0
}
379
380
/*
381
 * makeNullConst -
382
 *    creates a Const node representing a NULL of the specified type/typmod
383
 *
384
 * This is a convenience routine that just saves a lookup of the type's
385
 * storage properties.
386
 */
387
Const *
388
makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
389
0
{
390
0
  int16   typLen;
391
0
  bool    typByVal;
392
393
0
  get_typlenbyval(consttype, &typLen, &typByVal);
394
0
  return makeConst(consttype,
395
0
           consttypmod,
396
0
           constcollid,
397
0
           (int) typLen,
398
0
           (Datum) 0,
399
0
           true,
400
0
           typByVal);
401
0
}
402
403
/*
404
 * makeBoolConst -
405
 *    creates a Const node representing a boolean value (can be NULL too)
406
 */
407
Node *
408
makeBoolConst(bool value, bool isnull)
409
0
{
410
  /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
411
0
  return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
412
0
                BoolGetDatum(value), isnull, true);
413
0
}
414
415
/*
416
 * makeBoolExpr -
417
 *    creates a BoolExpr node
418
 */
419
Expr *
420
makeBoolExpr(BoolExprType boolop, List *args, int location)
421
2.19k
{
422
2.19k
  BoolExpr   *b = makeNode(BoolExpr);
423
424
2.19k
  b->boolop = boolop;
425
2.19k
  b->args = args;
426
2.19k
  b->location = location;
427
428
2.19k
  return (Expr *) b;
429
2.19k
}
430
431
/*
432
 * makeAlias -
433
 *    creates an Alias node
434
 *
435
 * NOTE: the given name is copied, but the colnames list (if any) isn't.
436
 */
437
Alias *
438
makeAlias(const char *aliasname, List *colnames)
439
0
{
440
0
  Alias    *a = makeNode(Alias);
441
442
0
  a->aliasname = pstrdup(aliasname);
443
0
  a->colnames = colnames;
444
445
0
  return a;
446
0
}
447
448
/*
449
 * makeRelabelType -
450
 *    creates a RelabelType node
451
 */
452
RelabelType *
453
makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
454
        CoercionForm rformat)
455
0
{
456
0
  RelabelType *r = makeNode(RelabelType);
457
458
0
  r->arg = arg;
459
0
  r->resulttype = rtype;
460
0
  r->resulttypmod = rtypmod;
461
0
  r->resultcollid = rcollid;
462
0
  r->relabelformat = rformat;
463
0
  r->location = -1;
464
465
0
  return r;
466
0
}
467
468
/*
469
 * makeRangeVar -
470
 *    creates a RangeVar node (rather oversimplified case)
471
 */
472
RangeVar *
473
makeRangeVar(char *schemaname, char *relname, int location)
474
0
{
475
0
  RangeVar   *r = makeNode(RangeVar);
476
477
0
  r->catalogname = NULL;
478
0
  r->schemaname = schemaname;
479
0
  r->relname = relname;
480
0
  r->inh = true;
481
0
  r->relpersistence = RELPERSISTENCE_PERMANENT;
482
0
  r->alias = NULL;
483
0
  r->location = location;
484
485
0
  return r;
486
0
}
487
488
/*
489
 * makeNotNullConstraint -
490
 *    creates a Constraint node for NOT NULL constraints
491
 */
492
Constraint *
493
makeNotNullConstraint(String *colname)
494
0
{
495
0
  Constraint *notnull;
496
497
0
  notnull = makeNode(Constraint);
498
0
  notnull->contype = CONSTR_NOTNULL;
499
0
  notnull->conname = NULL;
500
0
  notnull->is_no_inherit = false;
501
0
  notnull->deferrable = false;
502
0
  notnull->initdeferred = false;
503
0
  notnull->location = -1;
504
0
  notnull->keys = list_make1(colname);
505
0
  notnull->is_enforced = true;
506
0
  notnull->skip_validation = false;
507
0
  notnull->initially_valid = true;
508
509
0
  return notnull;
510
0
}
511
512
/*
513
 * makeTypeName -
514
 *  build a TypeName node for an unqualified name.
515
 *
516
 * typmod is defaulted, but can be changed later by caller.
517
 */
518
TypeName *
519
makeTypeName(char *typnam)
520
2.48k
{
521
2.48k
  return makeTypeNameFromNameList(list_make1(makeString(typnam)));
522
2.48k
}
523
524
/*
525
 * makeTypeNameFromNameList -
526
 *  build a TypeName node for a String list representing a qualified name.
527
 *
528
 * typmod is defaulted, but can be changed later by caller.
529
 */
530
TypeName *
531
makeTypeNameFromNameList(List *names)
532
7.72k
{
533
7.72k
  TypeName   *n = makeNode(TypeName);
534
535
7.72k
  n->names = names;
536
7.72k
  n->typmods = NIL;
537
7.72k
  n->typemod = -1;
538
7.72k
  n->location = -1;
539
7.72k
  return n;
540
7.72k
}
541
542
/*
543
 * makeTypeNameFromOid -
544
 *  build a TypeName node to represent a type already known by OID/typmod.
545
 */
546
TypeName *
547
makeTypeNameFromOid(Oid typeOid, int32 typmod)
548
0
{
549
0
  TypeName   *n = makeNode(TypeName);
550
551
0
  n->typeOid = typeOid;
552
0
  n->typemod = typmod;
553
0
  n->location = -1;
554
0
  return n;
555
0
}
556
557
/*
558
 * makeColumnDef -
559
 *  build a ColumnDef node to represent a simple column definition.
560
 *
561
 * Type and collation are specified by OID.
562
 * Other properties are all basic to start with.
563
 */
564
ColumnDef *
565
makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
566
0
{
567
0
  ColumnDef  *n = makeNode(ColumnDef);
568
569
0
  n->colname = pstrdup(colname);
570
0
  n->typeName = makeTypeNameFromOid(typeOid, typmod);
571
0
  n->inhcount = 0;
572
0
  n->is_local = true;
573
0
  n->is_not_null = false;
574
0
  n->is_from_type = false;
575
0
  n->storage = 0;
576
0
  n->raw_default = NULL;
577
0
  n->cooked_default = NULL;
578
0
  n->collClause = NULL;
579
0
  n->collOid = collOid;
580
0
  n->constraints = NIL;
581
0
  n->fdwoptions = NIL;
582
0
  n->location = -1;
583
584
0
  return n;
585
0
}
586
587
/*
588
 * makeFuncExpr -
589
 *  build an expression tree representing a function call.
590
 *
591
 * The argument expressions must have been transformed already.
592
 */
593
FuncExpr *
594
makeFuncExpr(Oid funcid, Oid rettype, List *args,
595
       Oid funccollid, Oid inputcollid, CoercionForm fformat)
596
0
{
597
0
  FuncExpr   *funcexpr;
598
599
0
  funcexpr = makeNode(FuncExpr);
600
0
  funcexpr->funcid = funcid;
601
0
  funcexpr->funcresulttype = rettype;
602
0
  funcexpr->funcretset = false;  /* only allowed case here */
603
0
  funcexpr->funcvariadic = false; /* only allowed case here */
604
0
  funcexpr->funcformat = fformat;
605
0
  funcexpr->funccollid = funccollid;
606
0
  funcexpr->inputcollid = inputcollid;
607
0
  funcexpr->args = args;
608
0
  funcexpr->location = -1;
609
610
0
  return funcexpr;
611
0
}
612
613
/*
614
 * makeStringConst -
615
 *  build a A_Const node of type T_String for given string
616
 */
617
Node *
618
makeStringConst(char *str, int location)
619
5.89k
{
620
5.89k
  A_Const    *n = makeNode(A_Const);
621
622
5.89k
  n->val.sval.type = T_String;
623
5.89k
  n->val.sval.sval = str;
624
5.89k
  n->location = location;
625
626
5.89k
  return (Node *) n;
627
5.89k
}
628
629
/*
630
 * makeDefElem -
631
 *  build a DefElem node
632
 *
633
 * This is sufficient for the "typical" case with an unqualified option name
634
 * and no special action.
635
 */
636
DefElem *
637
makeDefElem(char *name, Node *arg, int location)
638
0
{
639
0
  DefElem    *res = makeNode(DefElem);
640
641
0
  res->defnamespace = NULL;
642
0
  res->defname = name;
643
0
  res->arg = arg;
644
0
  res->defaction = DEFELEM_UNSPEC;
645
0
  res->location = location;
646
647
0
  return res;
648
0
}
649
650
/*
651
 * makeDefElemExtended -
652
 *  build a DefElem node with all fields available to be specified
653
 */
654
DefElem *
655
makeDefElemExtended(char *nameSpace, char *name, Node *arg,
656
          DefElemAction defaction, int location)
657
0
{
658
0
  DefElem    *res = makeNode(DefElem);
659
660
0
  res->defnamespace = nameSpace;
661
0
  res->defname = name;
662
0
  res->arg = arg;
663
0
  res->defaction = defaction;
664
0
  res->location = location;
665
666
0
  return res;
667
0
}
668
669
/*
670
 * makeFuncCall -
671
 *
672
 * Initialize a FuncCall struct with the information every caller must
673
 * supply.  Any non-default parameters have to be inserted by the caller.
674
 */
675
FuncCall *
676
makeFuncCall(List *name, List *args, CoercionForm funcformat, int location)
677
3.68k
{
678
3.68k
  FuncCall   *n = makeNode(FuncCall);
679
680
3.68k
  n->funcname = name;
681
3.68k
  n->args = args;
682
3.68k
  n->agg_order = NIL;
683
3.68k
  n->agg_filter = NULL;
684
3.68k
  n->over = NULL;
685
3.68k
  n->agg_within_group = false;
686
3.68k
  n->agg_star = false;
687
3.68k
  n->agg_distinct = false;
688
3.68k
  n->func_variadic = false;
689
3.68k
  n->funcformat = funcformat;
690
3.68k
  n->location = location;
691
3.68k
  return n;
692
3.68k
}
693
694
/*
695
 * make_opclause
696
 *    Creates an operator clause given its operator info, left operand
697
 *    and right operand (pass NULL to create single-operand clause),
698
 *    and collation info.
699
 */
700
Expr *
701
make_opclause(Oid opno, Oid opresulttype, bool opretset,
702
        Expr *leftop, Expr *rightop,
703
        Oid opcollid, Oid inputcollid)
704
0
{
705
0
  OpExpr     *expr = makeNode(OpExpr);
706
707
0
  expr->opno = opno;
708
0
  expr->opfuncid = InvalidOid;
709
0
  expr->opresulttype = opresulttype;
710
0
  expr->opretset = opretset;
711
0
  expr->opcollid = opcollid;
712
0
  expr->inputcollid = inputcollid;
713
0
  if (rightop)
714
0
    expr->args = list_make2(leftop, rightop);
715
0
  else
716
0
    expr->args = list_make1(leftop);
717
0
  expr->location = -1;
718
0
  return (Expr *) expr;
719
0
}
720
721
/*
722
 * make_andclause
723
 *
724
 * Creates an 'and' clause given a list of its subclauses.
725
 */
726
Expr *
727
make_andclause(List *andclauses)
728
0
{
729
0
  BoolExpr   *expr = makeNode(BoolExpr);
730
731
0
  expr->boolop = AND_EXPR;
732
0
  expr->args = andclauses;
733
0
  expr->location = -1;
734
0
  return (Expr *) expr;
735
0
}
736
737
/*
738
 * make_orclause
739
 *
740
 * Creates an 'or' clause given a list of its subclauses.
741
 */
742
Expr *
743
make_orclause(List *orclauses)
744
0
{
745
0
  BoolExpr   *expr = makeNode(BoolExpr);
746
747
0
  expr->boolop = OR_EXPR;
748
0
  expr->args = orclauses;
749
0
  expr->location = -1;
750
0
  return (Expr *) expr;
751
0
}
752
753
/*
754
 * make_notclause
755
 *
756
 * Create a 'not' clause given the expression to be negated.
757
 */
758
Expr *
759
make_notclause(Expr *notclause)
760
0
{
761
0
  BoolExpr   *expr = makeNode(BoolExpr);
762
763
0
  expr->boolop = NOT_EXPR;
764
0
  expr->args = list_make1(notclause);
765
0
  expr->location = -1;
766
0
  return (Expr *) expr;
767
0
}
768
769
/*
770
 * make_and_qual
771
 *
772
 * Variant of make_andclause for ANDing two qual conditions together.
773
 * Qual conditions have the property that a NULL nodetree is interpreted
774
 * as 'true'.
775
 *
776
 * NB: this makes no attempt to preserve AND/OR flatness; so it should not
777
 * be used on a qual that has already been run through prepqual.c.
778
 */
779
Node *
780
make_and_qual(Node *qual1, Node *qual2)
781
0
{
782
0
  if (qual1 == NULL)
783
0
    return qual2;
784
0
  if (qual2 == NULL)
785
0
    return qual1;
786
0
  return (Node *) make_andclause(list_make2(qual1, qual2));
787
0
}
788
789
/*
790
 * The planner and executor usually represent qualification expressions
791
 * as lists of boolean expressions with implicit AND semantics.
792
 *
793
 * These functions convert between an AND-semantics expression list and the
794
 * ordinary representation of a boolean expression.
795
 *
796
 * Note that an empty list is considered equivalent to TRUE.
797
 */
798
Expr *
799
make_ands_explicit(List *andclauses)
800
0
{
801
0
  if (andclauses == NIL)
802
0
    return (Expr *) makeBoolConst(true, false);
803
0
  else if (list_length(andclauses) == 1)
804
0
    return (Expr *) linitial(andclauses);
805
0
  else
806
0
    return make_andclause(andclauses);
807
0
}
808
809
List *
810
make_ands_implicit(Expr *clause)
811
0
{
812
  /*
813
   * NB: because the parser sets the qual field to NULL in a query that has
814
   * no WHERE clause, we must consider a NULL input clause as TRUE, even
815
   * though one might more reasonably think it FALSE.
816
   */
817
0
  if (clause == NULL)
818
0
    return NIL;       /* NULL -> NIL list == TRUE */
819
0
  else if (is_andclause(clause))
820
0
    return ((BoolExpr *) clause)->args;
821
0
  else if (IsA(clause, Const) &&
822
0
       !((Const *) clause)->constisnull &&
823
0
       DatumGetBool(((Const *) clause)->constvalue))
824
0
    return NIL;       /* constant TRUE input -> NIL list */
825
0
  else
826
0
    return list_make1(clause);
827
0
}
828
829
/*
830
 * makeIndexInfo
831
 *    create an IndexInfo node
832
 */
833
IndexInfo *
834
makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
835
        List *predicates, bool unique, bool nulls_not_distinct,
836
        bool isready, bool concurrent, bool summarizing,
837
        bool withoutoverlaps)
838
0
{
839
0
  IndexInfo  *n = makeNode(IndexInfo);
840
841
0
  n->ii_NumIndexAttrs = numattrs;
842
0
  n->ii_NumIndexKeyAttrs = numkeyattrs;
843
0
  Assert(n->ii_NumIndexKeyAttrs != 0);
844
0
  Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
845
0
  n->ii_Unique = unique;
846
0
  n->ii_NullsNotDistinct = nulls_not_distinct;
847
0
  n->ii_ReadyForInserts = isready;
848
0
  n->ii_CheckedUnchanged = false;
849
0
  n->ii_IndexUnchanged = false;
850
0
  n->ii_Concurrent = concurrent;
851
0
  n->ii_Summarizing = summarizing;
852
0
  n->ii_WithoutOverlaps = withoutoverlaps;
853
854
  /* summarizing indexes cannot contain non-key attributes */
855
0
  Assert(!summarizing || (numkeyattrs == numattrs));
856
857
  /* expressions */
858
0
  n->ii_Expressions = expressions;
859
0
  n->ii_ExpressionsState = NIL;
860
861
  /* predicates  */
862
0
  n->ii_Predicate = predicates;
863
0
  n->ii_PredicateState = NULL;
864
865
  /* exclusion constraints */
866
0
  n->ii_ExclusionOps = NULL;
867
0
  n->ii_ExclusionProcs = NULL;
868
0
  n->ii_ExclusionStrats = NULL;
869
870
  /* speculative inserts */
871
0
  n->ii_UniqueOps = NULL;
872
0
  n->ii_UniqueProcs = NULL;
873
0
  n->ii_UniqueStrats = NULL;
874
875
  /* initialize index-build state to default */
876
0
  n->ii_BrokenHotChain = false;
877
0
  n->ii_ParallelWorkers = 0;
878
879
  /* set up for possible use by index AM */
880
0
  n->ii_Am = amoid;
881
0
  n->ii_AmCache = NULL;
882
0
  n->ii_Context = CurrentMemoryContext;
883
884
0
  return n;
885
0
}
886
887
/*
888
 * makeGroupingSet
889
 *
890
 */
891
GroupingSet *
892
makeGroupingSet(GroupingSetKind kind, List *content, int location)
893
0
{
894
0
  GroupingSet *n = makeNode(GroupingSet);
895
896
0
  n->kind = kind;
897
0
  n->content = content;
898
0
  n->location = location;
899
0
  return n;
900
0
}
901
902
/*
903
 * makeVacuumRelation -
904
 *    create a VacuumRelation node
905
 */
906
VacuumRelation *
907
makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
908
0
{
909
0
  VacuumRelation *v = makeNode(VacuumRelation);
910
911
0
  v->relation = relation;
912
0
  v->oid = oid;
913
0
  v->va_cols = va_cols;
914
0
  return v;
915
0
}
916
917
/*
918
 * makeJsonFormat -
919
 *    creates a JsonFormat node
920
 */
921
JsonFormat *
922
makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
923
1.92k
{
924
1.92k
  JsonFormat *jf = makeNode(JsonFormat);
925
926
1.92k
  jf->format_type = type;
927
1.92k
  jf->encoding = encoding;
928
1.92k
  jf->location = location;
929
930
1.92k
  return jf;
931
1.92k
}
932
933
/*
934
 * makeJsonValueExpr -
935
 *    creates a JsonValueExpr node
936
 */
937
JsonValueExpr *
938
makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr,
939
          JsonFormat *format)
940
1.00k
{
941
1.00k
  JsonValueExpr *jve = makeNode(JsonValueExpr);
942
943
1.00k
  jve->raw_expr = raw_expr;
944
1.00k
  jve->formatted_expr = formatted_expr;
945
1.00k
  jve->format = format;
946
947
1.00k
  return jve;
948
1.00k
}
949
950
/*
951
 * makeJsonBehavior -
952
 *    creates a JsonBehavior node
953
 */
954
JsonBehavior *
955
makeJsonBehavior(JsonBehaviorType btype, Node *expr, int location)
956
0
{
957
0
  JsonBehavior *behavior = makeNode(JsonBehavior);
958
959
0
  behavior->btype = btype;
960
0
  behavior->expr = expr;
961
0
  behavior->location = location;
962
963
0
  return behavior;
964
0
}
965
966
/*
967
 * makeJsonTableDefaultPlan -
968
 *     creates a JsonTablePlanSpec node to represent a "default" JSON_TABLE plan
969
 *     with given join strategy
970
 */
971
Node *
972
makeJsonTableDefaultPlan(JsonTablePlanJoinType join_type, int location)
973
0
{
974
0
  JsonTablePlanSpec *n = makeNode(JsonTablePlanSpec);
975
976
0
  n->plan_type = JSTP_DEFAULT;
977
0
  n->join_type = join_type;
978
0
  n->location = location;
979
980
0
  return (Node *) n;
981
0
}
982
983
/*
984
 * makeJsonTableSimplePlan -
985
 *     creates a JsonTablePlanSpec node to represent a "simple" JSON_TABLE plan
986
 *     for given PATH
987
 */
988
Node *
989
makeJsonTableSimplePlan(char *pathname, int location)
990
0
{
991
0
  JsonTablePlanSpec *n = makeNode(JsonTablePlanSpec);
992
993
0
  n->plan_type = JSTP_SIMPLE;
994
0
  n->pathname = pathname;
995
0
  n->location = location;
996
997
0
  return (Node *) n;
998
0
}
999
1000
/*
1001
 * makeJsonTableJoinedPlan -
1002
 *     creates a JsonTablePlanSpec node to represent join between the given
1003
 *     pair of plans
1004
 */
1005
Node *
1006
makeJsonTableJoinedPlan(JsonTablePlanJoinType type, Node *plan1, Node *plan2,
1007
            int location)
1008
0
{
1009
0
  JsonTablePlanSpec *n = makeNode(JsonTablePlanSpec);
1010
1011
0
  n->plan_type = JSTP_JOINED;
1012
0
  n->join_type = type;
1013
0
  n->plan1 = castNode(JsonTablePlanSpec, plan1);
1014
0
  n->plan2 = castNode(JsonTablePlanSpec, plan2);
1015
0
  n->location = location;
1016
1017
0
  return (Node *) n;
1018
0
}
1019
1020
/*
1021
 * makeJsonKeyValue -
1022
 *    creates a JsonKeyValue node
1023
 */
1024
Node *
1025
makeJsonKeyValue(Node *key, Node *value)
1026
0
{
1027
0
  JsonKeyValue *n = makeNode(JsonKeyValue);
1028
1029
0
  n->key = (Expr *) key;
1030
0
  n->value = castNode(JsonValueExpr, value);
1031
1032
0
  return (Node *) n;
1033
0
}
1034
1035
/*
1036
 * makeJsonIsPredicate -
1037
 *    creates a JsonIsPredicate node
1038
 */
1039
Node *
1040
makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type,
1041
          bool unique_keys, Oid exprBaseType, int location)
1042
920
{
1043
920
  JsonIsPredicate *n = makeNode(JsonIsPredicate);
1044
1045
920
  Assert(expr != NULL);
1046
1047
920
  n->expr = expr;
1048
920
  n->format = format;
1049
920
  n->item_type = item_type;
1050
920
  n->unique_keys = unique_keys;
1051
920
  n->exprBaseType = exprBaseType;
1052
920
  n->location = location;
1053
1054
920
  return (Node *) n;
1055
920
}
1056
1057
/*
1058
 * makeJsonTablePathSpec -
1059
 *    Make JsonTablePathSpec node from given path string and name (if any)
1060
 */
1061
JsonTablePathSpec *
1062
makeJsonTablePathSpec(char *string, char *name, int string_location,
1063
            int name_location)
1064
0
{
1065
0
  JsonTablePathSpec *pathspec = makeNode(JsonTablePathSpec);
1066
1067
0
  Assert(string != NULL);
1068
0
  pathspec->string = makeStringConst(string, string_location);
1069
0
  if (name != NULL)
1070
0
    pathspec->name = pstrdup(name);
1071
1072
0
  pathspec->name_location = name_location;
1073
0
  pathspec->location = string_location;
1074
1075
0
  return pathspec;
1076
0
}
1077
1078
/*
1079
 * makeJsonTablePath -
1080
 *    Make JsonTablePath node for given path string and name
1081
 */
1082
JsonTablePath *
1083
makeJsonTablePath(Const *pathvalue, char *pathname)
1084
0
{
1085
0
  JsonTablePath *path = makeNode(JsonTablePath);
1086
1087
0
  Assert(IsA(pathvalue, Const));
1088
0
  path->value = pathvalue;
1089
0
  path->name = pathname;
1090
1091
0
  return path;
1092
0
}