|
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 |
|
|