Header And Logo

PostgreSQL
| The world's most advanced open source database.

makefuncs.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * makefuncs.c
00004  *    creator functions for primitive nodes. The functions here are for
00005  *    the most frequently created nodes.
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  *
00011  * IDENTIFICATION
00012  *    src/backend/nodes/makefuncs.c
00013  *
00014  *-------------------------------------------------------------------------
00015  */
00016 #include "postgres.h"
00017 
00018 #include "catalog/pg_class.h"
00019 #include "catalog/pg_type.h"
00020 #include "nodes/makefuncs.h"
00021 #include "nodes/nodeFuncs.h"
00022 #include "utils/lsyscache.h"
00023 
00024 
00025 /*
00026  * makeA_Expr -
00027  *      makes an A_Expr node
00028  */
00029 A_Expr *
00030 makeA_Expr(A_Expr_Kind kind, List *name,
00031            Node *lexpr, Node *rexpr, int location)
00032 {
00033     A_Expr     *a = makeNode(A_Expr);
00034 
00035     a->kind = kind;
00036     a->name = name;
00037     a->lexpr = lexpr;
00038     a->rexpr = rexpr;
00039     a->location = location;
00040     return a;
00041 }
00042 
00043 /*
00044  * makeSimpleA_Expr -
00045  *      As above, given a simple (unqualified) operator name
00046  */
00047 A_Expr *
00048 makeSimpleA_Expr(A_Expr_Kind kind, char *name,
00049                  Node *lexpr, Node *rexpr, int location)
00050 {
00051     A_Expr     *a = makeNode(A_Expr);
00052 
00053     a->kind = kind;
00054     a->name = list_make1(makeString((char *) name));
00055     a->lexpr = lexpr;
00056     a->rexpr = rexpr;
00057     a->location = location;
00058     return a;
00059 }
00060 
00061 /*
00062  * makeVar -
00063  *    creates a Var node
00064  */
00065 Var *
00066 makeVar(Index varno,
00067         AttrNumber varattno,
00068         Oid vartype,
00069         int32 vartypmod,
00070         Oid varcollid,
00071         Index varlevelsup)
00072 {
00073     Var        *var = makeNode(Var);
00074 
00075     var->varno = varno;
00076     var->varattno = varattno;
00077     var->vartype = vartype;
00078     var->vartypmod = vartypmod;
00079     var->varcollid = varcollid;
00080     var->varlevelsup = varlevelsup;
00081 
00082     /*
00083      * Since few if any routines ever create Var nodes with varnoold/varoattno
00084      * different from varno/varattno, we don't provide separate arguments for
00085      * them, but just initialize them to the given varno/varattno. This
00086      * reduces code clutter and chance of error for most callers.
00087      */
00088     var->varnoold = varno;
00089     var->varoattno = varattno;
00090 
00091     /* Likewise, we just set location to "unknown" here */
00092     var->location = -1;
00093 
00094     return var;
00095 }
00096 
00097 /*
00098  * makeVarFromTargetEntry -
00099  *      convenience function to create a same-level Var node from a
00100  *      TargetEntry
00101  */
00102 Var *
00103 makeVarFromTargetEntry(Index varno,
00104                        TargetEntry *tle)
00105 {
00106     return makeVar(varno,
00107                    tle->resno,
00108                    exprType((Node *) tle->expr),
00109                    exprTypmod((Node *) tle->expr),
00110                    exprCollation((Node *) tle->expr),
00111                    0);
00112 }
00113 
00114 /*
00115  * makeWholeRowVar -
00116  *    creates a Var node representing a whole row of the specified RTE
00117  *
00118  * A whole-row reference is a Var with varno set to the correct range
00119  * table entry, and varattno == 0 to signal that it references the whole
00120  * tuple.  (Use of zero here is unclean, since it could easily be confused
00121  * with error cases, but it's not worth changing now.)  The vartype indicates
00122  * a rowtype; either a named composite type, or RECORD.  This function
00123  * encapsulates the logic for determining the correct rowtype OID to use.
00124  *
00125  * If allowScalar is true, then for the case where the RTE is a function
00126  * returning a non-composite result type, we produce a normal Var referencing
00127  * the function's result directly, instead of the single-column composite
00128  * value that the whole-row notation might otherwise suggest.
00129  */
00130 Var *
00131 makeWholeRowVar(RangeTblEntry *rte,
00132                 Index varno,
00133                 Index varlevelsup,
00134                 bool allowScalar)
00135 {
00136     Var        *result;
00137     Oid         toid;
00138 
00139     switch (rte->rtekind)
00140     {
00141         case RTE_RELATION:
00142             /* relation: the rowtype is a named composite type */
00143             toid = get_rel_type_id(rte->relid);
00144             if (!OidIsValid(toid))
00145                 elog(ERROR, "could not find type OID for relation %u",
00146                      rte->relid);
00147             result = makeVar(varno,
00148                              InvalidAttrNumber,
00149                              toid,
00150                              -1,
00151                              InvalidOid,
00152                              varlevelsup);
00153             break;
00154         case RTE_FUNCTION:
00155             toid = exprType(rte->funcexpr);
00156             if (type_is_rowtype(toid))
00157             {
00158                 /* func returns composite; same as relation case */
00159                 result = makeVar(varno,
00160                                  InvalidAttrNumber,
00161                                  toid,
00162                                  -1,
00163                                  InvalidOid,
00164                                  varlevelsup);
00165             }
00166             else if (allowScalar)
00167             {
00168                 /* func returns scalar; just return its output as-is */
00169                 result = makeVar(varno,
00170                                  1,
00171                                  toid,
00172                                  -1,
00173                                  exprCollation(rte->funcexpr),
00174                                  varlevelsup);
00175             }
00176             else
00177             {
00178                 /* func returns scalar, but we want a composite result */
00179                 result = makeVar(varno,
00180                                  InvalidAttrNumber,
00181                                  RECORDOID,
00182                                  -1,
00183                                  InvalidOid,
00184                                  varlevelsup);
00185             }
00186             break;
00187         default:
00188 
00189             /*
00190              * RTE is a join, subselect, or VALUES.  We represent this as a
00191              * whole-row Var of RECORD type. (Note that in most cases the Var
00192              * will be expanded to a RowExpr during planning, but that is not
00193              * our concern here.)
00194              */
00195             result = makeVar(varno,
00196                              InvalidAttrNumber,
00197                              RECORDOID,
00198                              -1,
00199                              InvalidOid,
00200                              varlevelsup);
00201             break;
00202     }
00203 
00204     return result;
00205 }
00206 
00207 /*
00208  * makeTargetEntry -
00209  *    creates a TargetEntry node
00210  */
00211 TargetEntry *
00212 makeTargetEntry(Expr *expr,
00213                 AttrNumber resno,
00214                 char *resname,
00215                 bool resjunk)
00216 {
00217     TargetEntry *tle = makeNode(TargetEntry);
00218 
00219     tle->expr = expr;
00220     tle->resno = resno;
00221     tle->resname = resname;
00222 
00223     /*
00224      * We always set these fields to 0. If the caller wants to change them he
00225      * must do so explicitly.  Few callers do that, so omitting these
00226      * arguments reduces the chance of error.
00227      */
00228     tle->ressortgroupref = 0;
00229     tle->resorigtbl = InvalidOid;
00230     tle->resorigcol = 0;
00231 
00232     tle->resjunk = resjunk;
00233 
00234     return tle;
00235 }
00236 
00237 /*
00238  * flatCopyTargetEntry -
00239  *    duplicate a TargetEntry, but don't copy substructure
00240  *
00241  * This is commonly used when we just want to modify the resno or substitute
00242  * a new expression.
00243  */
00244 TargetEntry *
00245 flatCopyTargetEntry(TargetEntry *src_tle)
00246 {
00247     TargetEntry *tle = makeNode(TargetEntry);
00248 
00249     Assert(IsA(src_tle, TargetEntry));
00250     memcpy(tle, src_tle, sizeof(TargetEntry));
00251     return tle;
00252 }
00253 
00254 /*
00255  * makeFromExpr -
00256  *    creates a FromExpr node
00257  */
00258 FromExpr *
00259 makeFromExpr(List *fromlist, Node *quals)
00260 {
00261     FromExpr   *f = makeNode(FromExpr);
00262 
00263     f->fromlist = fromlist;
00264     f->quals = quals;
00265     return f;
00266 }
00267 
00268 /*
00269  * makeConst -
00270  *    creates a Const node
00271  */
00272 Const *
00273 makeConst(Oid consttype,
00274           int32 consttypmod,
00275           Oid constcollid,
00276           int constlen,
00277           Datum constvalue,
00278           bool constisnull,
00279           bool constbyval)
00280 {
00281     Const      *cnst = makeNode(Const);
00282 
00283     cnst->consttype = consttype;
00284     cnst->consttypmod = consttypmod;
00285     cnst->constcollid = constcollid;
00286     cnst->constlen = constlen;
00287     cnst->constvalue = constvalue;
00288     cnst->constisnull = constisnull;
00289     cnst->constbyval = constbyval;
00290     cnst->location = -1;        /* "unknown" */
00291 
00292     return cnst;
00293 }
00294 
00295 /*
00296  * makeNullConst -
00297  *    creates a Const node representing a NULL of the specified type/typmod
00298  *
00299  * This is a convenience routine that just saves a lookup of the type's
00300  * storage properties.
00301  */
00302 Const *
00303 makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
00304 {
00305     int16       typLen;
00306     bool        typByVal;
00307 
00308     get_typlenbyval(consttype, &typLen, &typByVal);
00309     return makeConst(consttype,
00310                      consttypmod,
00311                      constcollid,
00312                      (int) typLen,
00313                      (Datum) 0,
00314                      true,
00315                      typByVal);
00316 }
00317 
00318 /*
00319  * makeBoolConst -
00320  *    creates a Const node representing a boolean value (can be NULL too)
00321  */
00322 Node *
00323 makeBoolConst(bool value, bool isnull)
00324 {
00325     /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
00326     return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
00327                               BoolGetDatum(value), isnull, true);
00328 }
00329 
00330 /*
00331  * makeBoolExpr -
00332  *    creates a BoolExpr node
00333  */
00334 Expr *
00335 makeBoolExpr(BoolExprType boolop, List *args, int location)
00336 {
00337     BoolExpr   *b = makeNode(BoolExpr);
00338 
00339     b->boolop = boolop;
00340     b->args = args;
00341     b->location = location;
00342 
00343     return (Expr *) b;
00344 }
00345 
00346 /*
00347  * makeAlias -
00348  *    creates an Alias node
00349  *
00350  * NOTE: the given name is copied, but the colnames list (if any) isn't.
00351  */
00352 Alias *
00353 makeAlias(const char *aliasname, List *colnames)
00354 {
00355     Alias      *a = makeNode(Alias);
00356 
00357     a->aliasname = pstrdup(aliasname);
00358     a->colnames = colnames;
00359 
00360     return a;
00361 }
00362 
00363 /*
00364  * makeRelabelType -
00365  *    creates a RelabelType node
00366  */
00367 RelabelType *
00368 makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
00369                 CoercionForm rformat)
00370 {
00371     RelabelType *r = makeNode(RelabelType);
00372 
00373     r->arg = arg;
00374     r->resulttype = rtype;
00375     r->resulttypmod = rtypmod;
00376     r->resultcollid = rcollid;
00377     r->relabelformat = rformat;
00378     r->location = -1;
00379 
00380     return r;
00381 }
00382 
00383 /*
00384  * makeRangeVar -
00385  *    creates a RangeVar node (rather oversimplified case)
00386  */
00387 RangeVar *
00388 makeRangeVar(char *schemaname, char *relname, int location)
00389 {
00390     RangeVar   *r = makeNode(RangeVar);
00391 
00392     r->catalogname = NULL;
00393     r->schemaname = schemaname;
00394     r->relname = relname;
00395     r->inhOpt = INH_DEFAULT;
00396     r->relpersistence = RELPERSISTENCE_PERMANENT;
00397     r->alias = NULL;
00398     r->location = location;
00399 
00400     return r;
00401 }
00402 
00403 /*
00404  * makeTypeName -
00405  *  build a TypeName node for an unqualified name.
00406  *
00407  * typmod is defaulted, but can be changed later by caller.
00408  */
00409 TypeName *
00410 makeTypeName(char *typnam)
00411 {
00412     return makeTypeNameFromNameList(list_make1(makeString(typnam)));
00413 }
00414 
00415 /*
00416  * makeTypeNameFromNameList -
00417  *  build a TypeName node for a String list representing a qualified name.
00418  *
00419  * typmod is defaulted, but can be changed later by caller.
00420  */
00421 TypeName *
00422 makeTypeNameFromNameList(List *names)
00423 {
00424     TypeName   *n = makeNode(TypeName);
00425 
00426     n->names = names;
00427     n->typmods = NIL;
00428     n->typemod = -1;
00429     n->location = -1;
00430     return n;
00431 }
00432 
00433 /*
00434  * makeTypeNameFromOid -
00435  *  build a TypeName node to represent a type already known by OID/typmod.
00436  */
00437 TypeName *
00438 makeTypeNameFromOid(Oid typeOid, int32 typmod)
00439 {
00440     TypeName   *n = makeNode(TypeName);
00441 
00442     n->typeOid = typeOid;
00443     n->typemod = typmod;
00444     n->location = -1;
00445     return n;
00446 }
00447 
00448 /*
00449  * makeFuncExpr -
00450  *  build an expression tree representing a function call.
00451  *
00452  * The argument expressions must have been transformed already.
00453  */
00454 FuncExpr *
00455 makeFuncExpr(Oid funcid, Oid rettype, List *args,
00456              Oid funccollid, Oid inputcollid, CoercionForm fformat)
00457 {
00458     FuncExpr   *funcexpr;
00459 
00460     funcexpr = makeNode(FuncExpr);
00461     funcexpr->funcid = funcid;
00462     funcexpr->funcresulttype = rettype;
00463     funcexpr->funcretset = false;       /* only allowed case here */
00464     funcexpr->funcvariadic = false;     /* only allowed case here */
00465     funcexpr->funcformat = fformat;
00466     funcexpr->funccollid = funccollid;
00467     funcexpr->inputcollid = inputcollid;
00468     funcexpr->args = args;
00469     funcexpr->location = -1;
00470 
00471     return funcexpr;
00472 }
00473 
00474 /*
00475  * makeDefElem -
00476  *  build a DefElem node
00477  *
00478  * This is sufficient for the "typical" case with an unqualified option name
00479  * and no special action.
00480  */
00481 DefElem *
00482 makeDefElem(char *name, Node *arg)
00483 {
00484     DefElem    *res = makeNode(DefElem);
00485 
00486     res->defnamespace = NULL;
00487     res->defname = name;
00488     res->arg = arg;
00489     res->defaction = DEFELEM_UNSPEC;
00490 
00491     return res;
00492 }
00493 
00494 /*
00495  * makeDefElemExtended -
00496  *  build a DefElem node with all fields available to be specified
00497  */
00498 DefElem *
00499 makeDefElemExtended(char *nameSpace, char *name, Node *arg,
00500                     DefElemAction defaction)
00501 {
00502     DefElem    *res = makeNode(DefElem);
00503 
00504     res->defnamespace = nameSpace;
00505     res->defname = name;
00506     res->arg = arg;
00507     res->defaction = defaction;
00508 
00509     return res;
00510 }