*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
* 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)
ListCell *l;
int attrno,
numattrs;
+ List *colvars;
switch (rte->rtekind)
{
{
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),
}
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",