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

Commite64a331

Browse files
committed
Fix some (more) problems with subselects in rules. Rewriter failed to
mark query as having subselects if a subselect was added from a ruleWHERE condition (as opposed to a rule action). Also, fix adjustmentof varlevelsup so that it actually has some prospect of working wheninserting an expression containing a subselect into a subquery.
1 parent4a3a1e2 commite64a331

File tree

3 files changed

+188
-166
lines changed

3 files changed

+188
-166
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 22 additions & 146 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.68 2000/03/12 18:57:05 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.69 2000/03/16 03:23:18 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -55,16 +55,11 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
5555
staticboolrangeTableEntry_used(Node*node,intrt_index,intsublevels_up);
5656
staticboolattribute_used(Node*node,intrt_index,intattno,
5757
intsublevels_up);
58-
staticboolmodifyAggrefUplevel(Node*node,void*context);
5958
staticboolmodifyAggrefChangeVarnodes(Node*node,intrt_index,intnew_index,
6059
intsublevels_up,intnew_sublevels_up);
6160
staticNode*modifyAggrefDropQual(Node*node,Node*targetNode);
6261
staticSubLink*modifyAggrefMakeSublink(Aggref*aggref,Query*parsetree);
6362
staticNode*modifyAggrefQual(Node*node,Query*parsetree);
64-
staticboolcheckQueryHasAggs(Node*node);
65-
staticboolcheckQueryHasAggs_walker(Node*node,void*context);
66-
staticboolcheckQueryHasSubLink(Node*node);
67-
staticboolcheckQueryHasSubLink_walker(Node*node,void*context);
6863
staticQuery*fireRIRrules(Query*parsetree);
6964
staticQuery*Except_Intersect_Rewrite(Query*parsetree);
7065
staticvoidcheck_targetlists_are_compatible(List*prev_target,
@@ -290,65 +285,15 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
290285
}
291286

292287

293-
/*
294-
* modifyAggrefUplevel -
295-
*In the newly created sublink for an aggregate column used in
296-
*the qualification, we must increment the varlevelsup in all the
297-
*var nodes.
298-
*
299-
* NOTE: although this has the form of a walker, we cheat and modify the
300-
* Var nodes in-place. The given expression tree should have been copied
301-
* earlier to ensure that no unwanted side-effects occur!
302-
*/
303-
staticbool
304-
modifyAggrefUplevel(Node*node,void*context)
305-
{
306-
if (node==NULL)
307-
return false;
308-
if (IsA(node,Var))
309-
{
310-
Var*var= (Var*)node;
311-
312-
var->varlevelsup++;
313-
return false;
314-
}
315-
if (IsA(node,SubLink))
316-
{
317-
/*
318-
* Standard expression_tree_walker will not recurse into subselect,
319-
* but here we must do so.
320-
*/
321-
SubLink*sub= (SubLink*)node;
322-
323-
if (modifyAggrefUplevel((Node*) (sub->lefthand),context))
324-
return true;
325-
if (modifyAggrefUplevel((Node*) (sub->subselect),context))
326-
return true;
327-
return false;
328-
}
329-
if (IsA(node,Query))
330-
{
331-
/* Reach here after recursing down into subselect above... */
332-
Query*qry= (Query*)node;
333-
334-
if (modifyAggrefUplevel((Node*) (qry->targetList),context))
335-
return true;
336-
if (modifyAggrefUplevel((Node*) (qry->qual),context))
337-
return true;
338-
if (modifyAggrefUplevel((Node*) (qry->havingQual),context))
339-
return true;
340-
return false;
341-
}
342-
returnexpression_tree_walker(node,modifyAggrefUplevel,
343-
(void*)context);
344-
}
345-
346-
347288
/*
348289
* modifyAggrefChangeVarnodes -
349290
*Change the var nodes in a sublink created for an aggregate column
350291
*used in the qualification to point to the correct local RTE.
351292
*
293+
* XXX if we still need this after redoing querytree design, it should
294+
* be combined with ChangeVarNodes, which is the same thing except for
295+
* not having the option to adjust the vars' varlevelsup.
296+
*
352297
* NOTE: although this has the form of a walker, we cheat and modify the
353298
* Var nodes in-place. The given expression tree should have been copied
354299
* earlier to ensure that no unwanted side-effects occur!
@@ -547,18 +492,18 @@ modifyAggrefMakeSublink(Aggref *aggref, Query *parsetree)
547492
* Recursing would be a bad idea --- we'd likely produce an
548493
* infinite recursion. This whole technique is a crock, really...
549494
*/
550-
if (checkQueryHasAggs(subquery->qual))
495+
if (checkExprHasAggs(subquery->qual))
551496
elog(ERROR,"Cannot handle multiple aggregate functions in WHERE clause");
552497
subquery->groupClause=NIL;
553498
subquery->havingQual=NULL;
554499
subquery->hasAggs= TRUE;
555-
subquery->hasSubLinks=checkQueryHasSubLink(subquery->qual);
500+
subquery->hasSubLinks=checkExprHasSubLink(subquery->qual);
556501
subquery->unionClause=NULL;
557502

558503
/* Increment all varlevelsup fields in the new subquery */
559-
modifyAggrefUplevel((Node*)subquery,NULL);
504+
IncrementVarSublevelsUp((Node*)subquery,1,0);
560505

561-
/* Replace references to the target table with correct varno.
506+
/* Replace references to the target table with correctlocalvarno.
562507
* Note +1 here to account for effects of previous line!
563508
*/
564509
modifyAggrefChangeVarnodes((Node*)subquery,target->varno,
@@ -600,49 +545,6 @@ modifyAggrefQual(Node *node, Query *parsetree)
600545
}
601546

602547

603-
/*
604-
* checkQueryHasAggs -
605-
*Queries marked hasAggs might not have them any longer after
606-
*rewriting. Check it.
607-
*/
608-
staticbool
609-
checkQueryHasAggs(Node*node)
610-
{
611-
returncheckQueryHasAggs_walker(node,NULL);
612-
}
613-
614-
staticbool
615-
checkQueryHasAggs_walker(Node*node,void*context)
616-
{
617-
if (node==NULL)
618-
return false;
619-
if (IsA(node,Aggref))
620-
return true;/* abort the tree traversal and return true */
621-
returnexpression_tree_walker(node,checkQueryHasAggs_walker,context);
622-
}
623-
624-
/*
625-
* checkQueryHasSubLink -
626-
*Queries marked hasSubLinks might not have them any longer after
627-
*rewriting. Check it.
628-
*/
629-
staticbool
630-
checkQueryHasSubLink(Node*node)
631-
{
632-
returncheckQueryHasSubLink_walker(node,NULL);
633-
}
634-
635-
staticbool
636-
checkQueryHasSubLink_walker(Node*node,void*context)
637-
{
638-
if (node==NULL)
639-
return false;
640-
if (IsA(node,SubLink))
641-
return true;/* abort the tree traversal and return true */
642-
returnexpression_tree_walker(node,checkQueryHasSubLink_walker,context);
643-
}
644-
645-
646548
staticNode*
647549
FindMatchingTLEntry(List*tlist,char*e_attname)
648550
{
@@ -675,38 +577,6 @@ make_null(Oid type)
675577
}
676578

677579

678-
/*
679-
* apply_RIR_adjust_sublevel -
680-
*Set the varlevelsup field of all Var nodes in the given expression tree
681-
*to sublevels_up. We do NOT recurse into subselects.
682-
*
683-
* NOTE: although this has the form of a walker, we cheat and modify the
684-
* Var nodes in-place. The given expression tree should have been copied
685-
* earlier to ensure that no unwanted side-effects occur!
686-
*/
687-
staticbool
688-
apply_RIR_adjust_sublevel_walker(Node*node,int*sublevels_up)
689-
{
690-
if (node==NULL)
691-
return false;
692-
if (IsA(node,Var))
693-
{
694-
Var*var= (Var*)node;
695-
696-
var->varlevelsup=*sublevels_up;
697-
return false;
698-
}
699-
returnexpression_tree_walker(node,apply_RIR_adjust_sublevel_walker,
700-
(void*)sublevels_up);
701-
}
702-
703-
staticvoid
704-
apply_RIR_adjust_sublevel(Node*node,intsublevels_up)
705-
{
706-
apply_RIR_adjust_sublevel_walker(node,&sublevels_up);
707-
}
708-
709-
710580
/*
711581
* apply_RIR_view
712582
*Replace Vars matching a given RT index with copies of TL expressions.
@@ -749,9 +619,12 @@ apply_RIR_view_mutator(Node *node,
749619
returnmake_null(var->vartype);
750620
}
751621

622+
/* Make a copy of the tlist item to return */
752623
expr=copyObject(expr);
624+
/* Adjust varlevelsup if tlist item is from higher query level */
753625
if (var->varlevelsup>0)
754-
apply_RIR_adjust_sublevel(expr,var->varlevelsup);
626+
IncrementVarSublevelsUp(expr,var->varlevelsup,0);
627+
755628
*(context->modified)= true;
756629
return (Node*)expr;
757630
}
@@ -1279,8 +1152,11 @@ fireRules(Query *parsetree,
12791152
else
12801153
qual_product= (Query*)nth(0,*qual_products);
12811154

1155+
MemSet(&qual_info,0,sizeof(qual_info));
12821156
qual_info.event=qual_product->commandType;
1157+
qual_info.current_varno=rt_index;
12831158
qual_info.new_varno=length(qual_product->rtable)+2;
1159+
12841160
qual_product=CopyAndAddQual(qual_product,
12851161
actions,
12861162
event_qual,
@@ -1575,16 +1451,16 @@ BasicQueryRewrite(Query *parsetree)
15751451
if (query->hasAggs)
15761452
{
15771453
query->hasAggs=
1578-
checkQueryHasAggs((Node*) (query->targetList))||
1579-
checkQueryHasAggs((Node*) (query->havingQual));
1580-
if (checkQueryHasAggs((Node*) (query->qual)))
1454+
checkExprHasAggs((Node*) (query->targetList))||
1455+
checkExprHasAggs((Node*) (query->havingQual));
1456+
if (checkExprHasAggs((Node*) (query->qual)))
15811457
elog(ERROR,"BasicQueryRewrite: failed to remove aggs from qual");
15821458
}
15831459
if (query->hasSubLinks)
15841460
query->hasSubLinks=
1585-
checkQueryHasSubLink((Node*) (query->targetList))||
1586-
checkQueryHasSubLink((Node*) (query->qual))||
1587-
checkQueryHasSubLink((Node*) (query->havingQual));
1461+
checkExprHasSubLink((Node*) (query->targetList))||
1462+
checkExprHasSubLink((Node*) (query->qual))||
1463+
checkExprHasSubLink((Node*) (query->havingQual));
15881464
results=lappend(results,query);
15891465
}
15901466

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp