aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/allpaths.c
diff options
context:
space:
mode:
authorJoe Conway <mail@joeconway.com>2015-07-24 12:55:30 -0700
committerJoe Conway <mail@joeconway.com>2015-07-24 12:55:30 -0700
commitb26e3d660df51a088d14c3c2cfce5990c13c1195 (patch)
tree8bea46a185f0ce157f051445ec9fb57e7ea74d6d /src/backend/optimizer/path/allpaths.c
parentd9a356ff2e6bb7ed5fb1145af49fa3e51e68a98a (diff)
downloadpostgresql-b26e3d660df51a088d14c3c2cfce5990c13c1195.tar.gz
postgresql-b26e3d660df51a088d14c3c2cfce5990c13c1195.zip
Make RLS work with UPDATE ... WHERE CURRENT OF
UPDATE ... WHERE CURRENT OF would not work in conjunction with RLS. Arrange to allow the CURRENT OF expression to be pushed down. Issue noted by Peter Geoghegan. Patch by Dean Rasheed. Back patch to 9.5 where RLS was introduced.
Diffstat (limited to 'src/backend/optimizer/path/allpaths.c')
-rw-r--r--src/backend/optimizer/path/allpaths.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 0b831891fcb..888eeac5151 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2177,6 +2177,46 @@ subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual)
recurse_push_qual(subquery->setOperations, subquery,
rte, rti, qual);
}
+ else if (IsA(qual, CurrentOfExpr))
+ {
+ /*
+ * This is possible when a WHERE CURRENT OF expression is applied to a
+ * table with row-level security. In that case, the subquery should
+ * contain precisely one rtable entry for the table, and we can safely
+ * push the expression down into the subquery. This will cause a TID
+ * scan subquery plan to be generated allowing the target relation to
+ * be updated.
+ *
+ * Someday we might also be able to use a WHERE CURRENT OF expression
+ * on a view, but currently the rewriter prevents that, so we should
+ * never see any other case here, but generate sane error messages in
+ * case it does somehow happen.
+ */
+ if (subquery->rtable == NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("WHERE CURRENT OF is not supported on a view with no underlying relation")));
+
+ if (list_length(subquery->rtable) > 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("WHERE CURRENT OF is not supported on a view with more than one underlying relation")));
+
+ if (subquery->hasAggs || subquery->groupClause || subquery->groupingSets || subquery->havingQual)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("WHERE CURRENT OF is not supported on a view with grouping or aggregation")));
+
+ /*
+ * Adjust the CURRENT OF expression to refer to the underlying table
+ * in the subquery, and attach it to the subquery's WHERE clause.
+ */
+ qual = copyObject(qual);
+ ((CurrentOfExpr *) qual)->cvarno = 1;
+
+ subquery->jointree->quals =
+ make_and_qual(subquery->jointree->quals, qual);
+ }
else
{
/*