aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/analyze.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r--src/backend/parser/analyze.c72
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);