Commit ac25dbd8 authored by Tom Lane's avatar Tom Lane

Add support for FUNCTION RTEs to build_physical_tlist(), so that the

physical-tlist optimization can be applied to FunctionScan nodes as well
as regular tables and SubqueryScans.
parent 3e8dbc84
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.189 2005/05/22 22:30:19 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.190 2005/05/30 18:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -308,13 +308,17 @@ use_physical_tlist(RelOptInfo *rel) ...@@ -308,13 +308,17 @@ use_physical_tlist(RelOptInfo *rel)
int i; int i;
/* /*
* OK for subquery scans, but not function scans. (This is mainly * OK for subquery and function scans; otherwise, can't do it for
* because build_physical_tlist doesn't support them; worth adding?) * anything except real relations.
*/ */
if (rel->rtekind == RTE_SUBQUERY)
return true;
if (rel->rtekind != RTE_RELATION) if (rel->rtekind != RTE_RELATION)
{
if (rel->rtekind == RTE_SUBQUERY)
return true;
if (rel->rtekind == RTE_FUNCTION)
return true;
return false; return false;
}
/* /*
* Can't do it with inheritance cases either (mainly because Append * Can't do it with inheritance cases either (mainly because Append
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.108 2005/05/23 03:01:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.109 2005/05/30 18:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "rewrite/rewriteManip.h" #include "rewrite/rewriteManip.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
...@@ -373,8 +374,9 @@ estimate_rel_size(Relation rel, int32 *attr_widths, ...@@ -373,8 +374,9 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
* For now, we don't apply the physical-tlist optimization when there are * For now, we don't apply the physical-tlist optimization when there are
* dropped cols. * dropped cols.
* *
* We also support building a "physical" tlist for subqueries, since the * We also support building a "physical" tlist for subqueries and functions,
* same optimization can occur in SubqueryScan nodes. * since the same optimization can occur in SubqueryScan and FunctionScan
* nodes.
*/ */
List * List *
build_physical_tlist(Query *root, RelOptInfo *rel) build_physical_tlist(Query *root, RelOptInfo *rel)
...@@ -388,6 +390,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel) ...@@ -388,6 +390,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
ListCell *l; ListCell *l;
int attrno, int attrno,
numattrs; numattrs;
List *colvars;
switch (rte->rtekind) switch (rte->rtekind)
{ {
...@@ -429,6 +432,10 @@ build_physical_tlist(Query *root, RelOptInfo *rel) ...@@ -429,6 +432,10 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
{ {
TargetEntry *tle = (TargetEntry *) lfirst(l); TargetEntry *tle = (TargetEntry *) lfirst(l);
/*
* A resjunk column of the subquery can be reflected as
* resjunk in the physical tlist; we need not punt.
*/
var = makeVar(varno, var = makeVar(varno,
tle->resno, tle->resno,
exprType((Node *) tle->expr), exprType((Node *) tle->expr),
...@@ -443,6 +450,30 @@ build_physical_tlist(Query *root, RelOptInfo *rel) ...@@ -443,6 +450,30 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
} }
break; break;
case RTE_FUNCTION:
expandRTE(root->rtable, varno, 0, true /* include dropped */,
NULL, &colvars);
foreach(l, colvars)
{
var = (Var *) lfirst(l);
/*
* A non-Var in expandRTE's output means a dropped column;
* must punt.
*/
if (!IsA(var, Var))
{
tlist = NIL;
break;
}
tlist = lappend(tlist,
makeTargetEntry((Expr *) var,
var->varattno,
NULL,
false));
}
break;
default: default:
/* caller error */ /* caller error */
elog(ERROR, "unsupported RTE kind %d in build_physical_tlist", elog(ERROR, "unsupported RTE kind %d in build_physical_tlist",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment