aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 37ca331c215..a8aee204c74 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1868,6 +1868,35 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
}
/*
+ * OLD/NEW are not allowed in WITH queries, because they would
+ * amount to outer references for the WITH, which we disallow.
+ * However, they were already in the outer rangetable when we
+ * analyzed the query, so we have to check.
+ *
+ * Note that in the INSERT...SELECT case, we need to examine
+ * the CTE lists of both top_subqry and sub_qry.
+ *
+ * Note that we aren't digging into the body of the query
+ * looking for WITHs in nested sub-SELECTs. A WITH down there
+ * can legitimately refer to OLD/NEW, because it'd be an
+ * indirect-correlated outer reference.
+ */
+ if (rangeTableEntry_used((Node *) top_subqry->cteList,
+ PRS2_OLD_VARNO, 0) ||
+ rangeTableEntry_used((Node *) sub_qry->cteList,
+ PRS2_OLD_VARNO, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot refer to OLD within WITH query")));
+ if (rangeTableEntry_used((Node *) top_subqry->cteList,
+ PRS2_NEW_VARNO, 0) ||
+ rangeTableEntry_used((Node *) sub_qry->cteList,
+ PRS2_NEW_VARNO, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot refer to NEW within WITH query")));
+
+ /*
* For efficiency's sake, add OLD to the rule action's jointree
* only if it was actually referenced in the statement or qual.
*