RLS fails to work with UPDATE ... WHERE CURRENT OF
Attached test case patch shows how RLS fails to play nice with UPDATE
... WHERE CURRENT OF. If you run the revised rowsecurity regression
test against the master branch, the tests do not pass (which, ideally,
they would -- "expected" is actually what I expect here):
*** /home/pg/postgresql/src/test/regress/expected/rowsecurity.out
2015-06-06 15:04:02.142084059 -0700
--- /home/pg/postgresql/src/test/regress/results/rowsecurity.out
2015-06-06 15:04:09.014083800 -0700
***************
*** 2771,2780 ****
-- Still cannot UPDATE row through cursor:
UPDATE current_check SET payload = payload || '_new' WHERE CURRENT
OF current_check_cursor RETURNING *;
! currentid | payload | rlsuser
! -----------+---------+---------
! (0 rows)
! commit;
--
-- Clean up objects
--
--- 2771,2778 ----
-- Still cannot UPDATE row through cursor:
UPDATE current_check SET payload = payload || '_new' WHERE CURRENT
OF current_check_cursor RETURNING *;
! ERROR: WHERE CURRENT OF is not supported for this table type
! COMMIT;
--
-- Clean up objects
--
======================================================================
What's actually occurring here is that the executor imagines that this
involves a foreign table scan (although I suppose it's equivocating a
little bit by not saying so explicitly) -- ExecEvalCurrentOfExpr()
comments imply that that's the only reason why control should reach it
in practice. It looks like RLS has added a new way that CURRENT OF can
fail to be made into a TidScan qualification. It doesn't look like
Dean's most recent round of RLS fixes [1]/messages/by-id/CAEZATCVE7hdtfZGCJN-oevVaWBtBGG8-fBCh9VhDBHuZrsWY5w@mail.gmail.com -- Peter Geoghegan addressed this case, based
on his remarks. This non-support of WHERE CURRENT OF certainly isn't
documented, and so looks like a bug.
Unfortunately, the fact that WHERE CURRENT OF doesn't already accept
additional qualifications doesn't leave me optimistic about this bug
being easy to fix -- consider the gymnastics performed by commit
c29a9c37 to get an idea of what I mean. Maybe it should just be
formally desupported with RLS, as a stopgap solution for 9.5.
[1]: /messages/by-id/CAEZATCVE7hdtfZGCJN-oevVaWBtBGG8-fBCh9VhDBHuZrsWY5w@mail.gmail.com -- Peter Geoghegan
--
Peter Geoghegan
Attachments:
rls-where-current-of.patchtext/x-patch; charset=US-ASCII; name=rls-where-current-of.patchDownload
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 0ae5557..1c4c551 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -2729,6 +2729,52 @@ COPY copy_t FROM STDIN; --fail - permission denied.
ERROR: permission denied for relation copy_t
RESET SESSION AUTHORIZATION;
DROP TABLE copy_t;
+-- Check WHERE CURRENT OF
+SET SESSION AUTHORIZATION rls_regress_user0;
+CREATE TABLE current_check (currentid int, payload text, rlsuser text);
+GRANT ALL ON current_check TO PUBLIC;
+INSERT INTO current_check VALUES
+ (1, 'abc', 'rls_regress_user1'),
+ (2, 'bcd', 'rls_regress_user1'),
+ (3, 'cde', 'rls_regress_user1'),
+ (4, 'def', 'rls_regress_user1'),
+ (5, 'efg', 'rls_regress_user1'),
+ (6, 'fgh', 'rls_regress_user1'),
+ (7, 'fgh', 'rls_regress_user1'),
+ (8, 'fgh', 'rls_regress_user1');
+CREATE POLICY p1 ON current_check FOR SELECT USING (currentid % 2 = 0);
+CREATE POLICY p3 ON current_check FOR UPDATE USING (currentid = 4) WITH CHECK (rlsuser = current_user);
+ALTER TABLE current_check ENABLE ROW LEVEL SECURITY;
+SET SESSION AUTHORIZATION rls_regress_user1;
+-- Can SELECT this row just fine:
+SELECT * FROM current_check WHERE currentid = 2;
+ currentid | payload | rlsuser
+-----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+(1 row)
+
+-- Cannot UPDATE it, though:
+UPDATE current_check SET payload = payload || '_new' WHERE currentid = 2 RETURNING *;
+ currentid | payload | rlsuser
+-----------+---------+---------
+(0 rows)
+
+BEGIN;
+DECLARE current_check_cursor SCROLL CURSOR FOR SELECT * FROM current_check;
+-- Returns rows that can be seen according to SELECT policy, like plain SELECT
+-- above:
+FETCH ABSOLUTE 1 FROM current_check_cursor;
+ currentid | payload | rlsuser
+-----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+(1 row)
+
+-- Still cannot UPDATE row through cursor:
+UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+ currentid | payload | rlsuser
+-----------+---------+---------
+(0 rows)
+COMMIT;
--
-- Clean up objects
--
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index fdadf99..aeed5b1 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -1087,6 +1087,46 @@ COPY copy_t FROM STDIN; --fail - permission denied.
RESET SESSION AUTHORIZATION;
DROP TABLE copy_t;
+-- Check WHERE CURRENT OF
+SET SESSION AUTHORIZATION rls_regress_user0;
+
+CREATE TABLE current_check (currentid int, payload text, rlsuser text);
+GRANT ALL ON current_check TO PUBLIC;
+
+INSERT INTO current_check VALUES
+ (1, 'abc', 'rls_regress_user1'),
+ (2, 'bcd', 'rls_regress_user1'),
+ (3, 'cde', 'rls_regress_user1'),
+ (4, 'def', 'rls_regress_user1'),
+ (5, 'efg', 'rls_regress_user1'),
+ (6, 'fgh', 'rls_regress_user1'),
+ (7, 'fgh', 'rls_regress_user1'),
+ (8, 'fgh', 'rls_regress_user1');
+
+CREATE POLICY p1 ON current_check FOR SELECT USING (currentid % 2 = 0);
+CREATE POLICY p3 ON current_check FOR UPDATE USING (currentid = 4) WITH CHECK (rlsuser = current_user);
+
+ALTER TABLE current_check ENABLE ROW LEVEL SECURITY;
+
+SET SESSION AUTHORIZATION rls_regress_user1;
+
+-- Can SELECT this row just fine:
+SELECT * FROM current_check WHERE currentid = 2;
+
+-- Cannot UPDATE it, though:
+UPDATE current_check SET payload = payload || '_new' WHERE currentid = 2 RETURNING *;
+
+BEGIN;
+
+DECLARE current_check_cursor SCROLL CURSOR FOR SELECT * FROM current_check;
+-- Returns rows that can be seen according to SELECT policy, like plain SELECT
+-- above:
+FETCH ABSOLUTE 1 FROM current_check_cursor;
+-- Still cannot UPDATE row through cursor:
+UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+
+COMMIT;
+
--
-- Clean up objects
--
On 6 June 2015 at 23:28, Peter Geoghegan <pg@heroku.com> wrote:
Attached test case patch shows how RLS fails to play nice with UPDATE
... WHERE CURRENT OF.
[snip]
What's actually occurring here is that the executor imagines that this
involves a foreign table scan (although I suppose it's equivocating a
little bit by not saying so explicitly) -- ExecEvalCurrentOfExpr()
comments imply that that's the only reason why control should reach it
in practice. It looks like RLS has added a new way that CURRENT OF can
fail to be made into a TidScan qualification. It doesn't look like
Dean's most recent round of RLS fixes [1] addressed this case, based
on his remarks. This non-support of WHERE CURRENT OF certainly isn't
documented, and so looks like a bug.
Well spotted. I agree that this is a bug. We could just say that WHERE
CURRENT OF isn't supported on a table with RLS, but I think that would
be overly limiting.
Unfortunately, the fact that WHERE CURRENT OF doesn't already accept
additional qualifications doesn't leave me optimistic about this bug
being easy to fix -- consider the gymnastics performed by commit
c29a9c37 to get an idea of what I mean. Maybe it should just be
formally desupported with RLS, as a stopgap solution for 9.5.[1] /messages/by-id/CAEZATCVE7hdtfZGCJN-oevVaWBtBGG8-fBCh9VhDBHuZrsWY5w@mail.gmail.com
Actually I think it is fixable just by allowing the CURRENT OF
expression to be pushed down into the subquery through the security
barrier view. The planner is then guaranteed to generate a TID scan,
filtering by any other RLS quals, which ought to be the optimal plan.
Patch attached.
Regards,
Dean
Attachments:
rls-where-current-of.patchtext/x-patch; charset=US-ASCII; name=rls-where-current-of.patchDownload
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
new file mode 100644
index 0b83189..888eeac
*** a/src/backend/optimizer/path/allpaths.c
--- b/src/backend/optimizer/path/allpaths.c
*************** subquery_push_qual(Query *subquery, Rang
*** 2177,2182 ****
--- 2177,2222 ----
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
{
/*
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
new file mode 100644
index d40083d..0137e0e
*** a/src/backend/optimizer/util/clauses.c
--- b/src/backend/optimizer/util/clauses.c
*************** contain_leaked_vars_walker(Node *node, v
*** 1492,1497 ****
--- 1492,1507 ----
}
break;
+ case T_CurrentOfExpr:
+
+ /*
+ * WHERE CURRENT OF doesn't contain function calls. Moreover, it
+ * is important that this can be pushed down into a
+ * security_barrier view, since the planner must always generate
+ * a TID scan when CURRENT OF is present -- c.f. cost_tidscan.
+ */
+ return false;
+
default:
/*
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
new file mode 100644
index 0ae5557..7c25349
*** a/src/test/regress/expected/rowsecurity.out
--- b/src/test/regress/expected/rowsecurity.out
*************** COPY copy_t FROM STDIN; --fail - permiss
*** 2729,2734 ****
--- 2729,2841 ----
ERROR: permission denied for relation copy_t
RESET SESSION AUTHORIZATION;
DROP TABLE copy_t;
+ -- Check WHERE CURRENT OF
+ SET SESSION AUTHORIZATION rls_regress_user0;
+ CREATE TABLE current_check (currentid int, payload text, rlsuser text);
+ GRANT ALL ON current_check TO PUBLIC;
+ INSERT INTO current_check VALUES
+ (1, 'abc', 'rls_regress_user1'),
+ (2, 'bcd', 'rls_regress_user1'),
+ (3, 'cde', 'rls_regress_user1'),
+ (4, 'def', 'rls_regress_user1');
+ CREATE POLICY p1 ON current_check FOR SELECT USING (currentid % 2 = 0);
+ CREATE POLICY p2 ON current_check FOR DELETE USING (currentid = 4 AND rlsuser = current_user);
+ CREATE POLICY p3 ON current_check FOR UPDATE USING (currentid = 4) WITH CHECK (rlsuser = current_user);
+ ALTER TABLE current_check ENABLE ROW LEVEL SECURITY;
+ SET SESSION AUTHORIZATION rls_regress_user1;
+ -- Can SELECT even rows
+ SELECT * FROM current_check;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+ 4 | def | rls_regress_user1
+ (2 rows)
+
+ -- Cannot UPDATE row 2
+ UPDATE current_check SET payload = payload || '_new' WHERE currentid = 2 RETURNING *;
+ currentid | payload | rlsuser
+ -----------+---------+---------
+ (0 rows)
+
+ BEGIN;
+ DECLARE current_check_cursor SCROLL CURSOR FOR SELECT * FROM current_check;
+ -- Returns rows that can be seen according to SELECT policy, like plain SELECT
+ -- above (even rows)
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+ (1 row)
+
+ -- Still cannot UPDATE row 2 through cursor
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+ currentid | payload | rlsuser
+ -----------+---------+---------
+ (0 rows)
+
+ -- Can update row 4 through cursor, which is the next visible row
+ FETCH RELATIVE 1 FROM current_check_cursor;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 4 | def | rls_regress_user1
+ (1 row)
+
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 4 | def_new | rls_regress_user1
+ (1 row)
+
+ SELECT * FROM current_check;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+ 4 | def_new | rls_regress_user1
+ (2 rows)
+
+ -- Plan should be a subquery TID scan
+ EXPLAIN (COSTS OFF) UPDATE current_check SET payload = payload WHERE CURRENT OF current_check_cursor;
+ QUERY PLAN
+ ---------------------------------------------------------------
+ Update on current_check current_check_1
+ -> Subquery Scan on current_check
+ -> LockRows
+ -> Tid Scan on current_check current_check_2
+ TID Cond: CURRENT OF current_check_cursor
+ Filter: (currentid = 4)
+ (6 rows)
+
+ -- Similarly can only delete row 4
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+ (1 row)
+
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
+ currentid | payload | rlsuser
+ -----------+---------+---------
+ (0 rows)
+
+ FETCH RELATIVE 1 FROM current_check_cursor;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 4 | def | rls_regress_user1
+ (1 row)
+
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 4 | def_new | rls_regress_user1
+ (1 row)
+
+ SELECT * FROM current_check;
+ currentid | payload | rlsuser
+ -----------+---------+-------------------
+ 2 | bcd | rls_regress_user1
+ (1 row)
+
+ COMMIT;
--
-- Clean up objects
--
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
new file mode 100644
index fdadf99..e8d783c
*** a/src/test/regress/sql/rowsecurity.sql
--- b/src/test/regress/sql/rowsecurity.sql
*************** COPY copy_t FROM STDIN; --fail - permiss
*** 1087,1092 ****
--- 1087,1141 ----
RESET SESSION AUTHORIZATION;
DROP TABLE copy_t;
+ -- Check WHERE CURRENT OF
+ SET SESSION AUTHORIZATION rls_regress_user0;
+
+ CREATE TABLE current_check (currentid int, payload text, rlsuser text);
+ GRANT ALL ON current_check TO PUBLIC;
+
+ INSERT INTO current_check VALUES
+ (1, 'abc', 'rls_regress_user1'),
+ (2, 'bcd', 'rls_regress_user1'),
+ (3, 'cde', 'rls_regress_user1'),
+ (4, 'def', 'rls_regress_user1');
+
+ CREATE POLICY p1 ON current_check FOR SELECT USING (currentid % 2 = 0);
+ CREATE POLICY p2 ON current_check FOR DELETE USING (currentid = 4 AND rlsuser = current_user);
+ CREATE POLICY p3 ON current_check FOR UPDATE USING (currentid = 4) WITH CHECK (rlsuser = current_user);
+
+ ALTER TABLE current_check ENABLE ROW LEVEL SECURITY;
+
+ SET SESSION AUTHORIZATION rls_regress_user1;
+
+ -- Can SELECT even rows
+ SELECT * FROM current_check;
+
+ -- Cannot UPDATE row 2
+ UPDATE current_check SET payload = payload || '_new' WHERE currentid = 2 RETURNING *;
+
+ BEGIN;
+
+ DECLARE current_check_cursor SCROLL CURSOR FOR SELECT * FROM current_check;
+ -- Returns rows that can be seen according to SELECT policy, like plain SELECT
+ -- above (even rows)
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
+ -- Still cannot UPDATE row 2 through cursor
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+ -- Can update row 4 through cursor, which is the next visible row
+ FETCH RELATIVE 1 FROM current_check_cursor;
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
+ SELECT * FROM current_check;
+ -- Plan should be a subquery TID scan
+ EXPLAIN (COSTS OFF) UPDATE current_check SET payload = payload WHERE CURRENT OF current_check_cursor;
+ -- Similarly can only delete row 4
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
+ FETCH RELATIVE 1 FROM current_check_cursor;
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
+ SELECT * FROM current_check;
+
+ COMMIT;
+
--
-- Clean up objects
--
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 06/08/2015 02:08 AM, Dean Rasheed wrote:
Actually I think it is fixable just by allowing the CURRENT OF
expression to be pushed down into the subquery through the
security barrier view. The planner is then guaranteed to generate a
TID scan, filtering by any other RLS quals, which ought to be the
optimal plan. Patch attached.
This looks good to me. I have tested and don't find any issues with
it. Will commit in a day or so unless someone has objections.
Joe
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAEBAgAGBQJVnuwOAAoJEDfy90M199hlQY0QAIchkbm8cc1BTnZnoZ0vgoid
hzEENu1c8AjQSWxovEpW27C41koKBP47dVNTxq3orBr4lJU2Rh0MdEyw2mrUKpzs
rLUwgkoI0x7vzcLUv4ZclmkiY1+oOVxAocZBRwVFcMk0SgAinI6EJe9J5fAl0hOe
CQU9wQWptnvtkyZKyqELWtnzT3Y4Dk7Rk4MAtFpoGfamS4J5PVHBGGHIb7VfyVJ5
NMytTN4Wl/AVdFNIjoXrcQSOFV8gTs17KUwlCSFfFLnSDPlQpTICbIkTSR/APQFK
M0Xn/Frp3hVzrpU0poaElbz7TisjfijmVRUmLv6ZCHDPwVgLLtrL0PJlT2IKLzRf
qBUK2EHEZTXvfdWW4l2aSxY8v8gf7++aiIZYAT01uJsj2JIic4G4dI2KGZ1PQ/BI
EKo2QaBlI1KYeECAG7Ingg+SyB+E3Hf7LUAxSjbkX3O97GYkg1amrd8XtvxKk9v2
gtgerBAyGkWBbx9H8DqoMnhgzqhkAOHYHdCJpf2dSDVyP+Xp94CBhOBwgt9NryJq
083ydo/7jGXdjjWS33U1wTPOa78YlDL44c5UXQ07z3LzDQHvl1JUfTm9QxZPOaKX
ny5tJCafkCSjQfbrrykQ+lmFFM6JmIVOzZKktlfClk14ayQVe+YXsGetXNZmJARQ
xOn9wTAhK7DjBD7Mkb6R
=G/mB
-----END PGP SIGNATURE-----
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Jul 9, 2015 at 5:47 PM, Joe Conway <mail@joeconway.com> wrote:
On 06/08/2015 02:08 AM, Dean Rasheed wrote:
Actually I think it is fixable just by allowing the CURRENT OF
expression to be pushed down into the subquery through the
security barrier view. The planner is then guaranteed to generate a
TID scan, filtering by any other RLS quals, which ought to be the
optimal plan. Patch attached.This looks good to me. I have tested and don't find any issues with
it. Will commit in a day or so unless someone has objections.
Is this fix needed in all versions that support security barrier
views, or just in 9.5 and 9.6 that have RLS specifically?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 14 July 2015 at 13:59, Robert Haas <robertmhaas@gmail.com> wrote:
On Thu, Jul 9, 2015 at 5:47 PM, Joe Conway <mail@joeconway.com> wrote:
On 06/08/2015 02:08 AM, Dean Rasheed wrote:
Actually I think it is fixable just by allowing the CURRENT OF
expression to be pushed down into the subquery through the
security barrier view. The planner is then guaranteed to generate a
TID scan, filtering by any other RLS quals, which ought to be the
optimal plan. Patch attached.This looks good to me. I have tested and don't find any issues with
it. Will commit in a day or so unless someone has objections.Is this fix needed in all versions that support security barrier
views, or just in 9.5 and 9.6 that have RLS specifically?
It's only needed in 9.5 and later for tables with RLS, because WHERE
CURRENT OF isn't supported on views.
Regards,
Dean
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 07/14/2015 12:40 PM, Dean Rasheed wrote:
On 14 July 2015 at 13:59, Robert Haas <robertmhaas@gmail.com>
wrote:On Thu, Jul 9, 2015 at 5:47 PM, Joe Conway <mail@joeconway.com>
wrote:On 06/08/2015 02:08 AM, Dean Rasheed wrote:
Actually I think it is fixable just by allowing the CURRENT
OF expression to be pushed down into the subquery through
the security barrier view. The planner is then guaranteed to
generate a TID scan, filtering by any other RLS quals, which
ought to be the optimal plan. Patch attached.This looks good to me. I have tested and don't find any issues
with it. Will commit in a day or so unless someone has
objections.Is this fix needed in all versions that support security barrier
views, or just in 9.5 and 9.6 that have RLS specifically?It's only needed in 9.5 and later for tables with RLS, because
WHERE CURRENT OF isn't supported on views.
Pushed.
- --
Joe Conway
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAEBAgAGBQJVspjUAAoJEDfy90M199hlJ3kP/i87ZlFmIOwApwm1y/OPOM/r
iW4BvUXadkbBnRG0ReoW9PPHXQHFbytunnL3I5Ddnnwa3KHFmzc7LBUpwRQRG5JO
bclB+Z/0AHYgdkKh/dvfngp2QddPk5bRZ2PuEYgMNBOFBWtANzOCdDVsKKouPnoq
0+H9o0LVWtInse8mL0J321Xl34XH0DKdeJSgG8Tq2Te7YCDkISLFQMv4jaOctktt
cfs1AYF1gG6ZoWjNDhupXejCIVR22VzONtjX3JxNWht3vhcN5bRBhU9KPZobfdaw
9cGbgIGHqZdb5ZZDILWbgiKvif/4krEDcnKLXHlsdnW4wO2oS7399d1Atjf7KJNX
unTX3yskYNcocGxIn76cGc76xWHoMj88AFxTlQ0zU3cUInZAQyFEK//4UiQ0Wzad
iAvTO4SwjyOY3/ipNlxKP0gwH27EA83mVZLiZ/qfo3GExD/NfI2rT2iGn7Dx9syX
frGFyYAm8cSWqVK+EzideL6yZL5fWoDpCC3GZnSHJEpriO/jnbqC0EmFxftP2N7N
1HSX8bjOExvLLtARry5SV6ngtu1gJABqRD38TjzExg/WMn+3S2NnYZHE3YGWpowz
CdSqLnVoGzHCNcj74eEV8XseX0JRVY3jHlv0iEme0MGmtkA1AdMesaUBjy9A9MGh
y2ZONUQCpBj/3lPj+wtb
=odS2
-----END PGP SIGNATURE-----
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers