Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit496943e

Browse files
committed
Make viewquery a copy in rewriteTargetView()
Rather than expect the Query returned by get_view_query() to beread-only and then copy bits and pieces of it out, simply copy theentire structure when we get it. This addresses an issue whereAcquireRewriteLocks, which is called by acquireLocksOnSubLinks(),scribbles on the parsetree passed in, which was actually an entryin relcache, leading to segfaults with certain view definitions.This also future-proofs us a bit for anyone adding more code to thispath.The acquireLocksOnSubLinks() was added in commitc3e0ddd.Back-patch to 9.3 as that commit was.
1 parent0c28e76 commit496943e

File tree

3 files changed

+133
-12
lines changed

3 files changed

+133
-12
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,9 @@ fireRules(Query *parsetree,
20262026
*
20272027
* Caller should have verified that the relation is a view, and therefore
20282028
* we should find an ON SELECT action.
2029+
*
2030+
* Note that the pointer returned is into the relcache and therefore must
2031+
* be treated as read-only to the caller and not modified or scribbled on.
20292032
*/
20302033
Query*
20312034
get_view_query(Relationview)
@@ -2613,9 +2616,16 @@ rewriteTargetView(Query *parsetree, Relation view)
26132616
List*view_targetlist;
26142617
ListCell*lc;
26152618

2616-
/* The view must be updatable, else fail */
2617-
viewquery=get_view_query(view);
2619+
/*
2620+
* Get the Query from the view's ON SELECT rule. We're going to munge the
2621+
* Query to change the view's base relation into the target relation,
2622+
* along with various other changes along the way, so we need to make a
2623+
* copy of it (get_view_query() returns a pointer into the relcache, so we
2624+
* have to treat it as read-only).
2625+
*/
2626+
viewquery=copyObject(get_view_query(view));
26182627

2628+
/* The view must be updatable, else fail */
26192629
auto_update_detail=
26202630
view_query_is_auto_updatable(viewquery,
26212631
parsetree->commandType!=CMD_DELETE);
@@ -2779,7 +2789,7 @@ rewriteTargetView(Query *parsetree, Relation view)
27792789
* outer query. Perhaps someday we should refactor things enough so that
27802790
* we can share code with the planner.)
27812791
*/
2782-
new_rte= (RangeTblEntry*)copyObject(base_rte);
2792+
new_rte= (RangeTblEntry*)base_rte;
27832793
parsetree->rtable=lappend(parsetree->rtable,new_rte);
27842794
new_rt_index=list_length(parsetree->rtable);
27852795

@@ -2791,14 +2801,14 @@ rewriteTargetView(Query *parsetree, Relation view)
27912801
new_rte->inh= false;
27922802

27932803
/*
2794-
*Make a copy ofthe view's targetlist, adjusting itsVars to reference
2795-
*the new target RTE, iemake their varnos be new_rt_index instead of
2796-
*base_rt_index. There canbe no Vars for other rels in the tlist, so
2797-
*this is sufficient to pullup the tlist expressions for use in the
2798-
*outer query. The tlist willprovide the replacement expressions used
2799-
*by ReplaceVarsFromTargetListbelow.
2804+
*Adjustthe view's targetlistVars to reference the new target RTE, ie
2805+
* make their varnos be new_rt_index instead of base_rt_index. There can
2806+
* be no Vars for other rels in the tlist, so this is sufficient to pull
2807+
* up the tlist expressions for use in the outer query. The tlist will
2808+
* provide the replacement expressions used by ReplaceVarsFromTargetList
2809+
* below.
28002810
*/
2801-
view_targetlist=copyObject(viewquery->targetList);
2811+
view_targetlist=viewquery->targetList;
28022812

28032813
ChangeVarNodes((Node*)view_targetlist,
28042814
base_rt_index,
@@ -2949,7 +2959,7 @@ rewriteTargetView(Query *parsetree, Relation view)
29492959
if (parsetree->commandType!=CMD_INSERT&&
29502960
viewquery->jointree->quals!=NULL)
29512961
{
2952-
Node*viewqual= (Node*)copyObject(viewquery->jointree->quals);
2962+
Node*viewqual= (Node*)viewquery->jointree->quals;
29532963

29542964
ChangeVarNodes(viewqual,base_rt_index,new_rt_index,0);
29552965

@@ -3028,7 +3038,7 @@ rewriteTargetView(Query *parsetree, Relation view)
30283038

30293039
if (viewquery->jointree->quals!=NULL)
30303040
{
3031-
wco->qual= (Node*)copyObject(viewquery->jointree->quals);
3041+
wco->qual= (Node*)viewquery->jointree->quals;
30323042
ChangeVarNodes(wco->qual,base_rt_index,new_rt_index,0);
30333043

30343044
/*

‎src/test/regress/expected/updatable_views.out

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,3 +2353,70 @@ DROP TABLE t1, t11, t12, t111 CASCADE;
23532353
NOTICE: drop cascades to view v1
23542354
DROP FUNCTION snoop(anyelement);
23552355
DROP FUNCTION leakproof(anyelement);
2356+
CREATE TABLE tx1 (a integer);
2357+
CREATE TABLE tx2 (b integer);
2358+
CREATE TABLE tx3 (c integer);
2359+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2360+
INSERT INTO vx1 values (1);
2361+
SELECT * FROM tx1;
2362+
a
2363+
---
2364+
1
2365+
(1 row)
2366+
2367+
SELECT * FROM vx1;
2368+
a
2369+
---
2370+
(0 rows)
2371+
2372+
DROP VIEW vx1;
2373+
DROP TABLE tx1;
2374+
DROP TABLE tx2;
2375+
DROP TABLE tx3;
2376+
CREATE TABLE tx1 (a integer);
2377+
CREATE TABLE tx2 (b integer);
2378+
CREATE TABLE tx3 (c integer);
2379+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2380+
INSERT INTO vx1 VALUES (1);
2381+
INSERT INTO vx1 VALUES (1);
2382+
SELECT * FROM tx1;
2383+
a
2384+
---
2385+
1
2386+
1
2387+
(2 rows)
2388+
2389+
SELECT * FROM vx1;
2390+
a
2391+
---
2392+
(0 rows)
2393+
2394+
DROP VIEW vx1;
2395+
DROP TABLE tx1;
2396+
DROP TABLE tx2;
2397+
DROP TABLE tx3;
2398+
CREATE TABLE tx1 (a integer, b integer);
2399+
CREATE TABLE tx2 (b integer, c integer);
2400+
CREATE TABLE tx3 (c integer, d integer);
2401+
ALTER TABLE tx1 DROP COLUMN b;
2402+
ALTER TABLE tx2 DROP COLUMN c;
2403+
ALTER TABLE tx3 DROP COLUMN d;
2404+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2405+
INSERT INTO vx1 VALUES (1);
2406+
INSERT INTO vx1 VALUES (1);
2407+
SELECT * FROM tx1;
2408+
a
2409+
---
2410+
1
2411+
1
2412+
(2 rows)
2413+
2414+
SELECT * FROM vx1;
2415+
a
2416+
---
2417+
(0 rows)
2418+
2419+
DROP VIEW vx1;
2420+
DROP TABLE tx1;
2421+
DROP TABLE tx2;
2422+
DROP TABLE tx3;

‎src/test/regress/sql/updatable_views.sql

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,3 +1020,47 @@ TABLE t1; -- verify all a<=5 are intact
10201020
DROPTABLE t1, t11, t12, t111 CASCADE;
10211021
DROPFUNCTION snoop(anyelement);
10221022
DROPFUNCTION leakproof(anyelement);
1023+
1024+
CREATETABLEtx1 (ainteger);
1025+
CREATETABLEtx2 (binteger);
1026+
CREATETABLEtx3 (cinteger);
1027+
CREATEVIEWvx1ASSELECT aFROM tx1WHERE EXISTS(SELECT1FROM tx2JOIN tx3ON b=c);
1028+
INSERT INTO vx1values (1);
1029+
SELECT*FROM tx1;
1030+
SELECT*FROM vx1;
1031+
1032+
DROPVIEW vx1;
1033+
DROPTABLE tx1;
1034+
DROPTABLE tx2;
1035+
DROPTABLE tx3;
1036+
1037+
CREATETABLEtx1 (ainteger);
1038+
CREATETABLEtx2 (binteger);
1039+
CREATETABLEtx3 (cinteger);
1040+
CREATEVIEWvx1ASSELECT aFROM tx1WHERE EXISTS(SELECT1FROM tx2JOIN tx3ON b=c);
1041+
INSERT INTO vx1VALUES (1);
1042+
INSERT INTO vx1VALUES (1);
1043+
SELECT*FROM tx1;
1044+
SELECT*FROM vx1;
1045+
1046+
DROPVIEW vx1;
1047+
DROPTABLE tx1;
1048+
DROPTABLE tx2;
1049+
DROPTABLE tx3;
1050+
1051+
CREATETABLEtx1 (ainteger, binteger);
1052+
CREATETABLEtx2 (binteger, cinteger);
1053+
CREATETABLEtx3 (cinteger, dinteger);
1054+
ALTERTABLE tx1 DROP COLUMN b;
1055+
ALTERTABLE tx2 DROP COLUMN c;
1056+
ALTERTABLE tx3 DROP COLUMN d;
1057+
CREATEVIEWvx1ASSELECT aFROM tx1WHERE EXISTS(SELECT1FROM tx2JOIN tx3ON b=c);
1058+
INSERT INTO vx1VALUES (1);
1059+
INSERT INTO vx1VALUES (1);
1060+
SELECT*FROM tx1;
1061+
SELECT*FROM vx1;
1062+
1063+
DROPVIEW vx1;
1064+
DROPTABLE tx1;
1065+
DROPTABLE tx2;
1066+
DROPTABLE tx3;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp