aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/indxpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r--src/backend/optimizer/path/indxpath.c121
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