Skip to content

Commit d1423c5

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 5eaa05f commit d1423c5

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
@@ -477,6 +477,8 @@ rewriteRuleAction(Query *parsetree,
477477
/* other RTE types don't contain bare expressions */
478478
break;
479479
}
480+
sub_action->hasSubLinks |=
481+
checkExprHasSubLink((Node *) rte->securityQuals);
480482
if (sub_action->hasSubLinks)
481483
break; /* no need to keep scanning rtable */
482484
}
@@ -3338,7 +3340,7 @@ rewriteTargetView(Query *parsetree, Relation view)
33383340
view_targetlist,
33393341
REPLACEVARS_REPORT_ERROR,
33403342
0,
3341-
&parsetree->hasSubLinks);
3343+
NULL);
33423344

33433345
/*
33443346
* 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
@@ -2601,6 +2601,38 @@ DROP VIEW v1;
26012601
DROP TABLE t2;
26022602
DROP TABLE t1;
26032603
--
2604+
-- Test sub-select in nested security barrier views, per bug #17972
2605+
--
2606+
CREATE TABLE t1 (a int);
2607+
CREATE VIEW v1 WITH (security_barrier = true) AS
2608+
SELECT * FROM t1;
2609+
CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD
2610+
UPDATE t1 SET a = NEW.a WHERE a = OLD.a;
2611+
CREATE VIEW v2 WITH (security_barrier = true) AS
2612+
SELECT * FROM v1 WHERE EXISTS (SELECT 1);
2613+
EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1;
2614+
QUERY PLAN
2615+
---------------------------------------------------
2616+
Update on t1
2617+
InitPlan 1 (returns $0)
2618+
-> Result
2619+
-> Merge Join
2620+
Merge Cond: (t1.a = v1.a)
2621+
-> Sort
2622+
Sort Key: t1.a
2623+
-> Seq Scan on t1
2624+
-> Sort
2625+
Sort Key: v1.a
2626+
-> Subquery Scan on v1
2627+
-> Result
2628+
One-Time Filter: $0
2629+
-> Seq Scan on t1 t1_1
2630+
(14 rows)
2631+
2632+
DROP VIEW v2;
2633+
DROP VIEW v1;
2634+
DROP TABLE t1;
2635+
--
26042636
-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an
26052637
-- auto-updatable view and adding check options in a single step
26062638
--

src/test/regress/sql/updatable_views.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,23 @@ DROP VIEW v1;
12431243
DROP TABLE t2;
12441244
DROP TABLE t1;
12451245

1246+
--
1247+
-- Test sub-select in nested security barrier views, per bug #17972
1248+
--
1249+
CREATE TABLE t1 (a int);
1250+
CREATE VIEW v1 WITH (security_barrier = true) AS
1251+
SELECT * FROM t1;
1252+
CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD
1253+
UPDATE t1 SET a = NEW.a WHERE a = OLD.a;
1254+
CREATE VIEW v2 WITH (security_barrier = true) AS
1255+
SELECT * FROM v1 WHERE EXISTS (SELECT 1);
1256+
1257+
EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1;
1258+
1259+
DROP VIEW v2;
1260+
DROP VIEW v1;
1261+
DROP TABLE t1;
1262+
12461263
--
12471264
-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an
12481265
-- 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