LCOV - code coverage report
Current view: top level - src/backend/nodes - makefuncs.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 199 203 98.0 %
Date: 2017-09-29 13:40:31 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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) 1996-2017, 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 *
      31        3704 : makeA_Expr(A_Expr_Kind kind, List *name,
      32             :            Node *lexpr, Node *rexpr, int location)
      33             : {
      34        3704 :     A_Expr     *a = makeNode(A_Expr);
      35             : 
      36        3704 :     a->kind = kind;
      37        3704 :     a->name = name;
      38        3704 :     a->lexpr = lexpr;
      39        3704 :     a->rexpr = rexpr;
      40        3704 :     a->location = location;
      41        3704 :     return a;
      42             : }
      43             : 
      44             : /*
      45             :  * makeSimpleA_Expr -
      46             :  *      As above, given a simple (unqualified) operator name
      47             :  */
      48             : A_Expr *
      49       16729 : makeSimpleA_Expr(A_Expr_Kind kind, char *name,
      50             :                  Node *lexpr, Node *rexpr, int location)
      51             : {
      52       16729 :     A_Expr     *a = makeNode(A_Expr);
      53             : 
      54       16729 :     a->kind = kind;
      55       16729 :     a->name = list_make1(makeString((char *) name));
      56       16729 :     a->lexpr = lexpr;
      57       16729 :     a->rexpr = rexpr;
      58       16729 :     a->location = location;
      59       16729 :     return a;
      60             : }
      61             : 
      62             : /*
      63             :  * makeVar -
      64             :  *    creates a Var node
      65             :  */
      66             : Var *
      67      233579 : makeVar(Index varno,
      68             :         AttrNumber varattno,
      69             :         Oid vartype,
      70             :         int32 vartypmod,
      71             :         Oid varcollid,
      72             :         Index varlevelsup)
      73             : {
      74      233579 :     Var        *var = makeNode(Var);
      75             : 
      76      233579 :     var->varno = varno;
      77      233579 :     var->varattno = varattno;
      78      233579 :     var->vartype = vartype;
      79      233579 :     var->vartypmod = vartypmod;
      80      233579 :     var->varcollid = varcollid;
      81      233579 :     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      233579 :     var->varnoold = varno;
      90      233579 :     var->varoattno = varattno;
      91             : 
      92             :     /* Likewise, we just set location to "unknown" here */
      93      233579 :     var->location = -1;
      94             : 
      95      233579 :     return var;
      96             : }
      97             : 
      98             : /*
      99             :  * makeVarFromTargetEntry -
     100             :  *      convenience function to create a same-level Var node from a
     101             :  *      TargetEntry
     102             :  */
     103             : Var *
     104        2868 : makeVarFromTargetEntry(Index varno,
     105             :                        TargetEntry *tle)
     106             : {
     107       11472 :     return makeVar(varno,
     108        2868 :                    tle->resno,
     109        2868 :                    exprType((Node *) tle->expr),
     110        2868 :                    exprTypmod((Node *) tle->expr),
     111        2868 :                    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 RECORD.  This function
     124             :  * encapsulates the logic for determining the correct rowtype OID to use.
     125             :  *
     126             :  * If allowScalar is true, then for the case where the RTE is a single function
     127             :  * returning a non-composite result type, we produce a normal Var referencing
     128             :  * the function's result directly, instead of the single-column composite
     129             :  * value that the whole-row notation might otherwise suggest.
     130             :  */
     131             : Var *
     132         574 : makeWholeRowVar(RangeTblEntry *rte,
     133             :                 Index varno,
     134             :                 Index varlevelsup,
     135             :                 bool allowScalar)
     136             : {
     137             :     Var        *result;
     138             :     Oid         toid;
     139             :     Node       *fexpr;
     140             : 
     141         574 :     switch (rte->rtekind)
     142             :     {
     143             :         case RTE_RELATION:
     144             :             /* relation: the rowtype is a named composite type */
     145         440 :             toid = get_rel_type_id(rte->relid);
     146         440 :             if (!OidIsValid(toid))
     147           0 :                 elog(ERROR, "could not find type OID for relation %u",
     148             :                      rte->relid);
     149         440 :             result = makeVar(varno,
     150             :                              InvalidAttrNumber,
     151             :                              toid,
     152             :                              -1,
     153             :                              InvalidOid,
     154             :                              varlevelsup);
     155         440 :             break;
     156             : 
     157             :         case RTE_FUNCTION:
     158             : 
     159             :             /*
     160             :              * If there's more than one function, or ordinality is requested,
     161             :              * force a RECORD result, since there's certainly more than one
     162             :              * column involved and it can't be a known named type.
     163             :              */
     164           9 :             if (rte->funcordinality || list_length(rte->functions) != 1)
     165             :             {
     166             :                 /* always produces an anonymous RECORD result */
     167           1 :                 result = makeVar(varno,
     168             :                                  InvalidAttrNumber,
     169             :                                  RECORDOID,
     170             :                                  -1,
     171             :                                  InvalidOid,
     172             :                                  varlevelsup);
     173           1 :                 break;
     174             :             }
     175             : 
     176           8 :             fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
     177           8 :             toid = exprType(fexpr);
     178           8 :             if (type_is_rowtype(toid))
     179             :             {
     180             :                 /* func returns composite; same as relation case */
     181           8 :                 result = makeVar(varno,
     182             :                                  InvalidAttrNumber,
     183             :                                  toid,
     184             :                                  -1,
     185             :                                  InvalidOid,
     186             :                                  varlevelsup);
     187             :             }
     188           0 :             else if (allowScalar)
     189             :             {
     190             :                 /* func returns scalar; just return its output as-is */
     191           0 :                 result = makeVar(varno,
     192             :                                  1,
     193             :                                  toid,
     194             :                                  -1,
     195             :                                  exprCollation(fexpr),
     196             :                                  varlevelsup);
     197             :             }
     198             :             else
     199             :             {
     200             :                 /* func returns scalar, but we want a composite result */
     201           0 :                 result = makeVar(varno,
     202             :                                  InvalidAttrNumber,
     203             :                                  RECORDOID,
     204             :                                  -1,
     205             :                                  InvalidOid,
     206             :                                  varlevelsup);
     207             :             }
     208           8 :             break;
     209             : 
     210             :         default:
     211             : 
     212             :             /*
     213             :              * RTE is a join, subselect, tablefunc, or VALUES.  We represent
     214             :              * this as a whole-row Var of RECORD type. (Note that in most
     215             :              * cases the Var will be expanded to a RowExpr during planning,
     216             :              * but that is not our concern here.)
     217             :              */
     218         125 :             result = makeVar(varno,
     219             :                              InvalidAttrNumber,
     220             :                              RECORDOID,
     221             :                              -1,
     222             :                              InvalidOid,
     223             :                              varlevelsup);
     224         125 :             break;
     225             :     }
     226             : 
     227         574 :     return result;
     228             : }
     229             : 
     230             : /*
     231             :  * makeTargetEntry -
     232             :  *    creates a TargetEntry node
     233             :  */
     234             : TargetEntry *
     235      233459 : makeTargetEntry(Expr *expr,
     236             :                 AttrNumber resno,
     237             :                 char *resname,
     238             :                 bool resjunk)
     239             : {
     240      233459 :     TargetEntry *tle = makeNode(TargetEntry);
     241             : 
     242      233459 :     tle->expr = expr;
     243      233459 :     tle->resno = resno;
     244      233459 :     tle->resname = resname;
     245             : 
     246             :     /*
     247             :      * We always set these fields to 0. If the caller wants to change them he
     248             :      * must do so explicitly.  Few callers do that, so omitting these
     249             :      * arguments reduces the chance of error.
     250             :      */
     251      233459 :     tle->ressortgroupref = 0;
     252      233459 :     tle->resorigtbl = InvalidOid;
     253      233459 :     tle->resorigcol = 0;
     254             : 
     255      233459 :     tle->resjunk = resjunk;
     256             : 
     257      233459 :     return tle;
     258             : }
     259             : 
     260             : /*
     261             :  * flatCopyTargetEntry -
     262             :  *    duplicate a TargetEntry, but don't copy substructure
     263             :  *
     264             :  * This is commonly used when we just want to modify the resno or substitute
     265             :  * a new expression.
     266             :  */
     267             : TargetEntry *
     268       22615 : flatCopyTargetEntry(TargetEntry *src_tle)
     269             : {
     270       22615 :     TargetEntry *tle = makeNode(TargetEntry);
     271             : 
     272       22615 :     Assert(IsA(src_tle, TargetEntry));
     273       22615 :     memcpy(tle, src_tle, sizeof(TargetEntry));
     274       22615 :     return tle;
     275             : }
     276             : 
     277             : /*
     278             :  * makeFromExpr -
     279             :  *    creates a FromExpr node
     280             :  */
     281             : FromExpr *
     282       30929 : makeFromExpr(List *fromlist, Node *quals)
     283             : {
     284       30929 :     FromExpr   *f = makeNode(FromExpr);
     285             : 
     286       30929 :     f->fromlist = fromlist;
     287       30929 :     f->quals = quals;
     288       30929 :     return f;
     289             : }
     290             : 
     291             : /*
     292             :  * makeConst -
     293             :  *    creates a Const node
     294             :  */
     295             : Const *
     296       58424 : makeConst(Oid consttype,
     297             :           int32 consttypmod,
     298             :           Oid constcollid,
     299             :           int constlen,
     300             :           Datum constvalue,
     301             :           bool constisnull,
     302             :           bool constbyval)
     303             : {
     304       58424 :     Const      *cnst = makeNode(Const);
     305             : 
     306             :     /*
     307             :      * If it's a varlena value, force it to be in non-expanded (non-toasted)
     308             :      * format; this avoids any possible dependency on external values and
     309             :      * improves consistency of representation, which is important for equal().
     310             :      */
     311       58424 :     if (!constisnull && constlen == -1)
     312        6808 :         constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
     313             : 
     314       58424 :     cnst->consttype = consttype;
     315       58424 :     cnst->consttypmod = consttypmod;
     316       58424 :     cnst->constcollid = constcollid;
     317       58424 :     cnst->constlen = constlen;
     318       58424 :     cnst->constvalue = constvalue;
     319       58424 :     cnst->constisnull = constisnull;
     320       58424 :     cnst->constbyval = constbyval;
     321       58424 :     cnst->location = -1;     /* "unknown" */
     322             : 
     323       58424 :     return cnst;
     324             : }
     325             : 
     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         415 : makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
     335             : {
     336             :     int16       typLen;
     337             :     bool        typByVal;
     338             : 
     339         415 :     get_typlenbyval(consttype, &typLen, &typByVal);
     340         415 :     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         215 : makeBoolConst(bool value, bool isnull)
     355             : {
     356             :     /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
     357         215 :     return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
     358             :                               BoolGetDatum(value), isnull, true);
     359             : }
     360             : 
     361             : /*
     362             :  * makeBoolExpr -
     363             :  *    creates a BoolExpr node
     364             :  */
     365             : Expr *
     366        9896 : makeBoolExpr(BoolExprType boolop, List *args, int location)
     367             : {
     368        9896 :     BoolExpr   *b = makeNode(BoolExpr);
     369             : 
     370        9896 :     b->boolop = boolop;
     371        9896 :     b->args = args;
     372        9896 :     b->location = location;
     373             : 
     374        9896 :     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 *
     384       30099 : makeAlias(const char *aliasname, List *colnames)
     385             : {
     386       30099 :     Alias      *a = makeNode(Alias);
     387             : 
     388       30099 :     a->aliasname = pstrdup(aliasname);
     389       30099 :     a->colnames = colnames;
     390             : 
     391       30099 :     return a;
     392             : }
     393             : 
     394             : /*
     395             :  * makeRelabelType -
     396             :  *    creates a RelabelType node
     397             :  */
     398             : RelabelType *
     399        4266 : makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
     400             :                 CoercionForm rformat)
     401             : {
     402        4266 :     RelabelType *r = makeNode(RelabelType);
     403             : 
     404        4266 :     r->arg = arg;
     405        4266 :     r->resulttype = rtype;
     406        4266 :     r->resulttypmod = rtypmod;
     407        4266 :     r->resultcollid = rcollid;
     408        4266 :     r->relabelformat = rformat;
     409        4266 :     r->location = -1;
     410             : 
     411        4266 :     return r;
     412             : }
     413             : 
     414             : /*
     415             :  * makeRangeVar -
     416             :  *    creates a RangeVar node (rather oversimplified case)
     417             :  */
     418             : RangeVar *
     419       26823 : makeRangeVar(char *schemaname, char *relname, int location)
     420             : {
     421       26823 :     RangeVar   *r = makeNode(RangeVar);
     422             : 
     423       26823 :     r->catalogname = NULL;
     424       26823 :     r->schemaname = schemaname;
     425       26823 :     r->relname = relname;
     426       26823 :     r->inh = true;
     427       26823 :     r->relpersistence = RELPERSISTENCE_PERMANENT;
     428       26823 :     r->alias = NULL;
     429       26823 :     r->location = location;
     430             : 
     431       26823 :     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 *
     441        8600 : makeTypeName(char *typnam)
     442             : {
     443        8600 :     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 *
     453       20438 : makeTypeNameFromNameList(List *names)
     454             : {
     455       20438 :     TypeName   *n = makeNode(TypeName);
     456             : 
     457       20438 :     n->names = names;
     458       20438 :     n->typmods = NIL;
     459       20438 :     n->typemod = -1;
     460       20438 :     n->location = -1;
     461       20438 :     return n;
     462             : }
     463             : 
     464             : /*
     465             :  * makeTypeNameFromOid -
     466             :  *  build a TypeName node to represent a type already known by OID/typmod.
     467             :  */
     468             : TypeName *
     469        3510 : makeTypeNameFromOid(Oid typeOid, int32 typmod)
     470             : {
     471        3510 :     TypeName   *n = makeNode(TypeName);
     472             : 
     473        3510 :     n->typeOid = typeOid;
     474        3510 :     n->typemod = typmod;
     475        3510 :     n->location = -1;
     476        3510 :     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 *
     487        2356 : makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
     488             : {
     489        2356 :     ColumnDef  *n = makeNode(ColumnDef);
     490             : 
     491        2356 :     n->colname = pstrdup(colname);
     492        2356 :     n->typeName = makeTypeNameFromOid(typeOid, typmod);
     493        2356 :     n->inhcount = 0;
     494        2356 :     n->is_local = true;
     495        2356 :     n->is_not_null = false;
     496        2356 :     n->is_from_type = false;
     497        2356 :     n->is_from_parent = false;
     498        2356 :     n->storage = 0;
     499        2356 :     n->raw_default = NULL;
     500        2356 :     n->cooked_default = NULL;
     501        2356 :     n->collClause = NULL;
     502        2356 :     n->collOid = collOid;
     503        2356 :     n->constraints = NIL;
     504        2356 :     n->fdwoptions = NIL;
     505        2356 :     n->location = -1;
     506             : 
     507        2356 :     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 *
     517        9302 : makeFuncExpr(Oid funcid, Oid rettype, List *args,
     518             :              Oid funccollid, Oid inputcollid, CoercionForm fformat)
     519             : {
     520             :     FuncExpr   *funcexpr;
     521             : 
     522        9302 :     funcexpr = makeNode(FuncExpr);
     523        9302 :     funcexpr->funcid = funcid;
     524        9302 :     funcexpr->funcresulttype = rettype;
     525        9302 :     funcexpr->funcretset = false;    /* only allowed case here */
     526        9302 :     funcexpr->funcvariadic = false; /* only allowed case here */
     527        9302 :     funcexpr->funcformat = fformat;
     528        9302 :     funcexpr->funccollid = funccollid;
     529        9302 :     funcexpr->inputcollid = inputcollid;
     530        9302 :     funcexpr->args = args;
     531        9302 :     funcexpr->location = -1;
     532             : 
     533        9302 :     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 *
     544        5251 : makeDefElem(char *name, Node *arg, int location)
     545             : {
     546        5251 :     DefElem    *res = makeNode(DefElem);
     547             : 
     548        5251 :     res->defnamespace = NULL;
     549        5251 :     res->defname = name;
     550        5251 :     res->arg = arg;
     551        5251 :     res->defaction = DEFELEM_UNSPEC;
     552        5251 :     res->location = location;
     553             : 
     554        5251 :     return res;
     555             : }
     556             : 
     557             : /*
     558             :  * makeDefElemExtended -
     559             :  *  build a DefElem node with all fields available to be specified
     560             :  */
     561             : DefElem *
     562          13 : makeDefElemExtended(char *nameSpace, char *name, Node *arg,
     563             :                     DefElemAction defaction, int location)
     564             : {
     565          13 :     DefElem    *res = makeNode(DefElem);
     566             : 
     567          13 :     res->defnamespace = nameSpace;
     568          13 :     res->defname = name;
     569          13 :     res->arg = arg;
     570          13 :     res->defaction = defaction;
     571          13 :     res->location = location;
     572             : 
     573          13 :     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 *
     583       17499 : makeFuncCall(List *name, List *args, int location)
     584             : {
     585       17499 :     FuncCall   *n = makeNode(FuncCall);
     586             : 
     587       17499 :     n->funcname = name;
     588       17499 :     n->args = args;
     589       17499 :     n->agg_order = NIL;
     590       17499 :     n->agg_filter = NULL;
     591       17499 :     n->agg_within_group = false;
     592       17499 :     n->agg_star = false;
     593       17499 :     n->agg_distinct = false;
     594       17499 :     n->func_variadic = false;
     595       17499 :     n->over = NULL;
     596       17499 :     n->location = location;
     597       17499 :     return n;
     598             : }
     599             : 
     600             : /*
     601             :  * makeGroupingSet
     602             :  *
     603             :  */
     604             : GroupingSet *
     605         596 : makeGroupingSet(GroupingSetKind kind, List *content, int location)
     606             : {
     607         596 :     GroupingSet *n = makeNode(GroupingSet);
     608             : 
     609         596 :     n->kind = kind;
     610         596 :     n->content = content;
     611         596 :     n->location = location;
     612         596 :     return n;
     613             : }

Generated by: LCOV version 1.11