LCOV - code coverage report
Current view: top level - src/backend/parser - parse_expr.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 963 1335 72.1 %
Date: 2020-06-01 00:06:26 Functions: 37 39 94.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * parse_expr.c
       4             :  *    handle expressions in parser
       5             :  *
       6             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/parser/parse_expr.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres.h"
      17             : 
      18             : #include "catalog/pg_type.h"
      19             : #include "commands/dbcommands.h"
      20             : #include "miscadmin.h"
      21             : #include "nodes/makefuncs.h"
      22             : #include "nodes/nodeFuncs.h"
      23             : #include "optimizer/optimizer.h"
      24             : #include "parser/analyze.h"
      25             : #include "parser/parse_agg.h"
      26             : #include "parser/parse_clause.h"
      27             : #include "parser/parse_coerce.h"
      28             : #include "parser/parse_collate.h"
      29             : #include "parser/parse_expr.h"
      30             : #include "parser/parse_func.h"
      31             : #include "parser/parse_oper.h"
      32             : #include "parser/parse_relation.h"
      33             : #include "parser/parse_target.h"
      34             : #include "parser/parse_type.h"
      35             : #include "utils/builtins.h"
      36             : #include "utils/date.h"
      37             : #include "utils/lsyscache.h"
      38             : #include "utils/timestamp.h"
      39             : #include "utils/xml.h"
      40             : 
      41             : /* GUC parameters */
      42             : bool        operator_precedence_warning = false;
      43             : bool        Transform_null_equals = false;
      44             : 
      45             : /*
      46             :  * Node-type groups for operator precedence warnings
      47             :  * We use zero for everything not otherwise classified
      48             :  */
      49             : #define PREC_GROUP_POSTFIX_IS   1   /* postfix IS tests (NullTest, etc) */
      50             : #define PREC_GROUP_INFIX_IS     2   /* infix IS (IS DISTINCT FROM, etc) */
      51             : #define PREC_GROUP_LESS         3   /* < > */
      52             : #define PREC_GROUP_EQUAL        4   /* = */
      53             : #define PREC_GROUP_LESS_EQUAL   5   /* <= >= <> */
      54             : #define PREC_GROUP_LIKE         6   /* LIKE ILIKE SIMILAR */
      55             : #define PREC_GROUP_BETWEEN      7   /* BETWEEN */
      56             : #define PREC_GROUP_IN           8   /* IN */
      57             : #define PREC_GROUP_NOT_LIKE     9   /* NOT LIKE/ILIKE/SIMILAR */
      58             : #define PREC_GROUP_NOT_BETWEEN  10  /* NOT BETWEEN */
      59             : #define PREC_GROUP_NOT_IN       11  /* NOT IN */
      60             : #define PREC_GROUP_POSTFIX_OP   12  /* generic postfix operators */
      61             : #define PREC_GROUP_INFIX_OP     13  /* generic infix operators */
      62             : #define PREC_GROUP_PREFIX_OP    14  /* generic prefix operators */
      63             : 
      64             : /*
      65             :  * Map precedence groupings to old precedence ordering
      66             :  *
      67             :  * Old precedence order:
      68             :  * 1. NOT
      69             :  * 2. =
      70             :  * 3. < >
      71             :  * 4. LIKE ILIKE SIMILAR
      72             :  * 5. BETWEEN
      73             :  * 6. IN
      74             :  * 7. generic postfix Op
      75             :  * 8. generic Op, including <= => <>
      76             :  * 9. generic prefix Op
      77             :  * 10. IS tests (NullTest, BooleanTest, etc)
      78             :  *
      79             :  * NOT BETWEEN etc map to BETWEEN etc when considered as being on the left,
      80             :  * but to NOT when considered as being on the right, because of the buggy
      81             :  * precedence handling of those productions in the old grammar.
      82             :  */
      83             : static const int oldprecedence_l[] = {
      84             :     0, 10, 10, 3, 2, 8, 4, 5, 6, 4, 5, 6, 7, 8, 9
      85             : };
      86             : static const int oldprecedence_r[] = {
      87             :     0, 10, 10, 3, 2, 8, 4, 5, 6, 1, 1, 1, 7, 8, 9
      88             : };
      89             : 
      90             : static Node *transformExprRecurse(ParseState *pstate, Node *expr);
      91             : static Node *transformParamRef(ParseState *pstate, ParamRef *pref);
      92             : static Node *transformAExprOp(ParseState *pstate, A_Expr *a);
      93             : static Node *transformAExprOpAny(ParseState *pstate, A_Expr *a);
      94             : static Node *transformAExprOpAll(ParseState *pstate, A_Expr *a);
      95             : static Node *transformAExprDistinct(ParseState *pstate, A_Expr *a);
      96             : static Node *transformAExprNullIf(ParseState *pstate, A_Expr *a);
      97             : static Node *transformAExprOf(ParseState *pstate, A_Expr *a);
      98             : static Node *transformAExprIn(ParseState *pstate, A_Expr *a);
      99             : static Node *transformAExprBetween(ParseState *pstate, A_Expr *a);
     100             : static Node *transformBoolExpr(ParseState *pstate, BoolExpr *a);
     101             : static Node *transformFuncCall(ParseState *pstate, FuncCall *fn);
     102             : static Node *transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref);
     103             : static Node *transformCaseExpr(ParseState *pstate, CaseExpr *c);
     104             : static Node *transformSubLink(ParseState *pstate, SubLink *sublink);
     105             : static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
     106             :                                 Oid array_type, Oid element_type, int32 typmod);
     107             : static Node *transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault);
     108             : static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
     109             : static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
     110             : static Node *transformSQLValueFunction(ParseState *pstate,
     111             :                                        SQLValueFunction *svf);
     112             : static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
     113             : static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs);
     114             : static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
     115             : static Node *transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr);
     116             : static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
     117             : static Node *transformWholeRowRef(ParseState *pstate,
     118             :                                   ParseNamespaceItem *nsitem,
     119             :                                   int sublevels_up, int location);
     120             : static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
     121             : static Node *transformTypeCast(ParseState *pstate, TypeCast *tc);
     122             : static Node *transformCollateClause(ParseState *pstate, CollateClause *c);
     123             : static Node *make_row_comparison_op(ParseState *pstate, List *opname,
     124             :                                     List *largs, List *rargs, int location);
     125             : static Node *make_row_distinct_op(ParseState *pstate, List *opname,
     126             :                                   RowExpr *lrow, RowExpr *rrow, int location);
     127             : static Expr *make_distinct_op(ParseState *pstate, List *opname,
     128             :                               Node *ltree, Node *rtree, int location);
     129             : static Node *make_nulltest_from_distinct(ParseState *pstate,
     130             :                                          A_Expr *distincta, Node *arg);
     131             : static int  operator_precedence_group(Node *node, const char **nodename);
     132             : static void emit_precedence_warnings(ParseState *pstate,
     133             :                                      int opgroup, const char *opname,
     134             :                                      Node *lchild, Node *rchild,
     135             :                                      int location);
     136             : 
     137             : 
     138             : /*
     139             :  * transformExpr -
     140             :  *    Analyze and transform expressions. Type checking and type casting is
     141             :  *    done here.  This processing converts the raw grammar output into
     142             :  *    expression trees with fully determined semantics.
     143             :  */
     144             : Node *
     145     1839790 : transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
     146             : {
     147             :     Node       *result;
     148             :     ParseExprKind sv_expr_kind;
     149             : 
     150             :     /* Save and restore identity of expression type we're parsing */
     151             :     Assert(exprKind != EXPR_KIND_NONE);
     152     1839790 :     sv_expr_kind = pstate->p_expr_kind;
     153     1839790 :     pstate->p_expr_kind = exprKind;
     154             : 
     155     1839790 :     result = transformExprRecurse(pstate, expr);
     156             : 
     157     1837530 :     pstate->p_expr_kind = sv_expr_kind;
     158             : 
     159     1837530 :     return result;
     160             : }
     161             : 
     162             : static Node *
     163     4879702 : transformExprRecurse(ParseState *pstate, Node *expr)
     164             : {
     165             :     Node       *result;
     166             : 
     167     4879702 :     if (expr == NULL)
     168       60392 :         return NULL;
     169             : 
     170             :     /* Guard against stack overflow due to overly complex expressions */
     171     4819310 :     check_stack_depth();
     172             : 
     173     4819310 :     switch (nodeTag(expr))
     174             :     {
     175     1872510 :         case T_ColumnRef:
     176     1872510 :             result = transformColumnRef(pstate, (ColumnRef *) expr);
     177     1872144 :             break;
     178             : 
     179       44674 :         case T_ParamRef:
     180       44674 :             result = transformParamRef(pstate, (ParamRef *) expr);
     181       44670 :             break;
     182             : 
     183     1080978 :         case T_A_Const:
     184             :             {
     185     1080978 :                 A_Const    *con = (A_Const *) expr;
     186     1080978 :                 Value      *val = &con->val;
     187             : 
     188     1080978 :                 result = (Node *) make_const(pstate, val, con->location);
     189     1080978 :                 break;
     190             :             }
     191             : 
     192       22534 :         case T_A_Indirection:
     193       22534 :             result = transformIndirection(pstate, (A_Indirection *) expr);
     194       22510 :             break;
     195             : 
     196        3294 :         case T_A_ArrayExpr:
     197        3294 :             result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
     198             :                                         InvalidOid, InvalidOid, -1);
     199        3290 :             break;
     200             : 
     201      396600 :         case T_TypeCast:
     202      396600 :             result = transformTypeCast(pstate, (TypeCast *) expr);
     203      395404 :             break;
     204             : 
     205        2860 :         case T_CollateClause:
     206        2860 :             result = transformCollateClause(pstate, (CollateClause *) expr);
     207        2852 :             break;
     208             : 
     209      592042 :         case T_A_Expr:
     210             :             {
     211      592042 :                 A_Expr     *a = (A_Expr *) expr;
     212             : 
     213      592042 :                 switch (a->kind)
     214             :                 {
     215      543154 :                     case AEXPR_OP:
     216      543154 :                         result = transformAExprOp(pstate, a);
     217      542932 :                         break;
     218       12936 :                     case AEXPR_OP_ANY:
     219       12936 :                         result = transformAExprOpAny(pstate, a);
     220       12928 :                         break;
     221         162 :                     case AEXPR_OP_ALL:
     222         162 :                         result = transformAExprOpAll(pstate, a);
     223         162 :                         break;
     224         506 :                     case AEXPR_DISTINCT:
     225             :                     case AEXPR_NOT_DISTINCT:
     226         506 :                         result = transformAExprDistinct(pstate, a);
     227         506 :                         break;
     228         522 :                     case AEXPR_NULLIF:
     229         522 :                         result = transformAExprNullIf(pstate, a);
     230         522 :                         break;
     231          28 :                     case AEXPR_OF:
     232          28 :                         result = transformAExprOf(pstate, a);
     233          28 :                         break;
     234       32386 :                     case AEXPR_IN:
     235       32386 :                         result = transformAExprIn(pstate, a);
     236       32382 :                         break;
     237        1982 :                     case AEXPR_LIKE:
     238             :                     case AEXPR_ILIKE:
     239             :                     case AEXPR_SIMILAR:
     240             :                         /* we can transform these just like AEXPR_OP */
     241        1982 :                         result = transformAExprOp(pstate, a);
     242        1978 :                         break;
     243         366 :                     case AEXPR_BETWEEN:
     244             :                     case AEXPR_NOT_BETWEEN:
     245             :                     case AEXPR_BETWEEN_SYM:
     246             :                     case AEXPR_NOT_BETWEEN_SYM:
     247         366 :                         result = transformAExprBetween(pstate, a);
     248         366 :                         break;
     249           0 :                     case AEXPR_PAREN:
     250           0 :                         result = transformExprRecurse(pstate, a->lexpr);
     251           0 :                         break;
     252           0 :                     default:
     253           0 :                         elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
     254             :                         result = NULL;  /* keep compiler quiet */
     255             :                         break;
     256             :                 }
     257      591804 :                 break;
     258             :             }
     259             : 
     260      165064 :         case T_BoolExpr:
     261      165064 :             result = transformBoolExpr(pstate, (BoolExpr *) expr);
     262      165050 :             break;
     263             : 
     264      420590 :         case T_FuncCall:
     265      420590 :             result = transformFuncCall(pstate, (FuncCall *) expr);
     266      420032 :             break;
     267             : 
     268         194 :         case T_MultiAssignRef:
     269         194 :             result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
     270         190 :             break;
     271             : 
     272         176 :         case T_GroupingFunc:
     273         176 :             result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
     274         176 :             break;
     275             : 
     276         788 :         case T_NamedArgExpr:
     277             :             {
     278         788 :                 NamedArgExpr *na = (NamedArgExpr *) expr;
     279             : 
     280         788 :                 na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
     281         788 :                 result = expr;
     282         788 :                 break;
     283             :             }
     284             : 
     285       65418 :         case T_SubLink:
     286       65418 :             result = transformSubLink(pstate, (SubLink *) expr);
     287       65370 :             break;
     288             : 
     289       68734 :         case T_CaseExpr:
     290       68734 :             result = transformCaseExpr(pstate, (CaseExpr *) expr);
     291       68730 :             break;
     292             : 
     293        6534 :         case T_RowExpr:
     294        6534 :             result = transformRowExpr(pstate, (RowExpr *) expr, false);
     295        6534 :             break;
     296             : 
     297       18176 :         case T_CoalesceExpr:
     298       18176 :             result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
     299       18172 :             break;
     300             : 
     301         134 :         case T_MinMaxExpr:
     302         134 :             result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
     303         134 :             break;
     304             : 
     305        2500 :         case T_SQLValueFunction:
     306        2500 :             result = transformSQLValueFunction(pstate,
     307             :                                                (SQLValueFunction *) expr);
     308        2500 :             break;
     309             : 
     310         398 :         case T_XmlExpr:
     311         398 :             result = transformXmlExpr(pstate, (XmlExpr *) expr);
     312         378 :             break;
     313             : 
     314          24 :         case T_XmlSerialize:
     315          24 :             result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
     316          24 :             break;
     317             : 
     318       16926 :         case T_NullTest:
     319             :             {
     320       16926 :                 NullTest   *n = (NullTest *) expr;
     321             : 
     322       16926 :                 if (operator_precedence_warning)
     323           0 :                     emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
     324           0 :                                              (Node *) n->arg, NULL,
     325             :                                              n->location);
     326             : 
     327       16926 :                 n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
     328             :                 /* the argument can be any type, so don't coerce it */
     329       16926 :                 n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
     330       16926 :                 result = expr;
     331       16926 :                 break;
     332             :             }
     333             : 
     334         130 :         case T_BooleanTest:
     335         130 :             result = transformBooleanTest(pstate, (BooleanTest *) expr);
     336         130 :             break;
     337             : 
     338         158 :         case T_CurrentOfExpr:
     339         158 :             result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
     340         158 :             break;
     341             : 
     342             :             /*
     343             :              * In all places where DEFAULT is legal, the caller should have
     344             :              * processed it rather than passing it to transformExpr().
     345             :              */
     346           0 :         case T_SetToDefault:
     347           0 :             ereport(ERROR,
     348             :                     (errcode(ERRCODE_SYNTAX_ERROR),
     349             :                      errmsg("DEFAULT is not allowed in this context"),
     350             :                      parser_errposition(pstate,
     351             :                                         ((SetToDefault *) expr)->location)));
     352             :             break;
     353             : 
     354             :             /*
     355             :              * CaseTestExpr doesn't require any processing; it is only
     356             :              * injected into parse trees in a fully-formed state.
     357             :              *
     358             :              * Ordinarily we should not see a Var here, but it is convenient
     359             :              * for transformJoinUsingClause() to create untransformed operator
     360             :              * trees containing already-transformed Vars.  The best
     361             :              * alternative would be to deconstruct and reconstruct column
     362             :              * references, which seems expensively pointless.  So allow it.
     363             :              */
     364       37874 :         case T_CaseTestExpr:
     365             :         case T_Var:
     366             :             {
     367       37874 :                 result = (Node *) expr;
     368       37874 :                 break;
     369             :             }
     370             : 
     371           0 :         default:
     372             :             /* should not reach here */
     373           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
     374             :             result = NULL;      /* keep compiler quiet */
     375             :             break;
     376             :     }
     377             : 
     378     4816818 :     return result;
     379             : }
     380             : 
     381             : /*
     382             :  * helper routine for delivering "column does not exist" error message
     383             :  *
     384             :  * (Usually we don't have to work this hard, but the general case of field
     385             :  * selection from an arbitrary node needs it.)
     386             :  */
     387             : static void
     388          24 : unknown_attribute(ParseState *pstate, Node *relref, const char *attname,
     389             :                   int location)
     390             : {
     391             :     RangeTblEntry *rte;
     392             : 
     393          24 :     if (IsA(relref, Var) &&
     394           8 :         ((Var *) relref)->varattno == InvalidAttrNumber)
     395             :     {
     396             :         /* Reference the RTE by alias not by actual table name */
     397           0 :         rte = GetRTEByRangeTablePosn(pstate,
     398           0 :                                      ((Var *) relref)->varno,
     399           0 :                                      ((Var *) relref)->varlevelsup);
     400           0 :         ereport(ERROR,
     401             :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
     402             :                  errmsg("column %s.%s does not exist",
     403             :                         rte->eref->aliasname, attname),
     404             :                  parser_errposition(pstate, location)));
     405             :     }
     406             :     else
     407             :     {
     408             :         /* Have to do it by reference to the type of the expression */
     409          24 :         Oid         relTypeId = exprType(relref);
     410             : 
     411          24 :         if (ISCOMPLEX(relTypeId))
     412          12 :             ereport(ERROR,
     413             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
     414             :                      errmsg("column \"%s\" not found in data type %s",
     415             :                             attname, format_type_be(relTypeId)),
     416             :                      parser_errposition(pstate, location)));
     417          12 :         else if (relTypeId == RECORDOID)
     418          12 :             ereport(ERROR,
     419             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
     420             :                      errmsg("could not identify column \"%s\" in record data type",
     421             :                             attname),
     422             :                      parser_errposition(pstate, location)));
     423             :         else
     424           0 :             ereport(ERROR,
     425             :                     (errcode(ERRCODE_WRONG_OBJECT_TYPE),
     426             :                      errmsg("column notation .%s applied to type %s, "
     427             :                             "which is not a composite type",
     428             :                             attname, format_type_be(relTypeId)),
     429             :                      parser_errposition(pstate, location)));
     430             :     }
     431             : }
     432             : 
     433             : static Node *
     434       22534 : transformIndirection(ParseState *pstate, A_Indirection *ind)
     435             : {
     436       22534 :     Node       *last_srf = pstate->p_last_srf;
     437       22534 :     Node       *result = transformExprRecurse(pstate, ind->arg);
     438       22534 :     List       *subscripts = NIL;
     439       22534 :     int         location = exprLocation(result);
     440             :     ListCell   *i;
     441             : 
     442             :     /*
     443             :      * We have to split any field-selection operations apart from
     444             :      * subscripting.  Adjacent A_Indices nodes have to be treated as a single
     445             :      * multidimensional subscript operation.
     446             :      */
     447       42004 :     foreach(i, ind->indirection)
     448             :     {
     449       19494 :         Node       *n = lfirst(i);
     450             : 
     451       19494 :         if (IsA(n, A_Indices))
     452        7062 :             subscripts = lappend(subscripts, n);
     453       12432 :         else if (IsA(n, A_Star))
     454             :         {
     455           0 :             ereport(ERROR,
     456             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     457             :                      errmsg("row expansion via \"*\" is not supported here"),
     458             :                      parser_errposition(pstate, location)));
     459             :         }
     460             :         else
     461             :         {
     462             :             Node       *newresult;
     463             : 
     464             :             Assert(IsA(n, String));
     465             : 
     466             :             /* process subscripts before this field selection */
     467       12432 :             if (subscripts)
     468          88 :                 result = (Node *) transformContainerSubscripts(pstate,
     469             :                                                                result,
     470             :                                                                exprType(result),
     471             :                                                                InvalidOid,
     472             :                                                                exprTypmod(result),
     473             :                                                                subscripts,
     474             :                                                                NULL);
     475       12432 :             subscripts = NIL;
     476             : 
     477       12432 :             newresult = ParseFuncOrColumn(pstate,
     478       12432 :                                           list_make1(n),
     479       12432 :                                           list_make1(result),
     480             :                                           last_srf,
     481             :                                           NULL,
     482             :                                           false,
     483             :                                           location);
     484       12432 :             if (newresult == NULL)
     485          24 :                 unknown_attribute(pstate, result, strVal(n), location);
     486       12408 :             result = newresult;
     487             :         }
     488             :     }
     489             :     /* process trailing subscripts, if any */
     490       22510 :     if (subscripts)
     491        6826 :         result = (Node *) transformContainerSubscripts(pstate,
     492             :                                                        result,
     493             :                                                        exprType(result),
     494             :                                                        InvalidOid,
     495             :                                                        exprTypmod(result),
     496             :                                                        subscripts,
     497             :                                                        NULL);
     498             : 
     499       22510 :     return result;
     500             : }
     501             : 
     502             : /*
     503             :  * Transform a ColumnRef.
     504             :  *
     505             :  * If you find yourself changing this code, see also ExpandColumnRefStar.
     506             :  */
     507             : static Node *
     508     1872510 : transformColumnRef(ParseState *pstate, ColumnRef *cref)
     509             : {
     510     1872510 :     Node       *node = NULL;
     511     1872510 :     char       *nspname = NULL;
     512     1872510 :     char       *relname = NULL;
     513     1872510 :     char       *colname = NULL;
     514             :     ParseNamespaceItem *nsitem;
     515             :     int         levels_up;
     516             :     enum
     517             :     {
     518             :         CRERR_NO_COLUMN,
     519             :         CRERR_NO_RTE,
     520             :         CRERR_WRONG_DB,
     521             :         CRERR_TOO_MANY
     522     1872510 :     }           crerr = CRERR_NO_COLUMN;
     523             :     const char *err;
     524             : 
     525             :     /*
     526             :      * Check to see if the column reference is in an invalid place within the
     527             :      * query.  We allow column references in most places, except in default
     528             :      * expressions and partition bound expressions.
     529             :      */
     530     1872510 :     err = NULL;
     531     1872510 :     switch (pstate->p_expr_kind)
     532             :     {
     533           0 :         case EXPR_KIND_NONE:
     534             :             Assert(false);      /* can't happen */
     535           0 :             break;
     536     1872454 :         case EXPR_KIND_OTHER:
     537             :         case EXPR_KIND_JOIN_ON:
     538             :         case EXPR_KIND_JOIN_USING:
     539             :         case EXPR_KIND_FROM_SUBSELECT:
     540             :         case EXPR_KIND_FROM_FUNCTION:
     541             :         case EXPR_KIND_WHERE:
     542             :         case EXPR_KIND_POLICY:
     543             :         case EXPR_KIND_HAVING:
     544             :         case EXPR_KIND_FILTER:
     545             :         case EXPR_KIND_WINDOW_PARTITION:
     546             :         case EXPR_KIND_WINDOW_ORDER:
     547             :         case EXPR_KIND_WINDOW_FRAME_RANGE:
     548             :         case EXPR_KIND_WINDOW_FRAME_ROWS:
     549             :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
     550             :         case EXPR_KIND_SELECT_TARGET:
     551             :         case EXPR_KIND_INSERT_TARGET:
     552             :         case EXPR_KIND_UPDATE_SOURCE:
     553             :         case EXPR_KIND_UPDATE_TARGET:
     554             :         case EXPR_KIND_GROUP_BY:
     555             :         case EXPR_KIND_ORDER_BY:
     556             :         case EXPR_KIND_DISTINCT_ON:
     557             :         case EXPR_KIND_LIMIT:
     558             :         case EXPR_KIND_OFFSET:
     559             :         case EXPR_KIND_RETURNING:
     560             :         case EXPR_KIND_VALUES:
     561             :         case EXPR_KIND_VALUES_SINGLE:
     562             :         case EXPR_KIND_CHECK_CONSTRAINT:
     563             :         case EXPR_KIND_DOMAIN_CHECK:
     564             :         case EXPR_KIND_FUNCTION_DEFAULT:
     565             :         case EXPR_KIND_INDEX_EXPRESSION:
     566             :         case EXPR_KIND_INDEX_PREDICATE:
     567             :         case EXPR_KIND_ALTER_COL_TRANSFORM:
     568             :         case EXPR_KIND_EXECUTE_PARAMETER:
     569             :         case EXPR_KIND_TRIGGER_WHEN:
     570             :         case EXPR_KIND_PARTITION_EXPRESSION:
     571             :         case EXPR_KIND_CALL_ARGUMENT:
     572             :         case EXPR_KIND_COPY_WHERE:
     573             :         case EXPR_KIND_GENERATED_COLUMN:
     574             :             /* okay */
     575     1872454 :             break;
     576             : 
     577          16 :         case EXPR_KIND_COLUMN_DEFAULT:
     578          16 :             err = _("cannot use column reference in DEFAULT expression");
     579          16 :             break;
     580          40 :         case EXPR_KIND_PARTITION_BOUND:
     581          40 :             err = _("cannot use column reference in partition bound expression");
     582          40 :             break;
     583             : 
     584             :             /*
     585             :              * There is intentionally no default: case here, so that the
     586             :              * compiler will warn if we add a new ParseExprKind without
     587             :              * extending this switch.  If we do see an unrecognized value at
     588             :              * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
     589             :              * which is sane anyway.
     590             :              */
     591             :     }
     592     1872510 :     if (err)
     593          56 :         ereport(ERROR,
     594             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     595             :                  errmsg_internal("%s", err),
     596             :                  parser_errposition(pstate, cref->location)));
     597             : 
     598             :     /*
     599             :      * Give the PreParseColumnRefHook, if any, first shot.  If it returns
     600             :      * non-null then that's all, folks.
     601             :      */
     602     1872454 :     if (pstate->p_pre_columnref_hook != NULL)
     603             :     {
     604       18188 :         node = pstate->p_pre_columnref_hook(pstate, cref);
     605       18188 :         if (node != NULL)
     606        1062 :             return node;
     607             :     }
     608             : 
     609             :     /*----------
     610             :      * The allowed syntaxes are:
     611             :      *
     612             :      * A        First try to resolve as unqualified column name;
     613             :      *          if no luck, try to resolve as unqualified table name (A.*).
     614             :      * A.B      A is an unqualified table name; B is either a
     615             :      *          column or function name (trying column name first).
     616             :      * A.B.C    schema A, table B, col or func name C.
     617             :      * A.B.C.D  catalog A, schema B, table C, col or func D.
     618             :      * A.*      A is an unqualified table name; means whole-row value.
     619             :      * A.B.*    whole-row value of table B in schema A.
     620             :      * A.B.C.*  whole-row value of table C in schema B in catalog A.
     621             :      *
     622             :      * We do not need to cope with bare "*"; that will only be accepted by
     623             :      * the grammar at the top level of a SELECT list, and transformTargetList
     624             :      * will take care of it before it ever gets here.  Also, "A.*" etc will
     625             :      * be expanded by transformTargetList if they appear at SELECT top level,
     626             :      * so here we are only going to see them as function or operator inputs.
     627             :      *
     628             :      * Currently, if a catalog name is given then it must equal the current
     629             :      * database name; we check it here and then discard it.
     630             :      *----------
     631             :      */
     632     1871392 :     switch (list_length(cref->fields))
     633             :     {
     634      625678 :         case 1:
     635             :             {
     636      625678 :                 Node       *field1 = (Node *) linitial(cref->fields);
     637             : 
     638             :                 Assert(IsA(field1, String));
     639      625678 :                 colname = strVal(field1);
     640             : 
     641             :                 /* Try to identify as an unqualified column */
     642      625678 :                 node = colNameToVar(pstate, colname, false, cref->location);
     643             : 
     644      625642 :                 if (node == NULL)
     645             :                 {
     646             :                     /*
     647             :                      * Not known as a column of any range-table entry.
     648             :                      *
     649             :                      * Try to find the name as a relation.  Note that only
     650             :                      * relations already entered into the rangetable will be
     651             :                      * recognized.
     652             :                      *
     653             :                      * This is a hack for backwards compatibility with
     654             :                      * PostQUEL-inspired syntax.  The preferred form now is
     655             :                      * "rel.*".
     656             :                      */
     657       35232 :                     nsitem = refnameNamespaceItem(pstate, NULL, colname,
     658             :                                                   cref->location,
     659             :                                                   &levels_up);
     660       35232 :                     if (nsitem)
     661       21206 :                         node = transformWholeRowRef(pstate, nsitem, levels_up,
     662             :                                                     cref->location);
     663             :                 }
     664      625642 :                 break;
     665             :             }
     666     1245680 :         case 2:
     667             :             {
     668     1245680 :                 Node       *field1 = (Node *) linitial(cref->fields);
     669     1245680 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     670             : 
     671             :                 Assert(IsA(field1, String));
     672     1245680 :                 relname = strVal(field1);
     673             : 
     674             :                 /* Locate the referenced nsitem */
     675     1245680 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     676             :                                               cref->location,
     677             :                                               &levels_up);
     678     1245664 :                 if (nsitem == NULL)
     679             :                 {
     680        2706 :                     crerr = CRERR_NO_RTE;
     681        2706 :                     break;
     682             :                 }
     683             : 
     684             :                 /* Whole-row reference? */
     685     1242958 :                 if (IsA(field2, A_Star))
     686             :                 {
     687         486 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     688             :                                                 cref->location);
     689         486 :                     break;
     690             :                 }
     691             : 
     692             :                 Assert(IsA(field2, String));
     693     1242472 :                 colname = strVal(field2);
     694             : 
     695             :                 /* Try to identify as a column of the nsitem */
     696     1242472 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     697             :                                            cref->location);
     698     1242472 :                 if (node == NULL)
     699             :                 {
     700             :                     /* Try it as a function call on the whole row */
     701         104 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     702             :                                                 cref->location);
     703         104 :                     node = ParseFuncOrColumn(pstate,
     704         104 :                                              list_make1(makeString(colname)),
     705         104 :                                              list_make1(node),
     706             :                                              pstate->p_last_srf,
     707             :                                              NULL,
     708             :                                              false,
     709             :                                              cref->location);
     710             :                 }
     711     1242472 :                 break;
     712             :             }
     713          34 :         case 3:
     714             :             {
     715          34 :                 Node       *field1 = (Node *) linitial(cref->fields);
     716          34 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     717          34 :                 Node       *field3 = (Node *) lthird(cref->fields);
     718             : 
     719             :                 Assert(IsA(field1, String));
     720          34 :                 nspname = strVal(field1);
     721             :                 Assert(IsA(field2, String));
     722          34 :                 relname = strVal(field2);
     723             : 
     724             :                 /* Locate the referenced nsitem */
     725          34 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     726             :                                               cref->location,
     727             :                                               &levels_up);
     728          34 :                 if (nsitem == NULL)
     729             :                 {
     730          30 :                     crerr = CRERR_NO_RTE;
     731          30 :                     break;
     732             :                 }
     733             : 
     734             :                 /* Whole-row reference? */
     735           4 :                 if (IsA(field3, A_Star))
     736             :                 {
     737           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     738             :                                                 cref->location);
     739           0 :                     break;
     740             :                 }
     741             : 
     742             :                 Assert(IsA(field3, String));
     743           4 :                 colname = strVal(field3);
     744             : 
     745             :                 /* Try to identify as a column of the nsitem */
     746           4 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     747             :                                            cref->location);
     748           4 :                 if (node == NULL)
     749             :                 {
     750             :                     /* Try it as a function call on the whole row */
     751           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     752             :                                                 cref->location);
     753           0 :                     node = ParseFuncOrColumn(pstate,
     754           0 :                                              list_make1(makeString(colname)),
     755           0 :                                              list_make1(node),
     756             :                                              pstate->p_last_srf,
     757             :                                              NULL,
     758             :                                              false,
     759             :                                              cref->location);
     760             :                 }
     761           4 :                 break;
     762             :             }
     763           0 :         case 4:
     764             :             {
     765           0 :                 Node       *field1 = (Node *) linitial(cref->fields);
     766           0 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     767           0 :                 Node       *field3 = (Node *) lthird(cref->fields);
     768           0 :                 Node       *field4 = (Node *) lfourth(cref->fields);
     769             :                 char       *catname;
     770             : 
     771             :                 Assert(IsA(field1, String));
     772           0 :                 catname = strVal(field1);
     773             :                 Assert(IsA(field2, String));
     774           0 :                 nspname = strVal(field2);
     775             :                 Assert(IsA(field3, String));
     776           0 :                 relname = strVal(field3);
     777             : 
     778             :                 /*
     779             :                  * We check the catalog name and then ignore it.
     780             :                  */
     781           0 :                 if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
     782             :                 {
     783           0 :                     crerr = CRERR_WRONG_DB;
     784           0 :                     break;
     785             :                 }
     786             : 
     787             :                 /* Locate the referenced nsitem */
     788           0 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     789             :                                               cref->location,
     790             :                                               &levels_up);
     791           0 :                 if (nsitem == NULL)
     792             :                 {
     793           0 :                     crerr = CRERR_NO_RTE;
     794           0 :                     break;
     795             :                 }
     796             : 
     797             :                 /* Whole-row reference? */
     798           0 :                 if (IsA(field4, A_Star))
     799             :                 {
     800           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     801             :                                                 cref->location);
     802           0 :                     break;
     803             :                 }
     804             : 
     805             :                 Assert(IsA(field4, String));
     806           0 :                 colname = strVal(field4);
     807             : 
     808             :                 /* Try to identify as a column of the nsitem */
     809           0 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     810             :                                            cref->location);
     811           0 :                 if (node == NULL)
     812             :                 {
     813             :                     /* Try it as a function call on the whole row */
     814           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     815             :                                                 cref->location);
     816           0 :                     node = ParseFuncOrColumn(pstate,
     817           0 :                                              list_make1(makeString(colname)),
     818           0 :                                              list_make1(node),
     819             :                                              pstate->p_last_srf,
     820             :                                              NULL,
     821             :                                              false,
     822             :                                              cref->location);
     823             :                 }
     824           0 :                 break;
     825             :             }
     826           0 :         default:
     827           0 :             crerr = CRERR_TOO_MANY; /* too many dotted names */
     828           0 :             break;
     829             :     }
     830             : 
     831             :     /*
     832             :      * Now give the PostParseColumnRefHook, if any, a chance.  We pass the
     833             :      * translation-so-far so that it can throw an error if it wishes in the
     834             :      * case that it has a conflicting interpretation of the ColumnRef. (If it
     835             :      * just translates anyway, we'll throw an error, because we can't undo
     836             :      * whatever effects the preceding steps may have had on the pstate.) If it
     837             :      * returns NULL, use the standard translation, or throw a suitable error
     838             :      * if there is none.
     839             :      */
     840     1871340 :     if (pstate->p_post_columnref_hook != NULL)
     841             :     {
     842             :         Node       *hookresult;
     843             : 
     844       41518 :         hookresult = pstate->p_post_columnref_hook(pstate, cref, node);
     845       41506 :         if (node == NULL)
     846       16560 :             node = hookresult;
     847       24946 :         else if (hookresult != NULL)
     848           0 :             ereport(ERROR,
     849             :                     (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     850             :                      errmsg("column reference \"%s\" is ambiguous",
     851             :                             NameListToString(cref->fields)),
     852             :                      parser_errposition(pstate, cref->location)));
     853             :     }
     854             : 
     855             :     /*
     856             :      * Throw error if no translation found.
     857             :      */
     858     1871328 :     if (node == NULL)
     859             :     {
     860         246 :         switch (crerr)
     861             :         {
     862         202 :             case CRERR_NO_COLUMN:
     863         202 :                 errorMissingColumn(pstate, relname, colname, cref->location);
     864             :                 break;
     865          44 :             case CRERR_NO_RTE:
     866          44 :                 errorMissingRTE(pstate, makeRangeVar(nspname, relname,
     867             :                                                      cref->location));
     868             :                 break;
     869           0 :             case CRERR_WRONG_DB:
     870           0 :                 ereport(ERROR,
     871             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     872             :                          errmsg("cross-database references are not implemented: %s",
     873             :                                 NameListToString(cref->fields)),
     874             :                          parser_errposition(pstate, cref->location)));
     875             :                 break;
     876           0 :             case CRERR_TOO_MANY:
     877           0 :                 ereport(ERROR,
     878             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     879             :                          errmsg("improper qualified name (too many dotted names): %s",
     880             :                                 NameListToString(cref->fields)),
     881             :                          parser_errposition(pstate, cref->location)));
     882             :                 break;
     883             :         }
     884     1871082 :     }
     885             : 
     886     1871082 :     return node;
     887             : }
     888             : 
     889             : static Node *
     890       44674 : transformParamRef(ParseState *pstate, ParamRef *pref)
     891             : {
     892             :     Node       *result;
     893             : 
     894             :     /*
     895             :      * The core parser knows nothing about Params.  If a hook is supplied,
     896             :      * call it.  If not, or if the hook returns NULL, throw a generic error.
     897             :      */
     898       44674 :     if (pstate->p_paramref_hook != NULL)
     899       44674 :         result = pstate->p_paramref_hook(pstate, pref);
     900             :     else
     901           0 :         result = NULL;
     902             : 
     903       44674 :     if (result == NULL)
     904           4 :         ereport(ERROR,
     905             :                 (errcode(ERRCODE_UNDEFINED_PARAMETER),
     906             :                  errmsg("there is no parameter $%d", pref->number),
     907             :                  parser_errposition(pstate, pref->location)));
     908             : 
     909       44670 :     return result;
     910             : }
     911             : 
     912             : /* Test whether an a_expr is a plain NULL constant or not */
     913             : static bool
     914         992 : exprIsNullConstant(Node *arg)
     915             : {
     916         992 :     if (arg && IsA(arg, A_Const))
     917             :     {
     918          68 :         A_Const    *con = (A_Const *) arg;
     919             : 
     920          68 :         if (con->val.type == T_Null)
     921          20 :             return true;
     922             :     }
     923         972 :     return false;
     924             : }
     925             : 
     926             : static Node *
     927      545136 : transformAExprOp(ParseState *pstate, A_Expr *a)
     928             : {
     929      545136 :     Node       *lexpr = a->lexpr;
     930      545136 :     Node       *rexpr = a->rexpr;
     931             :     Node       *result;
     932             : 
     933      545136 :     if (operator_precedence_warning)
     934             :     {
     935             :         int         opgroup;
     936             :         const char *opname;
     937             : 
     938           0 :         opgroup = operator_precedence_group((Node *) a, &opname);
     939           0 :         if (opgroup > 0)
     940           0 :             emit_precedence_warnings(pstate, opgroup, opname,
     941             :                                      lexpr, rexpr,
     942             :                                      a->location);
     943             : 
     944             :         /* Look through AEXPR_PAREN nodes so they don't affect tests below */
     945           0 :         while (lexpr && IsA(lexpr, A_Expr) &&
     946           0 :                ((A_Expr *) lexpr)->kind == AEXPR_PAREN)
     947           0 :             lexpr = ((A_Expr *) lexpr)->lexpr;
     948           0 :         while (rexpr && IsA(rexpr, A_Expr) &&
     949           0 :                ((A_Expr *) rexpr)->kind == AEXPR_PAREN)
     950           0 :             rexpr = ((A_Expr *) rexpr)->lexpr;
     951             :     }
     952             : 
     953             :     /*
     954             :      * Special-case "foo = NULL" and "NULL = foo" for compatibility with
     955             :      * standards-broken products (like Microsoft's).  Turn these into IS NULL
     956             :      * exprs. (If either side is a CaseTestExpr, then the expression was
     957             :      * generated internally from a CASE-WHEN expression, and
     958             :      * transform_null_equals does not apply.)
     959             :      */
     960      545136 :     if (Transform_null_equals &&
     961           0 :         list_length(a->name) == 1 &&
     962           0 :         strcmp(strVal(linitial(a->name)), "=") == 0 &&
     963           0 :         (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
     964           0 :         (!IsA(lexpr, CaseTestExpr) && !IsA(rexpr, CaseTestExpr)))
     965           0 :     {
     966           0 :         NullTest   *n = makeNode(NullTest);
     967             : 
     968           0 :         n->nulltesttype = IS_NULL;
     969           0 :         n->location = a->location;
     970             : 
     971           0 :         if (exprIsNullConstant(lexpr))
     972           0 :             n->arg = (Expr *) rexpr;
     973             :         else
     974           0 :             n->arg = (Expr *) lexpr;
     975             : 
     976           0 :         result = transformExprRecurse(pstate, (Node *) n);
     977             :     }
     978      545136 :     else if (lexpr && IsA(lexpr, RowExpr) &&
     979        1918 :              rexpr && IsA(rexpr, SubLink) &&
     980           0 :              ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
     981           0 :     {
     982             :         /*
     983             :          * Convert "row op subselect" into a ROWCOMPARE sublink. Formerly the
     984             :          * grammar did this, but now that a row construct is allowed anywhere
     985             :          * in expressions, it's easier to do it here.
     986             :          */
     987           0 :         SubLink    *s = (SubLink *) rexpr;
     988             : 
     989           0 :         s->subLinkType = ROWCOMPARE_SUBLINK;
     990           0 :         s->testexpr = lexpr;
     991           0 :         s->operName = a->name;
     992           0 :         s->location = a->location;
     993           0 :         result = transformExprRecurse(pstate, (Node *) s);
     994             :     }
     995      545136 :     else if (lexpr && IsA(lexpr, RowExpr) &&
     996        1918 :              rexpr && IsA(rexpr, RowExpr))
     997             :     {
     998             :         /* ROW() op ROW() is handled specially */
     999        1918 :         lexpr = transformExprRecurse(pstate, lexpr);
    1000        1918 :         rexpr = transformExprRecurse(pstate, rexpr);
    1001             : 
    1002        1918 :         result = make_row_comparison_op(pstate,
    1003             :                                         a->name,
    1004             :                                         castNode(RowExpr, lexpr)->args,
    1005             :                                         castNode(RowExpr, rexpr)->args,
    1006             :                                         a->location);
    1007             :     }
    1008             :     else
    1009             :     {
    1010             :         /* Ordinary scalar operator */
    1011      543218 :         Node       *last_srf = pstate->p_last_srf;
    1012             : 
    1013      543218 :         lexpr = transformExprRecurse(pstate, lexpr);
    1014      543110 :         rexpr = transformExprRecurse(pstate, rexpr);
    1015             : 
    1016      543056 :         result = (Node *) make_op(pstate,
    1017             :                                   a->name,
    1018             :                                   lexpr,
    1019             :                                   rexpr,
    1020             :                                   last_srf,
    1021             :                                   a->location);
    1022             :     }
    1023             : 
    1024      544910 :     return result;
    1025             : }
    1026             : 
    1027             : static Node *
    1028       12936 : transformAExprOpAny(ParseState *pstate, A_Expr *a)
    1029             : {
    1030       12936 :     Node       *lexpr = a->lexpr;
    1031       12936 :     Node       *rexpr = a->rexpr;
    1032             : 
    1033       12936 :     if (operator_precedence_warning)
    1034           0 :         emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP,
    1035           0 :                                  strVal(llast(a->name)),
    1036             :                                  lexpr, NULL,
    1037             :                                  a->location);
    1038             : 
    1039       12936 :     lexpr = transformExprRecurse(pstate, lexpr);
    1040       12936 :     rexpr = transformExprRecurse(pstate, rexpr);
    1041             : 
    1042       12936 :     return (Node *) make_scalar_array_op(pstate,
    1043             :                                          a->name,
    1044             :                                          true,
    1045             :                                          lexpr,
    1046             :                                          rexpr,
    1047             :                                          a->location);
    1048             : }
    1049             : 
    1050             : static Node *
    1051         162 : transformAExprOpAll(ParseState *pstate, A_Expr *a)
    1052             : {
    1053         162 :     Node       *lexpr = a->lexpr;
    1054         162 :     Node       *rexpr = a->rexpr;
    1055             : 
    1056         162 :     if (operator_precedence_warning)
    1057           0 :         emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP,
    1058           0 :                                  strVal(llast(a->name)),
    1059             :                                  lexpr, NULL,
    1060             :                                  a->location);
    1061             : 
    1062         162 :     lexpr = transformExprRecurse(pstate, lexpr);
    1063         162 :     rexpr = transformExprRecurse(pstate, rexpr);
    1064             : 
    1065         162 :     return (Node *) make_scalar_array_op(pstate,
    1066             :                                          a->name,
    1067             :                                          false,
    1068             :                                          lexpr,
    1069             :                                          rexpr,
    1070             :                                          a->location);
    1071             : }
    1072             : 
    1073             : static Node *
    1074         506 : transformAExprDistinct(ParseState *pstate, A_Expr *a)
    1075             : {
    1076         506 :     Node       *lexpr = a->lexpr;
    1077         506 :     Node       *rexpr = a->rexpr;
    1078             :     Node       *result;
    1079             : 
    1080         506 :     if (operator_precedence_warning)
    1081           0 :         emit_precedence_warnings(pstate, PREC_GROUP_INFIX_IS, "IS",
    1082             :                                  lexpr, rexpr,
    1083             :                                  a->location);
    1084             : 
    1085             :     /*
    1086             :      * If either input is an undecorated NULL literal, transform to a NullTest
    1087             :      * on the other input. That's simpler to process than a full DistinctExpr,
    1088             :      * and it avoids needing to require that the datatype have an = operator.
    1089             :      */
    1090         506 :     if (exprIsNullConstant(rexpr))
    1091          20 :         return make_nulltest_from_distinct(pstate, a, lexpr);
    1092         486 :     if (exprIsNullConstant(lexpr))
    1093           0 :         return make_nulltest_from_distinct(pstate, a, rexpr);
    1094             : 
    1095         486 :     lexpr = transformExprRecurse(pstate, lexpr);
    1096         486 :     rexpr = transformExprRecurse(pstate, rexpr);
    1097             : 
    1098         486 :     if (lexpr && IsA(lexpr, RowExpr) &&
    1099           4 :         rexpr && IsA(rexpr, RowExpr))
    1100             :     {
    1101             :         /* ROW() op ROW() is handled specially */
    1102           4 :         result = make_row_distinct_op(pstate, a->name,
    1103             :                                       (RowExpr *) lexpr,
    1104             :                                       (RowExpr *) rexpr,
    1105             :                                       a->location);
    1106             :     }
    1107             :     else
    1108             :     {
    1109             :         /* Ordinary scalar operator */
    1110         482 :         result = (Node *) make_distinct_op(pstate,
    1111             :                                            a->name,
    1112             :                                            lexpr,
    1113             :                                            rexpr,
    1114             :                                            a->location);
    1115             :     }
    1116             : 
    1117             :     /*
    1118             :      * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a
    1119             :      * NOT on top.
    1120             :      */
    1121         486 :     if (a->kind == AEXPR_NOT_DISTINCT)
    1122          32 :         result = (Node *) makeBoolExpr(NOT_EXPR,
    1123          32 :                                        list_make1(result),
    1124             :                                        a->location);
    1125             : 
    1126         486 :     return result;
    1127             : }
    1128             : 
    1129             : static Node *
    1130         522 : transformAExprNullIf(ParseState *pstate, A_Expr *a)
    1131             : {
    1132         522 :     Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
    1133         522 :     Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
    1134             :     OpExpr     *result;
    1135             : 
    1136         522 :     result = (OpExpr *) make_op(pstate,
    1137             :                                 a->name,
    1138             :                                 lexpr,
    1139             :                                 rexpr,
    1140             :                                 pstate->p_last_srf,
    1141             :                                 a->location);
    1142             : 
    1143             :     /*
    1144             :      * The comparison operator itself should yield boolean ...
    1145             :      */
    1146         522 :     if (result->opresulttype != BOOLOID)
    1147           0 :         ereport(ERROR,
    1148             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1149             :                  errmsg("NULLIF requires = operator to yield boolean"),
    1150             :                  parser_errposition(pstate, a->location)));
    1151         522 :     if (result->opretset)
    1152           0 :         ereport(ERROR,
    1153             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1154             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    1155             :                  errmsg("%s must not return a set", "NULLIF"),
    1156             :                  parser_errposition(pstate, a->location)));
    1157             : 
    1158             :     /*
    1159             :      * ... but the NullIfExpr will yield the first operand's type.
    1160             :      */
    1161         522 :     result->opresulttype = exprType((Node *) linitial(result->args));
    1162             : 
    1163             :     /*
    1164             :      * We rely on NullIfExpr and OpExpr being the same struct
    1165             :      */
    1166         522 :     NodeSetTag(result, T_NullIfExpr);
    1167             : 
    1168         522 :     return (Node *) result;
    1169             : }
    1170             : 
    1171             : /*
    1172             :  * Checking an expression for match to a list of type names. Will result
    1173             :  * in a boolean constant node.
    1174             :  */
    1175             : static Node *
    1176          28 : transformAExprOf(ParseState *pstate, A_Expr *a)
    1177             : {
    1178          28 :     Node       *lexpr = a->lexpr;
    1179             :     Const      *result;
    1180             :     ListCell   *telem;
    1181             :     Oid         ltype,
    1182             :                 rtype;
    1183          28 :     bool        matched = false;
    1184             : 
    1185          28 :     if (operator_precedence_warning)
    1186           0 :         emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
    1187             :                                  lexpr, NULL,
    1188             :                                  a->location);
    1189             : 
    1190          28 :     lexpr = transformExprRecurse(pstate, lexpr);
    1191             : 
    1192          28 :     ltype = exprType(lexpr);
    1193          32 :     foreach(telem, (List *) a->rexpr)
    1194             :     {
    1195          28 :         rtype = typenameTypeId(pstate, lfirst(telem));
    1196          28 :         matched = (rtype == ltype);
    1197          28 :         if (matched)
    1198          24 :             break;
    1199             :     }
    1200             : 
    1201             :     /*
    1202             :      * We have two forms: equals or not equals. Flip the sense of the result
    1203             :      * for not equals.
    1204             :      */
    1205          28 :     if (strcmp(strVal(linitial(a->name)), "<>") == 0)
    1206           0 :         matched = (!matched);
    1207             : 
    1208          28 :     result = (Const *) makeBoolConst(matched, false);
    1209             : 
    1210             :     /* Make the result have the original input's parse location */
    1211          28 :     result->location = exprLocation((Node *) a);
    1212             : 
    1213          28 :     return (Node *) result;
    1214             : }
    1215             : 
    1216             : static Node *
    1217       32386 : transformAExprIn(ParseState *pstate, A_Expr *a)
    1218             : {
    1219       32386 :     Node       *result = NULL;
    1220             :     Node       *lexpr;
    1221             :     List       *rexprs;
    1222             :     List       *rvars;
    1223             :     List       *rnonvars;
    1224             :     bool        useOr;
    1225             :     ListCell   *l;
    1226             : 
    1227             :     /*
    1228             :      * If the operator is <>, combine with AND not OR.
    1229             :      */
    1230       32386 :     if (strcmp(strVal(linitial(a->name)), "<>") == 0)
    1231        3134 :         useOr = false;
    1232             :     else
    1233       29252 :         useOr = true;
    1234             : 
    1235       32386 :     if (operator_precedence_warning)
    1236           0 :         emit_precedence_warnings(pstate,
    1237             :                                  useOr ? PREC_GROUP_IN : PREC_GROUP_NOT_IN,
    1238             :                                  "IN",
    1239             :                                  a->lexpr, NULL,
    1240             :                                  a->location);
    1241             : 
    1242             :     /*
    1243             :      * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
    1244             :      * possible if there is a suitable array type available.  If not, we fall
    1245             :      * back to a boolean condition tree with multiple copies of the lefthand
    1246             :      * expression.  Also, any IN-list items that contain Vars are handled as
    1247             :      * separate boolean conditions, because that gives the planner more scope
    1248             :      * for optimization on such clauses.
    1249             :      *
    1250             :      * First step: transform all the inputs, and detect whether any contain
    1251             :      * Vars.
    1252             :      */
    1253       32386 :     lexpr = transformExprRecurse(pstate, a->lexpr);
    1254       32386 :     rexprs = rvars = rnonvars = NIL;
    1255      115916 :     foreach(l, (List *) a->rexpr)
    1256             :     {
    1257       83534 :         Node       *rexpr = transformExprRecurse(pstate, lfirst(l));
    1258             : 
    1259       83530 :         rexprs = lappend(rexprs, rexpr);
    1260       83530 :         if (contain_vars_of_level(rexpr, 0))
    1261           0 :             rvars = lappend(rvars, rexpr);
    1262             :         else
    1263       83530 :             rnonvars = lappend(rnonvars, rexpr);
    1264             :     }
    1265             : 
    1266             :     /*
    1267             :      * ScalarArrayOpExpr is only going to be useful if there's more than one
    1268             :      * non-Var righthand item.
    1269             :      */
    1270       32382 :     if (list_length(rnonvars) > 1)
    1271             :     {
    1272             :         List       *allexprs;
    1273             :         Oid         scalar_type;
    1274             :         Oid         array_type;
    1275             : 
    1276             :         /*
    1277             :          * Try to select a common type for the array elements.  Note that
    1278             :          * since the LHS' type is first in the list, it will be preferred when
    1279             :          * there is doubt (eg, when all the RHS items are unknown literals).
    1280             :          *
    1281             :          * Note: use list_concat here not lcons, to avoid damaging rnonvars.
    1282             :          */
    1283       27916 :         allexprs = list_concat(list_make1(lexpr), rnonvars);
    1284       27916 :         scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
    1285             : 
    1286             :         /*
    1287             :          * Do we have an array type to use?  Aside from the case where there
    1288             :          * isn't one, we don't risk using ScalarArrayOpExpr when the common
    1289             :          * type is RECORD, because the RowExpr comparison logic below can cope
    1290             :          * with some cases of non-identical row types.
    1291             :          */
    1292       27916 :         if (OidIsValid(scalar_type) && scalar_type != RECORDOID)
    1293       27904 :             array_type = get_array_type(scalar_type);
    1294             :         else
    1295          12 :             array_type = InvalidOid;
    1296       27916 :         if (array_type != InvalidOid)
    1297             :         {
    1298             :             /*
    1299             :              * OK: coerce all the right-hand non-Var inputs to the common type
    1300             :              * and build an ArrayExpr for them.
    1301             :              */
    1302             :             List       *aexprs;
    1303             :             ArrayExpr  *newa;
    1304             : 
    1305       27896 :             aexprs = NIL;
    1306      106920 :             foreach(l, rnonvars)
    1307             :             {
    1308       79024 :                 Node       *rexpr = (Node *) lfirst(l);
    1309             : 
    1310       79024 :                 rexpr = coerce_to_common_type(pstate, rexpr,
    1311             :                                               scalar_type,
    1312             :                                               "IN");
    1313       79024 :                 aexprs = lappend(aexprs, rexpr);
    1314             :             }
    1315       27896 :             newa = makeNode(ArrayExpr);
    1316       27896 :             newa->array_typeid = array_type;
    1317             :             /* array_collid will be set by parse_collate.c */
    1318       27896 :             newa->element_typeid = scalar_type;
    1319       27896 :             newa->elements = aexprs;
    1320       27896 :             newa->multidims = false;
    1321       27896 :             newa->location = -1;
    1322             : 
    1323       27896 :             result = (Node *) make_scalar_array_op(pstate,
    1324             :                                                    a->name,
    1325             :                                                    useOr,
    1326             :                                                    lexpr,
    1327             :                                                    (Node *) newa,
    1328             :                                                    a->location);
    1329             : 
    1330             :             /* Consider only the Vars (if any) in the loop below */
    1331       27896 :             rexprs = rvars;
    1332             :         }
    1333             :     }
    1334             : 
    1335             :     /*
    1336             :      * Must do it the hard way, ie, with a boolean expression tree.
    1337             :      */
    1338       36888 :     foreach(l, rexprs)
    1339             :     {
    1340        4506 :         Node       *rexpr = (Node *) lfirst(l);
    1341             :         Node       *cmp;
    1342             : 
    1343        4506 :         if (IsA(lexpr, RowExpr) &&
    1344          24 :             IsA(rexpr, RowExpr))
    1345             :         {
    1346             :             /* ROW() op ROW() is handled specially */
    1347          24 :             cmp = make_row_comparison_op(pstate,
    1348             :                                          a->name,
    1349          24 :                                          copyObject(((RowExpr *) lexpr)->args),
    1350             :                                          ((RowExpr *) rexpr)->args,
    1351             :                                          a->location);
    1352             :         }
    1353             :         else
    1354             :         {
    1355             :             /* Ordinary scalar operator */
    1356        4482 :             cmp = (Node *) make_op(pstate,
    1357             :                                    a->name,
    1358        4482 :                                    copyObject(lexpr),
    1359             :                                    rexpr,
    1360             :                                    pstate->p_last_srf,
    1361             :                                    a->location);
    1362             :         }
    1363             : 
    1364        4506 :         cmp = coerce_to_boolean(pstate, cmp, "IN");
    1365        4506 :         if (result == NULL)
    1366        4486 :             result = cmp;
    1367             :         else
    1368          20 :             result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
    1369          20 :                                            list_make2(result, cmp),
    1370             :                                            a->location);
    1371             :     }
    1372             : 
    1373       32382 :     return result;
    1374             : }
    1375             : 
    1376             : static Node *
    1377         366 : transformAExprBetween(ParseState *pstate, A_Expr *a)
    1378             : {
    1379             :     Node       *aexpr;
    1380             :     Node       *bexpr;
    1381             :     Node       *cexpr;
    1382             :     Node       *result;
    1383             :     Node       *sub1;
    1384             :     Node       *sub2;
    1385             :     List       *args;
    1386             : 
    1387             :     /* Deconstruct A_Expr into three subexprs */
    1388         366 :     aexpr = a->lexpr;
    1389         366 :     args = castNode(List, a->rexpr);
    1390             :     Assert(list_length(args) == 2);
    1391         366 :     bexpr = (Node *) linitial(args);
    1392         366 :     cexpr = (Node *) lsecond(args);
    1393             : 
    1394         366 :     if (operator_precedence_warning)
    1395             :     {
    1396             :         int         opgroup;
    1397             :         const char *opname;
    1398             : 
    1399           0 :         opgroup = operator_precedence_group((Node *) a, &opname);
    1400           0 :         emit_precedence_warnings(pstate, opgroup, opname,
    1401             :                                  aexpr, cexpr,
    1402             :                                  a->location);
    1403             :         /* We can ignore bexpr thanks to syntactic restrictions */
    1404             :         /* Wrap subexpressions to prevent extra warnings */
    1405           0 :         aexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, aexpr, NULL, -1);
    1406           0 :         bexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, bexpr, NULL, -1);
    1407           0 :         cexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, cexpr, NULL, -1);
    1408             :     }
    1409             : 
    1410             :     /*
    1411             :      * Build the equivalent comparison expression.  Make copies of
    1412             :      * multiply-referenced subexpressions for safety.  (XXX this is really
    1413             :      * wrong since it results in multiple runtime evaluations of what may be
    1414             :      * volatile expressions ...)
    1415             :      *
    1416             :      * Ideally we would not use hard-wired operators here but instead use
    1417             :      * opclasses.  However, mixed data types and other issues make this
    1418             :      * difficult:
    1419             :      * http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
    1420             :      */
    1421         366 :     switch (a->kind)
    1422             :     {
    1423         338 :         case AEXPR_BETWEEN:
    1424         338 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
    1425             :                                                aexpr, bexpr,
    1426             :                                                a->location),
    1427             :                               makeSimpleA_Expr(AEXPR_OP, "<=",
    1428             :                                                copyObject(aexpr), cexpr,
    1429             :                                                a->location));
    1430         338 :             result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1431         338 :             break;
    1432          12 :         case AEXPR_NOT_BETWEEN:
    1433          12 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
    1434             :                                                aexpr, bexpr,
    1435             :                                                a->location),
    1436             :                               makeSimpleA_Expr(AEXPR_OP, ">",
    1437             :                                                copyObject(aexpr), cexpr,
    1438             :                                                a->location));
    1439          12 :             result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1440          12 :             break;
    1441           8 :         case AEXPR_BETWEEN_SYM:
    1442           8 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
    1443             :                                                aexpr, bexpr,
    1444             :                                                a->location),
    1445             :                               makeSimpleA_Expr(AEXPR_OP, "<=",
    1446             :                                                copyObject(aexpr), cexpr,
    1447             :                                                a->location));
    1448           8 :             sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1449           8 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
    1450             :                                                copyObject(aexpr), copyObject(cexpr),
    1451             :                                                a->location),
    1452             :                               makeSimpleA_Expr(AEXPR_OP, "<=",
    1453             :                                                copyObject(aexpr), copyObject(bexpr),
    1454             :                                                a->location));
    1455           8 :             sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1456           8 :             args = list_make2(sub1, sub2);
    1457           8 :             result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1458           8 :             break;
    1459           8 :         case AEXPR_NOT_BETWEEN_SYM:
    1460           8 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
    1461             :                                                aexpr, bexpr,
    1462             :                                                a->location),
    1463             :                               makeSimpleA_Expr(AEXPR_OP, ">",
    1464             :                                                copyObject(aexpr), cexpr,
    1465             :                                                a->location));
    1466           8 :             sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1467           8 :             args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
    1468             :                                                copyObject(aexpr), copyObject(cexpr),
    1469             :                                                a->location),
    1470             :                               makeSimpleA_Expr(AEXPR_OP, ">",
    1471             :                                                copyObject(aexpr), copyObject(bexpr),
    1472             :                                                a->location));
    1473           8 :             sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1474           8 :             args = list_make2(sub1, sub2);
    1475           8 :             result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1476           8 :             break;
    1477           0 :         default:
    1478           0 :             elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
    1479             :             result = NULL;      /* keep compiler quiet */
    1480             :             break;
    1481             :     }
    1482             : 
    1483         366 :     return transformExprRecurse(pstate, result);
    1484             : }
    1485             : 
    1486             : static Node *
    1487      165064 : transformBoolExpr(ParseState *pstate, BoolExpr *a)
    1488             : {
    1489      165064 :     List       *args = NIL;
    1490             :     const char *opname;
    1491             :     ListCell   *lc;
    1492             : 
    1493      165064 :     switch (a->boolop)
    1494             :     {
    1495      109544 :         case AND_EXPR:
    1496      109544 :             opname = "AND";
    1497      109544 :             break;
    1498       25164 :         case OR_EXPR:
    1499       25164 :             opname = "OR";
    1500       25164 :             break;
    1501       30356 :         case NOT_EXPR:
    1502       30356 :             opname = "NOT";
    1503       30356 :             break;
    1504           0 :         default:
    1505           0 :             elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
    1506             :             opname = NULL;      /* keep compiler quiet */
    1507             :             break;
    1508             :     }
    1509             : 
    1510      568010 :     foreach(lc, a->args)
    1511             :     {
    1512      402960 :         Node       *arg = (Node *) lfirst(lc);
    1513             : 
    1514      402960 :         arg = transformExprRecurse(pstate, arg);
    1515      402946 :         arg = coerce_to_boolean(pstate, arg, opname);
    1516      402946 :         args = lappend(args, arg);
    1517             :     }
    1518             : 
    1519      165050 :     return (Node *) makeBoolExpr(a->boolop, args, a->location);
    1520             : }
    1521             : 
    1522             : static Node *
    1523      420590 : transformFuncCall(ParseState *pstate, FuncCall *fn)
    1524             : {
    1525      420590 :     Node       *last_srf = pstate->p_last_srf;
    1526             :     List       *targs;
    1527             :     ListCell   *args;
    1528             : 
    1529             :     /* Transform the list of arguments ... */
    1530      420590 :     targs = NIL;
    1531      962560 :     foreach(args, fn->args)
    1532             :     {
    1533      541970 :         targs = lappend(targs, transformExprRecurse(pstate,
    1534      542010 :                                                     (Node *) lfirst(args)));
    1535             :     }
    1536             : 
    1537             :     /*
    1538             :      * When WITHIN GROUP is used, we treat its ORDER BY expressions as
    1539             :      * additional arguments to the function, for purposes of function lookup
    1540             :      * and argument type coercion.  So, transform each such expression and add
    1541             :      * them to the targs list.  We don't explicitly mark where each argument
    1542             :      * came from, but ParseFuncOrColumn can tell what's what by reference to
    1543             :      * list_length(fn->agg_order).
    1544             :      */
    1545      420550 :     if (fn->agg_within_group)
    1546             :     {
    1547             :         Assert(fn->agg_order != NIL);
    1548         514 :         foreach(args, fn->agg_order)
    1549             :         {
    1550         278 :             SortBy     *arg = (SortBy *) lfirst(args);
    1551             : 
    1552         278 :             targs = lappend(targs, transformExpr(pstate, arg->node,
    1553             :                                                  EXPR_KIND_ORDER_BY));
    1554             :         }
    1555             :     }
    1556             : 
    1557             :     /* ... and hand off to ParseFuncOrColumn */
    1558      420550 :     return ParseFuncOrColumn(pstate,
    1559             :                              fn->funcname,
    1560             :                              targs,
    1561             :                              last_srf,
    1562             :                              fn,
    1563             :                              false,
    1564             :                              fn->location);
    1565             : }
    1566             : 
    1567             : static Node *
    1568         194 : transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
    1569             : {
    1570             :     SubLink    *sublink;
    1571             :     RowExpr    *rexpr;
    1572             :     Query      *qtree;
    1573             :     TargetEntry *tle;
    1574             : 
    1575             :     /* We should only see this in first-stage processing of UPDATE tlists */
    1576             :     Assert(pstate->p_expr_kind == EXPR_KIND_UPDATE_SOURCE);
    1577             : 
    1578             :     /* We only need to transform the source if this is the first column */
    1579         194 :     if (maref->colno == 1)
    1580             :     {
    1581             :         /*
    1582             :          * For now, we only allow EXPR SubLinks and RowExprs as the source of
    1583             :          * an UPDATE multiassignment.  This is sufficient to cover interesting
    1584             :          * cases; at worst, someone would have to write (SELECT * FROM expr)
    1585             :          * to expand a composite-returning expression of another form.
    1586             :          */
    1587          94 :         if (IsA(maref->source, SubLink) &&
    1588          62 :             ((SubLink *) maref->source)->subLinkType == EXPR_SUBLINK)
    1589             :         {
    1590             :             /* Relabel it as a MULTIEXPR_SUBLINK */
    1591          62 :             sublink = (SubLink *) maref->source;
    1592          62 :             sublink->subLinkType = MULTIEXPR_SUBLINK;
    1593             :             /* And transform it */
    1594          62 :             sublink = (SubLink *) transformExprRecurse(pstate,
    1595             :                                                        (Node *) sublink);
    1596             : 
    1597          62 :             qtree = castNode(Query, sublink->subselect);
    1598             : 
    1599             :             /* Check subquery returns required number of columns */
    1600          62 :             if (count_nonjunk_tlist_entries(qtree->targetList) != maref->ncolumns)
    1601           0 :                 ereport(ERROR,
    1602             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1603             :                          errmsg("number of columns does not match number of values"),
    1604             :                          parser_errposition(pstate, sublink->location)));
    1605             : 
    1606             :             /*
    1607             :              * Build a resjunk tlist item containing the MULTIEXPR SubLink,
    1608             :              * and add it to pstate->p_multiassign_exprs, whence it will later
    1609             :              * get appended to the completed targetlist.  We needn't worry
    1610             :              * about selecting a resno for it; transformUpdateStmt will do
    1611             :              * that.
    1612             :              */
    1613          62 :             tle = makeTargetEntry((Expr *) sublink, 0, NULL, true);
    1614          62 :             pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
    1615             :                                                   tle);
    1616             : 
    1617             :             /*
    1618             :              * Assign a unique-within-this-targetlist ID to the MULTIEXPR
    1619             :              * SubLink.  We can just use its position in the
    1620             :              * p_multiassign_exprs list.
    1621             :              */
    1622          62 :             sublink->subLinkId = list_length(pstate->p_multiassign_exprs);
    1623             :         }
    1624          32 :         else if (IsA(maref->source, RowExpr))
    1625             :         {
    1626             :             /* Transform the RowExpr, allowing SetToDefault items */
    1627          28 :             rexpr = (RowExpr *) transformRowExpr(pstate,
    1628          28 :                                                  (RowExpr *) maref->source,
    1629             :                                                  true);
    1630             : 
    1631             :             /* Check it returns required number of columns */
    1632          28 :             if (list_length(rexpr->args) != maref->ncolumns)
    1633           0 :                 ereport(ERROR,
    1634             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1635             :                          errmsg("number of columns does not match number of values"),
    1636             :                          parser_errposition(pstate, rexpr->location)));
    1637             : 
    1638             :             /*
    1639             :              * Temporarily append it to p_multiassign_exprs, so we can get it
    1640             :              * back when we come back here for additional columns.
    1641             :              */
    1642          28 :             tle = makeTargetEntry((Expr *) rexpr, 0, NULL, true);
    1643          28 :             pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
    1644             :                                                   tle);
    1645             :         }
    1646             :         else
    1647           4 :             ereport(ERROR,
    1648             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1649             :                      errmsg("source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression"),
    1650             :                      parser_errposition(pstate, exprLocation(maref->source))));
    1651             :     }
    1652             :     else
    1653             :     {
    1654             :         /*
    1655             :          * Second or later column in a multiassignment.  Re-fetch the
    1656             :          * transformed SubLink or RowExpr, which we assume is still the last
    1657             :          * entry in p_multiassign_exprs.
    1658             :          */
    1659             :         Assert(pstate->p_multiassign_exprs != NIL);
    1660         100 :         tle = (TargetEntry *) llast(pstate->p_multiassign_exprs);
    1661             :     }
    1662             : 
    1663             :     /*
    1664             :      * Emit the appropriate output expression for the current column
    1665             :      */
    1666         190 :     if (IsA(tle->expr, SubLink))
    1667             :     {
    1668             :         Param      *param;
    1669             : 
    1670         126 :         sublink = (SubLink *) tle->expr;
    1671             :         Assert(sublink->subLinkType == MULTIEXPR_SUBLINK);
    1672         126 :         qtree = castNode(Query, sublink->subselect);
    1673             : 
    1674             :         /* Build a Param representing the current subquery output column */
    1675         126 :         tle = (TargetEntry *) list_nth(qtree->targetList, maref->colno - 1);
    1676             :         Assert(!tle->resjunk);
    1677             : 
    1678         126 :         param = makeNode(Param);
    1679         126 :         param->paramkind = PARAM_MULTIEXPR;
    1680         126 :         param->paramid = (sublink->subLinkId << 16) | maref->colno;
    1681         126 :         param->paramtype = exprType((Node *) tle->expr);
    1682         126 :         param->paramtypmod = exprTypmod((Node *) tle->expr);
    1683         126 :         param->paramcollid = exprCollation((Node *) tle->expr);
    1684         126 :         param->location = exprLocation((Node *) tle->expr);
    1685             : 
    1686         126 :         return (Node *) param;
    1687             :     }
    1688             : 
    1689          64 :     if (IsA(tle->expr, RowExpr))
    1690             :     {
    1691             :         Node       *result;
    1692             : 
    1693          64 :         rexpr = (RowExpr *) tle->expr;
    1694             : 
    1695             :         /* Just extract and return the next element of the RowExpr */
    1696          64 :         result = (Node *) list_nth(rexpr->args, maref->colno - 1);
    1697             : 
    1698             :         /*
    1699             :          * If we're at the last column, delete the RowExpr from
    1700             :          * p_multiassign_exprs; we don't need it anymore, and don't want it in
    1701             :          * the finished UPDATE tlist.
    1702             :          */
    1703          64 :         if (maref->colno == maref->ncolumns)
    1704          28 :             pstate->p_multiassign_exprs =
    1705          28 :                 list_delete_ptr(pstate->p_multiassign_exprs, tle);
    1706             : 
    1707          64 :         return result;
    1708             :     }
    1709             : 
    1710           0 :     elog(ERROR, "unexpected expr type in multiassign list");
    1711             :     return NULL;                /* keep compiler quiet */
    1712             : }
    1713             : 
    1714             : static Node *
    1715       68734 : transformCaseExpr(ParseState *pstate, CaseExpr *c)
    1716             : {
    1717       68734 :     CaseExpr   *newc = makeNode(CaseExpr);
    1718       68734 :     Node       *last_srf = pstate->p_last_srf;
    1719             :     Node       *arg;
    1720             :     CaseTestExpr *placeholder;
    1721             :     List       *newargs;
    1722             :     List       *resultexprs;
    1723             :     ListCell   *l;
    1724             :     Node       *defresult;
    1725             :     Oid         ptype;
    1726             : 
    1727             :     /* transform the test expression, if any */
    1728       68734 :     arg = transformExprRecurse(pstate, (Node *) c->arg);
    1729             : 
    1730             :     /* generate placeholder for test expression */
    1731       68734 :     if (arg)
    1732             :     {
    1733             :         /*
    1734             :          * If test expression is an untyped literal, force it to text. We have
    1735             :          * to do something now because we won't be able to do this coercion on
    1736             :          * the placeholder.  This is not as flexible as what was done in 7.4
    1737             :          * and before, but it's good enough to handle the sort of silly coding
    1738             :          * commonly seen.
    1739             :          */
    1740        9018 :         if (exprType(arg) == UNKNOWNOID)
    1741           4 :             arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
    1742             : 
    1743             :         /*
    1744             :          * Run collation assignment on the test expression so that we know
    1745             :          * what collation to mark the placeholder with.  In principle we could
    1746             :          * leave it to parse_collate.c to do that later, but propagating the
    1747             :          * result to the CaseTestExpr would be unnecessarily complicated.
    1748             :          */
    1749        9018 :         assign_expr_collations(pstate, arg);
    1750             : 
    1751        9018 :         placeholder = makeNode(CaseTestExpr);
    1752        9018 :         placeholder->typeId = exprType(arg);
    1753        9018 :         placeholder->typeMod = exprTypmod(arg);
    1754        9018 :         placeholder->collation = exprCollation(arg);
    1755             :     }
    1756             :     else
    1757       59716 :         placeholder = NULL;
    1758             : 
    1759       68734 :     newc->arg = (Expr *) arg;
    1760             : 
    1761             :     /* transform the list of arguments */
    1762       68734 :     newargs = NIL;
    1763       68734 :     resultexprs = NIL;
    1764      184444 :     foreach(l, c->args)
    1765             :     {
    1766      115710 :         CaseWhen   *w = lfirst_node(CaseWhen, l);
    1767      115710 :         CaseWhen   *neww = makeNode(CaseWhen);
    1768             :         Node       *warg;
    1769             : 
    1770      115710 :         warg = (Node *) w->expr;
    1771      115710 :         if (placeholder)
    1772             :         {
    1773             :             /* shorthand form was specified, so expand... */
    1774       36102 :             warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
    1775             :                                              (Node *) placeholder,
    1776             :                                              warg,
    1777             :                                              w->location);
    1778             :         }
    1779      115710 :         neww->expr = (Expr *) transformExprRecurse(pstate, warg);
    1780             : 
    1781      231420 :         neww->expr = (Expr *) coerce_to_boolean(pstate,
    1782      115710 :                                                 (Node *) neww->expr,
    1783             :                                                 "CASE/WHEN");
    1784             : 
    1785      115710 :         warg = (Node *) w->result;
    1786      115710 :         neww->result = (Expr *) transformExprRecurse(pstate, warg);
    1787      115710 :         neww->location = w->location;
    1788             : 
    1789      115710 :         newargs = lappend(newargs, neww);
    1790      115710 :         resultexprs = lappend(resultexprs, neww->result);
    1791             :     }
    1792             : 
    1793       68734 :     newc->args = newargs;
    1794             : 
    1795             :     /* transform the default clause */
    1796       68734 :     defresult = (Node *) c->defresult;
    1797       68734 :     if (defresult == NULL)
    1798             :     {
    1799       13994 :         A_Const    *n = makeNode(A_Const);
    1800             : 
    1801       13994 :         n->val.type = T_Null;
    1802       13994 :         n->location = -1;
    1803       13994 :         defresult = (Node *) n;
    1804             :     }
    1805       68734 :     newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
    1806             : 
    1807             :     /*
    1808             :      * Note: default result is considered the most significant type in
    1809             :      * determining preferred type. This is how the code worked before, but it
    1810             :      * seems a little bogus to me --- tgl
    1811             :      */
    1812       68734 :     resultexprs = lcons(newc->defresult, resultexprs);
    1813             : 
    1814       68734 :     ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
    1815             :     Assert(OidIsValid(ptype));
    1816       68734 :     newc->casetype = ptype;
    1817             :     /* casecollid will be set by parse_collate.c */
    1818             : 
    1819             :     /* Convert default result clause, if necessary */
    1820       68734 :     newc->defresult = (Expr *)
    1821       68734 :         coerce_to_common_type(pstate,
    1822       68734 :                               (Node *) newc->defresult,
    1823             :                               ptype,
    1824             :                               "CASE/ELSE");
    1825             : 
    1826             :     /* Convert when-clause results, if necessary */
    1827      184444 :     foreach(l, newc->args)
    1828             :     {
    1829      115710 :         CaseWhen   *w = (CaseWhen *) lfirst(l);
    1830             : 
    1831      115710 :         w->result = (Expr *)
    1832      115710 :             coerce_to_common_type(pstate,
    1833      115710 :                                   (Node *) w->result,
    1834             :                                   ptype,
    1835             :                                   "CASE/WHEN");
    1836             :     }
    1837             : 
    1838             :     /* if any subexpression contained a SRF, complain */
    1839       68734 :     if (pstate->p_last_srf != last_srf)
    1840           4 :         ereport(ERROR,
    1841             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1842             :         /* translator: %s is name of a SQL construct, eg GROUP BY */
    1843             :                  errmsg("set-returning functions are not allowed in %s",
    1844             :                         "CASE"),
    1845             :                  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
    1846             :                  parser_errposition(pstate,
    1847             :                                     exprLocation(pstate->p_last_srf))));
    1848             : 
    1849       68730 :     newc->location = c->location;
    1850             : 
    1851       68730 :     return (Node *) newc;
    1852             : }
    1853             : 
    1854             : static Node *
    1855       65418 : transformSubLink(ParseState *pstate, SubLink *sublink)
    1856             : {
    1857       65418 :     Node       *result = (Node *) sublink;
    1858             :     Query      *qtree;
    1859             :     const char *err;
    1860             : 
    1861             :     /*
    1862             :      * Check to see if the sublink is in an invalid place within the query. We
    1863             :      * allow sublinks everywhere in SELECT/INSERT/UPDATE/DELETE, but generally
    1864             :      * not in utility statements.
    1865             :      */
    1866       65418 :     err = NULL;
    1867       65418 :     switch (pstate->p_expr_kind)
    1868             :     {
    1869           0 :         case EXPR_KIND_NONE:
    1870             :             Assert(false);      /* can't happen */
    1871           0 :             break;
    1872           0 :         case EXPR_KIND_OTHER:
    1873             :             /* Accept sublink here; caller must throw error if wanted */
    1874           0 :             break;
    1875       65394 :         case EXPR_KIND_JOIN_ON:
    1876             :         case EXPR_KIND_JOIN_USING:
    1877             :         case EXPR_KIND_FROM_SUBSELECT:
    1878             :         case EXPR_KIND_FROM_FUNCTION:
    1879             :         case EXPR_KIND_WHERE:
    1880             :         case EXPR_KIND_POLICY:
    1881             :         case EXPR_KIND_HAVING:
    1882             :         case EXPR_KIND_FILTER:
    1883             :         case EXPR_KIND_WINDOW_PARTITION:
    1884             :         case EXPR_KIND_WINDOW_ORDER:
    1885             :         case EXPR_KIND_WINDOW_FRAME_RANGE:
    1886             :         case EXPR_KIND_WINDOW_FRAME_ROWS:
    1887             :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
    1888             :         case EXPR_KIND_SELECT_TARGET:
    1889             :         case EXPR_KIND_INSERT_TARGET:
    1890             :         case EXPR_KIND_UPDATE_SOURCE:
    1891             :         case EXPR_KIND_UPDATE_TARGET:
    1892             :         case EXPR_KIND_GROUP_BY:
    1893             :         case EXPR_KIND_ORDER_BY:
    1894             :         case EXPR_KIND_DISTINCT_ON:
    1895             :         case EXPR_KIND_LIMIT:
    1896             :         case EXPR_KIND_OFFSET:
    1897             :         case EXPR_KIND_RETURNING:
    1898             :         case EXPR_KIND_VALUES:
    1899             :         case EXPR_KIND_VALUES_SINGLE:
    1900             :             /* okay */
    1901       65394 :             break;
    1902           0 :         case EXPR_KIND_CHECK_CONSTRAINT:
    1903             :         case EXPR_KIND_DOMAIN_CHECK:
    1904           0 :             err = _("cannot use subquery in check constraint");
    1905           0 :             break;
    1906           4 :         case EXPR_KIND_COLUMN_DEFAULT:
    1907             :         case EXPR_KIND_FUNCTION_DEFAULT:
    1908           4 :             err = _("cannot use subquery in DEFAULT expression");
    1909           4 :             break;
    1910           0 :         case EXPR_KIND_INDEX_EXPRESSION:
    1911           0 :             err = _("cannot use subquery in index expression");
    1912           0 :             break;
    1913           0 :         case EXPR_KIND_INDEX_PREDICATE:
    1914           0 :             err = _("cannot use subquery in index predicate");
    1915           0 :             break;
    1916           0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
    1917           0 :             err = _("cannot use subquery in transform expression");
    1918           0 :             break;
    1919           0 :         case EXPR_KIND_EXECUTE_PARAMETER:
    1920           0 :             err = _("cannot use subquery in EXECUTE parameter");
    1921           0 :             break;
    1922           0 :         case EXPR_KIND_TRIGGER_WHEN:
    1923           0 :             err = _("cannot use subquery in trigger WHEN condition");
    1924           0 :             break;
    1925           8 :         case EXPR_KIND_PARTITION_BOUND:
    1926           8 :             err = _("cannot use subquery in partition bound");
    1927           8 :             break;
    1928           4 :         case EXPR_KIND_PARTITION_EXPRESSION:
    1929           4 :             err = _("cannot use subquery in partition key expression");
    1930           4 :             break;
    1931           0 :         case EXPR_KIND_CALL_ARGUMENT:
    1932           0 :             err = _("cannot use subquery in CALL argument");
    1933           0 :             break;
    1934           4 :         case EXPR_KIND_COPY_WHERE:
    1935           4 :             err = _("cannot use subquery in COPY FROM WHERE condition");
    1936           4 :             break;
    1937           4 :         case EXPR_KIND_GENERATED_COLUMN:
    1938           4 :             err = _("cannot use subquery in column generation expression");
    1939           4 :             break;
    1940             : 
    1941             :             /*
    1942             :              * There is intentionally no default: case here, so that the
    1943             :              * compiler will warn if we add a new ParseExprKind without
    1944             :              * extending this switch.  If we do see an unrecognized value at
    1945             :              * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
    1946             :              * which is sane anyway.
    1947             :              */
    1948             :     }
    1949       65418 :     if (err)
    1950          24 :         ereport(ERROR,
    1951             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1952             :                  errmsg_internal("%s", err),
    1953             :                  parser_errposition(pstate, sublink->location)));
    1954             : 
    1955       65394 :     pstate->p_hasSubLinks = true;
    1956             : 
    1957             :     /*
    1958             :      * OK, let's transform the sub-SELECT.
    1959             :      */
    1960       65394 :     qtree = parse_sub_analyze(sublink->subselect, pstate, NULL, false, true);
    1961             : 
    1962             :     /*
    1963             :      * Check that we got a SELECT.  Anything else should be impossible given
    1964             :      * restrictions of the grammar, but check anyway.
    1965             :      */
    1966       65374 :     if (!IsA(qtree, Query) ||
    1967       65374 :         qtree->commandType != CMD_SELECT)
    1968           0 :         elog(ERROR, "unexpected non-SELECT command in SubLink");
    1969             : 
    1970       65374 :     sublink->subselect = (Node *) qtree;
    1971             : 
    1972       65374 :     if (sublink->subLinkType == EXISTS_SUBLINK)
    1973             :     {
    1974             :         /*
    1975             :          * EXISTS needs no test expression or combining operator. These fields
    1976             :          * should be null already, but make sure.
    1977             :          */
    1978       11180 :         sublink->testexpr = NULL;
    1979       11180 :         sublink->operName = NIL;
    1980             :     }
    1981       54194 :     else if (sublink->subLinkType == EXPR_SUBLINK ||
    1982       19640 :              sublink->subLinkType == ARRAY_SUBLINK)
    1983             :     {
    1984             :         /*
    1985             :          * Make sure the subselect delivers a single column (ignoring resjunk
    1986             :          * targets).
    1987             :          */
    1988       49428 :         if (count_nonjunk_tlist_entries(qtree->targetList) != 1)
    1989           0 :             ereport(ERROR,
    1990             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    1991             :                      errmsg("subquery must return only one column"),
    1992             :                      parser_errposition(pstate, sublink->location)));
    1993             : 
    1994             :         /*
    1995             :          * EXPR and ARRAY need no test expression or combining operator. These
    1996             :          * fields should be null already, but make sure.
    1997             :          */
    1998       49428 :         sublink->testexpr = NULL;
    1999       49428 :         sublink->operName = NIL;
    2000             :     }
    2001        4766 :     else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
    2002             :     {
    2003             :         /* Same as EXPR case, except no restriction on number of columns */
    2004          62 :         sublink->testexpr = NULL;
    2005          62 :         sublink->operName = NIL;
    2006             :     }
    2007             :     else
    2008             :     {
    2009             :         /* ALL, ANY, or ROWCOMPARE: generate row-comparing expression */
    2010             :         Node       *lefthand;
    2011             :         List       *left_list;
    2012             :         List       *right_list;
    2013             :         ListCell   *l;
    2014             : 
    2015        4704 :         if (operator_precedence_warning)
    2016             :         {
    2017           0 :             if (sublink->operName == NIL)
    2018           0 :                 emit_precedence_warnings(pstate, PREC_GROUP_IN, "IN",
    2019             :                                          sublink->testexpr, NULL,
    2020             :                                          sublink->location);
    2021             :             else
    2022           0 :                 emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP,
    2023           0 :                                          strVal(llast(sublink->operName)),
    2024             :                                          sublink->testexpr, NULL,
    2025             :                                          sublink->location);
    2026             :         }
    2027             : 
    2028             :         /*
    2029             :          * If the source was "x IN (select)", convert to "x = ANY (select)".
    2030             :          */
    2031        4704 :         if (sublink->operName == NIL)
    2032        4630 :             sublink->operName = list_make1(makeString("="));
    2033             : 
    2034             :         /*
    2035             :          * Transform lefthand expression, and convert to a list
    2036             :          */
    2037        4704 :         lefthand = transformExprRecurse(pstate, sublink->testexpr);
    2038        4704 :         if (lefthand && IsA(lefthand, RowExpr))
    2039         426 :             left_list = ((RowExpr *) lefthand)->args;
    2040             :         else
    2041        4278 :             left_list = list_make1(lefthand);
    2042             : 
    2043             :         /*
    2044             :          * Build a list of PARAM_SUBLINK nodes representing the output columns
    2045             :          * of the subquery.
    2046             :          */
    2047        4704 :         right_list = NIL;
    2048       10558 :         foreach(l, qtree->targetList)
    2049             :         {
    2050        5854 :             TargetEntry *tent = (TargetEntry *) lfirst(l);
    2051             :             Param      *param;
    2052             : 
    2053        5854 :             if (tent->resjunk)
    2054           8 :                 continue;
    2055             : 
    2056        5846 :             param = makeNode(Param);
    2057        5846 :             param->paramkind = PARAM_SUBLINK;
    2058        5846 :             param->paramid = tent->resno;
    2059        5846 :             param->paramtype = exprType((Node *) tent->expr);
    2060        5846 :             param->paramtypmod = exprTypmod((Node *) tent->expr);
    2061        5846 :             param->paramcollid = exprCollation((Node *) tent->expr);
    2062        5846 :             param->location = -1;
    2063             : 
    2064        5846 :             right_list = lappend(right_list, param);
    2065             :         }
    2066             : 
    2067             :         /*
    2068             :          * We could rely on make_row_comparison_op to complain if the list
    2069             :          * lengths differ, but we prefer to generate a more specific error
    2070             :          * message.
    2071             :          */
    2072        4704 :         if (list_length(left_list) < list_length(right_list))
    2073           0 :             ereport(ERROR,
    2074             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2075             :                      errmsg("subquery has too many columns"),
    2076             :                      parser_errposition(pstate, sublink->location)));
    2077        4704 :         if (list_length(left_list) > list_length(right_list))
    2078           0 :             ereport(ERROR,
    2079             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2080             :                      errmsg("subquery has too few columns"),
    2081             :                      parser_errposition(pstate, sublink->location)));
    2082             : 
    2083             :         /*
    2084             :          * Identify the combining operator(s) and generate a suitable
    2085             :          * row-comparison expression.
    2086             :          */
    2087        4704 :         sublink->testexpr = make_row_comparison_op(pstate,
    2088             :                                                    sublink->operName,
    2089             :                                                    left_list,
    2090             :                                                    right_list,
    2091             :                                                    sublink->location);
    2092             :     }
    2093             : 
    2094       65370 :     return result;
    2095             : }
    2096             : 
    2097             : /*
    2098             :  * transformArrayExpr
    2099             :  *
    2100             :  * If the caller specifies the target type, the resulting array will
    2101             :  * be of exactly that type.  Otherwise we try to infer a common type
    2102             :  * for the elements using select_common_type().
    2103             :  */
    2104             : static Node *
    2105        4286 : transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
    2106             :                    Oid array_type, Oid element_type, int32 typmod)
    2107             : {
    2108        4286 :     ArrayExpr  *newa = makeNode(ArrayExpr);
    2109        4286 :     List       *newelems = NIL;
    2110        4286 :     List       *newcoercedelems = NIL;
    2111             :     ListCell   *element;
    2112             :     Oid         coerce_type;
    2113             :     bool        coerce_hard;
    2114             : 
    2115             :     /*
    2116             :      * Transform the element expressions
    2117             :      *
    2118             :      * Assume that the array is one-dimensional unless we find an array-type
    2119             :      * element expression.
    2120             :      */
    2121        4286 :     newa->multidims = false;
    2122       14628 :     foreach(element, a->elements)
    2123             :     {
    2124       10342 :         Node       *e = (Node *) lfirst(element);
    2125             :         Node       *newe;
    2126             : 
    2127             :         /* Look through AEXPR_PAREN nodes so they don't affect test below */
    2128       10342 :         while (e && IsA(e, A_Expr) &&
    2129         126 :                ((A_Expr *) e)->kind == AEXPR_PAREN)
    2130           0 :             e = ((A_Expr *) e)->lexpr;
    2131             : 
    2132             :         /*
    2133             :          * If an element is itself an A_ArrayExpr, recurse directly so that we
    2134             :          * can pass down any target type we were given.
    2135             :          */
    2136       10342 :         if (IsA(e, A_ArrayExpr))
    2137             :         {
    2138         620 :             newe = transformArrayExpr(pstate,
    2139             :                                       (A_ArrayExpr *) e,
    2140             :                                       array_type,
    2141             :                                       element_type,
    2142             :                                       typmod);
    2143             :             /* we certainly have an array here */
    2144             :             Assert(array_type == InvalidOid || array_type == exprType(newe));
    2145         620 :             newa->multidims = true;
    2146             :         }
    2147             :         else
    2148             :         {
    2149        9722 :             newe = transformExprRecurse(pstate, e);
    2150             : 
    2151             :             /*
    2152             :              * Check for sub-array expressions, if we haven't already found
    2153             :              * one.
    2154             :              */
    2155        9722 :             if (!newa->multidims && type_is_array(exprType(newe)))
    2156           4 :                 newa->multidims = true;
    2157             :         }
    2158             : 
    2159       10342 :         newelems = lappend(newelems, newe);
    2160             :     }
    2161             : 
    2162             :     /*
    2163             :      * Select a target type for the elements.
    2164             :      *
    2165             :      * If we haven't been given a target array type, we must try to deduce a
    2166             :      * common type based on the types of the individual elements present.
    2167             :      */
    2168        4286 :     if (OidIsValid(array_type))
    2169             :     {
    2170             :         /* Caller must ensure array_type matches element_type */
    2171             :         Assert(OidIsValid(element_type));
    2172         468 :         coerce_type = (newa->multidims ? array_type : element_type);
    2173         468 :         coerce_hard = true;
    2174             :     }
    2175             :     else
    2176             :     {
    2177             :         /* Can't handle an empty array without a target type */
    2178        3818 :         if (newelems == NIL)
    2179           4 :             ereport(ERROR,
    2180             :                     (errcode(ERRCODE_INDETERMINATE_DATATYPE),
    2181             :                      errmsg("cannot determine type of empty array"),
    2182             :                      errhint("Explicitly cast to the desired type, "
    2183             :                              "for example ARRAY[]::integer[]."),
    2184             :                      parser_errposition(pstate, a->location)));
    2185             : 
    2186             :         /* Select a common type for the elements */
    2187        3814 :         coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
    2188             : 
    2189        3814 :         if (newa->multidims)
    2190             :         {
    2191         294 :             array_type = coerce_type;
    2192         294 :             element_type = get_element_type(array_type);
    2193         294 :             if (!OidIsValid(element_type))
    2194           0 :                 ereport(ERROR,
    2195             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2196             :                          errmsg("could not find element type for data type %s",
    2197             :                                 format_type_be(array_type)),
    2198             :                          parser_errposition(pstate, a->location)));
    2199             :         }
    2200             :         else
    2201             :         {
    2202        3520 :             element_type = coerce_type;
    2203        3520 :             array_type = get_array_type(element_type);
    2204        3520 :             if (!OidIsValid(array_type))
    2205           0 :                 ereport(ERROR,
    2206             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2207             :                          errmsg("could not find array type for data type %s",
    2208             :                                 format_type_be(element_type)),
    2209             :                          parser_errposition(pstate, a->location)));
    2210             :         }
    2211        3814 :         coerce_hard = false;
    2212             :     }
    2213             : 
    2214             :     /*
    2215             :      * Coerce elements to target type
    2216             :      *
    2217             :      * If the array has been explicitly cast, then the elements are in turn
    2218             :      * explicitly coerced.
    2219             :      *
    2220             :      * If the array's type was merely derived from the common type of its
    2221             :      * elements, then the elements are implicitly coerced to the common type.
    2222             :      * This is consistent with other uses of select_common_type().
    2223             :      */
    2224       14624 :     foreach(element, newelems)
    2225             :     {
    2226       10342 :         Node       *e = (Node *) lfirst(element);
    2227             :         Node       *newe;
    2228             : 
    2229       10342 :         if (coerce_hard)
    2230             :         {
    2231        1160 :             newe = coerce_to_target_type(pstate, e,
    2232             :                                          exprType(e),
    2233             :                                          coerce_type,
    2234             :                                          typmod,
    2235             :                                          COERCION_EXPLICIT,
    2236             :                                          COERCE_EXPLICIT_CAST,
    2237             :                                          -1);
    2238        1160 :             if (newe == NULL)
    2239           0 :                 ereport(ERROR,
    2240             :                         (errcode(ERRCODE_CANNOT_COERCE),
    2241             :                          errmsg("cannot cast type %s to %s",
    2242             :                                 format_type_be(exprType(e)),
    2243             :                                 format_type_be(coerce_type)),
    2244             :                          parser_errposition(pstate, exprLocation(e))));
    2245             :         }
    2246             :         else
    2247        9182 :             newe = coerce_to_common_type(pstate, e,
    2248             :                                          coerce_type,
    2249             :                                          "ARRAY");
    2250       10342 :         newcoercedelems = lappend(newcoercedelems, newe);
    2251             :     }
    2252             : 
    2253        4282 :     newa->array_typeid = array_type;
    2254             :     /* array_collid will be set by parse_collate.c */
    2255        4282 :     newa->element_typeid = element_type;
    2256        4282 :     newa->elements = newcoercedelems;
    2257        4282 :     newa->location = a->location;
    2258             : 
    2259        4282 :     return (Node *) newa;
    2260             : }
    2261             : 
    2262             : static Node *
    2263        6562 : transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
    2264             : {
    2265             :     RowExpr    *newr;
    2266             :     char        fname[16];
    2267             :     int         fnum;
    2268             : 
    2269        6562 :     newr = makeNode(RowExpr);
    2270             : 
    2271             :     /* Transform the field expressions */
    2272        6562 :     newr->args = transformExpressionList(pstate, r->args,
    2273             :                                          pstate->p_expr_kind, allowDefault);
    2274             : 
    2275             :     /* Barring later casting, we consider the type RECORD */
    2276        6562 :     newr->row_typeid = RECORDOID;
    2277        6562 :     newr->row_format = COERCE_IMPLICIT_CAST;
    2278             : 
    2279             :     /* ROW() has anonymous columns, so invent some field names */
    2280        6562 :     newr->colnames = NIL;
    2281       22284 :     for (fnum = 1; fnum <= list_length(newr->args); fnum++)
    2282             :     {
    2283       15722 :         snprintf(fname, sizeof(fname), "f%d", fnum);
    2284       15722 :         newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname)));
    2285             :     }
    2286             : 
    2287        6562 :     newr->location = r->location;
    2288             : 
    2289        6562 :     return (Node *) newr;
    2290             : }
    2291             : 
    2292             : static Node *
    2293       18176 : transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
    2294             : {
    2295       18176 :     CoalesceExpr *newc = makeNode(CoalesceExpr);
    2296       18176 :     Node       *last_srf = pstate->p_last_srf;
    2297       18176 :     List       *newargs = NIL;
    2298       18176 :     List       *newcoercedargs = NIL;
    2299             :     ListCell   *args;
    2300             : 
    2301       54520 :     foreach(args, c->args)
    2302             :     {
    2303       36344 :         Node       *e = (Node *) lfirst(args);
    2304             :         Node       *newe;
    2305             : 
    2306       36344 :         newe = transformExprRecurse(pstate, e);
    2307       36344 :         newargs = lappend(newargs, newe);
    2308             :     }
    2309             : 
    2310       18176 :     newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
    2311             :     /* coalescecollid will be set by parse_collate.c */
    2312             : 
    2313             :     /* Convert arguments if necessary */
    2314       54520 :     foreach(args, newargs)
    2315             :     {
    2316       36344 :         Node       *e = (Node *) lfirst(args);
    2317             :         Node       *newe;
    2318             : 
    2319       36344 :         newe = coerce_to_common_type(pstate, e,
    2320             :                                      newc->coalescetype,
    2321             :                                      "COALESCE");
    2322       36344 :         newcoercedargs = lappend(newcoercedargs, newe);
    2323             :     }
    2324             : 
    2325             :     /* if any subexpression contained a SRF, complain */
    2326       18176 :     if (pstate->p_last_srf != last_srf)
    2327           4 :         ereport(ERROR,
    2328             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2329             :         /* translator: %s is name of a SQL construct, eg GROUP BY */
    2330             :                  errmsg("set-returning functions are not allowed in %s",
    2331             :                         "COALESCE"),
    2332             :                  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
    2333             :                  parser_errposition(pstate,
    2334             :                                     exprLocation(pstate->p_last_srf))));
    2335             : 
    2336       18172 :     newc->args = newcoercedargs;
    2337       18172 :     newc->location = c->location;
    2338       18172 :     return (Node *) newc;
    2339             : }
    2340             : 
    2341             : static Node *
    2342         134 : transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
    2343             : {
    2344         134 :     MinMaxExpr *newm = makeNode(MinMaxExpr);
    2345         134 :     List       *newargs = NIL;
    2346         134 :     List       *newcoercedargs = NIL;
    2347         134 :     const char *funcname = (m->op == IS_GREATEST) ? "GREATEST" : "LEAST";
    2348             :     ListCell   *args;
    2349             : 
    2350         134 :     newm->op = m->op;
    2351         438 :     foreach(args, m->args)
    2352             :     {
    2353         304 :         Node       *e = (Node *) lfirst(args);
    2354             :         Node       *newe;
    2355             : 
    2356         304 :         newe = transformExprRecurse(pstate, e);
    2357         304 :         newargs = lappend(newargs, newe);
    2358             :     }
    2359             : 
    2360         134 :     newm->minmaxtype = select_common_type(pstate, newargs, funcname, NULL);
    2361             :     /* minmaxcollid and inputcollid will be set by parse_collate.c */
    2362             : 
    2363             :     /* Convert arguments if necessary */
    2364         438 :     foreach(args, newargs)
    2365             :     {
    2366         304 :         Node       *e = (Node *) lfirst(args);
    2367             :         Node       *newe;
    2368             : 
    2369         304 :         newe = coerce_to_common_type(pstate, e,
    2370             :                                      newm->minmaxtype,
    2371             :                                      funcname);
    2372         304 :         newcoercedargs = lappend(newcoercedargs, newe);
    2373             :     }
    2374             : 
    2375         134 :     newm->args = newcoercedargs;
    2376         134 :     newm->location = m->location;
    2377         134 :     return (Node *) newm;
    2378             : }
    2379             : 
    2380             : static Node *
    2381        2500 : transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
    2382             : {
    2383             :     /*
    2384             :      * All we need to do is insert the correct result type and (where needed)
    2385             :      * validate the typmod, so we just modify the node in-place.
    2386             :      */
    2387        2500 :     switch (svf->op)
    2388             :     {
    2389          30 :         case SVFOP_CURRENT_DATE:
    2390          30 :             svf->type = DATEOID;
    2391          30 :             break;
    2392           4 :         case SVFOP_CURRENT_TIME:
    2393           4 :             svf->type = TIMETZOID;
    2394           4 :             break;
    2395           4 :         case SVFOP_CURRENT_TIME_N:
    2396           4 :             svf->type = TIMETZOID;
    2397           4 :             svf->typmod = anytime_typmod_check(true, svf->typmod);
    2398           4 :             break;
    2399         248 :         case SVFOP_CURRENT_TIMESTAMP:
    2400         248 :             svf->type = TIMESTAMPTZOID;
    2401         248 :             break;
    2402         362 :         case SVFOP_CURRENT_TIMESTAMP_N:
    2403         362 :             svf->type = TIMESTAMPTZOID;
    2404         362 :             svf->typmod = anytimestamp_typmod_check(true, svf->typmod);
    2405         362 :             break;
    2406           4 :         case SVFOP_LOCALTIME:
    2407           4 :             svf->type = TIMEOID;
    2408           4 :             break;
    2409           4 :         case SVFOP_LOCALTIME_N:
    2410           4 :             svf->type = TIMEOID;
    2411           4 :             svf->typmod = anytime_typmod_check(false, svf->typmod);
    2412           4 :             break;
    2413          12 :         case SVFOP_LOCALTIMESTAMP:
    2414          12 :             svf->type = TIMESTAMPOID;
    2415          12 :             break;
    2416           4 :         case SVFOP_LOCALTIMESTAMP_N:
    2417           4 :             svf->type = TIMESTAMPOID;
    2418           4 :             svf->typmod = anytimestamp_typmod_check(false, svf->typmod);
    2419           4 :             break;
    2420        1828 :         case SVFOP_CURRENT_ROLE:
    2421             :         case SVFOP_CURRENT_USER:
    2422             :         case SVFOP_USER:
    2423             :         case SVFOP_SESSION_USER:
    2424             :         case SVFOP_CURRENT_CATALOG:
    2425             :         case SVFOP_CURRENT_SCHEMA:
    2426        1828 :             svf->type = NAMEOID;
    2427        1828 :             break;
    2428             :     }
    2429             : 
    2430        2500 :     return (Node *) svf;
    2431             : }
    2432             : 
    2433             : static Node *
    2434         398 : transformXmlExpr(ParseState *pstate, XmlExpr *x)
    2435             : {
    2436             :     XmlExpr    *newx;
    2437             :     ListCell   *lc;
    2438             :     int         i;
    2439             : 
    2440         398 :     if (operator_precedence_warning && x->op == IS_DOCUMENT)
    2441           0 :         emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
    2442           0 :                                  (Node *) linitial(x->args), NULL,
    2443             :                                  x->location);
    2444             : 
    2445         398 :     newx = makeNode(XmlExpr);
    2446         398 :     newx->op = x->op;
    2447         398 :     if (x->name)
    2448         174 :         newx->name = map_sql_identifier_to_xml_name(x->name, false, false);
    2449             :     else
    2450         224 :         newx->name = NULL;
    2451         398 :     newx->xmloption = x->xmloption;
    2452         398 :     newx->type = XMLOID;     /* this just marks the node as transformed */
    2453         398 :     newx->typmod = -1;
    2454         398 :     newx->location = x->location;
    2455             : 
    2456             :     /*
    2457             :      * gram.y built the named args as a list of ResTarget.  Transform each,
    2458             :      * and break the names out as a separate list.
    2459             :      */
    2460         398 :     newx->named_args = NIL;
    2461         398 :     newx->arg_names = NIL;
    2462             : 
    2463         548 :     foreach(lc, x->named_args)
    2464             :     {
    2465         158 :         ResTarget  *r = lfirst_node(ResTarget, lc);
    2466             :         Node       *expr;
    2467             :         char       *argname;
    2468             : 
    2469         158 :         expr = transformExprRecurse(pstate, r->val);
    2470             : 
    2471         158 :         if (r->name)
    2472          74 :             argname = map_sql_identifier_to_xml_name(r->name, false, false);
    2473          84 :         else if (IsA(r->val, ColumnRef))
    2474          80 :             argname = map_sql_identifier_to_xml_name(FigureColname(r->val),
    2475             :                                                      true, false);
    2476             :         else
    2477             :         {
    2478           4 :             ereport(ERROR,
    2479             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2480             :                      x->op == IS_XMLELEMENT
    2481             :                      ? errmsg("unnamed XML attribute value must be a column reference")
    2482             :                      : errmsg("unnamed XML element value must be a column reference"),
    2483             :                      parser_errposition(pstate, r->location)));
    2484             :             argname = NULL;     /* keep compiler quiet */
    2485             :         }
    2486             : 
    2487             :         /* reject duplicate argnames in XMLELEMENT only */
    2488         154 :         if (x->op == IS_XMLELEMENT)
    2489             :         {
    2490             :             ListCell   *lc2;
    2491             : 
    2492          82 :             foreach(lc2, newx->arg_names)
    2493             :             {
    2494          26 :                 if (strcmp(argname, strVal(lfirst(lc2))) == 0)
    2495           4 :                     ereport(ERROR,
    2496             :                             (errcode(ERRCODE_SYNTAX_ERROR),
    2497             :                              errmsg("XML attribute name \"%s\" appears more than once",
    2498             :                                     argname),
    2499             :                              parser_errposition(pstate, r->location)));
    2500             :             }
    2501             :         }
    2502             : 
    2503         150 :         newx->named_args = lappend(newx->named_args, expr);
    2504         150 :         newx->arg_names = lappend(newx->arg_names, makeString(argname));
    2505             :     }
    2506             : 
    2507             :     /* The other arguments are of varying types depending on the function */
    2508         390 :     newx->args = NIL;
    2509         390 :     i = 0;
    2510         938 :     foreach(lc, x->args)
    2511             :     {
    2512         560 :         Node       *e = (Node *) lfirst(lc);
    2513             :         Node       *newe;
    2514             : 
    2515         560 :         newe = transformExprRecurse(pstate, e);
    2516         560 :         switch (x->op)
    2517             :         {
    2518          88 :             case IS_XMLCONCAT:
    2519          88 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2520             :                                                "XMLCONCAT");
    2521          80 :                 break;
    2522          92 :             case IS_XMLELEMENT:
    2523             :                 /* no coercion necessary */
    2524          92 :                 break;
    2525           0 :             case IS_XMLFOREST:
    2526           0 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2527             :                                                "XMLFOREST");
    2528           0 :                 break;
    2529         188 :             case IS_XMLPARSE:
    2530         188 :                 if (i == 0)
    2531          94 :                     newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2532             :                                                    "XMLPARSE");
    2533             :                 else
    2534          94 :                     newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
    2535         188 :                 break;
    2536          34 :             case IS_XMLPI:
    2537          34 :                 newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2538             :                                                "XMLPI");
    2539          34 :                 break;
    2540         138 :             case IS_XMLROOT:
    2541         138 :                 if (i == 0)
    2542          46 :                     newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2543             :                                                    "XMLROOT");
    2544          92 :                 else if (i == 1)
    2545          46 :                     newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2546             :                                                    "XMLROOT");
    2547             :                 else
    2548          46 :                     newe = coerce_to_specific_type(pstate, newe, INT4OID,
    2549             :                                                    "XMLROOT");
    2550         138 :                 break;
    2551           0 :             case IS_XMLSERIALIZE:
    2552             :                 /* not handled here */
    2553             :                 Assert(false);
    2554           0 :                 break;
    2555          20 :             case IS_DOCUMENT:
    2556          20 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2557             :                                                "IS DOCUMENT");
    2558          16 :                 break;
    2559             :         }
    2560         548 :         newx->args = lappend(newx->args, newe);
    2561         548 :         i++;
    2562             :     }
    2563             : 
    2564         378 :     return (Node *) newx;
    2565             : }
    2566             : 
    2567             : static Node *
    2568          24 : transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
    2569             : {
    2570             :     Node       *result;
    2571             :     XmlExpr    *xexpr;
    2572             :     Oid         targetType;
    2573             :     int32       targetTypmod;
    2574             : 
    2575          24 :     xexpr = makeNode(XmlExpr);
    2576          24 :     xexpr->op = IS_XMLSERIALIZE;
    2577          24 :     xexpr->args = list_make1(coerce_to_specific_type(pstate,
    2578             :                                                      transformExprRecurse(pstate, xs->expr),
    2579             :                                                      XMLOID,
    2580             :                                                      "XMLSERIALIZE"));
    2581             : 
    2582          24 :     typenameTypeIdAndMod(pstate, xs->typeName, &targetType, &targetTypmod);
    2583             : 
    2584          24 :     xexpr->xmloption = xs->xmloption;
    2585          24 :     xexpr->location = xs->location;
    2586             :     /* We actually only need these to be able to parse back the expression. */
    2587          24 :     xexpr->type = targetType;
    2588          24 :     xexpr->typmod = targetTypmod;
    2589             : 
    2590             :     /*
    2591             :      * The actual target type is determined this way.  SQL allows char and
    2592             :      * varchar as target types.  We allow anything that can be cast implicitly
    2593             :      * from text.  This way, user-defined text-like data types automatically
    2594             :      * fit in.
    2595             :      */
    2596          24 :     result = coerce_to_target_type(pstate, (Node *) xexpr,
    2597             :                                    TEXTOID, targetType, targetTypmod,
    2598             :                                    COERCION_IMPLICIT,
    2599             :                                    COERCE_IMPLICIT_CAST,
    2600             :                                    -1);
    2601          24 :     if (result == NULL)
    2602           0 :         ereport(ERROR,
    2603             :                 (errcode(ERRCODE_CANNOT_COERCE),
    2604             :                  errmsg("cannot cast XMLSERIALIZE result to %s",
    2605             :                         format_type_be(targetType)),
    2606             :                  parser_errposition(pstate, xexpr->location)));
    2607          24 :     return result;
    2608             : }
    2609             : 
    2610             : static Node *
    2611         130 : transformBooleanTest(ParseState *pstate, BooleanTest *b)
    2612             : {
    2613             :     const char *clausename;
    2614             : 
    2615         130 :     if (operator_precedence_warning)
    2616           0 :         emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
    2617           0 :                                  (Node *) b->arg, NULL,
    2618             :                                  b->location);
    2619             : 
    2620         130 :     switch (b->booltesttype)
    2621             :     {
    2622          28 :         case IS_TRUE:
    2623          28 :             clausename = "IS TRUE";
    2624          28 :             break;
    2625          34 :         case IS_NOT_TRUE:
    2626          34 :             clausename = "IS NOT TRUE";
    2627          34 :             break;
    2628          28 :         case IS_FALSE:
    2629          28 :             clausename = "IS FALSE";
    2630          28 :             break;
    2631          20 :         case IS_NOT_FALSE:
    2632          20 :             clausename = "IS NOT FALSE";
    2633          20 :             break;
    2634          12 :         case IS_UNKNOWN:
    2635          12 :             clausename = "IS UNKNOWN";
    2636          12 :             break;
    2637           8 :         case IS_NOT_UNKNOWN:
    2638           8 :             clausename = "IS NOT UNKNOWN";
    2639           8 :             break;
    2640           0 :         default:
    2641           0 :             elog(ERROR, "unrecognized booltesttype: %d",
    2642             :                  (int) b->booltesttype);
    2643             :             clausename = NULL;  /* keep compiler quiet */
    2644             :     }
    2645             : 
    2646         130 :     b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
    2647             : 
    2648         260 :     b->arg = (Expr *) coerce_to_boolean(pstate,
    2649         130 :                                         (Node *) b->arg,
    2650             :                                         clausename);
    2651             : 
    2652         130 :     return (Node *) b;
    2653             : }
    2654             : 
    2655             : static Node *
    2656         158 : transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
    2657             : {
    2658             :     /* CURRENT OF can only appear at top level of UPDATE/DELETE */
    2659             :     Assert(pstate->p_target_nsitem != NULL);
    2660         158 :     cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
    2661             : 
    2662             :     /*
    2663             :      * Check to see if the cursor name matches a parameter of type REFCURSOR.
    2664             :      * If so, replace the raw name reference with a parameter reference. (This
    2665             :      * is a hack for the convenience of plpgsql.)
    2666             :      */
    2667         158 :     if (cexpr->cursor_name != NULL) /* in case already transformed */
    2668             :     {
    2669         158 :         ColumnRef  *cref = makeNode(ColumnRef);
    2670         158 :         Node       *node = NULL;
    2671             : 
    2672             :         /* Build an unqualified ColumnRef with the given name */
    2673         158 :         cref->fields = list_make1(makeString(cexpr->cursor_name));
    2674         158 :         cref->location = -1;
    2675             : 
    2676             :         /* See if there is a translation available from a parser hook */
    2677         158 :         if (pstate->p_pre_columnref_hook != NULL)
    2678           8 :             node = pstate->p_pre_columnref_hook(pstate, cref);
    2679         158 :         if (node == NULL && pstate->p_post_columnref_hook != NULL)
    2680           8 :             node = pstate->p_post_columnref_hook(pstate, cref, NULL);
    2681             : 
    2682             :         /*
    2683             :          * XXX Should we throw an error if we get a translation that isn't a
    2684             :          * refcursor Param?  For now it seems best to silently ignore false
    2685             :          * matches.
    2686             :          */
    2687         158 :         if (node != NULL && IsA(node, Param))
    2688             :         {
    2689           8 :             Param      *p = (Param *) node;
    2690             : 
    2691           8 :             if (p->paramkind == PARAM_EXTERN &&
    2692           8 :                 p->paramtype == REFCURSOROID)
    2693             :             {
    2694             :                 /* Matches, so convert CURRENT OF to a param reference */
    2695           8 :                 cexpr->cursor_name = NULL;
    2696           8 :                 cexpr->cursor_param = p->paramid;
    2697             :             }
    2698             :         }
    2699             :     }
    2700             : 
    2701         158 :     return (Node *) cexpr;
    2702             : }
    2703             : 
    2704             : /*
    2705             :  * Construct a whole-row reference to represent the notation "relation.*".
    2706             :  */
    2707             : static Node *
    2708       21796 : transformWholeRowRef(ParseState *pstate, ParseNamespaceItem *nsitem,
    2709             :                      int sublevels_up, int location)
    2710             : {
    2711             :     Var        *result;
    2712             : 
    2713             :     /*
    2714             :      * Build the appropriate referencing node.  Note that if the RTE is a
    2715             :      * function returning scalar, we create just a plain reference to the
    2716             :      * function value, not a composite containing a single column.  This is
    2717             :      * pretty inconsistent at first sight, but it's what we've done
    2718             :      * historically.  One argument for it is that "rel" and "rel.*" mean the
    2719             :      * same thing for composite relations, so why not for scalar functions...
    2720             :      */
    2721       21796 :     result = makeWholeRowVar(nsitem->p_rte, nsitem->p_rtindex,
    2722             :                              sublevels_up, true);
    2723             : 
    2724             :     /* location is not filled in by makeWholeRowVar */
    2725       21796 :     result->location = location;
    2726             : 
    2727             :     /* mark relation as requiring whole-row SELECT access */
    2728       21796 :     markVarForSelectPriv(pstate, result, nsitem->p_rte);
    2729             : 
    2730       21796 :     return (Node *) result;
    2731             : }
    2732             : 
    2733             : /*
    2734             :  * Handle an explicit CAST construct.
    2735             :  *
    2736             :  * Transform the argument, look up the type name, and apply any necessary
    2737             :  * coercion function(s).
    2738             :  */
    2739             : static Node *
    2740      396600 : transformTypeCast(ParseState *pstate, TypeCast *tc)
    2741             : {
    2742             :     Node       *result;
    2743      396600 :     Node       *arg = tc->arg;
    2744             :     Node       *expr;
    2745             :     Oid         inputType;
    2746             :     Oid         targetType;
    2747             :     int32       targetTypmod;
    2748             :     int         location;
    2749             : 
    2750             :     /* Look up the type name first */
    2751      396600 :     typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
    2752             : 
    2753             :     /*
    2754             :      * Look through any AEXPR_PAREN nodes that may have been inserted thanks
    2755             :      * to operator_precedence_warning.  Otherwise, ARRAY[]::foo[] behaves
    2756             :      * differently from (ARRAY[])::foo[].
    2757             :      */
    2758      396600 :     while (arg && IsA(arg, A_Expr) &&
    2759        2710 :            ((A_Expr *) arg)->kind == AEXPR_PAREN)
    2760           0 :         arg = ((A_Expr *) arg)->lexpr;
    2761             : 
    2762             :     /*
    2763             :      * If the subject of the typecast is an ARRAY[] construct and the target
    2764             :      * type is an array type, we invoke transformArrayExpr() directly so that
    2765             :      * we can pass down the type information.  This avoids some cases where
    2766             :      * transformArrayExpr() might not infer the correct type.  Otherwise, just
    2767             :      * transform the argument normally.
    2768             :      */
    2769      396600 :     if (IsA(arg, A_ArrayExpr))
    2770             :     {
    2771             :         Oid         targetBaseType;
    2772             :         int32       targetBaseTypmod;
    2773             :         Oid         elementType;
    2774             : 
    2775             :         /*
    2776             :          * If target is a domain over array, work with the base array type
    2777             :          * here.  Below, we'll cast the array type to the domain.  In the
    2778             :          * usual case that the target is not a domain, the remaining steps
    2779             :          * will be a no-op.
    2780             :          */
    2781         382 :         targetBaseTypmod = targetTypmod;
    2782         382 :         targetBaseType = getBaseTypeAndTypmod(targetType, &targetBaseTypmod);
    2783         382 :         elementType = get_element_type(targetBaseType);
    2784         382 :         if (OidIsValid(elementType))
    2785             :         {
    2786         372 :             expr = transformArrayExpr(pstate,
    2787             :                                       (A_ArrayExpr *) arg,
    2788             :                                       targetBaseType,
    2789             :                                       elementType,
    2790             :                                       targetBaseTypmod);
    2791             :         }
    2792             :         else
    2793          10 :             expr = transformExprRecurse(pstate, arg);
    2794             :     }
    2795             :     else
    2796      396218 :         expr = transformExprRecurse(pstate, arg);
    2797             : 
    2798      396588 :     inputType = exprType(expr);
    2799      396588 :     if (inputType == InvalidOid)
    2800           0 :         return expr;            /* do nothing if NULL input */
    2801             : 
    2802             :     /*
    2803             :      * Location of the coercion is preferentially the location of the :: or
    2804             :      * CAST symbol, but if there is none then use the location of the type
    2805             :      * name (this can happen in TypeName 'string' syntax, for instance).
    2806             :      */
    2807      396588 :     location = tc->location;
    2808      396588 :     if (location < 0)
    2809       34148 :         location = tc->typeName->location;
    2810             : 
    2811      396588 :     result = coerce_to_target_type(pstate, expr, inputType,
    2812             :                                    targetType, targetTypmod,
    2813             :                                    COERCION_EXPLICIT,
    2814             :                                    COERCE_EXPLICIT_CAST,
    2815             :                                    location);
    2816      395420 :     if (result == NULL)
    2817          16 :         ereport(ERROR,
    2818             :                 (errcode(ERRCODE_CANNOT_COERCE),
    2819             :                  errmsg("cannot cast type %s to %s",
    2820             :                         format_type_be(inputType),
    2821             :                         format_type_be(targetType)),
    2822             :                  parser_coercion_errposition(pstate, location, expr)));
    2823             : 
    2824      395404 :     return result;
    2825             : }
    2826             : 
    2827             : /*
    2828             :  * Handle an explicit COLLATE clause.
    2829             :  *
    2830             :  * Transform the argument, and look up the collation name.
    2831             :  */
    2832             : static Node *
    2833        2860 : transformCollateClause(ParseState *pstate, CollateClause *c)
    2834             : {
    2835             :     CollateExpr *newc;
    2836             :     Oid         argtype;
    2837             : 
    2838        2860 :     newc = makeNode(CollateExpr);
    2839        2860 :     newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
    2840             : 
    2841        2860 :     argtype = exprType((Node *) newc->arg);
    2842             : 
    2843             :     /*
    2844             :      * The unknown type is not collatable, but coerce_type() takes care of it
    2845             :      * separately, so we'll let it go here.
    2846             :      */
    2847        2860 :     if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
    2848           8 :         ereport(ERROR,
    2849             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    2850             :                  errmsg("collations are not supported by type %s",
    2851             :                         format_type_be(argtype)),
    2852             :                  parser_errposition(pstate, c->location)));
    2853             : 
    2854        2852 :     newc->collOid = LookupCollation(pstate, c->collname, c->location);
    2855        2852 :     newc->location = c->location;
    2856             : 
    2857        2852 :     return (Node *) newc;
    2858             : }
    2859             : 
    2860             : /*
    2861             :  * Transform a "row compare-op row" construct
    2862             :  *
    2863             :  * The inputs are lists of already-transformed expressions.
    2864             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    2865             :  * processing is wanted.
    2866             :  *
    2867             :  * The output may be a single OpExpr, an AND or OR combination of OpExprs,
    2868             :  * or a RowCompareExpr.  In all cases it is guaranteed to return boolean.
    2869             :  * The AND, OR, and RowCompareExpr cases further imply things about the
    2870             :  * behavior of the operators (ie, they behave as =, <>, or < <= > >=).
    2871             :  */
    2872             : static Node *
    2873        6646 : make_row_comparison_op(ParseState *pstate, List *opname,
    2874             :                        List *largs, List *rargs, int location)
    2875             : {
    2876             :     RowCompareExpr *rcexpr;
    2877             :     RowCompareType rctype;
    2878             :     List       *opexprs;
    2879             :     List       *opnos;
    2880             :     List       *opfamilies;
    2881             :     ListCell   *l,
    2882             :                *r;
    2883             :     List      **opinfo_lists;
    2884             :     Bitmapset  *strats;
    2885             :     int         nopers;
    2886             :     int         i;
    2887             : 
    2888        6646 :     nopers = list_length(largs);
    2889        6646 :     if (nopers != list_length(rargs))
    2890           0 :         ereport(ERROR,
    2891             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    2892             :                  errmsg("unequal number of entries in row expressions"),
    2893             :                  parser_errposition(pstate, location)));
    2894             : 
    2895             :     /*
    2896             :      * We can't compare zero-length rows because there is no principled basis
    2897             :      * for figuring out what the operator is.
    2898             :      */
    2899        6646 :     if (nopers == 0)
    2900           4 :         ereport(ERROR,
    2901             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2902             :                  errmsg("cannot compare rows of zero length"),
    2903             :                  parser_errposition(pstate, location)));
    2904             : 
    2905             :     /*
    2906             :      * Identify all the pairwise operators, using make_op so that behavior is
    2907             :      * the same as in the simple scalar case.
    2908             :      */
    2909        6642 :     opexprs = NIL;
    2910       16404 :     forboth(l, largs, r, rargs)
    2911             :     {
    2912        9766 :         Node       *larg = (Node *) lfirst(l);
    2913        9766 :         Node       *rarg = (Node *) lfirst(r);
    2914             :         OpExpr     *cmp;
    2915             : 
    2916        9766 :         cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg,
    2917             :                                        pstate->p_last_srf, location));
    2918             : 
    2919             :         /*
    2920             :          * We don't use coerce_to_boolean here because we insist on the
    2921             :          * operator yielding boolean directly, not via coercion.  If it
    2922             :          * doesn't yield bool it won't be in any index opfamilies...
    2923             :          */
    2924        9762 :         if (cmp->opresulttype != BOOLOID)
    2925           0 :             ereport(ERROR,
    2926             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2927             :                      errmsg("row comparison operator must yield type boolean, "
    2928             :                             "not type %s",
    2929             :                             format_type_be(cmp->opresulttype)),
    2930             :                      parser_errposition(pstate, location)));
    2931        9762 :         if (expression_returns_set((Node *) cmp))
    2932           0 :             ereport(ERROR,
    2933             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2934             :                      errmsg("row comparison operator must not return a set"),
    2935             :                      parser_errposition(pstate, location)));
    2936        9762 :         opexprs = lappend(opexprs, cmp);
    2937             :     }
    2938             : 
    2939             :     /*
    2940             :      * If rows are length 1, just return the single operator.  In this case we
    2941             :      * don't insist on identifying btree semantics for the operator (but we
    2942             :      * still require it to return boolean).
    2943             :      */
    2944        6638 :     if (nopers == 1)
    2945        4278 :         return (Node *) linitial(opexprs);
    2946             : 
    2947             :     /*
    2948             :      * Now we must determine which row comparison semantics (= <> < <= > >=)
    2949             :      * apply to this set of operators.  We look for btree opfamilies
    2950             :      * containing the operators, and see which interpretations (strategy
    2951             :      * numbers) exist for each operator.
    2952             :      */
    2953        2360 :     opinfo_lists = (List **) palloc(nopers * sizeof(List *));
    2954        2360 :     strats = NULL;
    2955        2360 :     i = 0;
    2956        7844 :     foreach(l, opexprs)
    2957             :     {
    2958        5484 :         Oid         opno = ((OpExpr *) lfirst(l))->opno;
    2959             :         Bitmapset  *this_strats;
    2960             :         ListCell   *j;
    2961             : 
    2962        5484 :         opinfo_lists[i] = get_op_btree_interpretation(opno);
    2963             : 
    2964             :         /*
    2965             :          * convert strategy numbers into a Bitmapset to make the intersection
    2966             :          * calculation easy.
    2967             :          */
    2968        5484 :         this_strats = NULL;
    2969       11358 :         foreach(j, opinfo_lists[i])
    2970             :         {
    2971        5874 :             OpBtreeInterpretation *opinfo = lfirst(j);
    2972             : 
    2973        5874 :             this_strats = bms_add_member(this_strats, opinfo->strategy);
    2974             :         }
    2975        5484 :         if (i == 0)
    2976        2360 :             strats = this_strats;
    2977             :         else
    2978        3124 :             strats = bms_int_members(strats, this_strats);
    2979        5484 :         i++;
    2980             :     }
    2981             : 
    2982             :     /*
    2983             :      * If there are multiple common interpretations, we may use any one of
    2984             :      * them ... this coding arbitrarily picks the lowest btree strategy
    2985             :      * number.
    2986             :      */
    2987        2360 :     i = bms_first_member(strats);
    2988        2360 :     if (i < 0)
    2989             :     {
    2990             :         /* No common interpretation, so fail */
    2991           4 :         ereport(ERROR,
    2992             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2993             :                  errmsg("could not determine interpretation of row comparison operator %s",
    2994             :                         strVal(llast(opname))),
    2995             :                  errhint("Row comparison operators must be associated with btree operator families."),
    2996             :                  parser_errposition(pstate, location)));
    2997             :     }
    2998        2356 :     rctype = (RowCompareType) i;
    2999             : 
    3000             :     /*
    3001             :      * For = and <> cases, we just combine the pairwise operators with AND or
    3002             :      * OR respectively.
    3003             :      */
    3004        2356 :     if (rctype == ROWCOMPARE_EQ)
    3005         808 :         return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
    3006        1548 :     if (rctype == ROWCOMPARE_NE)
    3007        1440 :         return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
    3008             : 
    3009             :     /*
    3010             :      * Otherwise we need to choose exactly which opfamily to associate with
    3011             :      * each operator.
    3012             :      */
    3013         108 :     opfamilies = NIL;
    3014         360 :     for (i = 0; i < nopers; i++)
    3015             :     {
    3016         252 :         Oid         opfamily = InvalidOid;
    3017             :         ListCell   *j;
    3018             : 
    3019         252 :         foreach(j, opinfo_lists[i])
    3020             :         {
    3021         252 :             OpBtreeInterpretation *opinfo = lfirst(j);
    3022             : 
    3023         252 :             if (opinfo->strategy == rctype)
    3024             :             {
    3025         252 :                 opfamily = opinfo->opfamily_id;
    3026         252 :                 break;
    3027             :             }
    3028             :         }
    3029         252 :         if (OidIsValid(opfamily))
    3030         252 :             opfamilies = lappend_oid(opfamilies, opfamily);
    3031             :         else                    /* should not happen */
    3032           0 :             ereport(ERROR,
    3033             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3034             :                      errmsg("could not determine interpretation of row comparison operator %s",
    3035             :                             strVal(llast(opname))),
    3036             :                      errdetail("There are multiple equally-plausible candidates."),
    3037             :                      parser_errposition(pstate, location)));
    3038             :     }
    3039             : 
    3040             :     /*
    3041             :      * Now deconstruct the OpExprs and create a RowCompareExpr.
    3042             :      *
    3043             :      * Note: can't just reuse the passed largs/rargs lists, because of
    3044             :      * possibility that make_op inserted coercion operations.
    3045             :      */
    3046         108 :     opnos = NIL;
    3047         108 :     largs = NIL;
    3048         108 :     rargs = NIL;
    3049         360 :     foreach(l, opexprs)
    3050             :     {
    3051         252 :         OpExpr     *cmp = (OpExpr *) lfirst(l);
    3052             : 
    3053         252 :         opnos = lappend_oid(opnos, cmp->opno);
    3054         252 :         largs = lappend(largs, linitial(cmp->args));
    3055         252 :         rargs = lappend(rargs, lsecond(cmp->args));
    3056             :     }
    3057             : 
    3058         108 :     rcexpr = makeNode(RowCompareExpr);
    3059         108 :     rcexpr->rctype = rctype;
    3060         108 :     rcexpr->opnos = opnos;
    3061         108 :     rcexpr->opfamilies = opfamilies;
    3062         108 :     rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
    3063         108 :     rcexpr->largs = largs;
    3064         108 :     rcexpr->rargs = rargs;
    3065             : 
    3066         108 :     return (Node *) rcexpr;
    3067             : }
    3068             : 
    3069             : /*
    3070             :  * Transform a "row IS DISTINCT FROM row" construct
    3071             :  *
    3072             :  * The input RowExprs are already transformed
    3073             :  */
    3074             : static Node *
    3075           4 : make_row_distinct_op(ParseState *pstate, List *opname,
    3076             :                      RowExpr *lrow, RowExpr *rrow,
    3077             :                      int location)
    3078             : {
    3079           4 :     Node       *result = NULL;
    3080           4 :     List       *largs = lrow->args;
    3081           4 :     List       *rargs = rrow->args;
    3082             :     ListCell   *l,
    3083             :                *r;
    3084             : 
    3085           4 :     if (list_length(largs) != list_length(rargs))
    3086           0 :         ereport(ERROR,
    3087             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    3088             :                  errmsg("unequal number of entries in row expressions"),
    3089             :                  parser_errposition(pstate, location)));
    3090             : 
    3091          16 :     forboth(l, largs, r, rargs)
    3092             :     {
    3093          12 :         Node       *larg = (Node *) lfirst(l);
    3094          12 :         Node       *rarg = (Node *) lfirst(r);
    3095             :         Node       *cmp;
    3096             : 
    3097          12 :         cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
    3098          12 :         if (result == NULL)
    3099           4 :             result = cmp;
    3100             :         else
    3101           8 :             result = (Node *) makeBoolExpr(OR_EXPR,
    3102           8 :                                            list_make2(result, cmp),
    3103             :                                            location);
    3104             :     }
    3105             : 
    3106           4 :     if (result == NULL)
    3107             :     {
    3108             :         /* zero-length rows?  Generate constant FALSE */
    3109           0 :         result = makeBoolConst(false, false);
    3110             :     }
    3111             : 
    3112           4 :     return result;
    3113             : }
    3114             : 
    3115             : /*
    3116             :  * make the node for an IS DISTINCT FROM operator
    3117             :  */
    3118             : static Expr *
    3119         494 : make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
    3120             :                  int location)
    3121             : {
    3122             :     Expr       *result;
    3123             : 
    3124         494 :     result = make_op(pstate, opname, ltree, rtree,
    3125             :                      pstate->p_last_srf, location);
    3126         494 :     if (((OpExpr *) result)->opresulttype != BOOLOID)
    3127           0 :         ereport(ERROR,
    3128             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3129             :                  errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
    3130             :                  parser_errposition(pstate, location)));
    3131         494 :     if (((OpExpr *) result)->opretset)
    3132           0 :         ereport(ERROR,
    3133             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3134             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    3135             :                  errmsg("%s must not return a set", "IS DISTINCT FROM"),
    3136             :                  parser_errposition(pstate, location)));
    3137             : 
    3138             :     /*
    3139             :      * We rely on DistinctExpr and OpExpr being same struct
    3140             :      */
    3141         494 :     NodeSetTag(result, T_DistinctExpr);
    3142             : 
    3143         494 :     return result;
    3144             : }
    3145             : 
    3146             : /*
    3147             :  * Produce a NullTest node from an IS [NOT] DISTINCT FROM NULL construct
    3148             :  *
    3149             :  * "arg" is the untransformed other argument
    3150             :  */
    3151             : static Node *
    3152          20 : make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
    3153             : {
    3154          20 :     NullTest   *nt = makeNode(NullTest);
    3155             : 
    3156          20 :     nt->arg = (Expr *) transformExprRecurse(pstate, arg);
    3157             :     /* the argument can be any type, so don't coerce it */
    3158          20 :     if (distincta->kind == AEXPR_NOT_DISTINCT)
    3159           8 :         nt->nulltesttype = IS_NULL;
    3160             :     else
    3161          12 :         nt->nulltesttype = IS_NOT_NULL;
    3162             :     /* argisrow = false is correct whether or not arg is composite */
    3163          20 :     nt->argisrow = false;
    3164          20 :     nt->location = distincta->location;
    3165          20 :     return (Node *) nt;
    3166             : }
    3167             : 
    3168             : /*
    3169             :  * Identify node's group for operator precedence warnings
    3170             :  *
    3171             :  * For items in nonzero groups, also return a suitable node name into *nodename
    3172             :  *
    3173             :  * Note: group zero is used for nodes that are higher or lower precedence
    3174             :  * than everything that changed precedence; we need never issue warnings
    3175             :  * related to such nodes.
    3176             :  */
    3177             : static int
    3178           0 : operator_precedence_group(Node *node, const char **nodename)
    3179             : {
    3180           0 :     int         group = 0;
    3181             : 
    3182           0 :     *nodename = NULL;
    3183           0 :     if (node == NULL)
    3184           0 :         return 0;
    3185             : 
    3186           0 :     if (IsA(node, A_Expr))
    3187             :     {
    3188           0 :         A_Expr     *aexpr = (A_Expr *) node;
    3189             : 
    3190           0 :         if (aexpr->kind == AEXPR_OP &&
    3191           0 :             aexpr->lexpr != NULL &&
    3192           0 :             aexpr->rexpr != NULL)
    3193             :         {
    3194             :             /* binary operator */
    3195           0 :             if (list_length(aexpr->name) == 1)
    3196             :             {
    3197           0 :                 *nodename = strVal(linitial(aexpr->name));
    3198             :                 /* Ignore if op was always higher priority than IS-tests */
    3199           0 :                 if (strcmp(*nodename, "+") == 0 ||
    3200           0 :                     strcmp(*nodename, "-") == 0 ||
    3201           0 :                     strcmp(*nodename, "*") == 0 ||
    3202           0 :                     strcmp(*nodename, "/") == 0 ||
    3203           0 :                     strcmp(*nodename, "%") == 0 ||
    3204           0 :                     strcmp(*nodename, "^") == 0)
    3205           0 :                     group = 0;
    3206           0 :                 else if (strcmp(*nodename, "<") == 0 ||
    3207           0 :                          strcmp(*nodename, ">") == 0)
    3208           0 :                     group = PREC_GROUP_LESS;
    3209           0 :                 else if (strcmp(*nodename, "=") == 0)
    3210           0 :                     group = PREC_GROUP_EQUAL;
    3211           0 :                 else if (strcmp(*nodename, "<=") == 0 ||
    3212           0 :                          strcmp(*nodename, ">=") == 0 ||
    3213           0 :                          strcmp(*nodename, "<>") == 0)
    3214           0 :                     group = PREC_GROUP_LESS_EQUAL;
    3215             :                 else
    3216           0 :                     group = PREC_GROUP_INFIX_OP;
    3217             :             }
    3218             :             else
    3219             :             {
    3220             :                 /* schema-qualified operator syntax */
    3221           0 :                 *nodename = "OPERATOR()";
    3222           0 :                 group = PREC_GROUP_INFIX_OP;
    3223             :             }
    3224             :         }
    3225           0 :         else if (aexpr->kind == AEXPR_OP &&
    3226           0 :                  aexpr->lexpr == NULL &&
    3227           0 :                  aexpr->rexpr != NULL)
    3228             :         {
    3229             :             /* prefix operator */
    3230           0 :             if (list_length(aexpr->name) == 1)
    3231             :             {
    3232           0 :                 *nodename = strVal(linitial(aexpr->name));
    3233             :                 /* Ignore if op was always higher priority than IS-tests */
    3234           0 :                 if (strcmp(*nodename, "+") == 0 ||
    3235           0 :                     strcmp(*nodename, "-") == 0)
    3236           0 :                     group = 0;
    3237             :                 else
    3238           0 :                     group = PREC_GROUP_PREFIX_OP;
    3239             :             }
    3240             :             else
    3241             :             {
    3242             :                 /* schema-qualified operator syntax */
    3243           0 :                 *nodename = "OPERATOR()";
    3244           0 :                 group = PREC_GROUP_PREFIX_OP;
    3245             :             }
    3246             :         }
    3247           0 :         else if (aexpr->kind == AEXPR_OP &&
    3248           0 :                  aexpr->lexpr != NULL &&
    3249           0 :                  aexpr->rexpr == NULL)
    3250             :         {
    3251             :             /* postfix operator */
    3252           0 :             if (list_length(aexpr->name) == 1)
    3253             :             {
    3254           0 :                 *nodename = strVal(linitial(aexpr->name));
    3255           0 :                 group = PREC_GROUP_POSTFIX_OP;
    3256             :             }
    3257             :             else
    3258             :             {
    3259             :                 /* schema-qualified operator syntax */
    3260           0 :                 *nodename = "OPERATOR()";
    3261           0 :                 group = PREC_GROUP_POSTFIX_OP;
    3262             :             }
    3263             :         }
    3264           0 :         else if (aexpr->kind == AEXPR_OP_ANY ||
    3265           0 :                  aexpr->kind == AEXPR_OP_ALL)
    3266             :         {
    3267           0 :             *nodename = strVal(llast(aexpr->name));
    3268           0 :             group = PREC_GROUP_POSTFIX_OP;
    3269             :         }
    3270           0 :         else if (aexpr->kind == AEXPR_DISTINCT ||
    3271           0 :                  aexpr->kind == AEXPR_NOT_DISTINCT)
    3272             :         {
    3273           0 :             *nodename = "IS";
    3274           0 :             group = PREC_GROUP_INFIX_IS;
    3275             :         }
    3276           0 :         else if (aexpr->kind == AEXPR_OF)
    3277             :         {
    3278           0 :             *nodename = "IS";
    3279           0 :             group = PREC_GROUP_POSTFIX_IS;
    3280             :         }
    3281           0 :         else if (aexpr->kind == AEXPR_IN)
    3282             :         {
    3283           0 :             *nodename = "IN";
    3284           0 :             if (strcmp(strVal(linitial(aexpr->name)), "=") == 0)
    3285           0 :                 group = PREC_GROUP_IN;
    3286             :             else
    3287           0 :                 group = PREC_GROUP_NOT_IN;
    3288             :         }
    3289           0 :         else if (aexpr->kind == AEXPR_LIKE)
    3290             :         {
    3291           0 :             *nodename = "LIKE";
    3292           0 :             if (strcmp(strVal(linitial(aexpr->name)), "~~") == 0)
    3293           0 :                 group = PREC_GROUP_LIKE;
    3294             :             else
    3295           0 :                 group = PREC_GROUP_NOT_LIKE;
    3296             :         }
    3297           0 :         else if (aexpr->kind == AEXPR_ILIKE)
    3298             :         {
    3299           0 :             *nodename = "ILIKE";
    3300           0 :             if (strcmp(strVal(linitial(aexpr->name)), "~~*") == 0)
    3301           0 :                 group = PREC_GROUP_LIKE;
    3302             :             else
    3303           0 :                 group = PREC_GROUP_NOT_LIKE;
    3304             :         }
    3305           0 :         else if (aexpr->kind == AEXPR_SIMILAR)
    3306             :         {
    3307           0 :             *nodename = "SIMILAR";
    3308           0 :             if (strcmp(strVal(linitial(aexpr->name)), "~") == 0)
    3309           0 :                 group = PREC_GROUP_LIKE;
    3310             :             else
    3311           0 :                 group = PREC_GROUP_NOT_LIKE;
    3312             :         }
    3313           0 :         else if (aexpr->kind == AEXPR_BETWEEN ||
    3314           0 :                  aexpr->kind == AEXPR_BETWEEN_SYM)
    3315             :         {
    3316             :             Assert(list_length(aexpr->name) == 1);
    3317           0 :             *nodename = strVal(linitial(aexpr->name));
    3318           0 :             group = PREC_GROUP_BETWEEN;
    3319             :         }
    3320           0 :         else if (aexpr->kind == AEXPR_NOT_BETWEEN ||
    3321           0 :                  aexpr->kind == AEXPR_NOT_BETWEEN_SYM)
    3322             :         {
    3323             :             Assert(list_length(aexpr->name) == 1);
    3324           0 :             *nodename = strVal(linitial(aexpr->name));
    3325           0 :             group = PREC_GROUP_NOT_BETWEEN;
    3326             :         }
    3327             :     }
    3328           0 :     else if (IsA(node, NullTest) ||
    3329           0 :              IsA(node, BooleanTest))
    3330             :     {
    3331           0 :         *nodename = "IS";
    3332           0 :         group = PREC_GROUP_POSTFIX_IS;
    3333             :     }
    3334           0 :     else if (IsA(node, XmlExpr))
    3335             :     {
    3336           0 :         XmlExpr    *x = (XmlExpr *) node;
    3337             : 
    3338           0 :         if (x->op == IS_DOCUMENT)
    3339             :         {
    3340           0 :             *nodename = "IS";
    3341           0 :             group = PREC_GROUP_POSTFIX_IS;
    3342             :         }
    3343             :     }
    3344           0 :     else if (IsA(node, SubLink))
    3345             :     {
    3346           0 :         SubLink    *s = (SubLink *) node;
    3347             : 
    3348           0 :         if (s->subLinkType == ANY_SUBLINK ||
    3349           0 :             s->subLinkType == ALL_SUBLINK)
    3350             :         {
    3351           0 :             if (s->operName == NIL)
    3352             :             {
    3353           0 :                 *nodename = "IN";
    3354           0 :                 group = PREC_GROUP_IN;
    3355             :             }
    3356             :             else
    3357             :             {
    3358           0 :                 *nodename = strVal(llast(s->operName));
    3359           0 :                 group = PREC_GROUP_POSTFIX_OP;
    3360             :             }
    3361             :         }
    3362             :     }
    3363           0 :     else if (IsA(node, BoolExpr))
    3364             :     {
    3365             :         /*
    3366             :          * Must dig into NOTs to see if it's IS NOT DOCUMENT or NOT IN.  This
    3367             :          * opens us to possibly misrecognizing, eg, NOT (x IS DOCUMENT) as a
    3368             :          * problematic construct.  We can tell the difference by checking
    3369             :          * whether the parse locations of the two nodes are identical.
    3370             :          *
    3371             :          * Note that when we are comparing the child node to its own children,
    3372             :          * we will not know that it was a NOT.  Fortunately, that doesn't
    3373             :          * matter for these cases.
    3374             :          */
    3375           0 :         BoolExpr   *b = (BoolExpr *) node;
    3376             : 
    3377           0 :         if (b->boolop == NOT_EXPR)
    3378             :         {
    3379           0 :             Node       *child = (Node *) linitial(b->args);
    3380             : 
    3381           0 :             if (IsA(child, XmlExpr))
    3382             :             {
    3383           0 :                 XmlExpr    *x = (XmlExpr *) child;
    3384             : 
    3385           0 :                 if (x->op == IS_DOCUMENT &&
    3386           0 :                     x->location == b->location)
    3387             :                 {
    3388           0 :                     *nodename = "IS";
    3389           0 :                     group = PREC_GROUP_POSTFIX_IS;
    3390             :                 }
    3391             :             }
    3392           0 :             else if (IsA(child, SubLink))
    3393             :             {
    3394           0 :                 SubLink    *s = (SubLink *) child;
    3395             : 
    3396           0 :                 if (s->subLinkType == ANY_SUBLINK && s->operName == NIL &&
    3397           0 :                     s->location == b->location)
    3398             :                 {
    3399           0 :                     *nodename = "IN";
    3400           0 :                     group = PREC_GROUP_NOT_IN;
    3401             :                 }
    3402             :             }
    3403             :         }
    3404             :     }
    3405           0 :     return group;
    3406             : }
    3407             : 
    3408             : /*
    3409             :  * helper routine for delivering 9.4-to-9.5 operator precedence warnings
    3410             :  *
    3411             :  * opgroup/opname/location represent some parent node
    3412             :  * lchild, rchild are its left and right children (either could be NULL)
    3413             :  *
    3414             :  * This should be called before transforming the child nodes, since if a
    3415             :  * precedence-driven parsing change has occurred in a query that used to work,
    3416             :  * it's quite possible that we'll get a semantic failure while analyzing the
    3417             :  * child expression.  We want to produce the warning before that happens.
    3418             :  * In any case, operator_precedence_group() expects untransformed input.
    3419             :  */
    3420             : static void
    3421           0 : emit_precedence_warnings(ParseState *pstate,
    3422             :                          int opgroup, const char *opname,
    3423             :                          Node *lchild, Node *rchild,
    3424             :                          int location)
    3425             : {
    3426             :     int         cgroup;
    3427             :     const char *copname;
    3428             : 
    3429             :     Assert(opgroup > 0);
    3430             : 
    3431             :     /*
    3432             :      * Complain if left child, which should be same or higher precedence
    3433             :      * according to current rules, used to be lower precedence.
    3434             :      *
    3435             :      * Exception to precedence rules: if left child is IN or NOT IN or a
    3436             :      * postfix operator, the grouping is syntactically forced regardless of
    3437             :      * precedence.
    3438             :      */
    3439           0 :     cgroup = operator_precedence_group(lchild, &copname);
    3440           0 :     if (cgroup > 0)
    3441             :     {
    3442           0 :         if (oldprecedence_l[cgroup] < oldprecedence_r[opgroup] &&
    3443           0 :             cgroup != PREC_GROUP_IN &&
    3444           0 :             cgroup != PREC_GROUP_NOT_IN &&
    3445           0 :             cgroup != PREC_GROUP_POSTFIX_OP &&
    3446             :             cgroup != PREC_GROUP_POSTFIX_IS)
    3447           0 :             ereport(WARNING,
    3448             :                     (errmsg("operator precedence change: %s is now lower precedence than %s",
    3449             :                             opname, copname),
    3450             :                      parser_errposition(pstate, location)));
    3451             :     }
    3452             : 
    3453             :     /*
    3454             :      * Complain if right child, which should be higher precedence according to
    3455             :      * current rules, used to be same or lower precedence.
    3456             :      *
    3457             :      * Exception to precedence rules: if right child is a prefix operator, the
    3458             :      * grouping is syntactically forced regardless of precedence.
    3459             :      */
    3460           0 :     cgroup = operator_precedence_group(rchild, &copname);
    3461           0 :     if (cgroup > 0)
    3462             :     {
    3463           0 :         if (oldprecedence_r[cgroup] <= oldprecedence_l[opgroup] &&
    3464             :             cgroup != PREC_GROUP_PREFIX_OP)
    3465           0 :             ereport(WARNING,
    3466             :                     (errmsg("operator precedence change: %s is now lower precedence than %s",
    3467             :                             opname, copname),
    3468             :                      parser_errposition(pstate, location)));
    3469             :     }
    3470           0 : }
    3471             : 
    3472             : /*
    3473             :  * Produce a string identifying an expression by kind.
    3474             :  *
    3475             :  * Note: when practical, use a simple SQL keyword for the result.  If that
    3476             :  * doesn't work well, check call sites to see whether custom error message
    3477             :  * strings are required.
    3478             :  */
    3479             : const char *
    3480          40 : ParseExprKindName(ParseExprKind exprKind)
    3481             : {
    3482          40 :     switch (exprKind)
    3483             :     {
    3484           0 :         case EXPR_KIND_NONE:
    3485           0 :             return "invalid expression context";
    3486           0 :         case EXPR_KIND_OTHER:
    3487           0 :             return "extension expression";
    3488           0 :         case EXPR_KIND_JOIN_ON:
    3489           0 :             return "JOIN/ON";
    3490           0 :         case EXPR_KIND_JOIN_USING:
    3491           0 :             return "JOIN/USING";
    3492           0 :         case EXPR_KIND_FROM_SUBSELECT:
    3493           0 :             return "sub-SELECT in FROM";
    3494           0 :         case EXPR_KIND_FROM_FUNCTION:
    3495           0 :             return "function in FROM";
    3496          12 :         case EXPR_KIND_WHERE:
    3497          12 :             return "WHERE";
    3498           0 :         case EXPR_KIND_POLICY:
    3499           0 :             return "POLICY";
    3500           0 :         case EXPR_KIND_HAVING:
    3501           0 :             return "HAVING";
    3502           0 :         case EXPR_KIND_FILTER:
    3503           0 :             return "FILTER";
    3504           0 :         case EXPR_KIND_WINDOW_PARTITION:
    3505           0 :             return "window PARTITION BY";
    3506           0 :         case EXPR_KIND_WINDOW_ORDER:
    3507           0 :             return "window ORDER BY";
    3508           0 :         case EXPR_KIND_WINDOW_FRAME_RANGE:
    3509           0 :             return "window RANGE";
    3510           0 :         case EXPR_KIND_WINDOW_FRAME_ROWS:
    3511           0 :             return "window ROWS";
    3512           0 :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
    3513           0 :             return "window GROUPS";
    3514           0 :         case EXPR_KIND_SELECT_TARGET:
    3515           0 :             return "SELECT";
    3516           0 :         case EXPR_KIND_INSERT_TARGET:
    3517           0 :             return "INSERT";
    3518           4 :         case EXPR_KIND_UPDATE_SOURCE:
    3519             :         case EXPR_KIND_UPDATE_TARGET:
    3520           4 :             return "UPDATE";
    3521           8 :         case EXPR_KIND_GROUP_BY:
    3522           8 :             return "GROUP BY";
    3523           0 :         case EXPR_KIND_ORDER_BY:
    3524           0 :             return "ORDER BY";
    3525           0 :         case EXPR_KIND_DISTINCT_ON:
    3526           0 :             return "DISTINCT ON";
    3527           4 :         case EXPR_KIND_LIMIT:
    3528           4 :             return "LIMIT";
    3529           0 :         case EXPR_KIND_OFFSET:
    3530           0 :             return "OFFSET";
    3531           8 :         case EXPR_KIND_RETURNING:
    3532           8 :             return "RETURNING";
    3533           4 :         case EXPR_KIND_VALUES:
    3534             :         case EXPR_KIND_VALUES_SINGLE:
    3535           4 :             return "VALUES";
    3536           0 :         case EXPR_KIND_CHECK_CONSTRAINT:
    3537             :         case EXPR_KIND_DOMAIN_CHECK:
    3538           0 :             return "CHECK";
    3539           0 :         case EXPR_KIND_COLUMN_DEFAULT:
    3540             :         case EXPR_KIND_FUNCTION_DEFAULT:
    3541           0 :             return "DEFAULT";
    3542           0 :         case EXPR_KIND_INDEX_EXPRESSION:
    3543           0 :             return "index expression";
    3544           0 :         case EXPR_KIND_INDEX_PREDICATE:
    3545           0 :             return "index predicate";
    3546           0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
    3547           0 :             return "USING";
    3548           0 :         case EXPR_KIND_EXECUTE_PARAMETER:
    3549           0 :             return "EXECUTE";
    3550           0 :         case EXPR_KIND_TRIGGER_WHEN:
    3551           0 :             return "WHEN";
    3552           0 :         case EXPR_KIND_PARTITION_BOUND:
    3553           0 :             return "partition bound";
    3554           0 :         case EXPR_KIND_PARTITION_EXPRESSION:
    3555           0 :             return "PARTITION BY";
    3556           0 :         case EXPR_KIND_CALL_ARGUMENT:
    3557           0 :             return "CALL";
    3558           0 :         case EXPR_KIND_COPY_WHERE:
    3559           0 :             return "WHERE";
    3560           0 :         case EXPR_KIND_GENERATED_COLUMN:
    3561           0 :             return "GENERATED AS";
    3562             : 
    3563             :             /*
    3564             :              * There is intentionally no default: case here, so that the
    3565             :              * compiler will warn if we add a new ParseExprKind without
    3566             :              * extending this switch.  If we do see an unrecognized value at
    3567             :              * runtime, we'll fall through to the "unrecognized" return.
    3568             :              */
    3569             :     }
    3570           0 :     return "unrecognized expression kind";
    3571             : }

Generated by: LCOV version 1.13