diff options
author | Joe Conway <mail@joeconway.com> | 2015-07-24 12:55:30 -0700 |
---|---|---|
committer | Joe Conway <mail@joeconway.com> | 2015-07-24 12:55:30 -0700 |
commit | b26e3d660df51a088d14c3c2cfce5990c13c1195 (patch) | |
tree | 8bea46a185f0ce157f051445ec9fb57e7ea74d6d /src/backend/optimizer/path/allpaths.c | |
parent | d9a356ff2e6bb7ed5fb1145af49fa3e51e68a98a (diff) | |
download | postgresql-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.c | 40 |
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 { /* |