diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-04-21 19:18:13 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-04-21 19:18:13 +0000 |
commit | 14c7fba3f7d0769d8a063dea2854693f35535f6a (patch) | |
tree | 51b519e88e8092e6fc9cdd6bf50dbff872bc6fa6 /src/backend/optimizer/plan/createplan.c | |
parent | c6221db3c0f7049b804391d59aeadcfbd1f51800 (diff) | |
download | postgresql-14c7fba3f7d0769d8a063dea2854693f35535f6a.tar.gz postgresql-14c7fba3f7d0769d8a063dea2854693f35535f6a.zip |
Rethink original decision to use AND/OR Expr nodes to represent bitmap
logic operations during planning. Seems cleaner to create two new Path
node types, instead --- this avoids duplication of cost-estimation code.
Also, create an enable_bitmapscan GUC parameter to control use of bitmap
plans.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 130 |
1 files changed, 44 insertions, 86 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 0abb900beaa..faaf727da0d 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.181 2005/04/21 02:28:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.182 2005/04/21 19:18:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,9 +51,9 @@ static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path, static BitmapHeapScan *create_bitmap_scan_plan(Query *root, BitmapHeapPath *best_path, List *tlist, List *scan_clauses); -static Plan *create_bitmap_subplan(Query *root, Node *bitmapqual); -static List *create_bitmap_qual(Node *bitmapqual); -static List *create_bitmap_indxqual(Node *bitmapqual); +static Plan *create_bitmap_subplan(Query *root, Path *bitmapqual); +static List *create_bitmap_qual(Path *bitmapqual); +static List *create_bitmap_indxqual(Path *bitmapqual); static TidScan *create_tidscan_plan(Query *root, TidPath *best_path, List *tlist, List *scan_clauses); static SubqueryScan *create_subqueryscan_plan(Query *root, Path *best_path, @@ -928,37 +928,41 @@ create_bitmap_scan_plan(Query *root, * Given a bitmapqual tree, generate the Plan tree that implements it */ static Plan * -create_bitmap_subplan(Query *root, Node *bitmapqual) +create_bitmap_subplan(Query *root, Path *bitmapqual) { Plan *plan; - Plan *subplan; - if (bitmapqual == NULL) - return NULL; /* probably can't happen */ - if (IsA(bitmapqual, List)) + if (IsA(bitmapqual, BitmapAndPath)) { - /* this case is to handle the List arguments of AND/OR */ + BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; List *newlist = NIL; ListCell *l; - foreach(l, (List *) bitmapqual) + foreach(l, apath->bitmapquals) { - subplan = create_bitmap_subplan(root, lfirst(l)); + Plan *subplan = create_bitmap_subplan(root, lfirst(l)); + newlist = lappend(newlist, subplan); } - plan = (Plan *) newlist; - } - else if (and_clause(bitmapqual)) - { - subplan = create_bitmap_subplan(root, - (Node *) ((BoolExpr *) bitmapqual)->args); - plan = (Plan *) make_bitmap_and((List *) subplan); + plan = (Plan *) make_bitmap_and(newlist); + copy_path_costsize(plan, bitmapqual); + plan->plan_width = 0; /* meaningless */ } - else if (or_clause(bitmapqual)) + else if (IsA(bitmapqual, BitmapOrPath)) { - subplan = create_bitmap_subplan(root, - (Node *) ((BoolExpr *) bitmapqual)->args); - plan = (Plan *) make_bitmap_or((List *) subplan); + BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; + List *newlist = NIL; + ListCell *l; + + foreach(l, opath->bitmapquals) + { + Plan *subplan = create_bitmap_subplan(root, lfirst(l)); + + newlist = lappend(newlist, subplan); + } + plan = (Plan *) make_bitmap_or(newlist); + copy_path_costsize(plan, bitmapqual); + plan->plan_width = 0; /* meaningless */ } else if (IsA(bitmapqual, IndexPath)) { @@ -976,7 +980,6 @@ create_bitmap_subplan(Query *root, Node *bitmapqual) linitial(iscan->indxqualorig), linitial(iscan->indxstrategy), linitial(iscan->indxsubtype)); - /* this must agree with cost_bitmap_qual in costsize.c */ bscan->scan.plan.startup_cost = 0.0; bscan->scan.plan.total_cost = ipath->indextotalcost; bscan->scan.plan.plan_rows = @@ -999,28 +1002,30 @@ create_bitmap_subplan(Query *root, Node *bitmapqual) * The result is expressed as an implicit-AND list. */ static List * -create_bitmap_qual(Node *bitmapqual) +create_bitmap_qual(Path *bitmapqual) { List *result; List *sublist; - if (and_clause(bitmapqual)) + if (IsA(bitmapqual, BitmapAndPath)) { + BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; ListCell *l; result = NIL; - foreach(l, ((BoolExpr *) bitmapqual)->args) + foreach(l, apath->bitmapquals) { sublist = create_bitmap_qual(lfirst(l)); result = list_concat(result, sublist); } } - else if (or_clause(bitmapqual)) + else if (IsA(bitmapqual, BitmapOrPath)) { + BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; List *newlist = NIL; ListCell *l; - foreach(l, ((BoolExpr *) bitmapqual)->args) + foreach(l, opath->bitmapquals) { sublist = create_bitmap_qual(lfirst(l)); if (sublist == NIL) @@ -1056,26 +1061,29 @@ create_bitmap_qual(Node *bitmapqual) * to enforce, which may be weaker than the original qual expressions. */ static List * -create_bitmap_indxqual(Node *bitmapqual) +create_bitmap_indxqual(Path *bitmapqual) { List *result; List *sublist; ListCell *l; - if (and_clause(bitmapqual)) + if (IsA(bitmapqual, BitmapAndPath)) { + BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; + result = NIL; - foreach(l, ((BoolExpr *) bitmapqual)->args) + foreach(l, apath->bitmapquals) { sublist = create_bitmap_indxqual(lfirst(l)); result = list_concat(result, sublist); } } - else if (or_clause(bitmapqual)) + else if (IsA(bitmapqual, BitmapOrPath)) { + BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; List *newlist = NIL; - foreach(l, ((BoolExpr *) bitmapqual)->args) + foreach(l, opath->bitmapquals) { sublist = create_bitmap_indxqual(lfirst(l)); if (sublist == NIL) @@ -2067,34 +2075,8 @@ make_bitmap_and(List *bitmapplans) { BitmapAnd *node = makeNode(BitmapAnd); Plan *plan = &node->plan; - ListCell *subnode; - - /* - * Compute cost as sum of subplan costs, plus 100x cpu_operator_cost - * (a pretty arbitrary amount, agreed) for each tbm_intersect needed. - * This must agree with cost_bitmap_qual in costsize.c. - */ - plan->startup_cost = 0; - plan->total_cost = 0; - plan->plan_rows = 0; - plan->plan_width = 0; /* meaningless */ - foreach(subnode, bitmapplans) - { - Plan *subplan = (Plan *) lfirst(subnode); - - if (subnode == list_head(bitmapplans)) /* first node? */ - { - plan->startup_cost = subplan->startup_cost; - plan->plan_rows = subplan->plan_rows; - } - else - { - plan->total_cost += cpu_operator_cost * 100.0; - plan->plan_rows = Min(plan->plan_rows, subplan->plan_rows); - } - plan->total_cost += subplan->total_cost; - } + /* cost should be inserted by caller */ plan->targetlist = NIL; plan->qual = NIL; plan->lefttree = NULL; @@ -2109,32 +2091,8 @@ make_bitmap_or(List *bitmapplans) { BitmapOr *node = makeNode(BitmapOr); Plan *plan = &node->plan; - ListCell *subnode; - - /* - * Compute cost as sum of subplan costs, plus 100x cpu_operator_cost - * (a pretty arbitrary amount, agreed) for each tbm_union needed. - * We assume that tbm_union can be optimized away for BitmapIndexScan - * subplans. - * - * This must agree with cost_bitmap_qual in costsize.c. - */ - plan->startup_cost = 0; - plan->total_cost = 0; - plan->plan_rows = 0; - plan->plan_width = 0; /* meaningless */ - foreach(subnode, bitmapplans) - { - Plan *subplan = (Plan *) lfirst(subnode); - - if (subnode == list_head(bitmapplans)) /* first node? */ - plan->startup_cost = subplan->startup_cost; - else if (!IsA(subplan, BitmapIndexScan)) - plan->total_cost += cpu_operator_cost * 100.0; - plan->total_cost += subplan->total_cost; - plan->plan_rows += subplan->plan_rows; /* ignore overlap */ - } + /* cost should be inserted by caller */ plan->targetlist = NIL; plan->qual = NIL; plan->lefttree = NULL; |