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

Generated by: LCOV version 1.13