1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Teach query_tree_walker, query_tree_mutator, and SS_finalize_plan to

process function RTE expressions, which they were previously missing.
This allows outer-Var references and subselects to work correctly in
the arguments of a function RTE.  Install check to prevent function RTEs
from cross-referencing Vars of sibling FROM-items, which doesn't make
any sense (if you want to join, write a JOIN or WHERE clause).
This commit is contained in:
Tom Lane
2002-05-18 18:49:41 +00:00
parent 2c50f6344b
commit a5b370943e
5 changed files with 87 additions and 41 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.118 2002/05/18 02:25:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.119 2002/05/18 18:49:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -246,7 +246,7 @@ subquery_planner(Query *parse, double tuple_fraction)
*/
if (PlannerPlanId != saved_planid || PlannerQueryLevel > 1)
{
(void) SS_finalize_plan(plan);
(void) SS_finalize_plan(plan, parse->rtable);
/*
* At the moment, SS_finalize_plan doesn't handle initPlans and so

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.52 2002/05/12 20:10:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.53 2002/05/18 18:49:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,7 @@
#include "optimizer/planmain.h"
#include "optimizer/planner.h"
#include "optimizer/subselect.h"
#include "parser/parsetree.h"
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
#include "utils/syscache.h"
@@ -586,7 +587,7 @@ process_sublinks_mutator(Node *node, void *context)
}
List *
SS_finalize_plan(Plan *plan)
SS_finalize_plan(Plan *plan, List *rtable)
{
List *extParam = NIL;
List *locParam = NIL;
@@ -619,10 +620,20 @@ SS_finalize_plan(Plan *plan)
&results);
break;
case T_Append:
foreach(lst, ((Append *) plan)->appendplans)
results.paramids = set_unioni(results.paramids,
SS_finalize_plan((Plan *) lfirst(lst)));
case T_IndexScan:
finalize_primnode((Node *) ((IndexScan *) plan)->indxqual,
&results);
/*
* we need not look at indxqualorig, since it will have the
* same param references as indxqual, and we aren't really
* concerned yet about having a complete subplan list.
*/
break;
case T_TidScan:
finalize_primnode((Node *) ((TidScan *) plan)->tideval,
&results);
break;
case T_SubqueryScan:
@@ -638,15 +649,22 @@ SS_finalize_plan(Plan *plan)
((SubqueryScan *) plan)->subplan->extParam);
break;
case T_IndexScan:
finalize_primnode((Node *) ((IndexScan *) plan)->indxqual,
&results);
case T_FunctionScan:
{
RangeTblEntry *rte;
/*
* we need not look at indxqualorig, since it will have the
* same param references as indxqual, and we aren't really
* concerned yet about having a complete subplan list.
*/
rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,
rtable);
Assert(rte->rtekind == RTE_FUNCTION);
finalize_primnode(rte->funcexpr, &results);
}
break;
case T_Append:
foreach(lst, ((Append *) plan)->appendplans)
results.paramids = set_unioni(results.paramids,
SS_finalize_plan((Plan *) lfirst(lst),
rtable));
break;
case T_NestLoop:
@@ -673,11 +691,6 @@ SS_finalize_plan(Plan *plan)
&results);
break;
case T_TidScan:
finalize_primnode((Node *) ((TidScan *) plan)->tideval,
&results);
break;
case T_Agg:
case T_SeqScan:
case T_Material:
@@ -686,7 +699,6 @@ SS_finalize_plan(Plan *plan)
case T_SetOp:
case T_Limit:
case T_Group:
case T_FunctionScan:
break;
default:
@@ -696,9 +708,11 @@ SS_finalize_plan(Plan *plan)
/* Process left and right subplans, if any */
results.paramids = set_unioni(results.paramids,
SS_finalize_plan(plan->lefttree));
SS_finalize_plan(plan->lefttree,
rtable));
results.paramids = set_unioni(results.paramids,
SS_finalize_plan(plan->righttree));
SS_finalize_plan(plan->righttree,
rtable));
/* Now we have all the paramids and subplans */

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.99 2002/05/12 23:43:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.100 2002/05/18 18:49:41 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1915,7 +1915,6 @@ query_tree_walker(Query *query,
{
case RTE_RELATION:
case RTE_SPECIAL:
case RTE_FUNCTION:
/* nothing to do */
break;
case RTE_SUBQUERY:
@@ -1927,6 +1926,10 @@ query_tree_walker(Query *query,
if (walker(rte->joinaliasvars, context))
return true;
break;
case RTE_FUNCTION:
if (walker(rte->funcexpr, context))
return true;
break;
}
}
return false;
@@ -2293,7 +2296,6 @@ query_tree_mutator(Query *query,
{
case RTE_RELATION:
case RTE_SPECIAL:
case RTE_FUNCTION:
/* nothing to do, don't bother to make a copy */
break;
case RTE_SUBQUERY:
@@ -2310,6 +2312,11 @@ query_tree_mutator(Query *query,
MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
rte = newrte;
break;
case RTE_FUNCTION:
FLATCOPY(newrte, rte, RangeTblEntry);
MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
rte = newrte;
break;
}
newrt = lappend(newrt, rte);
}