|
7 | 7 | *
|
8 | 8 | *
|
9 | 9 | * 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 $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -55,16 +55,11 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
|
55 | 55 | staticboolrangeTableEntry_used(Node*node,intrt_index,intsublevels_up);
|
56 | 56 | staticboolattribute_used(Node*node,intrt_index,intattno,
|
57 | 57 | intsublevels_up);
|
58 |
| -staticboolmodifyAggrefUplevel(Node*node,void*context); |
59 | 58 | staticboolmodifyAggrefChangeVarnodes(Node*node,intrt_index,intnew_index,
|
60 | 59 | intsublevels_up,intnew_sublevels_up);
|
61 | 60 | staticNode*modifyAggrefDropQual(Node*node,Node*targetNode);
|
62 | 61 | staticSubLink*modifyAggrefMakeSublink(Aggref*aggref,Query*parsetree);
|
63 | 62 | 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); |
68 | 63 | staticQuery*fireRIRrules(Query*parsetree);
|
69 | 64 | staticQuery*Except_Intersect_Rewrite(Query*parsetree);
|
70 | 65 | staticvoidcheck_targetlists_are_compatible(List*prev_target,
|
@@ -290,65 +285,15 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
|
290 | 285 | }
|
291 | 286 |
|
292 | 287 |
|
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 |
| - |
347 | 288 | /*
|
348 | 289 | * modifyAggrefChangeVarnodes -
|
349 | 290 | *Change the var nodes in a sublink created for an aggregate column
|
350 | 291 | *used in the qualification to point to the correct local RTE.
|
351 | 292 | *
|
| 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 | + * |
352 | 297 | * NOTE: although this has the form of a walker, we cheat and modify the
|
353 | 298 | * Var nodes in-place. The given expression tree should have been copied
|
354 | 299 | * earlier to ensure that no unwanted side-effects occur!
|
@@ -547,18 +492,18 @@ modifyAggrefMakeSublink(Aggref *aggref, Query *parsetree)
|
547 | 492 | * Recursing would be a bad idea --- we'd likely produce an
|
548 | 493 | * infinite recursion. This whole technique is a crock, really...
|
549 | 494 | */
|
550 |
| -if (checkQueryHasAggs(subquery->qual)) |
| 495 | +if (checkExprHasAggs(subquery->qual)) |
551 | 496 | elog(ERROR,"Cannot handle multiple aggregate functions in WHERE clause");
|
552 | 497 | subquery->groupClause=NIL;
|
553 | 498 | subquery->havingQual=NULL;
|
554 | 499 | subquery->hasAggs= TRUE;
|
555 |
| -subquery->hasSubLinks=checkQueryHasSubLink(subquery->qual); |
| 500 | +subquery->hasSubLinks=checkExprHasSubLink(subquery->qual); |
556 | 501 | subquery->unionClause=NULL;
|
557 | 502 |
|
558 | 503 | /* Increment all varlevelsup fields in the new subquery */
|
559 |
| -modifyAggrefUplevel((Node*)subquery,NULL); |
| 504 | +IncrementVarSublevelsUp((Node*)subquery,1,0); |
560 | 505 |
|
561 |
| -/* Replace references to the target table with correct varno. |
| 506 | +/* Replace references to the target table with correctlocalvarno. |
562 | 507 | * Note +1 here to account for effects of previous line!
|
563 | 508 | */
|
564 | 509 | modifyAggrefChangeVarnodes((Node*)subquery,target->varno,
|
@@ -600,49 +545,6 @@ modifyAggrefQual(Node *node, Query *parsetree)
|
600 | 545 | }
|
601 | 546 |
|
602 | 547 |
|
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 |
| - |
646 | 548 | staticNode*
|
647 | 549 | FindMatchingTLEntry(List*tlist,char*e_attname)
|
648 | 550 | {
|
@@ -675,38 +577,6 @@ make_null(Oid type)
|
675 | 577 | }
|
676 | 578 |
|
677 | 579 |
|
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 |
| - |
710 | 580 | /*
|
711 | 581 | * apply_RIR_view
|
712 | 582 | *Replace Vars matching a given RT index with copies of TL expressions.
|
@@ -749,9 +619,12 @@ apply_RIR_view_mutator(Node *node,
|
749 | 619 | returnmake_null(var->vartype);
|
750 | 620 | }
|
751 | 621 |
|
| 622 | +/* Make a copy of the tlist item to return */ |
752 | 623 | expr=copyObject(expr);
|
| 624 | +/* Adjust varlevelsup if tlist item is from higher query level */ |
753 | 625 | if (var->varlevelsup>0)
|
754 |
| -apply_RIR_adjust_sublevel(expr,var->varlevelsup); |
| 626 | +IncrementVarSublevelsUp(expr,var->varlevelsup,0); |
| 627 | + |
755 | 628 | *(context->modified)= true;
|
756 | 629 | return (Node*)expr;
|
757 | 630 | }
|
@@ -1279,8 +1152,11 @@ fireRules(Query *parsetree,
|
1279 | 1152 | else
|
1280 | 1153 | qual_product= (Query*)nth(0,*qual_products);
|
1281 | 1154 |
|
| 1155 | +MemSet(&qual_info,0,sizeof(qual_info)); |
1282 | 1156 | qual_info.event=qual_product->commandType;
|
| 1157 | +qual_info.current_varno=rt_index; |
1283 | 1158 | qual_info.new_varno=length(qual_product->rtable)+2;
|
| 1159 | + |
1284 | 1160 | qual_product=CopyAndAddQual(qual_product,
|
1285 | 1161 | actions,
|
1286 | 1162 | event_qual,
|
@@ -1575,16 +1451,16 @@ BasicQueryRewrite(Query *parsetree)
|
1575 | 1451 | if (query->hasAggs)
|
1576 | 1452 | {
|
1577 | 1453 | 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))) |
1581 | 1457 | elog(ERROR,"BasicQueryRewrite: failed to remove aggs from qual");
|
1582 | 1458 | }
|
1583 | 1459 | if (query->hasSubLinks)
|
1584 | 1460 | 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)); |
1588 | 1464 | results=lappend(results,query);
|
1589 | 1465 | }
|
1590 | 1466 |
|
|