*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/* 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);
TidScan *innerscan = (TidScan *) inner_plan;
innerscan->tideval = join_references(innerscan->tideval,
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
innerscan->scan.scanrelid);
* 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);
* clauses to contain INNER/OUTER var references.
*/
joinclauses = join_references(set_difference(joinclauses, mergeclauses),
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0);
* Fix the additional qpquals too.
*/
otherclauses = join_references(otherclauses,
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0);
* that the outer variable is always on the left.
*/
mergeclauses = switch_outer(join_references(mergeclauses,
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0));
* clauses to contain INNER/OUTER var references.
*/
joinclauses = join_references(set_difference(joinclauses, hashclauses),
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0);
* Fix the additional qpquals too.
*/
otherclauses = join_references(otherclauses,
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0);
* that the outer variable is always on the left.
*/
hashclauses = switch_outer(join_references(hashclauses,
- root,
+ root->rtable,
outer_tlist,
inner_tlist,
(Index) 0));
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
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
}
}
if (has_join_rtes)
- expr = flatten_join_alias_vars(expr, parse, false);
+ expr = flatten_join_alias_vars(expr, parse->rtable, false);
return expr;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
typedef struct
{
- Query *root;
+ List *rtable;
List *outer_tlist;
List *inner_tlist;
Index acceptable_rel;
} 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);
* 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;
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:
{
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);
(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);
* 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",
* 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);
}
}
* 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;
List *inner_tlist = ((inner == NULL) ? NIL : inner->targetlist);
join->plan.targetlist = join_references(join->plan.targetlist,
- root,
+ rtable,
outer_tlist,
inner_tlist,
(Index) 0);
* 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
*/
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;
/* 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))
{