]> granicus.if.org Git - postgresql/commitdiff
Add support for FUNCTION RTEs to build_physical_tlist(), so that the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 May 2005 18:55:49 +0000 (18:55 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 May 2005 18:55:49 +0000 (18:55 +0000)
physical-tlist optimization can be applied to FunctionScan nodes as well
as regular tables and SubqueryScans.

src/backend/optimizer/plan/createplan.c
src/backend/optimizer/util/plancat.c

index 930355b5204d5d37a59e766f268a8e57a15c16e3..b743c8348ed68e40a2b105b8f9beb9e8f86d8495 100644 (file)
@@ -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
index 3520ac96077be850ef113ece8bb834c14b97aa9b..35277073569e3ab3f2f81bf0ef97cbd54d3424d6 100644 (file)
@@ -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",