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