mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-11084 Select statement with partition selection against MyISAM table opens all partitions.
Now we don't open partitions if it was explicitly cpecified. ha_partition::m_opened_partition bitmap added to track partitions that were actually opened.
This commit is contained in:
parent
041a32abcd
commit
b4a2baffa8
16 changed files with 252 additions and 61 deletions
BIN
mysql-test/std_data/mdev11084.frm
Normal file
BIN
mysql-test/std_data/mdev11084.frm
Normal file
Binary file not shown.
BIN
mysql-test/std_data/mdev11084.par
Normal file
BIN
mysql-test/std_data/mdev11084.par
Normal file
Binary file not shown.
BIN
mysql-test/std_data/mdev11084.part1.MYD
Normal file
BIN
mysql-test/std_data/mdev11084.part1.MYD
Normal file
Binary file not shown.
BIN
mysql-test/std_data/mdev11084.part1.MYI
Normal file
BIN
mysql-test/std_data/mdev11084.part1.MYI
Normal file
Binary file not shown.
8
mysql-test/suite/parts/r/partition_open.result
Normal file
8
mysql-test/suite/parts/r/partition_open.result
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
x
|
||||||
|
300
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
|
||||||
|
drop table t1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1017 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
|
24
mysql-test/suite/parts/t/partition_open.test
Normal file
24
mysql-test/suite/parts/t/partition_open.test
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#
|
||||||
|
# MDEV-11084 Select statement with partition selection against MyISAM table opens all partitions.
|
||||||
|
#
|
||||||
|
--source include/have_partition.inc
|
||||||
|
|
||||||
|
let $datadir=`select @@datadir`;
|
||||||
|
|
||||||
|
# Table declared as having 2 partitions
|
||||||
|
# create table t1 (x int) egine=myisam
|
||||||
|
# partition by range columns (x)
|
||||||
|
# ( partition p0 values less than (100), partition p1 values less than (1000));
|
||||||
|
#
|
||||||
|
# But we copy only second partition. So the 'p0' can't be opened.
|
||||||
|
|
||||||
|
copy_file std_data/mdev11084.frm $datadir/test/t1.frm;
|
||||||
|
copy_file std_data/mdev11084.par $datadir/test/t1.par;
|
||||||
|
copy_file std_data/mdev11084.part1.MYD $datadir/test/t1#P#p1.MYD;
|
||||||
|
copy_file std_data/mdev11084.part1.MYI $datadir/test/t1#P#p1.MYI;
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
--replace_result $datadir ./
|
||||||
|
--error ER_FILE_NOT_FOUND
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
--replace_result $datadir ./
|
||||||
|
drop table t1;
|
|
@ -368,6 +368,7 @@ void ha_partition::init_handler_variables()
|
||||||
part_share= NULL;
|
part_share= NULL;
|
||||||
m_new_partitions_share_refs.empty();
|
m_new_partitions_share_refs.empty();
|
||||||
m_part_ids_sorted_by_num_of_records= NULL;
|
m_part_ids_sorted_by_num_of_records= NULL;
|
||||||
|
m_partitions_to_open= NULL;
|
||||||
|
|
||||||
m_range_info= NULL;
|
m_range_info= NULL;
|
||||||
m_mrr_full_buffer_size= 0;
|
m_mrr_full_buffer_size= 0;
|
||||||
|
@ -389,6 +390,7 @@ void ha_partition::init_handler_variables()
|
||||||
my_bitmap_clear(&m_partitions_to_reset);
|
my_bitmap_clear(&m_partitions_to_reset);
|
||||||
my_bitmap_clear(&m_key_not_found_partitions);
|
my_bitmap_clear(&m_key_not_found_partitions);
|
||||||
my_bitmap_clear(&m_mrr_used_partitions);
|
my_bitmap_clear(&m_mrr_used_partitions);
|
||||||
|
my_bitmap_clear(&m_opened_partitions);
|
||||||
|
|
||||||
#ifdef DONT_HAVE_TO_BE_INITALIZED
|
#ifdef DONT_HAVE_TO_BE_INITALIZED
|
||||||
m_start_key.flag= 0;
|
m_start_key.flag= 0;
|
||||||
|
@ -3360,6 +3362,7 @@ void ha_partition::free_partition_bitmaps()
|
||||||
my_bitmap_free(&m_locked_partitions);
|
my_bitmap_free(&m_locked_partitions);
|
||||||
my_bitmap_free(&m_partitions_to_reset);
|
my_bitmap_free(&m_partitions_to_reset);
|
||||||
my_bitmap_free(&m_key_not_found_partitions);
|
my_bitmap_free(&m_key_not_found_partitions);
|
||||||
|
my_bitmap_free(&m_opened_partitions);
|
||||||
my_bitmap_free(&m_mrr_used_partitions);
|
my_bitmap_free(&m_mrr_used_partitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3401,6 +3404,9 @@ bool ha_partition::init_partition_bitmaps()
|
||||||
if (bitmap_init(&m_mrr_used_partitions, NULL, m_tot_parts, TRUE))
|
if (bitmap_init(&m_mrr_used_partitions, NULL, m_tot_parts, TRUE))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
|
if (my_bitmap_init(&m_opened_partitions, NULL, m_tot_parts, FALSE))
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
/* Initialize the bitmap for read/lock_partitions */
|
/* Initialize the bitmap for read/lock_partitions */
|
||||||
if (!m_is_clone_of)
|
if (!m_is_clone_of)
|
||||||
{
|
{
|
||||||
|
@ -3437,8 +3443,8 @@ bool ha_partition::init_partition_bitmaps()
|
||||||
|
|
||||||
int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
{
|
{
|
||||||
char *name_buffer_ptr;
|
|
||||||
int error= HA_ERR_INITIALIZATION;
|
int error= HA_ERR_INITIALIZATION;
|
||||||
|
handler *file_sample= NULL;
|
||||||
handler **file;
|
handler **file;
|
||||||
char name_buff[FN_REFLEN + 1];
|
char name_buff[FN_REFLEN + 1];
|
||||||
ulonglong check_table_flags;
|
ulonglong check_table_flags;
|
||||||
|
@ -3451,7 +3457,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
m_part_field_array= m_part_info->full_part_field_array;
|
m_part_field_array= m_part_info->full_part_field_array;
|
||||||
if (get_from_handler_file(name, &table->mem_root, MY_TEST(m_is_clone_of)))
|
if (get_from_handler_file(name, &table->mem_root, MY_TEST(m_is_clone_of)))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
name_buffer_ptr= m_name_buffer_ptr;
|
|
||||||
if (populate_partition_name_hash())
|
if (populate_partition_name_hash())
|
||||||
{
|
{
|
||||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||||
|
@ -3473,6 +3478,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
if (init_partition_bitmaps())
|
if (init_partition_bitmaps())
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
|
|
||||||
|
if ((error= m_part_info->set_partition_bitmaps(m_partitions_to_open)))
|
||||||
|
goto err_alloc;
|
||||||
|
|
||||||
/* Allocate memory used with MMR */
|
/* Allocate memory used with MMR */
|
||||||
if (!(m_range_info= (void **)
|
if (!(m_range_info= (void **)
|
||||||
my_multi_malloc(MYF(MY_WME),
|
my_multi_malloc(MYF(MY_WME),
|
||||||
|
@ -3498,6 +3506,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
if (m_is_clone_of)
|
if (m_is_clone_of)
|
||||||
{
|
{
|
||||||
uint i, alloc_len;
|
uint i, alloc_len;
|
||||||
|
char *name_buffer_ptr;
|
||||||
DBUG_ASSERT(m_clone_mem_root);
|
DBUG_ASSERT(m_clone_mem_root);
|
||||||
/* Allocate an array of handler pointers for the partitions handlers. */
|
/* Allocate an array of handler pointers for the partitions handlers. */
|
||||||
alloc_len= (m_tot_parts + 1) * sizeof(handler*);
|
alloc_len= (m_tot_parts + 1) * sizeof(handler*);
|
||||||
|
@ -3507,6 +3516,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
memset(m_file, 0, alloc_len);
|
memset(m_file, 0, alloc_len);
|
||||||
|
name_buffer_ptr= m_name_buffer_ptr;
|
||||||
/*
|
/*
|
||||||
Populate them by cloning the original partitions. This also opens them.
|
Populate them by cloning the original partitions. This also opens them.
|
||||||
Note that file->ref is allocated too.
|
Note that file->ref is allocated too.
|
||||||
|
@ -3514,6 +3524,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
file= m_is_clone_of->m_file;
|
file= m_is_clone_of->m_file;
|
||||||
for (i= 0; i < m_tot_parts; i++)
|
for (i= 0; i < m_tot_parts; i++)
|
||||||
{
|
{
|
||||||
|
if (!bitmap_is_set(&m_is_clone_of->m_opened_partitions, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
|
if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
|
||||||
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
|
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
|
||||||
goto err_handler;
|
goto err_handler;
|
||||||
|
@ -3524,30 +3537,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
file= &m_file[i];
|
file= &m_file[i];
|
||||||
goto err_handler;
|
goto err_handler;
|
||||||
}
|
}
|
||||||
|
if (!file_sample)
|
||||||
|
file_sample= m_file[i];
|
||||||
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
||||||
|
bitmap_set_bit(&m_opened_partitions, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file= m_file;
|
if ((error= open_read_partitions(name_buff, sizeof(name_buff),
|
||||||
do
|
&file_sample)))
|
||||||
{
|
goto err_handler;
|
||||||
LEX_CSTRING save_connect_string= table->s->connect_string;
|
m_num_locks= file_sample->lock_count();
|
||||||
if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
|
|
||||||
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
|
|
||||||
goto err_handler;
|
|
||||||
if (!((*file)->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
|
|
||||||
table->s->connect_string= m_connect_string[(uint)(file-m_file)];
|
|
||||||
error= (*file)->ha_open(table, name_buff, mode,
|
|
||||||
test_if_locked | HA_OPEN_NO_PSI_CALL);
|
|
||||||
table->s->connect_string= save_connect_string;
|
|
||||||
if (error)
|
|
||||||
goto err_handler;
|
|
||||||
if (m_file == file)
|
|
||||||
m_num_locks= (*file)->lock_count();
|
|
||||||
DBUG_ASSERT(m_num_locks == (*file)->lock_count());
|
|
||||||
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
|
||||||
} while (*(++file));
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
We want to know the upper bound for locks, to allocate enough memory.
|
We want to know the upper bound for locks, to allocate enough memory.
|
||||||
|
@ -3558,12 +3559,14 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
m_num_locks*= m_tot_parts;
|
m_num_locks*= m_tot_parts;
|
||||||
|
|
||||||
file= m_file;
|
file= m_file;
|
||||||
ref_length= (*file)->ref_length;
|
ref_length= file_sample->ref_length;
|
||||||
check_table_flags= (((*file)->ha_table_flags() &
|
check_table_flags= ((file_sample->ha_table_flags() &
|
||||||
~(PARTITION_DISABLED_TABLE_FLAGS)) |
|
~(PARTITION_DISABLED_TABLE_FLAGS)) |
|
||||||
(PARTITION_ENABLED_TABLE_FLAGS));
|
(PARTITION_ENABLED_TABLE_FLAGS));
|
||||||
while (*(++file))
|
while (*(++file))
|
||||||
{
|
{
|
||||||
|
if (!bitmap_is_set(&m_opened_partitions, file - m_file))
|
||||||
|
continue;
|
||||||
/* MyISAM can have smaller ref_length for partitions with MAX_ROWS set */
|
/* MyISAM can have smaller ref_length for partitions with MAX_ROWS set */
|
||||||
set_if_bigger(ref_length, ((*file)->ref_length));
|
set_if_bigger(ref_length, ((*file)->ref_length));
|
||||||
/*
|
/*
|
||||||
|
@ -3580,8 +3583,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
goto err_handler;
|
goto err_handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key_used_on_scan= m_file[0]->key_used_on_scan;
|
key_used_on_scan= file_sample->key_used_on_scan;
|
||||||
implicit_emptied= m_file[0]->implicit_emptied;
|
implicit_emptied= file_sample->implicit_emptied;
|
||||||
/*
|
/*
|
||||||
Add 2 bytes for partition id in position ref length.
|
Add 2 bytes for partition id in position ref length.
|
||||||
ref_length=max_in_all_partitions(ref_length) + PARTITION_BYTES_IN_POS
|
ref_length=max_in_all_partitions(ref_length) + PARTITION_BYTES_IN_POS
|
||||||
|
@ -3612,8 +3615,12 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
||||||
|
|
||||||
err_handler:
|
err_handler:
|
||||||
DEBUG_SYNC(ha_thd(), "partition_open_error");
|
DEBUG_SYNC(ha_thd(), "partition_open_error");
|
||||||
|
file= &m_file[m_tot_parts - 1];
|
||||||
while (file-- != m_file)
|
while (file-- != m_file)
|
||||||
(*file)->ha_close();
|
{
|
||||||
|
if (bitmap_is_set(&m_opened_partitions, file - m_file))
|
||||||
|
(*file)->ha_close();
|
||||||
|
}
|
||||||
err_alloc:
|
err_alloc:
|
||||||
free_partition_bitmaps();
|
free_partition_bitmaps();
|
||||||
my_free(m_range_info);
|
my_free(m_range_info);
|
||||||
|
@ -3744,7 +3751,6 @@ int ha_partition::close(void)
|
||||||
DBUG_ASSERT(m_part_info);
|
DBUG_ASSERT(m_part_info);
|
||||||
|
|
||||||
destroy_record_priority_queue();
|
destroy_record_priority_queue();
|
||||||
free_partition_bitmaps();
|
|
||||||
|
|
||||||
for (; ft_first ; ft_first= tmp_ft_info)
|
for (; ft_first ; ft_first= tmp_ft_info)
|
||||||
{
|
{
|
||||||
|
@ -3795,9 +3801,12 @@ int ha_partition::close(void)
|
||||||
repeat:
|
repeat:
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(*file)->ha_close();
|
if (!first || bitmap_is_set(&m_opened_partitions, file - m_file))
|
||||||
|
(*file)->ha_close();
|
||||||
} while (*(++file));
|
} while (*(++file));
|
||||||
|
|
||||||
|
free_partition_bitmaps();
|
||||||
|
|
||||||
if (first && m_added_file && m_added_file[0])
|
if (first && m_added_file && m_added_file[0])
|
||||||
{
|
{
|
||||||
file= m_added_file;
|
file= m_added_file;
|
||||||
|
@ -8246,15 +8255,18 @@ int ha_partition::info(uint flag)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
file= *file_array;
|
file= *file_array;
|
||||||
/* Get variables if not already done */
|
if (bitmap_is_set(&(m_opened_partitions), (file_array - m_file)))
|
||||||
if (!(flag & HA_STATUS_VARIABLE) ||
|
|
||||||
!bitmap_is_set(&(m_part_info->read_partitions),
|
|
||||||
(uint)(file_array - m_file)))
|
|
||||||
file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
|
|
||||||
if (file->stats.records > max_records)
|
|
||||||
{
|
{
|
||||||
max_records= file->stats.records;
|
/* Get variables if not already done */
|
||||||
handler_instance= i;
|
if (!(flag & HA_STATUS_VARIABLE) ||
|
||||||
|
!bitmap_is_set(&(m_part_info->read_partitions),
|
||||||
|
(uint) (file_array - m_file)))
|
||||||
|
file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
|
||||||
|
if (file->stats.records > max_records)
|
||||||
|
{
|
||||||
|
max_records= file->stats.records;
|
||||||
|
handler_instance= i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
} while (*(++file_array));
|
} while (*(++file_array));
|
||||||
|
@ -8335,6 +8347,96 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ha_partition::set_partitions_to_open(List<String> *partition_names)
|
||||||
|
{
|
||||||
|
m_partitions_to_open= partition_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ha_partition::open_read_partitions(char *name_buff, size_t name_buff_size,
|
||||||
|
handler **sample)
|
||||||
|
{
|
||||||
|
handler **file;
|
||||||
|
char *name_buffer_ptr;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
name_buffer_ptr= m_name_buffer_ptr;
|
||||||
|
file= m_file;
|
||||||
|
*sample= NULL;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int n_file= file-m_file;
|
||||||
|
int is_open= bitmap_is_set(&m_opened_partitions, n_file);
|
||||||
|
int should_be_open= bitmap_is_set(&m_part_info->read_partitions, n_file);
|
||||||
|
|
||||||
|
if (is_open && !should_be_open)
|
||||||
|
{
|
||||||
|
if ((error= (*file)->ha_close()))
|
||||||
|
goto err_handler;
|
||||||
|
bitmap_clear_bit(&m_opened_partitions, n_file);
|
||||||
|
}
|
||||||
|
else if (!is_open && should_be_open)
|
||||||
|
{
|
||||||
|
LEX_CSTRING save_connect_string= table->s->connect_string;
|
||||||
|
if ((error= create_partition_name(name_buff, name_buff_size,
|
||||||
|
table->s->normalized_path.str,
|
||||||
|
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
|
||||||
|
goto err_handler;
|
||||||
|
if (!((*file)->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
|
||||||
|
table->s->connect_string= m_connect_string[(uint)(file-m_file)];
|
||||||
|
error= (*file)->ha_open(table, name_buff, m_mode,
|
||||||
|
m_open_test_lock | HA_OPEN_NO_PSI_CALL);
|
||||||
|
table->s->connect_string= save_connect_string;
|
||||||
|
if (error)
|
||||||
|
goto err_handler;
|
||||||
|
if (!(*sample))
|
||||||
|
*sample= *file;
|
||||||
|
bitmap_set_bit(&m_opened_partitions, n_file);
|
||||||
|
}
|
||||||
|
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
||||||
|
} while (*(++file));
|
||||||
|
|
||||||
|
err_handler:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ha_partition::change_partitions_to_open(List<String> *partition_names)
|
||||||
|
{
|
||||||
|
char name_buff[FN_REFLEN+1];
|
||||||
|
int error= 0;
|
||||||
|
handler *sample;
|
||||||
|
|
||||||
|
if (m_is_clone_of)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_partitions_to_open= partition_names;
|
||||||
|
if ((error= m_part_info->set_partition_bitmaps(partition_names)))
|
||||||
|
goto err_handler;
|
||||||
|
|
||||||
|
if (m_lock_type != F_UNLCK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
That happens after the LOCK TABLE statement.
|
||||||
|
Do nothing in this case.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitmap_cmp(&m_opened_partitions, &m_part_info->read_partitions) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((error= read_par_file(table->s->normalized_path.str)) ||
|
||||||
|
(error= open_read_partitions(name_buff, sizeof(name_buff), &sample)))
|
||||||
|
goto err_handler;
|
||||||
|
|
||||||
|
clear_handler_file();
|
||||||
|
|
||||||
|
err_handler:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
General function to prepare handler for certain behavior.
|
General function to prepare handler for certain behavior.
|
||||||
|
|
||||||
|
@ -8831,7 +8933,8 @@ int ha_partition::reset(void)
|
||||||
i < m_tot_parts;
|
i < m_tot_parts;
|
||||||
i= bitmap_get_next_set(&m_partitions_to_reset, i))
|
i= bitmap_get_next_set(&m_partitions_to_reset, i))
|
||||||
{
|
{
|
||||||
if ((tmp= m_file[i]->ha_reset()))
|
if (bitmap_is_set(&m_opened_partitions, i) &&
|
||||||
|
(tmp= m_file[i]->ha_reset()))
|
||||||
result= tmp;
|
result= tmp;
|
||||||
}
|
}
|
||||||
bitmap_clear_all(&m_partitions_to_reset);
|
bitmap_clear_all(&m_partitions_to_reset);
|
||||||
|
@ -8948,7 +9051,12 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
|
||||||
i < m_tot_parts;
|
i < m_tot_parts;
|
||||||
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
|
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
|
||||||
{
|
{
|
||||||
if ((tmp= m_file[i]->extra(operation)))
|
/*
|
||||||
|
This can be called after an error in ha_open.
|
||||||
|
In this case calling 'extra' can crash.
|
||||||
|
*/
|
||||||
|
if (bitmap_is_set(&m_opened_partitions, i) &&
|
||||||
|
(tmp= m_file[i]->extra(operation)))
|
||||||
result= tmp;
|
result= tmp;
|
||||||
}
|
}
|
||||||
/* Add all used partitions to be called in reset(). */
|
/* Add all used partitions to be called in reset(). */
|
||||||
|
|
|
@ -385,6 +385,8 @@ private:
|
||||||
/** partitions that returned HA_ERR_KEY_NOT_FOUND. */
|
/** partitions that returned HA_ERR_KEY_NOT_FOUND. */
|
||||||
MY_BITMAP m_key_not_found_partitions;
|
MY_BITMAP m_key_not_found_partitions;
|
||||||
bool m_key_not_found;
|
bool m_key_not_found;
|
||||||
|
List<String> *m_partitions_to_open;
|
||||||
|
MY_BITMAP m_opened_partitions;
|
||||||
public:
|
public:
|
||||||
handler **get_child_handlers()
|
handler **get_child_handlers()
|
||||||
{
|
{
|
||||||
|
@ -836,6 +838,10 @@ public:
|
||||||
virtual int info(uint);
|
virtual int info(uint);
|
||||||
void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||||
uint part_id);
|
uint part_id);
|
||||||
|
void set_partitions_to_open(List<String> *partition_names);
|
||||||
|
int change_partitions_to_open(List<String> *partition_names);
|
||||||
|
int open_read_partitions(char *name_buff, size_t name_buff_size,
|
||||||
|
handler **sample);
|
||||||
virtual int extra(enum ha_extra_function operation);
|
virtual int extra(enum ha_extra_function operation);
|
||||||
virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
|
virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
|
||||||
virtual int reset(void);
|
virtual int reset(void);
|
||||||
|
|
|
@ -2661,7 +2661,8 @@ PSI_table_share *handler::ha_table_share_psi() const
|
||||||
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
|
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
|
||||||
*/
|
*/
|
||||||
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
||||||
uint test_if_locked, MEM_ROOT *mem_root)
|
uint test_if_locked, MEM_ROOT *mem_root,
|
||||||
|
List<String> *partitions_to_open)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("handler::ha_open");
|
DBUG_ENTER("handler::ha_open");
|
||||||
|
@ -2676,6 +2677,8 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
||||||
DBUG_PRINT("info", ("old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK));
|
DBUG_PRINT("info", ("old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK));
|
||||||
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
|
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
|
||||||
|
|
||||||
|
set_partitions_to_open(partitions_to_open);
|
||||||
|
|
||||||
if ((error=open(name,mode,test_if_locked)))
|
if ((error=open(name,mode,test_if_locked)))
|
||||||
{
|
{
|
||||||
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
|
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
|
||||||
|
|
|
@ -2990,7 +2990,7 @@ public:
|
||||||
/* ha_ methods: pubilc wrappers for private virtual API */
|
/* ha_ methods: pubilc wrappers for private virtual API */
|
||||||
|
|
||||||
int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
|
int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
|
||||||
MEM_ROOT *mem_root= 0);
|
MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
|
||||||
int ha_index_init(uint idx, bool sorted)
|
int ha_index_init(uint idx, bool sorted)
|
||||||
{
|
{
|
||||||
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
|
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
|
||||||
|
@ -3569,6 +3569,9 @@ public:
|
||||||
virtual int info(uint)=0; // see my_base.h for full description
|
virtual int info(uint)=0; // see my_base.h for full description
|
||||||
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||||
uint part_id);
|
uint part_id);
|
||||||
|
virtual void set_partitions_to_open(List<String> *partition_names) {}
|
||||||
|
virtual int change_partitions_to_open(List<String> *partition_names)
|
||||||
|
{ return 0; }
|
||||||
virtual int extra(enum ha_extra_function operation)
|
virtual int extra(enum ha_extra_function operation)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
|
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
|
||||||
|
|
|
@ -256,16 +256,16 @@ bool partition_info::set_read_partitions(List<char> *partition_names)
|
||||||
Prune away partitions not mentioned in the PARTITION () clause,
|
Prune away partitions not mentioned in the PARTITION () clause,
|
||||||
if used.
|
if used.
|
||||||
|
|
||||||
@param table_list Table list pointing to table to prune.
|
@param partition_names list of names of partitions.
|
||||||
|
|
||||||
@return Operation status
|
@return Operation status
|
||||||
@retval true Failure
|
@retval true Failure
|
||||||
@retval false Success
|
@retval false Success
|
||||||
*/
|
*/
|
||||||
bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
|
bool partition_info::prune_partition_bitmaps(List<String> *partition_names)
|
||||||
{
|
{
|
||||||
List_iterator<String> partition_names_it(*(table_list->partition_names));
|
List_iterator<String> partition_names_it(*(partition_names));
|
||||||
uint num_names= table_list->partition_names->elements;
|
uint num_names= partition_names->elements;
|
||||||
uint i= 0;
|
uint i= 0;
|
||||||
DBUG_ENTER("partition_info::prune_partition_bitmaps");
|
DBUG_ENTER("partition_info::prune_partition_bitmaps");
|
||||||
|
|
||||||
|
@ -295,8 +295,7 @@ bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
|
||||||
/**
|
/**
|
||||||
Set read/lock_partitions bitmap over non pruned partitions
|
Set read/lock_partitions bitmap over non pruned partitions
|
||||||
|
|
||||||
@param table_list Possible TABLE_LIST which can contain
|
@param partition_names list of partition names to query
|
||||||
list of partition names to query
|
|
||||||
|
|
||||||
@return Operation status
|
@return Operation status
|
||||||
@retval FALSE OK
|
@retval FALSE OK
|
||||||
|
@ -306,7 +305,7 @@ bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
|
||||||
@note OK to call multiple times without the need for free_bitmaps.
|
@note OK to call multiple times without the need for free_bitmaps.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
|
bool partition_info::set_partition_bitmaps(List<String> *partition_names)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("partition_info::set_partition_bitmaps");
|
DBUG_ENTER("partition_info::set_partition_bitmaps");
|
||||||
|
|
||||||
|
@ -315,16 +314,15 @@ bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
|
||||||
if (!bitmaps_are_initialized)
|
if (!bitmaps_are_initialized)
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (table_list &&
|
if (partition_names &&
|
||||||
table_list->partition_names &&
|
partition_names->elements)
|
||||||
table_list->partition_names->elements)
|
|
||||||
{
|
{
|
||||||
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
|
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
|
||||||
{
|
{
|
||||||
my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
|
my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
if (prune_partition_bitmaps(table_list))
|
if (prune_partition_bitmaps(partition_names))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -338,6 +336,27 @@ bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set read/lock_partitions bitmap over non pruned partitions
|
||||||
|
|
||||||
|
@param table_list Possible TABLE_LIST which can contain
|
||||||
|
list of partition names to query
|
||||||
|
|
||||||
|
@return Operation status
|
||||||
|
@retval FALSE OK
|
||||||
|
@retval TRUE Failed to allocate memory for bitmap or list of partitions
|
||||||
|
did not match
|
||||||
|
|
||||||
|
@note OK to call multiple times without the need for free_bitmaps.
|
||||||
|
*/
|
||||||
|
bool partition_info::set_partition_bitmaps_from_table(TABLE_LIST *table_list)
|
||||||
|
{
|
||||||
|
List<String> *partition_names= table_list ?
|
||||||
|
NULL : table_list->partition_names;
|
||||||
|
return set_partition_bitmaps(partition_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a memory area where default partition names are stored and fill it
|
Create a memory area where default partition names are stored and fill it
|
||||||
up with the names.
|
up with the names.
|
||||||
|
|
|
@ -325,7 +325,8 @@ public:
|
||||||
|
|
||||||
partition_info *get_clone(THD *thd);
|
partition_info *get_clone(THD *thd);
|
||||||
bool set_named_partition_bitmap(const char *part_name, uint length);
|
bool set_named_partition_bitmap(const char *part_name, uint length);
|
||||||
bool set_partition_bitmaps(TABLE_LIST *table_list);
|
bool set_partition_bitmaps(List<String> *partition_names);
|
||||||
|
bool set_partition_bitmaps_from_table(TABLE_LIST *table_list);
|
||||||
/* Answers the question if subpartitioning is used for a certain table */
|
/* Answers the question if subpartitioning is used for a certain table */
|
||||||
bool is_sub_partitioned()
|
bool is_sub_partitioned()
|
||||||
{
|
{
|
||||||
|
@ -386,7 +387,7 @@ private:
|
||||||
char *create_default_subpartition_name(THD *thd, uint subpart_no,
|
char *create_default_subpartition_name(THD *thd, uint subpart_no,
|
||||||
const char *part_name);
|
const char *part_name);
|
||||||
// FIXME: prune_partition_bitmaps() is duplicate of set_read_partitions()
|
// FIXME: prune_partition_bitmaps() is duplicate of set_read_partitions()
|
||||||
bool prune_partition_bitmaps(TABLE_LIST *table_list);
|
bool prune_partition_bitmaps(List<String> *partition_names);
|
||||||
bool add_named_partition(const char *part_name, uint length);
|
bool add_named_partition(const char *part_name, uint length);
|
||||||
public:
|
public:
|
||||||
bool set_read_partitions(List<char> *partition_names);
|
bool set_read_partitions(List<char> *partition_names);
|
||||||
|
|
|
@ -1512,6 +1512,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
|
||||||
MDL_ticket *mdl_ticket;
|
MDL_ticket *mdl_ticket;
|
||||||
TABLE_SHARE *share;
|
TABLE_SHARE *share;
|
||||||
uint gts_flags;
|
uint gts_flags;
|
||||||
|
int part_names_error=0;
|
||||||
DBUG_ENTER("open_table");
|
DBUG_ENTER("open_table");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1609,6 +1610,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
|
||||||
table= best_table;
|
table= best_table;
|
||||||
table->query_id= thd->query_id;
|
table->query_id= thd->query_id;
|
||||||
DBUG_PRINT("info",("Using locked table"));
|
DBUG_PRINT("info",("Using locked table"));
|
||||||
|
if (table->part_info)
|
||||||
|
{
|
||||||
|
/* Set all [named] partitions as used. */
|
||||||
|
part_names_error=
|
||||||
|
table->file->change_partitions_to_open(table_list->partition_names);
|
||||||
|
}
|
||||||
goto reset;
|
goto reset;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1892,6 +1899,12 @@ retry_share:
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table->file != NULL);
|
DBUG_ASSERT(table->file != NULL);
|
||||||
MYSQL_REBIND_TABLE(table->file);
|
MYSQL_REBIND_TABLE(table->file);
|
||||||
|
if (table->part_info)
|
||||||
|
{
|
||||||
|
/* Set all [named] partitions as used. */
|
||||||
|
part_names_error=
|
||||||
|
table->file->change_partitions_to_open(table_list->partition_names);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1904,7 +1917,8 @@ retry_share:
|
||||||
error= open_table_from_share(thd, share, alias,
|
error= open_table_from_share(thd, share, alias,
|
||||||
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
|
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
|
||||||
EXTRA_RECORD,
|
EXTRA_RECORD,
|
||||||
thd->open_options, table, FALSE);
|
thd->open_options, table, FALSE,
|
||||||
|
table_list->partition_names);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -1953,9 +1967,12 @@ retry_share:
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
if (table->part_info)
|
if (table->part_info)
|
||||||
{
|
{
|
||||||
/* Set all [named] partitions as used. */
|
/* Partitions specified were incorrect.*/
|
||||||
if (table->part_info->set_partition_bitmaps(table_list))
|
if (part_names_error)
|
||||||
|
{
|
||||||
|
table->file->print_error(part_names_error, MYF(0));
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (table_list->partition_names)
|
else if (table_list->partition_names)
|
||||||
{
|
{
|
||||||
|
|
|
@ -802,8 +802,8 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
partition_names_list.push_back(str_partition_name, thd->mem_root);
|
partition_names_list.push_back(str_partition_name, thd->mem_root);
|
||||||
}
|
}
|
||||||
first_table->partition_names= &partition_names_list;
|
if (first_table->table->
|
||||||
if (first_table->table->part_info->set_partition_bitmaps(first_table))
|
part_info->set_partition_bitmaps(&partition_names_list))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
if (lock_tables(thd, first_table, table_counter, 0))
|
if (lock_tables(thd, first_table, table_counter, 0))
|
||||||
|
|
|
@ -3100,6 +3100,7 @@ static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
|
||||||
prgflag READ_ALL etc..
|
prgflag READ_ALL etc..
|
||||||
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
|
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
|
||||||
outparam result table
|
outparam result table
|
||||||
|
partitions_to_open open only these partitions.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
|
@ -3114,7 +3115,7 @@ static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
|
||||||
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
||||||
const char *alias, uint db_stat, uint prgflag,
|
const char *alias, uint db_stat, uint prgflag,
|
||||||
uint ha_open_flags, TABLE *outparam,
|
uint ha_open_flags, TABLE *outparam,
|
||||||
bool is_create_table)
|
bool is_create_table, List<String> *partitions_to_open)
|
||||||
{
|
{
|
||||||
enum open_frm_error error;
|
enum open_frm_error error;
|
||||||
uint records, i, bitmap_size, bitmap_count;
|
uint records, i, bitmap_size, bitmap_count;
|
||||||
|
@ -3458,7 +3459,7 @@ partititon_err:
|
||||||
|
|
||||||
int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str,
|
int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str,
|
||||||
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
|
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
|
||||||
ha_open_flags);
|
ha_open_flags, 0, partitions_to_open);
|
||||||
if (ha_err)
|
if (ha_err)
|
||||||
{
|
{
|
||||||
share->open_errno= ha_err;
|
share->open_errno= ha_err;
|
||||||
|
|
|
@ -2885,7 +2885,8 @@ void init_mdl_requests(TABLE_LIST *table_list);
|
||||||
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
||||||
const char *alias, uint db_stat, uint prgflag,
|
const char *alias, uint db_stat, uint prgflag,
|
||||||
uint ha_open_flags, TABLE *outparam,
|
uint ha_open_flags, TABLE *outparam,
|
||||||
bool is_create_table);
|
bool is_create_table,
|
||||||
|
List<String> *partitions_to_open= NULL);
|
||||||
bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
|
bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
|
||||||
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
|
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
|
||||||
Virtual_column_info *vcol);
|
Virtual_column_info *vcol);
|
||||||
|
|
Loading…
Reference in a new issue