Skip to content

Commit 792213f

Browse files
committed
Correctly update hasSubLinks while mutating a rule action.
rewriteRuleAction neglected to check for SubLink nodes in the securityQuals of range table entries. This could lead to failing to convert such a SubLink to a SubPlan, resulting in assertion crashes or weird errors later in planning. In passing, fix some poor coding in rewriteTargetView: we should not pass the source parsetree's hasSubLinks field to ReplaceVarsFromTargetList's outer_hasSubLinks. ReplaceVarsFromTargetList knows enough to ignore that when a Query node is passed, but it's still confusing and bad precedent: if we did try to update that flag we'd be updating a stale copy of the parsetree. Per bug #17972 from Alexander Lakhin. This has been broken since we added RangeTblEntry.securityQuals (although the presented test case only fails back to 215b43c), so back-patch all the way. Discussion: https://postgr.es/m/17972-f422c094237847d0@postgresql.org
1 parent b93c63d commit 792213f

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

src/backend/rewrite/rewriteHandler.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ rewriteRuleAction(Query *parsetree,
484484
/* other RTE types don't contain bare expressions */
485485
break;
486486
}
487+
sub_action->hasSubLinks |=
488+
checkExprHasSubLink((Node *) rte->securityQuals);
487489
if (sub_action->hasSubLinks)
488490
break; /* no need to keep scanning rtable */
489491
}
@@ -3341,7 +3343,7 @@ rewriteTargetView(Query *parsetree, Relation view)
33413343
view_targetlist,
33423344
REPLACEVARS_REPORT_ERROR,
33433345
0,
3344-
&parsetree->hasSubLinks);
3346+
NULL);
33453347

33463348
/*
33473349
* Update all other RTI references in the query that point to the view

src/test/regress/expected/updatable_views.out

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,6 +2838,38 @@ DROP VIEW v1;
28382838
DROP TABLE t2;
28392839
DROP TABLE t1;
28402840
--
2841+
-- Test sub-select in nested security barrier views, per bug #17972
2842+
--
2843+
CREATE TABLE t1 (a int);
2844+
CREATE VIEW v1 WITH (security_barrier = true) AS
2845+
SELECT * FROM t1;
2846+
CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD
2847+
UPDATE t1 SET a = NEW.a WHERE a = OLD.a;
2848+
CREATE VIEW v2 WITH (security_barrier = true) AS
2849+
SELECT * FROM v1 WHERE EXISTS (SELECT 1);
2850+
EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1;
2851+
QUERY PLAN
2852+
---------------------------------------------------
2853+
Update on t1
2854+
InitPlan 1 (returns $0)
2855+
-> Result
2856+
-> Merge Join
2857+
Merge Cond: (t1.a = v1.a)
2858+
-> Sort
2859+
Sort Key: t1.a
2860+
-> Seq Scan on t1
2861+
-> Sort
2862+
Sort Key: v1.a
2863+
-> Subquery Scan on v1
2864+
-> Result
2865+
One-Time Filter: $0
2866+
-> Seq Scan on t1 t1_1
2867+
(14 rows)
2868+
2869+
DROP VIEW v2;
2870+
DROP VIEW v1;
2871+
DROP TABLE t1;
2872+
--
28412873
-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an
28422874
-- auto-updatable view and adding check options in a single step
28432875
--

src/test/regress/sql/updatable_views.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,23 @@ DROP VIEW v1;
14231423
DROP TABLE t2;
14241424
DROP TABLE t1;
14251425

1426+
--
1427+
-- Test sub-select in nested security barrier views, per bug #17972
1428+
--
1429+
CREATE TABLE t1 (a int);
1430+
CREATE VIEW v1 WITH (security_barrier = true) AS
1431+
SELECT * FROM t1;
1432+
CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD
1433+
UPDATE t1 SET a = NEW.a WHERE a = OLD.a;
1434+
CREATE VIEW v2 WITH (security_barrier = true) AS
1435+
SELECT * FROM v1 WHERE EXISTS (SELECT 1);
1436+
1437+
EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1;
1438+
1439+
DROP VIEW v2;
1440+
DROP VIEW v1;
1441+
DROP TABLE t1;
1442+
14261443
--
14271444
-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an
14281445
-- auto-updatable view and adding check options in a single step

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy