|
6 | 6 | *
|
7 | 7 | *
|
8 | 8 | * IDENTIFICATION
|
9 |
| - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.10 1998/01/09 05:48:17 momjian Exp $ |
| 9 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.11 1998/01/21 04:24:36 momjian Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
|
29 | 29 | #include"commands/creatinh.h"
|
30 | 30 | #include"access/heapam.h"
|
31 | 31 |
|
32 |
| -staticvoid |
33 |
| -ApplyRetrieveRule(Query*parsetree,RewriteRule*rule, |
| 32 | +staticvoidApplyRetrieveRule(Query*parsetree,RewriteRule*rule, |
34 | 33 | intrt_index,intrelation_level,int*modified);
|
35 |
| -staticList* |
36 |
| -fireRules(Query*parsetree,intrt_index,CmdTypeevent, |
| 34 | +staticList*fireRules(Query*parsetree,intrt_index,CmdTypeevent, |
37 | 35 | bool*instead_flag,List*locks,List**qual_products);
|
| 36 | +staticvoidQueryRewriteSubLink(Node*node); |
| 37 | +staticList*QueryRewriteOne(Query*parsetree); |
38 | 38 | staticList*deepRewriteQuery(Query*parsetree);
|
39 | 39 |
|
40 | 40 | /*
|
@@ -77,11 +77,11 @@ gatherRewriteMeta(Query *parsetree,
|
77 | 77 | OffsetVarNodes((Node*)info->rule_action->targetList,rt_length);
|
78 | 78 | OffsetVarNodes(info->rule_qual,rt_length);
|
79 | 79 | ChangeVarNodes((Node*)info->rule_action->qual,
|
80 |
| -PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 80 | +PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
81 | 81 | ChangeVarNodes((Node*)info->rule_action->targetList,
|
82 |
| -PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 82 | +PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
83 | 83 | ChangeVarNodes(info->rule_qual,
|
84 |
| -PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 84 | +PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
85 | 85 |
|
86 | 86 | /*
|
87 | 87 | * bug here about replace CURRENT -- sort of replace current is
|
@@ -292,10 +292,10 @@ ApplyRetrieveRule(Query *parsetree,
|
292 | 292 | OffsetVarNodes((Node*)rule_action->targetList,rt_length);
|
293 | 293 | OffsetVarNodes(rule_qual,rt_length);
|
294 | 294 | ChangeVarNodes(rule_action->qual,
|
295 |
| -PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 295 | +PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
296 | 296 | ChangeVarNodes((Node*)rule_action->targetList,
|
297 |
| -PRS2_CURRENT_VARNO+rt_length,rt_index); |
298 |
| -ChangeVarNodes(rule_qual,PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 297 | +PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
| 298 | +ChangeVarNodes(rule_qual,PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
299 | 299 | if (relation_level)
|
300 | 300 | {
|
301 | 301 | HandleViewRule(parsetree,rtable,rule_action->targetList,rt_index,
|
@@ -402,7 +402,7 @@ CopyAndAddQual(Query *parsetree,
|
402 | 402 | rtable=append(rtable,listCopy(rule_action->rtable));
|
403 | 403 | new_tree->rtable=rtable;
|
404 | 404 | OffsetVarNodes(new_qual,rt_length);
|
405 |
| -ChangeVarNodes(new_qual,PRS2_CURRENT_VARNO+rt_length,rt_index); |
| 405 | +ChangeVarNodes(new_qual,PRS2_CURRENT_VARNO+rt_length,rt_index,0); |
406 | 406 | }
|
407 | 407 | /* XXX -- where current doesn't work for instead nothing.... yet */
|
408 | 408 | AddNotQual(new_tree,new_qual);
|
@@ -627,6 +627,82 @@ static intnumQueryRewriteInvoked = 0;
|
627 | 627 | */
|
628 | 628 | List*
|
629 | 629 | QueryRewrite(Query*parsetree)
|
| 630 | +{ |
| 631 | + |
| 632 | +QueryRewriteSubLink(parsetree->qual); |
| 633 | +returnQueryRewriteOne(parsetree); |
| 634 | +} |
| 635 | + |
| 636 | +/* |
| 637 | + *QueryRewriteSubLink |
| 638 | + * |
| 639 | + *This rewrites the SubLink subqueries first, doing the lowest ones first. |
| 640 | + *We already have code in the main rewrite loops to process correlated |
| 641 | + *variables from upper queries that exist in subqueries. |
| 642 | + */ |
| 643 | +staticvoid |
| 644 | +QueryRewriteSubLink(Node*node) |
| 645 | +{ |
| 646 | +if (node==NULL) |
| 647 | +return; |
| 648 | + |
| 649 | +switch (nodeTag(node)) |
| 650 | +{ |
| 651 | +caseT_TargetEntry: |
| 652 | +break; |
| 653 | +caseT_Aggreg: |
| 654 | +break; |
| 655 | +caseT_Expr: |
| 656 | +{ |
| 657 | +Expr*expr= (Expr*)node; |
| 658 | + |
| 659 | +QueryRewriteSubLink((Node*)expr->args); |
| 660 | +} |
| 661 | +break; |
| 662 | +caseT_Var: |
| 663 | +break; |
| 664 | +caseT_List: |
| 665 | +{ |
| 666 | +List*l; |
| 667 | + |
| 668 | +foreach(l, (List*)node) |
| 669 | +QueryRewriteSubLink(lfirst(l)); |
| 670 | +} |
| 671 | +break; |
| 672 | +caseT_SubLink: |
| 673 | +{ |
| 674 | +SubLink*sublink= (SubLink*)node; |
| 675 | +Query*query= (Query*)sublink->subselect; |
| 676 | +List*ret; |
| 677 | + |
| 678 | +/* |
| 679 | + *Nest down first. We do this so if a rewrite adds a |
| 680 | + *SubLink we don't process it as part of this loop. |
| 681 | + */ |
| 682 | +QueryRewriteSubLink((Node*)query->qual); |
| 683 | + |
| 684 | +ret=QueryRewriteOne(query); |
| 685 | +if (!ret) |
| 686 | +sublink->subselect=NULL; |
| 687 | +elseif (lnext(ret)==NIL) |
| 688 | +sublink->subselect=lfirst(ret); |
| 689 | +else |
| 690 | +elog(ERROR,"Don't know how to process subquery that rewrites to multiple queries."); |
| 691 | +} |
| 692 | +break; |
| 693 | +default: |
| 694 | +/* ignore the others */ |
| 695 | +break; |
| 696 | +} |
| 697 | +return; |
| 698 | +} |
| 699 | + |
| 700 | +/* |
| 701 | + * QueryOneRewrite - |
| 702 | + * rewrite one query |
| 703 | + */ |
| 704 | +staticList* |
| 705 | +QueryRewriteOne(Query*parsetree) |
630 | 706 | {
|
631 | 707 | numQueryRewriteInvoked=0;
|
632 | 708 |
|
|