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

Commit7711e40

Browse files
committed
Make application of FOR UPDATE to a view work exactly like the parser's
transformForUpdate does: it should recurse into subqueries.
1 parent0a844e8 commit7711e40

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.85 2000/12/06 23:55:18 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.86 2000/12/07 01:22:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -38,6 +38,7 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
3838
CmdTypeevent,
3939
boolinstead_flag);
4040
staticList*adjustJoinTreeList(Query*parsetree,intrt_index,bool*found);
41+
staticvoidmarkQueryForUpdate(Query*qry,boolskipOldNew);
4142
staticList*matchLocks(CmdTypeevent,RuleLock*rulelocks,
4243
intvarno,Query*parsetree);
4344
staticQuery*fireRIRrules(Query*parsetree);
@@ -263,7 +264,6 @@ ApplyRetrieveRule(Query *parsetree,
263264
Query*rule_action;
264265
RangeTblEntry*rte,
265266
*subrte;
266-
List*l;
267267

268268
if (length(rule->actions)!=1)
269269
elog(ERROR,"ApplyRetrieveRule: expected just one rule action");
@@ -308,8 +308,6 @@ ApplyRetrieveRule(Query *parsetree,
308308
*/
309309
if (intMember(rt_index,parsetree->rowMarks))
310310
{
311-
Indexinnerrti=1;
312-
313311
/*
314312
* Remove the view from the list of rels that will actually be
315313
* marked FOR UPDATE by the executor. It will still be access-
@@ -320,29 +318,51 @@ ApplyRetrieveRule(Query *parsetree,
320318
/*
321319
* Set up the view's referenced tables as if FOR UPDATE.
322320
*/
323-
foreach(l,rule_action->rtable)
324-
{
325-
subrte= (RangeTblEntry*)lfirst(l);
326-
327-
/*
328-
* RTable of VIEW has two entries of VIEW itself - skip them!
329-
* Also keep hands off of sub-subqueries.
330-
*/
331-
if (innerrti!=PRS2_OLD_VARNO&&innerrti!=PRS2_NEW_VARNO&&
332-
subrte->relid!=InvalidOid)
333-
{
334-
if (!intMember(innerrti,rule_action->rowMarks))
335-
rule_action->rowMarks=lappendi(rule_action->rowMarks,
336-
innerrti);
337-
subrte->checkForWrite= true;
338-
}
339-
innerrti++;
340-
}
321+
markQueryForUpdate(rule_action, true);
341322
}
342323

343324
returnparsetree;
344325
}
345326

327+
/*
328+
* Recursively mark all relations used by a view as FOR UPDATE.
329+
*
330+
* This may generate an invalid query, eg if some sub-query uses an
331+
* aggregate. We leave it to the planner to detect that.
332+
*
333+
* NB: this must agree with the parser's transformForUpdate() routine.
334+
*/
335+
staticvoid
336+
markQueryForUpdate(Query*qry,boolskipOldNew)
337+
{
338+
Indexrti=0;
339+
List*l;
340+
341+
foreach(l,qry->rtable)
342+
{
343+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(l);
344+
345+
rti++;
346+
347+
/* Ignore OLD and NEW entries if we are at top level of view */
348+
if (skipOldNew&&
349+
(rti==PRS2_OLD_VARNO||rti==PRS2_NEW_VARNO))
350+
continue;
351+
352+
if (rte->subquery)
353+
{
354+
/* FOR UPDATE of subquery is propagated to subquery's rels */
355+
markQueryForUpdate(rte->subquery, false);
356+
}
357+
else
358+
{
359+
if (!intMember(rti,qry->rowMarks))
360+
qry->rowMarks=lappendi(qry->rowMarks,rti);
361+
rte->checkForWrite= true;
362+
}
363+
}
364+
}
365+
346366

347367
/*
348368
* fireRIRonSubLink -

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp