aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/allpaths.c5
-rw-r--r--src/backend/optimizer/plan/createplan.c37
-rw-r--r--src/backend/optimizer/plan/planmain.c7
-rw-r--r--src/backend/optimizer/plan/planner.c63
-rw-r--r--src/backend/optimizer/plan/subselect.c28
-rw-r--r--src/backend/optimizer/prep/prepjointree.c5
-rw-r--r--src/backend/optimizer/prep/prepunion.c5
-rw-r--r--src/backend/optimizer/util/clauses.c3
8 files changed, 81 insertions, 72 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 99d979d57c0..0bf43cab24d 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.98 2003/03/05 20:01:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.99 2003/03/10 03:53:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -343,8 +343,7 @@ set_subquery_pathlist(Query *root, RelOptInfo *rel,
}
/* Generate the plan for the subquery */
- rel->subplan = subquery_planner(subquery,
- -1.0 /* default case */ );
+ rel->subplan = subquery_planner(subquery, 0.0 /* default case */ );
/* Copy number of output rows from subplan */
rel->tuples = rel->subplan->plan_rows;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index bfc11aa0046..d01acdc6182 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.137 2003/02/16 06:06:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.138 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1827,6 +1827,41 @@ make_material(List *tlist, Plan *lefttree)
return node;
}
+/*
+ * materialize_finished_plan: stick a Material node atop a completed plan
+ *
+ * There are a couple of places where we want to attach a Material node
+ * after completion of subquery_planner(). This currently requires hackery.
+ * Since subquery_planner has already run SS_finalize_plan on the subplan
+ * tree, we have to kluge up parameter lists for the Material node.
+ * Possibly this could be fixed by postponing SS_finalize_plan processing
+ * until setrefs.c is run?
+ */
+Plan *
+materialize_finished_plan(Plan *subplan)
+{
+ Plan *matplan;
+ Path matpath; /* dummy for result of cost_material */
+
+ matplan = (Plan *) make_material(subplan->targetlist, subplan);
+
+ /* Set cost data */
+ cost_material(&matpath,
+ subplan->total_cost,
+ subplan->plan_rows,
+ subplan->plan_width);
+ matplan->startup_cost = matpath.startup_cost;
+ matplan->total_cost = matpath.total_cost;
+ matplan->plan_rows = subplan->plan_rows;
+ matplan->plan_width = subplan->plan_width;
+
+ /* parameter kluge --- see comments above */
+ matplan->extParam = bms_copy(subplan->extParam);
+ matplan->allParam = bms_copy(subplan->allParam);
+
+ return matplan;
+}
+
Agg *
make_agg(Query *root, List *tlist, List *qual,
AggStrategy aggstrategy,
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index daa840f789e..97f6b76a8e4 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.74 2003/01/20 18:54:52 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.75 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,14 +61,11 @@
* indxpath.c need to see it.)
*
* tuple_fraction is interpreted as follows:
- * 0 (or less): expect all tuples to be retrieved (normal case)
+ * 0: expect all tuples to be retrieved (normal case)
* 0 < tuple_fraction < 1: expect the given fraction of tuples available
* from the plan to be retrieved
* tuple_fraction >= 1: tuple_fraction is the absolute number of tuples
* expected to be retrieved (ie, a LIMIT specification)
- * Note that while this routine and its subroutines treat a negative
- * tuple_fraction the same as 0, grouping_planner has a different
- * interpretation.
*--------------------
*/
void
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index c7c072fe2eb..9fa78b8a237 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.150 2003/03/05 20:01:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.151 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,6 +19,7 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
+#include "executor/executor.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#ifdef OPTIMIZER_DEBUG
@@ -73,8 +74,9 @@ static List *postprocess_setop_tlist(List *new_tlist, List *orig_tlist);
*
*****************************************************************************/
Plan *
-planner(Query *parse)
+planner(Query *parse, bool isCursor, int cursorOptions)
{
+ double tuple_fraction;
Plan *result_plan;
Index save_PlannerQueryLevel;
List *save_PlannerParamVar;
@@ -99,11 +101,38 @@ planner(Query *parse)
PlannerQueryLevel = 0; /* will be 1 in top-level subquery_planner */
PlannerParamVar = NIL;
+ /* Determine what fraction of the plan is likely to be scanned */
+ if (isCursor)
+ {
+ /*
+ * We have no real idea how many tuples the user will ultimately
+ * FETCH from a cursor, but it seems a good bet that he
+ * doesn't want 'em all. Optimize for 10% retrieval (you
+ * gotta better number? Should this be a SETtable parameter?)
+ */
+ tuple_fraction = 0.10;
+ }
+ else
+ {
+ /* Default assumption is we need all the tuples */
+ tuple_fraction = 0.0;
+ }
+
/* primary planning entry point (may recurse for subqueries) */
- result_plan = subquery_planner(parse, -1.0 /* default case */ );
+ result_plan = subquery_planner(parse, tuple_fraction);
Assert(PlannerQueryLevel == 0);
+ /*
+ * If creating a plan for a scrollable cursor, make sure it can
+ * run backwards on demand. Add a Material node at the top at need.
+ */
+ if (isCursor && (cursorOptions & CURSOR_OPT_SCROLL))
+ {
+ if (!ExecSupportsBackwardScan(result_plan))
+ result_plan = materialize_finished_plan(result_plan);
+ }
+
/* executor wants to know total number of Params used overall */
result_plan->nParamExec = length(PlannerParamVar);
@@ -505,14 +534,11 @@ inheritance_planner(Query *parse, List *inheritlist)
* tuple_fraction is the fraction of tuples we expect will be retrieved
*
* tuple_fraction is interpreted as follows:
- * < 0: determine fraction by inspection of query (normal case)
- * 0: expect all tuples to be retrieved
+ * 0: expect all tuples to be retrieved (normal case)
* 0 < tuple_fraction < 1: expect the given fraction of tuples available
* from the plan to be retrieved
* tuple_fraction >= 1: tuple_fraction is the absolute number of tuples
* expected to be retrieved (ie, a LIMIT specification)
- * The normal case is to pass -1, but some callers pass values >= 0 to
- * override this routine's determination of the appropriate fraction.
*
* Returns a query plan. Also, parse->query_pathkeys is returned as the
* actual output ordering of the plan (in pathkey format).
@@ -694,29 +720,6 @@ grouping_planner(Query *parse, double tuple_fraction)
parse->query_pathkeys = NIL;
/*
- * Figure out whether we expect to retrieve all the tuples that
- * the plan can generate, or to stop early due to outside factors
- * such as a cursor. If the caller passed a value >= 0, believe
- * that value, else do our own examination of the query context.
- */
- if (tuple_fraction < 0.0)
- {
- /* Initial assumption is we need all the tuples */
- tuple_fraction = 0.0;
-
- /*
- * Check for retrieve-into-portal, ie DECLARE CURSOR.
- *
- * We have no real idea how many tuples the user will ultimately
- * FETCH from a cursor, but it seems a good bet that he
- * doesn't want 'em all. Optimize for 10% retrieval (you
- * gotta better number? Should this be a SETtable parameter?)
- */
- if (parse->isPortal)
- tuple_fraction = 0.10;
- }
-
- /*
* Adjust tuple_fraction if we see that we are going to apply
* limiting/grouping/aggregation/etc. This is not overridable by
* the caller, since it reflects plan actions that this routine
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index fc428977c33..417eecc1fe3 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.72 2003/02/09 06:56:27 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.73 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -222,7 +222,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
slink->subLinkType == ANY_SUBLINK)
tuple_fraction = 0.5; /* 50% */
else
- tuple_fraction = -1.0; /* default behavior */
+ tuple_fraction = 0.0; /* default behavior */
/*
* Generate the plan for the subquery.
@@ -336,12 +336,6 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
* is anything more complicated than a plain sequential scan, and we
* do it even for seqscan if the qual appears selective enough to
* eliminate many tuples.
- *
- * XXX It's pretty ugly to be inserting a MATERIAL node at this
- * point. Since subquery_planner has already run SS_finalize_plan
- * on the subplan tree, we have to kluge up parameter lists for
- * the MATERIAL node. Possibly this could be fixed by postponing
- * SS_finalize_plan processing until setrefs.c is run.
*/
else if (node->parParam == NIL)
{
@@ -380,23 +374,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
}
if (use_material)
{
- Plan *matplan;
- Path matpath; /* dummy for result of cost_material */
-
- matplan = (Plan *) make_material(plan->targetlist, plan);
- /* need to calculate costs */
- cost_material(&matpath,
- plan->total_cost,
- plan->plan_rows,
- plan->plan_width);
- matplan->startup_cost = matpath.startup_cost;
- matplan->total_cost = matpath.total_cost;
- matplan->plan_rows = plan->plan_rows;
- matplan->plan_width = plan->plan_width;
- /* parameter kluge --- see comments above */
- matplan->extParam = bms_copy(plan->extParam);
- matplan->allParam = bms_copy(plan->allParam);
- node->plan = plan = matplan;
+ node->plan = plan = materialize_finished_plan(plan);
}
}
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 207a813e8e0..a265623bfb7 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -16,7 +16,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.6 2003/02/10 17:08:50 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.7 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -362,8 +362,7 @@ is_simple_subquery(Query *subquery)
if (!IsA(subquery, Query) ||
subquery->commandType != CMD_SELECT ||
subquery->resultRelation != 0 ||
- subquery->into != NULL ||
- subquery->isPortal)
+ subquery->into != NULL)
elog(ERROR, "is_simple_subquery: subquery is bogus");
/*
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index f0a64f2980c..1782bcc88b9 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.91 2003/03/05 20:01:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.92 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -134,8 +134,7 @@ recurse_set_operations(Node *setOp, Query *parse,
/*
* Generate plan for primitive subquery
*/
- subplan = subquery_planner(subquery,
- -1.0 /* default case */ );
+ subplan = subquery_planner(subquery, 0.0 /* default case */ );
/*
* Add a SubqueryScan with the caller-requested targetlist
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 40e440a3754..fcd58374189 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.130 2003/02/16 02:30:38 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.131 2003/03/10 03:53:50 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1787,7 +1787,6 @@ inline_function(Oid funcid, List *args, HeapTuple func_tuple,
querytree->commandType != CMD_SELECT ||
querytree->resultRelation != 0 ||
querytree->into ||
- querytree->isPortal ||
querytree->hasAggs ||
querytree->hasSubLinks ||
querytree->rtable ||