aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_clause.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_clause.c')
-rw-r--r--src/backend/parser/parse_clause.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 4f391d2d411..e268a127d13 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -59,9 +59,12 @@ static Node *transformJoinUsingClause(ParseState *pstate,
List *leftVars, List *rightVars);
static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j,
List *namespace);
+static RangeTblEntry *getRTEForSpecialRelationTypes(ParseState *pstate,
+ RangeVar *rv);
static RangeTblEntry *transformTableEntry(ParseState *pstate, RangeVar *r);
static RangeTblEntry *transformCTEReference(ParseState *pstate, RangeVar *r,
CommonTableExpr *cte, Index levelsup);
+static RangeTblEntry *transformENRReference(ParseState *pstate, RangeVar *r);
static RangeTblEntry *transformRangeSubselect(ParseState *pstate,
RangeSubselect *r);
static RangeTblEntry *transformRangeFunction(ParseState *pstate,
@@ -181,6 +184,14 @@ setTargetTable(ParseState *pstate, RangeVar *relation,
RangeTblEntry *rte;
int rtindex;
+ /* So far special relations are immutable; so they cannot be targets. */
+ rte = getRTEForSpecialRelationTypes(pstate, relation);
+ if (rte != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("relation \"%s\" cannot be the target of a modifying statement",
+ relation->relname)));
+
/* Close old target; this could only happen for multi-action rules */
if (pstate->p_target_relation != NULL)
heap_close(pstate->p_target_relation, NoLock);
@@ -435,6 +446,20 @@ transformCTEReference(ParseState *pstate, RangeVar *r,
}
/*
+ * transformENRReference --- transform a RangeVar that references an ephemeral
+ * named relation
+ */
+static RangeTblEntry *
+transformENRReference(ParseState *pstate, RangeVar *r)
+{
+ RangeTblEntry *rte;
+
+ rte = addRangeTableEntryForENR(pstate, r, true);
+
+ return rte;
+}
+
+/*
* transformRangeSubselect --- transform a sub-SELECT appearing in FROM
*/
static RangeTblEntry *
@@ -1021,6 +1046,24 @@ transformRangeTableSample(ParseState *pstate, RangeTableSample *rts)
return tablesample;
}
+
+static RangeTblEntry *
+getRTEForSpecialRelationTypes(ParseState *pstate, RangeVar *rv)
+{
+
+ CommonTableExpr *cte;
+ Index levelsup;
+ RangeTblEntry *rte = NULL;
+
+ cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup);
+ if (cte)
+ rte = transformCTEReference(pstate, rv, cte, levelsup);
+ if (!rte && scanNameSpaceForENR(pstate, rv->relname))
+ rte = transformENRReference(pstate, rv);
+
+ return rte;
+}
+
/*
* transformFromClauseItem -
* Transform a FROM-clause item, adding any required entries to the
@@ -1055,18 +1098,14 @@ transformFromClauseItem(ParseState *pstate, Node *n,
RangeTblEntry *rte = NULL;
int rtindex;
- /* if it is an unqualified name, it might be a CTE reference */
+ /*
+ * if it is an unqualified name, it might be a CTE or tuplestore
+ * reference
+ */
if (!rv->schemaname)
- {
- CommonTableExpr *cte;
- Index levelsup;
-
- cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup);
- if (cte)
- rte = transformCTEReference(pstate, rv, cte, levelsup);
- }
+ rte = getRTEForSpecialRelationTypes(pstate, rv);
- /* if not found as a CTE, must be a table reference */
+ /* if not found above, must be a table reference */
if (!rte)
rte = transformTableEntry(pstate, rv);