LCOV - code coverage report
Current view: top level - src/backend/parser - parse_expr.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 90.1 % 2208 1989
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 62 62
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 65.9 % 1410 929

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

Generated by: LCOV version 2.3.2-1