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

Commit6f8cb1e

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 parent99ccb23 commit6f8cb1e

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
@@ -2033,6 +2033,9 @@ fireRules(Query *parsetree,
20332033
*
20342034
* Caller should have verified that the relation is a view, and therefore
20352035
* we should find an ON SELECT action.
2036+
*
2037+
* Note that the pointer returned is into the relcache and therefore must
2038+
* be treated as read-only to the caller and not modified or scribbled on.
20362039
*/
20372040
Query*
20382041
get_view_query(Relationview)
@@ -2620,9 +2623,16 @@ rewriteTargetView(Query *parsetree, Relation view)
26202623
List*view_targetlist;
26212624
ListCell*lc;
26222625

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

2635+
/* The view must be updatable, else fail */
26262636
auto_update_detail=
26272637
view_query_is_auto_updatable(viewquery,
26282638
parsetree->commandType!=CMD_DELETE);
@@ -2786,7 +2796,7 @@ rewriteTargetView(Query *parsetree, Relation view)
27862796
* outer query. Perhaps someday we should refactor things enough so that
27872797
* we can share code with the planner.)
27882798
*/
2789-
new_rte= (RangeTblEntry*)copyObject(base_rte);
2799+
new_rte= (RangeTblEntry*)base_rte;
27902800
parsetree->rtable=lappend(parsetree->rtable,new_rte);
27912801
new_rt_index=list_length(parsetree->rtable);
27922802

@@ -2798,14 +2808,14 @@ rewriteTargetView(Query *parsetree, Relation view)
27982808
new_rte->inh= false;
27992809

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

28102820
ChangeVarNodes((Node*)view_targetlist,
28112821
base_rt_index,
@@ -2956,7 +2966,7 @@ rewriteTargetView(Query *parsetree, Relation view)
29562966
if (parsetree->commandType!=CMD_INSERT&&
29572967
viewquery->jointree->quals!=NULL)
29582968
{
2959-
Node*viewqual= (Node*)copyObject(viewquery->jointree->quals);
2969+
Node*viewqual= (Node*)viewquery->jointree->quals;
29602970

29612971
ChangeVarNodes(viewqual,base_rt_index,new_rt_index,0);
29622972

@@ -3035,7 +3045,7 @@ rewriteTargetView(Query *parsetree, Relation view)
30353045

30363046
if (viewquery->jointree->quals!=NULL)
30373047
{
3038-
wco->qual= (Node*)copyObject(viewquery->jointree->quals);
3048+
wco->qual= (Node*)viewquery->jointree->quals;
30393049
ChangeVarNodes(wco->qual,base_rt_index,new_rt_index,0);
30403050

30413051
/*

‎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