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-2019, 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  * make_opclause
603  *	  Creates an operator clause given its operator info, left operand
604  *	  and right operand (pass NULL to create single-operand clause),
605  *	  and collation info.
606  */
607 Expr *
make_opclause(Oid opno,Oid opresulttype,bool opretset,Expr * leftop,Expr * rightop,Oid opcollid,Oid inputcollid)608 make_opclause(Oid opno, Oid opresulttype, bool opretset,
609 			  Expr *leftop, Expr *rightop,
610 			  Oid opcollid, Oid inputcollid)
611 {
612 	OpExpr	   *expr = makeNode(OpExpr);
613 
614 	expr->opno = opno;
615 	expr->opfuncid = InvalidOid;
616 	expr->opresulttype = opresulttype;
617 	expr->opretset = opretset;
618 	expr->opcollid = opcollid;
619 	expr->inputcollid = inputcollid;
620 	if (rightop)
621 		expr->args = list_make2(leftop, rightop);
622 	else
623 		expr->args = list_make1(leftop);
624 	expr->location = -1;
625 	return (Expr *) expr;
626 }
627 
628 /*
629  * make_andclause
630  *
631  * Creates an 'and' clause given a list of its subclauses.
632  */
633 Expr *
make_andclause(List * andclauses)634 make_andclause(List *andclauses)
635 {
636 	BoolExpr   *expr = makeNode(BoolExpr);
637 
638 	expr->boolop = AND_EXPR;
639 	expr->args = andclauses;
640 	expr->location = -1;
641 	return (Expr *) expr;
642 }
643 
644 /*
645  * make_orclause
646  *
647  * Creates an 'or' clause given a list of its subclauses.
648  */
649 Expr *
make_orclause(List * orclauses)650 make_orclause(List *orclauses)
651 {
652 	BoolExpr   *expr = makeNode(BoolExpr);
653 
654 	expr->boolop = OR_EXPR;
655 	expr->args = orclauses;
656 	expr->location = -1;
657 	return (Expr *) expr;
658 }
659 
660 /*
661  * make_notclause
662  *
663  * Create a 'not' clause given the expression to be negated.
664  */
665 Expr *
make_notclause(Expr * notclause)666 make_notclause(Expr *notclause)
667 {
668 	BoolExpr   *expr = makeNode(BoolExpr);
669 
670 	expr->boolop = NOT_EXPR;
671 	expr->args = list_make1(notclause);
672 	expr->location = -1;
673 	return (Expr *) expr;
674 }
675 
676 /*
677  * make_and_qual
678  *
679  * Variant of make_andclause for ANDing two qual conditions together.
680  * Qual conditions have the property that a NULL nodetree is interpreted
681  * as 'true'.
682  *
683  * NB: this makes no attempt to preserve AND/OR flatness; so it should not
684  * be used on a qual that has already been run through prepqual.c.
685  */
686 Node *
make_and_qual(Node * qual1,Node * qual2)687 make_and_qual(Node *qual1, Node *qual2)
688 {
689 	if (qual1 == NULL)
690 		return qual2;
691 	if (qual2 == NULL)
692 		return qual1;
693 	return (Node *) make_andclause(list_make2(qual1, qual2));
694 }
695 
696 /*
697  * The planner and executor usually represent qualification expressions
698  * as lists of boolean expressions with implicit AND semantics.
699  *
700  * These functions convert between an AND-semantics expression list and the
701  * ordinary representation of a boolean expression.
702  *
703  * Note that an empty list is considered equivalent to TRUE.
704  */
705 Expr *
make_ands_explicit(List * andclauses)706 make_ands_explicit(List *andclauses)
707 {
708 	if (andclauses == NIL)
709 		return (Expr *) makeBoolConst(true, false);
710 	else if (list_length(andclauses) == 1)
711 		return (Expr *) linitial(andclauses);
712 	else
713 		return make_andclause(andclauses);
714 }
715 
716 List *
make_ands_implicit(Expr * clause)717 make_ands_implicit(Expr *clause)
718 {
719 	/*
720 	 * NB: because the parser sets the qual field to NULL in a query that has
721 	 * no WHERE clause, we must consider a NULL input clause as TRUE, even
722 	 * though one might more reasonably think it FALSE.
723 	 */
724 	if (clause == NULL)
725 		return NIL;				/* NULL -> NIL list == TRUE */
726 	else if (is_andclause(clause))
727 		return ((BoolExpr *) clause)->args;
728 	else if (IsA(clause, Const) &&
729 			 !((Const *) clause)->constisnull &&
730 			 DatumGetBool(((Const *) clause)->constvalue))
731 		return NIL;				/* constant TRUE input -> NIL list */
732 	else
733 		return list_make1(clause);
734 }
735 
736 /*
737  * makeIndexInfo
738  *	  create an IndexInfo node
739  */
740 IndexInfo *
makeIndexInfo(int numattrs,int numkeyattrs,Oid amoid,List * expressions,List * predicates,bool unique,bool isready,bool concurrent)741 makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
742 			  List *predicates, bool unique, bool isready, bool concurrent)
743 {
744 	IndexInfo  *n = makeNode(IndexInfo);
745 
746 	n->ii_NumIndexAttrs = numattrs;
747 	n->ii_NumIndexKeyAttrs = numkeyattrs;
748 	Assert(n->ii_NumIndexKeyAttrs != 0);
749 	Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
750 	n->ii_Unique = unique;
751 	n->ii_ReadyForInserts = isready;
752 	n->ii_Concurrent = concurrent;
753 
754 	/* expressions */
755 	n->ii_Expressions = expressions;
756 	n->ii_ExpressionsState = NIL;
757 
758 	/* predicates  */
759 	n->ii_Predicate = predicates;
760 	n->ii_PredicateState = NULL;
761 
762 	/* exclusion constraints */
763 	n->ii_ExclusionOps = NULL;
764 	n->ii_ExclusionProcs = NULL;
765 	n->ii_ExclusionStrats = NULL;
766 
767 	/* speculative inserts */
768 	n->ii_UniqueOps = NULL;
769 	n->ii_UniqueProcs = NULL;
770 	n->ii_UniqueStrats = NULL;
771 
772 	/* initialize index-build state to default */
773 	n->ii_BrokenHotChain = false;
774 	n->ii_ParallelWorkers = 0;
775 
776 	/* set up for possible use by index AM */
777 	n->ii_Am = amoid;
778 	n->ii_AmCache = NULL;
779 	n->ii_Context = CurrentMemoryContext;
780 
781 	return n;
782 }
783 
784 /*
785  * makeGroupingSet
786  *
787  */
788 GroupingSet *
makeGroupingSet(GroupingSetKind kind,List * content,int location)789 makeGroupingSet(GroupingSetKind kind, List *content, int location)
790 {
791 	GroupingSet *n = makeNode(GroupingSet);
792 
793 	n->kind = kind;
794 	n->content = content;
795 	n->location = location;
796 	return n;
797 }
798 
799 /*
800  * makeVacuumRelation -
801  *	  create a VacuumRelation node
802  */
803 VacuumRelation *
makeVacuumRelation(RangeVar * relation,Oid oid,List * va_cols)804 makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
805 {
806 	VacuumRelation *v = makeNode(VacuumRelation);
807 
808 	v->relation = relation;
809 	v->oid = oid;
810 	v->va_cols = va_cols;
811 	return v;
812 }
813