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

Commitf02137d

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 parent590d201 commitf02137d

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
@@ -1908,6 +1908,9 @@ fireRules(Query *parsetree,
19081908
*
19091909
* Caller should have verified that the relation is a view, and therefore
19101910
* we should find an ON SELECT action.
1911+
*
1912+
* Note that the pointer returned is into the relcache and therefore must
1913+
* be treated as read-only to the caller and not modified or scribbled on.
19111914
*/
19121915
Query*
19131916
get_view_query(Relationview)
@@ -2494,9 +2497,16 @@ rewriteTargetView(Query *parsetree, Relation view)
24942497
List*view_targetlist;
24952498
ListCell*lc;
24962499

2497-
/* The view must be updatable, else fail */
2498-
viewquery=get_view_query(view);
2500+
/*
2501+
* Get the Query from the view's ON SELECT rule. We're going to munge the
2502+
* Query to change the view's base relation into the target relation,
2503+
* along with various other changes along the way, so we need to make a
2504+
* copy of it (get_view_query() returns a pointer into the relcache, so we
2505+
* have to treat it as read-only).
2506+
*/
2507+
viewquery=copyObject(get_view_query(view));
24992508

2509+
/* The view must be updatable, else fail */
25002510
auto_update_detail=
25012511
view_query_is_auto_updatable(viewquery,
25022512
parsetree->commandType!=CMD_DELETE);
@@ -2648,7 +2658,7 @@ rewriteTargetView(Query *parsetree, Relation view)
26482658
* outer query. Perhaps someday we should refactor things enough so that
26492659
* we can share code with the planner.)
26502660
*/
2651-
new_rte= (RangeTblEntry*)copyObject(base_rte);
2661+
new_rte= (RangeTblEntry*)base_rte;
26522662
parsetree->rtable=lappend(parsetree->rtable,new_rte);
26532663
new_rt_index=list_length(parsetree->rtable);
26542664

@@ -2660,14 +2670,14 @@ rewriteTargetView(Query *parsetree, Relation view)
26602670
new_rte->inh= false;
26612671

26622672
/*
2663-
*Make a copy ofthe view's targetlist, adjusting itsVars to reference
2664-
*the new target RTE, iemake their varnos be new_rt_index instead of
2665-
*base_rt_index. There canbe no Vars for other rels in the tlist, so
2666-
*this is sufficient to pullup the tlist expressions for use in the
2667-
*outer query. The tlist willprovide the replacement expressions used
2668-
*by ReplaceVarsFromTargetListbelow.
2673+
*Adjustthe view's targetlistVars to reference the new target RTE, ie
2674+
* make their varnos be new_rt_index instead of base_rt_index. There can
2675+
* be no Vars for other rels in the tlist, so this is sufficient to pull
2676+
* up the tlist expressions for use in the outer query. The tlist will
2677+
* provide the replacement expressions used by ReplaceVarsFromTargetList
2678+
* below.
26692679
*/
2670-
view_targetlist=copyObject(viewquery->targetList);
2680+
view_targetlist=viewquery->targetList;
26712681

26722682
ChangeVarNodes((Node*)view_targetlist,
26732683
base_rt_index,
@@ -2813,7 +2823,7 @@ rewriteTargetView(Query *parsetree, Relation view)
28132823
if (parsetree->commandType!=CMD_INSERT&&
28142824
viewquery->jointree->quals!=NULL)
28152825
{
2816-
Node*viewqual= (Node*)copyObject(viewquery->jointree->quals);
2826+
Node*viewqual= (Node*)viewquery->jointree->quals;
28172827

28182828
ChangeVarNodes(viewqual,base_rt_index,new_rt_index,0);
28192829

@@ -2890,7 +2900,7 @@ rewriteTargetView(Query *parsetree, Relation view)
28902900

28912901
if (viewquery->jointree->quals!=NULL)
28922902
{
2893-
wco->qual= (Node*)copyObject(viewquery->jointree->quals);
2903+
wco->qual= (Node*)viewquery->jointree->quals;
28942904
ChangeVarNodes(wco->qual,base_rt_index,new_rt_index,0);
28952905

28962906
/*

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,3 +2284,70 @@ DROP TABLE t1, t11, t12, t111 CASCADE;
22842284
NOTICE: drop cascades to view v1
22852285
DROP FUNCTION snoop(anyelement);
22862286
DROP FUNCTION leakproof(anyelement);
2287+
CREATE TABLE tx1 (a integer);
2288+
CREATE TABLE tx2 (b integer);
2289+
CREATE TABLE tx3 (c integer);
2290+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2291+
INSERT INTO vx1 values (1);
2292+
SELECT * FROM tx1;
2293+
a
2294+
---
2295+
1
2296+
(1 row)
2297+
2298+
SELECT * FROM vx1;
2299+
a
2300+
---
2301+
(0 rows)
2302+
2303+
DROP VIEW vx1;
2304+
DROP TABLE tx1;
2305+
DROP TABLE tx2;
2306+
DROP TABLE tx3;
2307+
CREATE TABLE tx1 (a integer);
2308+
CREATE TABLE tx2 (b integer);
2309+
CREATE TABLE tx3 (c integer);
2310+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2311+
INSERT INTO vx1 VALUES (1);
2312+
INSERT INTO vx1 VALUES (1);
2313+
SELECT * FROM tx1;
2314+
a
2315+
---
2316+
1
2317+
1
2318+
(2 rows)
2319+
2320+
SELECT * FROM vx1;
2321+
a
2322+
---
2323+
(0 rows)
2324+
2325+
DROP VIEW vx1;
2326+
DROP TABLE tx1;
2327+
DROP TABLE tx2;
2328+
DROP TABLE tx3;
2329+
CREATE TABLE tx1 (a integer, b integer);
2330+
CREATE TABLE tx2 (b integer, c integer);
2331+
CREATE TABLE tx3 (c integer, d integer);
2332+
ALTER TABLE tx1 DROP COLUMN b;
2333+
ALTER TABLE tx2 DROP COLUMN c;
2334+
ALTER TABLE tx3 DROP COLUMN d;
2335+
CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
2336+
INSERT INTO vx1 VALUES (1);
2337+
INSERT INTO vx1 VALUES (1);
2338+
SELECT * FROM tx1;
2339+
a
2340+
---
2341+
1
2342+
1
2343+
(2 rows)
2344+
2345+
SELECT * FROM vx1;
2346+
a
2347+
---
2348+
(0 rows)
2349+
2350+
DROP VIEW vx1;
2351+
DROP TABLE tx1;
2352+
DROP TABLE tx2;
2353+
DROP TABLE tx3;

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

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp