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

Generated by: LCOV version 1.11