mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Clean up handling of FOR UPDATE inside views and subselects ... make it
work where we can (given that the executor only handles it at top level) and generate an error where we can't. Note that while the parser has been allowing views to say SELECT FOR UPDATE for a few weeks now, that hasn't actually worked until just now.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.84 2000/12/05 19:15:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.85 2000/12/06 23:55:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -31,9 +31,6 @@
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
|
||||
extern void CheckSelectForUpdate(Query *rule_action); /* in analyze.c */
|
||||
|
||||
|
||||
static RewriteInfo *gatherRewriteMeta(Query *parsetree,
|
||||
Query *rule_action,
|
||||
Node *rule_qual,
|
||||
@ -100,29 +97,6 @@ gatherRewriteMeta(Query *parsetree,
|
||||
ChangeVarNodes(info->rule_qual,
|
||||
PRS2_OLD_VARNO + rt_length, rt_index, 0);
|
||||
|
||||
/*
|
||||
* Update resultRelation too ... perhaps this should be done by
|
||||
* Offset/ChangeVarNodes?
|
||||
*/
|
||||
if (sub_action->resultRelation)
|
||||
{
|
||||
int result_reln;
|
||||
int new_result_reln;
|
||||
|
||||
result_reln = sub_action->resultRelation;
|
||||
switch (result_reln)
|
||||
{
|
||||
case PRS2_OLD_VARNO:
|
||||
new_result_reln = rt_index;
|
||||
break;
|
||||
case PRS2_NEW_VARNO:
|
||||
default:
|
||||
new_result_reln = result_reln + rt_length;
|
||||
break;
|
||||
}
|
||||
sub_action->resultRelation = new_result_reln;
|
||||
}
|
||||
|
||||
/*
|
||||
* We want the main parsetree's rtable to end up as the concatenation
|
||||
* of its original contents plus those of all the relevant rule
|
||||
@ -336,8 +310,6 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
{
|
||||
Index innerrti = 1;
|
||||
|
||||
CheckSelectForUpdate(rule_action);
|
||||
|
||||
/*
|
||||
* Remove the view from the list of rels that will actually be
|
||||
* marked FOR UPDATE by the executor. It will still be access-
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.52 2000/12/05 19:15:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.53 2000/12/06 23:55:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -169,8 +169,29 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
|
||||
* sublevels_up doesn't get incremented prematurely.
|
||||
*/
|
||||
if (node && IsA(node, Query))
|
||||
query_tree_walker((Query *) node, OffsetVarNodes_walker,
|
||||
{
|
||||
Query *qry = (Query *) node;
|
||||
List *l;
|
||||
|
||||
/*
|
||||
* If we are starting at a Query, and sublevels_up is zero, then we
|
||||
* must also fix rangetable indexes in the Query itself --- namely
|
||||
* resultRelation and rowMarks entries. sublevels_up cannot be zero
|
||||
* when recursing into a subquery, so there's no need to have the
|
||||
* same logic inside OffsetVarNodes_walker.
|
||||
*/
|
||||
if (sublevels_up == 0)
|
||||
{
|
||||
if (qry->resultRelation)
|
||||
qry->resultRelation += offset;
|
||||
foreach(l, qry->rowMarks)
|
||||
{
|
||||
lfirsti(l) += offset;
|
||||
}
|
||||
}
|
||||
query_tree_walker(qry, OffsetVarNodes_walker,
|
||||
(void *) &context, true);
|
||||
}
|
||||
else
|
||||
OffsetVarNodes_walker(node, &context);
|
||||
}
|
||||
@ -252,8 +273,30 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
|
||||
* sublevels_up doesn't get incremented prematurely.
|
||||
*/
|
||||
if (node && IsA(node, Query))
|
||||
query_tree_walker((Query *) node, ChangeVarNodes_walker,
|
||||
{
|
||||
Query *qry = (Query *) node;
|
||||
List *l;
|
||||
|
||||
/*
|
||||
* If we are starting at a Query, and sublevels_up is zero, then we
|
||||
* must also fix rangetable indexes in the Query itself --- namely
|
||||
* resultRelation and rowMarks entries. sublevels_up cannot be zero
|
||||
* when recursing into a subquery, so there's no need to have the
|
||||
* same logic inside ChangeVarNodes_walker.
|
||||
*/
|
||||
if (sublevels_up == 0)
|
||||
{
|
||||
if (qry->resultRelation == rt_index)
|
||||
qry->resultRelation = new_index;
|
||||
foreach(l, qry->rowMarks)
|
||||
{
|
||||
if (lfirsti(l) == rt_index)
|
||||
lfirsti(l) = new_index;
|
||||
}
|
||||
}
|
||||
query_tree_walker(qry, ChangeVarNodes_walker,
|
||||
(void *) &context, true);
|
||||
}
|
||||
else
|
||||
ChangeVarNodes_walker(node, &context);
|
||||
}
|
||||
|
Reference in New Issue
Block a user