* allpaths.c
* Routines to find possible search paths for processing a query
*
- * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
#include <math.h>
+#include "catalog/pg_class.h"
#include "nodes/nodeFuncs.h"
#ifdef OPTIMIZER_DEBUG
#include "nodes/print.h"
#include "parser/parse_clause.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
+#include "utils/lsyscache.h"
/* These parameters are set by GUC */
RangeTblEntry *rte);
static void set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel,
RangeTblEntry *rte);
+static void set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel,
+ RangeTblEntry *rte);
static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist);
static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery,
bool *differentTypes);
}
else
{
- /* Plain relation */
Assert(rel->rtekind == RTE_RELATION);
- set_plain_rel_pathlist(root, rel, rte);
+ if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
+ {
+ /* Foreign table */
+ set_foreign_pathlist(root, rel, rte);
+ }
+ else
+ {
+ /* Plain relation */
+ set_plain_rel_pathlist(root, rel, rte);
+ }
}
#ifdef OPTIMIZER_DEBUG
rel->subrtable = subroot->parse->rtable;
rel->subrowmark = subroot->rowMarks;
- /* Copy number of output rows from subplan */
- rel->tuples = rel->subplan->plan_rows;
-
/* Mark rel with estimated output rows, width, etc */
- set_baserel_size_estimates(root, rel);
+ set_subquery_size_estimates(root, rel, subroot);
/* Convert subquery pathkeys to outer representation */
pathkeys = convert_subquery_pathkeys(root, rel, subroot->query_pathkeys);
set_cheapest(rel);
}
+/*
+ * set_foreign_pathlist
+ * Build the (single) access path for a foreign table RTE
+ */
+static void
+set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
+{
+ /* Mark rel with estimated output rows, width, etc */
+ set_foreign_size_estimates(root, rel);
+
+ /* Generate appropriate path */
+ add_path(rel, (Path *) create_foreignscan_path(root, rel));
+
+ /* Select cheapest path (pretty easy in this case...) */
+ set_cheapest(rel);
+}
+
/*
* make_rel_from_joinlist
* Build access paths using a "joinlist" to guide the join path search.
case T_TidPath:
ptype = "TidScan";
break;
+ case T_ForeignPath:
+ ptype = "ForeignScan";
+ break;
case T_AppendPath:
ptype = "Append";
break;