From ac25dbd84bbcc288fc93f4053b6df4b848cf5bc6 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 30 May 2005 18:55:49 +0000 Subject: [PATCH] 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. --- src/backend/optimizer/plan/createplan.c | 14 ++++++---- src/backend/optimizer/util/plancat.c | 37 +++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 930355b520..b743c8348e 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * 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) int i; /* - * OK for subquery scans, but not function scans. (This is mainly - * because build_physical_tlist doesn't support them; worth adding?) + * OK for subquery and function scans; otherwise, can't do it for + * anything except real relations. */ - if (rel->rtekind == RTE_SUBQUERY) - return true; if (rel->rtekind != RTE_RELATION) + { + if (rel->rtekind == RTE_SUBQUERY) + return true; + if (rel->rtekind == RTE_FUNCTION) + return true; return false; + } /* * Can't do it with inheritance cases either (mainly because Append diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 3520ac9607..3527707356 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * 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 @@ #include "optimizer/tlist.h" #include "parser/parsetree.h" #include "parser/parse_expr.h" +#include "parser/parse_relation.h" #include "rewrite/rewriteManip.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -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 * dropped cols. * - * We also support building a "physical" tlist for subqueries, since the - * same optimization can occur in SubqueryScan nodes. + * We also support building a "physical" tlist for subqueries and functions, + * since the same optimization can occur in SubqueryScan and FunctionScan + * nodes. */ List * build_physical_tlist(Query *root, RelOptInfo *rel) @@ -388,6 +390,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel) ListCell *l; int attrno, numattrs; + List *colvars; switch (rte->rtekind) { @@ -429,6 +432,10 @@ build_physical_tlist(Query *root, RelOptInfo *rel) { 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, tle->resno, exprType((Node *) tle->expr), @@ -443,6 +450,30 @@ build_physical_tlist(Query *root, RelOptInfo *rel) } 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: /* caller error */ elog(ERROR, "unsupported RTE kind %d in build_physical_tlist", -- 2.40.0