LCOV - code coverage report
Current view: top level - src/backend/parser - analyze.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 814 902 90.2 %
Date: 2020-06-01 00:06:26 Functions: 30 31 96.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * analyze.c
       4             :  *    transform the raw parse tree into a query tree
       5             :  *
       6             :  * For optimizable statements, we are careful to obtain a suitable lock on
       7             :  * each referenced table, and other modules of the backend preserve or
       8             :  * re-obtain these locks before depending on the results.  It is therefore
       9             :  * okay to do significant semantic analysis of these statements.  For
      10             :  * utility commands, no locks are obtained here (and if they were, we could
      11             :  * not be sure we'd still have them at execution).  Hence the general rule
      12             :  * for utility commands is to just dump them into a Query node untransformed.
      13             :  * DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are exceptions because they
      14             :  * contain optimizable statements, which we should transform.
      15             :  *
      16             :  *
      17             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
      18             :  * Portions Copyright (c) 1994, Regents of the University of California
      19             :  *
      20             :  *  src/backend/parser/analyze.c
      21             :  *
      22             :  *-------------------------------------------------------------------------
      23             :  */
      24             : 
      25             : #include "postgres.h"
      26             : 
      27             : #include "access/sysattr.h"
      28             : #include "catalog/pg_type.h"
      29             : #include "miscadmin.h"
      30             : #include "nodes/makefuncs.h"
      31             : #include "nodes/nodeFuncs.h"
      32             : #include "optimizer/optimizer.h"
      33             : #include "parser/analyze.h"
      34             : #include "parser/parse_agg.h"
      35             : #include "parser/parse_clause.h"
      36             : #include "parser/parse_coerce.h"
      37             : #include "parser/parse_collate.h"
      38             : #include "parser/parse_cte.h"
      39             : #include "parser/parse_expr.h"
      40             : #include "parser/parse_func.h"
      41             : #include "parser/parse_oper.h"
      42             : #include "parser/parse_param.h"
      43             : #include "parser/parse_relation.h"
      44             : #include "parser/parse_target.h"
      45             : #include "parser/parsetree.h"
      46             : #include "rewrite/rewriteManip.h"
      47             : #include "utils/rel.h"
      48             : 
      49             : 
      50             : /* Hook for plugins to get control at end of parse analysis */
      51             : post_parse_analyze_hook_type post_parse_analyze_hook = NULL;
      52             : 
      53             : static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree);
      54             : static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
      55             : static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
      56             : static List *transformInsertRow(ParseState *pstate, List *exprlist,
      57             :                                 List *stmtcols, List *icolumns, List *attrnos,
      58             :                                 bool strip_indirection);
      59             : static OnConflictExpr *transformOnConflictClause(ParseState *pstate,
      60             :                                                  OnConflictClause *onConflictClause);
      61             : static int  count_rowexpr_columns(ParseState *pstate, Node *expr);
      62             : static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
      63             : static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt);
      64             : static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
      65             : static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
      66             :                                        bool isTopLevel, List **targetlist);
      67             : static void determineRecursiveColTypes(ParseState *pstate,
      68             :                                        Node *larg, List *nrtargetlist);
      69             : static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
      70             : static List *transformReturningList(ParseState *pstate, List *returningList);
      71             : static List *transformUpdateTargetList(ParseState *pstate,
      72             :                                        List *targetList);
      73             : static Query *transformDeclareCursorStmt(ParseState *pstate,
      74             :                                          DeclareCursorStmt *stmt);
      75             : static Query *transformExplainStmt(ParseState *pstate,
      76             :                                    ExplainStmt *stmt);
      77             : static Query *transformCreateTableAsStmt(ParseState *pstate,
      78             :                                          CreateTableAsStmt *stmt);
      79             : static Query *transformCallStmt(ParseState *pstate,
      80             :                                 CallStmt *stmt);
      81             : static void transformLockingClause(ParseState *pstate, Query *qry,
      82             :                                    LockingClause *lc, bool pushedDown);
      83             : #ifdef RAW_EXPRESSION_COVERAGE_TEST
      84             : static bool test_raw_expression_coverage(Node *node, void *context);
      85             : #endif
      86             : 
      87             : 
      88             : /*
      89             :  * parse_analyze
      90             :  *      Analyze a raw parse tree and transform it to Query form.
      91             :  *
      92             :  * Optionally, information about $n parameter types can be supplied.
      93             :  * References to $n indexes not defined by paramTypes[] are disallowed.
      94             :  *
      95             :  * The result is a Query node.  Optimizable statements require considerable
      96             :  * transformation, while utility-type statements are simply hung off
      97             :  * a dummy CMD_UTILITY Query node.
      98             :  */
      99             : Query *
     100      583116 : parse_analyze(RawStmt *parseTree, const char *sourceText,
     101             :               Oid *paramTypes, int numParams,
     102             :               QueryEnvironment *queryEnv)
     103             : {
     104      583116 :     ParseState *pstate = make_parsestate(NULL);
     105             :     Query      *query;
     106             : 
     107             :     Assert(sourceText != NULL); /* required as of 8.4 */
     108             : 
     109      583116 :     pstate->p_sourcetext = sourceText;
     110             : 
     111      583116 :     if (numParams > 0)
     112        3056 :         parse_fixed_parameters(pstate, paramTypes, numParams);
     113             : 
     114      583116 :     pstate->p_queryEnv = queryEnv;
     115             : 
     116      583116 :     query = transformTopLevelStmt(pstate, parseTree);
     117             : 
     118      579844 :     if (post_parse_analyze_hook)
     119         356 :         (*post_parse_analyze_hook) (pstate, query);
     120             : 
     121      579844 :     free_parsestate(pstate);
     122             : 
     123      579844 :     return query;
     124             : }
     125             : 
     126             : /*
     127             :  * parse_analyze_varparams
     128             :  *
     129             :  * This variant is used when it's okay to deduce information about $n
     130             :  * symbol datatypes from context.  The passed-in paramTypes[] array can
     131             :  * be modified or enlarged (via repalloc).
     132             :  */
     133             : Query *
     134        8544 : parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
     135             :                         Oid **paramTypes, int *numParams)
     136             : {
     137        8544 :     ParseState *pstate = make_parsestate(NULL);
     138             :     Query      *query;
     139             : 
     140             :     Assert(sourceText != NULL); /* required as of 8.4 */
     141             : 
     142        8544 :     pstate->p_sourcetext = sourceText;
     143             : 
     144        8544 :     parse_variable_parameters(pstate, paramTypes, numParams);
     145             : 
     146        8544 :     query = transformTopLevelStmt(pstate, parseTree);
     147             : 
     148             :     /* make sure all is well with parameter types */
     149        8544 :     check_variable_parameters(pstate, query);
     150             : 
     151        8544 :     if (post_parse_analyze_hook)
     152           4 :         (*post_parse_analyze_hook) (pstate, query);
     153             : 
     154        8544 :     free_parsestate(pstate);
     155             : 
     156        8544 :     return query;
     157             : }
     158             : 
     159             : /*
     160             :  * parse_sub_analyze
     161             :  *      Entry point for recursively analyzing a sub-statement.
     162             :  */
     163             : Query *
     164      115596 : parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
     165             :                   CommonTableExpr *parentCTE,
     166             :                   bool locked_from_parent,
     167             :                   bool resolve_unknowns)
     168             : {
     169      115596 :     ParseState *pstate = make_parsestate(parentParseState);
     170             :     Query      *query;
     171             : 
     172      115596 :     pstate->p_parent_cte = parentCTE;
     173      115596 :     pstate->p_locked_from_parent = locked_from_parent;
     174      115596 :     pstate->p_resolve_unknowns = resolve_unknowns;
     175             : 
     176      115596 :     query = transformStmt(pstate, parseTree);
     177             : 
     178      115470 :     free_parsestate(pstate);
     179             : 
     180      115470 :     return query;
     181             : }
     182             : 
     183             : /*
     184             :  * transformTopLevelStmt -
     185             :  *    transform a Parse tree into a Query tree.
     186             :  *
     187             :  * This function is just responsible for transferring statement location data
     188             :  * from the RawStmt into the finished Query.
     189             :  */
     190             : Query *
     191      636216 : transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
     192             : {
     193             :     Query      *result;
     194             : 
     195             :     /* We're at top level, so allow SELECT INTO */
     196      636216 :     result = transformOptionalSelectInto(pstate, parseTree->stmt);
     197             : 
     198      632894 :     result->stmt_location = parseTree->stmt_location;
     199      632894 :     result->stmt_len = parseTree->stmt_len;
     200             : 
     201      632894 :     return result;
     202             : }
     203             : 
     204             : /*
     205             :  * transformOptionalSelectInto -
     206             :  *    If SELECT has INTO, convert it to CREATE TABLE AS.
     207             :  *
     208             :  * The only thing we do here that we don't do in transformStmt() is to
     209             :  * convert SELECT ... INTO into CREATE TABLE AS.  Since utility statements
     210             :  * aren't allowed within larger statements, this is only allowed at the top
     211             :  * of the parse tree, and so we only try it before entering the recursive
     212             :  * transformStmt() processing.
     213             :  */
     214             : static Query *
     215      646622 : transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
     216             : {
     217      646622 :     if (IsA(parseTree, SelectStmt))
     218             :     {
     219      244174 :         SelectStmt *stmt = (SelectStmt *) parseTree;
     220             : 
     221             :         /* If it's a set-operation tree, drill down to leftmost SelectStmt */
     222      253250 :         while (stmt && stmt->op != SETOP_NONE)
     223        9076 :             stmt = stmt->larg;
     224             :         Assert(stmt && IsA(stmt, SelectStmt) && stmt->larg == NULL);
     225             : 
     226      244174 :         if (stmt->intoClause)
     227             :         {
     228         104 :             CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
     229             : 
     230         104 :             ctas->query = parseTree;
     231         104 :             ctas->into = stmt->intoClause;
     232         104 :             ctas->relkind = OBJECT_TABLE;
     233         104 :             ctas->is_select_into = true;
     234             : 
     235             :             /*
     236             :              * Remove the intoClause from the SelectStmt.  This makes it safe
     237             :              * for transformSelectStmt to complain if it finds intoClause set
     238             :              * (implying that the INTO appeared in a disallowed place).
     239             :              */
     240         104 :             stmt->intoClause = NULL;
     241             : 
     242         104 :             parseTree = (Node *) ctas;
     243             :         }
     244             :     }
     245             : 
     246      646622 :     return transformStmt(pstate, parseTree);
     247             : }
     248             : 
     249             : /*
     250             :  * transformStmt -
     251             :  *    recursively transform a Parse tree into a Query tree.
     252             :  */
     253             : Query *
     254      781342 : transformStmt(ParseState *pstate, Node *parseTree)
     255             : {
     256             :     Query      *result;
     257             : 
     258             :     /*
     259             :      * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements;
     260             :      * we can't just run it on everything because raw_expression_tree_walker()
     261             :      * doesn't claim to handle utility statements.
     262             :      */
     263             : #ifdef RAW_EXPRESSION_COVERAGE_TEST
     264      781342 :     switch (nodeTag(parseTree))
     265             :     {
     266      452132 :         case T_SelectStmt:
     267             :         case T_InsertStmt:
     268             :         case T_UpdateStmt:
     269             :         case T_DeleteStmt:
     270      452132 :             (void) test_raw_expression_coverage(parseTree, NULL);
     271      452132 :             break;
     272      329210 :         default:
     273      329210 :             break;
     274             :     }
     275             : #endif                          /* RAW_EXPRESSION_COVERAGE_TEST */
     276             : 
     277      781342 :     switch (nodeTag(parseTree))
     278             :     {
     279             :             /*
     280             :              * Optimizable statements
     281             :              */
     282       60906 :         case T_InsertStmt:
     283       60906 :             result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
     284       60044 :             break;
     285             : 
     286        3140 :         case T_DeleteStmt:
     287        3140 :             result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
     288        3104 :             break;
     289             : 
     290        9972 :         case T_UpdateStmt:
     291        9972 :             result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
     292        9922 :             break;
     293             : 
     294      378114 :         case T_SelectStmt:
     295             :             {
     296      378114 :                 SelectStmt *n = (SelectStmt *) parseTree;
     297             : 
     298      378114 :                 if (n->valuesLists)
     299        2538 :                     result = transformValuesClause(pstate, n);
     300      375576 :                 else if (n->op == SETOP_NONE)
     301      365690 :                     result = transformSelectStmt(pstate, n);
     302             :                 else
     303        9886 :                     result = transformSetOperationStmt(pstate, n);
     304             :             }
     305      375622 :             break;
     306             : 
     307             :             /*
     308             :              * Special cases
     309             :              */
     310        2032 :         case T_DeclareCursorStmt:
     311        2032 :             result = transformDeclareCursorStmt(pstate,
     312             :                                                 (DeclareCursorStmt *) parseTree);
     313        2020 :             break;
     314             : 
     315       10406 :         case T_ExplainStmt:
     316       10406 :             result = transformExplainStmt(pstate,
     317             :                                           (ExplainStmt *) parseTree);
     318       10402 :             break;
     319             : 
     320         954 :         case T_CreateTableAsStmt:
     321         954 :             result = transformCreateTableAsStmt(pstate,
     322             :                                                 (CreateTableAsStmt *) parseTree);
     323         954 :             break;
     324             : 
     325         260 :         case T_CallStmt:
     326         260 :             result = transformCallStmt(pstate,
     327             :                                        (CallStmt *) parseTree);
     328         244 :             break;
     329             : 
     330      315558 :         default:
     331             : 
     332             :             /*
     333             :              * other statements don't require any transformation; just return
     334             :              * the original parsetree with a Query node plastered on top.
     335             :              */
     336      315558 :             result = makeNode(Query);
     337      315558 :             result->commandType = CMD_UTILITY;
     338      315558 :             result->utilityStmt = (Node *) parseTree;
     339      315558 :             break;
     340             :     }
     341             : 
     342             :     /* Mark as original query until we learn differently */
     343      777870 :     result->querySource = QSRC_ORIGINAL;
     344      777870 :     result->canSetTag = true;
     345             : 
     346      777870 :     return result;
     347             : }
     348             : 
     349             : /*
     350             :  * analyze_requires_snapshot
     351             :  *      Returns true if a snapshot must be set before doing parse analysis
     352             :  *      on the given raw parse tree.
     353             :  *
     354             :  * Classification here should match transformStmt().
     355             :  */
     356             : bool
     357      527540 : analyze_requires_snapshot(RawStmt *parseTree)
     358             : {
     359             :     bool        result;
     360             : 
     361      527540 :     switch (nodeTag(parseTree->stmt))
     362             :     {
     363             :             /*
     364             :              * Optimizable statements
     365             :              */
     366      208422 :         case T_InsertStmt:
     367             :         case T_DeleteStmt:
     368             :         case T_UpdateStmt:
     369             :         case T_SelectStmt:
     370      208422 :             result = true;
     371      208422 :             break;
     372             : 
     373             :             /*
     374             :              * Special cases
     375             :              */
     376       10844 :         case T_DeclareCursorStmt:
     377             :         case T_ExplainStmt:
     378             :         case T_CreateTableAsStmt:
     379             :             /* yes, because we must analyze the contained statement */
     380       10844 :             result = true;
     381       10844 :             break;
     382             : 
     383      308274 :         default:
     384             :             /* other utility statements don't have any real parse analysis */
     385      308274 :             result = false;
     386      308274 :             break;
     387             :     }
     388             : 
     389      527540 :     return result;
     390             : }
     391             : 
     392             : /*
     393             :  * transformDeleteStmt -
     394             :  *    transforms a Delete Statement
     395             :  */
     396             : static Query *
     397        3140 : transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
     398             : {
     399        3140 :     Query      *qry = makeNode(Query);
     400             :     ParseNamespaceItem *nsitem;
     401             :     Node       *qual;
     402             : 
     403        3140 :     qry->commandType = CMD_DELETE;
     404             : 
     405             :     /* process the WITH clause independently of all else */
     406        3140 :     if (stmt->withClause)
     407             :     {
     408          20 :         qry->hasRecursive = stmt->withClause->recursive;
     409          20 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
     410          20 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
     411             :     }
     412             : 
     413             :     /* set up range table with just the result rel */
     414        6276 :     qry->resultRelation = setTargetTable(pstate, stmt->relation,
     415        3140 :                                          stmt->relation->inh,
     416             :                                          true,
     417             :                                          ACL_DELETE);
     418        3136 :     nsitem = pstate->p_target_nsitem;
     419             : 
     420             :     /* there's no DISTINCT in DELETE */
     421        3136 :     qry->distinctClause = NIL;
     422             : 
     423             :     /* subqueries in USING cannot access the result relation */
     424        3136 :     nsitem->p_lateral_only = true;
     425        3136 :     nsitem->p_lateral_ok = false;
     426             : 
     427             :     /*
     428             :      * The USING clause is non-standard SQL syntax, and is equivalent in
     429             :      * functionality to the FROM list that can be specified for UPDATE. The
     430             :      * USING keyword is used rather than FROM because FROM is already a
     431             :      * keyword in the DELETE syntax.
     432             :      */
     433        3136 :     transformFromClause(pstate, stmt->usingClause);
     434             : 
     435             :     /* remaining clauses can reference the result relation normally */
     436        3124 :     nsitem->p_lateral_only = false;
     437        3124 :     nsitem->p_lateral_ok = true;
     438             : 
     439        3124 :     qual = transformWhereClause(pstate, stmt->whereClause,
     440             :                                 EXPR_KIND_WHERE, "WHERE");
     441             : 
     442        3108 :     qry->returningList = transformReturningList(pstate, stmt->returningList);
     443             : 
     444             :     /* done building the range table and jointree */
     445        3104 :     qry->rtable = pstate->p_rtable;
     446        3104 :     qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
     447             : 
     448        3104 :     qry->hasSubLinks = pstate->p_hasSubLinks;
     449        3104 :     qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
     450        3104 :     qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
     451        3104 :     qry->hasAggs = pstate->p_hasAggs;
     452             : 
     453        3104 :     assign_query_collations(pstate, qry);
     454             : 
     455             :     /* this must be done after collations, for reliable comparison of exprs */
     456        3104 :     if (pstate->p_hasAggs)
     457           0 :         parseCheckAggregates(pstate, qry);
     458             : 
     459        3104 :     return qry;
     460             : }
     461             : 
     462             : /*
     463             :  * transformInsertStmt -
     464             :  *    transform an Insert Statement
     465             :  */
     466             : static Query *
     467       60906 : transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
     468             : {
     469       60906 :     Query      *qry = makeNode(Query);
     470       60906 :     SelectStmt *selectStmt = (SelectStmt *) stmt->selectStmt;
     471       60906 :     List       *exprList = NIL;
     472             :     bool        isGeneralSelect;
     473             :     List       *sub_rtable;
     474             :     List       *sub_namespace;
     475             :     List       *icolumns;
     476             :     List       *attrnos;
     477             :     ParseNamespaceItem *nsitem;
     478             :     RangeTblEntry *rte;
     479             :     ListCell   *icols;
     480             :     ListCell   *attnos;
     481             :     ListCell   *lc;
     482             :     bool        isOnConflictUpdate;
     483             :     AclMode     targetPerms;
     484             : 
     485             :     /* There can't be any outer WITH to worry about */
     486             :     Assert(pstate->p_ctenamespace == NIL);
     487             : 
     488       60906 :     qry->commandType = CMD_INSERT;
     489       60906 :     pstate->p_is_insert = true;
     490             : 
     491             :     /* process the WITH clause independently of all else */
     492       60906 :     if (stmt->withClause)
     493             :     {
     494         442 :         qry->hasRecursive = stmt->withClause->recursive;
     495         442 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
     496         442 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
     497             :     }
     498             : 
     499       60906 :     qry->override = stmt->override;
     500             : 
     501       61914 :     isOnConflictUpdate = (stmt->onConflictClause &&
     502        1008 :                           stmt->onConflictClause->action == ONCONFLICT_UPDATE);
     503             : 
     504             :     /*
     505             :      * We have three cases to deal with: DEFAULT VALUES (selectStmt == NULL),
     506             :      * VALUES list, or general SELECT input.  We special-case VALUES, both for
     507             :      * efficiency and so we can handle DEFAULT specifications.
     508             :      *
     509             :      * The grammar allows attaching ORDER BY, LIMIT, FOR UPDATE, or WITH to a
     510             :      * VALUES clause.  If we have any of those, treat it as a general SELECT;
     511             :      * so it will work, but you can't use DEFAULT items together with those.
     512             :      */
     513      106094 :     isGeneralSelect = (selectStmt && (selectStmt->valuesLists == NIL ||
     514       45188 :                                       selectStmt->sortClause != NIL ||
     515       45188 :                                       selectStmt->limitOffset != NULL ||
     516       45188 :                                       selectStmt->limitCount != NULL ||
     517       45188 :                                       selectStmt->lockingClause != NIL ||
     518       45188 :                                       selectStmt->withClause != NULL));
     519             : 
     520             :     /*
     521             :      * If a non-nil rangetable/namespace was passed in, and we are doing
     522             :      * INSERT/SELECT, arrange to pass the rangetable/namespace down to the
     523             :      * SELECT.  This can only happen if we are inside a CREATE RULE, and in
     524             :      * that case we want the rule's OLD and NEW rtable entries to appear as
     525             :      * part of the SELECT's rtable, not as outer references for it.  (Kluge!)
     526             :      * The SELECT's joinlist is not affected however.  We must do this before
     527             :      * adding the target table to the INSERT's rtable.
     528             :      */
     529       60906 :     if (isGeneralSelect)
     530             :     {
     531       15286 :         sub_rtable = pstate->p_rtable;
     532       15286 :         pstate->p_rtable = NIL;
     533       15286 :         sub_namespace = pstate->p_namespace;
     534       15286 :         pstate->p_namespace = NIL;
     535             :     }
     536             :     else
     537             :     {
     538       45620 :         sub_rtable = NIL;       /* not used, but keep compiler quiet */
     539       45620 :         sub_namespace = NIL;
     540             :     }
     541             : 
     542             :     /*
     543             :      * Must get write lock on INSERT target table before scanning SELECT, else
     544             :      * we will grab the wrong kind of initial lock if the target table is also
     545             :      * mentioned in the SELECT part.  Note that the target table is not added
     546             :      * to the joinlist or namespace.
     547             :      */
     548       60906 :     targetPerms = ACL_INSERT;
     549       60906 :     if (isOnConflictUpdate)
     550         764 :         targetPerms |= ACL_UPDATE;
     551       60906 :     qry->resultRelation = setTargetTable(pstate, stmt->relation,
     552             :                                          false, false, targetPerms);
     553             : 
     554             :     /* Validate stmt->cols list, or build default list if no list given */
     555       60894 :     icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
     556             :     Assert(list_length(icolumns) == list_length(attrnos));
     557             : 
     558             :     /*
     559             :      * Determine which variant of INSERT we have.
     560             :      */
     561       60862 :     if (selectStmt == NULL)
     562             :     {
     563             :         /*
     564             :          * We have INSERT ... DEFAULT VALUES.  We can handle this case by
     565             :          * emitting an empty targetlist --- all columns will be defaulted when
     566             :          * the planner expands the targetlist.
     567             :          */
     568         432 :         exprList = NIL;
     569             :     }
     570       60430 :     else if (isGeneralSelect)
     571             :     {
     572             :         /*
     573             :          * We make the sub-pstate a child of the outer pstate so that it can
     574             :          * see any Param definitions supplied from above.  Since the outer
     575             :          * pstate's rtable and namespace are presently empty, there are no
     576             :          * side-effects of exposing names the sub-SELECT shouldn't be able to
     577             :          * see.
     578             :          */
     579       15286 :         ParseState *sub_pstate = make_parsestate(pstate);
     580             :         Query      *selectQuery;
     581             : 
     582             :         /*
     583             :          * Process the source SELECT.
     584             :          *
     585             :          * It is important that this be handled just like a standalone SELECT;
     586             :          * otherwise the behavior of SELECT within INSERT might be different
     587             :          * from a stand-alone SELECT. (Indeed, Postgres up through 6.5 had
     588             :          * bugs of just that nature...)
     589             :          *
     590             :          * The sole exception is that we prevent resolving unknown-type
     591             :          * outputs as TEXT.  This does not change the semantics since if the
     592             :          * column type matters semantically, it would have been resolved to
     593             :          * something else anyway.  Doing this lets us resolve such outputs as
     594             :          * the target column's type, which we handle below.
     595             :          */
     596       15286 :         sub_pstate->p_rtable = sub_rtable;
     597       15286 :         sub_pstate->p_joinexprs = NIL;   /* sub_rtable has no joins */
     598       15286 :         sub_pstate->p_namespace = sub_namespace;
     599       15286 :         sub_pstate->p_resolve_unknowns = false;
     600             : 
     601       15286 :         selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
     602             : 
     603       15282 :         free_parsestate(sub_pstate);
     604             : 
     605             :         /* The grammar should have produced a SELECT */
     606       15282 :         if (!IsA(selectQuery, Query) ||
     607       15282 :             selectQuery->commandType != CMD_SELECT)
     608           0 :             elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
     609             : 
     610             :         /*
     611             :          * Make the source be a subquery in the INSERT's rangetable, and add
     612             :          * it to the INSERT's joinlist (but not the namespace).
     613             :          */
     614       15282 :         nsitem = addRangeTableEntryForSubquery(pstate,
     615             :                                                selectQuery,
     616             :                                                makeAlias("*SELECT*", NIL),
     617             :                                                false,
     618             :                                                false);
     619       15282 :         addNSItemToQuery(pstate, nsitem, true, false, false);
     620             : 
     621             :         /*----------
     622             :          * Generate an expression list for the INSERT that selects all the
     623             :          * non-resjunk columns from the subquery.  (INSERT's tlist must be
     624             :          * separate from the subquery's tlist because we may add columns,
     625             :          * insert datatype coercions, etc.)
     626             :          *
     627             :          * HACK: unknown-type constants and params in the SELECT's targetlist
     628             :          * are copied up as-is rather than being referenced as subquery
     629             :          * outputs.  This is to ensure that when we try to coerce them to
     630             :          * the target column's datatype, the right things happen (see
     631             :          * special cases in coerce_type).  Otherwise, this fails:
     632             :          *      INSERT INTO foo SELECT 'bar', ... FROM baz
     633             :          *----------
     634             :          */
     635       15282 :         exprList = NIL;
     636       97592 :         foreach(lc, selectQuery->targetList)
     637             :         {
     638       82310 :             TargetEntry *tle = (TargetEntry *) lfirst(lc);
     639             :             Expr       *expr;
     640             : 
     641       82310 :             if (tle->resjunk)
     642          16 :                 continue;
     643       82294 :             if (tle->expr &&
     644      131892 :                 (IsA(tle->expr, Const) || IsA(tle->expr, Param)) &&
     645       49598 :                 exprType((Node *) tle->expr) == UNKNOWNOID)
     646       11726 :                 expr = tle->expr;
     647             :             else
     648             :             {
     649       70568 :                 Var        *var = makeVarFromTargetEntry(nsitem->p_rtindex, tle);
     650             : 
     651       70568 :                 var->location = exprLocation((Node *) tle->expr);
     652       70568 :                 expr = (Expr *) var;
     653             :             }
     654       82294 :             exprList = lappend(exprList, expr);
     655             :         }
     656             : 
     657             :         /* Prepare row for assignment to target table */
     658       15282 :         exprList = transformInsertRow(pstate, exprList,
     659             :                                       stmt->cols,
     660             :                                       icolumns, attrnos,
     661             :                                       false);
     662             :     }
     663       45144 :     else if (list_length(selectStmt->valuesLists) > 1)
     664             :     {
     665             :         /*
     666             :          * Process INSERT ... VALUES with multiple VALUES sublists. We
     667             :          * generate a VALUES RTE holding the transformed expression lists, and
     668             :          * build up a targetlist containing Vars that reference the VALUES
     669             :          * RTE.
     670             :          */
     671        2382 :         List       *exprsLists = NIL;
     672        2382 :         List       *coltypes = NIL;
     673        2382 :         List       *coltypmods = NIL;
     674        2382 :         List       *colcollations = NIL;
     675        2382 :         int         sublist_length = -1;
     676        2382 :         bool        lateral = false;
     677             : 
     678             :         Assert(selectStmt->intoClause == NULL);
     679             : 
     680       10184 :         foreach(lc, selectStmt->valuesLists)
     681             :         {
     682        7802 :             List       *sublist = (List *) lfirst(lc);
     683             : 
     684             :             /*
     685             :              * Do basic expression transformation (same as a ROW() expr, but
     686             :              * allow SetToDefault at top level)
     687             :              */
     688        7802 :             sublist = transformExpressionList(pstate, sublist,
     689             :                                               EXPR_KIND_VALUES, true);
     690             : 
     691             :             /*
     692             :              * All the sublists must be the same length, *after*
     693             :              * transformation (which might expand '*' into multiple items).
     694             :              * The VALUES RTE can't handle anything different.
     695             :              */
     696        7802 :             if (sublist_length < 0)
     697             :             {
     698             :                 /* Remember post-transformation length of first sublist */
     699        2382 :                 sublist_length = list_length(sublist);
     700             :             }
     701        5420 :             else if (sublist_length != list_length(sublist))
     702             :             {
     703           0 :                 ereport(ERROR,
     704             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     705             :                          errmsg("VALUES lists must all be the same length"),
     706             :                          parser_errposition(pstate,
     707             :                                             exprLocation((Node *) sublist))));
     708             :             }
     709             : 
     710             :             /*
     711             :              * Prepare row for assignment to target table.  We process any
     712             :              * indirection on the target column specs normally but then strip
     713             :              * off the resulting field/array assignment nodes, since we don't
     714             :              * want the parsed statement to contain copies of those in each
     715             :              * VALUES row.  (It's annoying to have to transform the
     716             :              * indirection specs over and over like this, but avoiding it
     717             :              * would take some really messy refactoring of
     718             :              * transformAssignmentIndirection.)
     719             :              */
     720        7802 :             sublist = transformInsertRow(pstate, sublist,
     721             :                                          stmt->cols,
     722             :                                          icolumns, attrnos,
     723             :                                          true);
     724             : 
     725             :             /*
     726             :              * We must assign collations now because assign_query_collations
     727             :              * doesn't process rangetable entries.  We just assign all the
     728             :              * collations independently in each row, and don't worry about
     729             :              * whether they are consistent vertically.  The outer INSERT query
     730             :              * isn't going to care about the collations of the VALUES columns,
     731             :              * so it's not worth the effort to identify a common collation for
     732             :              * each one here.  (But note this does have one user-visible
     733             :              * consequence: INSERT ... VALUES won't complain about conflicting
     734             :              * explicit COLLATEs in a column, whereas the same VALUES
     735             :              * construct in another context would complain.)
     736             :              */
     737        7802 :             assign_list_collations(pstate, sublist);
     738             : 
     739        7802 :             exprsLists = lappend(exprsLists, sublist);
     740             :         }
     741             : 
     742             :         /*
     743             :          * Construct column type/typmod/collation lists for the VALUES RTE.
     744             :          * Every expression in each column has been coerced to the type/typmod
     745             :          * of the corresponding target column or subfield, so it's sufficient
     746             :          * to look at the exprType/exprTypmod of the first row.  We don't care
     747             :          * about the collation labeling, so just fill in InvalidOid for that.
     748             :          */
     749        6474 :         foreach(lc, (List *) linitial(exprsLists))
     750             :         {
     751        4092 :             Node       *val = (Node *) lfirst(lc);
     752             : 
     753        4092 :             coltypes = lappend_oid(coltypes, exprType(val));
     754        4092 :             coltypmods = lappend_int(coltypmods, exprTypmod(val));
     755        4092 :             colcollations = lappend_oid(colcollations, InvalidOid);
     756             :         }
     757             : 
     758             :         /*
     759             :          * Ordinarily there can't be any current-level Vars in the expression
     760             :          * lists, because the namespace was empty ... but if we're inside
     761             :          * CREATE RULE, then NEW/OLD references might appear.  In that case we
     762             :          * have to mark the VALUES RTE as LATERAL.
     763             :          */
     764        2392 :         if (list_length(pstate->p_rtable) != 1 &&
     765          10 :             contain_vars_of_level((Node *) exprsLists, 0))
     766          10 :             lateral = true;
     767             : 
     768             :         /*
     769             :          * Generate the VALUES RTE
     770             :          */
     771        2382 :         nsitem = addRangeTableEntryForValues(pstate, exprsLists,
     772             :                                              coltypes, coltypmods, colcollations,
     773             :                                              NULL, lateral, true);
     774        2382 :         addNSItemToQuery(pstate, nsitem, true, false, false);
     775             : 
     776             :         /*
     777             :          * Generate list of Vars referencing the RTE
     778             :          */
     779        2382 :         exprList = expandNSItemVars(nsitem, 0, -1, NULL);
     780             : 
     781             :         /*
     782             :          * Re-apply any indirection on the target column specs to the Vars
     783             :          */
     784        2382 :         exprList = transformInsertRow(pstate, exprList,
     785             :                                       stmt->cols,
     786             :                                       icolumns, attrnos,
     787             :                                       false);
     788             :     }
     789             :     else
     790             :     {
     791             :         /*
     792             :          * Process INSERT ... VALUES with a single VALUES sublist.  We treat
     793             :          * this case separately for efficiency.  The sublist is just computed
     794             :          * directly as the Query's targetlist, with no VALUES RTE.  So it
     795             :          * works just like a SELECT without any FROM.
     796             :          */
     797       42762 :         List       *valuesLists = selectStmt->valuesLists;
     798             : 
     799             :         Assert(list_length(valuesLists) == 1);
     800             :         Assert(selectStmt->intoClause == NULL);
     801             : 
     802             :         /*
     803             :          * Do basic expression transformation (same as a ROW() expr, but allow
     804             :          * SetToDefault at top level)
     805             :          */
     806       42762 :         exprList = transformExpressionList(pstate,
     807       42762 :                                            (List *) linitial(valuesLists),
     808             :                                            EXPR_KIND_VALUES_SINGLE,
     809             :                                            true);
     810             : 
     811             :         /* Prepare row for assignment to target table */
     812       42746 :         exprList = transformInsertRow(pstate, exprList,
     813             :                                       stmt->cols,
     814             :                                       icolumns, attrnos,
     815             :                                       false);
     816             :     }
     817             : 
     818             :     /*
     819             :      * Generate query's target list using the computed list of expressions.
     820             :      * Also, mark all the target columns as needing insert permissions.
     821             :      */
     822       60080 :     rte = pstate->p_target_nsitem->p_rte;
     823       60080 :     qry->targetList = NIL;
     824             :     Assert(list_length(exprList) <= list_length(icolumns));
     825      272914 :     forthree(lc, exprList, icols, icolumns, attnos, attrnos)
     826             :     {
     827      212834 :         Expr       *expr = (Expr *) lfirst(lc);
     828      212834 :         ResTarget  *col = lfirst_node(ResTarget, icols);
     829      212834 :         AttrNumber  attr_num = (AttrNumber) lfirst_int(attnos);
     830             :         TargetEntry *tle;
     831             : 
     832      212834 :         tle = makeTargetEntry(expr,
     833             :                               attr_num,
     834             :                               col->name,
     835             :                               false);
     836      212834 :         qry->targetList = lappend(qry->targetList, tle);
     837             : 
     838      212834 :         rte->insertedCols = bms_add_member(rte->insertedCols,
     839             :                                            attr_num - FirstLowInvalidHeapAttributeNumber);
     840             :     }
     841             : 
     842             :     /* Process ON CONFLICT, if any. */
     843       60080 :     if (stmt->onConflictClause)
     844        1008 :         qry->onConflict = transformOnConflictClause(pstate,
     845             :                                                     stmt->onConflictClause);
     846             : 
     847             :     /*
     848             :      * If we have a RETURNING clause, we need to add the target relation to
     849             :      * the query namespace before processing it, so that Var references in
     850             :      * RETURNING will work.  Also, remove any namespace entries added in a
     851             :      * sub-SELECT or VALUES list.
     852             :      */
     853       60056 :     if (stmt->returningList)
     854             :     {
     855         820 :         pstate->p_namespace = NIL;
     856         820 :         addNSItemToQuery(pstate, pstate->p_target_nsitem,
     857             :                          false, true, true);
     858         820 :         qry->returningList = transformReturningList(pstate,
     859             :                                                     stmt->returningList);
     860             :     }
     861             : 
     862             :     /* done building the range table and jointree */
     863       60044 :     qry->rtable = pstate->p_rtable;
     864       60044 :     qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
     865             : 
     866       60044 :     qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
     867       60044 :     qry->hasSubLinks = pstate->p_hasSubLinks;
     868             : 
     869       60044 :     assign_query_collations(pstate, qry);
     870             : 
     871       60044 :     return qry;
     872             : }
     873             : 
     874             : /*
     875             :  * Prepare an INSERT row for assignment to the target table.
     876             :  *
     877             :  * exprlist: transformed expressions for source values; these might come from
     878             :  * a VALUES row, or be Vars referencing a sub-SELECT or VALUES RTE output.
     879             :  * stmtcols: original target-columns spec for INSERT (we just test for NIL)
     880             :  * icolumns: effective target-columns spec (list of ResTarget)
     881             :  * attrnos: integer column numbers (must be same length as icolumns)
     882             :  * strip_indirection: if true, remove any field/array assignment nodes
     883             :  */
     884             : static List *
     885       68212 : transformInsertRow(ParseState *pstate, List *exprlist,
     886             :                    List *stmtcols, List *icolumns, List *attrnos,
     887             :                    bool strip_indirection)
     888             : {
     889             :     List       *result;
     890             :     ListCell   *lc;
     891             :     ListCell   *icols;
     892             :     ListCell   *attnos;
     893             : 
     894             :     /*
     895             :      * Check length of expr list.  It must not have more expressions than
     896             :      * there are target columns.  We allow fewer, but only if no explicit
     897             :      * columns list was given (the remaining columns are implicitly
     898             :      * defaulted).  Note we must check this *after* transformation because
     899             :      * that could expand '*' into multiple items.
     900             :      */
     901       68212 :     if (list_length(exprlist) > list_length(icolumns))
     902          16 :         ereport(ERROR,
     903             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     904             :                  errmsg("INSERT has more expressions than target columns"),
     905             :                  parser_errposition(pstate,
     906             :                                     exprLocation(list_nth(exprlist,
     907             :                                                           list_length(icolumns))))));
     908       80388 :     if (stmtcols != NIL &&
     909       12192 :         list_length(exprlist) < list_length(icolumns))
     910             :     {
     911             :         /*
     912             :          * We can get here for cases like INSERT ... SELECT (a,b,c) FROM ...
     913             :          * where the user accidentally created a RowExpr instead of separate
     914             :          * columns.  Add a suitable hint if that seems to be the problem,
     915             :          * because the main error message is quite misleading for this case.
     916             :          * (If there's no stmtcols, you'll get something about data type
     917             :          * mismatch, which is less misleading so we don't worry about giving a
     918             :          * hint in that case.)
     919             :          */
     920           8 :         ereport(ERROR,
     921             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     922             :                  errmsg("INSERT has more target columns than expressions"),
     923             :                  ((list_length(exprlist) == 1 &&
     924             :                    count_rowexpr_columns(pstate, linitial(exprlist)) ==
     925             :                    list_length(icolumns)) ?
     926             :                   errhint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?") : 0),
     927             :                  parser_errposition(pstate,
     928             :                                     exprLocation(list_nth(icolumns,
     929             :                                                           list_length(exprlist))))));
     930             :     }
     931             : 
     932             :     /*
     933             :      * Prepare columns for assignment to target table.
     934             :      */
     935       68188 :     result = NIL;
     936      295340 :     forthree(lc, exprlist, icols, icolumns, attnos, attrnos)
     937             :     {
     938      227890 :         Expr       *expr = (Expr *) lfirst(lc);
     939      227890 :         ResTarget  *col = lfirst_node(ResTarget, icols);
     940      227890 :         int         attno = lfirst_int(attnos);
     941             : 
     942      455780 :         expr = transformAssignedExpr(pstate, expr,
     943             :                                      EXPR_KIND_INSERT_TARGET,
     944      227890 :                                      col->name,
     945             :                                      attno,
     946             :                                      col->indirection,
     947             :                                      col->location);
     948             : 
     949      227152 :         if (strip_indirection)
     950             :         {
     951       14486 :             while (expr)
     952             :             {
     953       14486 :                 if (IsA(expr, FieldStore))
     954             :                 {
     955          64 :                     FieldStore *fstore = (FieldStore *) expr;
     956             : 
     957          64 :                     expr = (Expr *) linitial(fstore->newvals);
     958             :                 }
     959       14422 :                 else if (IsA(expr, SubscriptingRef))
     960             :                 {
     961         128 :                     SubscriptingRef *sbsref = (SubscriptingRef *) expr;
     962             : 
     963         128 :                     if (sbsref->refassgnexpr == NULL)
     964           0 :                         break;
     965             : 
     966         128 :                     expr = sbsref->refassgnexpr;
     967             :                 }
     968             :                 else
     969       14294 :                     break;
     970             :             }
     971             :         }
     972             : 
     973      227152 :         result = lappend(result, expr);
     974             :     }
     975             : 
     976       67450 :     return result;
     977             : }
     978             : 
     979             : /*
     980             :  * transformOnConflictClause -
     981             :  *    transforms an OnConflictClause in an INSERT
     982             :  */
     983             : static OnConflictExpr *
     984        1008 : transformOnConflictClause(ParseState *pstate,
     985             :                           OnConflictClause *onConflictClause)
     986             : {
     987             :     List       *arbiterElems;
     988             :     Node       *arbiterWhere;
     989             :     Oid         arbiterConstraint;
     990        1008 :     List       *onConflictSet = NIL;
     991        1008 :     Node       *onConflictWhere = NULL;
     992        1008 :     int         exclRelIndex = 0;
     993        1008 :     List       *exclRelTlist = NIL;
     994             :     OnConflictExpr *result;
     995             : 
     996             :     /* Process the arbiter clause, ON CONFLICT ON (...) */
     997        1008 :     transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems,
     998             :                                &arbiterWhere, &arbiterConstraint);
     999             : 
    1000             :     /* Process DO UPDATE */
    1001        1000 :     if (onConflictClause->action == ONCONFLICT_UPDATE)
    1002             :     {
    1003         756 :         Relation    targetrel = pstate->p_target_relation;
    1004             :         ParseNamespaceItem *exclNSItem;
    1005             :         RangeTblEntry *exclRte;
    1006             : 
    1007             :         /*
    1008             :          * All INSERT expressions have been parsed, get ready for potentially
    1009             :          * existing SET statements that need to be processed like an UPDATE.
    1010             :          */
    1011         756 :         pstate->p_is_insert = false;
    1012             : 
    1013             :         /*
    1014             :          * Add range table entry for the EXCLUDED pseudo relation.  relkind is
    1015             :          * set to composite to signal that we're not dealing with an actual
    1016             :          * relation, and no permission checks are required on it.  (We'll
    1017             :          * check the actual target relation, instead.)
    1018             :          */
    1019         756 :         exclNSItem = addRangeTableEntryForRelation(pstate,
    1020             :                                                    targetrel,
    1021             :                                                    RowExclusiveLock,
    1022             :                                                    makeAlias("excluded", NIL),
    1023             :                                                    false, false);
    1024         756 :         exclRte = exclNSItem->p_rte;
    1025         756 :         exclRelIndex = exclNSItem->p_rtindex;
    1026             : 
    1027         756 :         exclRte->relkind = RELKIND_COMPOSITE_TYPE;
    1028         756 :         exclRte->requiredPerms = 0;
    1029             :         /* other permissions fields in exclRte are already empty */
    1030             : 
    1031             :         /* Create EXCLUDED rel's targetlist for use by EXPLAIN */
    1032         756 :         exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel,
    1033             :                                                          exclRelIndex);
    1034             : 
    1035             :         /*
    1036             :          * Add EXCLUDED and the target RTE to the namespace, so that they can
    1037             :          * be used in the UPDATE subexpressions.
    1038             :          */
    1039         756 :         addNSItemToQuery(pstate, exclNSItem, false, true, true);
    1040         756 :         addNSItemToQuery(pstate, pstate->p_target_nsitem,
    1041             :                          false, true, true);
    1042             : 
    1043             :         /*
    1044             :          * Now transform the UPDATE subexpressions.
    1045             :          */
    1046             :         onConflictSet =
    1047         756 :             transformUpdateTargetList(pstate, onConflictClause->targetList);
    1048             : 
    1049         740 :         onConflictWhere = transformWhereClause(pstate,
    1050             :                                                onConflictClause->whereClause,
    1051             :                                                EXPR_KIND_WHERE, "WHERE");
    1052             :     }
    1053             : 
    1054             :     /* Finally, build ON CONFLICT DO [NOTHING | UPDATE] expression */
    1055         984 :     result = makeNode(OnConflictExpr);
    1056             : 
    1057         984 :     result->action = onConflictClause->action;
    1058         984 :     result->arbiterElems = arbiterElems;
    1059         984 :     result->arbiterWhere = arbiterWhere;
    1060         984 :     result->constraint = arbiterConstraint;
    1061         984 :     result->onConflictSet = onConflictSet;
    1062         984 :     result->onConflictWhere = onConflictWhere;
    1063         984 :     result->exclRelIndex = exclRelIndex;
    1064         984 :     result->exclRelTlist = exclRelTlist;
    1065             : 
    1066         984 :     return result;
    1067             : }
    1068             : 
    1069             : 
    1070             : /*
    1071             :  * BuildOnConflictExcludedTargetlist
    1072             :  *      Create target list for the EXCLUDED pseudo-relation of ON CONFLICT,
    1073             :  *      representing the columns of targetrel with varno exclRelIndex.
    1074             :  *
    1075             :  * Note: Exported for use in the rewriter.
    1076             :  */
    1077             : List *
    1078         852 : BuildOnConflictExcludedTargetlist(Relation targetrel,
    1079             :                                   Index exclRelIndex)
    1080             : {
    1081         852 :     List       *result = NIL;
    1082             :     int         attno;
    1083             :     Var        *var;
    1084             :     TargetEntry *te;
    1085             : 
    1086             :     /*
    1087             :      * Note that resnos of the tlist must correspond to attnos of the
    1088             :      * underlying relation, hence we need entries for dropped columns too.
    1089             :      */
    1090        3082 :     for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++)
    1091             :     {
    1092        2230 :         Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno);
    1093             :         char       *name;
    1094             : 
    1095        2230 :         if (attr->attisdropped)
    1096             :         {
    1097             :             /*
    1098             :              * can't use atttypid here, but it doesn't really matter what type
    1099             :              * the Const claims to be.
    1100             :              */
    1101          44 :             var = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
    1102          44 :             name = NULL;
    1103             :         }
    1104             :         else
    1105             :         {
    1106        2186 :             var = makeVar(exclRelIndex, attno + 1,
    1107             :                           attr->atttypid, attr->atttypmod,
    1108             :                           attr->attcollation,
    1109             :                           0);
    1110        2186 :             name = pstrdup(NameStr(attr->attname));
    1111             :         }
    1112             : 
    1113        2230 :         te = makeTargetEntry((Expr *) var,
    1114        2230 :                              attno + 1,
    1115             :                              name,
    1116             :                              false);
    1117             : 
    1118        2230 :         result = lappend(result, te);
    1119             :     }
    1120             : 
    1121             :     /*
    1122             :      * Add a whole-row-Var entry to support references to "EXCLUDED.*".  Like
    1123             :      * the other entries in the EXCLUDED tlist, its resno must match the Var's
    1124             :      * varattno, else the wrong things happen while resolving references in
    1125             :      * setrefs.c.  This is against normal conventions for targetlists, but
    1126             :      * it's okay since we don't use this as a real tlist.
    1127             :      */
    1128         852 :     var = makeVar(exclRelIndex, InvalidAttrNumber,
    1129         852 :                   targetrel->rd_rel->reltype,
    1130             :                   -1, InvalidOid, 0);
    1131         852 :     te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true);
    1132         852 :     result = lappend(result, te);
    1133             : 
    1134         852 :     return result;
    1135             : }
    1136             : 
    1137             : 
    1138             : /*
    1139             :  * count_rowexpr_columns -
    1140             :  *    get number of columns contained in a ROW() expression;
    1141             :  *    return -1 if expression isn't a RowExpr or a Var referencing one.
    1142             :  *
    1143             :  * This is currently used only for hint purposes, so we aren't terribly
    1144             :  * tense about recognizing all possible cases.  The Var case is interesting
    1145             :  * because that's what we'll get in the INSERT ... SELECT (...) case.
    1146             :  */
    1147             : static int
    1148           0 : count_rowexpr_columns(ParseState *pstate, Node *expr)
    1149             : {
    1150           0 :     if (expr == NULL)
    1151           0 :         return -1;
    1152           0 :     if (IsA(expr, RowExpr))
    1153           0 :         return list_length(((RowExpr *) expr)->args);
    1154           0 :     if (IsA(expr, Var))
    1155             :     {
    1156           0 :         Var        *var = (Var *) expr;
    1157           0 :         AttrNumber  attnum = var->varattno;
    1158             : 
    1159           0 :         if (attnum > 0 && var->vartype == RECORDOID)
    1160             :         {
    1161             :             RangeTblEntry *rte;
    1162             : 
    1163           0 :             rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
    1164           0 :             if (rte->rtekind == RTE_SUBQUERY)
    1165             :             {
    1166             :                 /* Subselect-in-FROM: examine sub-select's output expr */
    1167           0 :                 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
    1168             :                                                     attnum);
    1169             : 
    1170           0 :                 if (ste == NULL || ste->resjunk)
    1171           0 :                     return -1;
    1172           0 :                 expr = (Node *) ste->expr;
    1173           0 :                 if (IsA(expr, RowExpr))
    1174           0 :                     return list_length(((RowExpr *) expr)->args);
    1175             :             }
    1176             :         }
    1177             :     }
    1178           0 :     return -1;
    1179             : }
    1180             : 
    1181             : 
    1182             : /*
    1183             :  * transformSelectStmt -
    1184             :  *    transforms a Select Statement
    1185             :  *
    1186             :  * Note: this covers only cases with no set operations and no VALUES lists;
    1187             :  * see below for the other cases.
    1188             :  */
    1189             : static Query *
    1190      365690 : transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
    1191             : {
    1192      365690 :     Query      *qry = makeNode(Query);
    1193             :     Node       *qual;
    1194             :     ListCell   *l;
    1195             : 
    1196      365690 :     qry->commandType = CMD_SELECT;
    1197             : 
    1198             :     /* process the WITH clause independently of all else */
    1199      365690 :     if (stmt->withClause)
    1200             :     {
    1201         824 :         qry->hasRecursive = stmt->withClause->recursive;
    1202         824 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
    1203         710 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
    1204             :     }
    1205             : 
    1206             :     /* Complain if we get called from someplace where INTO is not allowed */
    1207      365576 :     if (stmt->intoClause)
    1208          12 :         ereport(ERROR,
    1209             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1210             :                  errmsg("SELECT ... INTO is not allowed here"),
    1211             :                  parser_errposition(pstate,
    1212             :                                     exprLocation((Node *) stmt->intoClause))));
    1213             : 
    1214             :     /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */
    1215      365564 :     pstate->p_locking_clause = stmt->lockingClause;
    1216             : 
    1217             :     /* make WINDOW info available for window functions, too */
    1218      365564 :     pstate->p_windowdefs = stmt->windowClause;
    1219             : 
    1220             :     /* process the FROM clause */
    1221      365564 :     transformFromClause(pstate, stmt->fromClause);
    1222             : 
    1223             :     /* transform targetlist */
    1224      365274 :     qry->targetList = transformTargetList(pstate, stmt->targetList,
    1225             :                                           EXPR_KIND_SELECT_TARGET);
    1226             : 
    1227             :     /* mark column origins */
    1228      363494 :     markTargetListOrigins(pstate, qry->targetList);
    1229             : 
    1230             :     /* transform WHERE */
    1231      363494 :     qual = transformWhereClause(pstate, stmt->whereClause,
    1232             :                                 EXPR_KIND_WHERE, "WHERE");
    1233             : 
    1234             :     /* initial processing of HAVING clause is much like WHERE clause */
    1235      363444 :     qry->havingQual = transformWhereClause(pstate, stmt->havingClause,
    1236             :                                            EXPR_KIND_HAVING, "HAVING");
    1237             : 
    1238             :     /*
    1239             :      * Transform sorting/grouping stuff.  Do ORDER BY first because both
    1240             :      * transformGroupClause and transformDistinctClause need the results. Note
    1241             :      * that these functions can also change the targetList, so it's passed to
    1242             :      * them by reference.
    1243             :      */
    1244      363440 :     qry->sortClause = transformSortClause(pstate,
    1245             :                                           stmt->sortClause,
    1246             :                                           &qry->targetList,
    1247             :                                           EXPR_KIND_ORDER_BY,
    1248             :                                           false /* allow SQL92 rules */ );
    1249             : 
    1250      363420 :     qry->groupClause = transformGroupClause(pstate,
    1251             :                                             stmt->groupClause,
    1252             :                                             &qry->groupingSets,
    1253             :                                             &qry->targetList,
    1254             :                                             qry->sortClause,
    1255             :                                             EXPR_KIND_GROUP_BY,
    1256             :                                             false /* allow SQL92 rules */ );
    1257             : 
    1258      363404 :     if (stmt->distinctClause == NIL)
    1259             :     {
    1260      361526 :         qry->distinctClause = NIL;
    1261      361526 :         qry->hasDistinctOn = false;
    1262             :     }
    1263        1878 :     else if (linitial(stmt->distinctClause) == NULL)
    1264             :     {
    1265             :         /* We had SELECT DISTINCT */
    1266        1834 :         qry->distinctClause = transformDistinctClause(pstate,
    1267             :                                                       &qry->targetList,
    1268             :                                                       qry->sortClause,
    1269             :                                                       false);
    1270        1834 :         qry->hasDistinctOn = false;
    1271             :     }
    1272             :     else
    1273             :     {
    1274             :         /* We had SELECT DISTINCT ON */
    1275          44 :         qry->distinctClause = transformDistinctOnClause(pstate,
    1276             :                                                         stmt->distinctClause,
    1277             :                                                         &qry->targetList,
    1278             :                                                         qry->sortClause);
    1279          36 :         qry->hasDistinctOn = true;
    1280             :     }
    1281             : 
    1282             :     /* transform LIMIT */
    1283      363396 :     qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
    1284             :                                             EXPR_KIND_OFFSET, "OFFSET",
    1285             :                                             stmt->limitOption);
    1286      363396 :     qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
    1287             :                                            EXPR_KIND_LIMIT, "LIMIT",
    1288             :                                            stmt->limitOption);
    1289      363388 :     qry->limitOption = stmt->limitOption;
    1290             : 
    1291             :     /* transform window clauses after we have seen all window functions */
    1292      363388 :     qry->windowClause = transformWindowDefinitions(pstate,
    1293             :                                                    pstate->p_windowdefs,
    1294             :                                                    &qry->targetList);
    1295             : 
    1296             :     /* resolve any still-unresolved output columns as being type text */
    1297      363348 :     if (pstate->p_resolve_unknowns)
    1298      321444 :         resolveTargetListUnknowns(pstate, qry->targetList);
    1299             : 
    1300      363348 :     qry->rtable = pstate->p_rtable;
    1301      363348 :     qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
    1302             : 
    1303      363348 :     qry->hasSubLinks = pstate->p_hasSubLinks;
    1304      363348 :     qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
    1305      363348 :     qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
    1306      363348 :     qry->hasAggs = pstate->p_hasAggs;
    1307             : 
    1308      367168 :     foreach(l, stmt->lockingClause)
    1309             :     {
    1310        3824 :         transformLockingClause(pstate, qry,
    1311        3824 :                                (LockingClause *) lfirst(l), false);
    1312             :     }
    1313             : 
    1314      363344 :     assign_query_collations(pstate, qry);
    1315             : 
    1316             :     /* this must be done after collations, for reliable comparison of exprs */
    1317      363324 :     if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
    1318       26916 :         parseCheckAggregates(pstate, qry);
    1319             : 
    1320      363252 :     return qry;
    1321             : }
    1322             : 
    1323             : /*
    1324             :  * transformValuesClause -
    1325             :  *    transforms a VALUES clause that's being used as a standalone SELECT
    1326             :  *
    1327             :  * We build a Query containing a VALUES RTE, rather as if one had written
    1328             :  *          SELECT * FROM (VALUES ...) AS "*VALUES*"
    1329             :  */
    1330             : static Query *
    1331        2538 : transformValuesClause(ParseState *pstate, SelectStmt *stmt)
    1332             : {
    1333        2538 :     Query      *qry = makeNode(Query);
    1334             :     List       *exprsLists;
    1335        2538 :     List       *coltypes = NIL;
    1336        2538 :     List       *coltypmods = NIL;
    1337        2538 :     List       *colcollations = NIL;
    1338        2538 :     List      **colexprs = NULL;
    1339        2538 :     int         sublist_length = -1;
    1340        2538 :     bool        lateral = false;
    1341             :     ParseNamespaceItem *nsitem;
    1342             :     ListCell   *lc;
    1343             :     ListCell   *lc2;
    1344             :     int         i;
    1345             : 
    1346        2538 :     qry->commandType = CMD_SELECT;
    1347             : 
    1348             :     /* Most SELECT stuff doesn't apply in a VALUES clause */
    1349             :     Assert(stmt->distinctClause == NIL);
    1350             :     Assert(stmt->intoClause == NULL);
    1351             :     Assert(stmt->targetList == NIL);
    1352             :     Assert(stmt->fromClause == NIL);
    1353             :     Assert(stmt->whereClause == NULL);
    1354             :     Assert(stmt->groupClause == NIL);
    1355             :     Assert(stmt->havingClause == NULL);
    1356             :     Assert(stmt->windowClause == NIL);
    1357             :     Assert(stmt->op == SETOP_NONE);
    1358             : 
    1359             :     /* process the WITH clause independently of all else */
    1360        2538 :     if (stmt->withClause)
    1361             :     {
    1362          16 :         qry->hasRecursive = stmt->withClause->recursive;
    1363          16 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
    1364          12 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
    1365             :     }
    1366             : 
    1367             :     /*
    1368             :      * For each row of VALUES, transform the raw expressions.
    1369             :      *
    1370             :      * Note that the intermediate representation we build is column-organized
    1371             :      * not row-organized.  That simplifies the type and collation processing
    1372             :      * below.
    1373             :      */
    1374       12990 :     foreach(lc, stmt->valuesLists)
    1375             :     {
    1376       10462 :         List       *sublist = (List *) lfirst(lc);
    1377             : 
    1378             :         /*
    1379             :          * Do basic expression transformation (same as a ROW() expr, but here
    1380             :          * we disallow SetToDefault)
    1381             :          */
    1382       10462 :         sublist = transformExpressionList(pstate, sublist,
    1383             :                                           EXPR_KIND_VALUES, false);
    1384             : 
    1385             :         /*
    1386             :          * All the sublists must be the same length, *after* transformation
    1387             :          * (which might expand '*' into multiple items).  The VALUES RTE can't
    1388             :          * handle anything different.
    1389             :          */
    1390       10456 :         if (sublist_length < 0)
    1391             :         {
    1392             :             /* Remember post-transformation length of first sublist */
    1393        2528 :             sublist_length = list_length(sublist);
    1394             :             /* and allocate array for per-column lists */
    1395        2528 :             colexprs = (List **) palloc0(sublist_length * sizeof(List *));
    1396             :         }
    1397        7928 :         else if (sublist_length != list_length(sublist))
    1398             :         {
    1399           0 :             ereport(ERROR,
    1400             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    1401             :                      errmsg("VALUES lists must all be the same length"),
    1402             :                      parser_errposition(pstate,
    1403             :                                         exprLocation((Node *) sublist))));
    1404             :         }
    1405             : 
    1406             :         /* Build per-column expression lists */
    1407       10456 :         i = 0;
    1408       25874 :         foreach(lc2, sublist)
    1409             :         {
    1410       15418 :             Node       *col = (Node *) lfirst(lc2);
    1411             : 
    1412       15418 :             colexprs[i] = lappend(colexprs[i], col);
    1413       15418 :             i++;
    1414             :         }
    1415             : 
    1416             :         /* Release sub-list's cells to save memory */
    1417       10456 :         list_free(sublist);
    1418             :     }
    1419             : 
    1420             :     /*
    1421             :      * Now resolve the common types of the columns, and coerce everything to
    1422             :      * those types.  Then identify the common typmod and common collation, if
    1423             :      * any, of each column.
    1424             :      *
    1425             :      * We must do collation processing now because (1) assign_query_collations
    1426             :      * doesn't process rangetable entries, and (2) we need to label the VALUES
    1427             :      * RTE with column collations for use in the outer query.  We don't
    1428             :      * consider conflict of implicit collations to be an error here; instead
    1429             :      * the column will just show InvalidOid as its collation, and you'll get a
    1430             :      * failure later if that results in failure to resolve a collation.
    1431             :      *
    1432             :      * Note we modify the per-column expression lists in-place.
    1433             :      */
    1434        6424 :     for (i = 0; i < sublist_length; i++)
    1435             :     {
    1436             :         Oid         coltype;
    1437        3896 :         int32       coltypmod = -1;
    1438             :         Oid         colcoll;
    1439        3896 :         bool        first = true;
    1440             : 
    1441        3896 :         coltype = select_common_type(pstate, colexprs[i], "VALUES", NULL);
    1442             : 
    1443       19314 :         foreach(lc, colexprs[i])
    1444             :         {
    1445       15418 :             Node       *col = (Node *) lfirst(lc);
    1446             : 
    1447       15418 :             col = coerce_to_common_type(pstate, col, coltype, "VALUES");
    1448       15418 :             lfirst(lc) = (void *) col;
    1449       15418 :             if (first)
    1450             :             {
    1451        3896 :                 coltypmod = exprTypmod(col);
    1452        3896 :                 first = false;
    1453             :             }
    1454             :             else
    1455             :             {
    1456             :                 /* As soon as we see a non-matching typmod, fall back to -1 */
    1457       11522 :                 if (coltypmod >= 0 && coltypmod != exprTypmod(col))
    1458           4 :                     coltypmod = -1;
    1459             :             }
    1460             :         }
    1461             : 
    1462        3896 :         colcoll = select_common_collation(pstate, colexprs[i], true);
    1463             : 
    1464        3896 :         coltypes = lappend_oid(coltypes, coltype);
    1465        3896 :         coltypmods = lappend_int(coltypmods, coltypmod);
    1466        3896 :         colcollations = lappend_oid(colcollations, colcoll);
    1467             :     }
    1468             : 
    1469             :     /*
    1470             :      * Finally, rearrange the coerced expressions into row-organized lists.
    1471             :      */
    1472        2528 :     exprsLists = NIL;
    1473       12984 :     foreach(lc, colexprs[0])
    1474             :     {
    1475       10456 :         Node       *col = (Node *) lfirst(lc);
    1476             :         List       *sublist;
    1477             : 
    1478       10456 :         sublist = list_make1(col);
    1479       10456 :         exprsLists = lappend(exprsLists, sublist);
    1480             :     }
    1481        2528 :     list_free(colexprs[0]);
    1482        3896 :     for (i = 1; i < sublist_length; i++)
    1483             :     {
    1484        6330 :         forboth(lc, colexprs[i], lc2, exprsLists)
    1485             :         {
    1486        4962 :             Node       *col = (Node *) lfirst(lc);
    1487        4962 :             List       *sublist = lfirst(lc2);
    1488             : 
    1489             :             /* sublist pointer in exprsLists won't need adjustment */
    1490        4962 :             (void) lappend(sublist, col);
    1491             :         }
    1492        1368 :         list_free(colexprs[i]);
    1493             :     }
    1494             : 
    1495             :     /*
    1496             :      * Ordinarily there can't be any current-level Vars in the expression
    1497             :      * lists, because the namespace was empty ... but if we're inside CREATE
    1498             :      * RULE, then NEW/OLD references might appear.  In that case we have to
    1499             :      * mark the VALUES RTE as LATERAL.
    1500             :      */
    1501        2534 :     if (pstate->p_rtable != NIL &&
    1502           6 :         contain_vars_of_level((Node *) exprsLists, 0))
    1503           6 :         lateral = true;
    1504             : 
    1505             :     /*
    1506             :      * Generate the VALUES RTE
    1507             :      */
    1508        2528 :     nsitem = addRangeTableEntryForValues(pstate, exprsLists,
    1509             :                                          coltypes, coltypmods, colcollations,
    1510             :                                          NULL, lateral, true);
    1511        2528 :     addNSItemToQuery(pstate, nsitem, true, true, true);
    1512             : 
    1513             :     /*
    1514             :      * Generate a targetlist as though expanding "*"
    1515             :      */
    1516             :     Assert(pstate->p_next_resno == 1);
    1517        2528 :     qry->targetList = expandNSItemAttrs(pstate, nsitem, 0, -1);
    1518             : 
    1519             :     /*
    1520             :      * The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a
    1521             :      * VALUES, so cope.
    1522             :      */
    1523        2528 :     qry->sortClause = transformSortClause(pstate,
    1524             :                                           stmt->sortClause,
    1525             :                                           &qry->targetList,
    1526             :                                           EXPR_KIND_ORDER_BY,
    1527             :                                           false /* allow SQL92 rules */ );
    1528             : 
    1529        2528 :     qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
    1530             :                                             EXPR_KIND_OFFSET, "OFFSET",
    1531             :                                             stmt->limitOption);
    1532        2528 :     qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
    1533             :                                            EXPR_KIND_LIMIT, "LIMIT",
    1534             :                                            stmt->limitOption);
    1535        2528 :     qry->limitOption = stmt->limitOption;
    1536             : 
    1537        2528 :     if (stmt->lockingClause)
    1538           0 :         ereport(ERROR,
    1539             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1540             :         /*------
    1541             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    1542             :                  errmsg("%s cannot be applied to VALUES",
    1543             :                         LCS_asString(((LockingClause *)
    1544             :                                       linitial(stmt->lockingClause))->strength))));
    1545             : 
    1546        2528 :     qry->rtable = pstate->p_rtable;
    1547        2528 :     qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
    1548             : 
    1549        2528 :     qry->hasSubLinks = pstate->p_hasSubLinks;
    1550             : 
    1551        2528 :     assign_query_collations(pstate, qry);
    1552             : 
    1553        2528 :     return qry;
    1554             : }
    1555             : 
    1556             : /*
    1557             :  * transformSetOperationStmt -
    1558             :  *    transforms a set-operations tree
    1559             :  *
    1560             :  * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
    1561             :  * structure to it.  We must transform each leaf SELECT and build up a top-
    1562             :  * level Query that contains the leaf SELECTs as subqueries in its rangetable.
    1563             :  * The tree of set operations is converted into the setOperations field of
    1564             :  * the top-level Query.
    1565             :  */
    1566             : static Query *
    1567        9886 : transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
    1568             : {
    1569        9886 :     Query      *qry = makeNode(Query);
    1570             :     SelectStmt *leftmostSelect;
    1571             :     int         leftmostRTI;
    1572             :     Query      *leftmostQuery;
    1573             :     SetOperationStmt *sostmt;
    1574             :     List       *sortClause;
    1575             :     Node       *limitOffset;
    1576             :     Node       *limitCount;
    1577             :     List       *lockingClause;
    1578             :     WithClause *withClause;
    1579             :     Node       *node;
    1580             :     ListCell   *left_tlist,
    1581             :                *lct,
    1582             :                *lcm,
    1583             :                *lcc,
    1584             :                *l;
    1585             :     List       *targetvars,
    1586             :                *targetnames,
    1587             :                *sv_namespace;
    1588             :     int         sv_rtable_length;
    1589             :     ParseNamespaceItem *jnsitem;
    1590             :     ParseNamespaceColumn *sortnscolumns;
    1591             :     int         sortcolindex;
    1592             :     int         tllen;
    1593             : 
    1594        9886 :     qry->commandType = CMD_SELECT;
    1595             : 
    1596             :     /*
    1597             :      * Find leftmost leaf SelectStmt.  We currently only need to do this in
    1598             :      * order to deliver a suitable error message if there's an INTO clause
    1599             :      * there, implying the set-op tree is in a context that doesn't allow
    1600             :      * INTO.  (transformSetOperationTree would throw error anyway, but it
    1601             :      * seems worth the trouble to throw a different error for non-leftmost
    1602             :      * INTO, so we produce that error in transformSetOperationTree.)
    1603             :      */
    1604        9886 :     leftmostSelect = stmt->larg;
    1605       17098 :     while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
    1606        7212 :         leftmostSelect = leftmostSelect->larg;
    1607             :     Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
    1608             :            leftmostSelect->larg == NULL);
    1609        9886 :     if (leftmostSelect->intoClause)
    1610           0 :         ereport(ERROR,
    1611             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1612             :                  errmsg("SELECT ... INTO is not allowed here"),
    1613             :                  parser_errposition(pstate,
    1614             :                                     exprLocation((Node *) leftmostSelect->intoClause))));
    1615             : 
    1616             :     /*
    1617             :      * We need to extract ORDER BY and other top-level clauses here and not
    1618             :      * let transformSetOperationTree() see them --- else it'll just recurse
    1619             :      * right back here!
    1620             :      */
    1621        9886 :     sortClause = stmt->sortClause;
    1622        9886 :     limitOffset = stmt->limitOffset;
    1623        9886 :     limitCount = stmt->limitCount;
    1624        9886 :     lockingClause = stmt->lockingClause;
    1625        9886 :     withClause = stmt->withClause;
    1626             : 
    1627        9886 :     stmt->sortClause = NIL;
    1628        9886 :     stmt->limitOffset = NULL;
    1629        9886 :     stmt->limitCount = NULL;
    1630        9886 :     stmt->lockingClause = NIL;
    1631        9886 :     stmt->withClause = NULL;
    1632             : 
    1633             :     /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
    1634        9886 :     if (lockingClause)
    1635           4 :         ereport(ERROR,
    1636             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1637             :         /*------
    1638             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    1639             :                  errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
    1640             :                         LCS_asString(((LockingClause *)
    1641             :                                       linitial(lockingClause))->strength))));
    1642             : 
    1643             :     /* Process the WITH clause independently of all else */
    1644        9882 :     if (withClause)
    1645             :     {
    1646          40 :         qry->hasRecursive = withClause->recursive;
    1647          40 :         qry->cteList = transformWithClause(pstate, withClause);
    1648          40 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
    1649             :     }
    1650             : 
    1651             :     /*
    1652             :      * Recursively transform the components of the tree.
    1653             :      */
    1654        9882 :     sostmt = castNode(SetOperationStmt,
    1655             :                       transformSetOperationTree(pstate, stmt, true, NULL));
    1656             :     Assert(sostmt);
    1657        9846 :     qry->setOperations = (Node *) sostmt;
    1658             : 
    1659             :     /*
    1660             :      * Re-find leftmost SELECT (now it's a sub-query in rangetable)
    1661             :      */
    1662        9846 :     node = sostmt->larg;
    1663       17046 :     while (node && IsA(node, SetOperationStmt))
    1664        7200 :         node = ((SetOperationStmt *) node)->larg;
    1665             :     Assert(node && IsA(node, RangeTblRef));
    1666        9846 :     leftmostRTI = ((RangeTblRef *) node)->rtindex;
    1667        9846 :     leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
    1668             :     Assert(leftmostQuery != NULL);
    1669             : 
    1670             :     /*
    1671             :      * Generate dummy targetlist for outer query using column names of
    1672             :      * leftmost select and common datatypes/collations of topmost set
    1673             :      * operation.  Also make lists of the dummy vars and their names for use
    1674             :      * in parsing ORDER BY.
    1675             :      *
    1676             :      * Note: we use leftmostRTI as the varno of the dummy variables. It
    1677             :      * shouldn't matter too much which RT index they have, as long as they
    1678             :      * have one that corresponds to a real RT entry; else funny things may
    1679             :      * happen when the tree is mashed by rule rewriting.
    1680             :      */
    1681        9846 :     qry->targetList = NIL;
    1682        9846 :     targetvars = NIL;
    1683        9846 :     targetnames = NIL;
    1684             :     sortnscolumns = (ParseNamespaceColumn *)
    1685        9846 :         palloc0(list_length(sostmt->colTypes) * sizeof(ParseNamespaceColumn));
    1686        9846 :     sortcolindex = 0;
    1687             : 
    1688       43802 :     forfour(lct, sostmt->colTypes,
    1689             :             lcm, sostmt->colTypmods,
    1690             :             lcc, sostmt->colCollations,
    1691             :             left_tlist, leftmostQuery->targetList)
    1692             :     {
    1693       33956 :         Oid         colType = lfirst_oid(lct);
    1694       33956 :         int32       colTypmod = lfirst_int(lcm);
    1695       33956 :         Oid         colCollation = lfirst_oid(lcc);
    1696       33956 :         TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
    1697             :         char       *colName;
    1698             :         TargetEntry *tle;
    1699             :         Var        *var;
    1700             : 
    1701             :         Assert(!lefttle->resjunk);
    1702       33956 :         colName = pstrdup(lefttle->resname);
    1703       33956 :         var = makeVar(leftmostRTI,
    1704       33956 :                       lefttle->resno,
    1705             :                       colType,
    1706             :                       colTypmod,
    1707             :                       colCollation,
    1708             :                       0);
    1709       33956 :         var->location = exprLocation((Node *) lefttle->expr);
    1710       33956 :         tle = makeTargetEntry((Expr *) var,
    1711       33956 :                               (AttrNumber) pstate->p_next_resno++,
    1712             :                               colName,
    1713             :                               false);
    1714       33956 :         qry->targetList = lappend(qry->targetList, tle);
    1715       33956 :         targetvars = lappend(targetvars, var);
    1716       33956 :         targetnames = lappend(targetnames, makeString(colName));
    1717       33956 :         sortnscolumns[sortcolindex].p_varno = leftmostRTI;
    1718       33956 :         sortnscolumns[sortcolindex].p_varattno = lefttle->resno;
    1719       33956 :         sortnscolumns[sortcolindex].p_vartype = colType;
    1720       33956 :         sortnscolumns[sortcolindex].p_vartypmod = colTypmod;
    1721       33956 :         sortnscolumns[sortcolindex].p_varcollid = colCollation;
    1722       33956 :         sortnscolumns[sortcolindex].p_varnosyn = leftmostRTI;
    1723       33956 :         sortnscolumns[sortcolindex].p_varattnosyn = lefttle->resno;
    1724       33956 :         sortcolindex++;
    1725             :     }
    1726             : 
    1727             :     /*
    1728             :      * As a first step towards supporting sort clauses that are expressions
    1729             :      * using the output columns, generate a namespace entry that makes the
    1730             :      * output columns visible.  A Join RTE node is handy for this, since we
    1731             :      * can easily control the Vars generated upon matches.
    1732             :      *
    1733             :      * Note: we don't yet do anything useful with such cases, but at least
    1734             :      * "ORDER BY upper(foo)" will draw the right error message rather than
    1735             :      * "foo not found".
    1736             :      */
    1737        9846 :     sv_rtable_length = list_length(pstate->p_rtable);
    1738             : 
    1739        9846 :     jnsitem = addRangeTableEntryForJoin(pstate,
    1740             :                                         targetnames,
    1741             :                                         sortnscolumns,
    1742             :                                         JOIN_INNER,
    1743             :                                         0,
    1744             :                                         targetvars,
    1745             :                                         NIL,
    1746             :                                         NIL,
    1747             :                                         NULL,
    1748             :                                         false);
    1749             : 
    1750        9846 :     sv_namespace = pstate->p_namespace;
    1751        9846 :     pstate->p_namespace = NIL;
    1752             : 
    1753             :     /* add jnsitem to column namespace only */
    1754        9846 :     addNSItemToQuery(pstate, jnsitem, false, false, true);
    1755             : 
    1756             :     /*
    1757             :      * For now, we don't support resjunk sort clauses on the output of a
    1758             :      * setOperation tree --- you can only use the SQL92-spec options of
    1759             :      * selecting an output column by name or number.  Enforce by checking that
    1760             :      * transformSortClause doesn't add any items to tlist.
    1761             :      */
    1762        9846 :     tllen = list_length(qry->targetList);
    1763             : 
    1764        9846 :     qry->sortClause = transformSortClause(pstate,
    1765             :                                           sortClause,
    1766             :                                           &qry->targetList,
    1767             :                                           EXPR_KIND_ORDER_BY,
    1768             :                                           false /* allow SQL92 rules */ );
    1769             : 
    1770             :     /* restore namespace, remove join RTE from rtable */
    1771        9842 :     pstate->p_namespace = sv_namespace;
    1772        9842 :     pstate->p_rtable = list_truncate(pstate->p_rtable, sv_rtable_length);
    1773             : 
    1774        9842 :     if (tllen != list_length(qry->targetList))
    1775           0 :         ereport(ERROR,
    1776             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1777             :                  errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
    1778             :                  errdetail("Only result column names can be used, not expressions or functions."),
    1779             :                  errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
    1780             :                  parser_errposition(pstate,
    1781             :                                     exprLocation(list_nth(qry->targetList, tllen)))));
    1782             : 
    1783        9842 :     qry->limitOffset = transformLimitClause(pstate, limitOffset,
    1784             :                                             EXPR_KIND_OFFSET, "OFFSET",
    1785             :                                             stmt->limitOption);
    1786        9842 :     qry->limitCount = transformLimitClause(pstate, limitCount,
    1787             :                                            EXPR_KIND_LIMIT, "LIMIT",
    1788             :                                            stmt->limitOption);
    1789        9842 :     qry->limitOption = stmt->limitOption;
    1790             : 
    1791        9842 :     qry->rtable = pstate->p_rtable;
    1792        9842 :     qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
    1793             : 
    1794        9842 :     qry->hasSubLinks = pstate->p_hasSubLinks;
    1795        9842 :     qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
    1796        9842 :     qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
    1797        9842 :     qry->hasAggs = pstate->p_hasAggs;
    1798             : 
    1799        9842 :     foreach(l, lockingClause)
    1800             :     {
    1801           0 :         transformLockingClause(pstate, qry,
    1802           0 :                                (LockingClause *) lfirst(l), false);
    1803             :     }
    1804             : 
    1805        9842 :     assign_query_collations(pstate, qry);
    1806             : 
    1807             :     /* this must be done after collations, for reliable comparison of exprs */
    1808        9842 :     if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
    1809           0 :         parseCheckAggregates(pstate, qry);
    1810             : 
    1811        9842 :     return qry;
    1812             : }
    1813             : 
    1814             : /*
    1815             :  * transformSetOperationTree
    1816             :  *      Recursively transform leaves and internal nodes of a set-op tree
    1817             :  *
    1818             :  * In addition to returning the transformed node, if targetlist isn't NULL
    1819             :  * then we return a list of its non-resjunk TargetEntry nodes.  For a leaf
    1820             :  * set-op node these are the actual targetlist entries; otherwise they are
    1821             :  * dummy entries created to carry the type, typmod, collation, and location
    1822             :  * (for error messages) of each output column of the set-op node.  This info
    1823             :  * is needed only during the internal recursion of this function, so outside
    1824             :  * callers pass NULL for targetlist.  Note: the reason for passing the
    1825             :  * actual targetlist entries of a leaf node is so that upper levels can
    1826             :  * replace UNKNOWN Consts with properly-coerced constants.
    1827             :  */
    1828             : static Node *
    1829       44122 : transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
    1830             :                           bool isTopLevel, List **targetlist)
    1831             : {
    1832             :     bool        isLeaf;
    1833             : 
    1834             :     Assert(stmt && IsA(stmt, SelectStmt));
    1835             : 
    1836             :     /* Guard against stack overflow due to overly complex set-expressions */
    1837       44122 :     check_stack_depth();
    1838             : 
    1839             :     /*
    1840             :      * Validity-check both leaf and internal SELECTs for disallowed ops.
    1841             :      */
    1842       44122 :     if (stmt->intoClause)
    1843           0 :         ereport(ERROR,
    1844             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1845             :                  errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
    1846             :                  parser_errposition(pstate,
    1847             :                                     exprLocation((Node *) stmt->intoClause))));
    1848             : 
    1849             :     /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
    1850       44122 :     if (stmt->lockingClause)
    1851           0 :         ereport(ERROR,
    1852             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1853             :         /*------
    1854             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    1855             :                  errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
    1856             :                         LCS_asString(((LockingClause *)
    1857             :                                       linitial(stmt->lockingClause))->strength))));
    1858             : 
    1859             :     /*
    1860             :      * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE,
    1861             :      * or WITH clauses attached, we need to treat it like a leaf node to
    1862             :      * generate an independent sub-Query tree.  Otherwise, it can be
    1863             :      * represented by a SetOperationStmt node underneath the parent Query.
    1864             :      */
    1865       44122 :     if (stmt->op == SETOP_NONE)
    1866             :     {
    1867             :         Assert(stmt->larg == NULL && stmt->rarg == NULL);
    1868       26964 :         isLeaf = true;
    1869             :     }
    1870             :     else
    1871             :     {
    1872             :         Assert(stmt->larg != NULL && stmt->rarg != NULL);
    1873       17158 :         if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
    1874       17142 :             stmt->lockingClause || stmt->withClause)
    1875          36 :             isLeaf = true;
    1876             :         else
    1877       17122 :             isLeaf = false;
    1878             :     }
    1879             : 
    1880       44122 :     if (isLeaf)
    1881             :     {
    1882             :         /* Process leaf SELECT */
    1883             :         Query      *selectQuery;
    1884             :         char        selectName[32];
    1885             :         ParseNamespaceItem *nsitem;
    1886             :         RangeTblRef *rtr;
    1887             :         ListCell   *tl;
    1888             : 
    1889             :         /*
    1890             :          * Transform SelectStmt into a Query.
    1891             :          *
    1892             :          * This works the same as SELECT transformation normally would, except
    1893             :          * that we prevent resolving unknown-type outputs as TEXT.  This does
    1894             :          * not change the subquery's semantics since if the column type
    1895             :          * matters semantically, it would have been resolved to something else
    1896             :          * anyway.  Doing this lets us resolve such outputs using
    1897             :          * select_common_type(), below.
    1898             :          *
    1899             :          * Note: previously transformed sub-queries don't affect the parsing
    1900             :          * of this sub-query, because they are not in the toplevel pstate's
    1901             :          * namespace list.
    1902             :          */
    1903       27000 :         selectQuery = parse_sub_analyze((Node *) stmt, pstate,
    1904             :                                         NULL, false, false);
    1905             : 
    1906             :         /*
    1907             :          * Check for bogus references to Vars on the current query level (but
    1908             :          * upper-level references are okay). Normally this can't happen
    1909             :          * because the namespace will be empty, but it could happen if we are
    1910             :          * inside a rule.
    1911             :          */
    1912       26980 :         if (pstate->p_namespace)
    1913             :         {
    1914           0 :             if (contain_vars_of_level((Node *) selectQuery, 1))
    1915           0 :                 ereport(ERROR,
    1916             :                         (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1917             :                          errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
    1918             :                          parser_errposition(pstate,
    1919             :                                             locate_var_of_level((Node *) selectQuery, 1))));
    1920             :         }
    1921             : 
    1922             :         /*
    1923             :          * Extract a list of the non-junk TLEs for upper-level processing.
    1924             :          */
    1925       26980 :         if (targetlist)
    1926             :         {
    1927       26980 :             *targetlist = NIL;
    1928      145022 :             foreach(tl, selectQuery->targetList)
    1929             :             {
    1930      118042 :                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
    1931             : 
    1932      118042 :                 if (!tle->resjunk)
    1933      118030 :                     *targetlist = lappend(*targetlist, tle);
    1934             :             }
    1935             :         }
    1936             : 
    1937             :         /*
    1938             :          * Make the leaf query be a subquery in the top-level rangetable.
    1939             :          */
    1940       26980 :         snprintf(selectName, sizeof(selectName), "*SELECT* %d",
    1941       26980 :                  list_length(pstate->p_rtable) + 1);
    1942       26980 :         nsitem = addRangeTableEntryForSubquery(pstate,
    1943             :                                                selectQuery,
    1944             :                                                makeAlias(selectName, NIL),
    1945             :                                                false,
    1946             :                                                false);
    1947             : 
    1948             :         /*
    1949             :          * Return a RangeTblRef to replace the SelectStmt in the set-op tree.
    1950             :          */
    1951       26980 :         rtr = makeNode(RangeTblRef);
    1952       26980 :         rtr->rtindex = nsitem->p_rtindex;
    1953       26980 :         return (Node *) rtr;
    1954             :     }
    1955             :     else
    1956             :     {
    1957             :         /* Process an internal node (set operation node) */
    1958       17122 :         SetOperationStmt *op = makeNode(SetOperationStmt);
    1959             :         List       *ltargetlist;
    1960             :         List       *rtargetlist;
    1961             :         ListCell   *ltl;
    1962             :         ListCell   *rtl;
    1963             :         const char *context;
    1964             : 
    1965       17406 :         context = (stmt->op == SETOP_UNION ? "UNION" :
    1966         284 :                    (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
    1967             :                     "EXCEPT"));
    1968             : 
    1969       17122 :         op->op = stmt->op;
    1970       17122 :         op->all = stmt->all;
    1971             : 
    1972             :         /*
    1973             :          * Recursively transform the left child node.
    1974             :          */
    1975       17122 :         op->larg = transformSetOperationTree(pstate, stmt->larg,
    1976             :                                              false,
    1977             :                                              &ltargetlist);
    1978             : 
    1979             :         /*
    1980             :          * If we are processing a recursive union query, now is the time to
    1981             :          * examine the non-recursive term's output columns and mark the
    1982             :          * containing CTE as having those result columns.  We should do this
    1983             :          * only at the topmost setop of the CTE, of course.
    1984             :          */
    1985       17118 :         if (isTopLevel &&
    1986        9878 :             pstate->p_parent_cte &&
    1987         402 :             pstate->p_parent_cte->cterecursive)
    1988         366 :             determineRecursiveColTypes(pstate, op->larg, ltargetlist);
    1989             : 
    1990             :         /*
    1991             :          * Recursively transform the right child node.
    1992             :          */
    1993       17118 :         op->rarg = transformSetOperationTree(pstate, stmt->rarg,
    1994             :                                              false,
    1995             :                                              &rtargetlist);
    1996             : 
    1997             :         /*
    1998             :          * Verify that the two children have the same number of non-junk
    1999             :          * columns, and determine the types of the merged output columns.
    2000             :          */
    2001       17102 :         if (list_length(ltargetlist) != list_length(rtargetlist))
    2002           0 :             ereport(ERROR,
    2003             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2004             :                      errmsg("each %s query must have the same number of columns",
    2005             :                             context),
    2006             :                      parser_errposition(pstate,
    2007             :                                         exprLocation((Node *) rtargetlist))));
    2008             : 
    2009       17102 :         if (targetlist)
    2010        7240 :             *targetlist = NIL;
    2011       17102 :         op->colTypes = NIL;
    2012       17102 :         op->colTypmods = NIL;
    2013       17102 :         op->colCollations = NIL;
    2014       17102 :         op->groupClauses = NIL;
    2015      101116 :         forboth(ltl, ltargetlist, rtl, rtargetlist)
    2016             :         {
    2017       84030 :             TargetEntry *ltle = (TargetEntry *) lfirst(ltl);
    2018       84030 :             TargetEntry *rtle = (TargetEntry *) lfirst(rtl);
    2019       84030 :             Node       *lcolnode = (Node *) ltle->expr;
    2020       84030 :             Node       *rcolnode = (Node *) rtle->expr;
    2021       84030 :             Oid         lcoltype = exprType(lcolnode);
    2022       84030 :             Oid         rcoltype = exprType(rcolnode);
    2023       84030 :             int32       lcoltypmod = exprTypmod(lcolnode);
    2024       84030 :             int32       rcoltypmod = exprTypmod(rcolnode);
    2025             :             Node       *bestexpr;
    2026             :             int         bestlocation;
    2027             :             Oid         rescoltype;
    2028             :             int32       rescoltypmod;
    2029             :             Oid         rescolcoll;
    2030             : 
    2031             :             /* select common type, same as CASE et al */
    2032       84030 :             rescoltype = select_common_type(pstate,
    2033       84030 :                                             list_make2(lcolnode, rcolnode),
    2034             :                                             context,
    2035             :                                             &bestexpr);
    2036       84030 :             bestlocation = exprLocation(bestexpr);
    2037             :             /* if same type and same typmod, use typmod; else default */
    2038       84030 :             if (lcoltype == rcoltype && lcoltypmod == rcoltypmod)
    2039       78782 :                 rescoltypmod = lcoltypmod;
    2040             :             else
    2041        5248 :                 rescoltypmod = -1;
    2042             : 
    2043             :             /*
    2044             :              * Verify the coercions are actually possible.  If not, we'd fail
    2045             :              * later anyway, but we want to fail now while we have sufficient
    2046             :              * context to produce an error cursor position.
    2047             :              *
    2048             :              * For all non-UNKNOWN-type cases, we verify coercibility but we
    2049             :              * don't modify the child's expression, for fear of changing the
    2050             :              * child query's semantics.
    2051             :              *
    2052             :              * If a child expression is an UNKNOWN-type Const or Param, we
    2053             :              * want to replace it with the coerced expression.  This can only
    2054             :              * happen when the child is a leaf set-op node.  It's safe to
    2055             :              * replace the expression because if the child query's semantics
    2056             :              * depended on the type of this output column, it'd have already
    2057             :              * coerced the UNKNOWN to something else.  We want to do this
    2058             :              * because (a) we want to verify that a Const is valid for the
    2059             :              * target type, or resolve the actual type of an UNKNOWN Param,
    2060             :              * and (b) we want to avoid unnecessary discrepancies between the
    2061             :              * output type of the child query and the resolved target type.
    2062             :              * Such a discrepancy would disable optimization in the planner.
    2063             :              *
    2064             :              * If it's some other UNKNOWN-type node, eg a Var, we do nothing
    2065             :              * (knowing that coerce_to_common_type would fail).  The planner
    2066             :              * is sometimes able to fold an UNKNOWN Var to a constant before
    2067             :              * it has to coerce the type, so failing now would just break
    2068             :              * cases that might work.
    2069             :              */
    2070       84030 :             if (lcoltype != UNKNOWNOID)
    2071       83628 :                 lcolnode = coerce_to_common_type(pstate, lcolnode,
    2072             :                                                  rescoltype, context);
    2073         402 :             else if (IsA(lcolnode, Const) ||
    2074           0 :                      IsA(lcolnode, Param))
    2075             :             {
    2076         402 :                 lcolnode = coerce_to_common_type(pstate, lcolnode,
    2077             :                                                  rescoltype, context);
    2078         402 :                 ltle->expr = (Expr *) lcolnode;
    2079             :             }
    2080             : 
    2081       84030 :             if (rcoltype != UNKNOWNOID)
    2082       81028 :                 rcolnode = coerce_to_common_type(pstate, rcolnode,
    2083             :                                                  rescoltype, context);
    2084        3002 :             else if (IsA(rcolnode, Const) ||
    2085           0 :                      IsA(rcolnode, Param))
    2086             :             {
    2087        3002 :                 rcolnode = coerce_to_common_type(pstate, rcolnode,
    2088             :                                                  rescoltype, context);
    2089        2998 :                 rtle->expr = (Expr *) rcolnode;
    2090             :             }
    2091             : 
    2092             :             /*
    2093             :              * Select common collation.  A common collation is required for
    2094             :              * all set operators except UNION ALL; see SQL:2008 7.13 <query
    2095             :              * expression> Syntax Rule 15c.  (If we fail to identify a common
    2096             :              * collation for a UNION ALL column, the colCollations element
    2097             :              * will be set to InvalidOid, which may result in a runtime error
    2098             :              * if something at a higher query level wants to use the column's
    2099             :              * collation.)
    2100             :              */
    2101       84026 :             rescolcoll = select_common_collation(pstate,
    2102       84026 :                                                  list_make2(lcolnode, rcolnode),
    2103       84026 :                                                  (op->op == SETOP_UNION && op->all));
    2104             : 
    2105             :             /* emit results */
    2106       84014 :             op->colTypes = lappend_oid(op->colTypes, rescoltype);
    2107       84014 :             op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
    2108       84014 :             op->colCollations = lappend_oid(op->colCollations, rescolcoll);
    2109             : 
    2110             :             /*
    2111             :              * For all cases except UNION ALL, identify the grouping operators
    2112             :              * (and, if available, sorting operators) that will be used to
    2113             :              * eliminate duplicates.
    2114             :              */
    2115       84014 :             if (op->op != SETOP_UNION || !op->all)
    2116             :             {
    2117        8932 :                 SortGroupClause *grpcl = makeNode(SortGroupClause);
    2118             :                 Oid         sortop;
    2119             :                 Oid         eqop;
    2120             :                 bool        hashable;
    2121             :                 ParseCallbackState pcbstate;
    2122             : 
    2123        8932 :                 setup_parser_errposition_callback(&pcbstate, pstate,
    2124             :                                                   bestlocation);
    2125             : 
    2126             :                 /* determine the eqop and optional sortop */
    2127        8932 :                 get_sort_group_operators(rescoltype,
    2128             :                                          false, true, false,
    2129             :                                          &sortop, &eqop, NULL,
    2130             :                                          &hashable);
    2131             : 
    2132        8932 :                 cancel_parser_errposition_callback(&pcbstate);
    2133             : 
    2134             :                 /* we don't have a tlist yet, so can't assign sortgrouprefs */
    2135        8932 :                 grpcl->tleSortGroupRef = 0;
    2136        8932 :                 grpcl->eqop = eqop;
    2137        8932 :                 grpcl->sortop = sortop;
    2138        8932 :                 grpcl->nulls_first = false; /* OK with or without sortop */
    2139        8932 :                 grpcl->hashable = hashable;
    2140             : 
    2141        8932 :                 op->groupClauses = lappend(op->groupClauses, grpcl);
    2142             :             }
    2143             : 
    2144             :             /*
    2145             :              * Construct a dummy tlist entry to return.  We use a SetToDefault
    2146             :              * node for the expression, since it carries exactly the fields
    2147             :              * needed, but any other expression node type would do as well.
    2148             :              */
    2149       84014 :             if (targetlist)
    2150             :             {
    2151       50046 :                 SetToDefault *rescolnode = makeNode(SetToDefault);
    2152             :                 TargetEntry *restle;
    2153             : 
    2154       50046 :                 rescolnode->typeId = rescoltype;
    2155       50046 :                 rescolnode->typeMod = rescoltypmod;
    2156       50046 :                 rescolnode->collation = rescolcoll;
    2157       50046 :                 rescolnode->location = bestlocation;
    2158       50046 :                 restle = makeTargetEntry((Expr *) rescolnode,
    2159             :                                          0, /* no need to set resno */
    2160             :                                          NULL,
    2161             :                                          false);
    2162       50046 :                 *targetlist = lappend(*targetlist, restle);
    2163             :             }
    2164             :         }
    2165             : 
    2166       17086 :         return (Node *) op;
    2167             :     }
    2168             : }
    2169             : 
    2170             : /*
    2171             :  * Process the outputs of the non-recursive term of a recursive union
    2172             :  * to set up the parent CTE's columns
    2173             :  */
    2174             : static void
    2175         366 : determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
    2176             : {
    2177             :     Node       *node;
    2178             :     int         leftmostRTI;
    2179             :     Query      *leftmostQuery;
    2180             :     List       *targetList;
    2181             :     ListCell   *left_tlist;
    2182             :     ListCell   *nrtl;
    2183             :     int         next_resno;
    2184             : 
    2185             :     /*
    2186             :      * Find leftmost leaf SELECT
    2187             :      */
    2188         366 :     node = larg;
    2189         366 :     while (node && IsA(node, SetOperationStmt))
    2190           0 :         node = ((SetOperationStmt *) node)->larg;
    2191             :     Assert(node && IsA(node, RangeTblRef));
    2192         366 :     leftmostRTI = ((RangeTblRef *) node)->rtindex;
    2193         366 :     leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
    2194             :     Assert(leftmostQuery != NULL);
    2195             : 
    2196             :     /*
    2197             :      * Generate dummy targetlist using column names of leftmost select and
    2198             :      * dummy result expressions of the non-recursive term.
    2199             :      */
    2200         366 :     targetList = NIL;
    2201         366 :     next_resno = 1;
    2202             : 
    2203        1168 :     forboth(nrtl, nrtargetlist, left_tlist, leftmostQuery->targetList)
    2204             :     {
    2205         802 :         TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl);
    2206         802 :         TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
    2207             :         char       *colName;
    2208             :         TargetEntry *tle;
    2209             : 
    2210             :         Assert(!lefttle->resjunk);
    2211         802 :         colName = pstrdup(lefttle->resname);
    2212         802 :         tle = makeTargetEntry(nrtle->expr,
    2213         802 :                               next_resno++,
    2214             :                               colName,
    2215             :                               false);
    2216         802 :         targetList = lappend(targetList, tle);
    2217             :     }
    2218             : 
    2219             :     /* Now build CTE's output column info using dummy targetlist */
    2220         366 :     analyzeCTETargetList(pstate, pstate->p_parent_cte, targetList);
    2221         366 : }
    2222             : 
    2223             : 
    2224             : /*
    2225             :  * transformUpdateStmt -
    2226             :  *    transforms an update statement
    2227             :  */
    2228             : static Query *
    2229        9972 : transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
    2230             : {
    2231        9972 :     Query      *qry = makeNode(Query);
    2232             :     ParseNamespaceItem *nsitem;
    2233             :     Node       *qual;
    2234             : 
    2235        9972 :     qry->commandType = CMD_UPDATE;
    2236        9972 :     pstate->p_is_insert = false;
    2237             : 
    2238             :     /* process the WITH clause independently of all else */
    2239        9972 :     if (stmt->withClause)
    2240             :     {
    2241          40 :         qry->hasRecursive = stmt->withClause->recursive;
    2242          40 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
    2243          40 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
    2244             :     }
    2245             : 
    2246       19942 :     qry->resultRelation = setTargetTable(pstate, stmt->relation,
    2247        9972 :                                          stmt->relation->inh,
    2248             :                                          true,
    2249             :                                          ACL_UPDATE);
    2250        9970 :     nsitem = pstate->p_target_nsitem;
    2251             : 
    2252             :     /* subqueries in FROM cannot access the result relation */
    2253        9970 :     nsitem->p_lateral_only = true;
    2254        9970 :     nsitem->p_lateral_ok = false;
    2255             : 
    2256             :     /*
    2257             :      * the FROM clause is non-standard SQL syntax. We used to be able to do
    2258             :      * this with REPLACE in POSTQUEL so we keep the feature.
    2259             :      */
    2260        9970 :     transformFromClause(pstate, stmt->fromClause);
    2261             : 
    2262             :     /* remaining clauses can reference the result relation normally */
    2263        9954 :     nsitem->p_lateral_only = false;
    2264        9954 :     nsitem->p_lateral_ok = true;
    2265             : 
    2266        9954 :     qual = transformWhereClause(pstate, stmt->whereClause,
    2267             :                                 EXPR_KIND_WHERE, "WHERE");
    2268             : 
    2269        9946 :     qry->returningList = transformReturningList(pstate, stmt->returningList);
    2270             : 
    2271             :     /*
    2272             :      * Now we are done with SELECT-like processing, and can get on with
    2273             :      * transforming the target list to match the UPDATE target columns.
    2274             :      */
    2275        9946 :     qry->targetList = transformUpdateTargetList(pstate, stmt->targetList);
    2276             : 
    2277        9922 :     qry->rtable = pstate->p_rtable;
    2278        9922 :     qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
    2279             : 
    2280        9922 :     qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
    2281        9922 :     qry->hasSubLinks = pstate->p_hasSubLinks;
    2282             : 
    2283        9922 :     assign_query_collations(pstate, qry);
    2284             : 
    2285        9922 :     return qry;
    2286             : }
    2287             : 
    2288             : /*
    2289             :  * transformUpdateTargetList -
    2290             :  *  handle SET clause in UPDATE/INSERT ... ON CONFLICT UPDATE
    2291             :  */
    2292             : static List *
    2293       10702 : transformUpdateTargetList(ParseState *pstate, List *origTlist)
    2294             : {
    2295       10702 :     List       *tlist = NIL;
    2296             :     RangeTblEntry *target_rte;
    2297             :     ListCell   *orig_tl;
    2298             :     ListCell   *tl;
    2299       10702 :     TupleDesc   tupdesc = pstate->p_target_relation->rd_att;
    2300             : 
    2301       10702 :     tlist = transformTargetList(pstate, origTlist,
    2302             :                                 EXPR_KIND_UPDATE_SOURCE);
    2303             : 
    2304             :     /* Prepare to assign non-conflicting resnos to resjunk attributes */
    2305       10674 :     if (pstate->p_next_resno <= RelationGetNumberOfAttributes(pstate->p_target_relation))
    2306        9376 :         pstate->p_next_resno = RelationGetNumberOfAttributes(pstate->p_target_relation) + 1;
    2307             : 
    2308             :     /* Prepare non-junk columns for assignment to target table */
    2309       10674 :     target_rte = pstate->p_target_nsitem->p_rte;
    2310       10674 :     orig_tl = list_head(origTlist);
    2311             : 
    2312       24366 :     foreach(tl, tlist)
    2313             :     {
    2314       13704 :         TargetEntry *tle = (TargetEntry *) lfirst(tl);
    2315             :         ResTarget  *origTarget;
    2316             :         int         attrno;
    2317             : 
    2318       13704 :         if (tle->resjunk)
    2319             :         {
    2320             :             /*
    2321             :              * Resjunk nodes need no additional processing, but be sure they
    2322             :              * have resnos that do not match any target columns; else rewriter
    2323             :              * or planner might get confused.  They don't need a resname
    2324             :              * either.
    2325             :              */
    2326          62 :             tle->resno = (AttrNumber) pstate->p_next_resno++;
    2327          62 :             tle->resname = NULL;
    2328          62 :             continue;
    2329             :         }
    2330       13642 :         if (orig_tl == NULL)
    2331           0 :             elog(ERROR, "UPDATE target count mismatch --- internal error");
    2332       13642 :         origTarget = lfirst_node(ResTarget, orig_tl);
    2333             : 
    2334       13642 :         attrno = attnameAttNum(pstate->p_target_relation,
    2335       13642 :                                origTarget->name, true);
    2336       13642 :         if (attrno == InvalidAttrNumber)
    2337           8 :             ereport(ERROR,
    2338             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    2339             :                      errmsg("column \"%s\" of relation \"%s\" does not exist",
    2340             :                             origTarget->name,
    2341             :                             RelationGetRelationName(pstate->p_target_relation)),
    2342             :                      parser_errposition(pstate, origTarget->location)));
    2343             : 
    2344       13634 :         updateTargetListEntry(pstate, tle, origTarget->name,
    2345             :                               attrno,
    2346             :                               origTarget->indirection,
    2347             :                               origTarget->location);
    2348             : 
    2349             :         /* Mark the target column as requiring update permissions */
    2350       13630 :         target_rte->updatedCols = bms_add_member(target_rte->updatedCols,
    2351             :                                                  attrno - FirstLowInvalidHeapAttributeNumber);
    2352             : 
    2353       13630 :         orig_tl = lnext(origTlist, orig_tl);
    2354             :     }
    2355       10662 :     if (orig_tl != NULL)
    2356           0 :         elog(ERROR, "UPDATE target count mismatch --- internal error");
    2357             : 
    2358       10662 :     fill_extraUpdatedCols(target_rte, tupdesc);
    2359             : 
    2360       10662 :     return tlist;
    2361             : }
    2362             : 
    2363             : /*
    2364             :  * Record in extraUpdatedCols generated columns referencing updated base
    2365             :  * columns.
    2366             :  */
    2367             : void
    2368       10924 : fill_extraUpdatedCols(RangeTblEntry *target_rte, TupleDesc tupdesc)
    2369             : {
    2370       10924 :     if (tupdesc->constr &&
    2371        7216 :         tupdesc->constr->has_generated_stored)
    2372             :     {
    2373          88 :         for (int i = 0; i < tupdesc->constr->num_defval; i++)
    2374             :         {
    2375          44 :             AttrDefault defval = tupdesc->constr->defval[i];
    2376             :             Node       *expr;
    2377          44 :             Bitmapset  *attrs_used = NULL;
    2378             : 
    2379             :             /* skip if not generated column */
    2380          44 :             if (!TupleDescAttr(tupdesc, defval.adnum - 1)->attgenerated)
    2381           0 :                 continue;
    2382             : 
    2383          44 :             expr = stringToNode(defval.adbin);
    2384          44 :             pull_varattnos(expr, 1, &attrs_used);
    2385             : 
    2386          44 :             if (bms_overlap(target_rte->updatedCols, attrs_used))
    2387          36 :                 target_rte->extraUpdatedCols = bms_add_member(target_rte->extraUpdatedCols,
    2388          36 :                                                               defval.adnum - FirstLowInvalidHeapAttributeNumber);
    2389             :         }
    2390             :     }
    2391       10924 : }
    2392             : 
    2393             : /*
    2394             :  * transformReturningList -
    2395             :  *  handle a RETURNING clause in INSERT/UPDATE/DELETE
    2396             :  */
    2397             : static List *
    2398       13874 : transformReturningList(ParseState *pstate, List *returningList)
    2399             : {
    2400             :     List       *rlist;
    2401             :     int         save_next_resno;
    2402             : 
    2403       13874 :     if (returningList == NIL)
    2404       12138 :         return NIL;             /* nothing to do */
    2405             : 
    2406             :     /*
    2407             :      * We need to assign resnos starting at one in the RETURNING list. Save
    2408             :      * and restore the main tlist's value of p_next_resno, just in case
    2409             :      * someone looks at it later (probably won't happen).
    2410             :      */
    2411        1736 :     save_next_resno = pstate->p_next_resno;
    2412        1736 :     pstate->p_next_resno = 1;
    2413             : 
    2414             :     /* transform RETURNING identically to a SELECT targetlist */
    2415        1736 :     rlist = transformTargetList(pstate, returningList, EXPR_KIND_RETURNING);
    2416             : 
    2417             :     /*
    2418             :      * Complain if the nonempty tlist expanded to nothing (which is possible
    2419             :      * if it contains only a star-expansion of a zero-column table).  If we
    2420             :      * allow this, the parsed Query will look like it didn't have RETURNING,
    2421             :      * with results that would probably surprise the user.
    2422             :      */
    2423        1720 :     if (rlist == NIL)
    2424           0 :         ereport(ERROR,
    2425             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    2426             :                  errmsg("RETURNING must have at least one column"),
    2427             :                  parser_errposition(pstate,
    2428             :                                     exprLocation(linitial(returningList)))));
    2429             : 
    2430             :     /* mark column origins */
    2431        1720 :     markTargetListOrigins(pstate, rlist);
    2432             : 
    2433             :     /* resolve any still-unresolved output columns as being type text */
    2434        1720 :     if (pstate->p_resolve_unknowns)
    2435        1720 :         resolveTargetListUnknowns(pstate, rlist);
    2436             : 
    2437             :     /* restore state */
    2438        1720 :     pstate->p_next_resno = save_next_resno;
    2439             : 
    2440        1720 :     return rlist;
    2441             : }
    2442             : 
    2443             : 
    2444             : /*
    2445             :  * transformDeclareCursorStmt -
    2446             :  *  transform a DECLARE CURSOR Statement
    2447             :  *
    2448             :  * DECLARE CURSOR is like other utility statements in that we emit it as a
    2449             :  * CMD_UTILITY Query node; however, we must first transform the contained
    2450             :  * query.  We used to postpone that until execution, but it's really necessary
    2451             :  * to do it during the normal parse analysis phase to ensure that side effects
    2452             :  * of parser hooks happen at the expected time.
    2453             :  */
    2454             : static Query *
    2455        2032 : transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
    2456             : {
    2457             :     Query      *result;
    2458             :     Query      *query;
    2459             : 
    2460             :     /*
    2461             :      * Don't allow both SCROLL and NO SCROLL to be specified
    2462             :      */
    2463        2032 :     if ((stmt->options & CURSOR_OPT_SCROLL) &&
    2464         148 :         (stmt->options & CURSOR_OPT_NO_SCROLL))
    2465           0 :         ereport(ERROR,
    2466             :                 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
    2467             :                  errmsg("cannot specify both SCROLL and NO SCROLL")));
    2468             : 
    2469             :     /* Transform contained query, not allowing SELECT INTO */
    2470        2032 :     query = transformStmt(pstate, stmt->query);
    2471        2020 :     stmt->query = (Node *) query;
    2472             : 
    2473             :     /* Grammar should not have allowed anything but SELECT */
    2474        2020 :     if (!IsA(query, Query) ||
    2475        2020 :         query->commandType != CMD_SELECT)
    2476           0 :         elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
    2477             : 
    2478             :     /*
    2479             :      * We also disallow data-modifying WITH in a cursor.  (This could be
    2480             :      * allowed, but the semantics of when the updates occur might be
    2481             :      * surprising.)
    2482             :      */
    2483        2020 :     if (query->hasModifyingCTE)
    2484           0 :         ereport(ERROR,
    2485             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2486             :                  errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH")));
    2487             : 
    2488             :     /* FOR UPDATE and WITH HOLD are not compatible */
    2489        2020 :     if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
    2490           0 :         ereport(ERROR,
    2491             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2492             :         /*------
    2493             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2494             :                  errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported",
    2495             :                         LCS_asString(((RowMarkClause *)
    2496             :                                       linitial(query->rowMarks))->strength)),
    2497             :                  errdetail("Holdable cursors must be READ ONLY.")));
    2498             : 
    2499             :     /* FOR UPDATE and SCROLL are not compatible */
    2500        2020 :     if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_SCROLL))
    2501           0 :         ereport(ERROR,
    2502             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2503             :         /*------
    2504             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2505             :                  errmsg("DECLARE SCROLL CURSOR ... %s is not supported",
    2506             :                         LCS_asString(((RowMarkClause *)
    2507             :                                       linitial(query->rowMarks))->strength)),
    2508             :                  errdetail("Scrollable cursors must be READ ONLY.")));
    2509             : 
    2510             :     /* FOR UPDATE and INSENSITIVE are not compatible */
    2511        2020 :     if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE))
    2512           0 :         ereport(ERROR,
    2513             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2514             :         /*------
    2515             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2516             :                  errmsg("DECLARE INSENSITIVE CURSOR ... %s is not supported",
    2517             :                         LCS_asString(((RowMarkClause *)
    2518             :                                       linitial(query->rowMarks))->strength)),
    2519             :                  errdetail("Insensitive cursors must be READ ONLY.")));
    2520             : 
    2521             :     /* represent the command as a utility Query */
    2522        2020 :     result = makeNode(Query);
    2523        2020 :     result->commandType = CMD_UTILITY;
    2524        2020 :     result->utilityStmt = (Node *) stmt;
    2525             : 
    2526        2020 :     return result;
    2527             : }
    2528             : 
    2529             : 
    2530             : /*
    2531             :  * transformExplainStmt -
    2532             :  *  transform an EXPLAIN Statement
    2533             :  *
    2534             :  * EXPLAIN is like other utility statements in that we emit it as a
    2535             :  * CMD_UTILITY Query node; however, we must first transform the contained
    2536             :  * query.  We used to postpone that until execution, but it's really necessary
    2537             :  * to do it during the normal parse analysis phase to ensure that side effects
    2538             :  * of parser hooks happen at the expected time.
    2539             :  */
    2540             : static Query *
    2541       10406 : transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
    2542             : {
    2543             :     Query      *result;
    2544             : 
    2545             :     /* transform contained query, allowing SELECT INTO */
    2546       10406 :     stmt->query = (Node *) transformOptionalSelectInto(pstate, stmt->query);
    2547             : 
    2548             :     /* represent the command as a utility Query */
    2549       10402 :     result = makeNode(Query);
    2550       10402 :     result->commandType = CMD_UTILITY;
    2551       10402 :     result->utilityStmt = (Node *) stmt;
    2552             : 
    2553       10402 :     return result;
    2554             : }
    2555             : 
    2556             : 
    2557             : /*
    2558             :  * transformCreateTableAsStmt -
    2559             :  *  transform a CREATE TABLE AS, SELECT ... INTO, or CREATE MATERIALIZED VIEW
    2560             :  *  Statement
    2561             :  *
    2562             :  * As with DECLARE CURSOR and EXPLAIN, transform the contained statement now.
    2563             :  */
    2564             : static Query *
    2565         954 : transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
    2566             : {
    2567             :     Query      *result;
    2568             :     Query      *query;
    2569             : 
    2570             :     /* transform contained query, not allowing SELECT INTO */
    2571         954 :     query = transformStmt(pstate, stmt->query);
    2572         954 :     stmt->query = (Node *) query;
    2573             : 
    2574             :     /* additional work needed for CREATE MATERIALIZED VIEW */
    2575         954 :     if (stmt->relkind == OBJECT_MATVIEW)
    2576             :     {
    2577             :         /*
    2578             :          * Prohibit a data-modifying CTE in the query used to create a
    2579             :          * materialized view. It's not sufficiently clear what the user would
    2580             :          * want to happen if the MV is refreshed or incrementally maintained.
    2581             :          */
    2582         206 :         if (query->hasModifyingCTE)
    2583           0 :             ereport(ERROR,
    2584             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2585             :                      errmsg("materialized views must not use data-modifying statements in WITH")));
    2586             : 
    2587             :         /*
    2588             :          * Check whether any temporary database objects are used in the
    2589             :          * creation query. It would be hard to refresh data or incrementally
    2590             :          * maintain it if a source disappeared.
    2591             :          */
    2592         206 :         if (isQueryUsingTempRelation(query))
    2593           0 :             ereport(ERROR,
    2594             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2595             :                      errmsg("materialized views must not use temporary tables or views")));
    2596             : 
    2597             :         /*
    2598             :          * A materialized view would either need to save parameters for use in
    2599             :          * maintaining/loading the data or prohibit them entirely.  The latter
    2600             :          * seems safer and more sane.
    2601             :          */
    2602         206 :         if (query_contains_extern_params(query))
    2603           0 :             ereport(ERROR,
    2604             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2605             :                      errmsg("materialized views may not be defined using bound parameters")));
    2606             : 
    2607             :         /*
    2608             :          * For now, we disallow unlogged materialized views, because it seems
    2609             :          * like a bad idea for them to just go to empty after a crash. (If we
    2610             :          * could mark them as unpopulated, that would be better, but that
    2611             :          * requires catalog changes which crash recovery can't presently
    2612             :          * handle.)
    2613             :          */
    2614         206 :         if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED)
    2615           0 :             ereport(ERROR,
    2616             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2617             :                      errmsg("materialized views cannot be unlogged")));
    2618             : 
    2619             :         /*
    2620             :          * At runtime, we'll need a copy of the parsed-but-not-rewritten Query
    2621             :          * for purposes of creating the view's ON SELECT rule.  We stash that
    2622             :          * in the IntoClause because that's where intorel_startup() can
    2623             :          * conveniently get it from.
    2624             :          */
    2625         206 :         stmt->into->viewQuery = (Node *) copyObject(query);
    2626             :     }
    2627             : 
    2628             :     /* represent the command as a utility Query */
    2629         954 :     result = makeNode(Query);
    2630         954 :     result->commandType = CMD_UTILITY;
    2631         954 :     result->utilityStmt = (Node *) stmt;
    2632             : 
    2633         954 :     return result;
    2634             : }
    2635             : 
    2636             : /*
    2637             :  * transform a CallStmt
    2638             :  *
    2639             :  * We need to do parse analysis on the procedure call and its arguments.
    2640             :  */
    2641             : static Query *
    2642         260 : transformCallStmt(ParseState *pstate, CallStmt *stmt)
    2643             : {
    2644             :     List       *targs;
    2645             :     ListCell   *lc;
    2646             :     Node       *node;
    2647             :     Query      *result;
    2648             : 
    2649         260 :     targs = NIL;
    2650         596 :     foreach(lc, stmt->funccall->args)
    2651             :     {
    2652         336 :         targs = lappend(targs, transformExpr(pstate,
    2653         336 :                                              (Node *) lfirst(lc),
    2654             :                                              EXPR_KIND_CALL_ARGUMENT));
    2655             :     }
    2656             : 
    2657         520 :     node = ParseFuncOrColumn(pstate,
    2658         260 :                              stmt->funccall->funcname,
    2659             :                              targs,
    2660             :                              pstate->p_last_srf,
    2661             :                              stmt->funccall,
    2662             :                              true,
    2663         260 :                              stmt->funccall->location);
    2664             : 
    2665         244 :     assign_expr_collations(pstate, node);
    2666             : 
    2667         244 :     stmt->funcexpr = castNode(FuncExpr, node);
    2668             : 
    2669         244 :     result = makeNode(Query);
    2670         244 :     result->commandType = CMD_UTILITY;
    2671         244 :     result->utilityStmt = (Node *) stmt;
    2672             : 
    2673         244 :     return result;
    2674             : }
    2675             : 
    2676             : /*
    2677             :  * Produce a string representation of a LockClauseStrength value.
    2678             :  * This should only be applied to valid values (not LCS_NONE).
    2679             :  */
    2680             : const char *
    2681           8 : LCS_asString(LockClauseStrength strength)
    2682             : {
    2683           8 :     switch (strength)
    2684             :     {
    2685           0 :         case LCS_NONE:
    2686             :             Assert(false);
    2687           0 :             break;
    2688           0 :         case LCS_FORKEYSHARE:
    2689           0 :             return "FOR KEY SHARE";
    2690           0 :         case LCS_FORSHARE:
    2691           0 :             return "FOR SHARE";
    2692           4 :         case LCS_FORNOKEYUPDATE:
    2693           4 :             return "FOR NO KEY UPDATE";
    2694           4 :         case LCS_FORUPDATE:
    2695           4 :             return "FOR UPDATE";
    2696             :     }
    2697           0 :     return "FOR some";            /* shouldn't happen */
    2698             : }
    2699             : 
    2700             : /*
    2701             :  * Check for features that are not supported with FOR [KEY] UPDATE/SHARE.
    2702             :  *
    2703             :  * exported so planner can check again after rewriting, query pullup, etc
    2704             :  */
    2705             : void
    2706        8744 : CheckSelectLocking(Query *qry, LockClauseStrength strength)
    2707             : {
    2708             :     Assert(strength != LCS_NONE);   /* else caller error */
    2709             : 
    2710        8744 :     if (qry->setOperations)
    2711           0 :         ereport(ERROR,
    2712             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2713             :         /*------
    2714             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2715             :                  errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
    2716             :                         LCS_asString(strength))));
    2717        8744 :     if (qry->distinctClause != NIL)
    2718           0 :         ereport(ERROR,
    2719             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2720             :         /*------
    2721             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2722             :                  errmsg("%s is not allowed with DISTINCT clause",
    2723             :                         LCS_asString(strength))));
    2724        8744 :     if (qry->groupClause != NIL)
    2725           0 :         ereport(ERROR,
    2726             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2727             :         /*------
    2728             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2729             :                  errmsg("%s is not allowed with GROUP BY clause",
    2730             :                         LCS_asString(strength))));
    2731        8744 :     if (qry->havingQual != NULL)
    2732           0 :         ereport(ERROR,
    2733             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2734             :         /*------
    2735             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2736             :                  errmsg("%s is not allowed with HAVING clause",
    2737             :                         LCS_asString(strength))));
    2738        8744 :     if (qry->hasAggs)
    2739           4 :         ereport(ERROR,
    2740             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2741             :         /*------
    2742             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2743             :                  errmsg("%s is not allowed with aggregate functions",
    2744             :                         LCS_asString(strength))));
    2745        8740 :     if (qry->hasWindowFuncs)
    2746           0 :         ereport(ERROR,
    2747             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2748             :         /*------
    2749             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2750             :                  errmsg("%s is not allowed with window functions",
    2751             :                         LCS_asString(strength))));
    2752        8740 :     if (qry->hasTargetSRFs)
    2753           0 :         ereport(ERROR,
    2754             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2755             :         /*------
    2756             :           translator: %s is a SQL row locking clause such as FOR UPDATE */
    2757             :                  errmsg("%s is not allowed with set-returning functions in the target list",
    2758             :                         LCS_asString(strength))));
    2759        8740 : }
    2760             : 
    2761             : /*
    2762             :  * Transform a FOR [KEY] UPDATE/SHARE clause
    2763             :  *
    2764             :  * This basically involves replacing names by integer relids.
    2765             :  *
    2766             :  * NB: if you need to change this, see also markQueryForLocking()
    2767             :  * in rewriteHandler.c, and isLockedRefname() in parse_relation.c.
    2768             :  */
    2769             : static void
    2770        3836 : transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
    2771             :                        bool pushedDown)
    2772             : {
    2773        3836 :     List       *lockedRels = lc->lockedRels;
    2774             :     ListCell   *l;
    2775             :     ListCell   *rt;
    2776             :     Index       i;
    2777             :     LockingClause *allrels;
    2778             : 
    2779        3836 :     CheckSelectLocking(qry, lc->strength);
    2780             : 
    2781             :     /* make a clause we can pass down to subqueries to select all rels */
    2782        3832 :     allrels = makeNode(LockingClause);
    2783        3832 :     allrels->lockedRels = NIL;   /* indicates all rels */
    2784        3832 :     allrels->strength = lc->strength;
    2785        3832 :     allrels->waitPolicy = lc->waitPolicy;
    2786             : 
    2787        3832 :     if (lockedRels == NIL)
    2788             :     {
    2789             :         /* all regular tables used in query */
    2790        1532 :         i = 0;
    2791        3124 :         foreach(rt, qry->rtable)
    2792             :         {
    2793        1592 :             RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
    2794             : 
    2795        1592 :             ++i;
    2796        1592 :             switch (rte->rtekind)
    2797             :             {
    2798        1564 :                 case RTE_RELATION:
    2799        1564 :                     applyLockingClause(qry, i, lc->strength, lc->waitPolicy,
    2800             :                                        pushedDown);
    2801        1564 :                     rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
    2802        1564 :                     break;
    2803           0 :                 case RTE_SUBQUERY:
    2804           0 :                     applyLockingClause(qry, i, lc->strength, lc->waitPolicy,
    2805             :                                        pushedDown);
    2806             : 
    2807             :                     /*
    2808             :                      * FOR UPDATE/SHARE of subquery is propagated to all of
    2809             :                      * subquery's rels, too.  We could do this later (based on
    2810             :                      * the marking of the subquery RTE) but it is convenient
    2811             :                      * to have local knowledge in each query level about which
    2812             :                      * rels need to be opened with RowShareLock.
    2813             :                      */
    2814           0 :                     transformLockingClause(pstate, rte->subquery,
    2815             :                                            allrels, true);
    2816           0 :                     break;
    2817          28 :                 default:
    2818             :                     /* ignore JOIN, SPECIAL, FUNCTION, VALUES, CTE RTEs */
    2819          28 :                     break;
    2820             :             }
    2821             :         }
    2822             :     }
    2823             :     else
    2824             :     {
    2825             :         /* just the named tables */
    2826        4612 :         foreach(l, lockedRels)
    2827             :         {
    2828        2312 :             RangeVar   *thisrel = (RangeVar *) lfirst(l);
    2829             : 
    2830             :             /* For simplicity we insist on unqualified alias names here */
    2831        2312 :             if (thisrel->catalogname || thisrel->schemaname)
    2832           0 :                 ereport(ERROR,
    2833             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    2834             :                 /*------
    2835             :                   translator: %s is a SQL row locking clause such as FOR UPDATE */
    2836             :                          errmsg("%s must specify unqualified relation names",
    2837             :                                 LCS_asString(lc->strength)),
    2838             :                          parser_errposition(pstate, thisrel->location)));
    2839             : 
    2840        2312 :             i = 0;
    2841        2532 :             foreach(rt, qry->rtable)
    2842             :             {
    2843        2532 :                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
    2844             : 
    2845        2532 :                 ++i;
    2846        2532 :                 if (strcmp(rte->eref->aliasname, thisrel->relname) == 0)
    2847             :                 {
    2848        2312 :                     switch (rte->rtekind)
    2849             :                     {
    2850        2300 :                         case RTE_RELATION:
    2851        2300 :                             applyLockingClause(qry, i, lc->strength,
    2852             :                                                lc->waitPolicy, pushedDown);
    2853        2300 :                             rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
    2854        2300 :                             break;
    2855          12 :                         case RTE_SUBQUERY:
    2856          12 :                             applyLockingClause(qry, i, lc->strength,
    2857             :                                                lc->waitPolicy, pushedDown);
    2858             :                             /* see comment above */
    2859          12 :                             transformLockingClause(pstate, rte->subquery,
    2860             :                                                    allrels, true);
    2861          12 :                             break;
    2862           0 :                         case RTE_JOIN:
    2863           0 :                             ereport(ERROR,
    2864             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2865             :                             /*------
    2866             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2867             :                                      errmsg("%s cannot be applied to a join",
    2868             :                                             LCS_asString(lc->strength)),
    2869             :                                      parser_errposition(pstate, thisrel->location)));
    2870             :                             break;
    2871           0 :                         case RTE_FUNCTION:
    2872           0 :                             ereport(ERROR,
    2873             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2874             :                             /*------
    2875             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2876             :                                      errmsg("%s cannot be applied to a function",
    2877             :                                             LCS_asString(lc->strength)),
    2878             :                                      parser_errposition(pstate, thisrel->location)));
    2879             :                             break;
    2880           0 :                         case RTE_TABLEFUNC:
    2881           0 :                             ereport(ERROR,
    2882             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2883             :                             /*------
    2884             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2885             :                                      errmsg("%s cannot be applied to a table function",
    2886             :                                             LCS_asString(lc->strength)),
    2887             :                                      parser_errposition(pstate, thisrel->location)));
    2888             :                             break;
    2889           0 :                         case RTE_VALUES:
    2890           0 :                             ereport(ERROR,
    2891             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2892             :                             /*------
    2893             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2894             :                                      errmsg("%s cannot be applied to VALUES",
    2895             :                                             LCS_asString(lc->strength)),
    2896             :                                      parser_errposition(pstate, thisrel->location)));
    2897             :                             break;
    2898           0 :                         case RTE_CTE:
    2899           0 :                             ereport(ERROR,
    2900             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2901             :                             /*------
    2902             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2903             :                                      errmsg("%s cannot be applied to a WITH query",
    2904             :                                             LCS_asString(lc->strength)),
    2905             :                                      parser_errposition(pstate, thisrel->location)));
    2906             :                             break;
    2907           0 :                         case RTE_NAMEDTUPLESTORE:
    2908           0 :                             ereport(ERROR,
    2909             :                                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2910             :                             /*------
    2911             :                               translator: %s is a SQL row locking clause such as FOR UPDATE */
    2912             :                                      errmsg("%s cannot be applied to a named tuplestore",
    2913             :                                             LCS_asString(lc->strength)),
    2914             :                                      parser_errposition(pstate, thisrel->location)));
    2915             :                             break;
    2916             : 
    2917             :                             /* Shouldn't be possible to see RTE_RESULT here */
    2918             : 
    2919           0 :                         default:
    2920           0 :                             elog(ERROR, "unrecognized RTE type: %d",
    2921             :                                  (int) rte->rtekind);
    2922             :                             break;
    2923             :                     }
    2924        2312 :                     break;      /* out of foreach loop */
    2925             :                 }
    2926             :             }
    2927        2312 :             if (rt == NULL)
    2928           0 :                 ereport(ERROR,
    2929             :                         (errcode(ERRCODE_UNDEFINED_TABLE),
    2930             :                 /*------
    2931             :                   translator: %s is a SQL row locking clause such as FOR UPDATE */
    2932             :                          errmsg("relation \"%s\" in %s clause not found in FROM clause",
    2933             :                                 thisrel->relname,
    2934             :                                 LCS_asString(lc->strength)),
    2935             :                          parser_errposition(pstate, thisrel->location)));
    2936             :         }
    2937             :     }
    2938        3832 : }
    2939             : 
    2940             : /*
    2941             :  * Record locking info for a single rangetable item
    2942             :  */
    2943             : void
    2944        3940 : applyLockingClause(Query *qry, Index rtindex,
    2945             :                    LockClauseStrength strength, LockWaitPolicy waitPolicy,
    2946             :                    bool pushedDown)
    2947             : {
    2948             :     RowMarkClause *rc;
    2949             : 
    2950             :     Assert(strength != LCS_NONE);   /* else caller error */
    2951             : 
    2952             :     /* If it's an explicit clause, make sure hasForUpdate gets set */
    2953        3940 :     if (!pushedDown)
    2954        3872 :         qry->hasForUpdate = true;
    2955             : 
    2956             :     /* Check for pre-existing entry for same rtindex */
    2957        3940 :     if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
    2958             :     {
    2959             :         /*
    2960             :          * If the same RTE is specified with more than one locking strength,
    2961             :          * use the strongest.  (Reasonable, since you can't take both a shared
    2962             :          * and exclusive lock at the same time; it'll end up being exclusive
    2963             :          * anyway.)
    2964             :          *
    2965             :          * Similarly, if the same RTE is specified with more than one lock
    2966             :          * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in
    2967             :          * turn wins over waiting for the lock (the default).  This is a bit
    2968             :          * more debatable but raising an error doesn't seem helpful. (Consider
    2969             :          * for instance SELECT FOR UPDATE NOWAIT from a view that internally
    2970             :          * contains a plain FOR UPDATE spec.)  Having NOWAIT win over SKIP
    2971             :          * LOCKED is reasonable since the former throws an error in case of
    2972             :          * coming across a locked tuple, which may be undesirable in some
    2973             :          * cases but it seems better than silently returning inconsistent
    2974             :          * results.
    2975             :          *
    2976             :          * And of course pushedDown becomes false if any clause is explicit.
    2977             :          */
    2978           0 :         rc->strength = Max(rc->strength, strength);
    2979           0 :         rc->waitPolicy = Max(rc->waitPolicy, waitPolicy);
    2980           0 :         rc->pushedDown &= pushedDown;
    2981           0 :         return;
    2982             :     }
    2983             : 
    2984             :     /* Make a new RowMarkClause */
    2985        3940 :     rc = makeNode(RowMarkClause);
    2986        3940 :     rc->rti = rtindex;
    2987        3940 :     rc->strength = strength;
    2988        3940 :     rc->waitPolicy = waitPolicy;
    2989        3940 :     rc->pushedDown = pushedDown;
    2990        3940 :     qry->rowMarks = lappend(qry->rowMarks, rc);
    2991             : }
    2992             : 
    2993             : /*
    2994             :  * Coverage testing for raw_expression_tree_walker().
    2995             :  *
    2996             :  * When enabled, we run raw_expression_tree_walker() over every DML statement
    2997             :  * submitted to parse analysis.  Without this provision, that function is only
    2998             :  * applied in limited cases involving CTEs, and we don't really want to have
    2999             :  * to test everything inside as well as outside a CTE.
    3000             :  */
    3001             : #ifdef RAW_EXPRESSION_COVERAGE_TEST
    3002             : 
    3003             : static bool
    3004    26658738 : test_raw_expression_coverage(Node *node, void *context)
    3005             : {
    3006    26658738 :     if (node == NULL)
    3007    13922006 :         return false;
    3008    12736732 :     return raw_expression_tree_walker(node,
    3009             :                                       test_raw_expression_coverage,
    3010             :                                       context);
    3011             : }
    3012             : 
    3013             : #endif                          /* RAW_EXPRESSION_COVERAGE_TEST */

Generated by: LCOV version 1.13