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