aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-08-22 00:16:04 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-08-22 00:16:04 +0000
commitbd3daddaf232d95b0c9ba6f99b0170a0147dd8af (patch)
tree8a64067729f1154120251984e823cdfaa1b0a080 /src/include
parent8875a16ee15d6bed09b8f95e813eb74cb8d22fe9 (diff)
downloadpostgresql-bd3daddaf232d95b0c9ba6f99b0170a0147dd8af.tar.gz
postgresql-bd3daddaf232d95b0c9ba6f99b0170a0147dd8af.zip
Arrange to convert EXISTS subqueries that are equivalent to hashable IN
subqueries into the same thing you'd have gotten from IN (except always with unknownEqFalse = true, so as to get the proper semantics for an EXISTS). I believe this fixes the last case within CVS HEAD in which an EXISTS could give worse performance than an equivalent IN subquery. The tricky part of this is that if the upper query probes the EXISTS for only a few rows, the hashing implementation can actually be worse than the default, and therefore we need to make a cost-based decision about which way to use. But at the time when the planner generates plans for subqueries, it doesn't really know how many times the subquery will be executed. The least invasive solution seems to be to generate both plans and postpone the choice until execution. Therefore, in a query that has been optimized this way, EXPLAIN will show two subplans for the EXISTS, of which only one will actually get executed. There is a lot more that could be done based on this infrastructure: in particular it's interesting to consider switching to the hash plan if we start out using the non-hashed plan but find a lot more upper rows going by than we expected. I have therefore left some minor inefficiencies in place, such as initializing both subplans even though we will currently only use one.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/nodeSubplan.h8
-rw-r--r--src/include/nodes/execnodes.h13
-rw-r--r--src/include/nodes/nodes.h4
-rw-r--r--src/include/nodes/primnodes.h26
-rw-r--r--src/include/optimizer/clauses.h3
-rw-r--r--src/include/optimizer/cost.h4
-rw-r--r--src/include/rewrite/rewriteManip.h3
7 files changed, 47 insertions, 14 deletions
diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h
index c7c9f4e2dc4..7d12a54b614 100644
--- a/src/include/executor/nodeSubplan.h
+++ b/src/include/executor/nodeSubplan.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/executor/nodeSubplan.h,v 1.27 2008/01/01 19:45:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/executor/nodeSubplan.h,v 1.28 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,10 +17,8 @@
#include "nodes/execnodes.h"
extern SubPlanState *ExecInitSubPlan(SubPlan *subplan, PlanState *parent);
-extern Datum ExecSubPlan(SubPlanState *node,
- ExprContext *econtext,
- bool *isNull,
- ExprDoneCond *isDone);
+
+extern AlternativeSubPlanState *ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent);
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index ce41c750afc..ee8c4a2bef7 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.186 2008/08/07 03:04:03 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.187 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -628,6 +628,17 @@ typedef struct SubPlanState
} SubPlanState;
/* ----------------
+ * AlternativeSubPlanState node
+ * ----------------
+ */
+typedef struct AlternativeSubPlanState
+{
+ ExprState xprstate;
+ List *subplans; /* states of alternative subplans */
+ int active; /* list index of the one we're using */
+} AlternativeSubPlanState;
+
+/* ----------------
* FieldSelectState node
* ----------------
*/
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 5fdd23c5a91..b9e00bfddea 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.208 2008/08/14 18:48:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.209 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -118,6 +118,7 @@ typedef enum NodeTag
T_BoolExpr,
T_SubLink,
T_SubPlan,
+ T_AlternativeSubPlan,
T_FieldSelect,
T_FieldStore,
T_RelabelType,
@@ -160,6 +161,7 @@ typedef enum NodeTag
T_ScalarArrayOpExprState,
T_BoolExprState,
T_SubPlanState,
+ T_AlternativeSubPlanState,
T_FieldSelectState,
T_FieldStoreState,
T_CoerceViaIOState,
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index f0c55112cbc..f6da1adbfa0 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.138 2008/08/02 21:32:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.139 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -445,7 +445,8 @@ typedef struct SubLink
*
* If the sub-select becomes an initplan rather than a subplan, the executable
* expression is part of the outer plan's expression tree (and the SubPlan
- * node itself is not). In this case testexpr is NULL to avoid duplication.
+ * node itself is not, but rather is found in the outer plan's initPlan
+ * list). In this case testexpr is NULL to avoid duplication.
*
* The planner also derives lists of the values that need to be passed into
* and out of the subplan. Input values are represented as a list "args" of
@@ -457,6 +458,10 @@ typedef struct SubLink
* is an initplan; they are listed in order by sub-select output column
* position. (parParam and setParam are integer Lists, not Bitmapsets,
* because their ordering is significant.)
+ *
+ * Also, the planner computes startup and per-call costs for use of the
+ * SubPlan. Note that these include the cost of the subquery proper,
+ * evaluation of the testexpr if any, and any hashtable management overhead.
*/
typedef struct SubPlan
{
@@ -482,8 +487,25 @@ typedef struct SubPlan
* Params for parent plan */
List *parParam; /* indices of input Params from parent plan */
List *args; /* exprs to pass as parParam values */
+ /* Estimated execution costs: */
+ Cost startup_cost; /* one-time setup cost */
+ Cost per_call_cost; /* cost for each subplan evaluation */
} SubPlan;
+/*
+ * AlternativeSubPlan - expression node for a choice among SubPlans
+ *
+ * The subplans are given as a List so that the node definition need not
+ * change if there's ever more than two alternatives. For the moment,
+ * though, there are always exactly two; and the first one is the fast-start
+ * plan.
+ */
+typedef struct AlternativeSubPlan
+{
+ Expr xpr;
+ List *subplans; /* SubPlan(s) with equivalent results */
+} AlternativeSubPlan;
+
/* ----------------
* FieldSelect
*
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 41e52d909aa..1ea3d701fe9 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.92 2008/08/14 18:48:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.93 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,6 @@
#define is_opclause(clause) ((clause) != NULL && IsA(clause, OpExpr))
#define is_funcclause(clause) ((clause) != NULL && IsA(clause, FuncExpr))
-#define is_subplan(clause) ((clause) != NULL && IsA(clause, SubPlan))
typedef struct
{
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 17caeb4ee41..8ad8f7f0626 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.91 2008/08/14 18:48:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.92 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -93,9 +93,9 @@ extern void cost_mergejoin(MergePath *path, PlannerInfo *root,
SpecialJoinInfo *sjinfo);
extern void cost_hashjoin(HashPath *path, PlannerInfo *root,
SpecialJoinInfo *sjinfo);
+extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan);
extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root);
extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root);
-extern Cost get_initplan_cost(PlannerInfo *root, SubPlan *subplan);
extern void set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel);
extern void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
RelOptInfo *outer_rel,
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 110d8ac0d11..a870ce889b0 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.45 2008/08/14 20:31:29 heikki Exp $
+ * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.46 2008/08/22 00:16:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,6 +35,7 @@ extern Query *getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr);
extern void AddQual(Query *parsetree, Node *qual);
extern void AddInvertedQual(Query *parsetree, Node *qual);
+extern bool contain_aggs_of_level(Node *node, int levelsup);
extern bool checkExprHasAggs(Node *node);
extern bool checkExprHasSubLink(Node *node);