1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-17613 Refactor prune_partitions() to build into a dedicated bitmap

prune_partitions() built the used-partition set directly in
read_partitions: it cleared it, let find_used_partitions*() fill it, and
in the index-merge case used it as scratch too - both buffer and result.

The patch adds PART_PRUNE_PARAM::parts_bitmap and builds the return
into it instead. read_partitions is produced from it only at the end:
copied when the condition was analyzed (IMPOSSIBLE included,
parts_bitmap left empty), or set to all locked partitions via
mark_all_partitions_as_used() when nothing could be pruned.

Pure refactoring: read_partitions ends up identical on every path. It
decouples the pruning scratch from read_partitions, so a later commit can
switch the final bitmap_copy() to bitmap_intersect() - letting pruning
narrow a pre-set read_partitions (e.g. a versioned table selecting only
its current partition) instead of overwriting it.
This commit is contained in:
Aleksey Midenkov
2026-10-16 15:11:21 +03:00
parent 9993e91785
commit b55aca57f2

View File

@@ -4019,7 +4019,7 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len)
struct st_part_prune_param;
struct st_part_opt_info;
typedef void (*mark_full_part_func)(partition_info*, uint32);
typedef void (*mark_full_part_func)(struct st_part_prune_param*, uint32);
/*
Partition pruning operation context
@@ -4080,6 +4080,12 @@ typedef struct st_part_prune_param
/* Iterator to be used to obtain the "current" set of used partitions */
PARTITION_ITERATOR part_iter;
/*
Initialized bitmap of read_partitions size.
find_used_partitions() will save the set of used partitions here.
*/
MY_BITMAP parts_bitmap;
/* Initialized bitmap of num_subparts size */
MY_BITMAP subparts_bitmap;
@@ -4181,7 +4187,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
thd->no_errors=1; // Don't warn about NULL
thd->mem_root=&alloc;
bitmap_clear_all(&part_info->read_partitions);
bitmap_clear_all(&prune_param.parts_bitmap);
prune_param.key= prune_param.range_param.key_parts;
SEL_TREE *tree;
@@ -4259,7 +4265,11 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
all_used:
retval= FALSE; // some partitions are used
mark_all_partitions_as_used(prune_param.part_info);
goto all_used_end;
end:
bitmap_copy(&prune_param.part_info->read_partitions,
&prune_param.parts_bitmap);
all_used_end:
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
thd->no_errors=0;
thd->mem_root= range_par->old_root;
@@ -4337,20 +4347,21 @@ static void store_selargs_to_rec(PART_PRUNE_PARAM *ppar, SEL_ARG **start,
/* Mark a partition as used in the case when there are no subpartitions */
static void mark_full_partition_used_no_parts(partition_info* part_info,
static void mark_full_partition_used_no_parts(PART_PRUNE_PARAM *ppar,
uint32 part_id)
{
DBUG_ENTER("mark_full_partition_used_no_parts");
DBUG_PRINT("enter", ("Mark partition %u as used", part_id));
bitmap_set_bit(&part_info->read_partitions, part_id);
bitmap_set_bit(&ppar->parts_bitmap, part_id);
DBUG_VOID_RETURN;
}
/* Mark a partition as used in the case when there are subpartitions */
static void mark_full_partition_used_with_parts(partition_info *part_info,
static void mark_full_partition_used_with_parts(PART_PRUNE_PARAM *ppar,
uint32 part_id)
{
partition_info *part_info= ppar->part_info;
uint32 start= part_id * part_info->num_subparts;
uint32 end= start + part_info->num_subparts;
DBUG_ENTER("mark_full_partition_used_with_parts");
@@ -4358,7 +4369,7 @@ static void mark_full_partition_used_with_parts(partition_info *part_info,
for (; start != end; start++)
{
DBUG_PRINT("info", ("1:Mark subpartition %u as used", start));
bitmap_set_bit(&part_info->read_partitions, start);
bitmap_set_bit(&ppar->parts_bitmap, start);
}
DBUG_VOID_RETURN;
}
@@ -4386,7 +4397,7 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
MY_BITMAP all_merges;
uint bitmap_bytes;
my_bitmap_map *bitmap_buf;
uint n_bits= ppar->part_info->read_partitions.n_bits;
uint n_bits= ppar->parts_bitmap.n_bits;
bitmap_bytes= bitmap_buffer_size(n_bits);
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(ppar->range_param.mem_root,
bitmap_bytes)))
@@ -4412,15 +4423,15 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
}
if (res != -1)
bitmap_intersect(&all_merges, &ppar->part_info->read_partitions);
bitmap_intersect(&all_merges, &ppar->parts_bitmap);
if (bitmap_is_clear_all(&all_merges))
return 0;
bitmap_clear_all(&ppar->part_info->read_partitions);
bitmap_clear_all(&ppar->parts_bitmap);
}
memcpy(ppar->part_info->read_partitions.bitmap, all_merges.bitmap,
memcpy(ppar->parts_bitmap.bitmap, all_merges.bitmap,
bitmap_bytes);
return 1;
}
@@ -4573,6 +4584,8 @@ int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar, SEL_IMERGE *imerge)
-1 Couldn't infer any partition pruning "intervals" from the passed
SEL_ARG* tree (which means that all partitions should be marked as
used) Marking partitions as used is the responsibility of the caller.
The set of used partitions is saved in PART_PRUNE_PARAM::parts_bitmap.
*/
static
@@ -4791,7 +4804,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
{
for (uint i= 0; i < ppar->part_info->num_subparts; i++)
if (bitmap_is_set(&ppar->subparts_bitmap, i))
bitmap_set_bit(&ppar->part_info->read_partitions,
bitmap_set_bit(&ppar->parts_bitmap,
part_id * ppar->part_info->num_subparts + i);
}
goto pop_and_go_right;
@@ -4853,7 +4866,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
NOT_A_PARTITION_ID)
{
bitmap_set_bit(&part_info->read_partitions,
bitmap_set_bit(&ppar->parts_bitmap,
part_id * part_info->num_subparts + subpart_id);
}
res= 1; /* Some partitions were marked as used */
@@ -4908,7 +4921,7 @@ process_next_key_part:
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
NOT_A_PARTITION_ID)
{
ppar->mark_full_partition_used(ppar->part_info, part_id);
ppar->mark_full_partition_used(ppar, part_id);
found= TRUE;
}
res= MY_TEST(found);
@@ -5048,6 +5061,15 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
!(ppar->is_subpart_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)*
total_parts)))
return TRUE;
{
my_bitmap_map *buf;
uint32 bufsize= bitmap_buffer_size(part_info->read_partitions.n_bits);
if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize)))
return TRUE;
my_bitmap_init(&ppar->parts_bitmap, buf,
part_info->read_partitions.n_bits);
}
if (ppar->subpart_fields)
{