LCOV - code coverage report
Current view: top level - src/backend/parser - parse_expr.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 87.5 % 1843 1612
Test Date: 2026-07-03 19:57:34 Functions: 100.0 % 62 62
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 72.7 % 1237 899

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * parse_expr.c
       4                 :             :  *    handle expressions in parser
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, 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 "access/htup_details.h"
      19                 :             : #include "catalog/pg_aggregate.h"
      20                 :             : #include "catalog/pg_type.h"
      21                 :             : #include "miscadmin.h"
      22                 :             : #include "nodes/makefuncs.h"
      23                 :             : #include "nodes/nodeFuncs.h"
      24                 :             : #include "optimizer/optimizer.h"
      25                 :             : #include "parser/analyze.h"
      26                 :             : #include "parser/parse_agg.h"
      27                 :             : #include "parser/parse_clause.h"
      28                 :             : #include "parser/parse_coerce.h"
      29                 :             : #include "parser/parse_collate.h"
      30                 :             : #include "parser/parse_expr.h"
      31                 :             : #include "parser/parse_func.h"
      32                 :             : #include "parser/parse_graphtable.h"
      33                 :             : #include "parser/parse_oper.h"
      34                 :             : #include "parser/parse_relation.h"
      35                 :             : #include "parser/parse_target.h"
      36                 :             : #include "parser/parse_type.h"
      37                 :             : #include "utils/builtins.h"
      38                 :             : #include "utils/date.h"
      39                 :             : #include "utils/fmgroids.h"
      40                 :             : #include "utils/lsyscache.h"
      41                 :             : #include "utils/timestamp.h"
      42                 :             : #include "utils/typcache.h"
      43                 :             : #include "utils/xml.h"
      44                 :             : 
      45                 :             : /* GUC parameters */
      46                 :             : bool        Transform_null_equals = false;
      47                 :             : 
      48                 :             : 
      49                 :             : static Node *transformExprRecurse(ParseState *pstate, Node *expr);
      50                 :             : static Node *transformParamRef(ParseState *pstate, ParamRef *pref);
      51                 :             : static Node *transformAExprOp(ParseState *pstate, A_Expr *a);
      52                 :             : static Node *transformAExprOpAny(ParseState *pstate, A_Expr *a);
      53                 :             : static Node *transformAExprOpAll(ParseState *pstate, A_Expr *a);
      54                 :             : static Node *transformAExprDistinct(ParseState *pstate, A_Expr *a);
      55                 :             : static Node *transformAExprNullIf(ParseState *pstate, A_Expr *a);
      56                 :             : static Node *transformAExprIn(ParseState *pstate, A_Expr *a);
      57                 :             : static Node *transformAExprBetween(ParseState *pstate, A_Expr *a);
      58                 :             : static Node *transformMergeSupportFunc(ParseState *pstate, MergeSupportFunc *f);
      59                 :             : static Node *transformBoolExpr(ParseState *pstate, BoolExpr *a);
      60                 :             : static Node *transformFuncCall(ParseState *pstate, FuncCall *fn);
      61                 :             : static Node *transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref);
      62                 :             : static Node *transformCaseExpr(ParseState *pstate, CaseExpr *c);
      63                 :             : static Node *transformSubLink(ParseState *pstate, SubLink *sublink);
      64                 :             : static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
      65                 :             :                                 Oid array_type, Oid element_type, int32 typmod);
      66                 :             : static Node *transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault);
      67                 :             : static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
      68                 :             : static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
      69                 :             : static Node *transformSQLValueFunction(ParseState *pstate,
      70                 :             :                                        SQLValueFunction *svf);
      71                 :             : static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
      72                 :             : static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs);
      73                 :             : static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
      74                 :             : static Node *transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr);
      75                 :             : static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
      76                 :             : static Node *transformWholeRowRef(ParseState *pstate,
      77                 :             :                                   ParseNamespaceItem *nsitem,
      78                 :             :                                   int sublevels_up, int location);
      79                 :             : static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
      80                 :             : static Node *transformTypeCast(ParseState *pstate, TypeCast *tc);
      81                 :             : static Node *transformCollateClause(ParseState *pstate, CollateClause *c);
      82                 :             : static Node *transformJsonObjectConstructor(ParseState *pstate,
      83                 :             :                                             JsonObjectConstructor *ctor);
      84                 :             : static Node *transformJsonArrayConstructor(ParseState *pstate,
      85                 :             :                                            JsonArrayConstructor *ctor);
      86                 :             : static Node *transformJsonArrayQueryConstructor(ParseState *pstate,
      87                 :             :                                                 JsonArrayQueryConstructor *ctor);
      88                 :             : static Node *transformJsonObjectAgg(ParseState *pstate, JsonObjectAgg *agg);
      89                 :             : static Node *transformJsonArrayAgg(ParseState *pstate, JsonArrayAgg *agg);
      90                 :             : static Node *transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred);
      91                 :             : static Node *transformJsonParseExpr(ParseState *pstate, JsonParseExpr *jsexpr);
      92                 :             : static Node *transformJsonScalarExpr(ParseState *pstate, JsonScalarExpr *jsexpr);
      93                 :             : static Node *transformJsonSerializeExpr(ParseState *pstate,
      94                 :             :                                         JsonSerializeExpr *expr);
      95                 :             : static Node *transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func);
      96                 :             : static void transformJsonPassingArgs(ParseState *pstate, const char *constructName,
      97                 :             :                                      JsonFormatType format, List *args,
      98                 :             :                                      List **passing_values, List **passing_names);
      99                 :             : static JsonBehavior *transformJsonBehavior(ParseState *pstate, JsonExpr *jsexpr,
     100                 :             :                                            JsonBehavior *behavior,
     101                 :             :                                            JsonBehaviorType default_behavior,
     102                 :             :                                            JsonReturning *returning);
     103                 :             : static Node *GetJsonBehaviorConst(JsonBehaviorType btype, int location);
     104                 :             : static Node *make_row_comparison_op(ParseState *pstate, List *opname,
     105                 :             :                                     List *largs, List *rargs, int location);
     106                 :             : static Node *make_row_distinct_op(ParseState *pstate, List *opname,
     107                 :             :                                   RowExpr *lrow, RowExpr *rrow, int location);
     108                 :             : static Expr *make_distinct_op(ParseState *pstate, List *opname,
     109                 :             :                               Node *ltree, Node *rtree, int location);
     110                 :             : static Node *make_nulltest_from_distinct(ParseState *pstate,
     111                 :             :                                          A_Expr *distincta, Node *arg);
     112                 :             : 
     113                 :             : 
     114                 :             : /*
     115                 :             :  * transformExpr -
     116                 :             :  *    Analyze and transform expressions. Type checking and type casting is
     117                 :             :  *    done here.  This processing converts the raw grammar output into
     118                 :             :  *    expression trees with fully determined semantics.
     119                 :             :  */
     120                 :             : Node *
     121                 :     1144024 : transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
     122                 :             : {
     123                 :             :     Node       *result;
     124                 :             :     ParseExprKind sv_expr_kind;
     125                 :             : 
     126                 :             :     /* Save and restore identity of expression type we're parsing */
     127                 :             :     Assert(exprKind != EXPR_KIND_NONE);
     128                 :     1144024 :     sv_expr_kind = pstate->p_expr_kind;
     129                 :     1144024 :     pstate->p_expr_kind = exprKind;
     130                 :             : 
     131                 :     1144024 :     result = transformExprRecurse(pstate, expr);
     132                 :             : 
     133                 :     1139647 :     pstate->p_expr_kind = sv_expr_kind;
     134                 :             : 
     135                 :     1139647 :     return result;
     136                 :             : }
     137                 :             : 
     138                 :             : static Node *
     139                 :     3101892 : transformExprRecurse(ParseState *pstate, Node *expr)
     140                 :             : {
     141                 :             :     Node       *result;
     142                 :             : 
     143         [ +  + ]:     3101892 :     if (expr == NULL)
     144                 :       23211 :         return NULL;
     145                 :             : 
     146                 :             :     /* Guard against stack overflow due to overly complex expressions */
     147                 :     3078681 :     check_stack_depth();
     148                 :             : 
     149   [ +  +  +  +  :     3078681 :     switch (nodeTag(expr))
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  +  +  +  
          +  +  +  +  +  
             +  +  +  - ]
     150                 :             :     {
     151                 :     1134507 :         case T_ColumnRef:
     152                 :     1134507 :             result = transformColumnRef(pstate, (ColumnRef *) expr);
     153                 :     1134010 :             break;
     154                 :             : 
     155                 :       25984 :         case T_ParamRef:
     156                 :       25984 :             result = transformParamRef(pstate, (ParamRef *) expr);
     157                 :       25976 :             break;
     158                 :             : 
     159                 :      793221 :         case T_A_Const:
     160                 :      793221 :             result = (Node *) make_const(pstate, (A_Const *) expr);
     161                 :      793205 :             break;
     162                 :             : 
     163                 :       16600 :         case T_A_Indirection:
     164                 :       16600 :             result = transformIndirection(pstate, (A_Indirection *) expr);
     165                 :       16537 :             break;
     166                 :             : 
     167                 :        4689 :         case T_A_ArrayExpr:
     168                 :        4689 :             result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
     169                 :             :                                         InvalidOid, InvalidOid, -1);
     170                 :        4685 :             break;
     171                 :             : 
     172                 :      197289 :         case T_TypeCast:
     173                 :      197289 :             result = transformTypeCast(pstate, (TypeCast *) expr);
     174                 :      194683 :             break;
     175                 :             : 
     176                 :        6844 :         case T_CollateClause:
     177                 :        6844 :             result = transformCollateClause(pstate, (CollateClause *) expr);
     178                 :        6832 :             break;
     179                 :             : 
     180                 :      414239 :         case T_A_Expr:
     181                 :             :             {
     182                 :      414239 :                 A_Expr     *a = (A_Expr *) expr;
     183                 :             : 
     184   [ +  +  +  +  :      414239 :                 switch (a->kind)
             +  +  +  +  
                      - ]
     185                 :             :                 {
     186                 :      387220 :                     case AEXPR_OP:
     187                 :      387220 :                         result = transformAExprOp(pstate, a);
     188                 :      386884 :                         break;
     189                 :       10931 :                     case AEXPR_OP_ANY:
     190                 :       10931 :                         result = transformAExprOpAny(pstate, a);
     191                 :       10923 :                         break;
     192                 :         205 :                     case AEXPR_OP_ALL:
     193                 :         205 :                         result = transformAExprOpAll(pstate, a);
     194                 :         205 :                         break;
     195                 :         722 :                     case AEXPR_DISTINCT:
     196                 :             :                     case AEXPR_NOT_DISTINCT:
     197                 :         722 :                         result = transformAExprDistinct(pstate, a);
     198                 :         722 :                         break;
     199                 :         470 :                     case AEXPR_NULLIF:
     200                 :         470 :                         result = transformAExprNullIf(pstate, a);
     201                 :         470 :                         break;
     202                 :       12505 :                     case AEXPR_IN:
     203                 :       12505 :                         result = transformAExprIn(pstate, a);
     204                 :       12497 :                         break;
     205                 :        1846 :                     case AEXPR_LIKE:
     206                 :             :                     case AEXPR_ILIKE:
     207                 :             :                     case AEXPR_SIMILAR:
     208                 :             :                         /* we can transform these just like AEXPR_OP */
     209                 :        1846 :                         result = transformAExprOp(pstate, a);
     210                 :        1842 :                         break;
     211                 :         340 :                     case AEXPR_BETWEEN:
     212                 :             :                     case AEXPR_NOT_BETWEEN:
     213                 :             :                     case AEXPR_BETWEEN_SYM:
     214                 :             :                     case AEXPR_NOT_BETWEEN_SYM:
     215                 :         340 :                         result = transformAExprBetween(pstate, a);
     216                 :         340 :                         break;
     217                 :           0 :                     default:
     218         [ #  # ]:           0 :                         elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
     219                 :             :                         result = NULL;  /* keep compiler quiet */
     220                 :             :                         break;
     221                 :             :                 }
     222                 :      413883 :                 break;
     223                 :             :             }
     224                 :             : 
     225                 :      111976 :         case T_BoolExpr:
     226                 :      111976 :             result = transformBoolExpr(pstate, (BoolExpr *) expr);
     227                 :      111959 :             break;
     228                 :             : 
     229                 :      243003 :         case T_FuncCall:
     230                 :      243003 :             result = transformFuncCall(pstate, (FuncCall *) expr);
     231                 :      242220 :             break;
     232                 :             : 
     233                 :         249 :         case T_MultiAssignRef:
     234                 :         249 :             result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
     235                 :         245 :             break;
     236                 :             : 
     237                 :         252 :         case T_GroupingFunc:
     238                 :         252 :             result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
     239                 :         252 :             break;
     240                 :             : 
     241                 :         138 :         case T_MergeSupportFunc:
     242                 :         138 :             result = transformMergeSupportFunc(pstate,
     243                 :             :                                                (MergeSupportFunc *) expr);
     244                 :         130 :             break;
     245                 :             : 
     246                 :       25480 :         case T_NamedArgExpr:
     247                 :             :             {
     248                 :       25480 :                 NamedArgExpr *na = (NamedArgExpr *) expr;
     249                 :             : 
     250                 :       25480 :                 na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
     251                 :       25480 :                 result = expr;
     252                 :       25480 :                 break;
     253                 :             :             }
     254                 :             : 
     255                 :       32092 :         case T_SubLink:
     256                 :       32092 :             result = transformSubLink(pstate, (SubLink *) expr);
     257                 :       32016 :             break;
     258                 :             : 
     259                 :       25607 :         case T_CaseExpr:
     260                 :       25607 :             result = transformCaseExpr(pstate, (CaseExpr *) expr);
     261                 :       25603 :             break;
     262                 :             : 
     263                 :        3897 :         case T_RowExpr:
     264                 :        3897 :             result = transformRowExpr(pstate, (RowExpr *) expr, false);
     265                 :        3897 :             break;
     266                 :             : 
     267                 :        2163 :         case T_CoalesceExpr:
     268                 :        2163 :             result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
     269                 :        2159 :             break;
     270                 :             : 
     271                 :         189 :         case T_MinMaxExpr:
     272                 :         189 :             result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
     273                 :         189 :             break;
     274                 :             : 
     275                 :        1647 :         case T_SQLValueFunction:
     276                 :        1647 :             result = transformSQLValueFunction(pstate,
     277                 :             :                                                (SQLValueFunction *) expr);
     278                 :        1647 :             break;
     279                 :             : 
     280                 :         396 :         case T_XmlExpr:
     281                 :         396 :             result = transformXmlExpr(pstate, (XmlExpr *) expr);
     282                 :         376 :             break;
     283                 :             : 
     284                 :         144 :         case T_XmlSerialize:
     285                 :         144 :             result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
     286                 :         144 :             break;
     287                 :             : 
     288                 :       11894 :         case T_NullTest:
     289                 :             :             {
     290                 :       11894 :                 NullTest   *n = (NullTest *) expr;
     291                 :             : 
     292                 :       11894 :                 n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
     293                 :             :                 /* the argument can be any type, so don't coerce it */
     294                 :       11890 :                 n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
     295                 :       11890 :                 result = expr;
     296                 :       11890 :                 break;
     297                 :             :             }
     298                 :             : 
     299                 :         668 :         case T_BooleanTest:
     300                 :         668 :             result = transformBooleanTest(pstate, (BooleanTest *) expr);
     301                 :         668 :             break;
     302                 :             : 
     303                 :         172 :         case T_CurrentOfExpr:
     304                 :         172 :             result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
     305                 :         172 :             break;
     306                 :             : 
     307                 :             :             /*
     308                 :             :              * In all places where DEFAULT is legal, the caller should have
     309                 :             :              * processed it rather than passing it to transformExpr().
     310                 :             :              */
     311                 :           0 :         case T_SetToDefault:
     312         [ #  # ]:           0 :             ereport(ERROR,
     313                 :             :                     (errcode(ERRCODE_SYNTAX_ERROR),
     314                 :             :                      errmsg("DEFAULT is not allowed in this context"),
     315                 :             :                      parser_errposition(pstate,
     316                 :             :                                         ((SetToDefault *) expr)->location)));
     317                 :             :             break;
     318                 :             : 
     319                 :             :             /*
     320                 :             :              * CaseTestExpr doesn't require any processing; it is only
     321                 :             :              * injected into parse trees in a fully-formed state.
     322                 :             :              *
     323                 :             :              * Ordinarily we should not see a Var here, but it is convenient
     324                 :             :              * for transformJoinUsingClause() to create untransformed operator
     325                 :             :              * trees containing already-transformed Vars.  The best
     326                 :             :              * alternative would be to deconstruct and reconstruct column
     327                 :             :              * references, which seems expensively pointless.  So allow it.
     328                 :             :              */
     329                 :       21653 :         case T_CaseTestExpr:
     330                 :             :         case T_Var:
     331                 :             :             {
     332                 :       21653 :                 result = expr;
     333                 :       21653 :                 break;
     334                 :             :             }
     335                 :             : 
     336                 :         378 :         case T_JsonObjectConstructor:
     337                 :         378 :             result = transformJsonObjectConstructor(pstate, (JsonObjectConstructor *) expr);
     338                 :         350 :             break;
     339                 :             : 
     340                 :         224 :         case T_JsonArrayConstructor:
     341                 :         224 :             result = transformJsonArrayConstructor(pstate, (JsonArrayConstructor *) expr);
     342                 :         212 :             break;
     343                 :             : 
     344                 :          92 :         case T_JsonArrayQueryConstructor:
     345                 :          92 :             result = transformJsonArrayQueryConstructor(pstate, (JsonArrayQueryConstructor *) expr);
     346                 :          72 :             break;
     347                 :             : 
     348                 :         144 :         case T_JsonObjectAgg:
     349                 :         144 :             result = transformJsonObjectAgg(pstate, (JsonObjectAgg *) expr);
     350                 :         136 :             break;
     351                 :             : 
     352                 :         192 :         case T_JsonArrayAgg:
     353                 :         192 :             result = transformJsonArrayAgg(pstate, (JsonArrayAgg *) expr);
     354                 :         184 :             break;
     355                 :             : 
     356                 :         280 :         case T_JsonIsPredicate:
     357                 :         280 :             result = transformJsonIsPredicate(pstate, (JsonIsPredicate *) expr);
     358                 :         264 :             break;
     359                 :             : 
     360                 :         108 :         case T_JsonParseExpr:
     361                 :         108 :             result = transformJsonParseExpr(pstate, (JsonParseExpr *) expr);
     362                 :          88 :             break;
     363                 :             : 
     364                 :          70 :         case T_JsonScalarExpr:
     365                 :          70 :             result = transformJsonScalarExpr(pstate, (JsonScalarExpr *) expr);
     366                 :          70 :             break;
     367                 :             : 
     368                 :          68 :         case T_JsonSerializeExpr:
     369                 :          68 :             result = transformJsonSerializeExpr(pstate, (JsonSerializeExpr *) expr);
     370                 :          62 :             break;
     371                 :             : 
     372                 :        2132 :         case T_JsonFuncExpr:
     373                 :        2132 :             result = transformJsonFuncExpr(pstate, (JsonFuncExpr *) expr);
     374                 :        2016 :             break;
     375                 :             : 
     376                 :           0 :         default:
     377                 :             :             /* should not reach here */
     378         [ #  # ]:           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
     379                 :             :             result = NULL;      /* keep compiler quiet */
     380                 :             :             break;
     381                 :             :     }
     382                 :             : 
     383                 :     3073965 :     return result;
     384                 :             : }
     385                 :             : 
     386                 :             : /*
     387                 :             :  * helper routine for delivering "column does not exist" error message
     388                 :             :  *
     389                 :             :  * (Usually we don't have to work this hard, but the general case of field
     390                 :             :  * selection from an arbitrary node needs it.)
     391                 :             :  */
     392                 :             : static void
     393                 :          29 : unknown_attribute(ParseState *pstate, Node *relref, const char *attname,
     394                 :             :                   int location)
     395                 :             : {
     396                 :             :     RangeTblEntry *rte;
     397                 :             : 
     398         [ +  + ]:          29 :     if (IsA(relref, Var) &&
     399         [ -  + ]:           8 :         ((Var *) relref)->varattno == InvalidAttrNumber)
     400                 :             :     {
     401                 :             :         /* Reference the RTE by alias not by actual table name */
     402                 :           0 :         rte = GetRTEByRangeTablePosn(pstate,
     403                 :             :                                      ((Var *) relref)->varno,
     404                 :           0 :                                      ((Var *) relref)->varlevelsup);
     405         [ #  # ]:           0 :         ereport(ERROR,
     406                 :             :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
     407                 :             :                  errmsg("column %s.%s does not exist",
     408                 :             :                         rte->eref->aliasname, attname),
     409                 :             :                  parser_errposition(pstate, location)));
     410                 :             :     }
     411                 :             :     else
     412                 :             :     {
     413                 :             :         /* Have to do it by reference to the type of the expression */
     414                 :          29 :         Oid         relTypeId = exprType(relref);
     415                 :             : 
     416         [ +  + ]:          29 :         if (ISCOMPLEX(relTypeId))
     417         [ +  - ]:          12 :             ereport(ERROR,
     418                 :             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
     419                 :             :                      errmsg("column \"%s\" not found in data type %s",
     420                 :             :                             attname, format_type_be(relTypeId)),
     421                 :             :                      parser_errposition(pstate, location)));
     422         [ +  + ]:          17 :         else if (relTypeId == RECORDOID)
     423         [ +  - ]:          13 :             ereport(ERROR,
     424                 :             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
     425                 :             :                      errmsg("could not identify column \"%s\" in record data type",
     426                 :             :                             attname),
     427                 :             :                      parser_errposition(pstate, location)));
     428                 :             :         else
     429         [ +  - ]:           4 :             ereport(ERROR,
     430                 :             :                     (errcode(ERRCODE_WRONG_OBJECT_TYPE),
     431                 :             :                      errmsg("column notation .%s applied to type %s, "
     432                 :             :                             "which is not a composite type",
     433                 :             :                             attname, format_type_be(relTypeId)),
     434                 :             :                      parser_errposition(pstate, location)));
     435                 :             :     }
     436                 :             : }
     437                 :             : 
     438                 :             : static Node *
     439                 :       16600 : transformIndirection(ParseState *pstate, A_Indirection *ind)
     440                 :             : {
     441                 :       16600 :     Node       *last_srf = pstate->p_last_srf;
     442                 :       16600 :     Node       *result = transformExprRecurse(pstate, ind->arg);
     443                 :       16600 :     List       *subscripts = NIL;
     444                 :       16600 :     int         location = exprLocation(result);
     445                 :             :     ListCell   *i;
     446                 :             : 
     447                 :             :     /*
     448                 :             :      * We have to split any field-selection operations apart from
     449                 :             :      * subscripting.  Adjacent A_Indices nodes have to be treated as a single
     450                 :             :      * multidimensional subscript operation.
     451                 :             :      */
     452   [ +  +  +  +  :       33119 :     foreach(i, ind->indirection)
                   +  + ]
     453                 :             :     {
     454                 :       16548 :         Node       *n = lfirst(i);
     455                 :             : 
     456         [ +  + ]:       16548 :         if (IsA(n, A_Indices))
     457                 :        8001 :             subscripts = lappend(subscripts, n);
     458         [ -  + ]:        8547 :         else if (IsA(n, A_Star))
     459                 :             :         {
     460         [ #  # ]:           0 :             ereport(ERROR,
     461                 :             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     462                 :             :                      errmsg("row expansion via \"*\" is not supported here"),
     463                 :             :                      parser_errposition(pstate, location)));
     464                 :             :         }
     465                 :             :         else
     466                 :             :         {
     467                 :             :             Node       *newresult;
     468                 :             : 
     469                 :             :             Assert(IsA(n, String));
     470                 :             : 
     471                 :             :             /* process subscripts before this field selection */
     472         [ +  + ]:        8547 :             if (subscripts)
     473                 :         102 :                 result = (Node *) transformContainerSubscripts(pstate,
     474                 :             :                                                                result,
     475                 :             :                                                                exprType(result),
     476                 :             :                                                                exprTypmod(result),
     477                 :             :                                                                subscripts,
     478                 :             :                                                                false);
     479                 :        8547 :             subscripts = NIL;
     480                 :             : 
     481                 :        8547 :             newresult = ParseFuncOrColumn(pstate,
     482                 :             :                                           list_make1(n),
     483                 :             :                                           list_make1(result),
     484                 :             :                                           last_srf,
     485                 :             :                                           NULL,
     486                 :             :                                           false,
     487                 :             :                                           location);
     488         [ +  + ]:        8547 :             if (newresult == NULL)
     489                 :          29 :                 unknown_attribute(pstate, result, strVal(n), location);
     490                 :        8518 :             result = newresult;
     491                 :             :         }
     492                 :             :     }
     493                 :             :     /* process trailing subscripts, if any */
     494         [ +  + ]:       16571 :     if (subscripts)
     495                 :        7685 :         result = (Node *) transformContainerSubscripts(pstate,
     496                 :             :                                                        result,
     497                 :             :                                                        exprType(result),
     498                 :             :                                                        exprTypmod(result),
     499                 :             :                                                        subscripts,
     500                 :             :                                                        false);
     501                 :             : 
     502                 :       16537 :     return result;
     503                 :             : }
     504                 :             : 
     505                 :             : /*
     506                 :             :  * Transform a ColumnRef.
     507                 :             :  *
     508                 :             :  * If you find yourself changing this code, see also ExpandColumnRefStar.
     509                 :             :  */
     510                 :             : static Node *
     511                 :     1134507 : transformColumnRef(ParseState *pstate, ColumnRef *cref)
     512                 :             : {
     513                 :     1134507 :     Node       *node = NULL;
     514                 :     1134507 :     char       *nspname = NULL;
     515                 :     1134507 :     char       *relname = NULL;
     516                 :     1134507 :     char       *colname = NULL;
     517                 :             :     ParseNamespaceItem *nsitem;
     518                 :             :     int         levels_up;
     519                 :             :     enum
     520                 :             :     {
     521                 :             :         CRERR_NO_COLUMN,
     522                 :             :         CRERR_NO_RTE,
     523                 :             :         CRERR_WRONG_DB,
     524                 :             :         CRERR_TOO_MANY
     525                 :     1134507 :     }           crerr = CRERR_NO_COLUMN;
     526                 :             :     const char *err;
     527                 :             : 
     528                 :             :     /*
     529                 :             :      * Check to see if the column reference is in an invalid place within the
     530                 :             :      * query.  We allow column references in most places, except in default
     531                 :             :      * expressions and partition bound expressions.
     532                 :             :      */
     533                 :     1134507 :     err = NULL;
     534   [ -  +  +  +  :     1134507 :     switch (pstate->p_expr_kind)
                   +  - ]
     535                 :             :     {
     536                 :           0 :         case EXPR_KIND_NONE:
     537                 :             :             Assert(false);      /* can't happen */
     538                 :           0 :             break;
     539                 :     1134443 :         case EXPR_KIND_OTHER:
     540                 :             :         case EXPR_KIND_JOIN_ON:
     541                 :             :         case EXPR_KIND_JOIN_USING:
     542                 :             :         case EXPR_KIND_FROM_SUBSELECT:
     543                 :             :         case EXPR_KIND_FROM_FUNCTION:
     544                 :             :         case EXPR_KIND_WHERE:
     545                 :             :         case EXPR_KIND_POLICY:
     546                 :             :         case EXPR_KIND_HAVING:
     547                 :             :         case EXPR_KIND_FILTER:
     548                 :             :         case EXPR_KIND_WINDOW_PARTITION:
     549                 :             :         case EXPR_KIND_WINDOW_ORDER:
     550                 :             :         case EXPR_KIND_WINDOW_FRAME_RANGE:
     551                 :             :         case EXPR_KIND_WINDOW_FRAME_ROWS:
     552                 :             :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
     553                 :             :         case EXPR_KIND_SELECT_TARGET:
     554                 :             :         case EXPR_KIND_INSERT_TARGET:
     555                 :             :         case EXPR_KIND_UPDATE_SOURCE:
     556                 :             :         case EXPR_KIND_UPDATE_TARGET:
     557                 :             :         case EXPR_KIND_MERGE_WHEN:
     558                 :             :         case EXPR_KIND_GROUP_BY:
     559                 :             :         case EXPR_KIND_ORDER_BY:
     560                 :             :         case EXPR_KIND_DISTINCT_ON:
     561                 :             :         case EXPR_KIND_LIMIT:
     562                 :             :         case EXPR_KIND_OFFSET:
     563                 :             :         case EXPR_KIND_RETURNING:
     564                 :             :         case EXPR_KIND_MERGE_RETURNING:
     565                 :             :         case EXPR_KIND_VALUES:
     566                 :             :         case EXPR_KIND_VALUES_SINGLE:
     567                 :             :         case EXPR_KIND_CHECK_CONSTRAINT:
     568                 :             :         case EXPR_KIND_DOMAIN_CHECK:
     569                 :             :         case EXPR_KIND_FUNCTION_DEFAULT:
     570                 :             :         case EXPR_KIND_INDEX_EXPRESSION:
     571                 :             :         case EXPR_KIND_INDEX_PREDICATE:
     572                 :             :         case EXPR_KIND_STATS_EXPRESSION:
     573                 :             :         case EXPR_KIND_ALTER_COL_TRANSFORM:
     574                 :             :         case EXPR_KIND_EXECUTE_PARAMETER:
     575                 :             :         case EXPR_KIND_TRIGGER_WHEN:
     576                 :             :         case EXPR_KIND_PARTITION_EXPRESSION:
     577                 :             :         case EXPR_KIND_CALL_ARGUMENT:
     578                 :             :         case EXPR_KIND_COPY_WHERE:
     579                 :             :         case EXPR_KIND_GENERATED_COLUMN:
     580                 :             :         case EXPR_KIND_CYCLE_MARK:
     581                 :             :         case EXPR_KIND_PROPGRAPH_PROPERTY:
     582                 :             :             /* okay */
     583                 :     1134443 :             break;
     584                 :             : 
     585                 :          16 :         case EXPR_KIND_COLUMN_DEFAULT:
     586                 :          16 :             err = _("cannot use column reference in DEFAULT expression");
     587                 :          16 :             break;
     588                 :          40 :         case EXPR_KIND_PARTITION_BOUND:
     589                 :          40 :             err = _("cannot use column reference in partition bound expression");
     590                 :          40 :             break;
     591                 :           8 :         case EXPR_KIND_FOR_PORTION:
     592                 :           8 :             err = _("cannot use column reference in FOR PORTION OF expression");
     593                 :           8 :             break;
     594                 :             : 
     595                 :             :             /*
     596                 :             :              * There is intentionally no default: case here, so that the
     597                 :             :              * compiler will warn if we add a new ParseExprKind without
     598                 :             :              * extending this switch.  If we do see an unrecognized value at
     599                 :             :              * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
     600                 :             :              * which is sane anyway.
     601                 :             :              */
     602                 :             :     }
     603         [ +  + ]:     1134507 :     if (err)
     604         [ +  - ]:          64 :         ereport(ERROR,
     605                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     606                 :             :                  errmsg_internal("%s", err),
     607                 :             :                  parser_errposition(pstate, cref->location)));
     608                 :             : 
     609                 :             :     /*
     610                 :             :      * Give the PreParseColumnRefHook, if any, first shot.  If it returns
     611                 :             :      * non-null then that's all, folks.
     612                 :             :      */
     613         [ +  + ]:     1134443 :     if (pstate->p_pre_columnref_hook != NULL)
     614                 :             :     {
     615                 :       25769 :         node = pstate->p_pre_columnref_hook(pstate, cref);
     616         [ +  + ]:       25769 :         if (node != NULL)
     617                 :         556 :             return node;
     618                 :             :     }
     619                 :             : 
     620                 :             :     /*
     621                 :             :      * Element pattern variables in a GRAPH_TABLE clause form the innermost
     622                 :             :      * namespace since we do not allow subqueries in GRAPH_TABLE patterns. Try
     623                 :             :      * to resolve the column reference as a graph table property reference
     624                 :             :      * before trying to resolve it as a regular column reference.
     625                 :             :      */
     626                 :     1133887 :     node = transformGraphTablePropertyRef(pstate, cref);
     627         [ +  + ]:     1133859 :     if (node != NULL)
     628                 :        1667 :         return node;
     629                 :             : 
     630                 :             :     /*----------
     631                 :             :      * The allowed syntaxes are:
     632                 :             :      *
     633                 :             :      * A        First try to resolve as unqualified column name;
     634                 :             :      *          if no luck, try to resolve as unqualified table name (A.*).
     635                 :             :      * A.B      A is an unqualified table name; B is either a
     636                 :             :      *          column or function name (trying column name first).
     637                 :             :      * A.B.C    schema A, table B, col or func name C.
     638                 :             :      * A.B.C.D  catalog A, schema B, table C, col or func D.
     639                 :             :      * A.*      A is an unqualified table name; means whole-row value.
     640                 :             :      * A.B.*    whole-row value of table B in schema A.
     641                 :             :      * A.B.C.*  whole-row value of table C in schema B in catalog A.
     642                 :             :      *
     643                 :             :      * We do not need to cope with bare "*"; that will only be accepted by
     644                 :             :      * the grammar at the top level of a SELECT list, and transformTargetList
     645                 :             :      * will take care of it before it ever gets here.  Also, "A.*" etc will
     646                 :             :      * be expanded by transformTargetList if they appear at SELECT top level,
     647                 :             :      * so here we are only going to see them as function or operator inputs.
     648                 :             :      *
     649                 :             :      * Currently, if a catalog name is given then it must equal the current
     650                 :             :      * database name; we check it here and then discard it.
     651                 :             :      *----------
     652                 :             :      */
     653   [ +  +  +  -  :     1132192 :     switch (list_length(cref->fields))
                      - ]
     654                 :             :     {
     655                 :      448419 :         case 1:
     656                 :             :             {
     657                 :      448419 :                 Node       *field1 = (Node *) linitial(cref->fields);
     658                 :             : 
     659                 :      448419 :                 colname = strVal(field1);
     660                 :             : 
     661                 :             :                 /* Try to identify as an unqualified column */
     662                 :      448419 :                 node = colNameToVar(pstate, colname, false, cref->location);
     663                 :             : 
     664         [ +  + ]:      448375 :                 if (node == NULL)
     665                 :             :                 {
     666                 :             :                     /*
     667                 :             :                      * Not known as a column of any range-table entry.
     668                 :             :                      *
     669                 :             :                      * Try to find the name as a relation.  Note that only
     670                 :             :                      * relations already entered into the rangetable will be
     671                 :             :                      * recognized.
     672                 :             :                      *
     673                 :             :                      * This is a hack for backwards compatibility with
     674                 :             :                      * PostQUEL-inspired syntax.  The preferred form now is
     675                 :             :                      * "rel.*".
     676                 :             :                      */
     677                 :       24734 :                     nsitem = refnameNamespaceItem(pstate, NULL, colname,
     678                 :             :                                                   cref->location,
     679                 :             :                                                   &levels_up);
     680         [ +  + ]:       24734 :                     if (nsitem)
     681                 :        4593 :                         node = transformWholeRowRef(pstate, nsitem, levels_up,
     682                 :             :                                                     cref->location);
     683                 :             :                 }
     684                 :      448375 :                 break;
     685                 :             :             }
     686                 :      683720 :         case 2:
     687                 :             :             {
     688                 :      683720 :                 Node       *field1 = (Node *) linitial(cref->fields);
     689                 :      683720 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     690                 :             : 
     691                 :      683720 :                 relname = strVal(field1);
     692                 :             : 
     693                 :             :                 /* Locate the referenced nsitem */
     694                 :      683720 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     695                 :             :                                               cref->location,
     696                 :             :                                               &levels_up);
     697         [ +  + ]:      683704 :                 if (nsitem == NULL)
     698                 :             :                 {
     699                 :        3814 :                     crerr = CRERR_NO_RTE;
     700                 :        3814 :                     break;
     701                 :             :                 }
     702                 :             : 
     703                 :             :                 /* Whole-row reference? */
     704         [ +  + ]:      679890 :                 if (IsA(field2, A_Star))
     705                 :             :                 {
     706                 :         889 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     707                 :             :                                                 cref->location);
     708                 :         889 :                     break;
     709                 :             :                 }
     710                 :             : 
     711                 :      679001 :                 colname = strVal(field2);
     712                 :             : 
     713                 :             :                 /* Try to identify as a column of the nsitem */
     714                 :      679001 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     715                 :             :                                            cref->location);
     716         [ +  + ]:      678997 :                 if (node == NULL)
     717                 :             :                 {
     718                 :             :                     /* Try it as a function call on the whole row */
     719                 :         112 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     720                 :             :                                                 cref->location);
     721                 :         224 :                     node = ParseFuncOrColumn(pstate,
     722                 :         112 :                                              list_make1(makeString(colname)),
     723                 :             :                                              list_make1(node),
     724                 :             :                                              pstate->p_last_srf,
     725                 :             :                                              NULL,
     726                 :             :                                              false,
     727                 :             :                                              cref->location);
     728                 :             :                 }
     729                 :      678997 :                 break;
     730                 :             :             }
     731                 :          53 :         case 3:
     732                 :             :             {
     733                 :          53 :                 Node       *field1 = (Node *) linitial(cref->fields);
     734                 :          53 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     735                 :          53 :                 Node       *field3 = (Node *) lthird(cref->fields);
     736                 :             : 
     737                 :          53 :                 nspname = strVal(field1);
     738                 :          53 :                 relname = strVal(field2);
     739                 :             : 
     740                 :             :                 /* Locate the referenced nsitem */
     741                 :          53 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     742                 :             :                                               cref->location,
     743                 :             :                                               &levels_up);
     744         [ +  + ]:          53 :                 if (nsitem == NULL)
     745                 :             :                 {
     746                 :          41 :                     crerr = CRERR_NO_RTE;
     747                 :          41 :                     break;
     748                 :             :                 }
     749                 :             : 
     750                 :             :                 /* Whole-row reference? */
     751         [ +  + ]:          12 :                 if (IsA(field3, A_Star))
     752                 :             :                 {
     753                 :           4 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     754                 :             :                                                 cref->location);
     755                 :           4 :                     break;
     756                 :             :                 }
     757                 :             : 
     758                 :           8 :                 colname = strVal(field3);
     759                 :             : 
     760                 :             :                 /* Try to identify as a column of the nsitem */
     761                 :           8 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     762                 :             :                                            cref->location);
     763         [ -  + ]:           8 :                 if (node == NULL)
     764                 :             :                 {
     765                 :             :                     /* Try it as a function call on the whole row */
     766                 :           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     767                 :             :                                                 cref->location);
     768                 :           0 :                     node = ParseFuncOrColumn(pstate,
     769                 :           0 :                                              list_make1(makeString(colname)),
     770                 :             :                                              list_make1(node),
     771                 :             :                                              pstate->p_last_srf,
     772                 :             :                                              NULL,
     773                 :             :                                              false,
     774                 :             :                                              cref->location);
     775                 :             :                 }
     776                 :           8 :                 break;
     777                 :             :             }
     778                 :           0 :         case 4:
     779                 :             :             {
     780                 :           0 :                 Node       *field1 = (Node *) linitial(cref->fields);
     781                 :           0 :                 Node       *field2 = (Node *) lsecond(cref->fields);
     782                 :           0 :                 Node       *field3 = (Node *) lthird(cref->fields);
     783                 :           0 :                 Node       *field4 = (Node *) lfourth(cref->fields);
     784                 :             :                 char       *catname;
     785                 :             : 
     786                 :           0 :                 catname = strVal(field1);
     787                 :           0 :                 nspname = strVal(field2);
     788                 :           0 :                 relname = strVal(field3);
     789                 :             : 
     790                 :             :                 /*
     791                 :             :                  * We check the catalog name and then ignore it.
     792                 :             :                  */
     793         [ #  # ]:           0 :                 if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
     794                 :             :                 {
     795                 :           0 :                     crerr = CRERR_WRONG_DB;
     796                 :           0 :                     break;
     797                 :             :                 }
     798                 :             : 
     799                 :             :                 /* Locate the referenced nsitem */
     800                 :           0 :                 nsitem = refnameNamespaceItem(pstate, nspname, relname,
     801                 :             :                                               cref->location,
     802                 :             :                                               &levels_up);
     803         [ #  # ]:           0 :                 if (nsitem == NULL)
     804                 :             :                 {
     805                 :           0 :                     crerr = CRERR_NO_RTE;
     806                 :           0 :                     break;
     807                 :             :                 }
     808                 :             : 
     809                 :             :                 /* Whole-row reference? */
     810         [ #  # ]:           0 :                 if (IsA(field4, A_Star))
     811                 :             :                 {
     812                 :           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     813                 :             :                                                 cref->location);
     814                 :           0 :                     break;
     815                 :             :                 }
     816                 :             : 
     817                 :           0 :                 colname = strVal(field4);
     818                 :             : 
     819                 :             :                 /* Try to identify as a column of the nsitem */
     820                 :           0 :                 node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
     821                 :             :                                            cref->location);
     822         [ #  # ]:           0 :                 if (node == NULL)
     823                 :             :                 {
     824                 :             :                     /* Try it as a function call on the whole row */
     825                 :           0 :                     node = transformWholeRowRef(pstate, nsitem, levels_up,
     826                 :             :                                                 cref->location);
     827                 :           0 :                     node = ParseFuncOrColumn(pstate,
     828                 :           0 :                                              list_make1(makeString(colname)),
     829                 :             :                                              list_make1(node),
     830                 :             :                                              pstate->p_last_srf,
     831                 :             :                                              NULL,
     832                 :             :                                              false,
     833                 :             :                                              cref->location);
     834                 :             :                 }
     835                 :           0 :                 break;
     836                 :             :             }
     837                 :           0 :         default:
     838                 :           0 :             crerr = CRERR_TOO_MANY; /* too many dotted names */
     839                 :           0 :             break;
     840                 :             :     }
     841                 :             : 
     842                 :             :     /*
     843                 :             :      * Now give the PostParseColumnRefHook, if any, a chance.  We pass the
     844                 :             :      * translation-so-far so that it can throw an error if it wishes in the
     845                 :             :      * case that it has a conflicting interpretation of the ColumnRef. (If it
     846                 :             :      * just translates anyway, we'll throw an error, because we can't undo
     847                 :             :      * whatever effects the preceding steps may have had on the pstate.) If it
     848                 :             :      * returns NULL, use the standard translation, or throw a suitable error
     849                 :             :      * if there is none.
     850                 :             :      */
     851         [ +  + ]:     1132128 :     if (pstate->p_post_columnref_hook != NULL)
     852                 :             :     {
     853                 :             :         Node       *hookresult;
     854                 :             : 
     855                 :       31358 :         hookresult = pstate->p_post_columnref_hook(pstate, cref, node);
     856         [ +  + ]:       31338 :         if (node == NULL)
     857                 :       23731 :             node = hookresult;
     858         [ -  + ]:        7607 :         else if (hookresult != NULL)
     859         [ #  # ]:           0 :             ereport(ERROR,
     860                 :             :                     (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     861                 :             :                      errmsg("column reference \"%s\" is ambiguous",
     862                 :             :                             NameListToString(cref->fields)),
     863                 :             :                      parser_errposition(pstate, cref->location)));
     864                 :             :     }
     865                 :             : 
     866                 :             :     /*
     867                 :             :      * Throw error if no translation found.
     868                 :             :      */
     869         [ +  + ]:     1132108 :     if (node == NULL)
     870                 :             :     {
     871   [ +  +  -  -  :         321 :         switch (crerr)
                      - ]
     872                 :             :         {
     873                 :         245 :             case CRERR_NO_COLUMN:
     874                 :         245 :                 errorMissingColumn(pstate, relname, colname, cref->location);
     875                 :             :                 break;
     876                 :          76 :             case CRERR_NO_RTE:
     877                 :          76 :                 errorMissingRTE(pstate, makeRangeVar(nspname, relname,
     878                 :             :                                                      cref->location));
     879                 :             :                 break;
     880                 :           0 :             case CRERR_WRONG_DB:
     881         [ #  # ]:           0 :                 ereport(ERROR,
     882                 :             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     883                 :             :                          errmsg("cross-database references are not implemented: %s",
     884                 :             :                                 NameListToString(cref->fields)),
     885                 :             :                          parser_errposition(pstate, cref->location)));
     886                 :             :                 break;
     887                 :           0 :             case CRERR_TOO_MANY:
     888         [ #  # ]:           0 :                 ereport(ERROR,
     889                 :             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     890                 :             :                          errmsg("improper qualified name (too many dotted names): %s",
     891                 :             :                                 NameListToString(cref->fields)),
     892                 :             :                          parser_errposition(pstate, cref->location)));
     893                 :             :                 break;
     894                 :             :         }
     895                 :             :     }
     896                 :             : 
     897                 :     1131787 :     return node;
     898                 :             : }
     899                 :             : 
     900                 :             : static Node *
     901                 :       25984 : transformParamRef(ParseState *pstate, ParamRef *pref)
     902                 :             : {
     903                 :             :     Node       *result;
     904                 :             : 
     905                 :             :     /*
     906                 :             :      * The core parser knows nothing about Params.  If a hook is supplied,
     907                 :             :      * call it.  If not, or if the hook returns NULL, throw a generic error.
     908                 :             :      */
     909         [ +  + ]:       25984 :     if (pstate->p_paramref_hook != NULL)
     910                 :       25980 :         result = pstate->p_paramref_hook(pstate, pref);
     911                 :             :     else
     912                 :           4 :         result = NULL;
     913                 :             : 
     914         [ +  + ]:       25984 :     if (result == NULL)
     915         [ +  - ]:           8 :         ereport(ERROR,
     916                 :             :                 (errcode(ERRCODE_UNDEFINED_PARAMETER),
     917                 :             :                  errmsg("there is no parameter $%d", pref->number),
     918                 :             :                  parser_errposition(pstate, pref->location)));
     919                 :             : 
     920                 :       25976 :     return result;
     921                 :             : }
     922                 :             : 
     923                 :             : /* Test whether an a_expr is a plain NULL constant or not */
     924                 :             : static bool
     925                 :        1424 : exprIsNullConstant(Node *arg)
     926                 :             : {
     927   [ +  -  +  + ]:        1424 :     if (arg && IsA(arg, A_Const))
     928                 :             :     {
     929                 :          96 :         A_Const    *con = (A_Const *) arg;
     930                 :             : 
     931         [ +  + ]:          96 :         if (con->isnull)
     932                 :          20 :             return true;
     933                 :             :     }
     934                 :        1404 :     return false;
     935                 :             : }
     936                 :             : 
     937                 :             : static Node *
     938                 :      389066 : transformAExprOp(ParseState *pstate, A_Expr *a)
     939                 :             : {
     940                 :      389066 :     Node       *lexpr = a->lexpr;
     941                 :      389066 :     Node       *rexpr = a->rexpr;
     942                 :             :     Node       *result;
     943                 :             : 
     944                 :             :     /*
     945                 :             :      * Special-case "foo = NULL" and "NULL = foo" for compatibility with
     946                 :             :      * standards-broken products (like Microsoft's).  Turn these into IS NULL
     947                 :             :      * exprs. (If either side is a CaseTestExpr, then the expression was
     948                 :             :      * generated internally from a CASE-WHEN expression, and
     949                 :             :      * transform_null_equals does not apply.)
     950                 :             :      */
     951   [ -  +  -  - ]:      389066 :     if (Transform_null_equals &&
     952                 :           0 :         list_length(a->name) == 1 &&
     953   [ #  #  #  # ]:           0 :         strcmp(strVal(linitial(a->name)), "=") == 0 &&
     954         [ #  # ]:           0 :         (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
     955   [ #  #  #  # ]:           0 :         (!IsA(lexpr, CaseTestExpr) && !IsA(rexpr, CaseTestExpr)))
     956                 :           0 :     {
     957                 :           0 :         NullTest   *n = makeNode(NullTest);
     958                 :             : 
     959                 :           0 :         n->nulltesttype = IS_NULL;
     960                 :           0 :         n->location = a->location;
     961                 :             : 
     962         [ #  # ]:           0 :         if (exprIsNullConstant(lexpr))
     963                 :           0 :             n->arg = (Expr *) rexpr;
     964                 :             :         else
     965                 :           0 :             n->arg = (Expr *) lexpr;
     966                 :             : 
     967                 :           0 :         result = transformExprRecurse(pstate, (Node *) n);
     968                 :             :     }
     969   [ +  +  +  +  :      389066 :     else if (lexpr && IsA(lexpr, RowExpr) &&
                   +  - ]
     970         [ +  + ]:         562 :              rexpr && IsA(rexpr, SubLink) &&
     971         [ +  - ]:          20 :              ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
     972                 :          20 :     {
     973                 :             :         /*
     974                 :             :          * Convert "row op subselect" into a ROWCOMPARE sublink. Formerly the
     975                 :             :          * grammar did this, but now that a row construct is allowed anywhere
     976                 :             :          * in expressions, it's easier to do it here.
     977                 :             :          */
     978                 :          20 :         SubLink    *s = (SubLink *) rexpr;
     979                 :             : 
     980                 :          20 :         s->subLinkType = ROWCOMPARE_SUBLINK;
     981                 :          20 :         s->testexpr = lexpr;
     982                 :          20 :         s->operName = a->name;
     983                 :          20 :         s->location = a->location;
     984                 :          20 :         result = transformExprRecurse(pstate, (Node *) s);
     985                 :             :     }
     986   [ +  +  +  +  :      389046 :     else if (lexpr && IsA(lexpr, RowExpr) &&
                   +  - ]
     987         [ +  + ]:         542 :              rexpr && IsA(rexpr, RowExpr))
     988                 :             :     {
     989                 :             :         /* ROW() op ROW() is handled specially */
     990                 :         538 :         lexpr = transformExprRecurse(pstate, lexpr);
     991                 :         538 :         rexpr = transformExprRecurse(pstate, rexpr);
     992                 :             : 
     993                 :         538 :         result = make_row_comparison_op(pstate,
     994                 :             :                                         a->name,
     995                 :             :                                         castNode(RowExpr, lexpr)->args,
     996                 :             :                                         castNode(RowExpr, rexpr)->args,
     997                 :             :                                         a->location);
     998                 :             :     }
     999                 :             :     else
    1000                 :             :     {
    1001                 :             :         /* Ordinary scalar operator */
    1002                 :      388508 :         Node       *last_srf = pstate->p_last_srf;
    1003                 :             : 
    1004                 :      388508 :         lexpr = transformExprRecurse(pstate, lexpr);
    1005                 :      388319 :         rexpr = transformExprRecurse(pstate, rexpr);
    1006                 :             : 
    1007                 :      388254 :         result = (Node *) make_op(pstate,
    1008                 :             :                                   a->name,
    1009                 :             :                                   lexpr,
    1010                 :             :                                   rexpr,
    1011                 :             :                                   last_srf,
    1012                 :             :                                   a->location);
    1013                 :             :     }
    1014                 :             : 
    1015                 :      388726 :     return result;
    1016                 :             : }
    1017                 :             : 
    1018                 :             : static Node *
    1019                 :       10931 : transformAExprOpAny(ParseState *pstate, A_Expr *a)
    1020                 :             : {
    1021                 :       10931 :     Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
    1022                 :       10931 :     Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
    1023                 :             : 
    1024                 :       10931 :     return (Node *) make_scalar_array_op(pstate,
    1025                 :             :                                          a->name,
    1026                 :             :                                          true,
    1027                 :             :                                          lexpr,
    1028                 :             :                                          rexpr,
    1029                 :             :                                          a->location);
    1030                 :             : }
    1031                 :             : 
    1032                 :             : static Node *
    1033                 :         205 : transformAExprOpAll(ParseState *pstate, A_Expr *a)
    1034                 :             : {
    1035                 :         205 :     Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
    1036                 :         205 :     Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
    1037                 :             : 
    1038                 :         205 :     return (Node *) make_scalar_array_op(pstate,
    1039                 :             :                                          a->name,
    1040                 :             :                                          false,
    1041                 :             :                                          lexpr,
    1042                 :             :                                          rexpr,
    1043                 :             :                                          a->location);
    1044                 :             : }
    1045                 :             : 
    1046                 :             : static Node *
    1047                 :         722 : transformAExprDistinct(ParseState *pstate, A_Expr *a)
    1048                 :             : {
    1049                 :         722 :     Node       *lexpr = a->lexpr;
    1050                 :         722 :     Node       *rexpr = a->rexpr;
    1051                 :             :     Node       *result;
    1052                 :             : 
    1053                 :             :     /*
    1054                 :             :      * If either input is an undecorated NULL literal, transform to a NullTest
    1055                 :             :      * on the other input. That's simpler to process than a full DistinctExpr,
    1056                 :             :      * and it avoids needing to require that the datatype have an = operator.
    1057                 :             :      */
    1058         [ +  + ]:         722 :     if (exprIsNullConstant(rexpr))
    1059                 :          20 :         return make_nulltest_from_distinct(pstate, a, lexpr);
    1060         [ -  + ]:         702 :     if (exprIsNullConstant(lexpr))
    1061                 :           0 :         return make_nulltest_from_distinct(pstate, a, rexpr);
    1062                 :             : 
    1063                 :         702 :     lexpr = transformExprRecurse(pstate, lexpr);
    1064                 :         702 :     rexpr = transformExprRecurse(pstate, rexpr);
    1065                 :             : 
    1066   [ +  -  +  +  :         702 :     if (lexpr && IsA(lexpr, RowExpr) &&
                   +  - ]
    1067         [ +  + ]:          20 :         rexpr && IsA(rexpr, RowExpr))
    1068                 :             :     {
    1069                 :             :         /* ROW() op ROW() is handled specially */
    1070                 :           4 :         result = make_row_distinct_op(pstate, a->name,
    1071                 :             :                                       (RowExpr *) lexpr,
    1072                 :             :                                       (RowExpr *) rexpr,
    1073                 :             :                                       a->location);
    1074                 :             :     }
    1075                 :             :     else
    1076                 :             :     {
    1077                 :             :         /* Ordinary scalar operator */
    1078                 :         698 :         result = (Node *) make_distinct_op(pstate,
    1079                 :             :                                            a->name,
    1080                 :             :                                            lexpr,
    1081                 :             :                                            rexpr,
    1082                 :             :                                            a->location);
    1083                 :             :     }
    1084                 :             : 
    1085                 :             :     /*
    1086                 :             :      * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a
    1087                 :             :      * NOT on top.
    1088                 :             :      */
    1089         [ +  + ]:         702 :     if (a->kind == AEXPR_NOT_DISTINCT)
    1090                 :          76 :         result = (Node *) makeBoolExpr(NOT_EXPR,
    1091                 :             :                                        list_make1(result),
    1092                 :             :                                        a->location);
    1093                 :             : 
    1094                 :         702 :     return result;
    1095                 :             : }
    1096                 :             : 
    1097                 :             : static Node *
    1098                 :         470 : transformAExprNullIf(ParseState *pstate, A_Expr *a)
    1099                 :             : {
    1100                 :         470 :     Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
    1101                 :         470 :     Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
    1102                 :             :     OpExpr     *result;
    1103                 :             : 
    1104                 :         470 :     result = (OpExpr *) make_op(pstate,
    1105                 :             :                                 a->name,
    1106                 :             :                                 lexpr,
    1107                 :             :                                 rexpr,
    1108                 :             :                                 pstate->p_last_srf,
    1109                 :             :                                 a->location);
    1110                 :             : 
    1111                 :             :     /*
    1112                 :             :      * The comparison operator itself should yield boolean ...
    1113                 :             :      */
    1114         [ -  + ]:         470 :     if (result->opresulttype != BOOLOID)
    1115         [ #  # ]:           0 :         ereport(ERROR,
    1116                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1117                 :             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    1118                 :             :                  errmsg("%s requires = operator to yield boolean", "NULLIF"),
    1119                 :             :                  parser_errposition(pstate, a->location)));
    1120         [ -  + ]:         470 :     if (result->opretset)
    1121         [ #  # ]:           0 :         ereport(ERROR,
    1122                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1123                 :             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    1124                 :             :                  errmsg("%s must not return a set", "NULLIF"),
    1125                 :             :                  parser_errposition(pstate, a->location)));
    1126                 :             : 
    1127                 :             :     /*
    1128                 :             :      * ... but the NullIfExpr will yield the first operand's type.
    1129                 :             :      */
    1130                 :         470 :     result->opresulttype = exprType((Node *) linitial(result->args));
    1131                 :             : 
    1132                 :             :     /*
    1133                 :             :      * We rely on NullIfExpr and OpExpr being the same struct
    1134                 :             :      */
    1135                 :         470 :     NodeSetTag(result, T_NullIfExpr);
    1136                 :             : 
    1137                 :         470 :     return (Node *) result;
    1138                 :             : }
    1139                 :             : 
    1140                 :             : static Node *
    1141                 :       12505 : transformAExprIn(ParseState *pstate, A_Expr *a)
    1142                 :             : {
    1143                 :       12505 :     Node       *result = NULL;
    1144                 :             :     Node       *lexpr;
    1145                 :             :     List       *rexprs;
    1146                 :             :     List       *rvars;
    1147                 :             :     List       *rnonvars;
    1148                 :             :     bool        useOr;
    1149                 :             :     ListCell   *l;
    1150                 :       12505 :     bool        has_rvars = false;
    1151                 :             : 
    1152                 :             :     /*
    1153                 :             :      * If the operator is <>, combine with AND not OR.
    1154                 :             :      */
    1155         [ +  + ]:       12505 :     if (strcmp(strVal(linitial(a->name)), "<>") == 0)
    1156                 :        1769 :         useOr = false;
    1157                 :             :     else
    1158                 :       10736 :         useOr = true;
    1159                 :             : 
    1160                 :             :     /*
    1161                 :             :      * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
    1162                 :             :      * possible if there is a suitable array type available.  If not, we fall
    1163                 :             :      * back to a boolean condition tree with multiple copies of the lefthand
    1164                 :             :      * expression.  Also, any IN-list items that contain Vars are handled as
    1165                 :             :      * separate boolean conditions, because that gives the planner more scope
    1166                 :             :      * for optimization on such clauses.
    1167                 :             :      *
    1168                 :             :      * First step: transform all the inputs, and detect whether any contain
    1169                 :             :      * Vars.
    1170                 :             :      */
    1171                 :       12505 :     lexpr = transformExprRecurse(pstate, a->lexpr);
    1172                 :       12505 :     rexprs = rvars = rnonvars = NIL;
    1173   [ +  -  +  +  :       47780 :     foreach(l, (List *) a->rexpr)
                   +  + ]
    1174                 :             :     {
    1175                 :       35279 :         Node       *rexpr = transformExprRecurse(pstate, lfirst(l));
    1176                 :             : 
    1177                 :       35275 :         rexprs = lappend(rexprs, rexpr);
    1178         [ +  + ]:       35275 :         if (contain_vars_of_level(rexpr, 0))
    1179                 :             :         {
    1180                 :           4 :             rvars = lappend(rvars, rexpr);
    1181                 :           4 :             has_rvars = true;
    1182                 :             :         }
    1183                 :             :         else
    1184                 :       35271 :             rnonvars = lappend(rnonvars, rexpr);
    1185                 :             :     }
    1186                 :             : 
    1187                 :             :     /*
    1188                 :             :      * ScalarArrayOpExpr is only going to be useful if there's more than one
    1189                 :             :      * non-Var righthand item.
    1190                 :             :      */
    1191         [ +  + ]:       12501 :     if (list_length(rnonvars) > 1)
    1192                 :             :     {
    1193                 :             :         List       *allexprs;
    1194                 :             :         Oid         scalar_type;
    1195                 :             :         Oid         array_type;
    1196                 :             : 
    1197                 :             :         /*
    1198                 :             :          * Try to select a common type for the array elements.  Note that
    1199                 :             :          * since the LHS' type is first in the list, it will be preferred when
    1200                 :             :          * there is doubt (eg, when all the RHS items are unknown literals).
    1201                 :             :          *
    1202                 :             :          * Note: use list_concat here not lcons, to avoid damaging rnonvars.
    1203                 :             :          */
    1204                 :       11014 :         allexprs = list_concat(list_make1(lexpr), rnonvars);
    1205                 :       11014 :         scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
    1206                 :             : 
    1207                 :             :         /* We have to verify that the selected type actually works */
    1208         [ +  + ]:       11014 :         if (OidIsValid(scalar_type) &&
    1209         [ +  + ]:       11012 :             !verify_common_type(scalar_type, allexprs))
    1210                 :           4 :             scalar_type = InvalidOid;
    1211                 :             : 
    1212                 :             :         /*
    1213                 :             :          * Do we have an array type to use?  Aside from the case where there
    1214                 :             :          * isn't one, we don't risk using ScalarArrayOpExpr when the common
    1215                 :             :          * type is RECORD, because the RowExpr comparison logic below can cope
    1216                 :             :          * with some cases of non-identical row types.
    1217                 :             :          */
    1218   [ +  +  +  + ]:       11014 :         if (OidIsValid(scalar_type) && scalar_type != RECORDOID)
    1219                 :       10992 :             array_type = get_array_type(scalar_type);
    1220                 :             :         else
    1221                 :          22 :             array_type = InvalidOid;
    1222         [ +  + ]:       11014 :         if (array_type != InvalidOid)
    1223                 :             :         {
    1224                 :             :             /*
    1225                 :             :              * OK: coerce all the right-hand non-Var inputs to the common type
    1226                 :             :              * and build an ArrayExpr for them.
    1227                 :             :              */
    1228                 :             :             List       *aexprs;
    1229                 :             :             ArrayExpr  *newa;
    1230                 :             : 
    1231                 :       10984 :             aexprs = NIL;
    1232   [ +  -  +  +  :       44708 :             foreach(l, rnonvars)
                   +  + ]
    1233                 :             :             {
    1234                 :       33724 :                 Node       *rexpr = (Node *) lfirst(l);
    1235                 :             : 
    1236                 :       33724 :                 rexpr = coerce_to_common_type(pstate, rexpr,
    1237                 :             :                                               scalar_type,
    1238                 :             :                                               "IN");
    1239                 :       33724 :                 aexprs = lappend(aexprs, rexpr);
    1240                 :             :             }
    1241                 :       10984 :             newa = makeNode(ArrayExpr);
    1242                 :       10984 :             newa->array_typeid = array_type;
    1243                 :             :             /* array_collid will be set by parse_collate.c */
    1244                 :       10984 :             newa->element_typeid = scalar_type;
    1245                 :       10984 :             newa->elements = aexprs;
    1246                 :       10984 :             newa->multidims = false;
    1247                 :       10984 :             newa->location = -1;
    1248                 :             : 
    1249                 :             :             /*
    1250                 :             :              * If the IN expression contains Vars, disable query jumbling
    1251                 :             :              * squashing.  Vars cannot be safely jumbled.
    1252                 :             :              */
    1253         [ +  + ]:       10984 :             newa->list_start = has_rvars ? -1 : a->rexpr_list_start;
    1254         [ +  + ]:       10984 :             newa->list_end = has_rvars ? -1 : a->rexpr_list_end;
    1255                 :             : 
    1256                 :       10984 :             result = (Node *) make_scalar_array_op(pstate,
    1257                 :             :                                                    a->name,
    1258                 :             :                                                    useOr,
    1259                 :             :                                                    lexpr,
    1260                 :             :                                                    (Node *) newa,
    1261                 :             :                                                    a->location);
    1262                 :             : 
    1263                 :             :             /* Consider only the Vars (if any) in the loop below */
    1264                 :       10984 :             rexprs = rvars;
    1265                 :             :         }
    1266                 :             :     }
    1267                 :             : 
    1268                 :             :     /*
    1269                 :             :      * Must do it the hard way, ie, with a boolean expression tree.
    1270                 :             :      */
    1271   [ +  +  +  +  :       14044 :     foreach(l, rexprs)
                   +  + ]
    1272                 :             :     {
    1273                 :        1547 :         Node       *rexpr = (Node *) lfirst(l);
    1274                 :             :         Node       *cmp;
    1275                 :             : 
    1276         [ +  + ]:        1547 :         if (IsA(lexpr, RowExpr) &&
    1277         [ +  - ]:          32 :             IsA(rexpr, RowExpr))
    1278                 :             :         {
    1279                 :             :             /* ROW() op ROW() is handled specially */
    1280                 :          32 :             cmp = make_row_comparison_op(pstate,
    1281                 :             :                                          a->name,
    1282                 :          32 :                                          copyObject(((RowExpr *) lexpr)->args),
    1283                 :             :                                          ((RowExpr *) rexpr)->args,
    1284                 :             :                                          a->location);
    1285                 :             :         }
    1286                 :             :         else
    1287                 :             :         {
    1288                 :             :             /* Ordinary scalar operator */
    1289                 :        1515 :             cmp = (Node *) make_op(pstate,
    1290                 :             :                                    a->name,
    1291                 :        1515 :                                    copyObject(lexpr),
    1292                 :             :                                    rexpr,
    1293                 :             :                                    pstate->p_last_srf,
    1294                 :             :                                    a->location);
    1295                 :             :         }
    1296                 :             : 
    1297                 :        1543 :         cmp = coerce_to_boolean(pstate, cmp, "IN");
    1298         [ +  + ]:        1543 :         if (result == NULL)
    1299                 :        1513 :             result = cmp;
    1300                 :             :         else
    1301                 :          30 :             result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
    1302                 :             :                                            list_make2(result, cmp),
    1303                 :             :                                            a->location);
    1304                 :             :     }
    1305                 :             : 
    1306                 :       12497 :     return result;
    1307                 :             : }
    1308                 :             : 
    1309                 :             : static Node *
    1310                 :         340 : transformAExprBetween(ParseState *pstate, A_Expr *a)
    1311                 :             : {
    1312                 :             :     Node       *aexpr;
    1313                 :             :     Node       *bexpr;
    1314                 :             :     Node       *cexpr;
    1315                 :             :     Node       *result;
    1316                 :             :     Node       *sub1;
    1317                 :             :     Node       *sub2;
    1318                 :             :     List       *args;
    1319                 :             : 
    1320                 :             :     /* Deconstruct A_Expr into three subexprs */
    1321                 :         340 :     aexpr = a->lexpr;
    1322                 :         340 :     args = castNode(List, a->rexpr);
    1323                 :             :     Assert(list_length(args) == 2);
    1324                 :         340 :     bexpr = (Node *) linitial(args);
    1325                 :         340 :     cexpr = (Node *) lsecond(args);
    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   [ +  +  +  +  :         340 :     switch (a->kind)
                      - ]
    1339                 :             :     {
    1340                 :         316 :         case AEXPR_BETWEEN:
    1341                 :         316 :             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                 :         316 :             result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1348                 :         316 :             break;
    1349                 :           8 :         case AEXPR_NOT_BETWEEN:
    1350                 :           8 :             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                 :           8 :             result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1357                 :           8 :             break;
    1358                 :           8 :         case AEXPR_BETWEEN_SYM:
    1359                 :           8 :             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                 :           8 :             sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1366                 :           8 :             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                 :           8 :             sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1373                 :           8 :             args = list_make2(sub1, sub2);
    1374                 :           8 :             result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1375                 :           8 :             break;
    1376                 :           8 :         case AEXPR_NOT_BETWEEN_SYM:
    1377                 :           8 :             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                 :           8 :             sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1384                 :           8 :             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                 :           8 :             sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
    1391                 :           8 :             args = list_make2(sub1, sub2);
    1392                 :           8 :             result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
    1393                 :           8 :             break;
    1394                 :           0 :         default:
    1395         [ #  # ]:           0 :             elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
    1396                 :             :             result = NULL;      /* keep compiler quiet */
    1397                 :             :             break;
    1398                 :             :     }
    1399                 :             : 
    1400                 :         340 :     return transformExprRecurse(pstate, result);
    1401                 :             : }
    1402                 :             : 
    1403                 :             : static Node *
    1404                 :         138 : transformMergeSupportFunc(ParseState *pstate, MergeSupportFunc *f)
    1405                 :             : {
    1406                 :             :     /*
    1407                 :             :      * All we need to do is check that we're in the RETURNING list of a MERGE
    1408                 :             :      * command.  If so, we just return the node as-is.
    1409                 :             :      */
    1410         [ +  + ]:         138 :     if (pstate->p_expr_kind != EXPR_KIND_MERGE_RETURNING)
    1411                 :             :     {
    1412                 :          12 :         ParseState *parent_pstate = pstate->parentParseState;
    1413                 :             : 
    1414         [ +  + ]:          12 :         while (parent_pstate &&
    1415         [ -  + ]:           4 :                parent_pstate->p_expr_kind != EXPR_KIND_MERGE_RETURNING)
    1416                 :           0 :             parent_pstate = parent_pstate->parentParseState;
    1417                 :             : 
    1418         [ +  + ]:          12 :         if (!parent_pstate)
    1419         [ +  - ]:           8 :             ereport(ERROR,
    1420                 :             :                     errcode(ERRCODE_SYNTAX_ERROR),
    1421                 :             :                     errmsg("MERGE_ACTION() can only be used in the RETURNING list of a MERGE command"),
    1422                 :             :                     parser_errposition(pstate, f->location));
    1423                 :             :     }
    1424                 :             : 
    1425                 :         130 :     return (Node *) f;
    1426                 :             : }
    1427                 :             : 
    1428                 :             : static Node *
    1429                 :      111976 : transformBoolExpr(ParseState *pstate, BoolExpr *a)
    1430                 :             : {
    1431                 :      111976 :     List       *args = NIL;
    1432                 :             :     const char *opname;
    1433                 :             :     ListCell   *lc;
    1434                 :             : 
    1435   [ +  +  +  - ]:      111976 :     switch (a->boolop)
    1436                 :             :     {
    1437                 :       84498 :         case AND_EXPR:
    1438                 :       84498 :             opname = "AND";
    1439                 :       84498 :             break;
    1440                 :       11932 :         case OR_EXPR:
    1441                 :       11932 :             opname = "OR";
    1442                 :       11932 :             break;
    1443                 :       15546 :         case NOT_EXPR:
    1444                 :       15546 :             opname = "NOT";
    1445                 :       15546 :             break;
    1446                 :           0 :         default:
    1447         [ #  # ]:           0 :             elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
    1448                 :             :             opname = NULL;      /* keep compiler quiet */
    1449                 :             :             break;
    1450                 :             :     }
    1451                 :             : 
    1452   [ +  -  +  +  :      390737 :     foreach(lc, a->args)
                   +  + ]
    1453                 :             :     {
    1454                 :      278778 :         Node       *arg = (Node *) lfirst(lc);
    1455                 :             : 
    1456                 :      278778 :         arg = transformExprRecurse(pstate, arg);
    1457                 :      278761 :         arg = coerce_to_boolean(pstate, arg, opname);
    1458                 :      278761 :         args = lappend(args, arg);
    1459                 :             :     }
    1460                 :             : 
    1461                 :      111959 :     return (Node *) makeBoolExpr(a->boolop, args, a->location);
    1462                 :             : }
    1463                 :             : 
    1464                 :             : static Node *
    1465                 :      243003 : transformFuncCall(ParseState *pstate, FuncCall *fn)
    1466                 :             : {
    1467                 :      243003 :     Node       *last_srf = pstate->p_last_srf;
    1468                 :             :     List       *targs;
    1469                 :             :     ListCell   *args;
    1470                 :             : 
    1471                 :             :     /* Transform the list of arguments ... */
    1472                 :      243003 :     targs = NIL;
    1473   [ +  +  +  +  :      640188 :     foreach(args, fn->args)
                   +  + ]
    1474                 :             :     {
    1475                 :      397185 :         targs = lappend(targs, transformExprRecurse(pstate,
    1476                 :      397233 :                                                     (Node *) lfirst(args)));
    1477                 :             :     }
    1478                 :             : 
    1479                 :             :     /*
    1480                 :             :      * When WITHIN GROUP is used, we treat its ORDER BY expressions as
    1481                 :             :      * additional arguments to the function, for purposes of function lookup
    1482                 :             :      * and argument type coercion.  So, transform each such expression and add
    1483                 :             :      * them to the targs list.  We don't explicitly mark where each argument
    1484                 :             :      * came from, but ParseFuncOrColumn can tell what's what by reference to
    1485                 :             :      * list_length(fn->agg_order).
    1486                 :             :      */
    1487         [ +  + ]:      242955 :     if (fn->agg_within_group)
    1488                 :             :     {
    1489                 :             :         Assert(fn->agg_order != NIL);
    1490   [ +  -  +  +  :         487 :         foreach(args, fn->agg_order)
                   +  + ]
    1491                 :             :         {
    1492                 :         263 :             SortBy     *arg = (SortBy *) lfirst(args);
    1493                 :             : 
    1494                 :         263 :             targs = lappend(targs, transformExpr(pstate, arg->node,
    1495                 :             :                                                  EXPR_KIND_ORDER_BY));
    1496                 :             :         }
    1497                 :             :     }
    1498                 :             : 
    1499                 :             :     /* ... and hand off to ParseFuncOrColumn */
    1500                 :      242955 :     return ParseFuncOrColumn(pstate,
    1501                 :             :                              fn->funcname,
    1502                 :             :                              targs,
    1503                 :             :                              last_srf,
    1504                 :             :                              fn,
    1505                 :             :                              false,
    1506                 :             :                              fn->location);
    1507                 :             : }
    1508                 :             : 
    1509                 :             : static Node *
    1510                 :         249 : transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
    1511                 :             : {
    1512                 :             :     SubLink    *sublink;
    1513                 :             :     RowExpr    *rexpr;
    1514                 :             :     Query      *qtree;
    1515                 :             :     TargetEntry *tle;
    1516                 :             : 
    1517                 :             :     /* We should only see this in first-stage processing of UPDATE tlists */
    1518                 :             :     Assert(pstate->p_expr_kind == EXPR_KIND_UPDATE_SOURCE);
    1519                 :             : 
    1520                 :             :     /* We only need to transform the source if this is the first column */
    1521         [ +  + ]:         249 :     if (maref->colno == 1)
    1522                 :             :     {
    1523                 :             :         /*
    1524                 :             :          * For now, we only allow EXPR SubLinks and RowExprs as the source of
    1525                 :             :          * an UPDATE multiassignment.  This is sufficient to cover interesting
    1526                 :             :          * cases; at worst, someone would have to write (SELECT * FROM expr)
    1527                 :             :          * to expand a composite-returning expression of another form.
    1528                 :             :          */
    1529         [ +  + ]:         121 :         if (IsA(maref->source, SubLink) &&
    1530         [ +  - ]:          91 :             ((SubLink *) maref->source)->subLinkType == EXPR_SUBLINK)
    1531                 :             :         {
    1532                 :             :             /* Relabel it as a MULTIEXPR_SUBLINK */
    1533                 :          91 :             sublink = (SubLink *) maref->source;
    1534                 :          91 :             sublink->subLinkType = MULTIEXPR_SUBLINK;
    1535                 :             :             /* And transform it */
    1536                 :          91 :             sublink = (SubLink *) transformExprRecurse(pstate,
    1537                 :             :                                                        (Node *) sublink);
    1538                 :             : 
    1539                 :          91 :             qtree = castNode(Query, sublink->subselect);
    1540                 :             : 
    1541                 :             :             /* Check subquery returns required number of columns */
    1542         [ -  + ]:          91 :             if (count_nonjunk_tlist_entries(qtree->targetList) != maref->ncolumns)
    1543         [ #  # ]:           0 :                 ereport(ERROR,
    1544                 :             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1545                 :             :                          errmsg("number of columns does not match number of values"),
    1546                 :             :                          parser_errposition(pstate, sublink->location)));
    1547                 :             : 
    1548                 :             :             /*
    1549                 :             :              * Build a resjunk tlist item containing the MULTIEXPR SubLink,
    1550                 :             :              * and add it to pstate->p_multiassign_exprs, whence it will later
    1551                 :             :              * get appended to the completed targetlist.  We needn't worry
    1552                 :             :              * about selecting a resno for it; transformUpdateStmt will do
    1553                 :             :              * that.
    1554                 :             :              */
    1555                 :          91 :             tle = makeTargetEntry((Expr *) sublink, 0, NULL, true);
    1556                 :          91 :             pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
    1557                 :             :                                                   tle);
    1558                 :             : 
    1559                 :             :             /*
    1560                 :             :              * Assign a unique-within-this-targetlist ID to the MULTIEXPR
    1561                 :             :              * SubLink.  We can just use its position in the
    1562                 :             :              * p_multiassign_exprs list.
    1563                 :             :              */
    1564                 :          91 :             sublink->subLinkId = list_length(pstate->p_multiassign_exprs);
    1565                 :             :         }
    1566         [ +  + ]:          30 :         else if (IsA(maref->source, RowExpr))
    1567                 :             :         {
    1568                 :             :             /* Transform the RowExpr, allowing SetToDefault items */
    1569                 :          26 :             rexpr = (RowExpr *) transformRowExpr(pstate,
    1570                 :          26 :                                                  (RowExpr *) maref->source,
    1571                 :             :                                                  true);
    1572                 :             : 
    1573                 :             :             /* Check it returns required number of columns */
    1574         [ -  + ]:          26 :             if (list_length(rexpr->args) != maref->ncolumns)
    1575         [ #  # ]:           0 :                 ereport(ERROR,
    1576                 :             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1577                 :             :                          errmsg("number of columns does not match number of values"),
    1578                 :             :                          parser_errposition(pstate, rexpr->location)));
    1579                 :             : 
    1580                 :             :             /*
    1581                 :             :              * Temporarily append it to p_multiassign_exprs, so we can get it
    1582                 :             :              * back when we come back here for additional columns.
    1583                 :             :              */
    1584                 :          26 :             tle = makeTargetEntry((Expr *) rexpr, 0, NULL, true);
    1585                 :          26 :             pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
    1586                 :             :                                                   tle);
    1587                 :             :         }
    1588                 :             :         else
    1589         [ +  - ]:           4 :             ereport(ERROR,
    1590                 :             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1591                 :             :                      errmsg("source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression"),
    1592                 :             :                      parser_errposition(pstate, exprLocation(maref->source))));
    1593                 :             :     }
    1594                 :             :     else
    1595                 :             :     {
    1596                 :             :         /*
    1597                 :             :          * Second or later column in a multiassignment.  Re-fetch the
    1598                 :             :          * transformed SubLink or RowExpr, which we assume is still the last
    1599                 :             :          * entry in p_multiassign_exprs.
    1600                 :             :          */
    1601                 :             :         Assert(pstate->p_multiassign_exprs != NIL);
    1602                 :         128 :         tle = (TargetEntry *) llast(pstate->p_multiassign_exprs);
    1603                 :             :     }
    1604                 :             : 
    1605                 :             :     /*
    1606                 :             :      * Emit the appropriate output expression for the current column
    1607                 :             :      */
    1608         [ +  + ]:         245 :     if (IsA(tle->expr, SubLink))
    1609                 :             :     {
    1610                 :             :         Param      *param;
    1611                 :             : 
    1612                 :         185 :         sublink = (SubLink *) tle->expr;
    1613                 :             :         Assert(sublink->subLinkType == MULTIEXPR_SUBLINK);
    1614                 :         185 :         qtree = castNode(Query, sublink->subselect);
    1615                 :             : 
    1616                 :             :         /* Build a Param representing the current subquery output column */
    1617                 :         185 :         tle = (TargetEntry *) list_nth(qtree->targetList, maref->colno - 1);
    1618                 :             :         Assert(!tle->resjunk);
    1619                 :             : 
    1620                 :         185 :         param = makeNode(Param);
    1621                 :         185 :         param->paramkind = PARAM_MULTIEXPR;
    1622                 :         185 :         param->paramid = (sublink->subLinkId << 16) | maref->colno;
    1623                 :         185 :         param->paramtype = exprType((Node *) tle->expr);
    1624                 :         185 :         param->paramtypmod = exprTypmod((Node *) tle->expr);
    1625                 :         185 :         param->paramcollid = exprCollation((Node *) tle->expr);
    1626                 :         185 :         param->location = exprLocation((Node *) tle->expr);
    1627                 :             : 
    1628                 :         185 :         return (Node *) param;
    1629                 :             :     }
    1630                 :             : 
    1631         [ +  - ]:          60 :     if (IsA(tle->expr, RowExpr))
    1632                 :             :     {
    1633                 :             :         Node       *result;
    1634                 :             : 
    1635                 :          60 :         rexpr = (RowExpr *) tle->expr;
    1636                 :             : 
    1637                 :             :         /* Just extract and return the next element of the RowExpr */
    1638                 :          60 :         result = (Node *) list_nth(rexpr->args, maref->colno - 1);
    1639                 :             : 
    1640                 :             :         /*
    1641                 :             :          * If we're at the last column, delete the RowExpr from
    1642                 :             :          * p_multiassign_exprs; we don't need it anymore, and don't want it in
    1643                 :             :          * the finished UPDATE tlist.  We assume this is still the last entry
    1644                 :             :          * in p_multiassign_exprs.
    1645                 :             :          */
    1646         [ +  + ]:          60 :         if (maref->colno == maref->ncolumns)
    1647                 :          26 :             pstate->p_multiassign_exprs =
    1648                 :          26 :                 list_delete_last(pstate->p_multiassign_exprs);
    1649                 :             : 
    1650                 :          60 :         return result;
    1651                 :             :     }
    1652                 :             : 
    1653         [ #  # ]:           0 :     elog(ERROR, "unexpected expr type in multiassign list");
    1654                 :             :     return NULL;                /* keep compiler quiet */
    1655                 :             : }
    1656                 :             : 
    1657                 :             : static Node *
    1658                 :       25607 : transformCaseExpr(ParseState *pstate, CaseExpr *c)
    1659                 :             : {
    1660                 :       25607 :     CaseExpr   *newc = makeNode(CaseExpr);
    1661                 :       25607 :     Node       *last_srf = pstate->p_last_srf;
    1662                 :             :     Node       *arg;
    1663                 :             :     CaseTestExpr *placeholder;
    1664                 :             :     List       *newargs;
    1665                 :             :     List       *resultexprs;
    1666                 :             :     ListCell   *l;
    1667                 :             :     Node       *defresult;
    1668                 :             :     Oid         ptype;
    1669                 :             : 
    1670                 :             :     /* transform the test expression, if any */
    1671                 :       25607 :     arg = transformExprRecurse(pstate, (Node *) c->arg);
    1672                 :             : 
    1673                 :             :     /* generate placeholder for test expression */
    1674         [ +  + ]:       25607 :     if (arg)
    1675                 :             :     {
    1676                 :             :         /*
    1677                 :             :          * If test expression is an untyped literal, force it to text. We have
    1678                 :             :          * to do something now because we won't be able to do this coercion on
    1679                 :             :          * the placeholder.  This is not as flexible as what was done in 7.4
    1680                 :             :          * and before, but it's good enough to handle the sort of silly coding
    1681                 :             :          * commonly seen.
    1682                 :             :          */
    1683         [ +  + ]:        5101 :         if (exprType(arg) == UNKNOWNOID)
    1684                 :           4 :             arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
    1685                 :             : 
    1686                 :             :         /*
    1687                 :             :          * Run collation assignment on the test expression so that we know
    1688                 :             :          * what collation to mark the placeholder with.  In principle we could
    1689                 :             :          * leave it to parse_collate.c to do that later, but propagating the
    1690                 :             :          * result to the CaseTestExpr would be unnecessarily complicated.
    1691                 :             :          */
    1692                 :        5101 :         assign_expr_collations(pstate, arg);
    1693                 :             : 
    1694                 :        5101 :         placeholder = makeNode(CaseTestExpr);
    1695                 :        5101 :         placeholder->typeId = exprType(arg);
    1696                 :        5101 :         placeholder->typeMod = exprTypmod(arg);
    1697                 :        5101 :         placeholder->collation = exprCollation(arg);
    1698                 :             :     }
    1699                 :             :     else
    1700                 :       20506 :         placeholder = NULL;
    1701                 :             : 
    1702                 :       25607 :     newc->arg = (Expr *) arg;
    1703                 :             : 
    1704                 :             :     /* transform the list of arguments */
    1705                 :       25607 :     newargs = NIL;
    1706                 :       25607 :     resultexprs = NIL;
    1707   [ +  -  +  +  :       71519 :     foreach(l, c->args)
                   +  + ]
    1708                 :             :     {
    1709                 :       45912 :         CaseWhen   *w = lfirst_node(CaseWhen, l);
    1710                 :       45912 :         CaseWhen   *neww = makeNode(CaseWhen);
    1711                 :             :         Node       *warg;
    1712                 :             : 
    1713                 :       45912 :         warg = (Node *) w->expr;
    1714         [ +  + ]:       45912 :         if (placeholder)
    1715                 :             :         {
    1716                 :             :             /* shorthand form was specified, so expand... */
    1717                 :       18709 :             warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
    1718                 :             :                                              (Node *) placeholder,
    1719                 :             :                                              warg,
    1720                 :             :                                              w->location);
    1721                 :             :         }
    1722                 :       45912 :         neww->expr = (Expr *) transformExprRecurse(pstate, warg);
    1723                 :             : 
    1724                 :       91824 :         neww->expr = (Expr *) coerce_to_boolean(pstate,
    1725                 :       45912 :                                                 (Node *) neww->expr,
    1726                 :             :                                                 "CASE/WHEN");
    1727                 :             : 
    1728                 :       45912 :         warg = (Node *) w->result;
    1729                 :       45912 :         neww->result = (Expr *) transformExprRecurse(pstate, warg);
    1730                 :       45912 :         neww->location = w->location;
    1731                 :             : 
    1732                 :       45912 :         newargs = lappend(newargs, neww);
    1733                 :       45912 :         resultexprs = lappend(resultexprs, neww->result);
    1734                 :             :     }
    1735                 :             : 
    1736                 :       25607 :     newc->args = newargs;
    1737                 :             : 
    1738                 :             :     /* transform the default clause */
    1739                 :       25607 :     defresult = (Node *) c->defresult;
    1740         [ +  + ]:       25607 :     if (defresult == NULL)
    1741                 :             :     {
    1742                 :        6588 :         A_Const    *n = makeNode(A_Const);
    1743                 :             : 
    1744                 :        6588 :         n->isnull = true;
    1745                 :        6588 :         n->location = -1;
    1746                 :        6588 :         defresult = (Node *) n;
    1747                 :             :     }
    1748                 :       25607 :     newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
    1749                 :             : 
    1750                 :             :     /*
    1751                 :             :      * Note: default result is considered the most significant type in
    1752                 :             :      * determining preferred type. This is how the code worked before, but it
    1753                 :             :      * seems a little bogus to me --- tgl
    1754                 :             :      */
    1755                 :       25607 :     resultexprs = lcons(newc->defresult, resultexprs);
    1756                 :             : 
    1757                 :       25607 :     ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
    1758                 :             :     Assert(OidIsValid(ptype));
    1759                 :       25607 :     newc->casetype = ptype;
    1760                 :             :     /* casecollid will be set by parse_collate.c */
    1761                 :             : 
    1762                 :             :     /* Convert default result clause, if necessary */
    1763                 :       25607 :     newc->defresult = (Expr *)
    1764                 :       25607 :         coerce_to_common_type(pstate,
    1765                 :       25607 :                               (Node *) newc->defresult,
    1766                 :             :                               ptype,
    1767                 :             :                               "CASE/ELSE");
    1768                 :             : 
    1769                 :             :     /* Convert when-clause results, if necessary */
    1770   [ +  -  +  +  :       71519 :     foreach(l, newc->args)
                   +  + ]
    1771                 :             :     {
    1772                 :       45912 :         CaseWhen   *w = (CaseWhen *) lfirst(l);
    1773                 :             : 
    1774                 :       45912 :         w->result = (Expr *)
    1775                 :       45912 :             coerce_to_common_type(pstate,
    1776                 :       45912 :                                   (Node *) w->result,
    1777                 :             :                                   ptype,
    1778                 :             :                                   "CASE/WHEN");
    1779                 :             :     }
    1780                 :             : 
    1781                 :             :     /* if any subexpression contained a SRF, complain */
    1782         [ +  + ]:       25607 :     if (pstate->p_last_srf != last_srf)
    1783         [ +  - ]:           4 :         ereport(ERROR,
    1784                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1785                 :             :         /* translator: %s is name of a SQL construct, eg GROUP BY */
    1786                 :             :                  errmsg("set-returning functions are not allowed in %s",
    1787                 :             :                         "CASE"),
    1788                 :             :                  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
    1789                 :             :                  parser_errposition(pstate,
    1790                 :             :                                     exprLocation(pstate->p_last_srf))));
    1791                 :             : 
    1792                 :       25603 :     newc->location = c->location;
    1793                 :             : 
    1794                 :       25603 :     return (Node *) newc;
    1795                 :             : }
    1796                 :             : 
    1797                 :             : static Node *
    1798                 :       32092 : transformSubLink(ParseState *pstate, SubLink *sublink)
    1799                 :             : {
    1800                 :       32092 :     Node       *result = (Node *) sublink;
    1801                 :             :     Query      *qtree;
    1802                 :             :     const char *err;
    1803                 :             : 
    1804                 :             :     /*
    1805                 :             :      * Check to see if the sublink is in an invalid place within the query. We
    1806                 :             :      * allow sublinks everywhere in SELECT/INSERT/UPDATE/DELETE/MERGE, but
    1807                 :             :      * generally not in utility statements.
    1808                 :             :      */
    1809                 :       32092 :     err = NULL;
    1810   [ -  -  +  -  :       32092 :     switch (pstate->p_expr_kind)
          +  -  -  -  -  
          -  -  +  +  -  
             +  +  -  +  
                      - ]
    1811                 :             :     {
    1812                 :           0 :         case EXPR_KIND_NONE:
    1813                 :             :             Assert(false);      /* can't happen */
    1814                 :           0 :             break;
    1815                 :           0 :         case EXPR_KIND_OTHER:
    1816                 :             :             /* Accept sublink here; caller must throw error if wanted */
    1817                 :           0 :             break;
    1818                 :       32056 :         case EXPR_KIND_JOIN_ON:
    1819                 :             :         case EXPR_KIND_JOIN_USING:
    1820                 :             :         case EXPR_KIND_FROM_SUBSELECT:
    1821                 :             :         case EXPR_KIND_FROM_FUNCTION:
    1822                 :             :         case EXPR_KIND_WHERE:
    1823                 :             :         case EXPR_KIND_POLICY:
    1824                 :             :         case EXPR_KIND_HAVING:
    1825                 :             :         case EXPR_KIND_FILTER:
    1826                 :             :         case EXPR_KIND_WINDOW_PARTITION:
    1827                 :             :         case EXPR_KIND_WINDOW_ORDER:
    1828                 :             :         case EXPR_KIND_WINDOW_FRAME_RANGE:
    1829                 :             :         case EXPR_KIND_WINDOW_FRAME_ROWS:
    1830                 :             :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
    1831                 :             :         case EXPR_KIND_SELECT_TARGET:
    1832                 :             :         case EXPR_KIND_INSERT_TARGET:
    1833                 :             :         case EXPR_KIND_UPDATE_SOURCE:
    1834                 :             :         case EXPR_KIND_UPDATE_TARGET:
    1835                 :             :         case EXPR_KIND_MERGE_WHEN:
    1836                 :             :         case EXPR_KIND_GROUP_BY:
    1837                 :             :         case EXPR_KIND_ORDER_BY:
    1838                 :             :         case EXPR_KIND_DISTINCT_ON:
    1839                 :             :         case EXPR_KIND_LIMIT:
    1840                 :             :         case EXPR_KIND_OFFSET:
    1841                 :             :         case EXPR_KIND_RETURNING:
    1842                 :             :         case EXPR_KIND_MERGE_RETURNING:
    1843                 :             :         case EXPR_KIND_VALUES:
    1844                 :             :         case EXPR_KIND_VALUES_SINGLE:
    1845                 :             :         case EXPR_KIND_CYCLE_MARK:
    1846                 :             :             /* okay */
    1847                 :       32056 :             break;
    1848                 :           0 :         case EXPR_KIND_CHECK_CONSTRAINT:
    1849                 :             :         case EXPR_KIND_DOMAIN_CHECK:
    1850                 :           0 :             err = _("cannot use subquery in check constraint");
    1851                 :           0 :             break;
    1852                 :           4 :         case EXPR_KIND_COLUMN_DEFAULT:
    1853                 :             :         case EXPR_KIND_FUNCTION_DEFAULT:
    1854                 :           4 :             err = _("cannot use subquery in DEFAULT expression");
    1855                 :           4 :             break;
    1856                 :           0 :         case EXPR_KIND_INDEX_EXPRESSION:
    1857                 :           0 :             err = _("cannot use subquery in index expression");
    1858                 :           0 :             break;
    1859                 :           0 :         case EXPR_KIND_INDEX_PREDICATE:
    1860                 :           0 :             err = _("cannot use subquery in index predicate");
    1861                 :           0 :             break;
    1862                 :           0 :         case EXPR_KIND_STATS_EXPRESSION:
    1863                 :           0 :             err = _("cannot use subquery in statistics expression");
    1864                 :           0 :             break;
    1865                 :           0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
    1866                 :           0 :             err = _("cannot use subquery in transform expression");
    1867                 :           0 :             break;
    1868                 :           0 :         case EXPR_KIND_EXECUTE_PARAMETER:
    1869                 :           0 :             err = _("cannot use subquery in EXECUTE parameter");
    1870                 :           0 :             break;
    1871                 :           0 :         case EXPR_KIND_TRIGGER_WHEN:
    1872                 :           0 :             err = _("cannot use subquery in trigger WHEN condition");
    1873                 :           0 :             break;
    1874                 :           8 :         case EXPR_KIND_PARTITION_BOUND:
    1875                 :           8 :             err = _("cannot use subquery in partition bound");
    1876                 :           8 :             break;
    1877                 :           4 :         case EXPR_KIND_PARTITION_EXPRESSION:
    1878                 :           4 :             err = _("cannot use subquery in partition key expression");
    1879                 :           4 :             break;
    1880                 :           0 :         case EXPR_KIND_CALL_ARGUMENT:
    1881                 :           0 :             err = _("cannot use subquery in CALL argument");
    1882                 :           0 :             break;
    1883                 :           4 :         case EXPR_KIND_COPY_WHERE:
    1884                 :           4 :             err = _("cannot use subquery in COPY FROM WHERE condition");
    1885                 :           4 :             break;
    1886                 :           8 :         case EXPR_KIND_GENERATED_COLUMN:
    1887                 :           8 :             err = _("cannot use subquery in column generation expression");
    1888                 :           8 :             break;
    1889                 :           0 :         case EXPR_KIND_PROPGRAPH_PROPERTY:
    1890                 :           0 :             err = _("cannot use subquery in property definition expression");
    1891                 :           0 :             break;
    1892                 :           8 :         case EXPR_KIND_FOR_PORTION:
    1893                 :           8 :             err = _("cannot use subquery in FOR PORTION OF expression");
    1894                 :           8 :             break;
    1895                 :             : 
    1896                 :             :             /*
    1897                 :             :              * There is intentionally no default: case here, so that the
    1898                 :             :              * compiler will warn if we add a new ParseExprKind without
    1899                 :             :              * extending this switch.  If we do see an unrecognized value at
    1900                 :             :              * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
    1901                 :             :              * which is sane anyway.
    1902                 :             :              */
    1903                 :             :     }
    1904         [ +  + ]:       32092 :     if (err)
    1905         [ +  - ]:          36 :         ereport(ERROR,
    1906                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1907                 :             :                  errmsg_internal("%s", err),
    1908                 :             :                  parser_errposition(pstate, sublink->location)));
    1909                 :             : 
    1910                 :       32056 :     pstate->p_hasSubLinks = true;
    1911                 :             : 
    1912                 :             :     /*
    1913                 :             :      * OK, let's transform the sub-SELECT.
    1914                 :             :      */
    1915                 :       32056 :     qtree = parse_sub_analyze(sublink->subselect, pstate, NULL, false, true);
    1916                 :             : 
    1917                 :             :     /*
    1918                 :             :      * Check that we got a SELECT.  Anything else should be impossible given
    1919                 :             :      * restrictions of the grammar, but check anyway.
    1920                 :             :      */
    1921         [ +  - ]:       32024 :     if (!IsA(qtree, Query) ||
    1922         [ -  + ]:       32024 :         qtree->commandType != CMD_SELECT)
    1923         [ #  # ]:           0 :         elog(ERROR, "unexpected non-SELECT command in SubLink");
    1924                 :             : 
    1925                 :       32024 :     sublink->subselect = (Node *) qtree;
    1926                 :             : 
    1927         [ +  + ]:       32024 :     if (sublink->subLinkType == EXISTS_SUBLINK)
    1928                 :             :     {
    1929                 :             :         /*
    1930                 :             :          * EXISTS needs no test expression or combining operator. These fields
    1931                 :             :          * should be null already, but make sure.
    1932                 :             :          */
    1933                 :        5900 :         sublink->testexpr = NULL;
    1934                 :        5900 :         sublink->operName = NIL;
    1935                 :             :     }
    1936         [ +  + ]:       26124 :     else if (sublink->subLinkType == EXPR_SUBLINK ||
    1937         [ +  + ]:        9442 :              sublink->subLinkType == ARRAY_SUBLINK)
    1938                 :             :     {
    1939                 :             :         /*
    1940                 :             :          * Make sure the subselect delivers a single column (ignoring resjunk
    1941                 :             :          * targets).
    1942                 :             :          */
    1943         [ -  + ]:       22068 :         if (count_nonjunk_tlist_entries(qtree->targetList) != 1)
    1944         [ #  # ]:           0 :             ereport(ERROR,
    1945                 :             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    1946                 :             :                      errmsg("subquery must return only one column"),
    1947                 :             :                      parser_errposition(pstate, sublink->location)));
    1948                 :             : 
    1949                 :             :         /*
    1950                 :             :          * EXPR and ARRAY need no test expression or combining operator. These
    1951                 :             :          * fields should be null already, but make sure.
    1952                 :             :          */
    1953                 :       22068 :         sublink->testexpr = NULL;
    1954                 :       22068 :         sublink->operName = NIL;
    1955                 :             :     }
    1956         [ +  + ]:        4056 :     else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
    1957                 :             :     {
    1958                 :             :         /* Same as EXPR case, except no restriction on number of columns */
    1959                 :          91 :         sublink->testexpr = NULL;
    1960                 :          91 :         sublink->operName = NIL;
    1961                 :             :     }
    1962                 :             :     else
    1963                 :             :     {
    1964                 :             :         /* ALL, ANY, or ROWCOMPARE: generate row-comparing expression */
    1965                 :             :         Node       *lefthand;
    1966                 :             :         List       *left_list;
    1967                 :             :         List       *right_list;
    1968                 :             :         ListCell   *l;
    1969                 :             : 
    1970                 :             :         /*
    1971                 :             :          * If the source was "x IN (select)", convert to "x = ANY (select)".
    1972                 :             :          */
    1973         [ +  + ]:        3965 :         if (sublink->operName == NIL)
    1974                 :        3821 :             sublink->operName = list_make1(makeString("="));
    1975                 :             : 
    1976                 :             :         /*
    1977                 :             :          * Transform lefthand expression, and convert to a list
    1978                 :             :          */
    1979                 :        3965 :         lefthand = transformExprRecurse(pstate, sublink->testexpr);
    1980   [ +  -  +  + ]:        3965 :         if (lefthand && IsA(lefthand, RowExpr))
    1981                 :         219 :             left_list = ((RowExpr *) lefthand)->args;
    1982                 :             :         else
    1983                 :        3746 :             left_list = list_make1(lefthand);
    1984                 :             : 
    1985                 :             :         /*
    1986                 :             :          * Build a list of PARAM_SUBLINK nodes representing the output columns
    1987                 :             :          * of the subquery.
    1988                 :             :          */
    1989                 :        3965 :         right_list = NIL;
    1990   [ +  -  +  +  :        8263 :         foreach(l, qtree->targetList)
                   +  + ]
    1991                 :             :         {
    1992                 :        4298 :             TargetEntry *tent = (TargetEntry *) lfirst(l);
    1993                 :             :             Param      *param;
    1994                 :             : 
    1995         [ +  + ]:        4298 :             if (tent->resjunk)
    1996                 :          12 :                 continue;
    1997                 :             : 
    1998                 :        4286 :             param = makeNode(Param);
    1999                 :        4286 :             param->paramkind = PARAM_SUBLINK;
    2000                 :        4286 :             param->paramid = tent->resno;
    2001                 :        4286 :             param->paramtype = exprType((Node *) tent->expr);
    2002                 :        4286 :             param->paramtypmod = exprTypmod((Node *) tent->expr);
    2003                 :        4286 :             param->paramcollid = exprCollation((Node *) tent->expr);
    2004                 :        4286 :             param->location = -1;
    2005                 :             : 
    2006                 :        4286 :             right_list = lappend(right_list, param);
    2007                 :             :         }
    2008                 :             : 
    2009                 :             :         /*
    2010                 :             :          * We could rely on make_row_comparison_op to complain if the list
    2011                 :             :          * lengths differ, but we prefer to generate a more specific error
    2012                 :             :          * message.
    2013                 :             :          */
    2014         [ -  + ]:        3965 :         if (list_length(left_list) < list_length(right_list))
    2015         [ #  # ]:           0 :             ereport(ERROR,
    2016                 :             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2017                 :             :                      errmsg("subquery has too many columns"),
    2018                 :             :                      parser_errposition(pstate, sublink->location)));
    2019         [ -  + ]:        3965 :         if (list_length(left_list) > list_length(right_list))
    2020         [ #  # ]:           0 :             ereport(ERROR,
    2021                 :             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2022                 :             :                      errmsg("subquery has too few columns"),
    2023                 :             :                      parser_errposition(pstate, sublink->location)));
    2024                 :             : 
    2025                 :             :         /*
    2026                 :             :          * Identify the combining operator(s) and generate a suitable
    2027                 :             :          * row-comparison expression.
    2028                 :             :          */
    2029                 :        3965 :         sublink->testexpr = make_row_comparison_op(pstate,
    2030                 :             :                                                    sublink->operName,
    2031                 :             :                                                    left_list,
    2032                 :             :                                                    right_list,
    2033                 :             :                                                    sublink->location);
    2034                 :             :     }
    2035                 :             : 
    2036                 :       32016 :     return result;
    2037                 :             : }
    2038                 :             : 
    2039                 :             : /*
    2040                 :             :  * transformArrayExpr
    2041                 :             :  *
    2042                 :             :  * If the caller specifies the target type, the resulting array will
    2043                 :             :  * be of exactly that type.  Otherwise we try to infer a common type
    2044                 :             :  * for the elements using select_common_type().
    2045                 :             :  */
    2046                 :             : static Node *
    2047                 :        5672 : transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
    2048                 :             :                    Oid array_type, Oid element_type, int32 typmod)
    2049                 :             : {
    2050                 :        5672 :     ArrayExpr  *newa = makeNode(ArrayExpr);
    2051                 :        5672 :     List       *newelems = NIL;
    2052                 :        5672 :     List       *newcoercedelems = NIL;
    2053                 :             :     ListCell   *element;
    2054                 :             :     Oid         coerce_type;
    2055                 :             :     bool        coerce_hard;
    2056                 :             : 
    2057                 :             :     /*
    2058                 :             :      * Transform the element expressions
    2059                 :             :      *
    2060                 :             :      * Assume that the array is one-dimensional unless we find an array-type
    2061                 :             :      * element expression.
    2062                 :             :      */
    2063                 :        5672 :     newa->multidims = false;
    2064   [ +  +  +  +  :       18781 :     foreach(element, a->elements)
                   +  + ]
    2065                 :             :     {
    2066                 :       13109 :         Node       *e = (Node *) lfirst(element);
    2067                 :             :         Node       *newe;
    2068                 :             : 
    2069                 :             :         /*
    2070                 :             :          * If an element is itself an A_ArrayExpr, recurse directly so that we
    2071                 :             :          * can pass down any target type we were given.
    2072                 :             :          */
    2073         [ +  + ]:       13109 :         if (IsA(e, A_ArrayExpr))
    2074                 :             :         {
    2075                 :         519 :             newe = transformArrayExpr(pstate,
    2076                 :             :                                       (A_ArrayExpr *) e,
    2077                 :             :                                       array_type,
    2078                 :             :                                       element_type,
    2079                 :             :                                       typmod);
    2080                 :             :             /* we certainly have an array here */
    2081                 :             :             Assert(array_type == InvalidOid || array_type == exprType(newe));
    2082                 :         519 :             newa->multidims = true;
    2083                 :             :         }
    2084                 :             :         else
    2085                 :             :         {
    2086                 :       12590 :             newe = transformExprRecurse(pstate, e);
    2087                 :             : 
    2088                 :             :             /*
    2089                 :             :              * Check for sub-array expressions, if we haven't already found
    2090                 :             :              * one.  Note we don't accept domain-over-array as a sub-array,
    2091                 :             :              * nor int2vector nor oidvector; those have constraints that don't
    2092                 :             :              * map well to being treated as a sub-array.
    2093                 :             :              */
    2094         [ +  - ]:       12590 :             if (!newa->multidims)
    2095                 :             :             {
    2096                 :       12590 :                 Oid         newetype = exprType(newe);
    2097                 :             : 
    2098   [ +  +  +  +  :       25148 :                 if (newetype != INT2VECTOROID && newetype != OIDVECTOROID &&
                   +  + ]
    2099                 :       12558 :                     type_is_array(newetype))
    2100                 :           4 :                     newa->multidims = true;
    2101                 :             :             }
    2102                 :             :         }
    2103                 :             : 
    2104                 :       13109 :         newelems = lappend(newelems, newe);
    2105                 :             :     }
    2106                 :             : 
    2107                 :             :     /*
    2108                 :             :      * Select a target type for the elements.
    2109                 :             :      *
    2110                 :             :      * If we haven't been given a target array type, we must try to deduce a
    2111                 :             :      * common type based on the types of the individual elements present.
    2112                 :             :      */
    2113         [ +  + ]:        5672 :     if (OidIsValid(array_type))
    2114                 :             :     {
    2115                 :             :         /* Caller must ensure array_type matches element_type */
    2116                 :             :         Assert(OidIsValid(element_type));
    2117         [ +  + ]:         543 :         coerce_type = (newa->multidims ? array_type : element_type);
    2118                 :         543 :         coerce_hard = true;
    2119                 :             :     }
    2120                 :             :     else
    2121                 :             :     {
    2122                 :             :         /* Can't handle an empty array without a target type */
    2123         [ +  + ]:        5129 :         if (newelems == NIL)
    2124         [ +  - ]:           4 :             ereport(ERROR,
    2125                 :             :                     (errcode(ERRCODE_INDETERMINATE_DATATYPE),
    2126                 :             :                      errmsg("cannot determine type of empty array"),
    2127                 :             :                      errhint("Explicitly cast to the desired type, "
    2128                 :             :                              "for example ARRAY[]::integer[]."),
    2129                 :             :                      parser_errposition(pstate, a->location)));
    2130                 :             : 
    2131                 :             :         /* Select a common type for the elements */
    2132                 :        5125 :         coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
    2133                 :             : 
    2134         [ +  + ]:        5125 :         if (newa->multidims)
    2135                 :             :         {
    2136                 :         250 :             array_type = coerce_type;
    2137                 :         250 :             element_type = get_element_type(array_type);
    2138         [ -  + ]:         250 :             if (!OidIsValid(element_type))
    2139         [ #  # ]:           0 :                 ereport(ERROR,
    2140                 :             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2141                 :             :                          errmsg("could not find element type for data type %s",
    2142                 :             :                                 format_type_be(array_type)),
    2143                 :             :                          parser_errposition(pstate, a->location)));
    2144                 :             :         }
    2145                 :             :         else
    2146                 :             :         {
    2147                 :        4875 :             element_type = coerce_type;
    2148                 :        4875 :             array_type = get_array_type(element_type);
    2149         [ -  + ]:        4875 :             if (!OidIsValid(array_type))
    2150         [ #  # ]:           0 :                 ereport(ERROR,
    2151                 :             :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    2152                 :             :                          errmsg("could not find array type for data type %s",
    2153                 :             :                                 format_type_be(element_type)),
    2154                 :             :                          parser_errposition(pstate, a->location)));
    2155                 :             :         }
    2156                 :        5125 :         coerce_hard = false;
    2157                 :             :     }
    2158                 :             : 
    2159                 :             :     /*
    2160                 :             :      * Coerce elements to target type
    2161                 :             :      *
    2162                 :             :      * If the array has been explicitly cast, then the elements are in turn
    2163                 :             :      * explicitly coerced.
    2164                 :             :      *
    2165                 :             :      * If the array's type was merely derived from the common type of its
    2166                 :             :      * elements, then the elements are implicitly coerced to the common type.
    2167                 :             :      * This is consistent with other uses of select_common_type().
    2168                 :             :      */
    2169   [ +  +  +  +  :       18777 :     foreach(element, newelems)
                   +  + ]
    2170                 :             :     {
    2171                 :       13109 :         Node       *e = (Node *) lfirst(element);
    2172                 :             :         Node       *newe;
    2173                 :             : 
    2174         [ +  + ]:       13109 :         if (coerce_hard)
    2175                 :             :         {
    2176                 :        1301 :             newe = coerce_to_target_type(pstate, e,
    2177                 :             :                                          exprType(e),
    2178                 :             :                                          coerce_type,
    2179                 :             :                                          typmod,
    2180                 :             :                                          COERCION_EXPLICIT,
    2181                 :             :                                          COERCE_EXPLICIT_CAST,
    2182                 :             :                                          -1);
    2183         [ -  + ]:        1301 :             if (newe == NULL)
    2184         [ #  # ]:           0 :                 ereport(ERROR,
    2185                 :             :                         (errcode(ERRCODE_CANNOT_COERCE),
    2186                 :             :                          errmsg("cannot cast type %s to %s",
    2187                 :             :                                 format_type_be(exprType(e)),
    2188                 :             :                                 format_type_be(coerce_type)),
    2189                 :             :                          parser_errposition(pstate, exprLocation(e))));
    2190                 :             :         }
    2191                 :             :         else
    2192                 :       11808 :             newe = coerce_to_common_type(pstate, e,
    2193                 :             :                                          coerce_type,
    2194                 :             :                                          "ARRAY");
    2195                 :       13109 :         newcoercedelems = lappend(newcoercedelems, newe);
    2196                 :             :     }
    2197                 :             : 
    2198                 :        5668 :     newa->array_typeid = array_type;
    2199                 :             :     /* array_collid will be set by parse_collate.c */
    2200                 :        5668 :     newa->element_typeid = element_type;
    2201                 :        5668 :     newa->elements = newcoercedelems;
    2202                 :        5668 :     newa->list_start = a->list_start;
    2203                 :        5668 :     newa->list_end = a->list_end;
    2204                 :        5668 :     newa->location = a->location;
    2205                 :             : 
    2206                 :        5668 :     return (Node *) newa;
    2207                 :             : }
    2208                 :             : 
    2209                 :             : static Node *
    2210                 :        3923 : transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
    2211                 :             : {
    2212                 :             :     RowExpr    *newr;
    2213                 :             :     char        fname[16];
    2214                 :             :     int         fnum;
    2215                 :             : 
    2216                 :        3923 :     newr = makeNode(RowExpr);
    2217                 :             : 
    2218                 :             :     /* Transform the field expressions */
    2219                 :        3923 :     newr->args = transformExpressionList(pstate, r->args,
    2220                 :             :                                          pstate->p_expr_kind, allowDefault);
    2221                 :             : 
    2222                 :             :     /* Disallow more columns than will fit in a tuple */
    2223         [ -  + ]:        3923 :     if (list_length(newr->args) > MaxTupleAttributeNumber)
    2224         [ #  # ]:           0 :         ereport(ERROR,
    2225                 :             :                 (errcode(ERRCODE_TOO_MANY_COLUMNS),
    2226                 :             :                  errmsg("ROW expressions can have at most %d entries",
    2227                 :             :                         MaxTupleAttributeNumber),
    2228                 :             :                  parser_errposition(pstate, r->location)));
    2229                 :             : 
    2230                 :             :     /* Barring later casting, we consider the type RECORD */
    2231                 :        3923 :     newr->row_typeid = RECORDOID;
    2232                 :        3923 :     newr->row_format = COERCE_IMPLICIT_CAST;
    2233                 :             : 
    2234                 :             :     /* ROW() has anonymous columns, so invent some field names */
    2235                 :        3923 :     newr->colnames = NIL;
    2236         [ +  + ]:       13503 :     for (fnum = 1; fnum <= list_length(newr->args); fnum++)
    2237                 :             :     {
    2238                 :        9580 :         snprintf(fname, sizeof(fname), "f%d", fnum);
    2239                 :        9580 :         newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname)));
    2240                 :             :     }
    2241                 :             : 
    2242                 :        3923 :     newr->location = r->location;
    2243                 :             : 
    2244                 :        3923 :     return (Node *) newr;
    2245                 :             : }
    2246                 :             : 
    2247                 :             : static Node *
    2248                 :        2163 : transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
    2249                 :             : {
    2250                 :        2163 :     CoalesceExpr *newc = makeNode(CoalesceExpr);
    2251                 :        2163 :     Node       *last_srf = pstate->p_last_srf;
    2252                 :        2163 :     List       *newargs = NIL;
    2253                 :        2163 :     List       *newcoercedargs = NIL;
    2254                 :             :     ListCell   *args;
    2255                 :             : 
    2256   [ +  -  +  +  :        6493 :     foreach(args, c->args)
                   +  + ]
    2257                 :             :     {
    2258                 :        4330 :         Node       *e = (Node *) lfirst(args);
    2259                 :             :         Node       *newe;
    2260                 :             : 
    2261                 :        4330 :         newe = transformExprRecurse(pstate, e);
    2262                 :        4330 :         newargs = lappend(newargs, newe);
    2263                 :             :     }
    2264                 :             : 
    2265                 :        2163 :     newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
    2266                 :             :     /* coalescecollid will be set by parse_collate.c */
    2267                 :             : 
    2268                 :             :     /* Convert arguments if necessary */
    2269   [ +  -  +  +  :        6493 :     foreach(args, newargs)
                   +  + ]
    2270                 :             :     {
    2271                 :        4330 :         Node       *e = (Node *) lfirst(args);
    2272                 :             :         Node       *newe;
    2273                 :             : 
    2274                 :        4330 :         newe = coerce_to_common_type(pstate, e,
    2275                 :             :                                      newc->coalescetype,
    2276                 :             :                                      "COALESCE");
    2277                 :        4330 :         newcoercedargs = lappend(newcoercedargs, newe);
    2278                 :             :     }
    2279                 :             : 
    2280                 :             :     /* if any subexpression contained a SRF, complain */
    2281         [ +  + ]:        2163 :     if (pstate->p_last_srf != last_srf)
    2282         [ +  - ]:           4 :         ereport(ERROR,
    2283                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2284                 :             :         /* translator: %s is name of a SQL construct, eg GROUP BY */
    2285                 :             :                  errmsg("set-returning functions are not allowed in %s",
    2286                 :             :                         "COALESCE"),
    2287                 :             :                  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
    2288                 :             :                  parser_errposition(pstate,
    2289                 :             :                                     exprLocation(pstate->p_last_srf))));
    2290                 :             : 
    2291                 :        2159 :     newc->args = newcoercedargs;
    2292                 :        2159 :     newc->location = c->location;
    2293                 :        2159 :     return (Node *) newc;
    2294                 :             : }
    2295                 :             : 
    2296                 :             : static Node *
    2297                 :         189 : transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
    2298                 :             : {
    2299                 :         189 :     MinMaxExpr *newm = makeNode(MinMaxExpr);
    2300                 :         189 :     List       *newargs = NIL;
    2301                 :         189 :     List       *newcoercedargs = NIL;
    2302         [ +  + ]:         189 :     const char *funcname = (m->op == IS_GREATEST) ? "GREATEST" : "LEAST";
    2303                 :             :     ListCell   *args;
    2304                 :             : 
    2305                 :         189 :     newm->op = m->op;
    2306   [ +  -  +  +  :         603 :     foreach(args, m->args)
                   +  + ]
    2307                 :             :     {
    2308                 :         414 :         Node       *e = (Node *) lfirst(args);
    2309                 :             :         Node       *newe;
    2310                 :             : 
    2311                 :         414 :         newe = transformExprRecurse(pstate, e);
    2312                 :         414 :         newargs = lappend(newargs, newe);
    2313                 :             :     }
    2314                 :             : 
    2315                 :         189 :     newm->minmaxtype = select_common_type(pstate, newargs, funcname, NULL);
    2316                 :             :     /* minmaxcollid and inputcollid will be set by parse_collate.c */
    2317                 :             : 
    2318                 :             :     /* Convert arguments if necessary */
    2319   [ +  -  +  +  :         603 :     foreach(args, newargs)
                   +  + ]
    2320                 :             :     {
    2321                 :         414 :         Node       *e = (Node *) lfirst(args);
    2322                 :             :         Node       *newe;
    2323                 :             : 
    2324                 :         414 :         newe = coerce_to_common_type(pstate, e,
    2325                 :             :                                      newm->minmaxtype,
    2326                 :             :                                      funcname);
    2327                 :         414 :         newcoercedargs = lappend(newcoercedargs, newe);
    2328                 :             :     }
    2329                 :             : 
    2330                 :         189 :     newm->args = newcoercedargs;
    2331                 :         189 :     newm->location = m->location;
    2332                 :         189 :     return (Node *) newm;
    2333                 :             : }
    2334                 :             : 
    2335                 :             : static Node *
    2336                 :        1647 : transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
    2337                 :             : {
    2338                 :             :     /*
    2339                 :             :      * All we need to do is insert the correct result type and (where needed)
    2340                 :             :      * validate the typmod, so we just modify the node in-place.
    2341                 :             :      */
    2342   [ +  +  +  +  :        1647 :     switch (svf->op)
          +  +  +  +  +  
                   +  - ]
    2343                 :             :     {
    2344                 :         211 :         case SVFOP_CURRENT_DATE:
    2345                 :         211 :             svf->type = DATEOID;
    2346                 :         211 :             break;
    2347                 :          16 :         case SVFOP_CURRENT_TIME:
    2348                 :          16 :             svf->type = TIMETZOID;
    2349                 :          16 :             break;
    2350                 :          16 :         case SVFOP_CURRENT_TIME_N:
    2351                 :          16 :             svf->type = TIMETZOID;
    2352                 :          16 :             svf->typmod = anytime_typmod_check(true, svf->typmod);
    2353                 :          16 :             break;
    2354                 :         151 :         case SVFOP_CURRENT_TIMESTAMP:
    2355                 :         151 :             svf->type = TIMESTAMPTZOID;
    2356                 :         151 :             break;
    2357                 :         107 :         case SVFOP_CURRENT_TIMESTAMP_N:
    2358                 :         107 :             svf->type = TIMESTAMPTZOID;
    2359                 :         107 :             svf->typmod = anytimestamp_typmod_check(true, svf->typmod);
    2360                 :         107 :             break;
    2361                 :          16 :         case SVFOP_LOCALTIME:
    2362                 :          16 :             svf->type = TIMEOID;
    2363                 :          16 :             break;
    2364                 :          16 :         case SVFOP_LOCALTIME_N:
    2365                 :          16 :             svf->type = TIMEOID;
    2366                 :          16 :             svf->typmod = anytime_typmod_check(false, svf->typmod);
    2367                 :          16 :             break;
    2368                 :          24 :         case SVFOP_LOCALTIMESTAMP:
    2369                 :          24 :             svf->type = TIMESTAMPOID;
    2370                 :          24 :             break;
    2371                 :          16 :         case SVFOP_LOCALTIMESTAMP_N:
    2372                 :          16 :             svf->type = TIMESTAMPOID;
    2373                 :          16 :             svf->typmod = anytimestamp_typmod_check(false, svf->typmod);
    2374                 :          16 :             break;
    2375                 :        1074 :         case SVFOP_CURRENT_ROLE:
    2376                 :             :         case SVFOP_CURRENT_USER:
    2377                 :             :         case SVFOP_USER:
    2378                 :             :         case SVFOP_SESSION_USER:
    2379                 :             :         case SVFOP_CURRENT_CATALOG:
    2380                 :             :         case SVFOP_CURRENT_SCHEMA:
    2381                 :        1074 :             svf->type = NAMEOID;
    2382                 :        1074 :             break;
    2383                 :             :     }
    2384                 :             : 
    2385                 :        1647 :     return (Node *) svf;
    2386                 :             : }
    2387                 :             : 
    2388                 :             : static Node *
    2389                 :         396 : transformXmlExpr(ParseState *pstate, XmlExpr *x)
    2390                 :             : {
    2391                 :             :     XmlExpr    *newx;
    2392                 :             :     ListCell   *lc;
    2393                 :             :     int         i;
    2394                 :             : 
    2395                 :         396 :     newx = makeNode(XmlExpr);
    2396                 :         396 :     newx->op = x->op;
    2397         [ +  + ]:         396 :     if (x->name)
    2398                 :         171 :         newx->name = map_sql_identifier_to_xml_name(x->name, false, false);
    2399                 :             :     else
    2400                 :         225 :         newx->name = NULL;
    2401                 :         396 :     newx->xmloption = x->xmloption;
    2402                 :         396 :     newx->type = XMLOID;     /* this just marks the node as transformed */
    2403                 :         396 :     newx->typmod = -1;
    2404                 :         396 :     newx->location = x->location;
    2405                 :             : 
    2406                 :             :     /*
    2407                 :             :      * gram.y built the named args as a list of ResTarget.  Transform each,
    2408                 :             :      * and break the names out as a separate list.
    2409                 :             :      */
    2410                 :         396 :     newx->named_args = NIL;
    2411                 :         396 :     newx->arg_names = NIL;
    2412                 :             : 
    2413   [ +  +  +  +  :         541 :     foreach(lc, x->named_args)
                   +  + ]
    2414                 :             :     {
    2415                 :         153 :         ResTarget  *r = lfirst_node(ResTarget, lc);
    2416                 :             :         Node       *expr;
    2417                 :             :         char       *argname;
    2418                 :             : 
    2419                 :         153 :         expr = transformExprRecurse(pstate, r->val);
    2420                 :             : 
    2421         [ +  + ]:         153 :         if (r->name)
    2422                 :          69 :             argname = map_sql_identifier_to_xml_name(r->name, false, false);
    2423         [ +  + ]:          84 :         else if (IsA(r->val, ColumnRef))
    2424                 :          80 :             argname = map_sql_identifier_to_xml_name(FigureColname(r->val),
    2425                 :             :                                                      true, false);
    2426                 :             :         else
    2427                 :             :         {
    2428   [ +  -  +  - ]:           4 :             ereport(ERROR,
    2429                 :             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2430                 :             :                      x->op == IS_XMLELEMENT
    2431                 :             :                      ? errmsg("unnamed XML attribute value must be a column reference")
    2432                 :             :                      : errmsg("unnamed XML element value must be a column reference"),
    2433                 :             :                      parser_errposition(pstate, r->location)));
    2434                 :             :             argname = NULL;     /* keep compiler quiet */
    2435                 :             :         }
    2436                 :             : 
    2437                 :             :         /* reject duplicate argnames in XMLELEMENT only */
    2438         [ +  + ]:         149 :         if (x->op == IS_XMLELEMENT)
    2439                 :             :         {
    2440                 :             :             ListCell   *lc2;
    2441                 :             : 
    2442   [ +  +  +  +  :          79 :             foreach(lc2, newx->arg_names)
                   +  + ]
    2443                 :             :             {
    2444         [ +  + ]:          25 :                 if (strcmp(argname, strVal(lfirst(lc2))) == 0)
    2445         [ +  - ]:           4 :                     ereport(ERROR,
    2446                 :             :                             (errcode(ERRCODE_SYNTAX_ERROR),
    2447                 :             :                              errmsg("XML attribute name \"%s\" appears more than once",
    2448                 :             :                                     argname),
    2449                 :             :                              parser_errposition(pstate, r->location)));
    2450                 :             :             }
    2451                 :             :         }
    2452                 :             : 
    2453                 :         145 :         newx->named_args = lappend(newx->named_args, expr);
    2454                 :         145 :         newx->arg_names = lappend(newx->arg_names, makeString(argname));
    2455                 :             :     }
    2456                 :             : 
    2457                 :             :     /* The other arguments are of varying types depending on the function */
    2458                 :         388 :     newx->args = NIL;
    2459                 :         388 :     i = 0;
    2460   [ +  +  +  +  :         932 :     foreach(lc, x->args)
                   +  + ]
    2461                 :             :     {
    2462                 :         556 :         Node       *e = (Node *) lfirst(lc);
    2463                 :             :         Node       *newe;
    2464                 :             : 
    2465                 :         556 :         newe = transformExprRecurse(pstate, e);
    2466   [ +  +  -  +  :         556 :         switch (x->op)
             +  +  -  +  
                      - ]
    2467                 :             :         {
    2468                 :          88 :             case IS_XMLCONCAT:
    2469                 :          88 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2470                 :             :                                                "XMLCONCAT");
    2471                 :          80 :                 break;
    2472                 :          90 :             case IS_XMLELEMENT:
    2473                 :             :                 /* no coercion necessary */
    2474                 :          90 :                 break;
    2475                 :           0 :             case IS_XMLFOREST:
    2476                 :           0 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2477                 :             :                                                "XMLFOREST");
    2478                 :           0 :                 break;
    2479                 :         186 :             case IS_XMLPARSE:
    2480         [ +  + ]:         186 :                 if (i == 0)
    2481                 :          93 :                     newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2482                 :             :                                                    "XMLPARSE");
    2483                 :             :                 else
    2484                 :          93 :                     newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
    2485                 :         186 :                 break;
    2486                 :          33 :             case IS_XMLPI:
    2487                 :          33 :                 newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2488                 :             :                                                "XMLPI");
    2489                 :          33 :                 break;
    2490                 :         135 :             case IS_XMLROOT:
    2491         [ +  + ]:         135 :                 if (i == 0)
    2492                 :          45 :                     newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2493                 :             :                                                    "XMLROOT");
    2494         [ +  + ]:          90 :                 else if (i == 1)
    2495                 :          45 :                     newe = coerce_to_specific_type(pstate, newe, TEXTOID,
    2496                 :             :                                                    "XMLROOT");
    2497                 :             :                 else
    2498                 :          45 :                     newe = coerce_to_specific_type(pstate, newe, INT4OID,
    2499                 :             :                                                    "XMLROOT");
    2500                 :         135 :                 break;
    2501                 :           0 :             case IS_XMLSERIALIZE:
    2502                 :             :                 /* not handled here */
    2503                 :             :                 Assert(false);
    2504                 :           0 :                 break;
    2505                 :          24 :             case IS_DOCUMENT:
    2506                 :          24 :                 newe = coerce_to_specific_type(pstate, newe, XMLOID,
    2507                 :             :                                                "IS DOCUMENT");
    2508                 :          20 :                 break;
    2509                 :             :         }
    2510                 :         544 :         newx->args = lappend(newx->args, newe);
    2511                 :         544 :         i++;
    2512                 :             :     }
    2513                 :             : 
    2514                 :         376 :     return (Node *) newx;
    2515                 :             : }
    2516                 :             : 
    2517                 :             : static Node *
    2518                 :         144 : transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
    2519                 :             : {
    2520                 :             :     Node       *result;
    2521                 :             :     XmlExpr    *xexpr;
    2522                 :             :     Oid         targetType;
    2523                 :             :     int32       targetTypmod;
    2524                 :             : 
    2525                 :         144 :     xexpr = makeNode(XmlExpr);
    2526                 :         144 :     xexpr->op = IS_XMLSERIALIZE;
    2527                 :         144 :     xexpr->args = list_make1(coerce_to_specific_type(pstate,
    2528                 :             :                                                      transformExprRecurse(pstate, xs->expr),
    2529                 :             :                                                      XMLOID,
    2530                 :             :                                                      "XMLSERIALIZE"));
    2531                 :             : 
    2532                 :         144 :     typenameTypeIdAndMod(pstate, xs->typeName, &targetType, &targetTypmod);
    2533                 :             : 
    2534                 :         144 :     xexpr->xmloption = xs->xmloption;
    2535                 :         144 :     xexpr->indent = xs->indent;
    2536                 :         144 :     xexpr->location = xs->location;
    2537                 :             :     /* We actually only need these to be able to parse back the expression. */
    2538                 :         144 :     xexpr->type = targetType;
    2539                 :         144 :     xexpr->typmod = targetTypmod;
    2540                 :             : 
    2541                 :             :     /*
    2542                 :             :      * The actual target type is determined this way.  SQL allows char and
    2543                 :             :      * varchar as target types.  We allow anything that can be cast implicitly
    2544                 :             :      * from text.  This way, user-defined text-like data types automatically
    2545                 :             :      * fit in.
    2546                 :             :      */
    2547                 :         144 :     result = coerce_to_target_type(pstate, (Node *) xexpr,
    2548                 :             :                                    TEXTOID, targetType, targetTypmod,
    2549                 :             :                                    COERCION_IMPLICIT,
    2550                 :             :                                    COERCE_IMPLICIT_CAST,
    2551                 :             :                                    -1);
    2552         [ -  + ]:         144 :     if (result == NULL)
    2553         [ #  # ]:           0 :         ereport(ERROR,
    2554                 :             :                 (errcode(ERRCODE_CANNOT_COERCE),
    2555                 :             :                  errmsg("cannot cast XMLSERIALIZE result to %s",
    2556                 :             :                         format_type_be(targetType)),
    2557                 :             :                  parser_errposition(pstate, xexpr->location)));
    2558                 :         144 :     return result;
    2559                 :             : }
    2560                 :             : 
    2561                 :             : static Node *
    2562                 :         668 : transformBooleanTest(ParseState *pstate, BooleanTest *b)
    2563                 :             : {
    2564                 :             :     const char *clausename;
    2565                 :             : 
    2566   [ +  +  +  +  :         668 :     switch (b->booltesttype)
                +  +  - ]
    2567                 :             :     {
    2568                 :         261 :         case IS_TRUE:
    2569                 :         261 :             clausename = "IS TRUE";
    2570                 :         261 :             break;
    2571                 :         100 :         case IS_NOT_TRUE:
    2572                 :         100 :             clausename = "IS NOT TRUE";
    2573                 :         100 :             break;
    2574                 :         148 :         case IS_FALSE:
    2575                 :         148 :             clausename = "IS FALSE";
    2576                 :         148 :             break;
    2577                 :          69 :         case IS_NOT_FALSE:
    2578                 :          69 :             clausename = "IS NOT FALSE";
    2579                 :          69 :             break;
    2580                 :          50 :         case IS_UNKNOWN:
    2581                 :          50 :             clausename = "IS UNKNOWN";
    2582                 :          50 :             break;
    2583                 :          40 :         case IS_NOT_UNKNOWN:
    2584                 :          40 :             clausename = "IS NOT UNKNOWN";
    2585                 :          40 :             break;
    2586                 :           0 :         default:
    2587         [ #  # ]:           0 :             elog(ERROR, "unrecognized booltesttype: %d",
    2588                 :             :                  (int) b->booltesttype);
    2589                 :             :             clausename = NULL;  /* keep compiler quiet */
    2590                 :             :     }
    2591                 :             : 
    2592                 :         668 :     b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
    2593                 :             : 
    2594                 :        1336 :     b->arg = (Expr *) coerce_to_boolean(pstate,
    2595                 :         668 :                                         (Node *) b->arg,
    2596                 :             :                                         clausename);
    2597                 :             : 
    2598                 :         668 :     return (Node *) b;
    2599                 :             : }
    2600                 :             : 
    2601                 :             : static Node *
    2602                 :         172 : transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
    2603                 :             : {
    2604                 :             :     /* CURRENT OF can only appear at top level of UPDATE/DELETE */
    2605                 :             :     Assert(pstate->p_target_nsitem != NULL);
    2606                 :         172 :     cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
    2607                 :             : 
    2608                 :             :     /*
    2609                 :             :      * Check to see if the cursor name matches a parameter of type REFCURSOR.
    2610                 :             :      * If so, replace the raw name reference with a parameter reference. (This
    2611                 :             :      * is a hack for the convenience of plpgsql.)
    2612                 :             :      */
    2613         [ +  - ]:         172 :     if (cexpr->cursor_name != NULL) /* in case already transformed */
    2614                 :             :     {
    2615                 :         172 :         ColumnRef  *cref = makeNode(ColumnRef);
    2616                 :         172 :         Node       *node = NULL;
    2617                 :             : 
    2618                 :             :         /* Build an unqualified ColumnRef with the given name */
    2619                 :         172 :         cref->fields = list_make1(makeString(cexpr->cursor_name));
    2620                 :         172 :         cref->location = -1;
    2621                 :             : 
    2622                 :             :         /* See if there is a translation available from a parser hook */
    2623         [ +  + ]:         172 :         if (pstate->p_pre_columnref_hook != NULL)
    2624                 :           8 :             node = pstate->p_pre_columnref_hook(pstate, cref);
    2625   [ +  -  +  + ]:         172 :         if (node == NULL && pstate->p_post_columnref_hook != NULL)
    2626                 :           8 :             node = pstate->p_post_columnref_hook(pstate, cref, NULL);
    2627                 :             : 
    2628                 :             :         /*
    2629                 :             :          * XXX Should we throw an error if we get a translation that isn't a
    2630                 :             :          * refcursor Param?  For now it seems best to silently ignore false
    2631                 :             :          * matches.
    2632                 :             :          */
    2633   [ +  +  +  - ]:         172 :         if (node != NULL && IsA(node, Param))
    2634                 :             :         {
    2635                 :           8 :             Param      *p = (Param *) node;
    2636                 :             : 
    2637         [ +  - ]:           8 :             if (p->paramkind == PARAM_EXTERN &&
    2638         [ +  - ]:           8 :                 p->paramtype == REFCURSOROID)
    2639                 :             :             {
    2640                 :             :                 /* Matches, so convert CURRENT OF to a param reference */
    2641                 :           8 :                 cexpr->cursor_name = NULL;
    2642                 :           8 :                 cexpr->cursor_param = p->paramid;
    2643                 :             :             }
    2644                 :             :         }
    2645                 :             :     }
    2646                 :             : 
    2647                 :         172 :     return (Node *) cexpr;
    2648                 :             : }
    2649                 :             : 
    2650                 :             : /*
    2651                 :             :  * Construct a whole-row reference to represent the notation "relation.*".
    2652                 :             :  */
    2653                 :             : static Node *
    2654                 :        5598 : transformWholeRowRef(ParseState *pstate, ParseNamespaceItem *nsitem,
    2655                 :             :                      int sublevels_up, int location)
    2656                 :             : {
    2657                 :             :     /*
    2658                 :             :      * Build the appropriate referencing node.  Normally this can be a
    2659                 :             :      * whole-row Var, but if the nsitem is a JOIN USING alias then it contains
    2660                 :             :      * only a subset of the columns of the underlying join RTE, so that will
    2661                 :             :      * not work.  Instead we immediately expand the reference into a RowExpr.
    2662                 :             :      * Since the JOIN USING's common columns are fully determined at this
    2663                 :             :      * point, there seems no harm in expanding it now rather than during
    2664                 :             :      * planning.
    2665                 :             :      *
    2666                 :             :      * Note that if the nsitem is an OLD/NEW alias for the target RTE (as can
    2667                 :             :      * appear in a RETURNING list), its alias won't match the target RTE's
    2668                 :             :      * alias, but we still want to make a whole-row Var here rather than a
    2669                 :             :      * RowExpr, for consistency with direct references to the target RTE, and
    2670                 :             :      * so that any dropped columns are handled correctly.  Thus we also check
    2671                 :             :      * p_returning_type here.
    2672                 :             :      *
    2673                 :             :      * Note that if the RTE is a function returning scalar, we create just a
    2674                 :             :      * plain reference to the function value, not a composite containing a
    2675                 :             :      * single column.  This is pretty inconsistent at first sight, but it's
    2676                 :             :      * what we've done historically.  One argument for it is that "rel" and
    2677                 :             :      * "rel.*" mean the same thing for composite relations, so why not for
    2678                 :             :      * scalar functions...
    2679                 :             :      */
    2680         [ +  + ]:        5598 :     if (nsitem->p_names == nsitem->p_rte->eref ||
    2681         [ +  + ]:         290 :         nsitem->p_returning_type != VAR_RETURNING_DEFAULT)
    2682                 :             :     {
    2683                 :             :         Var        *result;
    2684                 :             : 
    2685                 :        5590 :         result = makeWholeRowVar(nsitem->p_rte, nsitem->p_rtindex,
    2686                 :             :                                  sublevels_up, true);
    2687                 :             : 
    2688                 :             :         /* mark Var for RETURNING OLD/NEW, as necessary */
    2689                 :        5590 :         result->varreturningtype = nsitem->p_returning_type;
    2690                 :             : 
    2691                 :             :         /* location is not filled in by makeWholeRowVar */
    2692                 :        5590 :         result->location = location;
    2693                 :             : 
    2694                 :             :         /* mark Var if it's nulled by any outer joins */
    2695                 :        5590 :         markNullableIfNeeded(pstate, result);
    2696                 :             : 
    2697                 :             :         /* mark relation as requiring whole-row SELECT access */
    2698                 :        5590 :         markVarForSelectPriv(pstate, result);
    2699                 :             : 
    2700                 :        5590 :         return (Node *) result;
    2701                 :             :     }
    2702                 :             :     else
    2703                 :             :     {
    2704                 :             :         RowExpr    *rowexpr;
    2705                 :             :         List       *fields;
    2706                 :             : 
    2707                 :             :         /*
    2708                 :             :          * We want only as many columns as are listed in p_names->colnames,
    2709                 :             :          * and we should use those names not whatever possibly-aliased names
    2710                 :             :          * are in the RTE.  We needn't worry about marking the RTE for SELECT
    2711                 :             :          * access, as the common columns are surely so marked already.
    2712                 :             :          */
    2713                 :           8 :         expandRTE(nsitem->p_rte, nsitem->p_rtindex, sublevels_up,
    2714                 :             :                   nsitem->p_returning_type, location, false, NULL, &fields);
    2715                 :           8 :         rowexpr = makeNode(RowExpr);
    2716                 :           8 :         rowexpr->args = list_truncate(fields,
    2717                 :           8 :                                       list_length(nsitem->p_names->colnames));
    2718                 :           8 :         rowexpr->row_typeid = RECORDOID;
    2719                 :           8 :         rowexpr->row_format = COERCE_IMPLICIT_CAST;
    2720                 :           8 :         rowexpr->colnames = copyObject(nsitem->p_names->colnames);
    2721                 :           8 :         rowexpr->location = location;
    2722                 :             : 
    2723                 :             :         /* XXX we ought to mark the row as possibly nullable */
    2724                 :             : 
    2725                 :           8 :         return (Node *) rowexpr;
    2726                 :             :     }
    2727                 :             : }
    2728                 :             : 
    2729                 :             : /*
    2730                 :             :  * Handle an explicit CAST construct.
    2731                 :             :  *
    2732                 :             :  * Transform the argument, look up the type name, and apply any necessary
    2733                 :             :  * coercion function(s).
    2734                 :             :  */
    2735                 :             : static Node *
    2736                 :      197289 : transformTypeCast(ParseState *pstate, TypeCast *tc)
    2737                 :             : {
    2738                 :             :     Node       *result;
    2739                 :      197289 :     Node       *arg = tc->arg;
    2740                 :             :     Node       *expr;
    2741                 :             :     Oid         inputType;
    2742                 :             :     Oid         targetType;
    2743                 :             :     int32       targetTypmod;
    2744                 :             :     int         location;
    2745                 :             : 
    2746                 :             :     /* Look up the type name first */
    2747                 :      197289 :     typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
    2748                 :             : 
    2749                 :             :     /*
    2750                 :             :      * If the subject of the typecast is an ARRAY[] construct and the target
    2751                 :             :      * type is an array type, we invoke transformArrayExpr() directly so that
    2752                 :             :      * we can pass down the type information.  This avoids some cases where
    2753                 :             :      * transformArrayExpr() might not infer the correct type.  Otherwise, just
    2754                 :             :      * transform the argument normally.
    2755                 :             :      */
    2756         [ +  + ]:      197289 :     if (IsA(arg, A_ArrayExpr))
    2757                 :             :     {
    2758                 :             :         Oid         targetBaseType;
    2759                 :             :         int32       targetBaseTypmod;
    2760                 :             :         Oid         elementType;
    2761                 :             : 
    2762                 :             :         /*
    2763                 :             :          * If target is a domain over array, work with the base array type
    2764                 :             :          * here.  Below, we'll cast the array type to the domain.  In the
    2765                 :             :          * usual case that the target is not a domain, the remaining steps
    2766                 :             :          * will be a no-op.
    2767                 :             :          */
    2768                 :         469 :         targetBaseTypmod = targetTypmod;
    2769                 :         469 :         targetBaseType = getBaseTypeAndTypmod(targetType, &targetBaseTypmod);
    2770                 :         469 :         elementType = get_element_type(targetBaseType);
    2771         [ +  + ]:         469 :         if (OidIsValid(elementType))
    2772                 :             :         {
    2773                 :         464 :             expr = transformArrayExpr(pstate,
    2774                 :             :                                       (A_ArrayExpr *) arg,
    2775                 :             :                                       targetBaseType,
    2776                 :             :                                       elementType,
    2777                 :             :                                       targetBaseTypmod);
    2778                 :             :         }
    2779                 :             :         else
    2780                 :           5 :             expr = transformExprRecurse(pstate, arg);
    2781                 :             :     }
    2782                 :             :     else
    2783                 :      196820 :         expr = transformExprRecurse(pstate, arg);
    2784                 :             : 
    2785                 :      197277 :     inputType = exprType(expr);
    2786         [ -  + ]:      197277 :     if (inputType == InvalidOid)
    2787                 :           0 :         return expr;            /* do nothing if NULL input */
    2788                 :             : 
    2789                 :             :     /*
    2790                 :             :      * Location of the coercion is preferentially the location of the :: or
    2791                 :             :      * CAST symbol, but if there is none then use the location of the type
    2792                 :             :      * name (this can happen in TypeName 'string' syntax, for instance).
    2793                 :             :      */
    2794                 :      197277 :     location = tc->location;
    2795         [ +  + ]:      197277 :     if (location < 0)
    2796                 :       11169 :         location = tc->typeName->location;
    2797                 :             : 
    2798                 :      197277 :     result = coerce_to_target_type(pstate, expr, inputType,
    2799                 :             :                                    targetType, targetTypmod,
    2800                 :             :                                    COERCION_EXPLICIT,
    2801                 :             :                                    COERCE_EXPLICIT_CAST,
    2802                 :             :                                    location);
    2803         [ +  + ]:      194701 :     if (result == NULL)
    2804         [ +  - ]:          18 :         ereport(ERROR,
    2805                 :             :                 (errcode(ERRCODE_CANNOT_COERCE),
    2806                 :             :                  errmsg("cannot cast type %s to %s",
    2807                 :             :                         format_type_be(inputType),
    2808                 :             :                         format_type_be(targetType)),
    2809                 :             :                  parser_coercion_errposition(pstate, location, expr)));
    2810                 :             : 
    2811                 :      194683 :     return result;
    2812                 :             : }
    2813                 :             : 
    2814                 :             : /*
    2815                 :             :  * Handle an explicit COLLATE clause.
    2816                 :             :  *
    2817                 :             :  * Transform the argument, and look up the collation name.
    2818                 :             :  */
    2819                 :             : static Node *
    2820                 :        6844 : transformCollateClause(ParseState *pstate, CollateClause *c)
    2821                 :             : {
    2822                 :             :     CollateExpr *newc;
    2823                 :             :     Oid         argtype;
    2824                 :             : 
    2825                 :        6844 :     newc = makeNode(CollateExpr);
    2826                 :        6844 :     newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
    2827                 :             : 
    2828                 :        6844 :     argtype = exprType((Node *) newc->arg);
    2829                 :             : 
    2830                 :             :     /*
    2831                 :             :      * The unknown type is not collatable, but coerce_type() takes care of it
    2832                 :             :      * separately, so we'll let it go here.
    2833                 :             :      */
    2834   [ +  +  +  + ]:        6844 :     if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
    2835         [ +  - ]:          12 :         ereport(ERROR,
    2836                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    2837                 :             :                  errmsg("collations are not supported by type %s",
    2838                 :             :                         format_type_be(argtype)),
    2839                 :             :                  parser_errposition(pstate, c->location)));
    2840                 :             : 
    2841                 :        6832 :     newc->collOid = LookupCollation(pstate, c->collname, c->location);
    2842                 :        6832 :     newc->location = c->location;
    2843                 :             : 
    2844                 :        6832 :     return (Node *) newc;
    2845                 :             : }
    2846                 :             : 
    2847                 :             : /*
    2848                 :             :  * Transform a "row compare-op row" construct
    2849                 :             :  *
    2850                 :             :  * The inputs are lists of already-transformed expressions.
    2851                 :             :  * As with coerce_type, pstate may be NULL if no special unknown-Param
    2852                 :             :  * processing is wanted.
    2853                 :             :  *
    2854                 :             :  * The output may be a single OpExpr, an AND or OR combination of OpExprs,
    2855                 :             :  * or a RowCompareExpr.  In all cases it is guaranteed to return boolean.
    2856                 :             :  * The AND, OR, and RowCompareExpr cases further imply things about the
    2857                 :             :  * behavior of the operators (ie, they behave as =, <>, or < <= > >=).
    2858                 :             :  */
    2859                 :             : static Node *
    2860                 :        4535 : make_row_comparison_op(ParseState *pstate, List *opname,
    2861                 :             :                        List *largs, List *rargs, int location)
    2862                 :             : {
    2863                 :             :     RowCompareExpr *rcexpr;
    2864                 :             :     CompareType cmptype;
    2865                 :             :     List       *opexprs;
    2866                 :             :     List       *opnos;
    2867                 :             :     List       *opfamilies;
    2868                 :             :     ListCell   *l,
    2869                 :             :                *r;
    2870                 :             :     List      **opinfo_lists;
    2871                 :             :     Bitmapset  *cmptypes;
    2872                 :             :     int         nopers;
    2873                 :             :     int         i;
    2874                 :             : 
    2875                 :        4535 :     nopers = list_length(largs);
    2876         [ -  + ]:        4535 :     if (nopers != list_length(rargs))
    2877         [ #  # ]:           0 :         ereport(ERROR,
    2878                 :             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    2879                 :             :                  errmsg("unequal number of entries in row expressions"),
    2880                 :             :                  parser_errposition(pstate, location)));
    2881                 :             : 
    2882                 :             :     /*
    2883                 :             :      * We can't compare zero-length rows because there is no principled basis
    2884                 :             :      * for figuring out what the operator is.
    2885                 :             :      */
    2886         [ +  + ]:        4535 :     if (nopers == 0)
    2887         [ +  - ]:           4 :         ereport(ERROR,
    2888                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2889                 :             :                  errmsg("cannot compare rows of zero length"),
    2890                 :             :                  parser_errposition(pstate, location)));
    2891                 :             : 
    2892                 :             :     /*
    2893                 :             :      * Identify all the pairwise operators, using make_op so that behavior is
    2894                 :             :      * the same as in the simple scalar case.
    2895                 :             :      */
    2896                 :        4531 :     opexprs = NIL;
    2897   [ +  -  +  +  :        9985 :     forboth(l, largs, r, rargs)
          +  -  +  +  +  
             +  +  -  +  
                      + ]
    2898                 :             :     {
    2899                 :        5462 :         Node       *larg = (Node *) lfirst(l);
    2900                 :        5462 :         Node       *rarg = (Node *) lfirst(r);
    2901                 :             :         OpExpr     *cmp;
    2902                 :             : 
    2903                 :        5462 :         cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg,
    2904                 :             :                                        pstate->p_last_srf, location));
    2905                 :             : 
    2906                 :             :         /*
    2907                 :             :          * We don't use coerce_to_boolean here because we insist on the
    2908                 :             :          * operator yielding boolean directly, not via coercion.  If it
    2909                 :             :          * doesn't yield bool it won't be in any index opfamilies...
    2910                 :             :          */
    2911         [ -  + ]:        5454 :         if (cmp->opresulttype != BOOLOID)
    2912         [ #  # ]:           0 :             ereport(ERROR,
    2913                 :             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2914                 :             :                      errmsg("row comparison operator must yield type boolean, "
    2915                 :             :                             "not type %s",
    2916                 :             :                             format_type_be(cmp->opresulttype)),
    2917                 :             :                      parser_errposition(pstate, location)));
    2918         [ -  + ]:        5454 :         if (expression_returns_set((Node *) cmp))
    2919         [ #  # ]:           0 :             ereport(ERROR,
    2920                 :             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    2921                 :             :                      errmsg("row comparison operator must not return a set"),
    2922                 :             :                      parser_errposition(pstate, location)));
    2923                 :        5454 :         opexprs = lappend(opexprs, cmp);
    2924                 :             :     }
    2925                 :             : 
    2926                 :             :     /*
    2927                 :             :      * If rows are length 1, just return the single operator.  In this case we
    2928                 :             :      * don't insist on identifying btree semantics for the operator (but we
    2929                 :             :      * still require it to return boolean).
    2930                 :             :      */
    2931         [ +  + ]:        4523 :     if (nopers == 1)
    2932                 :        3750 :         return (Node *) linitial(opexprs);
    2933                 :             : 
    2934                 :             :     /*
    2935                 :             :      * Now we must determine which row comparison semantics (= <> < <= > >=)
    2936                 :             :      * apply to this set of operators.  We look for opfamilies containing the
    2937                 :             :      * operators, and see which interpretations (cmptypes) exist for each
    2938                 :             :      * operator.
    2939                 :             :      */
    2940                 :         773 :     opinfo_lists = palloc_array(List *, nopers);
    2941                 :         773 :     cmptypes = NULL;
    2942                 :         773 :     i = 0;
    2943   [ +  -  +  +  :        2477 :     foreach(l, opexprs)
                   +  + ]
    2944                 :             :     {
    2945                 :        1704 :         Oid         opno = ((OpExpr *) lfirst(l))->opno;
    2946                 :             :         Bitmapset  *this_cmptypes;
    2947                 :             :         ListCell   *j;
    2948                 :             : 
    2949                 :        1704 :         opinfo_lists[i] = get_op_index_interpretation(opno);
    2950                 :             : 
    2951                 :             :         /*
    2952                 :             :          * convert comparison types into a Bitmapset to make the intersection
    2953                 :             :          * calculation easy.
    2954                 :             :          */
    2955                 :        1704 :         this_cmptypes = NULL;
    2956   [ +  +  +  +  :        3503 :         foreach(j, opinfo_lists[i])
                   +  + ]
    2957                 :             :         {
    2958                 :        1799 :             OpIndexInterpretation *opinfo = lfirst(j);
    2959                 :             : 
    2960                 :        1799 :             this_cmptypes = bms_add_member(this_cmptypes, opinfo->cmptype);
    2961                 :             :         }
    2962         [ +  + ]:        1704 :         if (i == 0)
    2963                 :         773 :             cmptypes = this_cmptypes;
    2964                 :             :         else
    2965                 :         931 :             cmptypes = bms_int_members(cmptypes, this_cmptypes);
    2966                 :        1704 :         i++;
    2967                 :             :     }
    2968                 :             : 
    2969                 :             :     /*
    2970                 :             :      * If there are multiple common interpretations, we may use any one of
    2971                 :             :      * them ... this coding arbitrarily picks the lowest comparison type
    2972                 :             :      * number.
    2973                 :             :      */
    2974                 :         773 :     i = bms_next_member(cmptypes, -1);
    2975         [ +  + ]:         773 :     if (i < 0)
    2976                 :             :     {
    2977                 :             :         /* No common interpretation, so fail */
    2978         [ +  - ]:           4 :         ereport(ERROR,
    2979                 :             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2980                 :             :                  errmsg("could not determine interpretation of row comparison operator %s",
    2981                 :             :                         strVal(llast(opname))),
    2982                 :             :                  errhint("Row comparison operators must be associated with btree operator families."),
    2983                 :             :                  parser_errposition(pstate, location)));
    2984                 :             :     }
    2985                 :         769 :     cmptype = (CompareType) i;
    2986                 :             : 
    2987                 :             :     /*
    2988                 :             :      * For = and <> cases, we just combine the pairwise operators with AND or
    2989                 :             :      * OR respectively.
    2990                 :             :      */
    2991         [ +  + ]:         769 :     if (cmptype == COMPARE_EQ)
    2992                 :         294 :         return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
    2993         [ +  + ]:         475 :     if (cmptype == COMPARE_NE)
    2994                 :         283 :         return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
    2995                 :             : 
    2996                 :             :     /*
    2997                 :             :      * Otherwise we need to choose exactly which opfamily to associate with
    2998                 :             :      * each operator.
    2999                 :             :      */
    3000                 :         192 :     opfamilies = NIL;
    3001         [ +  + ]:         612 :     for (i = 0; i < nopers; i++)
    3002                 :             :     {
    3003                 :         420 :         Oid         opfamily = InvalidOid;
    3004                 :             :         ListCell   *j;
    3005                 :             : 
    3006   [ +  -  +  -  :         420 :         foreach(j, opinfo_lists[i])
                   +  - ]
    3007                 :             :         {
    3008                 :         420 :             OpIndexInterpretation *opinfo = lfirst(j);
    3009                 :             : 
    3010         [ +  - ]:         420 :             if (opinfo->cmptype == cmptype)
    3011                 :             :             {
    3012                 :         420 :                 opfamily = opinfo->opfamily_id;
    3013                 :         420 :                 break;
    3014                 :             :             }
    3015                 :             :         }
    3016         [ +  - ]:         420 :         if (OidIsValid(opfamily))
    3017                 :         420 :             opfamilies = lappend_oid(opfamilies, opfamily);
    3018                 :             :         else                    /* should not happen */
    3019         [ #  # ]:           0 :             ereport(ERROR,
    3020                 :             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3021                 :             :                      errmsg("could not determine interpretation of row comparison operator %s",
    3022                 :             :                             strVal(llast(opname))),
    3023                 :             :                      errdetail("There are multiple equally-plausible candidates."),
    3024                 :             :                      parser_errposition(pstate, location)));
    3025                 :             :     }
    3026                 :             : 
    3027                 :             :     /*
    3028                 :             :      * Now deconstruct the OpExprs and create a RowCompareExpr.
    3029                 :             :      *
    3030                 :             :      * Note: can't just reuse the passed largs/rargs lists, because of
    3031                 :             :      * possibility that make_op inserted coercion operations.
    3032                 :             :      */
    3033                 :         192 :     opnos = NIL;
    3034                 :         192 :     largs = NIL;
    3035                 :         192 :     rargs = NIL;
    3036   [ +  -  +  +  :         612 :     foreach(l, opexprs)
                   +  + ]
    3037                 :             :     {
    3038                 :         420 :         OpExpr     *cmp = (OpExpr *) lfirst(l);
    3039                 :             : 
    3040                 :         420 :         opnos = lappend_oid(opnos, cmp->opno);
    3041                 :         420 :         largs = lappend(largs, linitial(cmp->args));
    3042                 :         420 :         rargs = lappend(rargs, lsecond(cmp->args));
    3043                 :             :     }
    3044                 :             : 
    3045                 :         192 :     rcexpr = makeNode(RowCompareExpr);
    3046                 :         192 :     rcexpr->cmptype = cmptype;
    3047                 :         192 :     rcexpr->opnos = opnos;
    3048                 :         192 :     rcexpr->opfamilies = opfamilies;
    3049                 :         192 :     rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
    3050                 :         192 :     rcexpr->largs = largs;
    3051                 :         192 :     rcexpr->rargs = rargs;
    3052                 :             : 
    3053                 :         192 :     return (Node *) rcexpr;
    3054                 :             : }
    3055                 :             : 
    3056                 :             : /*
    3057                 :             :  * Transform a "row IS DISTINCT FROM row" construct
    3058                 :             :  *
    3059                 :             :  * The input RowExprs are already transformed
    3060                 :             :  */
    3061                 :             : static Node *
    3062                 :           4 : make_row_distinct_op(ParseState *pstate, List *opname,
    3063                 :             :                      RowExpr *lrow, RowExpr *rrow,
    3064                 :             :                      int location)
    3065                 :             : {
    3066                 :           4 :     Node       *result = NULL;
    3067                 :           4 :     List       *largs = lrow->args;
    3068                 :           4 :     List       *rargs = rrow->args;
    3069                 :             :     ListCell   *l,
    3070                 :             :                *r;
    3071                 :             : 
    3072         [ -  + ]:           4 :     if (list_length(largs) != list_length(rargs))
    3073         [ #  # ]:           0 :         ereport(ERROR,
    3074                 :             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    3075                 :             :                  errmsg("unequal number of entries in row expressions"),
    3076                 :             :                  parser_errposition(pstate, location)));
    3077                 :             : 
    3078   [ +  -  +  +  :          16 :     forboth(l, largs, r, rargs)
          +  -  +  +  +  
             +  +  -  +  
                      + ]
    3079                 :             :     {
    3080                 :          12 :         Node       *larg = (Node *) lfirst(l);
    3081                 :          12 :         Node       *rarg = (Node *) lfirst(r);
    3082                 :             :         Node       *cmp;
    3083                 :             : 
    3084                 :          12 :         cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
    3085         [ +  + ]:          12 :         if (result == NULL)
    3086                 :           4 :             result = cmp;
    3087                 :             :         else
    3088                 :           8 :             result = (Node *) makeBoolExpr(OR_EXPR,
    3089                 :             :                                            list_make2(result, cmp),
    3090                 :             :                                            location);
    3091                 :             :     }
    3092                 :             : 
    3093         [ -  + ]:           4 :     if (result == NULL)
    3094                 :             :     {
    3095                 :             :         /* zero-length rows?  Generate constant FALSE */
    3096                 :           0 :         result = makeBoolConst(false, false);
    3097                 :             :     }
    3098                 :             : 
    3099                 :           4 :     return result;
    3100                 :             : }
    3101                 :             : 
    3102                 :             : /*
    3103                 :             :  * make the node for an IS DISTINCT FROM operator
    3104                 :             :  */
    3105                 :             : static Expr *
    3106                 :         710 : make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
    3107                 :             :                  int location)
    3108                 :             : {
    3109                 :             :     Expr       *result;
    3110                 :             : 
    3111                 :         710 :     result = make_op(pstate, opname, ltree, rtree,
    3112                 :             :                      pstate->p_last_srf, location);
    3113         [ -  + ]:         710 :     if (((OpExpr *) result)->opresulttype != BOOLOID)
    3114         [ #  # ]:           0 :         ereport(ERROR,
    3115                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3116                 :             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    3117                 :             :                  errmsg("%s requires = operator to yield boolean",
    3118                 :             :                         "IS DISTINCT FROM"),
    3119                 :             :                  parser_errposition(pstate, location)));
    3120         [ -  + ]:         710 :     if (((OpExpr *) result)->opretset)
    3121         [ #  # ]:           0 :         ereport(ERROR,
    3122                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3123                 :             :         /* translator: %s is name of a SQL construct, eg NULLIF */
    3124                 :             :                  errmsg("%s must not return a set", "IS DISTINCT FROM"),
    3125                 :             :                  parser_errposition(pstate, location)));
    3126                 :             : 
    3127                 :             :     /*
    3128                 :             :      * We rely on DistinctExpr and OpExpr being same struct
    3129                 :             :      */
    3130                 :         710 :     NodeSetTag(result, T_DistinctExpr);
    3131                 :             : 
    3132                 :         710 :     return result;
    3133                 :             : }
    3134                 :             : 
    3135                 :             : /*
    3136                 :             :  * Produce a NullTest node from an IS [NOT] DISTINCT FROM NULL construct
    3137                 :             :  *
    3138                 :             :  * "arg" is the untransformed other argument
    3139                 :             :  */
    3140                 :             : static Node *
    3141                 :          20 : make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
    3142                 :             : {
    3143                 :          20 :     NullTest   *nt = makeNode(NullTest);
    3144                 :             : 
    3145                 :          20 :     nt->arg = (Expr *) transformExprRecurse(pstate, arg);
    3146                 :             :     /* the argument can be any type, so don't coerce it */
    3147         [ +  + ]:          20 :     if (distincta->kind == AEXPR_NOT_DISTINCT)
    3148                 :           8 :         nt->nulltesttype = IS_NULL;
    3149                 :             :     else
    3150                 :          12 :         nt->nulltesttype = IS_NOT_NULL;
    3151                 :             :     /* argisrow = false is correct whether or not arg is composite */
    3152                 :          20 :     nt->argisrow = false;
    3153                 :          20 :     nt->location = distincta->location;
    3154                 :          20 :     return (Node *) nt;
    3155                 :             : }
    3156                 :             : 
    3157                 :             : /*
    3158                 :             :  * Produce a string identifying an expression by kind.
    3159                 :             :  *
    3160                 :             :  * Note: when practical, use a simple SQL keyword for the result.  If that
    3161                 :             :  * doesn't work well, check call sites to see whether custom error message
    3162                 :             :  * strings are required.
    3163                 :             :  */
    3164                 :             : const char *
    3165                 :          52 : ParseExprKindName(ParseExprKind exprKind)
    3166                 :             : {
    3167   [ -  -  -  -  :          52 :     switch (exprKind)
          -  -  +  -  -  
          +  -  -  -  -  
          -  -  -  +  -  
          +  -  -  +  -  
          +  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  - ]
    3168                 :             :     {
    3169                 :           0 :         case EXPR_KIND_NONE:
    3170                 :           0 :             return "invalid expression context";
    3171                 :           0 :         case EXPR_KIND_OTHER:
    3172                 :           0 :             return "extension expression";
    3173                 :           0 :         case EXPR_KIND_JOIN_ON:
    3174                 :           0 :             return "JOIN/ON";
    3175                 :           0 :         case EXPR_KIND_JOIN_USING:
    3176                 :           0 :             return "JOIN/USING";
    3177                 :           0 :         case EXPR_KIND_FROM_SUBSELECT:
    3178                 :           0 :             return "sub-SELECT in FROM";
    3179                 :           0 :         case EXPR_KIND_FROM_FUNCTION:
    3180                 :           0 :             return "function in FROM";
    3181                 :          16 :         case EXPR_KIND_WHERE:
    3182                 :          16 :             return "WHERE";
    3183                 :           0 :         case EXPR_KIND_POLICY:
    3184                 :           0 :             return "POLICY";
    3185                 :           0 :         case EXPR_KIND_HAVING:
    3186                 :           0 :             return "HAVING";
    3187                 :           8 :         case EXPR_KIND_FILTER:
    3188                 :           8 :             return "FILTER";
    3189                 :           0 :         case EXPR_KIND_WINDOW_PARTITION:
    3190                 :           0 :             return "window PARTITION BY";
    3191                 :           0 :         case EXPR_KIND_WINDOW_ORDER:
    3192                 :           0 :             return "window ORDER BY";
    3193                 :           0 :         case EXPR_KIND_WINDOW_FRAME_RANGE:
    3194                 :           0 :             return "window RANGE";
    3195                 :           0 :         case EXPR_KIND_WINDOW_FRAME_ROWS:
    3196                 :           0 :             return "window ROWS";
    3197                 :           0 :         case EXPR_KIND_WINDOW_FRAME_GROUPS:
    3198                 :           0 :             return "window GROUPS";
    3199                 :           0 :         case EXPR_KIND_SELECT_TARGET:
    3200                 :           0 :             return "SELECT";
    3201                 :           0 :         case EXPR_KIND_INSERT_TARGET:
    3202                 :           0 :             return "INSERT";
    3203                 :           4 :         case EXPR_KIND_UPDATE_SOURCE:
    3204                 :             :         case EXPR_KIND_UPDATE_TARGET:
    3205                 :           4 :             return "UPDATE";
    3206                 :           0 :         case EXPR_KIND_MERGE_WHEN:
    3207                 :           0 :             return "MERGE WHEN";
    3208                 :           8 :         case EXPR_KIND_GROUP_BY:
    3209                 :           8 :             return "GROUP BY";
    3210                 :           0 :         case EXPR_KIND_ORDER_BY:
    3211                 :           0 :             return "ORDER BY";
    3212                 :           0 :         case EXPR_KIND_DISTINCT_ON:
    3213                 :           0 :             return "DISTINCT ON";
    3214                 :           4 :         case EXPR_KIND_LIMIT:
    3215                 :           4 :             return "LIMIT";
    3216                 :           0 :         case EXPR_KIND_OFFSET:
    3217                 :           0 :             return "OFFSET";
    3218                 :           8 :         case EXPR_KIND_RETURNING:
    3219                 :             :         case EXPR_KIND_MERGE_RETURNING:
    3220                 :           8 :             return "RETURNING";
    3221                 :           4 :         case EXPR_KIND_VALUES:
    3222                 :             :         case EXPR_KIND_VALUES_SINGLE:
    3223                 :           4 :             return "VALUES";
    3224                 :           0 :         case EXPR_KIND_CHECK_CONSTRAINT:
    3225                 :             :         case EXPR_KIND_DOMAIN_CHECK:
    3226                 :           0 :             return "CHECK";
    3227                 :           0 :         case EXPR_KIND_COLUMN_DEFAULT:
    3228                 :             :         case EXPR_KIND_FUNCTION_DEFAULT:
    3229                 :           0 :             return "DEFAULT";
    3230                 :           0 :         case EXPR_KIND_INDEX_EXPRESSION:
    3231                 :           0 :             return "index expression";
    3232                 :           0 :         case EXPR_KIND_INDEX_PREDICATE:
    3233                 :           0 :             return "index predicate";
    3234                 :           0 :         case EXPR_KIND_STATS_EXPRESSION:
    3235                 :           0 :             return "statistics expression";
    3236                 :           0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
    3237                 :           0 :             return "USING";
    3238                 :           0 :         case EXPR_KIND_EXECUTE_PARAMETER:
    3239                 :           0 :             return "EXECUTE";
    3240                 :           0 :         case EXPR_KIND_TRIGGER_WHEN:
    3241                 :           0 :             return "WHEN";
    3242                 :           0 :         case EXPR_KIND_PARTITION_BOUND:
    3243                 :           0 :             return "partition bound";
    3244                 :           0 :         case EXPR_KIND_PARTITION_EXPRESSION:
    3245                 :           0 :             return "PARTITION BY";
    3246                 :           0 :         case EXPR_KIND_CALL_ARGUMENT:
    3247                 :           0 :             return "CALL";
    3248                 :           0 :         case EXPR_KIND_COPY_WHERE:
    3249                 :           0 :             return "WHERE";
    3250                 :           0 :         case EXPR_KIND_GENERATED_COLUMN:
    3251                 :           0 :             return "GENERATED AS";
    3252                 :           0 :         case EXPR_KIND_CYCLE_MARK:
    3253                 :           0 :             return "CYCLE";
    3254                 :           0 :         case EXPR_KIND_PROPGRAPH_PROPERTY:
    3255                 :           0 :             return "property definition expression";
    3256                 :           0 :         case EXPR_KIND_FOR_PORTION:
    3257                 :           0 :             return "FOR PORTION OF";
    3258                 :             : 
    3259                 :             :             /*
    3260                 :             :              * There is intentionally no default: case here, so that the
    3261                 :             :              * compiler will warn if we add a new ParseExprKind without
    3262                 :             :              * extending this switch.  If we do see an unrecognized value at
    3263                 :             :              * runtime, we'll fall through to the "unrecognized" return.
    3264                 :             :              */
    3265                 :             :     }
    3266                 :           0 :     return "unrecognized expression kind";
    3267                 :             : }
    3268                 :             : 
    3269                 :             : /*
    3270                 :             :  * Make string Const node from JSON encoding name.
    3271                 :             :  *
    3272                 :             :  * UTF8 is default encoding.
    3273                 :             :  */
    3274                 :             : static Const *
    3275                 :         136 : getJsonEncodingConst(JsonFormat *format)
    3276                 :             : {
    3277                 :             :     JsonEncoding encoding;
    3278                 :             :     const char *enc;
    3279                 :         136 :     Name        encname = palloc_object(NameData);
    3280                 :             : 
    3281         [ +  - ]:         136 :     if (!format ||
    3282         [ +  + ]:         136 :         format->format_type == JS_FORMAT_DEFAULT ||
    3283         [ +  + ]:          88 :         format->encoding == JS_ENC_DEFAULT)
    3284                 :         120 :         encoding = JS_ENC_UTF8;
    3285                 :             :     else
    3286                 :          16 :         encoding = format->encoding;
    3287                 :             : 
    3288   [ -  -  +  - ]:         136 :     switch (encoding)
    3289                 :             :     {
    3290                 :           0 :         case JS_ENC_UTF16:
    3291                 :           0 :             enc = "UTF16";
    3292                 :           0 :             break;
    3293                 :           0 :         case JS_ENC_UTF32:
    3294                 :           0 :             enc = "UTF32";
    3295                 :           0 :             break;
    3296                 :         136 :         case JS_ENC_UTF8:
    3297                 :         136 :             enc = "UTF8";
    3298                 :         136 :             break;
    3299                 :           0 :         default:
    3300         [ #  # ]:           0 :             elog(ERROR, "invalid JSON encoding: %d", encoding);
    3301                 :             :             break;
    3302                 :             :     }
    3303                 :             : 
    3304                 :         136 :     namestrcpy(encname, enc);
    3305                 :             : 
    3306                 :         136 :     return makeConst(NAMEOID, -1, InvalidOid, NAMEDATALEN,
    3307                 :             :                      NameGetDatum(encname), false, false);
    3308                 :             : }
    3309                 :             : 
    3310                 :             : /*
    3311                 :             :  * Make bytea => text conversion using specified JSON format encoding.
    3312                 :             :  */
    3313                 :             : static Node *
    3314                 :          96 : makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
    3315                 :             : {
    3316                 :          96 :     Const      *encoding = getJsonEncodingConst(format);
    3317                 :          96 :     FuncExpr   *fexpr = makeFuncExpr(F_CONVERT_FROM, TEXTOID,
    3318                 :             :                                      list_make2(expr, encoding),
    3319                 :             :                                      InvalidOid, InvalidOid,
    3320                 :             :                                      COERCE_EXPLICIT_CALL);
    3321                 :             : 
    3322                 :          96 :     fexpr->location = location;
    3323                 :             : 
    3324                 :          96 :     return (Node *) fexpr;
    3325                 :             : }
    3326                 :             : 
    3327                 :             : /*
    3328                 :             :  * Transform JSON value expression using specified input JSON format or
    3329                 :             :  * default format otherwise, coercing to the targettype if needed.
    3330                 :             :  *
    3331                 :             :  * Returned expression is either ve->raw_expr coerced to text (if needed) or
    3332                 :             :  * a JsonValueExpr with formatted_expr set to the coerced copy of raw_expr
    3333                 :             :  * if the specified format and the targettype requires it.
    3334                 :             :  */
    3335                 :             : static Node *
    3336                 :        4130 : transformJsonValueExpr(ParseState *pstate, const char *constructName,
    3337                 :             :                        JsonValueExpr *ve, JsonFormatType default_format,
    3338                 :             :                        Oid targettype, bool isarg)
    3339                 :             : {
    3340                 :        4130 :     Node       *expr = transformExprRecurse(pstate, (Node *) ve->raw_expr);
    3341                 :             :     Node       *rawexpr;
    3342                 :             :     JsonFormatType format;
    3343                 :             :     Oid         exprtype;
    3344                 :             :     int         location;
    3345                 :             :     char        typcategory;
    3346                 :             :     bool        typispreferred;
    3347                 :             : 
    3348         [ +  + ]:        4130 :     if (exprType(expr) == UNKNOWNOID)
    3349                 :         480 :         expr = coerce_to_specific_type(pstate, expr, TEXTOID, constructName);
    3350                 :             : 
    3351                 :        4130 :     rawexpr = expr;
    3352                 :        4130 :     exprtype = exprType(expr);
    3353                 :        4130 :     location = exprLocation(expr);
    3354                 :             : 
    3355                 :        4130 :     get_type_category_preferred(exprtype, &typcategory, &typispreferred);
    3356                 :             : 
    3357         [ +  + ]:        4130 :     if (ve->format->format_type != JS_FORMAT_DEFAULT)
    3358                 :             :     {
    3359   [ +  +  +  + ]:         162 :         if (ve->format->encoding != JS_ENC_DEFAULT && exprtype != BYTEAOID)
    3360         [ +  - ]:          18 :             ereport(ERROR,
    3361                 :             :                     errcode(ERRCODE_DATATYPE_MISMATCH),
    3362                 :             :                     errmsg("JSON ENCODING clause is only allowed for bytea input type"),
    3363                 :             :                     parser_errposition(pstate, ve->format->location));
    3364                 :             : 
    3365   [ +  +  +  + ]:         144 :         if (exprtype == JSONOID || exprtype == JSONBOID)
    3366                 :           8 :             format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
    3367                 :             :         else
    3368                 :         136 :             format = ve->format->format_type;
    3369                 :             :     }
    3370         [ +  + ]:        3968 :     else if (isarg)
    3371                 :             :     {
    3372                 :             :         /*
    3373                 :             :          * Special treatment for PASSING arguments.
    3374                 :             :          *
    3375                 :             :          * Pass types supported by GetJsonPathVar() / JsonItemFromDatum()
    3376                 :             :          * directly without converting to json[b].
    3377                 :             :          */
    3378         [ +  + ]:         800 :         switch (exprtype)
    3379                 :             :         {
    3380                 :         620 :             case BOOLOID:
    3381                 :             :             case NUMERICOID:
    3382                 :             :             case INT2OID:
    3383                 :             :             case INT4OID:
    3384                 :             :             case INT8OID:
    3385                 :             :             case FLOAT4OID:
    3386                 :             :             case FLOAT8OID:
    3387                 :             :             case TEXTOID:
    3388                 :             :             case VARCHAROID:
    3389                 :             :             case DATEOID:
    3390                 :             :             case TIMEOID:
    3391                 :             :             case TIMETZOID:
    3392                 :             :             case TIMESTAMPOID:
    3393                 :             :             case TIMESTAMPTZOID:
    3394                 :         620 :                 return expr;
    3395                 :             : 
    3396                 :         180 :             default:
    3397         [ -  + ]:         180 :                 if (typcategory == TYPCATEGORY_STRING)
    3398                 :           0 :                     return expr;
    3399                 :             :                 /* else convert argument to json[b] type */
    3400                 :         180 :                 break;
    3401                 :             :         }
    3402                 :             : 
    3403                 :         180 :         format = default_format;
    3404                 :             :     }
    3405   [ +  +  +  + ]:        3168 :     else if (exprtype == JSONOID || exprtype == JSONBOID)
    3406                 :        2044 :         format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
    3407                 :             :     else
    3408                 :        1124 :         format = default_format;
    3409                 :             : 
    3410   [ +  +  +  + ]:        3492 :     if (format != JS_FORMAT_DEFAULT ||
    3411         [ +  + ]:        2046 :         (OidIsValid(targettype) && exprtype != targettype))
    3412                 :             :     {
    3413                 :             :         Node       *coerced;
    3414                 :         532 :         bool        only_allow_cast = OidIsValid(targettype);
    3415                 :             : 
    3416                 :             :         /*
    3417                 :             :          * PASSING args are handled appropriately by GetJsonPathVar() /
    3418                 :             :          * JsonItemFromDatum().
    3419                 :             :          */
    3420         [ +  + ]:         532 :         if (!isarg &&
    3421   [ +  +  +  + ]:         352 :             !only_allow_cast &&
    3422         [ +  + ]:         130 :             exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
    3423   [ +  -  -  +  :           4 :             ereport(ERROR,
                   +  - ]
    3424                 :             :                     errcode(ERRCODE_DATATYPE_MISMATCH),
    3425                 :             :                     ve->format->format_type == JS_FORMAT_DEFAULT ?
    3426                 :             :                     errmsg("cannot use non-string types with implicit FORMAT JSON clause") :
    3427                 :             :                     errmsg("cannot use non-string types with explicit FORMAT JSON clause"),
    3428                 :             :                     parser_errposition(pstate, ve->format->location >= 0 ?
    3429                 :             :                                        ve->format->location : location));
    3430                 :             : 
    3431                 :             :         /* Convert encoded JSON text from bytea. */
    3432   [ +  +  +  + ]:         528 :         if (format == JS_FORMAT_JSON && exprtype == BYTEAOID)
    3433                 :             :         {
    3434                 :          48 :             expr = makeJsonByteaToTextConversion(expr, ve->format, location);
    3435                 :          48 :             exprtype = TEXTOID;
    3436                 :             :         }
    3437                 :             : 
    3438         [ +  + ]:         528 :         if (!OidIsValid(targettype))
    3439         [ +  + ]:         342 :             targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
    3440                 :             : 
    3441                 :             :         /* Try to coerce to the target type. */
    3442                 :         528 :         coerced = coerce_to_target_type(pstate, expr, exprtype,
    3443                 :             :                                         targettype, -1,
    3444                 :             :                                         COERCION_EXPLICIT,
    3445                 :             :                                         COERCE_EXPLICIT_CAST,
    3446                 :             :                                         location);
    3447                 :             : 
    3448         [ +  + ]:         528 :         if (!coerced)
    3449                 :             :         {
    3450                 :             :             /* If coercion failed, use to_json()/to_jsonb() functions. */
    3451                 :             :             FuncExpr   *fexpr;
    3452                 :             :             Oid         fnoid;
    3453                 :             : 
    3454                 :             :             /*
    3455                 :             :              * Though only allow a cast when the target type is specified by
    3456                 :             :              * the caller.
    3457                 :             :              */
    3458         [ +  + ]:          20 :             if (only_allow_cast)
    3459         [ +  - ]:           4 :                 ereport(ERROR,
    3460                 :             :                         (errcode(ERRCODE_CANNOT_COERCE),
    3461                 :             :                          errmsg("cannot cast type %s to %s",
    3462                 :             :                                 format_type_be(exprtype),
    3463                 :             :                                 format_type_be(targettype)),
    3464                 :             :                          parser_errposition(pstate, location)));
    3465                 :             : 
    3466         [ -  + ]:          16 :             fnoid = targettype == JSONOID ? F_TO_JSON : F_TO_JSONB;
    3467                 :          16 :             fexpr = makeFuncExpr(fnoid, targettype, list_make1(expr),
    3468                 :             :                                  InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
    3469                 :             : 
    3470                 :          16 :             fexpr->location = location;
    3471                 :             : 
    3472                 :          16 :             coerced = (Node *) fexpr;
    3473                 :             :         }
    3474                 :             : 
    3475         [ -  + ]:         524 :         if (coerced == expr)
    3476                 :           0 :             expr = rawexpr;
    3477                 :             :         else
    3478                 :             :         {
    3479                 :         524 :             ve = copyObject(ve);
    3480                 :         524 :             ve->raw_expr = (Expr *) rawexpr;
    3481                 :         524 :             ve->formatted_expr = (Expr *) coerced;
    3482                 :             : 
    3483                 :         524 :             expr = (Node *) ve;
    3484                 :             :         }
    3485                 :             :     }
    3486                 :             : 
    3487                 :             :     /* If returning a JsonValueExpr, formatted_expr must have been set. */
    3488                 :             :     Assert(!IsA(expr, JsonValueExpr) ||
    3489                 :             :            ((JsonValueExpr *) expr)->formatted_expr != NULL);
    3490                 :             : 
    3491                 :        3484 :     return expr;
    3492                 :             : }
    3493                 :             : 
    3494                 :             : /*
    3495                 :             :  * Checks specified output format for its applicability to the target type.
    3496                 :             :  */
    3497                 :             : static void
    3498                 :         164 : checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format,
    3499                 :             :                       Oid targettype, bool allow_format_for_non_strings)
    3500                 :             : {
    3501         [ +  + ]:         164 :     if (!allow_format_for_non_strings &&
    3502   [ +  -  +  + ]:          96 :         format->format_type != JS_FORMAT_DEFAULT &&
    3503         [ +  + ]:          84 :         (targettype != BYTEAOID &&
    3504         [ +  + ]:          80 :          targettype != JSONOID &&
    3505                 :             :          targettype != JSONBOID))
    3506                 :             :     {
    3507                 :             :         char        typcategory;
    3508                 :             :         bool        typispreferred;
    3509                 :             : 
    3510                 :          60 :         get_type_category_preferred(targettype, &typcategory, &typispreferred);
    3511                 :             : 
    3512         [ -  + ]:          60 :         if (typcategory != TYPCATEGORY_STRING)
    3513         [ #  # ]:           0 :             ereport(ERROR,
    3514                 :             :                     errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3515                 :             :                     parser_errposition(pstate, format->location),
    3516                 :             :                     errmsg("cannot use JSON format with non-string output types"));
    3517                 :             :     }
    3518                 :             : 
    3519         [ +  - ]:         164 :     if (format->format_type == JS_FORMAT_JSON)
    3520                 :             :     {
    3521                 :         328 :         JsonEncoding enc = format->encoding != JS_ENC_DEFAULT ?
    3522         [ +  + ]:         164 :             format->encoding : JS_ENC_UTF8;
    3523                 :             : 
    3524         [ +  + ]:         164 :         if (targettype != BYTEAOID &&
    3525         [ +  + ]:         120 :             format->encoding != JS_ENC_DEFAULT)
    3526         [ +  - ]:           8 :             ereport(ERROR,
    3527                 :             :                     errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3528                 :             :                     parser_errposition(pstate, format->location),
    3529                 :             :                     errmsg("cannot set JSON encoding for non-bytea output types"));
    3530                 :             : 
    3531         [ +  + ]:         156 :         if (enc != JS_ENC_UTF8)
    3532         [ +  - ]:          16 :             ereport(ERROR,
    3533                 :             :                     errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3534                 :             :                     errmsg("unsupported JSON encoding"),
    3535                 :             :                     errhint("Only UTF8 JSON encoding is supported."),
    3536                 :             :                     parser_errposition(pstate, format->location));
    3537                 :             :     }
    3538                 :         140 : }
    3539                 :             : 
    3540                 :             : /*
    3541                 :             :  * Transform JSON output clause.
    3542                 :             :  *
    3543                 :             :  * Assigns target type oid and modifier.
    3544                 :             :  * Assigns default format or checks specified format for its applicability to
    3545                 :             :  * the target type.
    3546                 :             :  */
    3547                 :             : static JsonReturning *
    3548                 :        3110 : transformJsonOutput(ParseState *pstate, const JsonOutput *output,
    3549                 :             :                     bool allow_format)
    3550                 :             : {
    3551                 :             :     JsonReturning *ret;
    3552                 :             : 
    3553                 :             :     /* if output clause is not specified, make default clause value */
    3554         [ +  + ]:        3110 :     if (!output)
    3555                 :             :     {
    3556                 :        1264 :         ret = makeNode(JsonReturning);
    3557                 :             : 
    3558                 :        1264 :         ret->format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
    3559                 :        1264 :         ret->typid = InvalidOid;
    3560                 :        1264 :         ret->typmod = -1;
    3561                 :             : 
    3562                 :        1264 :         return ret;
    3563                 :             :     }
    3564                 :             : 
    3565                 :        1846 :     ret = copyObject(output->returning);
    3566                 :             : 
    3567                 :        1846 :     typenameTypeIdAndMod(pstate, output->typeName, &ret->typid, &ret->typmod);
    3568                 :             : 
    3569         [ -  + ]:        1846 :     if (output->typeName->setof)
    3570         [ #  # ]:           0 :         ereport(ERROR,
    3571                 :             :                 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3572                 :             :                 errmsg("returning SETOF types is not supported in SQL/JSON functions"));
    3573                 :             : 
    3574         [ +  + ]:        1846 :     if (get_typtype(ret->typid) == TYPTYPE_PSEUDO)
    3575         [ +  - ]:           8 :         ereport(ERROR,
    3576                 :             :                 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3577                 :             :                 errmsg("returning pseudo-types is not supported in SQL/JSON functions"));
    3578                 :             : 
    3579         [ +  + ]:        1838 :     if (ret->format->format_type == JS_FORMAT_DEFAULT)
    3580                 :             :         /* assign JSONB format when returning jsonb, or JSON format otherwise */
    3581                 :        1674 :         ret->format->format_type =
    3582         [ +  + ]:        1674 :             ret->typid == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
    3583                 :             :     else
    3584                 :         164 :         checkJsonOutputFormat(pstate, ret->format, ret->typid, allow_format);
    3585                 :             : 
    3586                 :        1814 :     return ret;
    3587                 :             : }
    3588                 :             : 
    3589                 :             : /*
    3590                 :             :  * Transform JSON output clause of JSON constructor functions.
    3591                 :             :  *
    3592                 :             :  * Derive RETURNING type, if not specified, from argument types.
    3593                 :             :  */
    3594                 :             : static JsonReturning *
    3595                 :         994 : transformJsonConstructorOutput(ParseState *pstate, JsonOutput *output,
    3596                 :             :                                List *args)
    3597                 :             : {
    3598                 :         994 :     JsonReturning *returning = transformJsonOutput(pstate, output, true);
    3599                 :             : 
    3600         [ +  + ]:         970 :     if (!OidIsValid(returning->typid))
    3601                 :             :     {
    3602                 :             :         ListCell   *lc;
    3603                 :         364 :         bool        have_jsonb = false;
    3604                 :             : 
    3605   [ +  +  +  +  :        1176 :         foreach(lc, args)
                   +  + ]
    3606                 :             :         {
    3607                 :         832 :             Node       *expr = lfirst(lc);
    3608                 :         832 :             Oid         typid = exprType(expr);
    3609                 :             : 
    3610                 :         832 :             have_jsonb |= typid == JSONBOID;
    3611                 :             : 
    3612         [ +  + ]:         832 :             if (have_jsonb)
    3613                 :          20 :                 break;
    3614                 :             :         }
    3615                 :             : 
    3616         [ +  + ]:         364 :         if (have_jsonb)
    3617                 :             :         {
    3618                 :          20 :             returning->typid = JSONBOID;
    3619                 :          20 :             returning->format->format_type = JS_FORMAT_JSONB;
    3620                 :             :         }
    3621                 :             :         else
    3622                 :             :         {
    3623                 :             :             /* XXX TEXT is default by the standard, but we return JSON */
    3624                 :         344 :             returning->typid = JSONOID;
    3625                 :         344 :             returning->format->format_type = JS_FORMAT_JSON;
    3626                 :             :         }
    3627                 :             : 
    3628                 :         364 :         returning->typmod = -1;
    3629                 :             :     }
    3630                 :             : 
    3631                 :         970 :     return returning;
    3632                 :             : }
    3633                 :             : 
    3634                 :             : /*
    3635                 :             :  * Coerce json[b]-valued function expression to the output type.
    3636                 :             :  */
    3637                 :             : static Node *
    3638                 :        1174 : coerceJsonFuncExpr(ParseState *pstate, Node *expr,
    3639                 :             :                    const JsonReturning *returning, bool report_error)
    3640                 :             : {
    3641                 :             :     Node       *res;
    3642                 :             :     int         location;
    3643                 :        1174 :     Oid         exprtype = exprType(expr);
    3644                 :             : 
    3645                 :             :     /* if output type is not specified or equals to function type, return */
    3646   [ +  -  +  + ]:        1174 :     if (!OidIsValid(returning->typid) || returning->typid == exprtype)
    3647                 :         938 :         return expr;
    3648                 :             : 
    3649                 :         236 :     location = exprLocation(expr);
    3650                 :             : 
    3651         [ +  - ]:         236 :     if (location < 0)
    3652                 :         236 :         location = returning->format->location;
    3653                 :             : 
    3654                 :             :     /* special case for RETURNING bytea FORMAT json */
    3655         [ +  - ]:         236 :     if (returning->format->format_type == JS_FORMAT_JSON &&
    3656         [ +  + ]:         236 :         returning->typid == BYTEAOID)
    3657                 :             :     {
    3658                 :             :         /* encode json text into bytea using pg_convert_to() */
    3659                 :          40 :         Node       *texpr = coerce_to_specific_type(pstate, expr, TEXTOID,
    3660                 :             :                                                     "JSON_FUNCTION");
    3661                 :          40 :         Const      *enc = getJsonEncodingConst(returning->format);
    3662                 :          40 :         FuncExpr   *fexpr = makeFuncExpr(F_CONVERT_TO, BYTEAOID,
    3663                 :             :                                          list_make2(texpr, enc),
    3664                 :             :                                          InvalidOid, InvalidOid,
    3665                 :             :                                          COERCE_EXPLICIT_CALL);
    3666                 :             : 
    3667                 :          40 :         fexpr->location = location;
    3668                 :             : 
    3669                 :          40 :         return (Node *) fexpr;
    3670                 :             :     }
    3671                 :             : 
    3672                 :             :     /*
    3673                 :             :      * For other cases, try to coerce expression to the output type using
    3674                 :             :      * assignment-level casts, erroring out if none available.  This basically
    3675                 :             :      * allows coercing the jsonb value to any string type (typcategory = 'S').
    3676                 :             :      *
    3677                 :             :      * Requesting assignment-level here means that typmod / length coercion
    3678                 :             :      * assumes implicit coercion which is the behavior we want; see
    3679                 :             :      * build_coercion_expression().
    3680                 :             :      */
    3681                 :         196 :     res = coerce_to_target_type(pstate, expr, exprtype,
    3682                 :         196 :                                 returning->typid, returning->typmod,
    3683                 :             :                                 COERCION_ASSIGNMENT,
    3684                 :             :                                 COERCE_IMPLICIT_CAST,
    3685                 :             :                                 location);
    3686                 :             : 
    3687   [ -  +  -  - ]:         196 :     if (!res && report_error)
    3688         [ #  # ]:           0 :         ereport(ERROR,
    3689                 :             :                 errcode(ERRCODE_CANNOT_COERCE),
    3690                 :             :                 errmsg("cannot cast type %s to %s",
    3691                 :             :                        format_type_be(exprtype),
    3692                 :             :                        format_type_be(returning->typid)),
    3693                 :             :                 parser_coercion_errposition(pstate, location, expr));
    3694                 :             : 
    3695                 :         196 :     return res;
    3696                 :             : }
    3697                 :             : 
    3698                 :             : /*
    3699                 :             :  * Make a JsonConstructorExpr node.
    3700                 :             :  */
    3701                 :             : static Node *
    3702                 :        1174 : makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
    3703                 :             :                         List *args, Expr *fexpr, JsonReturning *returning,
    3704                 :             :                         bool unique, bool absent_on_null, int location)
    3705                 :             : {
    3706                 :        1174 :     JsonConstructorExpr *jsctor = makeNode(JsonConstructorExpr);
    3707                 :             :     Node       *placeholder;
    3708                 :             :     Node       *coercion;
    3709                 :             : 
    3710                 :        1174 :     jsctor->args = args;
    3711                 :        1174 :     jsctor->func = fexpr;
    3712                 :        1174 :     jsctor->type = type;
    3713                 :        1174 :     jsctor->returning = returning;
    3714                 :        1174 :     jsctor->unique = unique;
    3715                 :        1174 :     jsctor->absent_on_null = absent_on_null;
    3716                 :        1174 :     jsctor->location = location;
    3717                 :             : 
    3718                 :             :     /*
    3719                 :             :      * Coerce to the RETURNING type and format, if needed.  We abuse
    3720                 :             :      * CaseTestExpr here as placeholder to pass the result of either
    3721                 :             :      * evaluating 'fexpr' or whatever is produced by ExecEvalJsonConstructor()
    3722                 :             :      * that is of type JSON or JSONB to the coercion function.
    3723                 :             :      */
    3724         [ +  + ]:        1174 :     if (fexpr)
    3725                 :             :     {
    3726                 :         392 :         CaseTestExpr *cte = makeNode(CaseTestExpr);
    3727                 :             : 
    3728                 :         392 :         cte->typeId = exprType((Node *) fexpr);
    3729                 :         392 :         cte->typeMod = exprTypmod((Node *) fexpr);
    3730                 :         392 :         cte->collation = exprCollation((Node *) fexpr);
    3731                 :             : 
    3732                 :         392 :         placeholder = (Node *) cte;
    3733                 :             :     }
    3734                 :             :     else
    3735                 :             :     {
    3736                 :         782 :         CaseTestExpr *cte = makeNode(CaseTestExpr);
    3737                 :             : 
    3738                 :        1564 :         cte->typeId = returning->format->format_type == JS_FORMAT_JSONB ?
    3739         [ +  + ]:         782 :             JSONBOID : JSONOID;
    3740                 :         782 :         cte->typeMod = -1;
    3741                 :         782 :         cte->collation = InvalidOid;
    3742                 :             : 
    3743                 :         782 :         placeholder = (Node *) cte;
    3744                 :             :     }
    3745                 :             : 
    3746                 :        1174 :     coercion = coerceJsonFuncExpr(pstate, placeholder, returning, true);
    3747                 :             : 
    3748         [ +  + ]:        1174 :     if (coercion != placeholder)
    3749                 :         236 :         jsctor->coercion = (Expr *) coercion;
    3750                 :             : 
    3751                 :        1174 :     return (Node *) jsctor;
    3752                 :             : }
    3753                 :             : 
    3754                 :             : /*
    3755                 :             :  * Transform JSON_OBJECT() constructor.
    3756                 :             :  *
    3757                 :             :  * JSON_OBJECT() is transformed into a JsonConstructorExpr node of type
    3758                 :             :  * JSCTOR_JSON_OBJECT.  The result is coerced to the target type given
    3759                 :             :  * by ctor->output.
    3760                 :             :  */
    3761                 :             : static Node *
    3762                 :         378 : transformJsonObjectConstructor(ParseState *pstate, JsonObjectConstructor *ctor)
    3763                 :             : {
    3764                 :             :     JsonReturning *returning;
    3765                 :         378 :     List       *args = NIL;
    3766                 :             : 
    3767                 :             :     /* transform key-value pairs, if any */
    3768         [ +  + ]:         378 :     if (ctor->exprs)
    3769                 :             :     {
    3770                 :             :         ListCell   *lc;
    3771                 :             : 
    3772                 :             :         /* transform and append key-value arguments */
    3773   [ +  -  +  +  :         788 :         foreach(lc, ctor->exprs)
                   +  + ]
    3774                 :             :         {
    3775                 :         486 :             JsonKeyValue *kv = castNode(JsonKeyValue, lfirst(lc));
    3776                 :         486 :             Node       *key = transformExprRecurse(pstate, (Node *) kv->key);
    3777                 :         486 :             Node       *val = transformJsonValueExpr(pstate, "JSON_OBJECT()",
    3778                 :             :                                                      kv->value,
    3779                 :             :                                                      JS_FORMAT_DEFAULT,
    3780                 :             :                                                      InvalidOid, false);
    3781                 :             : 
    3782                 :         470 :             args = lappend(args, key);
    3783                 :         470 :             args = lappend(args, val);
    3784                 :             :         }
    3785                 :             :     }
    3786                 :             : 
    3787                 :         362 :     returning = transformJsonConstructorOutput(pstate, ctor->output, args);
    3788                 :             : 
    3789                 :         700 :     return makeJsonConstructorExpr(pstate, JSCTOR_JSON_OBJECT, args, NULL,
    3790                 :         350 :                                    returning, ctor->unique,
    3791                 :         350 :                                    ctor->absent_on_null, ctor->location);
    3792                 :             : }
    3793                 :             : 
    3794                 :             : /*
    3795                 :             :  * Transform JSON_ARRAY(subquery) constructor.
    3796                 :             :  *
    3797                 :             :  * JSON_ARRAY(subquery) is transformed into a JsonConstructorExpr node of type
    3798                 :             :  * JSCTOR_JSON_ARRAY_QUERY.  The node carries:
    3799                 :             :  *
    3800                 :             :  *  - func: the executable form, which is a COALESCE expression wrapping a
    3801                 :             :  *    JSON_ARRAYAGG subquery:
    3802                 :             :  *
    3803                 :             :  *        COALESCE((SELECT JSON_ARRAYAGG(a) FROM (subquery) q(a)), '[]')
    3804                 :             :  *
    3805                 :             :  *    The COALESCE ensures that an empty result set produces '[]' rather than
    3806                 :             :  *    NULL, per the SQL/JSON standard.
    3807                 :             :  *
    3808                 :             :  *  - orig_query: the transformed Query of the user's original subquery, so
    3809                 :             :  *    that ruleutils.c can deparse the original JSON_ARRAY(SELECT ...) syntax
    3810                 :             :  *    for view definitions.
    3811                 :             :  */
    3812                 :             : static Node *
    3813                 :          92 : transformJsonArrayQueryConstructor(ParseState *pstate,
    3814                 :             :                                    JsonArrayQueryConstructor *ctor)
    3815                 :             : {
    3816                 :             :     Query      *query;
    3817                 :             :     ParseState *qpstate;
    3818                 :             :     SubLink    *sublink;
    3819                 :             :     SelectStmt *select;
    3820                 :             :     RangeSubselect *range;
    3821                 :             :     Alias      *alias;
    3822                 :             :     ResTarget  *target;
    3823                 :             :     JsonArrayAgg *agg;
    3824                 :             :     ColumnRef  *colref;
    3825                 :             :     Node       *exec_expr;
    3826                 :             :     CoalesceExpr *coalesce;
    3827                 :             :     Const      *empty_const;
    3828                 :             :     Oid         result_type;
    3829                 :             :     int32       result_typmod;
    3830                 :             :     Oid         typinput;
    3831                 :             :     Oid         typioparam;
    3832                 :             :     int16       typlen;
    3833                 :             :     bool        typbyval;
    3834                 :             :     JsonReturning *returning;
    3835                 :             :     List       *args;
    3836                 :             :     Node       *result;
    3837                 :             : 
    3838                 :             :     /*
    3839                 :             :      * Transform a copy of the subquery to validate the single-column
    3840                 :             :      * constraint and to obtain the transformed Query for deparsing.  This
    3841                 :             :      * uses a private ParseState so it doesn't affect the main parse context.
    3842                 :             :      */
    3843                 :          92 :     qpstate = make_parsestate(pstate);
    3844                 :             : 
    3845                 :          92 :     query = transformStmt(qpstate, copyObject(ctor->query));
    3846                 :             : 
    3847         [ +  + ]:          92 :     if (count_nonjunk_tlist_entries(query->targetList) != 1)
    3848         [ +  - ]:          12 :         ereport(ERROR,
    3849                 :             :                 errcode(ERRCODE_SYNTAX_ERROR),
    3850                 :             :                 errmsg("subquery must return only one column"),
    3851                 :             :                 parser_errposition(pstate, ctor->location));
    3852                 :             : 
    3853                 :          80 :     free_parsestate(qpstate);
    3854                 :             : 
    3855                 :             :     /*
    3856                 :             :      * Build the executable form by constructing query:
    3857                 :             :      *
    3858                 :             :      * (SELECT JSON_ARRAYAGG(a [FORMAT] [RETURNING]) FROM (subquery) q(a))
    3859                 :             :      *
    3860                 :             :      * ... using raw parse tree nodes, then transforming via
    3861                 :             :      * transformExprRecurse.
    3862                 :             :      */
    3863                 :          80 :     colref = makeNode(ColumnRef);
    3864                 :          80 :     colref->fields = list_make2(makeString(pstrdup("q")),
    3865                 :             :                                 makeString(pstrdup("a")));
    3866                 :          80 :     colref->location = ctor->location;
    3867                 :             : 
    3868                 :          80 :     agg = makeNode(JsonArrayAgg);
    3869                 :          80 :     agg->arg = makeJsonValueExpr((Expr *) colref, (Expr *) colref,
    3870                 :             :                                  ctor->format);
    3871                 :          80 :     agg->absent_on_null = ctor->absent_on_null;
    3872                 :          80 :     agg->constructor = makeNode(JsonAggConstructor);
    3873                 :          80 :     agg->constructor->agg_order = NIL;
    3874                 :          80 :     agg->constructor->output = ctor->output;
    3875                 :          80 :     agg->constructor->location = ctor->location;
    3876                 :             : 
    3877                 :          80 :     target = makeNode(ResTarget);
    3878                 :          80 :     target->name = NULL;
    3879                 :          80 :     target->indirection = NIL;
    3880                 :          80 :     target->val = (Node *) agg;
    3881                 :          80 :     target->location = ctor->location;
    3882                 :             : 
    3883                 :          80 :     alias = makeNode(Alias);
    3884                 :          80 :     alias->aliasname = pstrdup("q");
    3885                 :          80 :     alias->colnames = list_make1(makeString(pstrdup("a")));
    3886                 :             : 
    3887                 :          80 :     range = makeNode(RangeSubselect);
    3888                 :          80 :     range->lateral = false;
    3889                 :          80 :     range->subquery = ctor->query;
    3890                 :          80 :     range->alias = alias;
    3891                 :             : 
    3892                 :          80 :     select = makeNode(SelectStmt);
    3893                 :          80 :     select->targetList = list_make1(target);
    3894                 :          80 :     select->fromClause = list_make1(range);
    3895                 :             : 
    3896                 :          80 :     sublink = makeNode(SubLink);
    3897                 :          80 :     sublink->subLinkType = EXPR_SUBLINK;
    3898                 :          80 :     sublink->subLinkId = 0;
    3899                 :          80 :     sublink->testexpr = NULL;
    3900                 :          80 :     sublink->operName = NIL;
    3901                 :          80 :     sublink->subselect = (Node *) select;
    3902                 :          80 :     sublink->location = ctor->location;
    3903                 :             : 
    3904                 :          80 :     exec_expr = transformExprRecurse(pstate, (Node *) sublink);
    3905                 :             : 
    3906                 :             :     /*
    3907                 :             :      * Wrap in COALESCE so that an empty result set produces '[]' rather than
    3908                 :             :      * NULL.  The empty-array constant is created in the output type and
    3909                 :             :      * typmod, so that the COALESCE arguments have consistent types and any
    3910                 :             :      * length restriction from the RETURNING clause is enforced uniformly
    3911                 :             :      * across the empty and non-empty paths.
    3912                 :             :      */
    3913                 :          80 :     result_type = exprType(exec_expr);
    3914                 :          80 :     result_typmod = exprTypmod(exec_expr);
    3915                 :          80 :     getTypeInputInfo(result_type, &typinput, &typioparam);
    3916                 :          80 :     get_typlenbyval(result_type, &typlen, &typbyval);
    3917                 :             : 
    3918                 :          80 :     empty_const = makeConst(result_type,
    3919                 :             :                             result_typmod,
    3920                 :             :                             exprCollation(exec_expr),
    3921                 :             :                             (int) typlen,
    3922                 :             :                             OidInputFunctionCall(typinput, "[]",
    3923                 :             :                                                  typioparam, result_typmod),
    3924                 :             :                             false,
    3925                 :             :                             typbyval);
    3926                 :             : 
    3927                 :          72 :     coalesce = makeNode(CoalesceExpr);
    3928                 :          72 :     coalesce->coalescetype = result_type;
    3929                 :          72 :     coalesce->coalescecollid = exprCollation(exec_expr);
    3930                 :          72 :     coalesce->args = list_make2(exec_expr, empty_const);
    3931                 :          72 :     coalesce->location = ctor->location;
    3932                 :             : 
    3933                 :             :     /*
    3934                 :             :      * Build the JSCTOR_JSON_ARRAY_QUERY node.  The COALESCE goes in func as
    3935                 :             :      * the executable form; during planning, eval_const_expressions replaces
    3936                 :             :      * the entire node with func.  The transformed Query is stored in
    3937                 :             :      * orig_query so that ruleutils.c can deparse the original syntax.
    3938                 :             :      */
    3939                 :          72 :     args = list_make1(linitial_node(TargetEntry, query->targetList)->expr);
    3940                 :          72 :     returning = transformJsonConstructorOutput(pstate, ctor->output, args);
    3941                 :             : 
    3942                 :          72 :     result = makeJsonConstructorExpr(pstate, JSCTOR_JSON_ARRAY_QUERY,
    3943                 :             :                                      NIL, (Expr *) coalesce, returning,
    3944                 :          72 :                                      false, ctor->absent_on_null,
    3945                 :             :                                      ctor->location);
    3946                 :          72 :     ((JsonConstructorExpr *) result)->orig_query = (Node *) query;
    3947                 :             : 
    3948                 :          72 :     return result;
    3949                 :             : }
    3950                 :             : 
    3951                 :             : /*
    3952                 :             :  * Common code for JSON_OBJECTAGG and JSON_ARRAYAGG transformation.
    3953                 :             :  */
    3954                 :             : static Node *
    3955                 :         336 : transformJsonAggConstructor(ParseState *pstate, JsonAggConstructor *agg_ctor,
    3956                 :             :                             JsonReturning *returning, List *args,
    3957                 :             :                             Oid aggfnoid, Oid aggtype,
    3958                 :             :                             JsonConstructorType ctor_type,
    3959                 :             :                             bool unique, bool absent_on_null)
    3960                 :             : {
    3961                 :             :     Node       *node;
    3962                 :             :     Expr       *aggfilter;
    3963                 :             : 
    3964                 :         672 :     aggfilter = agg_ctor->agg_filter ? (Expr *)
    3965                 :          28 :         transformWhereClause(pstate, agg_ctor->agg_filter,
    3966         [ +  + ]:         336 :                              EXPR_KIND_FILTER, "FILTER") : NULL;
    3967                 :             : 
    3968         [ +  + ]:         336 :     if (agg_ctor->over)
    3969                 :             :     {
    3970                 :             :         /* window function */
    3971                 :          32 :         WindowFunc *wfunc = makeNode(WindowFunc);
    3972                 :             : 
    3973                 :          32 :         wfunc->winfnoid = aggfnoid;
    3974                 :          32 :         wfunc->wintype = aggtype;
    3975                 :             :         /* wincollid and inputcollid will be set by parse_collate.c */
    3976                 :          32 :         wfunc->args = args;
    3977                 :          32 :         wfunc->aggfilter = aggfilter;
    3978                 :          32 :         wfunc->runCondition = NIL;
    3979                 :             :         /* winref will be set by transformWindowFuncCall */
    3980                 :          32 :         wfunc->winstar = false;
    3981                 :          32 :         wfunc->winagg = true;
    3982                 :          32 :         wfunc->location = agg_ctor->location;
    3983                 :             : 
    3984                 :             :         /*
    3985                 :             :          * ordered aggs not allowed in windows yet
    3986                 :             :          */
    3987         [ -  + ]:          32 :         if (agg_ctor->agg_order != NIL)
    3988         [ #  # ]:           0 :             ereport(ERROR,
    3989                 :             :                     errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3990                 :             :                     errmsg("aggregate ORDER BY is not implemented for window functions"),
    3991                 :             :                     parser_errposition(pstate, agg_ctor->location));
    3992                 :             : 
    3993                 :             :         /* parse_agg.c does additional window-func-specific processing */
    3994                 :          32 :         transformWindowFuncCall(pstate, wfunc, agg_ctor->over);
    3995                 :             : 
    3996                 :          32 :         node = (Node *) wfunc;
    3997                 :             :     }
    3998                 :             :     else
    3999                 :             :     {
    4000                 :         304 :         Aggref     *aggref = makeNode(Aggref);
    4001                 :             : 
    4002                 :         304 :         aggref->aggfnoid = aggfnoid;
    4003                 :         304 :         aggref->aggtype = aggtype;
    4004                 :             : 
    4005                 :             :         /* aggcollid and inputcollid will be set by parse_collate.c */
    4006                 :             :         /* aggtranstype will be set by planner */
    4007                 :             :         /* aggargtypes will be set by transformAggregateCall */
    4008                 :             :         /* aggdirectargs and args will be set by transformAggregateCall */
    4009                 :             :         /* aggorder and aggdistinct will be set by transformAggregateCall */
    4010                 :         304 :         aggref->aggfilter = aggfilter;
    4011                 :         304 :         aggref->aggstar = false;
    4012                 :         304 :         aggref->aggvariadic = false;
    4013                 :         304 :         aggref->aggkind = AGGKIND_NORMAL;
    4014                 :         304 :         aggref->aggpresorted = false;
    4015                 :             :         /* agglevelsup will be set by transformAggregateCall */
    4016                 :         304 :         aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
    4017                 :         304 :         aggref->aggno = -1;      /* planner will set aggno and aggtransno */
    4018                 :         304 :         aggref->aggtransno = -1;
    4019                 :         304 :         aggref->location = agg_ctor->location;
    4020                 :             : 
    4021                 :         304 :         transformAggregateCall(pstate, aggref, args, agg_ctor->agg_order, false);
    4022                 :             : 
    4023                 :         288 :         node = (Node *) aggref;
    4024                 :             :     }
    4025                 :             : 
    4026                 :         320 :     return makeJsonConstructorExpr(pstate, ctor_type, NIL, (Expr *) node,
    4027                 :             :                                    returning, unique, absent_on_null,
    4028                 :             :                                    agg_ctor->location);
    4029                 :             : }
    4030                 :             : 
    4031                 :             : /*
    4032                 :             :  * Transform JSON_OBJECTAGG() aggregate function.
    4033                 :             :  *
    4034                 :             :  * JSON_OBJECTAGG() is transformed into a JsonConstructorExpr node of type
    4035                 :             :  * JSCTOR_JSON_OBJECTAGG, which at runtime becomes a
    4036                 :             :  * json[b]_object_agg[_unique][_strict](agg->arg->key, agg->arg->value) call
    4037                 :             :  * depending on the output JSON format.  The result is coerced to the target
    4038                 :             :  * type given by agg->constructor->output.
    4039                 :             :  */
    4040                 :             : static Node *
    4041                 :         144 : transformJsonObjectAgg(ParseState *pstate, JsonObjectAgg *agg)
    4042                 :             : {
    4043                 :             :     JsonReturning *returning;
    4044                 :             :     Node       *key;
    4045                 :             :     Node       *val;
    4046                 :             :     List       *args;
    4047                 :             :     Oid         aggfnoid;
    4048                 :             :     Oid         aggtype;
    4049                 :             : 
    4050                 :         144 :     key = transformExprRecurse(pstate, (Node *) agg->arg->key);
    4051                 :         144 :     val = transformJsonValueExpr(pstate, "JSON_OBJECTAGG()",
    4052                 :         144 :                                  agg->arg->value,
    4053                 :             :                                  JS_FORMAT_DEFAULT,
    4054                 :             :                                  InvalidOid, false);
    4055                 :         144 :     args = list_make2(key, val);
    4056                 :             : 
    4057                 :         144 :     returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
    4058                 :             :                                                args);
    4059                 :             : 
    4060         [ +  + ]:         144 :     if (returning->format->format_type == JS_FORMAT_JSONB)
    4061                 :             :     {
    4062         [ +  + ]:          40 :         if (agg->absent_on_null)
    4063         [ +  + ]:          16 :             if (agg->unique)
    4064                 :          12 :                 aggfnoid = F_JSONB_OBJECT_AGG_UNIQUE_STRICT;
    4065                 :             :             else
    4066                 :           4 :                 aggfnoid = F_JSONB_OBJECT_AGG_STRICT;
    4067         [ +  + ]:          24 :         else if (agg->unique)
    4068                 :           4 :             aggfnoid = F_JSONB_OBJECT_AGG_UNIQUE;
    4069                 :             :         else
    4070                 :          20 :             aggfnoid = F_JSONB_OBJECT_AGG;
    4071                 :             : 
    4072                 :          40 :         aggtype = JSONBOID;
    4073                 :             :     }
    4074                 :             :     else
    4075                 :             :     {
    4076         [ +  + ]:         104 :         if (agg->absent_on_null)
    4077         [ +  + ]:          28 :             if (agg->unique)
    4078                 :          16 :                 aggfnoid = F_JSON_OBJECT_AGG_UNIQUE_STRICT;
    4079                 :             :             else
    4080                 :          12 :                 aggfnoid = F_JSON_OBJECT_AGG_STRICT;
    4081         [ +  + ]:          76 :         else if (agg->unique)
    4082                 :          32 :             aggfnoid = F_JSON_OBJECT_AGG_UNIQUE;
    4083                 :             :         else
    4084                 :          44 :             aggfnoid = F_JSON_OBJECT_AGG;
    4085                 :             : 
    4086                 :         104 :         aggtype = JSONOID;
    4087                 :             :     }
    4088                 :             : 
    4089                 :         280 :     return transformJsonAggConstructor(pstate, agg->constructor, returning,
    4090                 :             :                                        args, aggfnoid, aggtype,
    4091                 :             :                                        JSCTOR_JSON_OBJECTAGG,
    4092                 :         144 :                                        agg->unique, agg->absent_on_null);
    4093                 :             : }
    4094                 :             : 
    4095                 :             : /*
    4096                 :             :  * Transform JSON_ARRAYAGG() aggregate function.
    4097                 :             :  *
    4098                 :             :  * JSON_ARRAYAGG() is transformed into a JsonConstructorExpr node of type
    4099                 :             :  * JSCTOR_JSON_ARRAYAGG, which at runtime becomes a
    4100                 :             :  * json[b]_object_agg[_unique][_strict](agg->arg) call depending on the output
    4101                 :             :  * JSON format.  The result is coerced to the target type given by
    4102                 :             :  * agg->constructor->output.
    4103                 :             :  */
    4104                 :             : static Node *
    4105                 :         192 : transformJsonArrayAgg(ParseState *pstate, JsonArrayAgg *agg)
    4106                 :             : {
    4107                 :             :     JsonReturning *returning;
    4108                 :             :     Node       *arg;
    4109                 :             :     Oid         aggfnoid;
    4110                 :             :     Oid         aggtype;
    4111                 :             : 
    4112                 :         192 :     arg = transformJsonValueExpr(pstate, "JSON_ARRAYAGG()", agg->arg,
    4113                 :             :                                  JS_FORMAT_DEFAULT, InvalidOid, false);
    4114                 :             : 
    4115                 :         192 :     returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
    4116                 :             :                                                list_make1(arg));
    4117                 :             : 
    4118         [ +  + ]:         192 :     if (returning->format->format_type == JS_FORMAT_JSONB)
    4119                 :             :     {
    4120         [ +  + ]:          72 :         aggfnoid = agg->absent_on_null ? F_JSONB_AGG_STRICT : F_JSONB_AGG;
    4121                 :          72 :         aggtype = JSONBOID;
    4122                 :             :     }
    4123                 :             :     else
    4124                 :             :     {
    4125         [ +  + ]:         120 :         aggfnoid = agg->absent_on_null ? F_JSON_AGG_STRICT : F_JSON_AGG;
    4126                 :         120 :         aggtype = JSONOID;
    4127                 :             :     }
    4128                 :             : 
    4129                 :         192 :     return transformJsonAggConstructor(pstate, agg->constructor, returning,
    4130                 :             :                                        list_make1(arg), aggfnoid, aggtype,
    4131                 :             :                                        JSCTOR_JSON_ARRAYAGG,
    4132                 :         192 :                                        false, agg->absent_on_null);
    4133                 :             : }
    4134                 :             : 
    4135                 :             : /*
    4136                 :             :  * Transform JSON_ARRAY() constructor.
    4137                 :             :  *
    4138                 :             :  * JSON_ARRAY() is transformed into a JsonConstructorExpr node of type
    4139                 :             :  * JSCTOR_JSON_ARRAY.  The result is coerced to the target type given
    4140                 :             :  * by ctor->output.
    4141                 :             :  */
    4142                 :             : static Node *
    4143                 :         224 : transformJsonArrayConstructor(ParseState *pstate, JsonArrayConstructor *ctor)
    4144                 :             : {
    4145                 :             :     JsonReturning *returning;
    4146                 :         224 :     List       *args = NIL;
    4147                 :             : 
    4148                 :             :     /* transform element expressions, if any */
    4149         [ +  + ]:         224 :     if (ctor->exprs)
    4150                 :             :     {
    4151                 :             :         ListCell   *lc;
    4152                 :             : 
    4153                 :             :         /* transform and append element arguments */
    4154   [ +  -  +  +  :         428 :         foreach(lc, ctor->exprs)
                   +  + ]
    4155                 :             :         {
    4156                 :         260 :             JsonValueExpr *jsval = castNode(JsonValueExpr, lfirst(lc));
    4157                 :         260 :             Node       *val = transformJsonValueExpr(pstate, "JSON_ARRAY()",
    4158                 :             :                                                      jsval, JS_FORMAT_DEFAULT,
    4159                 :             :                                                      InvalidOid, false);
    4160                 :             : 
    4161                 :         260 :             args = lappend(args, val);
    4162                 :             :         }
    4163                 :             :     }
    4164                 :             : 
    4165                 :         224 :     returning = transformJsonConstructorOutput(pstate, ctor->output, args);
    4166                 :             : 
    4167                 :         424 :     return makeJsonConstructorExpr(pstate, JSCTOR_JSON_ARRAY, args, NULL,
    4168                 :         212 :                                    returning, false, ctor->absent_on_null,
    4169                 :             :                                    ctor->location);
    4170                 :             : }
    4171                 :             : 
    4172                 :             : static Node *
    4173                 :         300 : transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format,
    4174                 :             :                       Oid *exprtype)
    4175                 :             : {
    4176                 :         300 :     Node       *raw_expr = transformExprRecurse(pstate, jsexpr);
    4177                 :         300 :     Node       *expr = raw_expr;
    4178                 :             : 
    4179                 :         300 :     *exprtype = getBaseType(exprType(expr));
    4180                 :             : 
    4181                 :             :     /* prepare input document */
    4182         [ +  + ]:         300 :     if (*exprtype == BYTEAOID)
    4183                 :             :     {
    4184                 :             :         JsonValueExpr *jve;
    4185                 :             : 
    4186                 :          48 :         expr = raw_expr;
    4187                 :          48 :         expr = makeJsonByteaToTextConversion(expr, format, exprLocation(expr));
    4188                 :          48 :         *exprtype = TEXTOID;
    4189                 :             : 
    4190                 :          48 :         jve = makeJsonValueExpr((Expr *) raw_expr, (Expr *) expr, format);
    4191                 :          48 :         expr = (Node *) jve;
    4192                 :             :     }
    4193                 :             :     else
    4194                 :             :     {
    4195                 :             :         char        typcategory;
    4196                 :             :         bool        typispreferred;
    4197                 :             : 
    4198                 :         252 :         get_type_category_preferred(*exprtype, &typcategory, &typispreferred);
    4199                 :             : 
    4200   [ +  +  +  + ]:         252 :         if (*exprtype == UNKNOWNOID || typcategory == TYPCATEGORY_STRING)
    4201                 :             :         {
    4202                 :         142 :             int         location = exprLocation(expr);
    4203                 :             : 
    4204                 :         142 :             expr = coerce_to_target_type(pstate, expr, *exprtype,
    4205                 :             :                                          TEXTOID, -1,
    4206                 :             :                                          COERCION_IMPLICIT,
    4207                 :             :                                          COERCE_IMPLICIT_CAST, -1);
    4208         [ +  + ]:         142 :             if (expr == NULL)
    4209         [ +  - ]:           8 :                 ereport(ERROR,
    4210                 :             :                         errcode(ERRCODE_CANNOT_COERCE),
    4211                 :             :                         errmsg("cannot cast type %s to %s",
    4212                 :             :                                format_type_be(*exprtype),
    4213                 :             :                                format_type_be(TEXTOID)),
    4214                 :             :                         parser_errposition(pstate, location));
    4215                 :             : 
    4216                 :         134 :             *exprtype = TEXTOID;
    4217                 :             :         }
    4218                 :             : 
    4219         [ -  + ]:         244 :         if (format->encoding != JS_ENC_DEFAULT)
    4220         [ #  # ]:           0 :             ereport(ERROR,
    4221                 :             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4222                 :             :                      parser_errposition(pstate, format->location),
    4223                 :             :                      errmsg("cannot use JSON FORMAT ENCODING clause for non-bytea input types")));
    4224                 :             :     }
    4225                 :             : 
    4226                 :         292 :     return expr;
    4227                 :             : }
    4228                 :             : 
    4229                 :             : /*
    4230                 :             :  * Transform IS JSON predicate.
    4231                 :             :  */
    4232                 :             : static Node *
    4233                 :         280 : transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
    4234                 :             : {
    4235                 :             :     Oid         exprtype;
    4236                 :         280 :     Node       *expr = transformJsonParseArg(pstate, pred->expr, pred->format,
    4237                 :             :                                              &exprtype);
    4238                 :             : 
    4239                 :             :     /* make resulting expression */
    4240   [ +  +  +  +  :         276 :     if (exprtype != TEXTOID && exprtype != JSONOID && exprtype != JSONBOID)
                   +  + ]
    4241         [ +  - ]:          12 :         ereport(ERROR,
    4242                 :             :                 errcode(ERRCODE_DATATYPE_MISMATCH),
    4243                 :             :                 errmsg("cannot use type %s in IS JSON predicate",
    4244                 :             :                        format_type_be(exprType(expr))),
    4245                 :             :                 parser_errposition(pstate, exprLocation(expr)));
    4246                 :             : 
    4247                 :             :     /* This intentionally(?) drops the format clause. */
    4248                 :         528 :     return makeJsonIsPredicate(expr, NULL, pred->item_type,
    4249                 :         264 :                                pred->unique_keys, exprtype, pred->location);
    4250                 :             : }
    4251                 :             : 
    4252                 :             : /*
    4253                 :             :  * Transform the RETURNING clause of a JSON_*() expression if there is one and
    4254                 :             :  * create one if not.
    4255                 :             :  */
    4256                 :             : static JsonReturning *
    4257                 :         178 : transformJsonReturning(ParseState *pstate, JsonOutput *output, const char *fname)
    4258                 :             : {
    4259                 :             :     JsonReturning *returning;
    4260                 :             : 
    4261         [ -  + ]:         178 :     if (output)
    4262                 :             :     {
    4263                 :           0 :         returning = transformJsonOutput(pstate, output, false);
    4264                 :             : 
    4265                 :             :         Assert(OidIsValid(returning->typid));
    4266                 :             : 
    4267   [ #  #  #  # ]:           0 :         if (returning->typid != JSONOID && returning->typid != JSONBOID)
    4268         [ #  # ]:           0 :             ereport(ERROR,
    4269                 :             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    4270                 :             :                      errmsg("cannot use type %s in RETURNING clause of %s",
    4271                 :             :                             format_type_be(returning->typid), fname),
    4272                 :             :                      errhint("Try returning json or jsonb."),
    4273                 :             :                      parser_errposition(pstate, output->typeName->location)));
    4274                 :             :     }
    4275                 :             :     else
    4276                 :             :     {
    4277                 :             :         /* Output type is JSON by default. */
    4278                 :         178 :         Oid         targettype = JSONOID;
    4279                 :         178 :         JsonFormatType format = JS_FORMAT_JSON;
    4280                 :             : 
    4281                 :         178 :         returning = makeNode(JsonReturning);
    4282                 :         178 :         returning->format = makeJsonFormat(format, JS_ENC_DEFAULT, -1);
    4283                 :         178 :         returning->typid = targettype;
    4284                 :         178 :         returning->typmod = -1;
    4285                 :             :     }
    4286                 :             : 
    4287                 :         178 :     return returning;
    4288                 :             : }
    4289                 :             : 
    4290                 :             : /*
    4291                 :             :  * Transform a JSON() expression.
    4292                 :             :  *
    4293                 :             :  * JSON() is transformed into a JsonConstructorExpr of type JSCTOR_JSON_PARSE,
    4294                 :             :  * which validates the input expression value as JSON.
    4295                 :             :  */
    4296                 :             : static Node *
    4297                 :         108 : transformJsonParseExpr(ParseState *pstate, JsonParseExpr *jsexpr)
    4298                 :             : {
    4299                 :         108 :     JsonOutput *output = jsexpr->output;
    4300                 :             :     JsonReturning *returning;
    4301                 :             :     Node       *arg;
    4302                 :             : 
    4303                 :         108 :     returning = transformJsonReturning(pstate, output, "JSON()");
    4304                 :             : 
    4305         [ +  + ]:         108 :     if (jsexpr->unique_keys)
    4306                 :             :     {
    4307                 :             :         /*
    4308                 :             :          * Coerce string argument to text and then to json[b] in the executor
    4309                 :             :          * node with key uniqueness check.
    4310                 :             :          */
    4311                 :          20 :         JsonValueExpr *jve = jsexpr->expr;
    4312                 :             :         Oid         arg_type;
    4313                 :             : 
    4314                 :          20 :         arg = transformJsonParseArg(pstate, (Node *) jve->raw_expr, jve->format,
    4315                 :             :                                     &arg_type);
    4316                 :             : 
    4317         [ +  + ]:          16 :         if (arg_type != TEXTOID)
    4318         [ +  - ]:           6 :             ereport(ERROR,
    4319                 :             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    4320                 :             :                      errmsg("cannot use non-string types with WITH UNIQUE KEYS clause"),
    4321                 :             :                      parser_errposition(pstate, jsexpr->location)));
    4322                 :             :     }
    4323                 :             :     else
    4324                 :             :     {
    4325                 :             :         /*
    4326                 :             :          * Coerce argument to target type using CAST for compatibility with PG
    4327                 :             :          * function-like CASTs.
    4328                 :             :          */
    4329                 :          88 :         arg = transformJsonValueExpr(pstate, "JSON()", jsexpr->expr,
    4330                 :             :                                      JS_FORMAT_JSON, returning->typid, false);
    4331                 :             :     }
    4332                 :             : 
    4333                 :          88 :     return makeJsonConstructorExpr(pstate, JSCTOR_JSON_PARSE, list_make1(arg), NULL,
    4334                 :          88 :                                    returning, jsexpr->unique_keys, false,
    4335                 :             :                                    jsexpr->location);
    4336                 :             : }
    4337                 :             : 
    4338                 :             : /*
    4339                 :             :  * Transform a JSON_SCALAR() expression.
    4340                 :             :  *
    4341                 :             :  * JSON_SCALAR() is transformed into a JsonConstructorExpr of type
    4342                 :             :  * JSCTOR_JSON_SCALAR, which converts the input SQL scalar value into
    4343                 :             :  * a json[b] value.
    4344                 :             :  */
    4345                 :             : static Node *
    4346                 :          70 : transformJsonScalarExpr(ParseState *pstate, JsonScalarExpr *jsexpr)
    4347                 :             : {
    4348                 :          70 :     Node       *arg = transformExprRecurse(pstate, (Node *) jsexpr->expr);
    4349                 :          70 :     JsonOutput *output = jsexpr->output;
    4350                 :             :     JsonReturning *returning;
    4351                 :             : 
    4352                 :          70 :     returning = transformJsonReturning(pstate, output, "JSON_SCALAR()");
    4353                 :             : 
    4354         [ +  + ]:          70 :     if (exprType(arg) == UNKNOWNOID)
    4355                 :          16 :         arg = coerce_to_specific_type(pstate, arg, TEXTOID, "JSON_SCALAR");
    4356                 :             : 
    4357                 :          70 :     return makeJsonConstructorExpr(pstate, JSCTOR_JSON_SCALAR, list_make1(arg), NULL,
    4358                 :             :                                    returning, false, false, jsexpr->location);
    4359                 :             : }
    4360                 :             : 
    4361                 :             : /*
    4362                 :             :  * Transform a JSON_SERIALIZE() expression.
    4363                 :             :  *
    4364                 :             :  * JSON_SERIALIZE() is transformed into a JsonConstructorExpr of type
    4365                 :             :  * JSCTOR_JSON_SERIALIZE which converts the input JSON value into a character
    4366                 :             :  * or bytea string.
    4367                 :             :  */
    4368                 :             : static Node *
    4369                 :          68 : transformJsonSerializeExpr(ParseState *pstate, JsonSerializeExpr *expr)
    4370                 :             : {
    4371                 :             :     JsonReturning *returning;
    4372                 :          68 :     Node       *arg = transformJsonValueExpr(pstate, "JSON_SERIALIZE()",
    4373                 :             :                                              expr->expr,
    4374                 :             :                                              JS_FORMAT_JSON,
    4375                 :             :                                              InvalidOid, false);
    4376                 :             : 
    4377         [ +  + ]:          68 :     if (expr->output)
    4378                 :             :     {
    4379                 :          32 :         returning = transformJsonOutput(pstate, expr->output, true);
    4380                 :             : 
    4381         [ +  + ]:          32 :         if (returning->typid != BYTEAOID)
    4382                 :             :         {
    4383                 :             :             char        typcategory;
    4384                 :             :             bool        typispreferred;
    4385                 :             : 
    4386                 :          24 :             get_type_category_preferred(returning->typid, &typcategory,
    4387                 :             :                                         &typispreferred);
    4388         [ +  + ]:          24 :             if (typcategory != TYPCATEGORY_STRING)
    4389         [ +  - ]:           6 :                 ereport(ERROR,
    4390                 :             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    4391                 :             :                          errmsg("cannot use type %s in RETURNING clause of %s",
    4392                 :             :                                 format_type_be(returning->typid),
    4393                 :             :                                 "JSON_SERIALIZE()"),
    4394                 :             :                          errhint("Try returning a string type or bytea.")));
    4395                 :             :         }
    4396                 :             :     }
    4397                 :             :     else
    4398                 :             :     {
    4399                 :             :         /* RETURNING TEXT FORMAT JSON is by default */
    4400                 :          36 :         returning = makeNode(JsonReturning);
    4401                 :          36 :         returning->format = makeJsonFormat(JS_FORMAT_JSON, JS_ENC_DEFAULT, -1);
    4402                 :          36 :         returning->typid = TEXTOID;
    4403                 :          36 :         returning->typmod = -1;
    4404                 :             :     }
    4405                 :             : 
    4406                 :          62 :     return makeJsonConstructorExpr(pstate, JSCTOR_JSON_SERIALIZE, list_make1(arg),
    4407                 :             :                                    NULL, returning, false, false, expr->location);
    4408                 :             : }
    4409                 :             : 
    4410                 :             : /*
    4411                 :             :  * Transform JSON_VALUE, JSON_QUERY, JSON_EXISTS, JSON_TABLE functions into
    4412                 :             :  * a JsonExpr node.
    4413                 :             :  */
    4414                 :             : static Node *
    4415                 :        2132 : transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
    4416                 :             : {
    4417                 :             :     JsonExpr   *jsexpr;
    4418                 :             :     Node       *path_spec;
    4419                 :             :     Oid         pathspec_type;
    4420                 :             :     int         pathspec_loc;
    4421                 :             :     Node       *coerced_path_spec;
    4422                 :        2132 :     const char *func_name = NULL;
    4423                 :             :     JsonFormatType default_format;
    4424                 :             : 
    4425   [ +  +  +  +  :        2132 :     switch (func->op)
                      - ]
    4426                 :             :     {
    4427                 :         204 :         case JSON_EXISTS_OP:
    4428                 :         204 :             func_name = "JSON_EXISTS";
    4429                 :         204 :             default_format = JS_FORMAT_DEFAULT;
    4430                 :         204 :             break;
    4431                 :         880 :         case JSON_QUERY_OP:
    4432                 :         880 :             func_name = "JSON_QUERY";
    4433                 :         880 :             default_format = JS_FORMAT_JSONB;
    4434                 :         880 :             break;
    4435                 :         732 :         case JSON_VALUE_OP:
    4436                 :         732 :             func_name = "JSON_VALUE";
    4437                 :         732 :             default_format = JS_FORMAT_DEFAULT;
    4438                 :         732 :             break;
    4439                 :         316 :         case JSON_TABLE_OP:
    4440                 :         316 :             func_name = "JSON_TABLE";
    4441                 :         316 :             default_format = JS_FORMAT_JSONB;
    4442                 :         316 :             break;
    4443                 :           0 :         default:
    4444         [ #  # ]:           0 :             elog(ERROR, "invalid JsonFuncExpr op %d", (int) func->op);
    4445                 :             :             default_format = JS_FORMAT_DEFAULT; /* keep compiler quiet */
    4446                 :             :             break;
    4447                 :             :     }
    4448                 :             : 
    4449                 :             :     /*
    4450                 :             :      * Even though the syntax allows it, FORMAT JSON specification in
    4451                 :             :      * RETURNING is meaningless except for JSON_QUERY().  Flag if not
    4452                 :             :      * JSON_QUERY().
    4453                 :             :      */
    4454   [ +  +  +  + ]:        2132 :     if (func->output && func->op != JSON_QUERY_OP)
    4455                 :             :     {
    4456                 :         704 :         JsonFormat *format = func->output->returning->format;
    4457                 :             : 
    4458         [ +  + ]:         704 :         if (format->format_type != JS_FORMAT_DEFAULT ||
    4459         [ -  + ]:         700 :             format->encoding != JS_ENC_DEFAULT)
    4460         [ +  - ]:           4 :             ereport(ERROR,
    4461                 :             :                     errcode(ERRCODE_SYNTAX_ERROR),
    4462                 :             :                     errmsg("cannot specify FORMAT JSON in RETURNING clause of %s()",
    4463                 :             :                            func_name),
    4464                 :             :                     parser_errposition(pstate, format->location));
    4465                 :             :     }
    4466                 :             : 
    4467                 :             :     /* OMIT QUOTES is meaningless when strings are wrapped. */
    4468         [ +  + ]:        2128 :     if (func->op == JSON_QUERY_OP)
    4469                 :             :     {
    4470         [ +  + ]:         880 :         if (func->quotes == JS_QUOTES_OMIT &&
    4471         [ +  + ]:         120 :             (func->wrapper == JSW_CONDITIONAL ||
    4472         [ +  + ]:         116 :              func->wrapper == JSW_UNCONDITIONAL))
    4473         [ +  - ]:          12 :             ereport(ERROR,
    4474                 :             :                     errcode(ERRCODE_SYNTAX_ERROR),
    4475                 :             :                     errmsg("SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used"),
    4476                 :             :                     parser_errposition(pstate, func->location));
    4477         [ +  + ]:         868 :         if (func->on_empty != NULL &&
    4478         [ +  + ]:          64 :             func->on_empty->btype != JSON_BEHAVIOR_ERROR &&
    4479         [ +  + ]:          40 :             func->on_empty->btype != JSON_BEHAVIOR_NULL &&
    4480         [ +  - ]:          36 :             func->on_empty->btype != JSON_BEHAVIOR_EMPTY &&
    4481         [ +  + ]:          36 :             func->on_empty->btype != JSON_BEHAVIOR_EMPTY_ARRAY &&
    4482         [ +  + ]:          20 :             func->on_empty->btype != JSON_BEHAVIOR_EMPTY_OBJECT &&
    4483         [ -  + ]:          16 :             func->on_empty->btype != JSON_BEHAVIOR_DEFAULT)
    4484                 :             :         {
    4485         [ #  # ]:           0 :             if (func->column_name == NULL)
    4486         [ #  # ]:           0 :                 ereport(ERROR,
    4487                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4488                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4489                 :             :                         errmsg("invalid %s behavior", "ON EMPTY"),
    4490                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
    4491                 :             :                     second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
    4492                 :             :                         errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s.",
    4493                 :             :                                   "ON EMPTY", "JSON_QUERY()"),
    4494                 :             :                         parser_errposition(pstate, func->on_empty->location));
    4495                 :             :             else
    4496         [ #  # ]:           0 :                 ereport(ERROR,
    4497                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4498                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4499                 :             :                         errmsg("invalid %s behavior for column \"%s\"",
    4500                 :             :                                "ON EMPTY", func->column_name),
    4501                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4502                 :             :                         errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns.",
    4503                 :             :                                   "ON EMPTY"),
    4504                 :             :                         parser_errposition(pstate, func->on_empty->location));
    4505                 :             :         }
    4506         [ +  + ]:         868 :         if (func->on_error != NULL &&
    4507         [ +  + ]:         220 :             func->on_error->btype != JSON_BEHAVIOR_ERROR &&
    4508         [ +  + ]:         104 :             func->on_error->btype != JSON_BEHAVIOR_NULL &&
    4509         [ +  - ]:         100 :             func->on_error->btype != JSON_BEHAVIOR_EMPTY &&
    4510         [ +  + ]:         100 :             func->on_error->btype != JSON_BEHAVIOR_EMPTY_ARRAY &&
    4511         [ +  + ]:          96 :             func->on_error->btype != JSON_BEHAVIOR_EMPTY_OBJECT &&
    4512         [ +  + ]:          60 :             func->on_error->btype != JSON_BEHAVIOR_DEFAULT)
    4513                 :             :         {
    4514         [ +  + ]:           8 :             if (func->column_name == NULL)
    4515         [ +  - ]:           4 :                 ereport(ERROR,
    4516                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4517                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4518                 :             :                         errmsg("invalid %s behavior", "ON ERROR"),
    4519                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
    4520                 :             :                     second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
    4521                 :             :                         errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s.",
    4522                 :             :                                   "ON ERROR", "JSON_QUERY()"),
    4523                 :             :                         parser_errposition(pstate, func->on_error->location));
    4524                 :             :             else
    4525         [ +  - ]:           4 :                 ereport(ERROR,
    4526                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4527                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4528                 :             :                         errmsg("invalid %s behavior for column \"%s\"",
    4529                 :             :                                "ON ERROR", func->column_name),
    4530                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4531                 :             :                         errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns.",
    4532                 :             :                                   "ON ERROR"),
    4533                 :             :                         parser_errposition(pstate, func->on_error->location));
    4534                 :             :         }
    4535                 :             :     }
    4536                 :             : 
    4537                 :             :     /* Check that ON ERROR/EMPTY behavior values are valid for the function. */
    4538         [ +  + ]:        2108 :     if (func->op == JSON_EXISTS_OP &&
    4539         [ +  + ]:         204 :         func->on_error != NULL &&
    4540         [ +  + ]:          60 :         func->on_error->btype != JSON_BEHAVIOR_ERROR &&
    4541         [ +  + ]:          32 :         func->on_error->btype != JSON_BEHAVIOR_TRUE &&
    4542         [ +  + ]:          24 :         func->on_error->btype != JSON_BEHAVIOR_FALSE &&
    4543         [ +  + ]:          16 :         func->on_error->btype != JSON_BEHAVIOR_UNKNOWN)
    4544                 :             :     {
    4545         [ +  + ]:           8 :         if (func->column_name == NULL)
    4546         [ +  - ]:           4 :             ereport(ERROR,
    4547                 :             :                     errcode(ERRCODE_SYNTAX_ERROR),
    4548                 :             :             /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4549                 :             :                     errmsg("invalid %s behavior", "ON ERROR"),
    4550                 :             :                     errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s.",
    4551                 :             :                               "ON ERROR", "JSON_EXISTS()"),
    4552                 :             :                     parser_errposition(pstate, func->on_error->location));
    4553                 :             :         else
    4554         [ +  - ]:           4 :             ereport(ERROR,
    4555                 :             :                     errcode(ERRCODE_SYNTAX_ERROR),
    4556                 :             :             /*- translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) */
    4557                 :             :                     errmsg("invalid %s behavior for column \"%s\"",
    4558                 :             :                            "ON ERROR", func->column_name),
    4559                 :             :             /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4560                 :             :                     errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns.",
    4561                 :             :                               "ON ERROR"),
    4562                 :             :                     parser_errposition(pstate, func->on_error->location));
    4563                 :             :     }
    4564         [ +  + ]:        2100 :     if (func->op == JSON_VALUE_OP)
    4565                 :             :     {
    4566         [ +  + ]:         728 :         if (func->on_empty != NULL &&
    4567         [ +  + ]:         148 :             func->on_empty->btype != JSON_BEHAVIOR_ERROR &&
    4568         [ +  + ]:         128 :             func->on_empty->btype != JSON_BEHAVIOR_NULL &&
    4569         [ +  + ]:         124 :             func->on_empty->btype != JSON_BEHAVIOR_DEFAULT)
    4570                 :             :         {
    4571         [ -  + ]:           4 :             if (func->column_name == NULL)
    4572         [ #  # ]:           0 :                 ereport(ERROR,
    4573                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4574                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4575                 :             :                         errmsg("invalid %s behavior", "ON EMPTY"),
    4576                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
    4577                 :             :                     second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
    4578                 :             :                         errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s.",
    4579                 :             :                                   "ON EMPTY", "JSON_VALUE()"),
    4580                 :             :                         parser_errposition(pstate, func->on_empty->location));
    4581                 :             :             else
    4582         [ +  - ]:           4 :                 ereport(ERROR,
    4583                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4584                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4585                 :             :                         errmsg("invalid %s behavior for column \"%s\"",
    4586                 :             :                                "ON EMPTY", func->column_name),
    4587                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4588                 :             :                         errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns.",
    4589                 :             :                                   "ON EMPTY"),
    4590                 :             :                         parser_errposition(pstate, func->on_empty->location));
    4591                 :             :         }
    4592         [ +  + ]:         724 :         if (func->on_error != NULL &&
    4593         [ +  + ]:         216 :             func->on_error->btype != JSON_BEHAVIOR_ERROR &&
    4594         [ +  - ]:          96 :             func->on_error->btype != JSON_BEHAVIOR_NULL &&
    4595         [ +  + ]:          96 :             func->on_error->btype != JSON_BEHAVIOR_DEFAULT)
    4596                 :             :         {
    4597         [ +  - ]:           4 :             if (func->column_name == NULL)
    4598         [ +  - ]:           4 :                 ereport(ERROR,
    4599                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4600                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4601                 :             :                         errmsg("invalid %s behavior", "ON ERROR"),
    4602                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
    4603                 :             :                     second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
    4604                 :             :                         errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s.",
    4605                 :             :                                   "ON ERROR", "JSON_VALUE()"),
    4606                 :             :                         parser_errposition(pstate, func->on_error->location));
    4607                 :             :             else
    4608         [ #  # ]:           0 :                 ereport(ERROR,
    4609                 :             :                         errcode(ERRCODE_SYNTAX_ERROR),
    4610                 :             :                 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4611                 :             :                         errmsg("invalid %s behavior for column \"%s\"",
    4612                 :             :                                "ON ERROR", func->column_name),
    4613                 :             :                 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
    4614                 :             :                         errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns.",
    4615                 :             :                                   "ON ERROR"),
    4616                 :             :                         parser_errposition(pstate, func->on_error->location));
    4617                 :             :         }
    4618                 :             :     }
    4619                 :             : 
    4620                 :        2092 :     jsexpr = makeNode(JsonExpr);
    4621                 :        2092 :     jsexpr->location = func->location;
    4622                 :        2092 :     jsexpr->op = func->op;
    4623                 :        2092 :     jsexpr->column_name = func->column_name;
    4624                 :             : 
    4625                 :             :     /*
    4626                 :             :      * jsonpath machinery can only handle jsonb documents, so coerce the input
    4627                 :             :      * if not already of jsonb type.
    4628                 :             :      */
    4629                 :        2092 :     jsexpr->formatted_expr = transformJsonValueExpr(pstate, func_name,
    4630                 :             :                                                     func->context_item,
    4631                 :             :                                                     default_format,
    4632                 :             :                                                     JSONBOID,
    4633                 :             :                                                     false);
    4634                 :        2092 :     jsexpr->format = func->context_item->format;
    4635                 :             : 
    4636                 :        2092 :     path_spec = transformExprRecurse(pstate, func->pathspec);
    4637                 :        2092 :     pathspec_type = exprType(path_spec);
    4638                 :        2092 :     pathspec_loc = exprLocation(path_spec);
    4639                 :        2092 :     coerced_path_spec = coerce_to_target_type(pstate, path_spec,
    4640                 :             :                                               pathspec_type,
    4641                 :             :                                               JSONPATHOID, -1,
    4642                 :             :                                               COERCION_EXPLICIT,
    4643                 :             :                                               COERCE_IMPLICIT_CAST,
    4644                 :             :                                               pathspec_loc);
    4645         [ +  + ]:        2092 :     if (coerced_path_spec == NULL)
    4646         [ +  - ]:           8 :         ereport(ERROR,
    4647                 :             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    4648                 :             :                  errmsg("JSON path expression must be of type %s, not of type %s",
    4649                 :             :                         "jsonpath", format_type_be(pathspec_type)),
    4650                 :             :                  parser_errposition(pstate, pathspec_loc)));
    4651                 :        2084 :     jsexpr->path_spec = coerced_path_spec;
    4652                 :             : 
    4653                 :             :     /* Transform and coerce the PASSING arguments to jsonb. */
    4654                 :        2084 :     transformJsonPassingArgs(pstate, func_name,
    4655                 :             :                              JS_FORMAT_JSONB,
    4656                 :             :                              func->passing,
    4657                 :             :                              &jsexpr->passing_values,
    4658                 :             :                              &jsexpr->passing_names);
    4659                 :             : 
    4660                 :             :     /* Transform the JsonOutput into JsonReturning. */
    4661                 :        2084 :     jsexpr->returning = transformJsonOutput(pstate, func->output, false);
    4662                 :             : 
    4663   [ +  +  +  +  :        2076 :     switch (func->op)
                      - ]
    4664                 :             :     {
    4665                 :         196 :         case JSON_EXISTS_OP:
    4666                 :             :             /* JSON_EXISTS returns boolean by default. */
    4667         [ +  + ]:         196 :             if (!OidIsValid(jsexpr->returning->typid))
    4668                 :             :             {
    4669                 :         108 :                 jsexpr->returning->typid = BOOLOID;
    4670                 :         108 :                 jsexpr->returning->typmod = -1;
    4671                 :         108 :                 jsexpr->collation = InvalidOid;
    4672                 :             :             }
    4673                 :             : 
    4674                 :             :             /* JSON_TABLE() COLUMNS can specify a non-boolean type. */
    4675         [ +  + ]:         196 :             if (jsexpr->returning->typid != BOOLOID)
    4676                 :          80 :                 jsexpr->use_json_coercion = true;
    4677                 :             : 
    4678                 :         196 :             jsexpr->on_error = transformJsonBehavior(pstate,
    4679                 :             :                                                      jsexpr,
    4680                 :             :                                                      func->on_error,
    4681                 :             :                                                      JSON_BEHAVIOR_FALSE,
    4682                 :             :                                                      jsexpr->returning);
    4683                 :         196 :             break;
    4684                 :             : 
    4685                 :         852 :         case JSON_QUERY_OP:
    4686                 :             :             /* JSON_QUERY returns jsonb by default. */
    4687         [ +  + ]:         852 :             if (!OidIsValid(jsexpr->returning->typid))
    4688                 :             :             {
    4689                 :         360 :                 JsonReturning *ret = jsexpr->returning;
    4690                 :             : 
    4691                 :         360 :                 ret->typid = JSONBOID;
    4692                 :         360 :                 ret->typmod = -1;
    4693                 :             :             }
    4694                 :             : 
    4695                 :         852 :             jsexpr->collation = get_typcollation(jsexpr->returning->typid);
    4696                 :             : 
    4697                 :             :             /*
    4698                 :             :              * Keep quotes on scalar strings by default, omitting them only if
    4699                 :             :              * OMIT QUOTES is specified.
    4700                 :             :              */
    4701                 :         852 :             jsexpr->omit_quotes = (func->quotes == JS_QUOTES_OMIT);
    4702                 :         852 :             jsexpr->wrapper = func->wrapper;
    4703                 :             : 
    4704                 :             :             /*
    4705                 :             :              * Set up to coerce the result value of JsonPathValue() to the
    4706                 :             :              * RETURNING type (default or user-specified), if needed.  Also if
    4707                 :             :              * OMIT QUOTES is specified.
    4708                 :             :              */
    4709   [ +  +  +  + ]:         852 :             if (jsexpr->returning->typid != JSONBOID || jsexpr->omit_quotes)
    4710                 :         460 :                 jsexpr->use_json_coercion = true;
    4711                 :             : 
    4712                 :             :             /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
    4713                 :         852 :             jsexpr->on_empty = transformJsonBehavior(pstate,
    4714                 :             :                                                      jsexpr,
    4715                 :             :                                                      func->on_empty,
    4716                 :             :                                                      JSON_BEHAVIOR_NULL,
    4717                 :             :                                                      jsexpr->returning);
    4718                 :             :             /* Assume NULL ON ERROR when ON ERROR is not specified. */
    4719                 :         852 :             jsexpr->on_error = transformJsonBehavior(pstate,
    4720                 :             :                                                      jsexpr,
    4721                 :             :                                                      func->on_error,
    4722                 :             :                                                      JSON_BEHAVIOR_NULL,
    4723                 :             :                                                      jsexpr->returning);
    4724                 :         812 :             break;
    4725                 :             : 
    4726                 :         712 :         case JSON_VALUE_OP:
    4727                 :             :             /* JSON_VALUE returns text by default. */
    4728         [ +  + ]:         712 :             if (!OidIsValid(jsexpr->returning->typid))
    4729                 :             :             {
    4730                 :         116 :                 jsexpr->returning->typid = TEXTOID;
    4731                 :         116 :                 jsexpr->returning->typmod = -1;
    4732                 :             :             }
    4733                 :         712 :             jsexpr->collation = get_typcollation(jsexpr->returning->typid);
    4734                 :             : 
    4735                 :             :             /*
    4736                 :             :              * Override whatever transformJsonOutput() set these to, which
    4737                 :             :              * assumes that output type to be jsonb.
    4738                 :             :              */
    4739                 :         712 :             jsexpr->returning->format->format_type = JS_FORMAT_DEFAULT;
    4740                 :         712 :             jsexpr->returning->format->encoding = JS_ENC_DEFAULT;
    4741                 :             : 
    4742                 :             :             /* Always omit quotes from scalar strings. */
    4743                 :         712 :             jsexpr->omit_quotes = true;
    4744                 :             : 
    4745                 :             :             /*
    4746                 :             :              * Set up to coerce the result value of JsonPathValue() to the
    4747                 :             :              * RETURNING type (default or user-specified), if needed.
    4748                 :             :              */
    4749         [ +  + ]:         712 :             if (jsexpr->returning->typid != TEXTOID)
    4750                 :             :             {
    4751   [ +  +  +  + ]:         668 :                 if (get_typtype(jsexpr->returning->typid) == TYPTYPE_DOMAIN &&
    4752                 :         128 :                     DomainHasConstraints(jsexpr->returning->typid, NULL))
    4753                 :          88 :                     jsexpr->use_json_coercion = true;
    4754                 :             :                 else
    4755                 :         452 :                     jsexpr->use_io_coercion = true;
    4756                 :             :             }
    4757                 :             : 
    4758                 :             :             /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
    4759                 :         712 :             jsexpr->on_empty = transformJsonBehavior(pstate,
    4760                 :             :                                                      jsexpr,
    4761                 :             :                                                      func->on_empty,
    4762                 :             :                                                      JSON_BEHAVIOR_NULL,
    4763                 :             :                                                      jsexpr->returning);
    4764                 :             :             /* Assume NULL ON ERROR when ON ERROR is not specified. */
    4765                 :         696 :             jsexpr->on_error = transformJsonBehavior(pstate,
    4766                 :             :                                                      jsexpr,
    4767                 :             :                                                      func->on_error,
    4768                 :             :                                                      JSON_BEHAVIOR_NULL,
    4769                 :             :                                                      jsexpr->returning);
    4770                 :         692 :             break;
    4771                 :             : 
    4772                 :         316 :         case JSON_TABLE_OP:
    4773         [ +  - ]:         316 :             if (!OidIsValid(jsexpr->returning->typid))
    4774                 :             :             {
    4775                 :         316 :                 jsexpr->returning->typid = exprType(jsexpr->formatted_expr);
    4776                 :         316 :                 jsexpr->returning->typmod = -1;
    4777                 :             :             }
    4778                 :         316 :             jsexpr->collation = get_typcollation(jsexpr->returning->typid);
    4779                 :             : 
    4780                 :             :             /*
    4781                 :             :              * Assume EMPTY ARRAY ON ERROR when ON ERROR is not specified.
    4782                 :             :              *
    4783                 :             :              * ON EMPTY cannot be specified at the top level but it can be for
    4784                 :             :              * the individual columns.
    4785                 :             :              */
    4786                 :         316 :             jsexpr->on_error = transformJsonBehavior(pstate,
    4787                 :             :                                                      jsexpr,
    4788                 :             :                                                      func->on_error,
    4789                 :             :                                                      JSON_BEHAVIOR_EMPTY_ARRAY,
    4790                 :             :                                                      jsexpr->returning);
    4791                 :         316 :             break;
    4792                 :             : 
    4793                 :           0 :         default:
    4794         [ #  # ]:           0 :             elog(ERROR, "invalid JsonFuncExpr op %d", (int) func->op);
    4795                 :             :             break;
    4796                 :             :     }
    4797                 :             : 
    4798                 :        2016 :     return (Node *) jsexpr;
    4799                 :             : }
    4800                 :             : 
    4801                 :             : /*
    4802                 :             :  * Transform a SQL/JSON PASSING clause.
    4803                 :             :  */
    4804                 :             : static void
    4805                 :        2084 : transformJsonPassingArgs(ParseState *pstate, const char *constructName,
    4806                 :             :                          JsonFormatType format, List *args,
    4807                 :             :                          List **passing_values, List **passing_names)
    4808                 :             : {
    4809                 :             :     ListCell   *lc;
    4810                 :             : 
    4811                 :        2084 :     *passing_values = NIL;
    4812                 :        2084 :     *passing_names = NIL;
    4813                 :             : 
    4814   [ +  +  +  +  :        2884 :     foreach(lc, args)
                   +  + ]
    4815                 :             :     {
    4816                 :         800 :         JsonArgument *arg = castNode(JsonArgument, lfirst(lc));
    4817                 :         800 :         Node       *expr = transformJsonValueExpr(pstate, constructName,
    4818                 :             :                                                   arg->val, format,
    4819                 :             :                                                   InvalidOid, true);
    4820                 :             : 
    4821                 :         800 :         *passing_values = lappend(*passing_values, expr);
    4822                 :         800 :         *passing_names = lappend(*passing_names, makeString(arg->name));
    4823                 :             :     }
    4824                 :        2084 : }
    4825                 :             : 
    4826                 :             : /*
    4827                 :             :  * Recursively checks if the given expression, or its sub-node in some cases,
    4828                 :             :  * is valid for using as an ON ERROR / ON EMPTY DEFAULT expression.
    4829                 :             :  */
    4830                 :             : static bool
    4831                 :         388 : ValidJsonBehaviorDefaultExpr(Node *expr, void *context)
    4832                 :             : {
    4833         [ -  + ]:         388 :     if (expr == NULL)
    4834                 :           0 :         return false;
    4835                 :             : 
    4836      [ +  +  + ]:         388 :     switch (nodeTag(expr))
    4837                 :             :     {
    4838                 :             :             /* Acceptable expression nodes */
    4839                 :         248 :         case T_Const:
    4840                 :             :         case T_FuncExpr:
    4841                 :             :         case T_OpExpr:
    4842                 :         248 :             return true;
    4843                 :             : 
    4844                 :             :             /* Acceptable iff arg of the following nodes is one of the above */
    4845                 :         104 :         case T_CoerceViaIO:
    4846                 :             :         case T_CoerceToDomain:
    4847                 :             :         case T_ArrayCoerceExpr:
    4848                 :             :         case T_ConvertRowtypeExpr:
    4849                 :             :         case T_RelabelType:
    4850                 :             :         case T_CollateExpr:
    4851                 :         104 :             return expression_tree_walker(expr, ValidJsonBehaviorDefaultExpr,
    4852                 :             :                                           context);
    4853                 :          36 :         default:
    4854                 :          36 :             break;
    4855                 :             :     }
    4856                 :             : 
    4857                 :          36 :     return false;
    4858                 :             : }
    4859                 :             : 
    4860                 :             : /*
    4861                 :             :  * Transform a JSON BEHAVIOR clause.
    4862                 :             :  */
    4863                 :             : static JsonBehavior *
    4864                 :        3624 : transformJsonBehavior(ParseState *pstate, JsonExpr *jsexpr,
    4865                 :             :                       JsonBehavior *behavior,
    4866                 :             :                       JsonBehaviorType default_behavior,
    4867                 :             :                       JsonReturning *returning)
    4868                 :             : {
    4869                 :        3624 :     JsonBehaviorType btype = default_behavior;
    4870                 :        3624 :     Node       *expr = NULL;
    4871                 :        3624 :     bool        coerce_at_runtime = false;
    4872                 :        3624 :     int         location = -1;
    4873                 :             : 
    4874         [ +  + ]:        3624 :     if (behavior)
    4875                 :             :     {
    4876                 :         708 :         btype = behavior->btype;
    4877                 :         708 :         location = behavior->location;
    4878         [ +  + ]:         708 :         if (btype == JSON_BEHAVIOR_DEFAULT)
    4879                 :             :         {
    4880                 :         280 :             Oid         targetcoll = jsexpr->collation;
    4881                 :             :             Oid         exprcoll;
    4882                 :             : 
    4883                 :         280 :             expr = transformExprRecurse(pstate, behavior->expr);
    4884                 :             : 
    4885         [ +  + ]:         280 :             if (!ValidJsonBehaviorDefaultExpr(expr, NULL))
    4886         [ +  - ]:          32 :                 ereport(ERROR,
    4887                 :             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    4888                 :             :                          errmsg("can only specify a constant, non-aggregate function, or operator expression for DEFAULT"),
    4889                 :             :                          parser_errposition(pstate, exprLocation(expr))));
    4890         [ +  + ]:         248 :             if (contain_var_clause(expr))
    4891         [ +  - ]:           4 :                 ereport(ERROR,
    4892                 :             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    4893                 :             :                          errmsg("DEFAULT expression must not contain column references"),
    4894                 :             :                          parser_errposition(pstate, exprLocation(expr))));
    4895         [ +  + ]:         244 :             if (expression_returns_set(expr))
    4896         [ +  - ]:           4 :                 ereport(ERROR,
    4897                 :             :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    4898                 :             :                          errmsg("DEFAULT expression must not return a set"),
    4899                 :             :                          parser_errposition(pstate, exprLocation(expr))));
    4900                 :             : 
    4901                 :             :             /*
    4902                 :             :              * Reject a DEFAULT expression whose collation differs from the
    4903                 :             :              * enclosing JSON expression's result collation
    4904                 :             :              * (jsexpr->collation), as chosen by the RETURNING clause.
    4905                 :             :              */
    4906                 :         240 :             exprcoll = exprCollation(expr);
    4907         [ +  + ]:         240 :             if (!OidIsValid(exprcoll))
    4908                 :         224 :                 exprcoll = get_typcollation(exprType(expr));
    4909   [ +  +  +  +  :         240 :             if (OidIsValid(targetcoll) && OidIsValid(exprcoll) &&
                   +  + ]
    4910                 :             :                 targetcoll != exprcoll)
    4911         [ +  - ]:          16 :                 ereport(ERROR,
    4912                 :             :                         errcode(ERRCODE_COLLATION_MISMATCH),
    4913                 :             :                         errmsg("collation of DEFAULT expression conflicts with RETURNING clause"),
    4914                 :             :                         errdetail("\"%s\" versus \"%s\"",
    4915                 :             :                                   get_collation_name(exprcoll),
    4916                 :             :                                   get_collation_name(targetcoll)),
    4917                 :             :                         parser_errposition(pstate, exprLocation(expr)));
    4918                 :             :         }
    4919                 :             :     }
    4920                 :             : 
    4921   [ +  +  +  + ]:        3568 :     if (expr == NULL && btype != JSON_BEHAVIOR_ERROR)
    4922                 :        3020 :         expr = GetJsonBehaviorConst(btype, location);
    4923                 :             : 
    4924                 :             :     /*
    4925                 :             :      * Try to coerce the expression if needed.
    4926                 :             :      *
    4927                 :             :      * Use runtime coercion using json_populate_type() if the expression is
    4928                 :             :      * NULL, jsonb-valued, or boolean-valued (unless the target type is
    4929                 :             :      * integer or domain over integer, in which case use the
    4930                 :             :      * boolean-to-integer cast function).
    4931                 :             :      *
    4932                 :             :      * For other non-NULL expressions, try to find a cast and error out if one
    4933                 :             :      * is not found.
    4934                 :             :      */
    4935   [ +  +  +  + ]:        3568 :     if (expr && exprType(expr) != returning->typid)
    4936                 :             :     {
    4937   [ +  +  +  + ]:        2244 :         bool        isnull = (IsA(expr, Const) && ((Const *) expr)->constisnull);
    4938                 :             : 
    4939   [ +  +  +  + ]:        2452 :         if (isnull ||
    4940         [ +  + ]:         388 :             exprType(expr) == JSONBOID ||
    4941         [ +  + ]:         232 :             (exprType(expr) == BOOLOID &&
    4942                 :          52 :              getBaseType(returning->typid) != INT4OID))
    4943                 :             :         {
    4944                 :        2092 :             coerce_at_runtime = true;
    4945                 :             : 
    4946                 :             :             /*
    4947                 :             :              * json_populate_type() expects to be passed a jsonb value, so gin
    4948                 :             :              * up a Const containing the appropriate boolean value represented
    4949                 :             :              * as jsonb, discarding the original Const containing a plain
    4950                 :             :              * boolean.
    4951                 :             :              */
    4952         [ +  + ]:        2120 :             if (exprType(expr) == BOOLOID)
    4953                 :             :             {
    4954         [ -  + ]:          28 :                 char       *val = btype == JSON_BEHAVIOR_TRUE ? "true" : "false";
    4955                 :             : 
    4956                 :          28 :                 expr = (Node *) makeConst(JSONBOID, -1, InvalidOid, -1,
    4957                 :             :                                           DirectFunctionCall1(jsonb_in,
    4958                 :             :                                                               CStringGetDatum(val)),
    4959                 :             :                                           false, false);
    4960                 :             :             }
    4961                 :             :         }
    4962                 :             :         else
    4963                 :             :         {
    4964                 :             :             Node       *coerced_expr;
    4965                 :         152 :             char        typcategory = TypeCategory(returning->typid);
    4966                 :             : 
    4967                 :             :             /*
    4968                 :             :              * Use an assignment cast if coercing to a string type so that
    4969                 :             :              * build_coercion_expression() assumes implicit coercion when
    4970                 :             :              * coercing the typmod, so that inputs exceeding length cause an
    4971                 :             :              * error instead of silent truncation.
    4972                 :             :              */
    4973                 :             :             coerced_expr =
    4974         [ +  + ]:         216 :                 coerce_to_target_type(pstate, expr, exprType(expr),
    4975                 :             :                                       returning->typid, returning->typmod,
    4976         [ +  + ]:          64 :                                       (typcategory == TYPCATEGORY_STRING ||
    4977                 :             :                                        typcategory == TYPCATEGORY_BITSTRING) ?
    4978                 :             :                                       COERCION_ASSIGNMENT :
    4979                 :             :                                       COERCION_EXPLICIT,
    4980                 :             :                                       COERCE_EXPLICIT_CAST,
    4981                 :             :                                       exprLocation((Node *) behavior));
    4982                 :             : 
    4983         [ +  + ]:         152 :             if (coerced_expr == NULL)
    4984                 :             :             {
    4985                 :             :                 /*
    4986                 :             :                  * Provide a HINT if the expression comes from a DEFAULT
    4987                 :             :                  * clause.
    4988                 :             :                  */
    4989         [ +  - ]:           4 :                 if (btype == JSON_BEHAVIOR_DEFAULT)
    4990         [ +  - ]:           4 :                     ereport(ERROR,
    4991                 :             :                             errcode(ERRCODE_CANNOT_COERCE),
    4992                 :             :                             errmsg("cannot cast behavior expression of type %s to %s",
    4993                 :             :                                    format_type_be(exprType(expr)),
    4994                 :             :                                    format_type_be(returning->typid)),
    4995                 :             :                             errhint("You will need to explicitly cast the expression to type %s.",
    4996                 :             :                                     format_type_be(returning->typid)),
    4997                 :             :                             parser_errposition(pstate, exprLocation(expr)));
    4998                 :             :                 else
    4999         [ #  # ]:           0 :                     ereport(ERROR,
    5000                 :             :                             errcode(ERRCODE_CANNOT_COERCE),
    5001                 :             :                             errmsg("cannot cast behavior expression of type %s to %s",
    5002                 :             :                                    format_type_be(exprType(expr)),
    5003                 :             :                                    format_type_be(returning->typid)),
    5004                 :             :                             parser_errposition(pstate, exprLocation(expr)));
    5005                 :             :             }
    5006                 :             : 
    5007                 :         148 :             expr = coerced_expr;
    5008                 :             :         }
    5009                 :             :     }
    5010                 :             : 
    5011         [ +  + ]:        3564 :     if (behavior)
    5012                 :         648 :         behavior->expr = expr;
    5013                 :             :     else
    5014                 :        2916 :         behavior = makeJsonBehavior(btype, expr, location);
    5015                 :             : 
    5016                 :        3564 :     behavior->coerce = coerce_at_runtime;
    5017                 :             : 
    5018                 :        3564 :     return behavior;
    5019                 :             : }
    5020                 :             : 
    5021                 :             : /*
    5022                 :             :  * Returns a Const node holding the value for the given non-ERROR
    5023                 :             :  * JsonBehaviorType.
    5024                 :             :  */
    5025                 :             : static Node *
    5026                 :        3020 : GetJsonBehaviorConst(JsonBehaviorType btype, int location)
    5027                 :             : {
    5028                 :        3020 :     Datum       val = (Datum) 0;
    5029                 :        3020 :     Oid         typid = JSONBOID;
    5030                 :        3020 :     int         len = -1;
    5031                 :        3020 :     bool        isbyval = false;
    5032                 :        3020 :     bool        isnull = false;
    5033                 :             :     Const      *con;
    5034                 :             : 
    5035   [ +  +  +  +  :        3020 :     switch (btype)
                +  -  - ]
    5036                 :             :     {
    5037                 :         320 :         case JSON_BEHAVIOR_EMPTY_ARRAY:
    5038                 :         320 :             val = DirectFunctionCall1(jsonb_in, CStringGetDatum("[]"));
    5039                 :         320 :             break;
    5040                 :             : 
    5041                 :          36 :         case JSON_BEHAVIOR_EMPTY_OBJECT:
    5042                 :          36 :             val = DirectFunctionCall1(jsonb_in, CStringGetDatum("{}"));
    5043                 :          36 :             break;
    5044                 :             : 
    5045                 :           8 :         case JSON_BEHAVIOR_TRUE:
    5046                 :           8 :             val = BoolGetDatum(true);
    5047                 :           8 :             typid = BOOLOID;
    5048                 :           8 :             len = sizeof(bool);
    5049                 :           8 :             isbyval = true;
    5050                 :           8 :             break;
    5051                 :             : 
    5052                 :         152 :         case JSON_BEHAVIOR_FALSE:
    5053                 :         152 :             val = BoolGetDatum(false);
    5054                 :         152 :             typid = BOOLOID;
    5055                 :         152 :             len = sizeof(bool);
    5056                 :         152 :             isbyval = true;
    5057                 :         152 :             break;
    5058                 :             : 
    5059                 :        2504 :         case JSON_BEHAVIOR_NULL:
    5060                 :             :         case JSON_BEHAVIOR_UNKNOWN:
    5061                 :             :         case JSON_BEHAVIOR_EMPTY:
    5062                 :        2504 :             val = (Datum) 0;
    5063                 :        2504 :             isnull = true;
    5064                 :        2504 :             typid = INT4OID;
    5065                 :        2504 :             len = sizeof(int32);
    5066                 :        2504 :             isbyval = true;
    5067                 :        2504 :             break;
    5068                 :             : 
    5069                 :             :             /* These two behavior types are handled by the caller. */
    5070                 :           0 :         case JSON_BEHAVIOR_DEFAULT:
    5071                 :             :         case JSON_BEHAVIOR_ERROR:
    5072                 :             :             Assert(false);
    5073                 :           0 :             break;
    5074                 :             : 
    5075                 :           0 :         default:
    5076         [ #  # ]:           0 :             elog(ERROR, "unrecognized SQL/JSON behavior %d", btype);
    5077                 :             :             break;
    5078                 :             :     }
    5079                 :             : 
    5080                 :        3020 :     con = makeConst(typid, -1, InvalidOid, len, val, isnull, isbyval);
    5081                 :        3020 :     con->location = location;
    5082                 :             : 
    5083                 :        3020 :     return (Node *) con;
    5084                 :             : }
        

Generated by: LCOV version 2.0-1