LCOV - code coverage report
Current view: top level - src/backend/nodes - makefuncs.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta1 Lines: 255 260 98.1 %
Date: 2019-06-16 15:06:48 Functions: 32 32 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-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 *
      31       61570 : makeA_Expr(A_Expr_Kind kind, List *name,
      32             :            Node *lexpr, Node *rexpr, int location)
      33             : {
      34       61570 :     A_Expr     *a = makeNode(A_Expr);
      35             : 
      36       61570 :     a->kind = kind;
      37       61570 :     a->name = name;
      38       61570 :     a->lexpr = lexpr;
      39       61570 :     a->rexpr = rexpr;
      40       61570 :     a->location = location;
      41       61570 :     return a;
      42             : }
      43             : 
      44             : /*
      45             :  * makeSimpleA_Expr -
      46             :  *      As above, given a simple (unqualified) operator name
      47             :  */
      48             : A_Expr *
      49      468694 : makeSimpleA_Expr(A_Expr_Kind kind, char *name,
      50             :                  Node *lexpr, Node *rexpr, int location)
      51             : {
      52      468694 :     A_Expr     *a = makeNode(A_Expr);
      53             : 
      54      468694 :     a->kind = kind;
      55      468694 :     a->name = list_make1(makeString((char *) name));
      56      468694 :     a->lexpr = lexpr;
      57      468694 :     a->rexpr = rexpr;
      58      468694 :     a->location = location;
      59      468694 :     return a;
      60             : }
      61             : 
      62             : /*
      63             :  * makeVar -
      64             :  *    creates a Var node
      65             :  */
      66             : Var *
      67     8234696 : makeVar(Index varno,
      68             :         AttrNumber varattno,
      69             :         Oid vartype,
      70             :         int32 vartypmod,
      71             :         Oid varcollid,
      72             :         Index varlevelsup)
      73             : {
      74     8234696 :     Var        *var = makeNode(Var);
      75             : 
      76     8234696 :     var->varno = varno;
      77     8234696 :     var->varattno = varattno;
      78     8234696 :     var->vartype = vartype;
      79     8234696 :     var->vartypmod = vartypmod;
      80     8234696 :     var->varcollid = varcollid;
      81     8234696 :     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     8234696 :     var->varnoold = varno;
      90     8234696 :     var->varoattno = varattno;
      91             : 
      92             :     /* Likewise, we just set location to "unknown" here */
      93     8234696 :     var->location = -1;
      94             : 
      95     8234696 :     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       84050 : makeVarFromTargetEntry(Index varno,
     105             :                        TargetEntry *tle)
     106             : {
     107      336200 :     return makeVar(varno,
     108       84050 :                    tle->resno,
     109       84050 :                    exprType((Node *) tle->expr),
     110       84050 :                    exprTypmod((Node *) tle->expr),
     111       84050 :                    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 *
     134       20244 : makeWholeRowVar(RangeTblEntry *rte,
     135             :                 Index varno,
     136             :                 Index varlevelsup,
     137             :                 bool allowScalar)
     138             : {
     139             :     Var        *result;
     140             :     Oid         toid;
     141             :     Node       *fexpr;
     142             : 
     143       20244 :     switch (rte->rtekind)
     144             :     {
     145             :         case RTE_RELATION:
     146             :             /* relation: the rowtype is a named composite type */
     147       19456 :             toid = get_rel_type_id(rte->relid);
     148       19456 :             if (!OidIsValid(toid))
     149           0 :                 elog(ERROR, "could not find type OID for relation %u",
     150             :                      rte->relid);
     151       19456 :             result = makeVar(varno,
     152             :                              InvalidAttrNumber,
     153             :                              toid,
     154             :                              -1,
     155             :                              InvalidOid,
     156             :                              varlevelsup);
     157       19456 :             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          38 :             if (rte->funcordinality || list_length(rte->functions) != 1)
     167             :             {
     168             :                 /* always produces an anonymous RECORD result */
     169           4 :                 result = makeVar(varno,
     170             :                                  InvalidAttrNumber,
     171             :                                  RECORDOID,
     172             :                                  -1,
     173             :                                  InvalidOid,
     174             :                                  varlevelsup);
     175           4 :                 break;
     176             :             }
     177             : 
     178          34 :             fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
     179          34 :             toid = exprType(fexpr);
     180          34 :             if (type_is_rowtype(toid))
     181             :             {
     182             :                 /* func returns composite; same as relation case */
     183          32 :                 result = makeVar(varno,
     184             :                                  InvalidAttrNumber,
     185             :                                  toid,
     186             :                                  -1,
     187             :                                  InvalidOid,
     188             :                                  varlevelsup);
     189             :             }
     190           2 :             else if (allowScalar)
     191             :             {
     192             :                 /* func returns scalar; just return its output as-is */
     193           2 :                 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           0 :                 result = makeVar(varno,
     204             :                                  InvalidAttrNumber,
     205             :                                  RECORDOID,
     206             :                                  -1,
     207             :                                  InvalidOid,
     208             :                                  varlevelsup);
     209             :             }
     210          34 :             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         750 :             result = makeVar(varno,
     221             :                              InvalidAttrNumber,
     222             :                              RECORDOID,
     223             :                              -1,
     224             :                              InvalidOid,
     225             :                              varlevelsup);
     226         750 :             break;
     227             :     }
     228             : 
     229       20244 :     return result;
     230             : }
     231             : 
     232             : /*
     233             :  * makeTargetEntry -
     234             :  *    creates a TargetEntry node
     235             :  */
     236             : TargetEntry *
     237     5302706 : makeTargetEntry(Expr *expr,
     238             :                 AttrNumber resno,
     239             :                 char *resname,
     240             :                 bool resjunk)
     241             : {
     242     5302706 :     TargetEntry *tle = makeNode(TargetEntry);
     243             : 
     244     5302706 :     tle->expr = expr;
     245     5302706 :     tle->resno = resno;
     246     5302706 :     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     5302706 :     tle->ressortgroupref = 0;
     254     5302706 :     tle->resorigtbl = InvalidOid;
     255     5302706 :     tle->resorigcol = 0;
     256             : 
     257     5302706 :     tle->resjunk = resjunk;
     258             : 
     259     5302706 :     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 *
     270      325370 : flatCopyTargetEntry(TargetEntry *src_tle)
     271             : {
     272      325370 :     TargetEntry *tle = makeNode(TargetEntry);
     273             : 
     274             :     Assert(IsA(src_tle, TargetEntry));
     275      325370 :     memcpy(tle, src_tle, sizeof(TargetEntry));
     276      325370 :     return tle;
     277             : }
     278             : 
     279             : /*
     280             :  * makeFromExpr -
     281             :  *    creates a FromExpr node
     282             :  */
     283             : FromExpr *
     284      462550 : makeFromExpr(List *fromlist, Node *quals)
     285             : {
     286      462550 :     FromExpr   *f = makeNode(FromExpr);
     287             : 
     288      462550 :     f->fromlist = fromlist;
     289      462550 :     f->quals = quals;
     290      462550 :     return f;
     291             : }
     292             : 
     293             : /*
     294             :  * makeConst -
     295             :  *    creates a Const node
     296             :  */
     297             : Const *
     298     1198158 : makeConst(Oid consttype,
     299             :           int32 consttypmod,
     300             :           Oid constcollid,
     301             :           int constlen,
     302             :           Datum constvalue,
     303             :           bool constisnull,
     304             :           bool constbyval)
     305             : {
     306     1198158 :     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     1198158 :     if (!constisnull && constlen == -1)
     314       61340 :         constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
     315             : 
     316     1198158 :     cnst->consttype = consttype;
     317     1198158 :     cnst->consttypmod = consttypmod;
     318     1198158 :     cnst->constcollid = constcollid;
     319     1198158 :     cnst->constlen = constlen;
     320     1198158 :     cnst->constvalue = constvalue;
     321     1198158 :     cnst->constisnull = constisnull;
     322     1198158 :     cnst->constbyval = constbyval;
     323     1198158 :     cnst->location = -1;     /* "unknown" */
     324             : 
     325     1198158 :     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 *
     336        5132 : makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
     337             : {
     338             :     int16       typLen;
     339             :     bool        typByVal;
     340             : 
     341        5132 :     get_typlenbyval(consttype, &typLen, &typByVal);
     342        5132 :     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 *
     356        2896 : makeBoolConst(bool value, bool isnull)
     357             : {
     358             :     /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
     359        2896 :     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 *
     368      301908 : makeBoolExpr(BoolExprType boolop, List *args, int location)
     369             : {
     370      301908 :     BoolExpr   *b = makeNode(BoolExpr);
     371             : 
     372      301908 :     b->boolop = boolop;
     373      301908 :     b->args = args;
     374      301908 :     b->location = location;
     375             : 
     376      301908 :     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 *
     386      893350 : makeAlias(const char *aliasname, List *colnames)
     387             : {
     388      893350 :     Alias      *a = makeNode(Alias);
     389             : 
     390      893350 :     a->aliasname = pstrdup(aliasname);
     391      893350 :     a->colnames = colnames;
     392             : 
     393      893350 :     return a;
     394             : }
     395             : 
     396             : /*
     397             :  * makeRelabelType -
     398             :  *    creates a RelabelType node
     399             :  */
     400             : RelabelType *
     401      107592 : makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
     402             :                 CoercionForm rformat)
     403             : {
     404      107592 :     RelabelType *r = makeNode(RelabelType);
     405             : 
     406      107592 :     r->arg = arg;
     407      107592 :     r->resulttype = rtype;
     408      107592 :     r->resulttypmod = rtypmod;
     409      107592 :     r->resultcollid = rcollid;
     410      107592 :     r->relabelformat = rformat;
     411      107592 :     r->location = -1;
     412             : 
     413      107592 :     return r;
     414             : }
     415             : 
     416             : /*
     417             :  * makeRangeVar -
     418             :  *    creates a RangeVar node (rather oversimplified case)
     419             :  */
     420             : RangeVar *
     421      639284 : makeRangeVar(char *schemaname, char *relname, int location)
     422             : {
     423      639284 :     RangeVar   *r = makeNode(RangeVar);
     424             : 
     425      639284 :     r->catalogname = NULL;
     426      639284 :     r->schemaname = schemaname;
     427      639284 :     r->relname = relname;
     428      639284 :     r->inh = true;
     429      639284 :     r->relpersistence = RELPERSISTENCE_PERMANENT;
     430      639284 :     r->alias = NULL;
     431      639284 :     r->location = location;
     432             : 
     433      639284 :     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 *
     443      395986 : makeTypeName(char *typnam)
     444             : {
     445      395986 :     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 *
     455      599614 : makeTypeNameFromNameList(List *names)
     456             : {
     457      599614 :     TypeName   *n = makeNode(TypeName);
     458             : 
     459      599614 :     n->names = names;
     460      599614 :     n->typmods = NIL;
     461      599614 :     n->typemod = -1;
     462      599614 :     n->location = -1;
     463      599614 :     return n;
     464             : }
     465             : 
     466             : /*
     467             :  * makeTypeNameFromOid -
     468             :  *  build a TypeName node to represent a type already known by OID/typmod.
     469             :  */
     470             : TypeName *
     471      410730 : makeTypeNameFromOid(Oid typeOid, int32 typmod)
     472             : {
     473      410730 :     TypeName   *n = makeNode(TypeName);
     474             : 
     475      410730 :     n->typeOid = typeOid;
     476      410730 :     n->typemod = typmod;
     477      410730 :     n->location = -1;
     478      410730 :     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 *
     489      398124 : makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
     490             : {
     491      398124 :     ColumnDef  *n = makeNode(ColumnDef);
     492             : 
     493      398124 :     n->colname = pstrdup(colname);
     494      398124 :     n->typeName = makeTypeNameFromOid(typeOid, typmod);
     495      398124 :     n->inhcount = 0;
     496      398124 :     n->is_local = true;
     497      398124 :     n->is_not_null = false;
     498      398124 :     n->is_from_type = false;
     499      398124 :     n->storage = 0;
     500      398124 :     n->raw_default = NULL;
     501      398124 :     n->cooked_default = NULL;
     502      398124 :     n->collClause = NULL;
     503      398124 :     n->collOid = collOid;
     504      398124 :     n->constraints = NIL;
     505      398124 :     n->fdwoptions = NIL;
     506      398124 :     n->location = -1;
     507             : 
     508      398124 :     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 *
     518      138408 : makeFuncExpr(Oid funcid, Oid rettype, List *args,
     519             :              Oid funccollid, Oid inputcollid, CoercionForm fformat)
     520             : {
     521             :     FuncExpr   *funcexpr;
     522             : 
     523      138408 :     funcexpr = makeNode(FuncExpr);
     524      138408 :     funcexpr->funcid = funcid;
     525      138408 :     funcexpr->funcresulttype = rettype;
     526      138408 :     funcexpr->funcretset = false;    /* only allowed case here */
     527      138408 :     funcexpr->funcvariadic = false; /* only allowed case here */
     528      138408 :     funcexpr->funcformat = fformat;
     529      138408 :     funcexpr->funccollid = funccollid;
     530      138408 :     funcexpr->inputcollid = inputcollid;
     531      138408 :     funcexpr->args = args;
     532      138408 :     funcexpr->location = -1;
     533             : 
     534      138408 :     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 *
     545      174596 : makeDefElem(char *name, Node *arg, int location)
     546             : {
     547      174596 :     DefElem    *res = makeNode(DefElem);
     548             : 
     549      174596 :     res->defnamespace = NULL;
     550      174596 :     res->defname = name;
     551      174596 :     res->arg = arg;
     552      174596 :     res->defaction = DEFELEM_UNSPEC;
     553      174596 :     res->location = location;
     554             : 
     555      174596 :     return res;
     556             : }
     557             : 
     558             : /*
     559             :  * makeDefElemExtended -
     560             :  *  build a DefElem node with all fields available to be specified
     561             :  */
     562             : DefElem *
     563         100 : makeDefElemExtended(char *nameSpace, char *name, Node *arg,
     564             :                     DefElemAction defaction, int location)
     565             : {
     566         100 :     DefElem    *res = makeNode(DefElem);
     567             : 
     568         100 :     res->defnamespace = nameSpace;
     569         100 :     res->defname = name;
     570         100 :     res->arg = arg;
     571         100 :     res->defaction = defaction;
     572         100 :     res->location = location;
     573             : 
     574         100 :     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 *
     584      388278 : makeFuncCall(List *name, List *args, int location)
     585             : {
     586      388278 :     FuncCall   *n = makeNode(FuncCall);
     587             : 
     588      388278 :     n->funcname = name;
     589      388278 :     n->args = args;
     590      388278 :     n->agg_order = NIL;
     591      388278 :     n->agg_filter = NULL;
     592      388278 :     n->agg_within_group = false;
     593      388278 :     n->agg_star = false;
     594      388278 :     n->agg_distinct = false;
     595      388278 :     n->func_variadic = false;
     596      388278 :     n->over = NULL;
     597      388278 :     n->location = location;
     598      388278 :     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 *
     608       88390 : make_opclause(Oid opno, Oid opresulttype, bool opretset,
     609             :               Expr *leftop, Expr *rightop,
     610             :               Oid opcollid, Oid inputcollid)
     611             : {
     612       88390 :     OpExpr     *expr = makeNode(OpExpr);
     613             : 
     614       88390 :     expr->opno = opno;
     615       88390 :     expr->opfuncid = InvalidOid;
     616       88390 :     expr->opresulttype = opresulttype;
     617       88390 :     expr->opretset = opretset;
     618       88390 :     expr->opcollid = opcollid;
     619       88390 :     expr->inputcollid = inputcollid;
     620       88390 :     if (rightop)
     621       88390 :         expr->args = list_make2(leftop, rightop);
     622             :     else
     623           0 :         expr->args = list_make1(leftop);
     624       88390 :     expr->location = -1;
     625       88390 :     return (Expr *) expr;
     626             : }
     627             : 
     628             : /*
     629             :  * make_andclause
     630             :  *
     631             :  * Creates an 'and' clause given a list of its subclauses.
     632             :  */
     633             : Expr *
     634      187324 : make_andclause(List *andclauses)
     635             : {
     636      187324 :     BoolExpr   *expr = makeNode(BoolExpr);
     637             : 
     638      187324 :     expr->boolop = AND_EXPR;
     639      187324 :     expr->args = andclauses;
     640      187324 :     expr->location = -1;
     641      187324 :     return (Expr *) expr;
     642             : }
     643             : 
     644             : /*
     645             :  * make_orclause
     646             :  *
     647             :  * Creates an 'or' clause given a list of its subclauses.
     648             :  */
     649             : Expr *
     650       20754 : make_orclause(List *orclauses)
     651             : {
     652       20754 :     BoolExpr   *expr = makeNode(BoolExpr);
     653             : 
     654       20754 :     expr->boolop = OR_EXPR;
     655       20754 :     expr->args = orclauses;
     656       20754 :     expr->location = -1;
     657       20754 :     return (Expr *) expr;
     658             : }
     659             : 
     660             : /*
     661             :  * make_notclause
     662             :  *
     663             :  * Create a 'not' clause given the expression to be negated.
     664             :  */
     665             : Expr *
     666       10536 : make_notclause(Expr *notclause)
     667             : {
     668       10536 :     BoolExpr   *expr = makeNode(BoolExpr);
     669             : 
     670       10536 :     expr->boolop = NOT_EXPR;
     671       10536 :     expr->args = list_make1(notclause);
     672       10536 :     expr->location = -1;
     673       10536 :     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 *
     687        1688 : make_and_qual(Node *qual1, Node *qual2)
     688             : {
     689        1688 :     if (qual1 == NULL)
     690         756 :         return qual2;
     691         932 :     if (qual2 == NULL)
     692           0 :         return qual1;
     693         932 :     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 *
     706       21822 : make_ands_explicit(List *andclauses)
     707             : {
     708       21822 :     if (andclauses == NIL)
     709           0 :         return (Expr *) makeBoolConst(true, false);
     710       21822 :     else if (list_length(andclauses) == 1)
     711       16334 :         return (Expr *) linitial(andclauses);
     712             :     else
     713        5488 :         return make_andclause(andclauses);
     714             : }
     715             : 
     716             : List *
     717      295086 : 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      295086 :     if (clause == NULL)
     725       90002 :         return NIL;             /* NULL -> NIL list == TRUE */
     726      205084 :     else if (is_andclause(clause))
     727       65646 :         return ((BoolExpr *) clause)->args;
     728      140530 :     else if (IsA(clause, Const) &&
     729        2184 :              !((Const *) clause)->constisnull &&
     730        1092 :              DatumGetBool(((Const *) clause)->constvalue))
     731         594 :         return NIL;             /* constant TRUE input -> NIL list */
     732             :     else
     733      138844 :         return list_make1(clause);
     734             : }
     735             : 
     736             : /*
     737             :  * makeGroupingSet
     738             :  *
     739             :  */
     740             : GroupingSet *
     741        2632 : makeGroupingSet(GroupingSetKind kind, List *content, int location)
     742             : {
     743        2632 :     GroupingSet *n = makeNode(GroupingSet);
     744             : 
     745        2632 :     n->kind = kind;
     746        2632 :     n->content = content;
     747        2632 :     n->location = location;
     748        2632 :     return n;
     749             : }
     750             : 
     751             : /*
     752             :  * makeVacuumRelation -
     753             :  *    create a VacuumRelation node
     754             :  */
     755             : VacuumRelation *
     756       70018 : makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
     757             : {
     758       70018 :     VacuumRelation *v = makeNode(VacuumRelation);
     759             : 
     760       70018 :     v->relation = relation;
     761       70018 :     v->oid = oid;
     762       70018 :     v->va_cols = va_cols;
     763       70018 :     return v;
     764             : }

Generated by: LCOV version 1.13