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

Commitcbcd170

Browse files
committed
Fix AcquireRewriteLocks to be sure that it acquires the right lock strength
when FOR UPDATE is propagated down into a sub-select expanded from a view.Similar bug to parser's isLockedRel issue that I fixed yesterday; likewiseseems not quite worth the effort to back-patch.
1 parent46e3a16 commitcbcd170

File tree

3 files changed

+45
-23
lines changed

3 files changed

+45
-23
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.190 2009/10/2814:55:43 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.191 2009/10/2817:36:50 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -55,7 +55,8 @@ static void markQueryForLocking(Query *qry, Node *jtnode,
5555
boolforUpdate,boolnoWait,boolpushedDown);
5656
staticList*matchLocks(CmdTypeevent,RuleLock*rulelocks,
5757
intvarno,Query*parsetree);
58-
staticQuery*fireRIRrules(Query*parsetree,List*activeRIRs);
58+
staticQuery*fireRIRrules(Query*parsetree,List*activeRIRs,
59+
boolforUpdatePushedDown);
5960

6061

6162
/*
@@ -64,6 +65,10 @@ static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
6465
* These locks will ensure that the relation schemas don't change under us
6566
* while we are rewriting and planning the query.
6667
*
68+
* forUpdatePushedDown indicates that a pushed-down FOR UPDATE/SHARE applies
69+
* to the current subquery, requiring all rels to be opened with RowShareLock.
70+
* This should always be false at the start of the recursion.
71+
*
6772
* A secondary purpose of this routine is to fix up JOIN RTE references to
6873
* dropped columns (see details below). Because the RTEs are modified in
6974
* place, it is generally appropriate for the caller of this routine to have
@@ -91,7 +96,7 @@ static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
9196
* construction of a nested join was O(N^2) in the nesting depth.)
9297
*/
9398
void
94-
AcquireRewriteLocks(Query*parsetree)
99+
AcquireRewriteLocks(Query*parsetree,boolforUpdatePushedDown)
95100
{
96101
ListCell*l;
97102
intrt_index;
@@ -129,7 +134,8 @@ AcquireRewriteLocks(Query *parsetree)
129134
*/
130135
if (rt_index==parsetree->resultRelation)
131136
lockmode=RowExclusiveLock;
132-
elseif (get_parse_rowmark(parsetree,rt_index)!=NULL)
137+
elseif (forUpdatePushedDown||
138+
get_parse_rowmark(parsetree,rt_index)!=NULL)
133139
lockmode=RowShareLock;
134140
else
135141
lockmode=AccessShareLock;
@@ -206,7 +212,9 @@ AcquireRewriteLocks(Query *parsetree)
206212
* The subquery RTE itself is all right, but we have to
207213
* recurse to process the represented subquery.
208214
*/
209-
AcquireRewriteLocks(rte->subquery);
215+
AcquireRewriteLocks(rte->subquery,
216+
(forUpdatePushedDown||
217+
get_parse_rowmark(parsetree,rt_index)!=NULL));
210218
break;
211219

212220
default:
@@ -220,7 +228,7 @@ AcquireRewriteLocks(Query *parsetree)
220228
{
221229
CommonTableExpr*cte= (CommonTableExpr*)lfirst(l);
222230

223-
AcquireRewriteLocks((Query*)cte->ctequery);
231+
AcquireRewriteLocks((Query*)cte->ctequery, false);
224232
}
225233

226234
/*
@@ -245,7 +253,7 @@ acquireLocksOnSubLinks(Node *node, void *context)
245253
SubLink*sub= (SubLink*)node;
246254

247255
/* Do what we came for */
248-
AcquireRewriteLocks((Query*)sub->subselect);
256+
AcquireRewriteLocks((Query*)sub->subselect, false);
249257
/* Fall through to process lefthand args of SubLink */
250258
}
251259

@@ -298,7 +306,7 @@ rewriteRuleAction(Query *parsetree,
298306
/*
299307
* Acquire necessary locks and fix any deleted JOIN RTE entries.
300308
*/
301-
AcquireRewriteLocks(rule_action);
309+
AcquireRewriteLocks(rule_action, false);
302310
(void)acquireLocksOnSubLinks(rule_qual,NULL);
303311

304312
current_varno=rt_index;
@@ -1134,7 +1142,8 @@ ApplyRetrieveRule(Query *parsetree,
11341142
intrt_index,
11351143
boolrelation_level,
11361144
Relationrelation,
1137-
List*activeRIRs)
1145+
List*activeRIRs,
1146+
boolforUpdatePushedDown)
11381147
{
11391148
Query*rule_action;
11401149
RangeTblEntry*rte,
@@ -1148,18 +1157,25 @@ ApplyRetrieveRule(Query *parsetree,
11481157
if (!relation_level)
11491158
elog(ERROR,"cannot handle per-attribute ON SELECT rule");
11501159

1160+
/*
1161+
* If FOR UPDATE/SHARE of view, be sure we get right initial lock on the
1162+
* relations it references.
1163+
*/
1164+
rc=get_parse_rowmark(parsetree,rt_index);
1165+
forUpdatePushedDown |= (rc!=NULL);
1166+
11511167
/*
11521168
* Make a modifiable copy of the view query, and acquire needed locks on
11531169
* the relations it mentions.
11541170
*/
11551171
rule_action=copyObject(linitial(rule->actions));
11561172

1157-
AcquireRewriteLocks(rule_action);
1173+
AcquireRewriteLocks(rule_action,forUpdatePushedDown);
11581174

11591175
/*
11601176
* Recursively expand any view references inside the view.
11611177
*/
1162-
rule_action=fireRIRrules(rule_action,activeRIRs);
1178+
rule_action=fireRIRrules(rule_action,activeRIRs,forUpdatePushedDown);
11631179

11641180
/*
11651181
* VIEWs are really easy --- just plug the view query in as a subselect,
@@ -1192,8 +1208,11 @@ ApplyRetrieveRule(Query *parsetree,
11921208
* If FOR UPDATE/SHARE of view, mark all the contained tables as
11931209
* implicit FOR UPDATE/SHARE, the same as the parser would have done
11941210
* if the view's subquery had been written out explicitly.
1211+
*
1212+
* Note: we don't consider forUpdatePushedDown here; such marks will be
1213+
* made by recursing from the upper level in markQueryForLocking.
11951214
*/
1196-
if ((rc=get_parse_rowmark(parsetree,rt_index))!=NULL)
1215+
if (rc!=NULL)
11971216
markQueryForLocking(rule_action, (Node*)rule_action->jointree,
11981217
rc->forUpdate,rc->noWait, true);
11991218

@@ -1281,7 +1300,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
12811300

12821301
/* Do what we came for */
12831302
sub->subselect= (Node*)fireRIRrules((Query*)sub->subselect,
1284-
activeRIRs);
1303+
activeRIRs, false);
12851304
/* Fall through to process lefthand args of SubLink */
12861305
}
12871306

@@ -1299,7 +1318,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
12991318
*Apply all RIR rules on each rangetable entry in a query
13001319
*/
13011320
staticQuery*
1302-
fireRIRrules(Query*parsetree,List*activeRIRs)
1321+
fireRIRrules(Query*parsetree,List*activeRIRs,boolforUpdatePushedDown)
13031322
{
13041323
intrt_index;
13051324
ListCell*lc;
@@ -1329,7 +1348,9 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
13291348
*/
13301349
if (rte->rtekind==RTE_SUBQUERY)
13311350
{
1332-
rte->subquery=fireRIRrules(rte->subquery,activeRIRs);
1351+
rte->subquery=fireRIRrules(rte->subquery,activeRIRs,
1352+
(forUpdatePushedDown||
1353+
get_parse_rowmark(parsetree,rt_index)!=NULL));
13331354
continue;
13341355
}
13351356

@@ -1406,7 +1427,8 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
14061427
rt_index,
14071428
rule->attrno==-1,
14081429
rel,
1409-
activeRIRs);
1430+
activeRIRs,
1431+
forUpdatePushedDown);
14101432
}
14111433

14121434
activeRIRs=list_delete_first(activeRIRs);
@@ -1421,7 +1443,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
14211443
CommonTableExpr*cte= (CommonTableExpr*)lfirst(lc);
14221444

14231445
cte->ctequery= (Node*)
1424-
fireRIRrules((Query*)cte->ctequery,activeRIRs);
1446+
fireRIRrules((Query*)cte->ctequery,activeRIRs, false);
14251447
}
14261448

14271449
/*
@@ -1850,7 +1872,7 @@ QueryRewrite(Query *parsetree)
18501872
{
18511873
Query*query= (Query*)lfirst(l);
18521874

1853-
query=fireRIRrules(query,NIL);
1875+
query=fireRIRrules(query,NIL, false);
18541876

18551877
/*
18561878
* If the query target was rewritten as a view, complain.

‎src/backend/utils/adt/ruleutils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.311 2009/10/2814:55:44 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.312 2009/10/2817:36:50 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -2175,7 +2175,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
21752175
query=getInsertSelectQuery(query,NULL);
21762176

21772177
/* Must acquire locks right away; see notes in get_query_def() */
2178-
AcquireRewriteLocks(query);
2178+
AcquireRewriteLocks(query, false);
21792179

21802180
context.buf=buf;
21812181
context.namespaces=list_make1(&dpns);
@@ -2320,7 +2320,7 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace,
23202320
* consistent results.Note we assume it's OK to scribble on the passed
23212321
* querytree!
23222322
*/
2323-
AcquireRewriteLocks(query);
2323+
AcquireRewriteLocks(query, false);
23242324

23252325
context.buf=buf;
23262326
context.namespaces=lcons(&dpns,list_copy(parentnamespace));

‎src/include/rewrite/rewriteHandler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/rewrite/rewriteHandler.h,v 1.31 2009/01/01 17:24:01 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/rewrite/rewriteHandler.h,v 1.32 2009/10/28 17:36:50 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -18,7 +18,7 @@
1818
#include"nodes/parsenodes.h"
1919

2020
externList*QueryRewrite(Query*parsetree);
21-
externvoidAcquireRewriteLocks(Query*parsetree);
21+
externvoidAcquireRewriteLocks(Query*parsetree,boolforUpdatePushedDown);
2222
externNode*build_column_default(Relationrel,intattrno);
2323

2424
#endif/* REWRITEHANDLER_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp