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

Generated by: LCOV version 1.11