Age Owner Branch data TLA Line data Source code
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-2025, 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 *
7116 tgl@sss.pgh.pa.us 30 :CBC 37843 : makeA_Expr(A_Expr_Kind kind, List *name,
31 : : Node *lexpr, Node *rexpr, int location)
32 : : {
8544 33 : 37843 : A_Expr *a = makeNode(A_Expr);
34 : :
8244 35 : 37843 : a->kind = kind;
8544 36 : 37843 : a->name = name;
37 : 37843 : a->lexpr = lexpr;
38 : 37843 : a->rexpr = rexpr;
7116 39 : 37843 : a->location = location;
8544 40 : 37843 : return a;
41 : : }
42 : :
43 : : /*
44 : : * makeSimpleA_Expr -
45 : : * As above, given a simple (unqualified) operator name
46 : : */
47 : : A_Expr *
5109 peter_e@gmx.net 48 : 279036 : makeSimpleA_Expr(A_Expr_Kind kind, char *name,
49 : : Node *lexpr, Node *rexpr, int location)
50 : : {
8544 tgl@sss.pgh.pa.us 51 : 279036 : A_Expr *a = makeNode(A_Expr);
52 : :
8244 53 : 279036 : a->kind = kind;
198 peter@eisentraut.org 54 : 279036 : a->name = list_make1(makeString(name));
8544 tgl@sss.pgh.pa.us 55 : 279036 : a->lexpr = lexpr;
56 : 279036 : a->rexpr = rexpr;
7116 57 : 279036 : a->location = location;
8544 58 : 279036 : return a;
59 : : }
60 : :
61 : : /*
62 : : * makeVar -
63 : : * creates a Var node
64 : : */
65 : : Var *
1452 66 : 5113770 : makeVar(int varno,
67 : : AttrNumber varattno,
68 : : Oid vartype,
69 : : int32 vartypmod,
70 : : Oid varcollid,
71 : : Index varlevelsup)
72 : : {
10225 bruce@momjian.us 73 : 5113770 : Var *var = makeNode(Var);
74 : :
10226 75 : 5113770 : var->varno = varno;
76 : 5113770 : var->varattno = varattno;
77 : 5113770 : var->vartype = vartype;
10070 78 : 5113770 : var->vartypmod = vartypmod;
5324 peter_e@gmx.net 79 : 5113770 : var->varcollid = varcollid;
10091 bruce@momjian.us 80 : 5113770 : 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 : : */
233 dean.a.rasheed@gmail 90 : 5113770 : var->varreturningtype = VAR_RETURNING_DEFAULT;
950 tgl@sss.pgh.pa.us 91 : 5113770 : var->varnullingrels = NULL;
1452 92 : 5113770 : var->varnosyn = (Index) varno;
2067 93 : 5113770 : var->varattnosyn = varattno;
94 : :
95 : : /* Likewise, we just set location to "unknown" here */
6218 96 : 5113770 : var->location = -1;
97 : :
10226 bruce@momjian.us 98 : 5113770 : return var;
99 : : }
100 : :
101 : : /*
102 : : * makeVarFromTargetEntry -
103 : : * convenience function to create a same-level Var node from a
104 : : * TargetEntry
105 : : */
106 : : Var *
1452 tgl@sss.pgh.pa.us 107 : 41532 : makeVarFromTargetEntry(int varno,
108 : : TargetEntry *tle)
109 : : {
5489 peter_e@gmx.net 110 : 207660 : return makeVar(varno,
111 : 41532 : tle->resno,
112 : 41532 : exprType((Node *) tle->expr),
113 : 41532 : exprTypmod((Node *) tle->expr),
5324 114 : 41532 : exprCollation((Node *) tle->expr),
115 : : 0);
116 : : }
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 *
5436 tgl@sss.pgh.pa.us 137 : 5061 : makeWholeRowVar(RangeTblEntry *rte,
138 : : int varno,
139 : : Index varlevelsup,
140 : : bool allowScalar)
141 : : {
142 : : Var *result;
143 : : Oid toid;
144 : : Node *fexpr;
145 : :
146 [ + + + + ]: 5061 : switch (rte->rtekind)
147 : : {
148 : 4288 : case RTE_RELATION:
149 : : /* relation: the rowtype is a named composite type */
150 : 4288 : toid = get_rel_type_id(rte->relid);
151 [ - + ]: 4288 : if (!OidIsValid(toid))
1887 tgl@sss.pgh.pa.us 152 [ # # ]:UBC 0 : ereport(ERROR,
153 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
154 : : errmsg("relation \"%s\" does not have a composite type",
155 : : get_rel_name(rte->relid))));
5436 tgl@sss.pgh.pa.us 156 :CBC 4288 : result = makeVar(varno,
157 : : InvalidAttrNumber,
158 : : toid,
159 : : -1,
160 : : InvalidOid,
161 : : varlevelsup);
162 : 4288 : break;
163 : :
178 164 : 312 : 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 [ + + ]: 312 : if (OidIsValid(rte->relid))
174 : : {
175 : : /* Subquery was expanded from a view */
176 : 60 : toid = get_rel_type_id(rte->relid);
177 [ - + ]: 60 : if (!OidIsValid(toid))
178 tgl@sss.pgh.pa.us 178 [ # # ]:UBC 0 : ereport(ERROR,
179 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
180 : : errmsg("relation \"%s\" does not have a composite type",
181 : : get_rel_name(rte->relid))));
182 : : }
178 tgl@sss.pgh.pa.us 183 [ + + ]:CBC 252 : else if (rte->functions)
184 : : {
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 [ - + ]: 6 : Assert(!allowScalar);
193 : 6 : fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
194 : 6 : toid = exprType(fexpr);
195 [ - + ]: 6 : if (!type_is_rowtype(toid))
178 tgl@sss.pgh.pa.us 196 :UBC 0 : toid = RECORDOID;
197 : : }
198 : : else
199 : : {
200 : : /* Normal subquery-in-FROM */
178 tgl@sss.pgh.pa.us 201 :CBC 246 : toid = RECORDOID;
202 : : }
203 : 312 : result = makeVar(varno,
204 : : InvalidAttrNumber,
205 : : toid,
206 : : -1,
207 : : InvalidOid,
208 : : varlevelsup);
209 : 312 : break;
210 : :
5436 211 : 92 : 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 : : */
4307 218 [ + + - + ]: 92 : if (rte->funcordinality || list_length(rte->functions) != 1)
219 : : {
220 : : /* always produces an anonymous RECORD result */
4422 stark@mit.edu 221 : 3 : result = makeVar(varno,
222 : : InvalidAttrNumber,
223 : : RECORDOID,
224 : : -1,
225 : : InvalidOid,
226 : : varlevelsup);
4307 tgl@sss.pgh.pa.us 227 : 3 : break;
228 : : }
229 : :
230 : 89 : fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
231 : 89 : toid = exprType(fexpr);
232 [ + + ]: 89 : if (type_is_rowtype(toid))
233 : : {
234 : : /* func returns composite; same as relation case */
5436 235 : 37 : result = makeVar(varno,
236 : : InvalidAttrNumber,
237 : : toid,
238 : : -1,
239 : : InvalidOid,
240 : : varlevelsup);
241 : : }
5032 242 [ + + ]: 52 : else if (allowScalar)
243 : : {
244 : : /* func returns scalar; just return its output as-is */
5436 245 : 12 : result = makeVar(varno,
246 : : 1,
247 : : toid,
248 : : -1,
249 : : exprCollation(fexpr),
250 : : varlevelsup);
251 : : }
252 : : else
253 : : {
254 : : /* func returns scalar, but we want a composite result */
5032 255 : 40 : result = makeVar(varno,
256 : : InvalidAttrNumber,
257 : : RECORDOID,
258 : : -1,
259 : : InvalidOid,
260 : : varlevelsup);
261 : : }
5436 262 : 89 : break;
263 : :
4422 stark@mit.edu 264 : 369 : 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 : : */
5436 tgl@sss.pgh.pa.us 272 : 369 : result = makeVar(varno,
273 : : InvalidAttrNumber,
274 : : RECORDOID,
275 : : -1,
276 : : InvalidOid,
277 : : varlevelsup);
278 : 369 : break;
279 : : }
280 : :
281 : 5061 : return result;
282 : : }
283 : :
284 : : /*
285 : : * makeTargetEntry -
286 : : * creates a TargetEntry node
287 : : */
288 : : TargetEntry *
7458 289 : 4186740 : makeTargetEntry(Expr *expr,
290 : : AttrNumber resno,
291 : : char *resname,
292 : : bool resjunk)
293 : : {
294 : 4186740 : TargetEntry *tle = makeNode(TargetEntry);
295 : :
296 : 4186740 : tle->expr = expr;
297 : 4186740 : tle->resno = resno;
298 : 4186740 : 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 : 4186740 : tle->ressortgroupref = 0;
306 : 4186740 : tle->resorigtbl = InvalidOid;
307 : 4186740 : tle->resorigcol = 0;
308 : :
309 : 4186740 : tle->resjunk = resjunk;
310 : :
311 : 4186740 : return tle;
312 : : }
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 : 317361 : flatCopyTargetEntry(TargetEntry *src_tle)
323 : : {
324 : 317361 : TargetEntry *tle = makeNode(TargetEntry);
325 : :
326 [ - + ]: 317361 : Assert(IsA(src_tle, TargetEntry));
327 : 317361 : memcpy(tle, src_tle, sizeof(TargetEntry));
328 : 317361 : return tle;
329 : : }
330 : :
331 : : /*
332 : : * makeFromExpr -
333 : : * creates a FromExpr node
334 : : */
335 : : FromExpr *
6650 336 : 306467 : makeFromExpr(List *fromlist, Node *quals)
337 : : {
338 : 306467 : FromExpr *f = makeNode(FromExpr);
339 : :
340 : 306467 : f->fromlist = fromlist;
341 : 306467 : f->quals = quals;
342 : 306467 : return f;
343 : : }
344 : :
345 : : /*
346 : : * makeConst -
347 : : * creates a Const node
348 : : */
349 : : Const *
10651 scrappy@hub.org 350 : 1346317 : makeConst(Oid consttype,
351 : : int32 consttypmod,
352 : : Oid constcollid,
353 : : int constlen,
354 : : Datum constvalue,
355 : : bool constisnull,
356 : : bool constbyval)
357 : : {
10225 bruce@momjian.us 358 : 1346317 : 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 : : */
3516 tgl@sss.pgh.pa.us 365 [ + + + + ]: 1346317 : if (!constisnull && constlen == -1)
366 : 72929 : constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
367 : :
10226 bruce@momjian.us 368 : 1346317 : cnst->consttype = consttype;
6748 tgl@sss.pgh.pa.us 369 : 1346317 : cnst->consttypmod = consttypmod;
5279 370 : 1346317 : cnst->constcollid = constcollid;
10226 bruce@momjian.us 371 : 1346317 : cnst->constlen = constlen;
372 : 1346317 : cnst->constvalue = constvalue;
373 : 1346317 : cnst->constisnull = constisnull;
374 : 1346317 : cnst->constbyval = constbyval;
6218 tgl@sss.pgh.pa.us 375 : 1346317 : cnst->location = -1; /* "unknown" */
376 : :
10226 bruce@momjian.us 377 : 1346317 : return cnst;
378 : : }
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 *
5279 tgl@sss.pgh.pa.us 388 : 4654 : makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
389 : : {
390 : : int16 typLen;
391 : : bool typByVal;
392 : :
9060 393 : 4654 : get_typlenbyval(consttype, &typLen, &typByVal);
394 : 4654 : return makeConst(consttype,
395 : : consttypmod,
396 : : constcollid,
397 : : (int) typLen,
398 : : (Datum) 0,
399 : : true,
400 : : typByVal);
401 : : }
402 : :
403 : : /*
404 : : * makeBoolConst -
405 : : * creates a Const node representing a boolean value (can be NULL too)
406 : : */
407 : : Node *
7789 408 : 4248 : makeBoolConst(bool value, bool isnull)
409 : : {
410 : : /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
5279 411 : 4248 : return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
412 : : BoolGetDatum(value), isnull, true);
413 : : }
414 : :
415 : : /*
416 : : * makeBoolExpr -
417 : : * creates a BoolExpr node
418 : : */
419 : : Expr *
6218 420 : 155759 : makeBoolExpr(BoolExprType boolop, List *args, int location)
421 : : {
8304 422 : 155759 : BoolExpr *b = makeNode(BoolExpr);
423 : :
424 : 155759 : b->boolop = boolop;
425 : 155759 : b->args = args;
6218 426 : 155759 : b->location = location;
427 : :
8304 428 : 155759 : return (Expr *) b;
429 : : }
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 *
8570 438 : 530551 : makeAlias(const char *aliasname, List *colnames)
439 : : {
440 : 530551 : Alias *a = makeNode(Alias);
441 : :
442 : 530551 : a->aliasname = pstrdup(aliasname);
443 : 530551 : a->colnames = colnames;
444 : :
9335 lockhart@fourpalms.o 445 : 530551 : return a;
446 : : }
447 : :
448 : : /*
449 : : * makeRelabelType -
450 : : * creates a RelabelType node
451 : : */
452 : : RelabelType *
5285 tgl@sss.pgh.pa.us 453 : 79295 : makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
454 : : CoercionForm rformat)
455 : : {
8571 456 : 79295 : RelabelType *r = makeNode(RelabelType);
457 : :
458 : 79295 : r->arg = arg;
459 : 79295 : r->resulttype = rtype;
460 : 79295 : r->resulttypmod = rtypmod;
5285 461 : 79295 : r->resultcollid = rcollid;
8389 462 : 79295 : r->relabelformat = rformat;
6218 463 : 79295 : r->location = -1;
464 : :
8571 465 : 79295 : return r;
466 : : }
467 : :
468 : : /*
469 : : * makeRangeVar -
470 : : * creates a RangeVar node (rather oversimplified case)
471 : : */
472 : : RangeVar *
6214 473 : 386255 : makeRangeVar(char *schemaname, char *relname, int location)
474 : : {
8403 bruce@momjian.us 475 : 386255 : RangeVar *r = makeNode(RangeVar);
476 : :
8569 tgl@sss.pgh.pa.us 477 : 386255 : r->catalogname = NULL;
478 : 386255 : r->schemaname = schemaname;
479 : 386255 : r->relname = relname;
3179 480 : 386255 : r->inh = true;
5381 rhaas@postgresql.org 481 : 386255 : r->relpersistence = RELPERSISTENCE_PERMANENT;
8569 tgl@sss.pgh.pa.us 482 : 386255 : r->alias = NULL;
6214 483 : 386255 : r->location = location;
484 : :
8569 485 : 386255 : return r;
486 : : }
487 : :
488 : : /*
489 : : * makeNotNullConstraint -
490 : : * creates a Constraint node for NOT NULL constraints
491 : : */
492 : : Constraint *
302 alvherre@alvh.no-ip. 493 : 7879 : makeNotNullConstraint(String *colname)
494 : : {
495 : : Constraint *notnull;
496 : :
497 : 7879 : notnull = makeNode(Constraint);
498 : 7879 : notnull->contype = CONSTR_NOTNULL;
499 : 7879 : notnull->conname = NULL;
500 : 7879 : notnull->is_no_inherit = false;
501 : 7879 : notnull->deferrable = false;
502 : 7879 : notnull->initdeferred = false;
503 : 7879 : notnull->location = -1;
504 : 7879 : notnull->keys = list_make1(colname);
238 peter@eisentraut.org 505 : 7879 : notnull->is_enforced = true;
302 alvherre@alvh.no-ip. 506 : 7879 : notnull->skip_validation = false;
507 : 7879 : notnull->initially_valid = true;
508 : :
509 : 7879 : return notnull;
510 : : }
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 *
8562 tgl@sss.pgh.pa.us 519 : 145301 : makeTypeName(char *typnam)
520 : : {
6825 521 : 145301 : return makeTypeNameFromNameList(list_make1(makeString(typnam)));
522 : : }
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 *
7116 531 : 303169 : makeTypeNameFromNameList(List *names)
532 : : {
533 : 303169 : TypeName *n = makeNode(TypeName);
534 : :
535 : 303169 : n->names = names;
6825 536 : 303169 : n->typmods = NIL;
537 : 303169 : n->typemod = -1;
7116 538 : 303169 : n->location = -1;
539 : 303169 : return n;
540 : : }
541 : :
542 : : /*
543 : : * makeTypeNameFromOid -
544 : : * build a TypeName node to represent a type already known by OID/typmod.
545 : : */
546 : : TypeName *
5295 547 : 94876 : makeTypeNameFromOid(Oid typeOid, int32 typmod)
548 : : {
7116 549 : 94876 : TypeName *n = makeNode(TypeName);
550 : :
5896 peter_e@gmx.net 551 : 94876 : n->typeOid = typeOid;
6825 tgl@sss.pgh.pa.us 552 : 94876 : n->typemod = typmod;
7116 553 : 94876 : n->location = -1;
8562 554 : 94876 : return n;
555 : : }
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 *
3358 565 : 94225 : makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
566 : : {
567 : 94225 : ColumnDef *n = makeNode(ColumnDef);
568 : :
569 : 94225 : n->colname = pstrdup(colname);
570 : 94225 : n->typeName = makeTypeNameFromOid(typeOid, typmod);
571 : 94225 : n->inhcount = 0;
572 : 94225 : n->is_local = true;
573 : 94225 : n->is_not_null = false;
574 : 94225 : n->is_from_type = false;
564 peter@eisentraut.org 575 : 94225 : n->storage = 0;
3358 tgl@sss.pgh.pa.us 576 : 94225 : n->raw_default = NULL;
577 : 94225 : n->cooked_default = NULL;
578 : 94225 : n->collClause = NULL;
579 : 94225 : n->collOid = collOid;
580 : 94225 : n->constraints = NIL;
581 : 94225 : n->fdwoptions = NIL;
582 : 94225 : n->location = -1;
583 : :
584 : 94225 : return n;
585 : : }
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 *
5285 594 : 79659 : makeFuncExpr(Oid funcid, Oid rettype, List *args,
595 : : Oid funccollid, Oid inputcollid, CoercionForm fformat)
596 : : {
597 : : FuncExpr *funcexpr;
598 : :
8103 599 : 79659 : funcexpr = makeNode(FuncExpr);
600 : 79659 : funcexpr->funcid = funcid;
601 : 79659 : funcexpr->funcresulttype = rettype;
2999 602 : 79659 : funcexpr->funcretset = false; /* only allowed case here */
603 : 79659 : funcexpr->funcvariadic = false; /* only allowed case here */
8103 604 : 79659 : funcexpr->funcformat = fformat;
5285 605 : 79659 : funcexpr->funccollid = funccollid;
606 : 79659 : funcexpr->inputcollid = inputcollid;
8103 607 : 79659 : funcexpr->args = args;
6218 608 : 79659 : funcexpr->location = -1;
609 : :
8103 610 : 79659 : return funcexpr;
611 : : }
612 : :
613 : : /*
614 : : * makeStringConst -
615 : : * build a A_Const node of type T_String for given string
616 : : */
617 : : Node *
520 amitlan@postgresql.o 618 : 369929 : makeStringConst(char *str, int location)
619 : : {
620 : 369929 : A_Const *n = makeNode(A_Const);
621 : :
622 : 369929 : n->val.sval.type = T_String;
623 : 369929 : n->val.sval.sval = str;
624 : 369929 : n->location = location;
625 : :
626 : 369929 : return (Node *) n;
627 : : }
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 *
3287 peter_e@gmx.net 637 : 122957 : makeDefElem(char *name, Node *arg, int location)
638 : : {
6912 bruce@momjian.us 639 : 122957 : DefElem *res = makeNode(DefElem);
640 : :
5999 tgl@sss.pgh.pa.us 641 : 122957 : res->defnamespace = NULL;
6956 642 : 122957 : res->defname = name;
643 : 122957 : res->arg = arg;
5999 644 : 122957 : res->defaction = DEFELEM_UNSPEC;
3287 peter_e@gmx.net 645 : 122957 : res->location = location;
646 : :
6956 tgl@sss.pgh.pa.us 647 : 122957 : return res;
648 : : }
649 : :
650 : : /*
651 : : * makeDefElemExtended -
652 : : * build a DefElem node with all fields available to be specified
653 : : */
654 : : DefElem *
5896 peter_e@gmx.net 655 : 98 : makeDefElemExtended(char *nameSpace, char *name, Node *arg,
656 : : DefElemAction defaction, int location)
657 : : {
5999 tgl@sss.pgh.pa.us 658 : 98 : DefElem *res = makeNode(DefElem);
659 : :
5896 peter_e@gmx.net 660 : 98 : res->defnamespace = nameSpace;
5999 tgl@sss.pgh.pa.us 661 : 98 : res->defname = name;
6060 alvherre@alvh.no-ip. 662 : 98 : res->arg = arg;
5999 tgl@sss.pgh.pa.us 663 : 98 : res->defaction = defaction;
3287 peter_e@gmx.net 664 : 98 : res->location = location;
665 : :
6060 alvherre@alvh.no-ip. 666 : 98 : return res;
667 : : }
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 *
1767 tgl@sss.pgh.pa.us 676 : 183974 : makeFuncCall(List *name, List *args, CoercionForm funcformat, int location)
677 : : {
4307 678 : 183974 : FuncCall *n = makeNode(FuncCall);
679 : :
4450 rhaas@postgresql.org 680 : 183974 : n->funcname = name;
681 : 183974 : n->args = args;
682 : 183974 : n->agg_order = NIL;
4435 noah@leadboat.com 683 : 183974 : n->agg_filter = NULL;
1767 tgl@sss.pgh.pa.us 684 : 183974 : n->over = NULL;
4275 685 : 183974 : n->agg_within_group = false;
686 : 183974 : n->agg_star = false;
687 : 183974 : n->agg_distinct = false;
688 : 183974 : n->func_variadic = false;
1767 689 : 183974 : n->funcformat = funcformat;
4307 690 : 183974 : n->location = location;
4450 rhaas@postgresql.org 691 : 183974 : return n;
692 : : }
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 *
2412 tgl@sss.pgh.pa.us 701 : 76073 : make_opclause(Oid opno, Oid opresulttype, bool opretset,
702 : : Expr *leftop, Expr *rightop,
703 : : Oid opcollid, Oid inputcollid)
704 : : {
705 : 76073 : OpExpr *expr = makeNode(OpExpr);
706 : :
707 : 76073 : expr->opno = opno;
708 : 76073 : expr->opfuncid = InvalidOid;
709 : 76073 : expr->opresulttype = opresulttype;
710 : 76073 : expr->opretset = opretset;
711 : 76073 : expr->opcollid = opcollid;
712 : 76073 : expr->inputcollid = inputcollid;
713 [ + - ]: 76073 : if (rightop)
714 : 76073 : expr->args = list_make2(leftop, rightop);
715 : : else
2412 tgl@sss.pgh.pa.us 716 :UBC 0 : expr->args = list_make1(leftop);
2412 tgl@sss.pgh.pa.us 717 :CBC 76073 : expr->location = -1;
718 : 76073 : return (Expr *) expr;
719 : : }
720 : :
721 : : /*
722 : : * make_andclause
723 : : *
724 : : * Creates an 'and' clause given a list of its subclauses.
725 : : */
726 : : Expr *
727 : 157560 : make_andclause(List *andclauses)
728 : : {
729 : 157560 : BoolExpr *expr = makeNode(BoolExpr);
730 : :
731 : 157560 : expr->boolop = AND_EXPR;
732 : 157560 : expr->args = andclauses;
733 : 157560 : expr->location = -1;
734 : 157560 : return (Expr *) expr;
735 : : }
736 : :
737 : : /*
738 : : * make_orclause
739 : : *
740 : : * Creates an 'or' clause given a list of its subclauses.
741 : : */
742 : : Expr *
743 : 19551 : make_orclause(List *orclauses)
744 : : {
745 : 19551 : BoolExpr *expr = makeNode(BoolExpr);
746 : :
747 : 19551 : expr->boolop = OR_EXPR;
748 : 19551 : expr->args = orclauses;
749 : 19551 : expr->location = -1;
750 : 19551 : return (Expr *) expr;
751 : : }
752 : :
753 : : /*
754 : : * make_notclause
755 : : *
756 : : * Create a 'not' clause given the expression to be negated.
757 : : */
758 : : Expr *
759 : 6536 : make_notclause(Expr *notclause)
760 : : {
761 : 6536 : BoolExpr *expr = makeNode(BoolExpr);
762 : :
763 : 6536 : expr->boolop = NOT_EXPR;
764 : 6536 : expr->args = list_make1(notclause);
765 : 6536 : expr->location = -1;
766 : 6536 : return (Expr *) expr;
767 : : }
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 : 2134 : make_and_qual(Node *qual1, Node *qual2)
781 : : {
782 [ + + ]: 2134 : if (qual1 == NULL)
783 : 846 : return qual2;
784 [ - + ]: 1288 : if (qual2 == NULL)
2412 tgl@sss.pgh.pa.us 785 :UBC 0 : return qual1;
2412 tgl@sss.pgh.pa.us 786 :CBC 1288 : return (Node *) make_andclause(list_make2(qual1, qual2));
787 : : }
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 : 26805 : make_ands_explicit(List *andclauses)
800 : : {
801 [ - + ]: 26805 : if (andclauses == NIL)
2412 tgl@sss.pgh.pa.us 802 :UBC 0 : return (Expr *) makeBoolConst(true, false);
2412 tgl@sss.pgh.pa.us 803 [ + + ]:CBC 26805 : else if (list_length(andclauses) == 1)
804 : 19450 : return (Expr *) linitial(andclauses);
805 : : else
806 : 7355 : return make_andclause(andclauses);
807 : : }
808 : :
809 : : List *
810 : 216170 : make_ands_implicit(Expr *clause)
811 : : {
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 [ + + ]: 216170 : if (clause == NULL)
818 : 35652 : return NIL; /* NULL -> NIL list == TRUE */
819 [ + + ]: 180518 : else if (is_andclause(clause))
820 : 60559 : return ((BoolExpr *) clause)->args;
821 [ + + ]: 119959 : else if (IsA(clause, Const) &&
822 [ + + + + ]: 3247 : !((Const *) clause)->constisnull &&
823 : 1565 : DatumGetBool(((Const *) clause)->constvalue))
824 : 988 : return NIL; /* constant TRUE input -> NIL list */
825 : : else
826 : 118971 : return list_make1(clause);
827 : : }
828 : :
829 : : /*
830 : : * makeIndexInfo
831 : : * create an IndexInfo node
832 : : */
833 : : IndexInfo *
2231 michael@paquier.xyz 834 : 1795188 : 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 : : {
839 : 1795188 : IndexInfo *n = makeNode(IndexInfo);
840 : :
841 : 1795188 : n->ii_NumIndexAttrs = numattrs;
842 : 1795188 : n->ii_NumIndexKeyAttrs = numkeyattrs;
843 [ - + ]: 1795188 : Assert(n->ii_NumIndexKeyAttrs != 0);
844 [ - + ]: 1795188 : Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
845 : 1795188 : n->ii_Unique = unique;
1311 peter@eisentraut.org 846 : 1795188 : n->ii_NullsNotDistinct = nulls_not_distinct;
2231 michael@paquier.xyz 847 : 1795188 : n->ii_ReadyForInserts = isready;
1333 pg@bowt.ie 848 : 1795188 : n->ii_CheckedUnchanged = false;
849 : 1795188 : n->ii_IndexUnchanged = false;
2231 michael@paquier.xyz 850 : 1795188 : n->ii_Concurrent = concurrent;
901 tomas.vondra@postgre 851 : 1795188 : n->ii_Summarizing = summarizing;
354 peter@eisentraut.org 852 : 1795188 : n->ii_WithoutOverlaps = withoutoverlaps;
853 : :
854 : : /* summarizing indexes cannot contain non-key attributes */
901 tomas.vondra@postgre 855 [ + + - + ]: 1795188 : Assert(!summarizing || (numkeyattrs == numattrs));
856 : :
857 : : /* expressions */
2231 michael@paquier.xyz 858 : 1795188 : n->ii_Expressions = expressions;
859 : 1795188 : n->ii_ExpressionsState = NIL;
860 : :
861 : : /* predicates */
862 : 1795188 : n->ii_Predicate = predicates;
863 : 1795188 : n->ii_PredicateState = NULL;
864 : :
865 : : /* exclusion constraints */
866 : 1795188 : n->ii_ExclusionOps = NULL;
867 : 1795188 : n->ii_ExclusionProcs = NULL;
868 : 1795188 : n->ii_ExclusionStrats = NULL;
869 : :
870 : : /* speculative inserts */
871 : 1795188 : n->ii_UniqueOps = NULL;
872 : 1795188 : n->ii_UniqueProcs = NULL;
873 : 1795188 : n->ii_UniqueStrats = NULL;
874 : :
875 : : /* initialize index-build state to default */
876 : 1795188 : n->ii_BrokenHotChain = false;
877 : 1795188 : n->ii_ParallelWorkers = 0;
878 : :
879 : : /* set up for possible use by index AM */
880 : 1795188 : n->ii_Am = amoid;
881 : 1795188 : n->ii_AmCache = NULL;
882 : 1795188 : n->ii_Context = CurrentMemoryContext;
883 : :
884 : 1795188 : return n;
885 : : }
886 : :
887 : : /*
888 : : * makeGroupingSet
889 : : *
890 : : */
891 : : GroupingSet *
3766 andres@anarazel.de 892 : 2741 : makeGroupingSet(GroupingSetKind kind, List *content, int location)
893 : : {
3759 bruce@momjian.us 894 : 2741 : GroupingSet *n = makeNode(GroupingSet);
895 : :
3766 andres@anarazel.de 896 : 2741 : n->kind = kind;
897 : 2741 : n->content = content;
898 : 2741 : n->location = location;
899 : 2741 : return n;
900 : : }
901 : :
902 : : /*
903 : : * makeVacuumRelation -
904 : : * create a VacuumRelation node
905 : : */
906 : : VacuumRelation *
2895 tgl@sss.pgh.pa.us 907 : 22131 : makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
908 : : {
909 : 22131 : VacuumRelation *v = makeNode(VacuumRelation);
910 : :
911 : 22131 : v->relation = relation;
912 : 22131 : v->oid = oid;
913 : 22131 : v->va_cols = va_cols;
914 : 22131 : return v;
915 : : }
916 : :
917 : : /*
918 : : * makeJsonFormat -
919 : : * creates a JsonFormat node
920 : : */
921 : : JsonFormat *
892 alvherre@alvh.no-ip. 922 : 4964 : makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
923 : : {
924 : 4964 : JsonFormat *jf = makeNode(JsonFormat);
925 : :
926 : 4964 : jf->format_type = type;
927 : 4964 : jf->encoding = encoding;
928 : 4964 : jf->location = location;
929 : :
930 : 4964 : return jf;
931 : : }
932 : :
933 : : /*
934 : : * makeJsonValueExpr -
935 : : * creates a JsonValueExpr node
936 : : */
937 : : JsonValueExpr *
778 amitlan@postgresql.o 938 : 2689 : makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr,
939 : : JsonFormat *format)
940 : : {
892 alvherre@alvh.no-ip. 941 : 2689 : JsonValueExpr *jve = makeNode(JsonValueExpr);
942 : :
778 amitlan@postgresql.o 943 : 2689 : jve->raw_expr = raw_expr;
944 : 2689 : jve->formatted_expr = formatted_expr;
892 alvherre@alvh.no-ip. 945 : 2689 : jve->format = format;
946 : :
947 : 2689 : return jve;
948 : : }
949 : :
950 : : /*
951 : : * makeJsonBehavior -
952 : : * creates a JsonBehavior node
953 : : */
954 : : JsonBehavior *
534 amitlan@postgresql.o 955 : 2667 : makeJsonBehavior(JsonBehaviorType btype, Node *expr, int location)
956 : : {
957 : 2667 : JsonBehavior *behavior = makeNode(JsonBehavior);
958 : :
959 : 2667 : behavior->btype = btype;
960 : 2667 : behavior->expr = expr;
961 : 2667 : behavior->location = location;
962 : :
963 : 2667 : return behavior;
964 : : }
965 : :
966 : : /*
967 : : * makeJsonKeyValue -
968 : : * creates a JsonKeyValue node
969 : : */
970 : : Node *
892 alvherre@alvh.no-ip. 971 : 397 : makeJsonKeyValue(Node *key, Node *value)
972 : : {
973 : 397 : JsonKeyValue *n = makeNode(JsonKeyValue);
974 : :
975 : 397 : n->key = (Expr *) key;
976 : 397 : n->value = castNode(JsonValueExpr, value);
977 : :
978 : 397 : return (Node *) n;
979 : : }
980 : :
981 : : /*
982 : : * makeJsonIsPredicate -
983 : : * creates a JsonIsPredicate node
984 : : */
985 : : Node *
890 986 : 331 : makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type,
987 : : bool unique_keys, int location)
988 : : {
989 : 331 : JsonIsPredicate *n = makeNode(JsonIsPredicate);
990 : :
991 : 331 : n->expr = expr;
992 : 331 : n->format = format;
993 : 331 : n->item_type = item_type;
994 : 331 : n->unique_keys = unique_keys;
995 : 331 : n->location = location;
996 : :
997 : 331 : return (Node *) n;
998 : : }
999 : :
1000 : : /*
1001 : : * makeJsonTablePathSpec -
1002 : : * Make JsonTablePathSpec node from given path string and name (if any)
1003 : : */
1004 : : JsonTablePathSpec *
520 amitlan@postgresql.o 1005 : 820 : makeJsonTablePathSpec(char *string, char *name, int string_location,
1006 : : int name_location)
1007 : : {
1008 : 820 : JsonTablePathSpec *pathspec = makeNode(JsonTablePathSpec);
1009 : :
1010 [ - + ]: 820 : Assert(string != NULL);
1011 : 820 : pathspec->string = makeStringConst(string, string_location);
1012 [ + + ]: 820 : if (name != NULL)
1013 : 100 : pathspec->name = pstrdup(name);
1014 : :
1015 : 820 : pathspec->name_location = name_location;
1016 : 820 : pathspec->location = string_location;
1017 : :
1018 : 820 : return pathspec;
1019 : : }
1020 : :
1021 : : /*
1022 : : * makeJsonTablePath -
1023 : : * Make JsonTablePath node for given path string and name
1024 : : */
1025 : : JsonTablePath *
1026 : 349 : makeJsonTablePath(Const *pathvalue, char *pathname)
1027 : : {
1028 : 349 : JsonTablePath *path = makeNode(JsonTablePath);
1029 : :
1030 [ - + ]: 349 : Assert(IsA(pathvalue, Const));
1031 : 349 : path->value = pathvalue;
1032 : 349 : path->name = pathname;
1033 : :
1034 : 349 : return path;
1035 : : }
|