diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index cd8b0e6612..f24fe23f15 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.114 2002/05/12 20:10:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.115 2002/05/18 02:25:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -671,19 +671,19 @@ create_nestloop_plan(Query *root, /* only refs to outer vars get changed in the inner indexqual */ innerscan->indxqualorig = join_references(indxqualorig, - root, + root->rtable, outer_tlist, NIL, innerrel); innerscan->indxqual = join_references(innerscan->indxqual, - root, + root->rtable, outer_tlist, NIL, innerrel); /* fix the inner qpqual too, if it has join clauses */ if (NumRelids((Node *) inner_plan->qual) > 1) inner_plan->qual = join_references(inner_plan->qual, - root, + root->rtable, outer_tlist, NIL, innerrel); @@ -694,7 +694,7 @@ create_nestloop_plan(Query *root, TidScan *innerscan = (TidScan *) inner_plan; innerscan->tideval = join_references(innerscan->tideval, - root, + root->rtable, outer_tlist, inner_tlist, innerscan->scan.scanrelid); @@ -716,12 +716,12 @@ create_nestloop_plan(Query *root, * Set quals to contain INNER/OUTER var references. */ joinclauses = join_references(joinclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); otherclauses = join_references(otherclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); @@ -760,7 +760,7 @@ create_mergejoin_plan(Query *root, * clauses to contain INNER/OUTER var references. */ joinclauses = join_references(set_difference(joinclauses, mergeclauses), - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); @@ -769,7 +769,7 @@ create_mergejoin_plan(Query *root, * Fix the additional qpquals too. */ otherclauses = join_references(otherclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); @@ -779,7 +779,7 @@ create_mergejoin_plan(Query *root, * that the outer variable is always on the left. */ mergeclauses = switch_outer(join_references(mergeclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0)); @@ -886,7 +886,7 @@ create_hashjoin_plan(Query *root, * clauses to contain INNER/OUTER var references. */ joinclauses = join_references(set_difference(joinclauses, hashclauses), - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); @@ -895,7 +895,7 @@ create_hashjoin_plan(Query *root, * Fix the additional qpquals too. */ otherclauses = join_references(otherclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0); @@ -905,7 +905,7 @@ create_hashjoin_plan(Query *root, * that the outer variable is always on the left. */ hashclauses = switch_outer(join_references(hashclauses, - root, + root->rtable, outer_tlist, inner_tlist, (Index) 0)); diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index fdd375acd8..2d12a623f7 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.71 2002/05/17 22:35:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.72 2002/05/18 02:25:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -177,7 +177,7 @@ add_vars_to_targetlist(Query *root, List *vars) List *varsused; expansion = flatten_join_alias_vars((Node *) var, - root, true); + root->rtable, true); varsused = pull_var_clause(expansion, false); add_vars_to_targetlist(root, varsused); freeList(varsused); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 500297f215..a3eeced7bb 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.117 2002/05/12 23:43:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.118 2002/05/18 02:25:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -101,7 +101,7 @@ planner(Query *parse) result_plan->nParamExec = length(PlannerParamVar); /* final cleanup of the plan */ - set_plan_references(parse, result_plan); + set_plan_references(result_plan, parse->rtable); /* restore state for outer planner, if any */ PlannerQueryLevel = save_PlannerQueryLevel; @@ -175,6 +175,17 @@ subquery_planner(Query *parse, double tuple_fraction) parse->havingQual = preprocess_expression(parse, parse->havingQual, EXPRKIND_HAVING); + /* Also need to preprocess expressions for function RTEs */ + foreach(lst, parse->rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst); + + if (rte->rtekind == RTE_FUNCTION) + rte->funcexpr = preprocess_expression(parse, rte->funcexpr, + EXPRKIND_TARGET); + /* These are not targetlist items, but close enough... */ + } + /* * Check for ungrouped variables passed to subplans in targetlist and * HAVING clause (but not in WHERE or JOIN/ON clauses, since those are @@ -737,7 +748,7 @@ preprocess_expression(Query *parse, Node *expr, int kind) } } if (has_join_rtes) - expr = flatten_join_alias_vars(expr, parse, false); + expr = flatten_join_alias_vars(expr, parse->rtable, false); return expr; } diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 1b05d49054..3f0187617a 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.77 2002/05/18 00:42:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.78 2002/05/18 02:25:50 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ typedef struct { - Query *root; + List *rtable; List *outer_tlist; List *inner_tlist; Index acceptable_rel; @@ -42,7 +42,7 @@ typedef struct } replace_vars_with_subplan_refs_context; static void fix_expr_references(Plan *plan, Node *node); -static void set_join_references(Query *root, Join *join); +static void set_join_references(Join *join, List *rtable); static void set_uppernode_references(Plan *plan, Index subvarno); static Node *join_references_mutator(Node *node, join_references_context *context); @@ -75,7 +75,7 @@ static bool fix_opids_walker(Node *node, void *context); * Returns nothing of interest, but modifies internal fields of nodes. */ void -set_plan_references(Query *root, Plan *plan) +set_plan_references(Plan *plan, List *rtable) { List *pl; @@ -110,16 +110,24 @@ set_plan_references(Query *root, Plan *plan) fix_expr_references(plan, (Node *) plan->qual); break; case T_SubqueryScan: + { + RangeTblEntry *rte; - /* - * We do not do set_uppernode_references() here, because a - * SubqueryScan will always have been created with correct - * references to its subplan's outputs to begin with. - */ - fix_expr_references(plan, (Node *) plan->targetlist); - fix_expr_references(plan, (Node *) plan->qual); - /* Recurse into subplan too */ - set_plan_references(root, ((SubqueryScan *) plan)->subplan); + /* + * We do not do set_uppernode_references() here, because a + * SubqueryScan will always have been created with correct + * references to its subplan's outputs to begin with. + */ + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); + + /* Recurse into subplan too */ + rte = rt_fetch(((SubqueryScan *) plan)->scan.scanrelid, + rtable); + Assert(rte->rtekind == RTE_SUBQUERY); + set_plan_references(((SubqueryScan *) plan)->subplan, + rte->subquery->rtable); + } break; case T_FunctionScan: { @@ -128,19 +136,19 @@ set_plan_references(Query *root, Plan *plan) fix_expr_references(plan, (Node *) plan->targetlist); fix_expr_references(plan, (Node *) plan->qual); rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid, - root->rtable); + rtable); Assert(rte->rtekind == RTE_FUNCTION); fix_expr_references(plan, rte->funcexpr); } break; case T_NestLoop: - set_join_references(root, (Join *) plan); + set_join_references((Join *) plan, rtable); fix_expr_references(plan, (Node *) plan->targetlist); fix_expr_references(plan, (Node *) plan->qual); fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual); break; case T_MergeJoin: - set_join_references(root, (Join *) plan); + set_join_references((Join *) plan, rtable); fix_expr_references(plan, (Node *) plan->targetlist); fix_expr_references(plan, (Node *) plan->qual); fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual); @@ -148,7 +156,7 @@ set_plan_references(Query *root, Plan *plan) (Node *) ((MergeJoin *) plan)->mergeclauses); break; case T_HashJoin: - set_join_references(root, (Join *) plan); + set_join_references((Join *) plan, rtable); fix_expr_references(plan, (Node *) plan->targetlist); fix_expr_references(plan, (Node *) plan->qual); fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual); @@ -202,7 +210,7 @@ set_plan_references(Query *root, Plan *plan) * recurse into subplans. */ foreach(pl, ((Append *) plan)->appendplans) - set_plan_references(root, (Plan *) lfirst(pl)); + set_plan_references((Plan *) lfirst(pl), rtable); break; default: elog(ERROR, "set_plan_references: unknown plan type %d", @@ -219,21 +227,21 @@ set_plan_references(Query *root, Plan *plan) * plan's var nodes against the already-modified nodes of the * subplans. */ - set_plan_references(root, plan->lefttree); - set_plan_references(root, plan->righttree); + set_plan_references(plan->lefttree, rtable); + set_plan_references(plan->righttree, rtable); foreach(pl, plan->initPlan) { SubPlan *sp = (SubPlan *) lfirst(pl); Assert(IsA(sp, SubPlan)); - set_plan_references(root, sp->plan); + set_plan_references(sp->plan, sp->rtable); } foreach(pl, plan->subPlan) { SubPlan *sp = (SubPlan *) lfirst(pl); Assert(IsA(sp, SubPlan)); - set_plan_references(root, sp->plan); + set_plan_references(sp->plan, sp->rtable); } } @@ -269,10 +277,11 @@ fix_expr_references(Plan *plan, Node *node) * creation of a plan node by createplan.c and its fixing by this module. * Fortunately, there doesn't seem to be any need to do that. * - * 'join' is a join plan node + * 'join' is a join plan node + * 'rtable' is the associated range table */ static void -set_join_references(Query *root, Join *join) +set_join_references(Join *join, List *rtable) { Plan *outer = join->plan.lefttree; Plan *inner = join->plan.righttree; @@ -280,7 +289,7 @@ set_join_references(Query *root, Join *join) List *inner_tlist = ((inner == NULL) ? NIL : inner->targetlist); join->plan.targetlist = join_references(join->plan.targetlist, - root, + rtable, outer_tlist, inner_tlist, (Index) 0); @@ -374,6 +383,7 @@ set_uppernode_references(Plan *plan, Index subvarno) * pass inner_tlist = NIL and acceptable_rel = the ID of the inner relation. * * 'clauses' is the targetlist or list of join clauses + * 'rtable' is the current range table * 'outer_tlist' is the target list of the outer join relation * 'inner_tlist' is the target list of the inner join relation, or NIL * 'acceptable_rel' is either zero or the rangetable index of a relation @@ -384,14 +394,14 @@ set_uppernode_references(Plan *plan, Index subvarno) */ List * join_references(List *clauses, - Query *root, + List *rtable, List *outer_tlist, List *inner_tlist, Index acceptable_rel) { join_references_context context; - context.root = root; + context.rtable = rtable; context.outer_tlist = outer_tlist; context.inner_tlist = inner_tlist; context.acceptable_rel = acceptable_rel; @@ -432,7 +442,7 @@ join_references_mutator(Node *node, /* Perhaps it's a join alias that can be resolved to input vars? */ newnode = flatten_join_alias_vars((Node *) var, - context->root, + context->rtable, true); if (!equal(newnode, (Node *) var)) { diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index ee861c3557..2bdb23897c 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.36 2002/04/28 19:54:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.37 2002/05/18 02:25:50 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,7 +41,7 @@ typedef struct typedef struct { - Query *root; + List *rtable; bool force; } flatten_join_alias_vars_context; @@ -328,11 +328,11 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context) * of sublinks to subplans! */ Node * -flatten_join_alias_vars(Node *node, Query *root, bool force) +flatten_join_alias_vars(Node *node, List *rtable, bool force) { flatten_join_alias_vars_context context; - context.root = root; + context.rtable = rtable; context.force = force; return flatten_join_alias_vars_mutator(node, &context); @@ -352,7 +352,7 @@ flatten_join_alias_vars_mutator(Node *node, if (var->varlevelsup != 0) return node; /* no need to copy, really */ - rte = rt_fetch(var->varno, context->root->rtable); + rte = rt_fetch(var->varno, context->rtable); if (rte->rtekind != RTE_JOIN) return node; Assert(var->varattno > 0); diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 3956555a2e..29319a1485 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: planmain.h,v 1.56 2002/04/28 19:54:28 tgl Exp $ + * $Id: planmain.h,v 1.57 2002/05/18 02:25:50 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -56,8 +56,8 @@ extern void process_implied_equality(Query *root, Node *item1, Node *item2, /* * prototypes for plan/setrefs.c */ -extern void set_plan_references(Query *root, Plan *plan); -extern List *join_references(List *clauses, Query *root, +extern void set_plan_references(Plan *plan, List *rtable); +extern List *join_references(List *clauses, List *rtable, List *outer_tlist, List *inner_tlist, Index acceptable_rel); extern void fix_opids(Node *node); diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h index c9a22b8f55..0ae554bc3e 100644 --- a/src/include/optimizer/var.h +++ b/src/include/optimizer/var.h @@ -7,14 +7,14 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: var.h,v 1.19 2002/04/28 19:54:28 tgl Exp $ + * $Id: var.h,v 1.20 2002/05/18 02:25:50 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef VAR_H #define VAR_H -#include "nodes/parsenodes.h" +#include "nodes/primnodes.h" extern List *pull_varnos(Node *node); @@ -23,6 +23,6 @@ extern bool contain_var_reference(Node *node, int varno, int varattno, extern bool contain_whole_tuple_var(Node *node, int varno, int levelsup); extern bool contain_var_clause(Node *node); extern List *pull_var_clause(Node *node, bool includeUpperVars); -extern Node *flatten_join_alias_vars(Node *node, Query *root, bool force); +extern Node *flatten_join_alias_vars(Node *node, List *rtable, bool force); #endif /* VAR_H */