LCOV - code coverage report
Current view: top level - src/backend/nodes - makefuncs.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 278 283 98.2 %
Date: 2019-08-24 16:07:17 Functions: 33 33 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "nodes/makefuncs.h"
      21             : #include "nodes/nodeFuncs.h"
      22             : #include "utils/lsyscache.h"
      23             : 
      24             : 
      25             : /*
      26             :  * makeA_Expr -
      27             :  *      makes an A_Expr node
      28             :  */
      29             : A_Expr *
      30       61690 : makeA_Expr(A_Expr_Kind kind, List *name,
      31             :            Node *lexpr, Node *rexpr, int location)
      32             : {
      33       61690 :     A_Expr     *a = makeNode(A_Expr);
      34             : 
      35       61690 :     a->kind = kind;
      36       61690 :     a->name = name;
      37       61690 :     a->lexpr = lexpr;
      38       61690 :     a->rexpr = rexpr;
      39       61690 :     a->location = location;
      40       61690 :     return a;
      41             : }
      42             : 
      43             : /*
      44             :  * makeSimpleA_Expr -
      45             :  *      As above, given a simple (unqualified) operator name
      46             :  */
      47             : A_Expr *
      48      473176 : makeSimpleA_Expr(A_Expr_Kind kind, char *name,
      49             :                  Node *lexpr, Node *rexpr, int location)
      50             : {
      51      473176 :     A_Expr     *a = makeNode(A_Expr);
      52             : 
      53      473176 :     a->kind = kind;
      54      473176 :     a->name = list_make1(makeString((char *) name));
      55      473176 :     a->lexpr = lexpr;
      56      473176 :     a->rexpr = rexpr;
      57      473176 :     a->location = location;
      58      473176 :     return a;
      59             : }
      60             : 
      61             : /*
      62             :  * makeVar -
      63             :  *    creates a Var node
      64             :  */
      65             : Var *
      66     8205004 : makeVar(Index varno,
      67             :         AttrNumber varattno,
      68             :         Oid vartype,
      69             :         int32 vartypmod,
      70             :         Oid varcollid,
      71             :         Index varlevelsup)
      72             : {
      73     8205004 :     Var        *var = makeNode(Var);
      74             : 
      75     8205004 :     var->varno = varno;
      76     8205004 :     var->varattno = varattno;
      77     8205004 :     var->vartype = vartype;
      78     8205004 :     var->vartypmod = vartypmod;
      79     8205004 :     var->varcollid = varcollid;
      80     8205004 :     var->varlevelsup = varlevelsup;
      81             : 
      82             :     /*
      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.
      87             :      */
      88     8205004 :     var->varnoold = varno;
      89     8205004 :     var->varoattno = varattno;
      90             : 
      91             :     /* Likewise, we just set location to "unknown" here */
      92     8205004 :     var->location = -1;
      93             : 
      94     8205004 :     return var;
      95             : }
      96             : 
      97             : /*
      98             :  * makeVarFromTargetEntry -
      99             :  *      convenience function to create a same-level Var node from a
     100             :  *      TargetEntry
     101             :  */
     102             : Var *
     103       84714 : makeVarFromTargetEntry(Index varno,
     104             :                        TargetEntry *tle)
     105             : {
     106      338856 :     return makeVar(varno,
     107       84714 :                    tle->resno,
     108       84714 :                    exprType((Node *) tle->expr),
     109       84714 :                    exprTypmod((Node *) tle->expr),
     110       84714 :                    exprCollation((Node *) tle->expr),
     111             :                    0);
     112             : }
     113             : 
     114             : /*
     115             :  * makeWholeRowVar -
     116             :  *    creates a Var node representing a whole row of the specified RTE
     117             :  *
     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 a domain over a named
     123             :  * composite type (only possible if the RTE is a function returning that),
     124             :  * or RECORD.  This function encapsulates the logic for determining the
     125             :  * correct rowtype OID to use.
     126             :  *
     127             :  * If allowScalar is true, then for the case where the RTE is a single function
     128             :  * returning a non-composite result type, we produce a normal Var referencing
     129             :  * the function's result directly, instead of the single-column composite
     130             :  * value that the whole-row notation might otherwise suggest.
     131             :  */
     132             : Var *
     133       20356 : makeWholeRowVar(RangeTblEntry *rte,
     134             :                 Index varno,
     135             :                 Index varlevelsup,
     136             :                 bool allowScalar)
     137             : {
     138             :     Var        *result;
     139             :     Oid         toid;
     140             :     Node       *fexpr;
     141             : 
     142       20356 :     switch (rte->rtekind)
     143             :     {
     144             :         case RTE_RELATION:
     145             :             /* relation: the rowtype is a named composite type */
     146       19568 :             toid = get_rel_type_id(rte->relid);
     147       19568 :             if (!OidIsValid(toid))
     148           0 :                 elog(ERROR, "could not find type OID for relation %u",
     149             :                      rte->relid);
     150       19568 :             result = makeVar(varno,
     151             :                              InvalidAttrNumber,
     152             :                              toid,
     153             :                              -1,
     154             :                              InvalidOid,
     155             :                              varlevelsup);
     156       19568 :             break;
     157             : 
     158             :         case RTE_FUNCTION:
     159             : 
     160             :             /*
     161             :              * If there's more than one function, or ordinality is requested,
     162             :              * force a RECORD result, since there's certainly more than one
     163             :              * column involved and it can't be a known named type.
     164             :              */
     165          38 :             if (rte->funcordinality || list_length(rte->functions) != 1)
     166             :             {
     167             :                 /* always produces an anonymous RECORD result */
     168           4 :                 result = makeVar(varno,
     169             :                                  InvalidAttrNumber,
     170             :                                  RECORDOID,
     171             :                                  -1,
     172             :                                  InvalidOid,
     173             :                                  varlevelsup);
     174           4 :                 break;
     175             :             }
     176             : 
     177          34 :             fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
     178          34 :             toid = exprType(fexpr);
     179          34 :             if (type_is_rowtype(toid))
     180             :             {
     181             :                 /* func returns composite; same as relation case */
     182          32 :                 result = makeVar(varno,
     183             :                                  InvalidAttrNumber,
     184             :                                  toid,
     185             :                                  -1,
     186             :                                  InvalidOid,
     187             :                                  varlevelsup);
     188             :             }
     189           2 :             else if (allowScalar)
     190             :             {
     191             :                 /* func returns scalar; just return its output as-is */
     192           2 :                 result = makeVar(varno,
     193             :                                  1,
     194             :                                  toid,
     195             :                                  -1,
     196             :                                  exprCollation(fexpr),
     197             :                                  varlevelsup);
     198             :             }
     199             :             else
     200             :             {
     201             :                 /* func returns scalar, but we want a composite result */
     202           0 :                 result = makeVar(varno,
     203             :                                  InvalidAttrNumber,
     204             :                                  RECORDOID,
     205             :                                  -1,
     206             :                                  InvalidOid,
     207             :                                  varlevelsup);
     208             :             }
     209          34 :             break;
     210             : 
     211             :         default:
     212             : 
     213             :             /*
     214             :              * RTE is a join, subselect, tablefunc, or VALUES.  We represent
     215             :              * this as a whole-row Var of RECORD type. (Note that in most
     216             :              * cases the Var will be expanded to a RowExpr during planning,
     217             :              * but that is not our concern here.)
     218             :              */
     219         750 :             result = makeVar(varno,
     220             :                              InvalidAttrNumber,
     221             :                              RECORDOID,
     222             :                              -1,
     223             :                              InvalidOid,
     224             :                              varlevelsup);
     225         750 :             break;
     226             :     }
     227             : 
     228       20356 :     return result;
     229             : }
     230             : 
     231             : /*
     232             :  * makeTargetEntry -
     233             :  *    creates a TargetEntry node
     234             :  */
     235             : TargetEntry *
     236     5294558 : makeTargetEntry(Expr *expr,
     237             :                 AttrNumber resno,
     238             :                 char *resname,
     239             :                 bool resjunk)
     240             : {
     241     5294558 :     TargetEntry *tle = makeNode(TargetEntry);
     242             : 
     243     5294558 :     tle->expr = expr;
     244     5294558 :     tle->resno = resno;
     245     5294558 :     tle->resname = resname;
     246             : 
     247             :     /*
     248             :      * We always set these fields to 0. If the caller wants to change them he
     249             :      * must do so explicitly.  Few callers do that, so omitting these
     250             :      * arguments reduces the chance of error.
     251             :      */
     252     5294558 :     tle->ressortgroupref = 0;
     253     5294558 :     tle->resorigtbl = InvalidOid;
     254     5294558 :     tle->resorigcol = 0;
     255             : 
     256     5294558 :     tle->resjunk = resjunk;
     257             : 
     258     5294558 :     return tle;
     259             : }
     260             : 
     261             : /*
     262             :  * flatCopyTargetEntry -
     263             :  *    duplicate a TargetEntry, but don't copy substructure
     264             :  *
     265             :  * This is commonly used when we just want to modify the resno or substitute
     266             :  * a new expression.
     267             :  */
     268             : TargetEntry *
     269      334084 : flatCopyTargetEntry(TargetEntry *src_tle)
     270             : {
     271      334084 :     TargetEntry *tle = makeNode(TargetEntry);
     272             : 
     273             :     Assert(IsA(src_tle, TargetEntry));
     274      334084 :     memcpy(tle, src_tle, sizeof(TargetEntry));
     275      334084 :     return tle;
     276             : }
     277             : 
     278             : /*
     279             :  * makeFromExpr -
     280             :  *    creates a FromExpr node
     281             :  */
     282             : FromExpr *
     283      462670 : makeFromExpr(List *fromlist, Node *quals)
     284             : {
     285      462670 :     FromExpr   *f = makeNode(FromExpr);
     286             : 
     287      462670 :     f->fromlist = fromlist;
     288      462670 :     f->quals = quals;
     289      462670 :     return f;
     290             : }
     291             : 
     292             : /*
     293             :  * makeConst -
     294             :  *    creates a Const node
     295             :  */
     296             : Const *
     297     1209516 : makeConst(Oid consttype,
     298             :           int32 consttypmod,
     299             :           Oid constcollid,
     300             :           int constlen,
     301             :           Datum constvalue,
     302             :           bool constisnull,
     303             :           bool constbyval)
     304             : {
     305     1209516 :     Const      *cnst = makeNode(Const);
     306             : 
     307             :     /*
     308             :      * If it's a varlena value, force it to be in non-expanded (non-toasted)
     309             :      * format; this avoids any possible dependency on external values and
     310             :      * improves consistency of representation, which is important for equal().
     311             :      */
     312     1209516 :     if (!constisnull && constlen == -1)
     313       62028 :         constvalue = PointerGetDatum(PG_DETOAST_DATUM(constvalue));
     314             : 
     315     1209516 :     cnst->consttype = consttype;
     316     1209516 :     cnst->consttypmod = consttypmod;
     317     1209516 :     cnst->constcollid = constcollid;
     318     1209516 :     cnst->constlen = constlen;
     319     1209516 :     cnst->constvalue = constvalue;
     320     1209516 :     cnst->constisnull = constisnull;
     321     1209516 :     cnst->constbyval = constbyval;
     322     1209516 :     cnst->location = -1;     /* "unknown" */
     323             : 
     324     1209516 :     return cnst;
     325             : }
     326             : 
     327             : /*
     328             :  * makeNullConst -
     329             :  *    creates a Const node representing a NULL of the specified type/typmod
     330             :  *
     331             :  * This is a convenience routine that just saves a lookup of the type's
     332             :  * storage properties.
     333             :  */
     334             : Const *
     335        5018 : makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
     336             : {
     337             :     int16       typLen;
     338             :     bool        typByVal;
     339             : 
     340        5018 :     get_typlenbyval(consttype, &typLen, &typByVal);
     341        5018 :     return makeConst(consttype,
     342             :                      consttypmod,
     343             :                      constcollid,
     344             :                      (int) typLen,
     345             :                      (Datum) 0,
     346             :                      true,
     347             :                      typByVal);
     348             : }
     349             : 
     350             : /*
     351             :  * makeBoolConst -
     352             :  *    creates a Const node representing a boolean value (can be NULL too)
     353             :  */
     354             : Node *
     355        2928 : makeBoolConst(bool value, bool isnull)
     356             : {
     357             :     /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
     358        2928 :     return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
     359             :                               BoolGetDatum(value), isnull, true);
     360             : }
     361             : 
     362             : /*
     363             :  * makeBoolExpr -
     364             :  *    creates a BoolExpr node
     365             :  */
     366             : Expr *
     367      302774 : makeBoolExpr(BoolExprType boolop, List *args, int location)
     368             : {
     369      302774 :     BoolExpr   *b = makeNode(BoolExpr);
     370             : 
     371      302774 :     b->boolop = boolop;
     372      302774 :     b->args = args;
     373      302774 :     b->location = location;
     374             : 
     375      302774 :     return (Expr *) b;
     376             : }
     377             : 
     378             : /*
     379             :  * makeAlias -
     380             :  *    creates an Alias node
     381             :  *
     382             :  * NOTE: the given name is copied, but the colnames list (if any) isn't.
     383             :  */
     384             : Alias *
     385      896522 : makeAlias(const char *aliasname, List *colnames)
     386             : {
     387      896522 :     Alias      *a = makeNode(Alias);
     388             : 
     389      896522 :     a->aliasname = pstrdup(aliasname);
     390      896522 :     a->colnames = colnames;
     391             : 
     392      896522 :     return a;
     393             : }
     394             : 
     395             : /*
     396             :  * makeRelabelType -
     397             :  *    creates a RelabelType node
     398             :  */
     399             : RelabelType *
     400      109472 : makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
     401             :                 CoercionForm rformat)
     402             : {
     403      109472 :     RelabelType *r = makeNode(RelabelType);
     404             : 
     405      109472 :     r->arg = arg;
     406      109472 :     r->resulttype = rtype;
     407      109472 :     r->resulttypmod = rtypmod;
     408      109472 :     r->resultcollid = rcollid;
     409      109472 :     r->relabelformat = rformat;
     410      109472 :     r->location = -1;
     411             : 
     412      109472 :     return r;
     413             : }
     414             : 
     415             : /*
     416             :  * makeRangeVar -
     417             :  *    creates a RangeVar node (rather oversimplified case)
     418             :  */
     419             : RangeVar *
     420      643794 : makeRangeVar(char *schemaname, char *relname, int location)
     421             : {
     422      643794 :     RangeVar   *r = makeNode(RangeVar);
     423             : 
     424      643794 :     r->catalogname = NULL;
     425      643794 :     r->schemaname = schemaname;
     426      643794 :     r->relname = relname;
     427      643794 :     r->inh = true;
     428      643794 :     r->relpersistence = RELPERSISTENCE_PERMANENT;
     429      643794 :     r->alias = NULL;
     430      643794 :     r->location = location;
     431             : 
     432      643794 :     return r;
     433             : }
     434             : 
     435             : /*
     436             :  * makeTypeName -
     437             :  *  build a TypeName node for an unqualified name.
     438             :  *
     439             :  * typmod is defaulted, but can be changed later by caller.
     440             :  */
     441             : TypeName *
     442      399922 : makeTypeName(char *typnam)
     443             : {
     444      399922 :     return makeTypeNameFromNameList(list_make1(makeString(typnam)));
     445             : }
     446             : 
     447             : /*
     448             :  * makeTypeNameFromNameList -
     449             :  *  build a TypeName node for a String list representing a qualified name.
     450             :  *
     451             :  * typmod is defaulted, but can be changed later by caller.
     452             :  */
     453             : TypeName *
     454      604242 : makeTypeNameFromNameList(List *names)
     455             : {
     456      604242 :     TypeName   *n = makeNode(TypeName);
     457             : 
     458      604242 :     n->names = names;
     459      604242 :     n->typmods = NIL;
     460      604242 :     n->typemod = -1;
     461      604242 :     n->location = -1;
     462      604242 :     return n;
     463             : }
     464             : 
     465             : /*
     466             :  * makeTypeNameFromOid -
     467             :  *  build a TypeName node to represent a type already known by OID/typmod.
     468             :  */
     469             : TypeName *
     470      413466 : makeTypeNameFromOid(Oid typeOid, int32 typmod)
     471             : {
     472      413466 :     TypeName   *n = makeNode(TypeName);
     473             : 
     474      413466 :     n->typeOid = typeOid;
     475      413466 :     n->typemod = typmod;
     476      413466 :     n->location = -1;
     477      413466 :     return n;
     478             : }
     479             : 
     480             : /*
     481             :  * makeColumnDef -
     482             :  *  build a ColumnDef node to represent a simple column definition.
     483             :  *
     484             :  * Type and collation are specified by OID.
     485             :  * Other properties are all basic to start with.
     486             :  */
     487             : ColumnDef *
     488      400654 : makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
     489             : {
     490      400654 :     ColumnDef  *n = makeNode(ColumnDef);
     491             : 
     492      400654 :     n->colname = pstrdup(colname);
     493      400654 :     n->typeName = makeTypeNameFromOid(typeOid, typmod);
     494      400654 :     n->inhcount = 0;
     495      400654 :     n->is_local = true;
     496      400654 :     n->is_not_null = false;
     497      400654 :     n->is_from_type = false;
     498      400654 :     n->storage = 0;
     499      400654 :     n->raw_default = NULL;
     500      400654 :     n->cooked_default = NULL;
     501      400654 :     n->collClause = NULL;
     502      400654 :     n->collOid = collOid;
     503      400654 :     n->constraints = NIL;
     504      400654 :     n->fdwoptions = NIL;
     505      400654 :     n->location = -1;
     506             : 
     507      400654 :     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      138896 : makeFuncExpr(Oid funcid, Oid rettype, List *args,
     518             :              Oid funccollid, Oid inputcollid, CoercionForm fformat)
     519             : {
     520             :     FuncExpr   *funcexpr;
     521             : 
     522      138896 :     funcexpr = makeNode(FuncExpr);
     523      138896 :     funcexpr->funcid = funcid;
     524      138896 :     funcexpr->funcresulttype = rettype;
     525      138896 :     funcexpr->funcretset = false;    /* only allowed case here */
     526      138896 :     funcexpr->funcvariadic = false; /* only allowed case here */
     527      138896 :     funcexpr->funcformat = fformat;
     528      138896 :     funcexpr->funccollid = funccollid;
     529      138896 :     funcexpr->inputcollid = inputcollid;
     530      138896 :     funcexpr->args = args;
     531      138896 :     funcexpr->location = -1;
     532             : 
     533      138896 :     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      174884 : makeDefElem(char *name, Node *arg, int location)
     545             : {
     546      174884 :     DefElem    *res = makeNode(DefElem);
     547             : 
     548      174884 :     res->defnamespace = NULL;
     549      174884 :     res->defname = name;
     550      174884 :     res->arg = arg;
     551      174884 :     res->defaction = DEFELEM_UNSPEC;
     552      174884 :     res->location = location;
     553             : 
     554      174884 :     return res;
     555             : }
     556             : 
     557             : /*
     558             :  * makeDefElemExtended -
     559             :  *  build a DefElem node with all fields available to be specified
     560             :  */
     561             : DefElem *
     562         108 : makeDefElemExtended(char *nameSpace, char *name, Node *arg,
     563             :                     DefElemAction defaction, int location)
     564             : {
     565         108 :     DefElem    *res = makeNode(DefElem);
     566             : 
     567         108 :     res->defnamespace = nameSpace;
     568         108 :     res->defname = name;
     569         108 :     res->arg = arg;
     570         108 :     res->defaction = defaction;
     571         108 :     res->location = location;
     572             : 
     573         108 :     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      387192 : makeFuncCall(List *name, List *args, int location)
     584             : {
     585      387192 :     FuncCall   *n = makeNode(FuncCall);
     586             : 
     587      387192 :     n->funcname = name;
     588      387192 :     n->args = args;
     589      387192 :     n->agg_order = NIL;
     590      387192 :     n->agg_filter = NULL;
     591      387192 :     n->agg_within_group = false;
     592      387192 :     n->agg_star = false;
     593      387192 :     n->agg_distinct = false;
     594      387192 :     n->func_variadic = false;
     595      387192 :     n->over = NULL;
     596      387192 :     n->location = location;
     597      387192 :     return n;
     598             : }
     599             : 
     600             : /*
     601             :  * make_opclause
     602             :  *    Creates an operator clause given its operator info, left operand
     603             :  *    and right operand (pass NULL to create single-operand clause),
     604             :  *    and collation info.
     605             :  */
     606             : Expr *
     607       96738 : make_opclause(Oid opno, Oid opresulttype, bool opretset,
     608             :               Expr *leftop, Expr *rightop,
     609             :               Oid opcollid, Oid inputcollid)
     610             : {
     611       96738 :     OpExpr     *expr = makeNode(OpExpr);
     612             : 
     613       96738 :     expr->opno = opno;
     614       96738 :     expr->opfuncid = InvalidOid;
     615       96738 :     expr->opresulttype = opresulttype;
     616       96738 :     expr->opretset = opretset;
     617       96738 :     expr->opcollid = opcollid;
     618       96738 :     expr->inputcollid = inputcollid;
     619       96738 :     if (rightop)
     620       96738 :         expr->args = list_make2(leftop, rightop);
     621             :     else
     622           0 :         expr->args = list_make1(leftop);
     623       96738 :     expr->location = -1;
     624       96738 :     return (Expr *) expr;
     625             : }
     626             : 
     627             : /*
     628             :  * make_andclause
     629             :  *
     630             :  * Creates an 'and' clause given a list of its subclauses.
     631             :  */
     632             : Expr *
     633      186600 : make_andclause(List *andclauses)
     634             : {
     635      186600 :     BoolExpr   *expr = makeNode(BoolExpr);
     636             : 
     637      186600 :     expr->boolop = AND_EXPR;
     638      186600 :     expr->args = andclauses;
     639      186600 :     expr->location = -1;
     640      186600 :     return (Expr *) expr;
     641             : }
     642             : 
     643             : /*
     644             :  * make_orclause
     645             :  *
     646             :  * Creates an 'or' clause given a list of its subclauses.
     647             :  */
     648             : Expr *
     649       21652 : make_orclause(List *orclauses)
     650             : {
     651       21652 :     BoolExpr   *expr = makeNode(BoolExpr);
     652             : 
     653       21652 :     expr->boolop = OR_EXPR;
     654       21652 :     expr->args = orclauses;
     655       21652 :     expr->location = -1;
     656       21652 :     return (Expr *) expr;
     657             : }
     658             : 
     659             : /*
     660             :  * make_notclause
     661             :  *
     662             :  * Create a 'not' clause given the expression to be negated.
     663             :  */
     664             : Expr *
     665       10666 : make_notclause(Expr *notclause)
     666             : {
     667       10666 :     BoolExpr   *expr = makeNode(BoolExpr);
     668             : 
     669       10666 :     expr->boolop = NOT_EXPR;
     670       10666 :     expr->args = list_make1(notclause);
     671       10666 :     expr->location = -1;
     672       10666 :     return (Expr *) expr;
     673             : }
     674             : 
     675             : /*
     676             :  * make_and_qual
     677             :  *
     678             :  * Variant of make_andclause for ANDing two qual conditions together.
     679             :  * Qual conditions have the property that a NULL nodetree is interpreted
     680             :  * as 'true'.
     681             :  *
     682             :  * NB: this makes no attempt to preserve AND/OR flatness; so it should not
     683             :  * be used on a qual that has already been run through prepqual.c.
     684             :  */
     685             : Node *
     686        1680 : make_and_qual(Node *qual1, Node *qual2)
     687             : {
     688        1680 :     if (qual1 == NULL)
     689         748 :         return qual2;
     690         932 :     if (qual2 == NULL)
     691           0 :         return qual1;
     692         932 :     return (Node *) make_andclause(list_make2(qual1, qual2));
     693             : }
     694             : 
     695             : /*
     696             :  * The planner and executor usually represent qualification expressions
     697             :  * as lists of boolean expressions with implicit AND semantics.
     698             :  *
     699             :  * These functions convert between an AND-semantics expression list and the
     700             :  * ordinary representation of a boolean expression.
     701             :  *
     702             :  * Note that an empty list is considered equivalent to TRUE.
     703             :  */
     704             : Expr *
     705       22694 : make_ands_explicit(List *andclauses)
     706             : {
     707       22694 :     if (andclauses == NIL)
     708           0 :         return (Expr *) makeBoolConst(true, false);
     709       22694 :     else if (list_length(andclauses) == 1)
     710       17140 :         return (Expr *) linitial(andclauses);
     711             :     else
     712        5554 :         return make_andclause(andclauses);
     713             : }
     714             : 
     715             : List *
     716      294902 : make_ands_implicit(Expr *clause)
     717             : {
     718             :     /*
     719             :      * NB: because the parser sets the qual field to NULL in a query that has
     720             :      * no WHERE clause, we must consider a NULL input clause as TRUE, even
     721             :      * though one might more reasonably think it FALSE.
     722             :      */
     723      294902 :     if (clause == NULL)
     724       90392 :         return NIL;             /* NULL -> NIL list == TRUE */
     725      204510 :     else if (is_andclause(clause))
     726       65122 :         return ((BoolExpr *) clause)->args;
     727      140504 :     else if (IsA(clause, Const) &&
     728        2232 :              !((Const *) clause)->constisnull &&
     729        1116 :              DatumGetBool(((Const *) clause)->constvalue))
     730         594 :         return NIL;             /* constant TRUE input -> NIL list */
     731             :     else
     732      138794 :         return list_make1(clause);
     733             : }
     734             : 
     735             : /*
     736             :  * makeIndexInfo
     737             :  *    create an IndexInfo node
     738             :  */
     739             : IndexInfo *
     740     3762940 : makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
     741             :               List *predicates, bool unique, bool isready, bool concurrent)
     742             : {
     743     3762940 :     IndexInfo  *n = makeNode(IndexInfo);
     744             : 
     745     3762940 :     n->ii_NumIndexAttrs = numattrs;
     746     3762940 :     n->ii_NumIndexKeyAttrs = numkeyattrs;
     747             :     Assert(n->ii_NumIndexKeyAttrs != 0);
     748             :     Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
     749     3762940 :     n->ii_Unique = unique;
     750     3762940 :     n->ii_ReadyForInserts = isready;
     751     3762940 :     n->ii_Concurrent = concurrent;
     752             : 
     753             :     /* expressions */
     754     3762940 :     n->ii_Expressions = expressions;
     755     3762940 :     n->ii_ExpressionsState = NIL;
     756             : 
     757             :     /* predicates  */
     758     3762940 :     n->ii_Predicate = predicates;
     759     3762940 :     n->ii_PredicateState = NULL;
     760             : 
     761             :     /* exclusion constraints */
     762     3762940 :     n->ii_ExclusionOps = NULL;
     763     3762940 :     n->ii_ExclusionProcs = NULL;
     764     3762940 :     n->ii_ExclusionStrats = NULL;
     765             : 
     766             :     /* speculative inserts */
     767     3762940 :     n->ii_UniqueOps = NULL;
     768     3762940 :     n->ii_UniqueProcs = NULL;
     769     3762940 :     n->ii_UniqueStrats = NULL;
     770             : 
     771             :     /* initialize index-build state to default */
     772     3762940 :     n->ii_BrokenHotChain = false;
     773     3762940 :     n->ii_ParallelWorkers = 0;
     774             : 
     775             :     /* set up for possible use by index AM */
     776     3762940 :     n->ii_Am = amoid;
     777     3762940 :     n->ii_AmCache = NULL;
     778     3762940 :     n->ii_Context = CurrentMemoryContext;
     779             : 
     780     3762940 :     return n;
     781             : }
     782             : 
     783             : /*
     784             :  * makeGroupingSet
     785             :  *
     786             :  */
     787             : GroupingSet *
     788        2780 : makeGroupingSet(GroupingSetKind kind, List *content, int location)
     789             : {
     790        2780 :     GroupingSet *n = makeNode(GroupingSet);
     791             : 
     792        2780 :     n->kind = kind;
     793        2780 :     n->content = content;
     794        2780 :     n->location = location;
     795        2780 :     return n;
     796             : }
     797             : 
     798             : /*
     799             :  * makeVacuumRelation -
     800             :  *    create a VacuumRelation node
     801             :  */
     802             : VacuumRelation *
     803       70504 : makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
     804             : {
     805       70504 :     VacuumRelation *v = makeNode(VacuumRelation);
     806             : 
     807       70504 :     v->relation = relation;
     808       70504 :     v->oid = oid;
     809       70504 :     v->va_cols = va_cols;
     810       70504 :     return v;
     811             : }

Generated by: LCOV version 1.13