1 /*-------------------------------------------------------------------------
2 *
3 * makefuncs.c
4 * creator functions for primitive nodes. The functions here are for
5 * the most frequently created nodes.
6 *
7 * Portions Copyright (c) 1996-2018, 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 "fmgr.h"
21 #include "nodes/makefuncs.h"
22 #include "nodes/nodeFuncs.h"
23 #include "utils/lsyscache.h"
24
25
26 /*
27 * makeA_Expr -
28 * makes an A_Expr node
29 */
30 A_Expr *
makeA_Expr(A_Expr_Kind kind,List * name,Node * lexpr,Node * rexpr,int location)31 makeA_Expr(A_Expr_Kind kind, List *name,
32 Node *lexpr, Node *rexpr, int location)
33 {
34 A_Expr *a = makeNode(A_Expr);
35
36 a->kind = kind;
37 a->name = name;
38 a->lexpr = lexpr;
39 a->rexpr = rexpr;
40 a->location = location;
41 return a;
42 }
43
44 /*
45 * makeSimpleA_Expr -
46 * As above, given a simple (unqualified) operator name
47 */
48 A_Expr *
makeSimpleA_Expr(A_Expr_Kind kind,char * name,Node * lexpr,Node * rexpr,int location)49 makeSimpleA_Expr(A_Expr_Kind kind, char *name,
50 Node *lexpr, Node *rexpr, int location)
51 {
52 A_Expr *a = makeNode(A_Expr);
53
54 a->kind = kind;
55 a->name = list_make1(makeString((char *) name));
56 a->lexpr = lexpr;
57 a->rexpr = rexpr;
58 a->location = location;
59 return a;
60 }
61
62 /*
63 * makeVar -
64 * creates a Var node
65 */
66 Var *
makeVar(Index varno,AttrNumber varattno,Oid vartype,int32 vartypmod,Oid varcollid,Index varlevelsup)67 makeVar(Index varno,
68 AttrNumber varattno,
69 Oid vartype,
70 int32 vartypmod,
71 Oid varcollid,
72 Index varlevelsup)
73 {
74 Var *var = makeNode(Var);
75
76 var->varno = varno;
77 var->varattno = varattno;
78 var->vartype = vartype;
79 var->vartypmod = vartypmod;
80 var->varcollid = varcollid;
81 var->varlevelsup = varlevelsup;
82
83 /*
84 * Since few if any routines ever create Var nodes with varnoold/varoattno
85 * different from varno/varattno, we don't provide separate arguments for
86 * them, but just initialize them to the given varno/varattno. This
87 * reduces code clutter and chance of error for most callers.
88 */
89 var->varnoold = varno;
90 var->varoattno = varattno;
91
92 /* Likewise, we just set location to "unknown" here */
93 var->location = -1;
94
95 return var;
96 }
97
98 /*
99 * makeVarFromTargetEntry -
100 * convenience function to create a same-level Var node from a
101 * TargetEntry
102 */
103 Var *
makeVarFromTargetEntry(Index varno,TargetEntry * tle)104 makeVarFromTargetEntry(Index varno,
105 TargetEntry *tle)
106 {
107 return makeVar(varno,
108 tle->resno,
109 exprType((Node *) tle->expr),
110 exprTypmod((Node *) tle->expr),
111 exprCollation((Node *) tle->expr),
112 0);
113 }
114
115 /*
116 * makeWholeRowVar -
117 * creates a Var node representing a whole row of the specified RTE
118 *
119 * A whole-row reference is a Var with varno set to the correct range
120 * table entry, and varattno == 0 to signal that it references the whole
121 * tuple. (Use of zero here is unclean, since it could easily be confused
122 * with error cases, but it's not worth changing now.) The vartype indicates
123 * a rowtype; either a named composite type, or a domain over a named
124 * composite type (only possible if the RTE is a function returning that),
125 * or RECORD. This function encapsulates the logic for determining the
126 * correct rowtype OID to use.
127 *
128 * If allowScalar is true, then for the case where the RTE is a single function
129 * returning a non-composite result type, we produce a normal Var referencing
130 * the function's result directly, instead of the single-column composite
131 * value that the whole-row notation might otherwise suggest.
132 */
133 Var *
makeWholeRowVar(RangeTblEntry * rte,Index varno,Index varlevelsup,bool allowScalar)134 makeWholeRowVar(RangeTblEntry *rte,
135 Index varno,
136 Index varlevelsup,
137 bool allowScalar)
138 {
139 Var *result;
140 Oid toid;
141 Node *fexpr;
142
143 switch (rte->rtekind)
144 {
145 case RTE_RELATION:
146 /* relation: the rowtype is a named composite type */
147 toid = get_rel_type_id(rte->relid);
148 if (!OidIsValid(toid))
149 elog(ERROR, "could not find type OID for relation %u",
150 rte->relid);
151 result = makeVar(varno,
152 InvalidAttrNumber,
153 toid,
154 -1,
155 InvalidOid,
156 varlevelsup);
157 break;
158
159 case RTE_FUNCTION:
160
161 /*
162 * If there's more than one function, or ordinality is requested,
163 * force a RECORD result, since there's certainly more than one
164 * column involved and it can't be a known named type.
165 */
166 if (rte->funcordinality || list_length(rte->functions) != 1)
167 {
168 /* always produces an anonymous RECORD result */
169 result = makeVar(varno,
170 InvalidAttrNumber,
171 RECORDOID,
172 -1,
173 InvalidOid,
174 varlevelsup);
175 break;
176 }
177
178 fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
179 toid = exprType(fexpr);
180 if (type_is_rowtype(toid))
181 {
182 /* func returns composite; same as relation case */
183 result = makeVar(varno,
184 InvalidAttrNumber,
185 toid,
186 -1,
187 InvalidOid,
188 varlevelsup);
189 }
190 else if (allowScalar)
191 {
192 /* func returns scalar; just return its output as-is */
193 result = makeVar(varno,
194 1,
195 toid,
196 -1,
197 exprCollation(fexpr),
198 varlevelsup);
199 }
200 else
201 {
202 /* func returns scalar, but we want a composite result */
203 result = makeVar(varno,
204 InvalidAttrNumber,
205 RECORDOID,
206 -1,
207 InvalidOid,
208 varlevelsup);
209 }
210 break;
211
212 default:
213
214 /*
215 * RTE is a join, subselect, tablefunc, or VALUES. We represent
216 * this as a whole-row Var of RECORD type. (Note that in most
217 * cases the Var will be expanded to a RowExpr during planning,
218 * but that is not our concern here.)
219 */
220 result = makeVar(varno,
221 InvalidAttrNumber,
222 RECORDOID,
223 -1,
224 InvalidOid,
225 varlevelsup);
226 break;
227 }
228
229 return result;
230 }
231
232 /*
233 * makeTargetEntry -
234 * creates a TargetEntry node
235 */
236 TargetEntry *
makeTargetEntry(Expr * expr,AttrNumber resno,char * resname,bool resjunk)237 makeTargetEntry(Expr *expr,
238 AttrNumber resno,
239 char *resname,
240 bool resjunk)
241 {
242 TargetEntry *tle = makeNode(TargetEntry);
243
244 tle->expr = expr;
245 tle->resno = resno;
246 tle->resname = resname;
247
248 /*
249 * We always set these fields to 0. If the caller wants to change them he
250 * must do so explicitly. Few callers do that, so omitting these
251 * arguments reduces the chance of error.
252 */
253 tle->ressortgroupref = 0;
254 tle->resorigtbl = InvalidOid;
255 tle->resorigcol = 0;
256
257 tle->resjunk = resjunk;
258
259 return tle;
260 }
261
262 /*
263 * flatCopyTargetEntry -
264 * duplicate a TargetEntry, but don't copy substructure
265 *
266 * This is commonly used when we just want to modify the resno or substitute
267 * a new expression.
268 */
269 TargetEntry *
flatCopyTargetEntry(TargetEntry * src_tle)270 flatCopyTargetEntry(TargetEntry *src_tle)
271 {
272 TargetEntry *tle = makeNode(TargetEntry);
273
274 Assert(IsA(src_tle, TargetEntry));
275 memcpy(tle, src_tle, sizeof(TargetEntry));
276 return tle;
277 }
278
279 /*
280 * makeFromExpr -
281 * creates a FromExpr node
282 */
283 FromExpr *
makeFromExpr(List * fromlist,Node * quals)284 makeFromExpr(List *fromlist, Node *quals)
285 {
286 FromExpr *f = makeNode(FromExpr);
287
288 f->fromlist = fromlist;
289 f->quals = quals;
290 return f;
291 }
292
293 /*
294 * makeConst -
295 * creates a Const node
296 */
297 Const *
makeConst(Oid consttype,int32 consttypmod,Oid constcollid,int constlen,Datum constvalue,bool constisnull,bool constbyval)298 makeConst(Oid consttype,
299 int32 consttypmod,
300 Oid constcollid,
301 int constlen,
302 Datum constvalue,
303 bool constisnull,
304 bool constbyval)
305 {
306 Const *cnst = makeNode(Const);
307
308 /*
309 * If it's a varlena value, force it to be in non-expanded (non-toasted)
310 * format; this avoids any possible dependency on external values and
311 * improves consistency of representation, which is important for equal().
312 */
313 if (!constisnull && constlen == -1)
314 constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
315
316 cnst->consttype = consttype;
317 cnst->consttypmod = consttypmod;
318 cnst->constcollid = constcollid;
319 cnst->constlen = constlen;
320 cnst->constvalue = constvalue;
321 cnst->constisnull = constisnull;
322 cnst->constbyval = constbyval;
323 cnst->location = -1; /* "unknown" */
324
325 return cnst;
326 }
327
328 /*
329 * makeNullConst -
330 * creates a Const node representing a NULL of the specified type/typmod
331 *
332 * This is a convenience routine that just saves a lookup of the type's
333 * storage properties.
334 */
335 Const *
makeNullConst(Oid consttype,int32 consttypmod,Oid constcollid)336 makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
337 {
338 int16 typLen;
339 bool typByVal;
340
341 get_typlenbyval(consttype, &typLen, &typByVal);
342 return makeConst(consttype,
343 consttypmod,
344 constcollid,
345 (int) typLen,
346 (Datum) 0,
347 true,
348 typByVal);
349 }
350
351 /*
352 * makeBoolConst -
353 * creates a Const node representing a boolean value (can be NULL too)
354 */
355 Node *
makeBoolConst(bool value,bool isnull)356 makeBoolConst(bool value, bool isnull)
357 {
358 /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
359 return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
360 BoolGetDatum(value), isnull, true);
361 }
362
363 /*
364 * makeBoolExpr -
365 * creates a BoolExpr node
366 */
367 Expr *
makeBoolExpr(BoolExprType boolop,List * args,int location)368 makeBoolExpr(BoolExprType boolop, List *args, int location)
369 {
370 BoolExpr *b = makeNode(BoolExpr);
371
372 b->boolop = boolop;
373 b->args = args;
374 b->location = location;
375
376 return (Expr *) b;
377 }
378
379 /*
380 * makeAlias -
381 * creates an Alias node
382 *
383 * NOTE: the given name is copied, but the colnames list (if any) isn't.
384 */
385 Alias *
makeAlias(const char * aliasname,List * colnames)386 makeAlias(const char *aliasname, List *colnames)
387 {
388 Alias *a = makeNode(Alias);
389
390 a->aliasname = pstrdup(aliasname);
391 a->colnames = colnames;
392
393 return a;
394 }
395
396 /*
397 * makeRelabelType -
398 * creates a RelabelType node
399 */
400 RelabelType *
makeRelabelType(Expr * arg,Oid rtype,int32 rtypmod,Oid rcollid,CoercionForm rformat)401 makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
402 CoercionForm rformat)
403 {
404 RelabelType *r = makeNode(RelabelType);
405
406 r->arg = arg;
407 r->resulttype = rtype;
408 r->resulttypmod = rtypmod;
409 r->resultcollid = rcollid;
410 r->relabelformat = rformat;
411 r->location = -1;
412
413 return r;
414 }
415
416 /*
417 * makeRangeVar -
418 * creates a RangeVar node (rather oversimplified case)
419 */
420 RangeVar *
makeRangeVar(char * schemaname,char * relname,int location)421 makeRangeVar(char *schemaname, char *relname, int location)
422 {
423 RangeVar *r = makeNode(RangeVar);
424
425 r->catalogname = NULL;
426 r->schemaname = schemaname;
427 r->relname = relname;
428 r->inh = true;
429 r->relpersistence = RELPERSISTENCE_PERMANENT;
430 r->alias = NULL;
431 r->location = location;
432
433 return r;
434 }
435
436 /*
437 * makeTypeName -
438 * build a TypeName node for an unqualified name.
439 *
440 * typmod is defaulted, but can be changed later by caller.
441 */
442 TypeName *
makeTypeName(char * typnam)443 makeTypeName(char *typnam)
444 {
445 return makeTypeNameFromNameList(list_make1(makeString(typnam)));
446 }
447
448 /*
449 * makeTypeNameFromNameList -
450 * build a TypeName node for a String list representing a qualified name.
451 *
452 * typmod is defaulted, but can be changed later by caller.
453 */
454 TypeName *
makeTypeNameFromNameList(List * names)455 makeTypeNameFromNameList(List *names)
456 {
457 TypeName *n = makeNode(TypeName);
458
459 n->names = names;
460 n->typmods = NIL;
461 n->typemod = -1;
462 n->location = -1;
463 return n;
464 }
465
466 /*
467 * makeTypeNameFromOid -
468 * build a TypeName node to represent a type already known by OID/typmod.
469 */
470 TypeName *
makeTypeNameFromOid(Oid typeOid,int32 typmod)471 makeTypeNameFromOid(Oid typeOid, int32 typmod)
472 {
473 TypeName *n = makeNode(TypeName);
474
475 n->typeOid = typeOid;
476 n->typemod = typmod;
477 n->location = -1;
478 return n;
479 }
480
481 /*
482 * makeColumnDef -
483 * build a ColumnDef node to represent a simple column definition.
484 *
485 * Type and collation are specified by OID.
486 * Other properties are all basic to start with.
487 */
488 ColumnDef *
makeColumnDef(const char * colname,Oid typeOid,int32 typmod,Oid collOid)489 makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
490 {
491 ColumnDef *n = makeNode(ColumnDef);
492
493 n->colname = pstrdup(colname);
494 n->typeName = makeTypeNameFromOid(typeOid, typmod);
495 n->inhcount = 0;
496 n->is_local = true;
497 n->is_not_null = false;
498 n->is_from_type = false;
499 n->storage = 0;
500 n->raw_default = NULL;
501 n->cooked_default = NULL;
502 n->collClause = NULL;
503 n->collOid = collOid;
504 n->constraints = NIL;
505 n->fdwoptions = NIL;
506 n->location = -1;
507
508 return n;
509 }
510
511 /*
512 * makeFuncExpr -
513 * build an expression tree representing a function call.
514 *
515 * The argument expressions must have been transformed already.
516 */
517 FuncExpr *
makeFuncExpr(Oid funcid,Oid rettype,List * args,Oid funccollid,Oid inputcollid,CoercionForm fformat)518 makeFuncExpr(Oid funcid, Oid rettype, List *args,
519 Oid funccollid, Oid inputcollid, CoercionForm fformat)
520 {
521 FuncExpr *funcexpr;
522
523 funcexpr = makeNode(FuncExpr);
524 funcexpr->funcid = funcid;
525 funcexpr->funcresulttype = rettype;
526 funcexpr->funcretset = false; /* only allowed case here */
527 funcexpr->funcvariadic = false; /* only allowed case here */
528 funcexpr->funcformat = fformat;
529 funcexpr->funccollid = funccollid;
530 funcexpr->inputcollid = inputcollid;
531 funcexpr->args = args;
532 funcexpr->location = -1;
533
534 return funcexpr;
535 }
536
537 /*
538 * makeDefElem -
539 * build a DefElem node
540 *
541 * This is sufficient for the "typical" case with an unqualified option name
542 * and no special action.
543 */
544 DefElem *
makeDefElem(char * name,Node * arg,int location)545 makeDefElem(char *name, Node *arg, int location)
546 {
547 DefElem *res = makeNode(DefElem);
548
549 res->defnamespace = NULL;
550 res->defname = name;
551 res->arg = arg;
552 res->defaction = DEFELEM_UNSPEC;
553 res->location = location;
554
555 return res;
556 }
557
558 /*
559 * makeDefElemExtended -
560 * build a DefElem node with all fields available to be specified
561 */
562 DefElem *
makeDefElemExtended(char * nameSpace,char * name,Node * arg,DefElemAction defaction,int location)563 makeDefElemExtended(char *nameSpace, char *name, Node *arg,
564 DefElemAction defaction, int location)
565 {
566 DefElem *res = makeNode(DefElem);
567
568 res->defnamespace = nameSpace;
569 res->defname = name;
570 res->arg = arg;
571 res->defaction = defaction;
572 res->location = location;
573
574 return res;
575 }
576
577 /*
578 * makeFuncCall -
579 *
580 * Initialize a FuncCall struct with the information every caller must
581 * supply. Any non-default parameters have to be inserted by the caller.
582 */
583 FuncCall *
makeFuncCall(List * name,List * args,int location)584 makeFuncCall(List *name, List *args, int location)
585 {
586 FuncCall *n = makeNode(FuncCall);
587
588 n->funcname = name;
589 n->args = args;
590 n->agg_order = NIL;
591 n->agg_filter = NULL;
592 n->agg_within_group = false;
593 n->agg_star = false;
594 n->agg_distinct = false;
595 n->func_variadic = false;
596 n->over = NULL;
597 n->location = location;
598 return n;
599 }
600
601 /*
602 * makeGroupingSet
603 *
604 */
605 GroupingSet *
makeGroupingSet(GroupingSetKind kind,List * content,int location)606 makeGroupingSet(GroupingSetKind kind, List *content, int location)
607 {
608 GroupingSet *n = makeNode(GroupingSet);
609
610 n->kind = kind;
611 n->content = content;
612 n->location = location;
613 return n;
614 }
615
616 /*
617 * makeVacuumRelation -
618 * create a VacuumRelation node
619 */
620 VacuumRelation *
makeVacuumRelation(RangeVar * relation,Oid oid,List * va_cols)621 makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
622 {
623 VacuumRelation *v = makeNode(VacuumRelation);
624
625 v->relation = relation;
626 v->oid = oid;
627 v->va_cols = va_cols;
628 return v;
629 }
630