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) 2003-2021, PgPool Global Development Group
8  * Portions Copyright (c) 1996-2021, 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 	 * Only a few callers need to make Var nodes with varnosyn/varattnosyn
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->varnosyn = varno;
90 	var->varattnosyn = 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 				ereport(ERROR,
151 						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
152 						 errmsg("relation \"%s\" does not have a composite type",
153 								get_rel_name(rte->relid))));
154 			result = makeVar(varno,
155 							 InvalidAttrNumber,
156 							 toid,
157 							 -1,
158 							 InvalidOid,
159 							 varlevelsup);
160 			break;
161 
162 		case RTE_FUNCTION:
163 
164 			/*
165 			 * If there's more than one function, or ordinality is requested,
166 			 * force a RECORD result, since there's certainly more than one
167 			 * column involved and it can't be a known named type.
168 			 */
169 			if (rte->funcordinality || list_length(rte->functions) != 1)
170 			{
171 				/* always produces an anonymous RECORD result */
172 				result = makeVar(varno,
173 								 InvalidAttrNumber,
174 								 RECORDOID,
175 								 -1,
176 								 InvalidOid,
177 								 varlevelsup);
178 				break;
179 			}
180 
181 			fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
182 			toid = exprType(fexpr);
183 			if (type_is_rowtype(toid))
184 			{
185 				/* func returns composite; same as relation case */
186 				result = makeVar(varno,
187 								 InvalidAttrNumber,
188 								 toid,
189 								 -1,
190 								 InvalidOid,
191 								 varlevelsup);
192 			}
193 			else if (allowScalar)
194 			{
195 				/* func returns scalar; just return its output as-is */
196 				result = makeVar(varno,
197 								 1,
198 								 toid,
199 								 -1,
200 								 exprCollation(fexpr),
201 								 varlevelsup);
202 			}
203 			else
204 			{
205 				/* func returns scalar, but we want a composite result */
206 				result = makeVar(varno,
207 								 InvalidAttrNumber,
208 								 RECORDOID,
209 								 -1,
210 								 InvalidOid,
211 								 varlevelsup);
212 			}
213 			break;
214 
215 		default:
216 
217 			/*
218 			 * RTE is a join, subselect, tablefunc, or VALUES.  We represent
219 			 * this as a whole-row Var of RECORD type. (Note that in most
220 			 * cases the Var will be expanded to a RowExpr during planning,
221 			 * but that is not our concern here.)
222 			 */
223 			result = makeVar(varno,
224 							 InvalidAttrNumber,
225 							 RECORDOID,
226 							 -1,
227 							 InvalidOid,
228 							 varlevelsup);
229 			break;
230 	}
231 
232 	return result;
233 }
234 
235 #endif
236 
237 /*
238  * makeTargetEntry -
239  *	  creates a TargetEntry node
240  */
241 TargetEntry *
makeTargetEntry(Expr * expr,AttrNumber resno,char * resname,bool resjunk)242 makeTargetEntry(Expr *expr,
243 				AttrNumber resno,
244 				char *resname,
245 				bool resjunk)
246 {
247 	TargetEntry *tle = makeNode(TargetEntry);
248 
249 	tle->expr = expr;
250 	tle->resno = resno;
251 	tle->resname = resname;
252 
253 	/*
254 	 * We always set these fields to 0. If the caller wants to change them he
255 	 * must do so explicitly.  Few callers do that, so omitting these
256 	 * arguments reduces the chance of error.
257 	 */
258 	tle->ressortgroupref = 0;
259 	tle->resorigtbl = InvalidOid;
260 	tle->resorigcol = 0;
261 
262 	tle->resjunk = resjunk;
263 
264 	return tle;
265 }
266 
267 /*
268  * flatCopyTargetEntry -
269  *	  duplicate a TargetEntry, but don't copy substructure
270  *
271  * This is commonly used when we just want to modify the resno or substitute
272  * a new expression.
273  */
274 TargetEntry *
flatCopyTargetEntry(TargetEntry * src_tle)275 flatCopyTargetEntry(TargetEntry *src_tle)
276 {
277 	TargetEntry *tle = makeNode(TargetEntry);
278 
279 	Assert(IsA(src_tle, TargetEntry));
280 	memcpy(tle, src_tle, sizeof(TargetEntry));
281 	return tle;
282 }
283 
284 /*
285  * makeFromExpr -
286  *	  creates a FromExpr node
287  */
288 FromExpr *
makeFromExpr(List * fromlist,Node * quals)289 makeFromExpr(List *fromlist, Node *quals)
290 {
291 	FromExpr   *f = makeNode(FromExpr);
292 
293 	f->fromlist = fromlist;
294 	f->quals = quals;
295 	return f;
296 }
297 
298 /*
299  * makeConst -
300  *	  creates a Const node
301  */
302 Const *
makeConst(Oid consttype,int32 consttypmod,Oid constcollid,int constlen,Datum constvalue,bool constisnull,bool constbyval)303 makeConst(Oid consttype,
304 		  int32 consttypmod,
305 		  Oid constcollid,
306 		  int constlen,
307 		  Datum constvalue,
308 		  bool constisnull,
309 		  bool constbyval)
310 {
311 	Const	   *cnst = makeNode(Const);
312 
313 	cnst->consttype = consttype;
314 	cnst->consttypmod = consttypmod;
315 	cnst->constcollid = constcollid;
316 	cnst->constlen = constlen;
317 	cnst->constvalue = constvalue;
318 	cnst->constisnull = constisnull;
319 	cnst->constbyval = constbyval;
320 	cnst->location = -1;		/* "unknown" */
321 
322 	return cnst;
323 }
324 
325 #if 0
326 /*
327  * makeNullConst -
328  *	  creates a Const node representing a NULL of the specified type/typmod
329  *
330  * This is a convenience routine that just saves a lookup of the type's
331  * storage properties.
332  */
333 Const *
334 makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
335 {
336 	int16		typLen;
337 	bool		typByVal;
338 
339 	get_typlenbyval(consttype, &typLen, &typByVal);
340 	return makeConst(consttype,
341 					 consttypmod,
342 					 constcollid,
343 					 (int) typLen,
344 					 (Datum) 0,
345 					 true,
346 					 typByVal);
347 }
348 
349 /*
350  * makeBoolConst -
351  *	  creates a Const node representing a boolean value (can be NULL too)
352  */
353 Node *
354 makeBoolConst(bool value, bool isnull)
355 {
356 	/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
357 	return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
358 							  BoolGetDatum(value), isnull, true);
359 }
360 
361 #endif
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,CoercionForm funcformat,int location)584 makeFuncCall(List *name, List *args, CoercionForm funcformat, 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->over = NULL;
593 	n->agg_within_group = false;
594 	n->agg_star = false;
595 	n->agg_distinct = false;
596 	n->func_variadic = false;
597 	n->funcformat = funcformat;
598 	n->location = location;
599 	return n;
600 }
601 
602 /*
603  * makeGroupingSet
604  *
605  */
606 GroupingSet *
makeGroupingSet(GroupingSetKind kind,List * content,int location)607 makeGroupingSet(GroupingSetKind kind, List *content, int location)
608 {
609 	GroupingSet *n = makeNode(GroupingSet);
610 
611 	n->kind = kind;
612 	n->content = content;
613 	n->location = location;
614 	return n;
615 }
616 
617 /*
618  * makeVacuumRelation -
619  *	  create a VacuumRelation node
620  */
621 VacuumRelation *
makeVacuumRelation(RangeVar * relation,Oid oid,List * va_cols)622 makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
623 {
624 	VacuumRelation *v = makeNode(VacuumRelation);
625 
626 	v->relation = relation;
627 	v->oid = oid;
628 	v->va_cols = va_cols;
629 	return v;
630 }
631