1 /*-------------------------------------------------------------------------
4 * creator functions for primitive nodes. The functions here are for
5 * the most frequently created nodes.
7 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/nodes/makefuncs.c
14 *-------------------------------------------------------------------------
18 #include "catalog/pg_class.h"
19 #include "catalog/pg_type.h"
20 #include "nodes/makefuncs.h"
21 #include "nodes/nodeFuncs.h"
22 #include "utils/lsyscache.h"
27 * makes an A_Expr node
30 makeA_Expr(A_Expr_Kind kind, List *name,
31 Node *lexpr, Node *rexpr, int location)
33 A_Expr *a = makeNode(A_Expr);
39 a->location = location;
45 * As above, given a simple (unqualified) operator name
48 makeSimpleA_Expr(A_Expr_Kind kind, char *name,
49 Node *lexpr, Node *rexpr, int location)
51 A_Expr *a = makeNode(A_Expr);
54 a->name = list_make1(makeString((char *) name));
57 a->location = location;
73 Var *var = makeNode(Var);
76 var->varattno = varattno;
77 var->vartype = vartype;
78 var->vartypmod = vartypmod;
79 var->varcollid = varcollid;
80 var->varlevelsup = varlevelsup;
83 * Since few if any routines ever create Var nodes with varnoold/varoattno
84 * different from varno/varattno, we don't provide separate arguments for
85 * them, but just initialize them to the given varno/varattno. This
86 * reduces code clutter and chance of error for most callers.
88 var->varnoold = varno;
89 var->varoattno = varattno;
91 /* Likewise, we just set location to "unknown" here */
98 * makeVarFromTargetEntry -
99 * convenience function to create a same-level Var node from a
103 makeVarFromTargetEntry(Index varno,
106 return makeVar(varno,
108 exprType((Node *) tle->expr),
109 exprTypmod((Node *) tle->expr),
110 exprCollation((Node *) tle->expr),
116 * creates a Var node representing a whole row of the specified RTE
118 * A whole-row reference is a Var with varno set to the correct range
119 * table entry, and varattno == 0 to signal that it references the whole
120 * tuple. (Use of zero here is unclean, since it could easily be confused
121 * with error cases, but it's not worth changing now.) The vartype indicates
122 * a rowtype; either a named composite type, or RECORD. This function
123 * encapsulates the logic for determining the correct rowtype OID to use.
125 * If allowScalar is true, then for the case where the RTE is a function
126 * returning a non-composite result type, we produce a normal Var referencing
127 * the function's result directly, instead of the single-column composite
128 * value that the whole-row notation might otherwise suggest.
131 makeWholeRowVar(RangeTblEntry *rte,
139 switch (rte->rtekind)
142 /* relation: the rowtype is a named composite type */
143 toid = get_rel_type_id(rte->relid);
144 if (!OidIsValid(toid))
145 elog(ERROR, "could not find type OID for relation %u",
147 result = makeVar(varno,
155 toid = exprType(rte->funcexpr);
156 if (type_is_rowtype(toid))
158 /* func returns composite; same as relation case */
159 result = makeVar(varno,
166 else if (allowScalar)
168 /* func returns scalar; just return its output as-is */
169 result = makeVar(varno,
173 exprCollation(rte->funcexpr),
178 /* func returns scalar, but we want a composite result */
179 result = makeVar(varno,
190 * RTE is a join, subselect, or VALUES. We represent this as a
191 * whole-row Var of RECORD type. (Note that in most cases the Var
192 * will be expanded to a RowExpr during planning, but that is not
195 result = makeVar(varno,
209 * creates a TargetEntry node
212 makeTargetEntry(Expr *expr,
217 TargetEntry *tle = makeNode(TargetEntry);
221 tle->resname = resname;
224 * We always set these fields to 0. If the caller wants to change them he
225 * must do so explicitly. Few callers do that, so omitting these
226 * arguments reduces the chance of error.
228 tle->ressortgroupref = 0;
229 tle->resorigtbl = InvalidOid;
232 tle->resjunk = resjunk;
238 * flatCopyTargetEntry -
239 * duplicate a TargetEntry, but don't copy substructure
241 * This is commonly used when we just want to modify the resno or substitute
245 flatCopyTargetEntry(TargetEntry *src_tle)
247 TargetEntry *tle = makeNode(TargetEntry);
249 Assert(IsA(src_tle, TargetEntry));
250 memcpy(tle, src_tle, sizeof(TargetEntry));
256 * creates a FromExpr node
259 makeFromExpr(List *fromlist, Node *quals)
261 FromExpr *f = makeNode(FromExpr);
263 f->fromlist = fromlist;
270 * creates a Const node
273 makeConst(Oid consttype,
281 Const *cnst = makeNode(Const);
283 cnst->consttype = consttype;
284 cnst->consttypmod = consttypmod;
285 cnst->constcollid = constcollid;
286 cnst->constlen = constlen;
287 cnst->constvalue = constvalue;
288 cnst->constisnull = constisnull;
289 cnst->constbyval = constbyval;
290 cnst->location = -1; /* "unknown" */
297 * creates a Const node representing a NULL of the specified type/typmod
299 * This is a convenience routine that just saves a lookup of the type's
300 * storage properties.
303 makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
308 get_typlenbyval(consttype, &typLen, &typByVal);
309 return makeConst(consttype,
320 * creates a Const node representing a boolean value (can be NULL too)
323 makeBoolConst(bool value, bool isnull)
325 /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
326 return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
327 BoolGetDatum(value), isnull, true);
332 * creates a BoolExpr node
335 makeBoolExpr(BoolExprType boolop, List *args, int location)
337 BoolExpr *b = makeNode(BoolExpr);
341 b->location = location;
348 * creates an Alias node
350 * NOTE: the given name is copied, but the colnames list (if any) isn't.
353 makeAlias(const char *aliasname, List *colnames)
355 Alias *a = makeNode(Alias);
357 a->aliasname = pstrdup(aliasname);
358 a->colnames = colnames;
365 * creates a RelabelType node
368 makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
369 CoercionForm rformat)
371 RelabelType *r = makeNode(RelabelType);
374 r->resulttype = rtype;
375 r->resulttypmod = rtypmod;
376 r->resultcollid = rcollid;
377 r->relabelformat = rformat;
385 * creates a RangeVar node (rather oversimplified case)
388 makeRangeVar(char *schemaname, char *relname, int location)
390 RangeVar *r = makeNode(RangeVar);
392 r->catalogname = NULL;
393 r->schemaname = schemaname;
394 r->relname = relname;
395 r->inhOpt = INH_DEFAULT;
396 r->relpersistence = RELPERSISTENCE_PERMANENT;
398 r->location = location;
405 * build a TypeName node for an unqualified name.
407 * typmod is defaulted, but can be changed later by caller.
410 makeTypeName(char *typnam)
412 return makeTypeNameFromNameList(list_make1(makeString(typnam)));
416 * makeTypeNameFromNameList -
417 * build a TypeName node for a String list representing a qualified name.
419 * typmod is defaulted, but can be changed later by caller.
422 makeTypeNameFromNameList(List *names)
424 TypeName *n = makeNode(TypeName);
434 * makeTypeNameFromOid -
435 * build a TypeName node to represent a type already known by OID/typmod.
438 makeTypeNameFromOid(Oid typeOid, int32 typmod)
440 TypeName *n = makeNode(TypeName);
442 n->typeOid = typeOid;
450 * build an expression tree representing a function call.
452 * The argument expressions must have been transformed already.
455 makeFuncExpr(Oid funcid, Oid rettype, List *args,
456 Oid funccollid, Oid inputcollid, CoercionForm fformat)
460 funcexpr = makeNode(FuncExpr);
461 funcexpr->funcid = funcid;
462 funcexpr->funcresulttype = rettype;
463 funcexpr->funcretset = false; /* only allowed case here */
464 funcexpr->funcformat = fformat;
465 funcexpr->funccollid = funccollid;
466 funcexpr->inputcollid = inputcollid;
467 funcexpr->args = args;
468 funcexpr->location = -1;
475 * build a DefElem node
477 * This is sufficient for the "typical" case with an unqualified option name
478 * and no special action.
481 makeDefElem(char *name, Node *arg)
483 DefElem *res = makeNode(DefElem);
485 res->defnamespace = NULL;
488 res->defaction = DEFELEM_UNSPEC;
494 * makeDefElemExtended -
495 * build a DefElem node with all fields available to be specified
498 makeDefElemExtended(char *nameSpace, char *name, Node *arg,
499 DefElemAction defaction)
501 DefElem *res = makeNode(DefElem);
503 res->defnamespace = nameSpace;
506 res->defaction = defaction;