diff options
Diffstat (limited to 'src/backend/optimizer/util/clauses.c')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index fbb5a98e83d..2d960b5cf03 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.48 1999/08/22 20:14:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.49 1999/08/25 23:21:41 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -817,8 +817,8 @@ CommuteClause(Expr *clause) * the args and slink->oper lists (which belong to the outer plan), but it * will *not* visit the inner plan, since that's typically what expression * tree walkers want. A walker that wants to visit the subplan can force - * appropriate behavior by recognizing subplan nodes and doing the right - * thing. + * appropriate behavior by recognizing subplan expression nodes and doing + * the right thing. * * Bare SubLink nodes (without a SUBPLAN_EXPR) are handled by recursing into * the "lefthand" argument list only. (A bare SubLink should be seen only if @@ -854,26 +854,18 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) case T_Expr: { Expr *expr = (Expr *) node; + if (expr->opType == SUBPLAN_EXPR) { - /* examine args list (params to be passed to subplan) */ - if (expression_tree_walker((Node *) expr->args, - walker, context)) - return true; - /* examine oper list as well */ - if (expression_tree_walker( - (Node *) ((SubPlan *) expr->oper)->sublink->oper, - walker, context)) - return true; - /* but not the subplan itself */ - } - else - { - /* for other Expr node types, just examine args list */ - if (expression_tree_walker((Node *) expr->args, - walker, context)) + /* recurse to the SubLink node (skipping SubPlan!) */ + if (walker((Node *) ((SubPlan *) expr->oper)->sublink, + context)) return true; } + /* for all Expr node types, examine args list */ + if (expression_tree_walker((Node *) expr->args, + walker, context)) + return true; } break; case T_Aggref: @@ -918,11 +910,20 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) } break; case T_SubLink: - /* A "bare" SubLink (note we will not come here if we found - * a SUBPLAN_EXPR node above it). Examine the lefthand side, - * but not the oper list nor the subquery. - */ - return walker(((SubLink *) node)->lefthand, context); + { + SubLink *sublink = (SubLink *) node; + + /* If the SubLink has already been processed by subselect.c, + * it will have lefthand=NIL, and we only need to look at + * the oper list. Otherwise we only need to look at lefthand + * (the Oper nodes in the oper list are deemed uninteresting). + */ + if (sublink->lefthand) + return walker((Node *) sublink->lefthand, context); + else + return walker((Node *) sublink->oper, context); + } + break; case T_List: foreach(temp, (List *) node) { @@ -988,8 +989,8 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) * the args and slink->oper lists (which belong to the outer plan), but it * will simply copy the link to the inner plan, since that's typically what * expression tree mutators want. A mutator that wants to modify the subplan - * can force appropriate behavior by recognizing subplan nodes and doing the - * right thing. + * can force appropriate behavior by recognizing subplan expression nodes + * and doing the right thing. * * Bare SubLink nodes (without a SUBPLAN_EXPR) are handled by recursing into * the "lefthand" argument list only. (A bare SubLink should be seen only if |