diff options
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r-- | src/backend/parser/analyze.c | 72 |
1 files changed, 14 insertions, 58 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 263edb5a7a6..1a112cd9a4e 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -533,6 +533,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) rte = addRangeTableEntryForSubquery(pstate, selectQuery, makeAlias("*SELECT*", NIL), + false, false); rtr = makeNode(RangeTblRef); /* assume new rte is at end */ @@ -652,18 +653,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) collations = lappend_oid(collations, InvalidOid); /* - * There mustn't have been any table references in the expressions, - * else strange things would happen, like Cartesian products of those - * tables with the VALUES list ... - */ - if (pstate->p_joinlist != NIL) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("VALUES must not contain table references"), - parser_errposition(pstate, - locate_var_of_level((Node *) exprsLists, 0)))); - - /* * Another thing we can't currently support is NEW/OLD references in * rules --- seems we'd need something like SQL99's LATERAL construct * to ensure that the values would be available while evaluating the @@ -1067,7 +1056,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) List **colexprs = NULL; int sublist_length = -1; RangeTblEntry *rte; - RangeTblRef *rtr; + int rtindex; ListCell *lc; ListCell *lc2; int i; @@ -1215,19 +1204,17 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) */ rte = addRangeTableEntryForValues(pstate, exprsLists, collations, NULL, true); - rtr = makeNode(RangeTblRef); + addRTEtoQuery(pstate, rte, true, true, true); + /* assume new rte is at end */ - rtr->rtindex = list_length(pstate->p_rtable); - Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable)); - pstate->p_joinlist = lappend(pstate->p_joinlist, rtr); - pstate->p_relnamespace = lappend(pstate->p_relnamespace, rte); - pstate->p_varnamespace = lappend(pstate->p_varnamespace, rte); + rtindex = list_length(pstate->p_rtable); + Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); /* * Generate a targetlist as though expanding "*" */ Assert(pstate->p_next_resno == 1); - qry->targetList = expandRelAttrs(pstate, rte, rtr->rtindex, 0, -1); + qry->targetList = expandRelAttrs(pstate, rte, rtindex, 0, -1); /* * The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a @@ -1250,19 +1237,6 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES"))); /* - * There mustn't have been any table references in the expressions, else - * strange things would happen, like Cartesian products of those tables - * with the VALUES list. We have to check this after parsing ORDER BY et - * al since those could insert more junk. - */ - if (list_length(pstate->p_joinlist) != 1) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("VALUES must not contain table references"), - parser_errposition(pstate, - locate_var_of_level((Node *) exprsLists, 0)))); - - /* * Another thing we can't currently support is NEW/OLD references in rules * --- seems we'd need something like SQL99's LATERAL construct to ensure * that the values would be available while evaluating the VALUES RTE. @@ -1477,10 +1451,12 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) false); sv_relnamespace = pstate->p_relnamespace; - pstate->p_relnamespace = NIL; /* no qualified names allowed */ - sv_varnamespace = pstate->p_varnamespace; - pstate->p_varnamespace = list_make1(jrte); + pstate->p_relnamespace = NIL; + pstate->p_varnamespace = NIL; + + /* add jrte to varnamespace only */ + addRTEtoQuery(pstate, jrte, false, false, true); /* * For now, we don't support resjunk sort clauses on the output of a @@ -1577,7 +1553,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, /* * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE, * or WITH clauses attached, we need to treat it like a leaf node to - * generate an independent sub-Query tree. Otherwise, it can be + * generate an independent sub-Query tree. Otherwise, it can be * represented by a SetOperationStmt node underneath the parent Query. */ if (stmt->op == SETOP_NONE) @@ -1652,6 +1628,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, rte = addRangeTableEntryForSubquery(pstate, selectQuery, makeAlias(selectName, NIL), + false, false); /* @@ -2074,7 +2051,6 @@ transformReturningList(ParseState *pstate, List *returningList) int save_next_resno; bool save_hasAggs; bool save_hasWindowFuncs; - int length_rtable; if (returningList == NIL) return NIL; /* nothing to do */ @@ -2092,7 +2068,6 @@ transformReturningList(ParseState *pstate, List *returningList) pstate->p_hasAggs = false; save_hasWindowFuncs = pstate->p_hasWindowFuncs; pstate->p_hasWindowFuncs = false; - length_rtable = list_length(pstate->p_rtable); /* transform RETURNING identically to a SELECT targetlist */ rlist = transformTargetList(pstate, returningList); @@ -2113,25 +2088,6 @@ transformReturningList(ParseState *pstate, List *returningList) parser_errposition(pstate, locate_windowfunc((Node *) rlist)))); - /* no new relation references please */ - if (list_length(pstate->p_rtable) != length_rtable) - { - int vlocation = -1; - int relid; - - /* try to locate such a reference to point to */ - for (relid = length_rtable + 1; relid <= list_length(pstate->p_rtable); relid++) - { - vlocation = locate_var_of_relation((Node *) rlist, relid, 0); - if (vlocation >= 0) - break; - } - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("RETURNING cannot contain references to other relations"), - parser_errposition(pstate, vlocation))); - } - /* mark column origins */ markTargetListOrigins(pstate, rlist); |