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

Generated by: LCOV version 1.14