@ -122,7 +122,6 @@ static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel,
List * paths ) ;
List * paths ) ;
static PathClauseUsage * classify_index_clause_usage ( Path * path ,
static PathClauseUsage * classify_index_clause_usage ( Path * path ,
List * * clauselist ) ;
List * * clauselist ) ;
static Relids get_bitmap_tree_required_outer ( Path * bitmapqual ) ;
static void find_indexpath_quals ( Path * bitmapqual , List * * quals , List * * preds ) ;
static void find_indexpath_quals ( Path * bitmapqual , List * * quals , List * * preds ) ;
static int find_list_position ( Node * node , List * * nodelist ) ;
static int find_list_position ( Node * node , List * * nodelist ) ;
static bool check_index_only ( RelOptInfo * rel , IndexOptInfo * index ) ;
static bool check_index_only ( RelOptInfo * rel , IndexOptInfo * index ) ;
@ -357,23 +356,16 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
*/
*/
if ( bitjoinpaths ! = NIL )
if ( bitjoinpaths ! = NIL )
{
{
List * path_outer ;
List * all_path_outers ;
List * all_path_outers ;
ListCell * lc ;
ListCell * lc ;
/*
/* Identify each distinct parameterization seen in bitjoinpaths */
* path_outer holds the parameterization of each path in bitjoinpaths
all_path_outers = NIL ;
* ( to save recalculating that several times ) , while all_path_outers
* holds all distinct parameterization sets .
*/
path_outer = all_path_outers = NIL ;
foreach ( lc , bitjoinpaths )
foreach ( lc , bitjoinpaths )
{
{
Path * path = ( Path * ) lfirst ( lc ) ;
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 ) )
if ( ! bms_equal_any ( required_outer , all_path_outers ) )
all_path_outers = lappend ( all_path_outers , required_outer ) ;
all_path_outers = lappend ( all_path_outers , required_outer ) ;
}
}
@ -388,16 +380,14 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
double loop_count ;
double loop_count ;
BitmapHeapPath * bpath ;
BitmapHeapPath * bpath ;
ListCell * lcp ;
ListCell * lcp ;
ListCell * lco ;
/* Identify all the bitmap join paths needing no more than that */
/* Identify all the bitmap join paths needing no more than that */
this_path_set = NIL ;
this_path_set = NIL ;
forbot h ( lcp , bitjoinpaths , lco , path_outer )
foreac h ( lcp , bitjoinpaths )
{
{
Path * path = ( Path * ) lfirst ( lcp ) ;
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 ) ;
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 ) ;
bitmapqual = choose_bitmap_and ( root , rel , this_path_set ) ;
/* And push that path into the mix */
/* 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 ) ;
loop_count = get_loop_count ( root , rel - > relid , required_outer ) ;
bpath = create_bitmap_heap_path ( root , rel , bitmapqual ,
bpath = create_bitmap_heap_path ( root , rel , bitmapqual ,
required_outer , loop_count , 0 ) ;
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
* 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
* index path ( which could be a BitmapAnd or BitmapOr node ) .
* a BitmapOr ) .
*/
*/
static Cost
static Cost
bitmap_scan_cost_est ( PlannerInfo * root , RelOptInfo * rel , Path * ipath )
bitmap_scan_cost_est ( PlannerInfo * root , RelOptInfo * rel , Path * ipath )
{
{
BitmapHeapPath bpath ;
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 */
/* Set up a dummy BitmapHeapPath */
bpath . path . type = T_BitmapHeapPath ;
bpath . path . type = T_BitmapHeapPath ;
bpath . path . pathtype = T_BitmapHeapScan ;
bpath . path . pathtype = T_BitmapHeapScan ;
bpath . path . parent = rel ;
bpath . path . parent = rel ;
bpath . path . pathtarget = rel - > reltarget ;
bpath . path . pathtarget = rel - > reltarget ;
bpath . path . param_info = get_baserel_parampathinfo ( root , rel ,
bpath . path . param_info = ipath - > param_info ;
required_outer ) ;
bpath . path . pathkeys = NIL ;
bpath . path . pathkeys = NIL ;
bpath . bitmapqual = ipath ;
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 .
* Parallel bitmap heap path will be considered at later stage .
*/
*/
bpath . path . parallel_workers = 0 ;
bpath . path . parallel_workers = 0 ;
/* Now we can do cost_bitmap_heap_scan */
cost_bitmap_heap_scan ( & bpath . path , root , rel ,
cost_bitmap_heap_scan ( & bpath . path , root , rel ,
bpath . path . param_info ,
bpath . path . param_info ,
ipath ,
ipath ,
get_loop_count ( root , rel - > relid , required_outer ) ) ;
get_loop_count ( root , rel - > relid ,
PATH_REQ_OUTER ( ipath ) ) ) ;
return bpath . path . total_cost ;
return bpath . path . total_cost ;
}
}
@ -1643,46 +1630,15 @@ bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath)
static Cost
static Cost
bitmap_and_cost_est ( PlannerInfo * root , RelOptInfo * rel , List * paths )
bitmap_and_cost_est ( PlannerInfo * root , RelOptInfo * rel , List * paths )
{
{
BitmapAndPath apath ;
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 ;
/*
/*
* Check the cost of temporary path without considering parallelism .
* Might as well build a real BitmapAndPath here , as the work is slightly
* Parallel bitmap heap path will be considered at later stage .
* too complicated to be worth repeating just to save one palloc .
*/
*/
bpath . path . parallel_workers = 0 ;
apath = create_bitmap_and_path ( root , rel , paths ) ;
/* 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 ) ) ;
return bpath . path . total_cost ;
return bitmap_scan_cost_est ( root , rel , ( Path * ) apath ) ;
}
}
@ -1753,49 +1709,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
* find_indexpath_quals
*
*