diff options
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 121 |
1 files changed, 17 insertions, 104 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 2a50272da6b..bcb1bc6097d 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -122,7 +122,6 @@ static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths); static PathClauseUsage *classify_index_clause_usage(Path *path, List **clauselist); -static Relids get_bitmap_tree_required_outer(Path *bitmapqual); static void find_indexpath_quals(Path *bitmapqual, List **quals, List **preds); static int find_list_position(Node *node, List **nodelist); static bool check_index_only(RelOptInfo *rel, IndexOptInfo *index); @@ -357,23 +356,16 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) */ if (bitjoinpaths != NIL) { - List *path_outer; List *all_path_outers; ListCell *lc; - /* - * path_outer holds the parameterization of each path in bitjoinpaths - * (to save recalculating that several times), while all_path_outers - * holds all distinct parameterization sets. - */ - path_outer = all_path_outers = NIL; + /* Identify each distinct parameterization seen in bitjoinpaths */ + all_path_outers = NIL; foreach(lc, bitjoinpaths) { Path *path = (Path *) lfirst(lc); - Relids required_outer; + Relids required_outer = PATH_REQ_OUTER(path); - required_outer = get_bitmap_tree_required_outer(path); - path_outer = lappend(path_outer, required_outer); if (!bms_equal_any(required_outer, all_path_outers)) all_path_outers = lappend(all_path_outers, required_outer); } @@ -388,16 +380,14 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) double loop_count; BitmapHeapPath *bpath; ListCell *lcp; - ListCell *lco; /* Identify all the bitmap join paths needing no more than that */ this_path_set = NIL; - forboth(lcp, bitjoinpaths, lco, path_outer) + foreach(lcp, bitjoinpaths) { Path *path = (Path *) lfirst(lcp); - Relids p_outers = (Relids) lfirst(lco); - if (bms_is_subset(p_outers, max_outers)) + if (bms_is_subset(PATH_REQ_OUTER(path), max_outers)) this_path_set = lappend(this_path_set, path); } @@ -411,7 +401,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) bitmapqual = choose_bitmap_and(root, rel, this_path_set); /* And push that path into the mix */ - required_outer = get_bitmap_tree_required_outer(bitmapqual); + required_outer = PATH_REQ_OUTER(bitmapqual); loop_count = get_loop_count(root, rel->relid, required_outer); bpath = create_bitmap_heap_path(root, rel, bitmapqual, required_outer, loop_count, 0); @@ -1601,25 +1591,19 @@ path_usage_comparator(const void *a, const void *b) /* * Estimate the cost of actually executing a bitmap scan with a single - * index path (no BitmapAnd, at least not at this level; but it could be - * a BitmapOr). + * index path (which could be a BitmapAnd or BitmapOr node). */ static Cost bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath) { BitmapHeapPath bpath; - Relids required_outer; - - /* Identify required outer rels, in case it's a parameterized scan */ - required_outer = get_bitmap_tree_required_outer(ipath); /* Set up a dummy BitmapHeapPath */ bpath.path.type = T_BitmapHeapPath; bpath.path.pathtype = T_BitmapHeapScan; bpath.path.parent = rel; bpath.path.pathtarget = rel->reltarget; - bpath.path.param_info = get_baserel_parampathinfo(root, rel, - required_outer); + bpath.path.param_info = ipath->param_info; bpath.path.pathkeys = NIL; bpath.bitmapqual = ipath; @@ -1628,10 +1612,13 @@ bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath) * Parallel bitmap heap path will be considered at later stage. */ bpath.path.parallel_workers = 0; + + /* Now we can do cost_bitmap_heap_scan */ cost_bitmap_heap_scan(&bpath.path, root, rel, bpath.path.param_info, ipath, - get_loop_count(root, rel->relid, required_outer)); + get_loop_count(root, rel->relid, + PATH_REQ_OUTER(ipath))); return bpath.path.total_cost; } @@ -1643,46 +1630,15 @@ bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath) static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths) { - BitmapAndPath apath; - BitmapHeapPath bpath; - Relids required_outer; - - /* Set up a dummy BitmapAndPath */ - apath.path.type = T_BitmapAndPath; - apath.path.pathtype = T_BitmapAnd; - apath.path.parent = rel; - apath.path.pathtarget = rel->reltarget; - apath.path.param_info = NULL; /* not used in bitmap trees */ - apath.path.pathkeys = NIL; - apath.bitmapquals = paths; - cost_bitmap_and_node(&apath, root); - - /* Identify required outer rels, in case it's a parameterized scan */ - required_outer = get_bitmap_tree_required_outer((Path *) &apath); - - /* Set up a dummy BitmapHeapPath */ - bpath.path.type = T_BitmapHeapPath; - bpath.path.pathtype = T_BitmapHeapScan; - bpath.path.parent = rel; - bpath.path.pathtarget = rel->reltarget; - bpath.path.param_info = get_baserel_parampathinfo(root, rel, - required_outer); - bpath.path.pathkeys = NIL; - bpath.bitmapqual = (Path *) &apath; + BitmapAndPath *apath; /* - * Check the cost of temporary path without considering parallelism. - * Parallel bitmap heap path will be considered at later stage. + * Might as well build a real BitmapAndPath here, as the work is slightly + * too complicated to be worth repeating just to save one palloc. */ - bpath.path.parallel_workers = 0; - - /* Now we can do cost_bitmap_heap_scan */ - cost_bitmap_heap_scan(&bpath.path, root, rel, - bpath.path.param_info, - (Path *) &apath, - get_loop_count(root, rel->relid, required_outer)); + apath = create_bitmap_and_path(root, rel, paths); - return bpath.path.total_cost; + return bitmap_scan_cost_est(root, rel, (Path *) apath); } @@ -1754,49 +1710,6 @@ classify_index_clause_usage(Path *path, List **clauselist) /* - * get_bitmap_tree_required_outer - * Find the required outer rels for a bitmap tree (index/and/or) - * - * We don't associate any particular parameterization with a BitmapAnd or - * BitmapOr node; however, the IndexPaths have parameterization info, in - * their capacity as standalone access paths. The parameterization required - * for the bitmap heap scan node is the union of rels referenced in the - * child IndexPaths. - */ -static Relids -get_bitmap_tree_required_outer(Path *bitmapqual) -{ - Relids result = NULL; - ListCell *lc; - - if (IsA(bitmapqual, IndexPath)) - { - return bms_copy(PATH_REQ_OUTER(bitmapqual)); - } - else if (IsA(bitmapqual, BitmapAndPath)) - { - foreach(lc, ((BitmapAndPath *) bitmapqual)->bitmapquals) - { - result = bms_join(result, - get_bitmap_tree_required_outer((Path *) lfirst(lc))); - } - } - else if (IsA(bitmapqual, BitmapOrPath)) - { - foreach(lc, ((BitmapOrPath *) bitmapqual)->bitmapquals) - { - result = bms_join(result, - get_bitmap_tree_required_outer((Path *) lfirst(lc))); - } - } - else - elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual)); - - return result; -} - - -/* * find_indexpath_quals * * Given the Path structure for a plain or bitmap indexscan, extract lists |