Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita5b3709

Browse files
committed
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 inthe arguments of a function RTE. Install check to prevent function RTEsfrom cross-referencing Vars of sibling FROM-items, which doesn't makeany sense (if you want to join, write a JOIN or WHERE clause).
1 parent2c50f63 commita5b3709

File tree

5 files changed

+85
-39
lines changed

5 files changed

+85
-39
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.118 2002/05/1802:25:49 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.119 2002/05/1818:49:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -246,7 +246,7 @@ subquery_planner(Query *parse, double tuple_fraction)
246246
*/
247247
if (PlannerPlanId!=saved_planid||PlannerQueryLevel>1)
248248
{
249-
(void)SS_finalize_plan(plan);
249+
(void)SS_finalize_plan(plan,parse->rtable);
250250

251251
/*
252252
* At the moment, SS_finalize_plan doesn't handle initPlans and so

‎src/backend/optimizer/plan/subselect.c

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.52 2002/05/12 20:10:03 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.53 2002/05/18 18:49:41 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,6 +21,7 @@
2121
#include"optimizer/planmain.h"
2222
#include"optimizer/planner.h"
2323
#include"optimizer/subselect.h"
24+
#include"parser/parsetree.h"
2425
#include"parser/parse_expr.h"
2526
#include"parser/parse_oper.h"
2627
#include"utils/syscache.h"
@@ -586,7 +587,7 @@ process_sublinks_mutator(Node *node, void *context)
586587
}
587588

588589
List*
589-
SS_finalize_plan(Plan*plan)
590+
SS_finalize_plan(Plan*plan,List*rtable)
590591
{
591592
List*extParam=NIL;
592593
List*locParam=NIL;
@@ -619,10 +620,20 @@ SS_finalize_plan(Plan *plan)
619620
&results);
620621
break;
621622

622-
caseT_Append:
623-
foreach(lst, ((Append*)plan)->appendplans)
624-
results.paramids=set_unioni(results.paramids,
625-
SS_finalize_plan((Plan*)lfirst(lst)));
623+
caseT_IndexScan:
624+
finalize_primnode((Node*) ((IndexScan*)plan)->indxqual,
625+
&results);
626+
627+
/*
628+
* we need not look at indxqualorig, since it will have the
629+
* same param references as indxqual, and we aren't really
630+
* concerned yet about having a complete subplan list.
631+
*/
632+
break;
633+
634+
caseT_TidScan:
635+
finalize_primnode((Node*) ((TidScan*)plan)->tideval,
636+
&results);
626637
break;
627638

628639
caseT_SubqueryScan:
@@ -638,15 +649,22 @@ SS_finalize_plan(Plan *plan)
638649
((SubqueryScan*)plan)->subplan->extParam);
639650
break;
640651

641-
caseT_IndexScan:
642-
finalize_primnode((Node*) ((IndexScan*)plan)->indxqual,
643-
&results);
652+
caseT_FunctionScan:
653+
{
654+
RangeTblEntry*rte;
644655

645-
/*
646-
* we need not look at indxqualorig, since it will have the
647-
* same param references as indxqual, and we aren't really
648-
* concerned yet about having a complete subplan list.
649-
*/
656+
rte=rt_fetch(((FunctionScan*)plan)->scan.scanrelid,
657+
rtable);
658+
Assert(rte->rtekind==RTE_FUNCTION);
659+
finalize_primnode(rte->funcexpr,&results);
660+
}
661+
break;
662+
663+
caseT_Append:
664+
foreach(lst, ((Append*)plan)->appendplans)
665+
results.paramids=set_unioni(results.paramids,
666+
SS_finalize_plan((Plan*)lfirst(lst),
667+
rtable));
650668
break;
651669

652670
caseT_NestLoop:
@@ -673,11 +691,6 @@ SS_finalize_plan(Plan *plan)
673691
&results);
674692
break;
675693

676-
caseT_TidScan:
677-
finalize_primnode((Node*) ((TidScan*)plan)->tideval,
678-
&results);
679-
break;
680-
681694
caseT_Agg:
682695
caseT_SeqScan:
683696
caseT_Material:
@@ -686,7 +699,6 @@ SS_finalize_plan(Plan *plan)
686699
caseT_SetOp:
687700
caseT_Limit:
688701
caseT_Group:
689-
caseT_FunctionScan:
690702
break;
691703

692704
default:
@@ -696,9 +708,11 @@ SS_finalize_plan(Plan *plan)
696708

697709
/* Process left and right subplans, if any */
698710
results.paramids=set_unioni(results.paramids,
699-
SS_finalize_plan(plan->lefttree));
711+
SS_finalize_plan(plan->lefttree,
712+
rtable));
700713
results.paramids=set_unioni(results.paramids,
701-
SS_finalize_plan(plan->righttree));
714+
SS_finalize_plan(plan->righttree,
715+
rtable));
702716

703717
/* Now we have all the paramids and subplans */
704718

‎src/backend/optimizer/util/clauses.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.99 2002/05/12 23:43:03 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.100 2002/05/18 18:49:41 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -1915,7 +1915,6 @@ query_tree_walker(Query *query,
19151915
{
19161916
caseRTE_RELATION:
19171917
caseRTE_SPECIAL:
1918-
caseRTE_FUNCTION:
19191918
/* nothing to do */
19201919
break;
19211920
caseRTE_SUBQUERY:
@@ -1927,6 +1926,10 @@ query_tree_walker(Query *query,
19271926
if (walker(rte->joinaliasvars,context))
19281927
return true;
19291928
break;
1929+
caseRTE_FUNCTION:
1930+
if (walker(rte->funcexpr,context))
1931+
return true;
1932+
break;
19301933
}
19311934
}
19321935
return false;
@@ -2293,7 +2296,6 @@ query_tree_mutator(Query *query,
22932296
{
22942297
caseRTE_RELATION:
22952298
caseRTE_SPECIAL:
2296-
caseRTE_FUNCTION:
22972299
/* nothing to do, don't bother to make a copy */
22982300
break;
22992301
caseRTE_SUBQUERY:
@@ -2310,6 +2312,11 @@ query_tree_mutator(Query *query,
23102312
MUTATE(newrte->joinaliasvars,rte->joinaliasvars,List*);
23112313
rte=newrte;
23122314
break;
2315+
caseRTE_FUNCTION:
2316+
FLATCOPY(newrte,rte,RangeTblEntry);
2317+
MUTATE(newrte->funcexpr,rte->funcexpr,Node*);
2318+
rte=newrte;
2319+
break;
23132320
}
23142321
newrt=lappend(newrt,rte);
23152322
}

‎src/backend/parser/parse_clause.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.92 2002/05/12 23:43:03 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.93 2002/05/18 18:49:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -410,7 +410,9 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
410410
*/
411411
save_namespace=pstate->p_namespace;
412412
pstate->p_namespace=NIL;
413+
413414
parsetrees=parse_analyze(r->subquery,pstate);
415+
414416
pstate->p_namespace=save_namespace;
415417

416418
/*
@@ -455,26 +457,49 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
455457
{
456458
Node*funcexpr;
457459
char*funcname;
460+
List*save_namespace;
458461
RangeTblEntry*rte;
459462
RangeTblRef*rtr;
460463

464+
/* Get function name for possible use as alias */
465+
Assert(IsA(r->funccallnode,FuncCall));
466+
funcname=strVal(llast(((FuncCall*)r->funccallnode)->funcname));
467+
461468
/*
462-
* Transform the raw FuncCall node
469+
* Transform the raw FuncCall node. This is a bit tricky because we don't
470+
* want the function expression to be able to see any FROM items already
471+
* created in the current query (compare to transformRangeSubselect).
472+
* But it does need to be able to see any further-up parent states.
473+
* So, temporarily make the current query level have an empty namespace.
474+
* NOTE: this code is OK only because the expression can't legally alter
475+
* the namespace by causing implicit relation refs to be added.
463476
*/
477+
save_namespace=pstate->p_namespace;
478+
pstate->p_namespace=NIL;
479+
464480
funcexpr=transformExpr(pstate,r->funccallnode);
465481

466-
Assert(IsA(r->funccallnode,FuncCall));
467-
funcname=strVal(llast(((FuncCall*)r->funccallnode)->funcname));
482+
pstate->p_namespace=save_namespace;
483+
484+
/*
485+
* We still need to check that the function parameters don't refer
486+
* to any other rels. That could happen despite our hack on the namespace
487+
* if fully-qualified names are used. So, check there are no local
488+
* Var references in the transformed expression. (Outer references
489+
* are OK, and are ignored here.)
490+
*/
491+
if (pull_varnos(funcexpr)!=NIL)
492+
elog(ERROR,"FROM function expression may not refer to other relations of same query level");
468493

469494
/*
470-
* Disallow aggregate functions and subselects in the expression.
471-
* (Aggregates clearly make no sense; perhaps later we could support
472-
* subselects, though.)
495+
* Disallow aggregate functions in the expression. (No reason to postpone
496+
* this check until parseCheckAggregates.)
473497
*/
474-
if (contain_agg_clause(funcexpr))
475-
elog(ERROR,"cannot use aggregate function in FROM function expression");
476-
if (contain_subplans(funcexpr))
477-
elog(ERROR,"cannot use subselect in FROM function expression");
498+
if (pstate->p_hasAggs)
499+
{
500+
if (contain_agg_clause(funcexpr))
501+
elog(ERROR,"cannot use aggregate function in FROM function expression");
502+
}
478503

479504
/*
480505
* Insist we have a bare function call (explain.c is the only place

‎src/include/optimizer/subselect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extern List *PlannerInitPlan;/* init subplans for current query */
1414
externList*PlannerParamVar;/* to get Var from Param->paramid */
1515
externintPlannerPlanId;/* to assign unique ID to subquery plans */
1616

17-
externList*SS_finalize_plan(Plan*plan);
17+
externList*SS_finalize_plan(Plan*plan,List*rtable);
1818
externNode*SS_replace_correlation_vars(Node*expr);
1919
externNode*SS_process_sublinks(Node*expr);
2020

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp