summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2018-01-29 11:01:14 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2018-01-29 11:01:14 +0400
commitb4a2baffa82e5c07b96a1c752228560dcac1359b (patch)
tree5520b02f5c3bd21bf36f1fdf00a85dc9143c7fe5 /sql
parent041a32abcdd9791761a15d93e77ff2ea7dbc9d7c (diff)
downloadmariadb-git-b4a2baffa82e5c07b96a1c752228560dcac1359b.tar.gz
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.
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc184
-rw-r--r--sql/ha_partition.h6
-rw-r--r--sql/handler.cc5
-rw-r--r--sql/handler.h5
-rw-r--r--sql/partition_info.cc41
-rw-r--r--sql/partition_info.h5
-rw-r--r--sql/sql_base.cc23
-rw-r--r--sql/sql_partition_admin.cc4
-rw-r--r--sql/table.cc5
-rw-r--r--sql/table.h3
10 files changed, 220 insertions, 61 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 20fa2eabea1..1236a94fcfd 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -368,6 +368,7 @@ void ha_partition::init_handler_variables()
part_share= NULL;
m_new_partitions_share_refs.empty();
m_part_ids_sorted_by_num_of_records= NULL;
+ m_partitions_to_open= NULL;
m_range_info= NULL;
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_key_not_found_partitions);
my_bitmap_clear(&m_mrr_used_partitions);
+ my_bitmap_clear(&m_opened_partitions);
#ifdef DONT_HAVE_TO_BE_INITALIZED
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_partitions_to_reset);
my_bitmap_free(&m_key_not_found_partitions);
+ my_bitmap_free(&m_opened_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))
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 */
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)
{
- char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION;
+ handler *file_sample= NULL;
handler **file;
char name_buff[FN_REFLEN + 1];
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;
if (get_from_handler_file(name, &table->mem_root, MY_TEST(m_is_clone_of)))
DBUG_RETURN(error);
- name_buffer_ptr= m_name_buffer_ptr;
if (populate_partition_name_hash())
{
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())
goto err_alloc;
+ if ((error= m_part_info->set_partition_bitmaps(m_partitions_to_open)))
+ goto err_alloc;
+
/* Allocate memory used with MMR */
if (!(m_range_info= (void **)
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)
{
uint i, alloc_len;
+ char *name_buffer_ptr;
DBUG_ASSERT(m_clone_mem_root);
/* Allocate an array of handler pointers for the partitions handlers. */
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;
}
memset(m_file, 0, alloc_len);
+ name_buffer_ptr= m_name_buffer_ptr;
/*
Populate them by cloning the original partitions. This also opens them.
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;
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,
name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
goto err_handler;
@@ -3524,30 +3537,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= &m_file[i];
goto err_handler;
}
+ if (!file_sample)
+ file_sample= m_file[i];
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
+ bitmap_set_bit(&m_opened_partitions, i);
}
}
else
{
- file= m_file;
- do
- {
- LEX_CSTRING save_connect_string= table->s->connect_string;
- 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));
+ if ((error= open_read_partitions(name_buff, sizeof(name_buff),
+ &file_sample)))
+ goto err_handler;
+ m_num_locks= file_sample->lock_count();
}
/*
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;
file= m_file;
- ref_length= (*file)->ref_length;
- check_table_flags= (((*file)->ha_table_flags() &
+ ref_length= file_sample->ref_length;
+ check_table_flags= ((file_sample->ha_table_flags() &
~(PARTITION_DISABLED_TABLE_FLAGS)) |
(PARTITION_ENABLED_TABLE_FLAGS));
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 */
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;
}
}
- key_used_on_scan= m_file[0]->key_used_on_scan;
- implicit_emptied= m_file[0]->implicit_emptied;
+ key_used_on_scan= file_sample->key_used_on_scan;
+ implicit_emptied= file_sample->implicit_emptied;
/*
Add 2 bytes for partition id in position ref length.
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:
DEBUG_SYNC(ha_thd(), "partition_open_error");
+ file= &m_file[m_tot_parts - 1];
while (file-- != m_file)
- (*file)->ha_close();
+ {
+ if (bitmap_is_set(&m_opened_partitions, file - m_file))
+ (*file)->ha_close();
+ }
err_alloc:
free_partition_bitmaps();
my_free(m_range_info);
@@ -3744,7 +3751,6 @@ int ha_partition::close(void)
DBUG_ASSERT(m_part_info);
destroy_record_priority_queue();
- free_partition_bitmaps();
for (; ft_first ; ft_first= tmp_ft_info)
{
@@ -3795,9 +3801,12 @@ int ha_partition::close(void)
repeat:
do
{
- (*file)->ha_close();
+ if (!first || bitmap_is_set(&m_opened_partitions, file - m_file))
+ (*file)->ha_close();
} while (*(++file));
+ free_partition_bitmaps();
+
if (first && m_added_file && m_added_file[0])
{
file= m_added_file;
@@ -8246,15 +8255,18 @@ int ha_partition::info(uint flag)
do
{
file= *file_array;
- /* Get variables if not already done */
- 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)
+ if (bitmap_is_set(&(m_opened_partitions), (file_array - m_file)))
{
- max_records= file->stats.records;
- handler_instance= i;
+ /* Get variables if not already done */
+ 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++;
} 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.
@@ -8831,7 +8933,8 @@ int ha_partition::reset(void)
i < m_tot_parts;
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;
}
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= 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;
}
/* Add all used partitions to be called in reset(). */
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index ac41de16f20..66a70348cfd 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -385,6 +385,8 @@ private:
/** partitions that returned HA_ERR_KEY_NOT_FOUND. */
MY_BITMAP m_key_not_found_partitions;
bool m_key_not_found;
+ List<String> *m_partitions_to_open;
+ MY_BITMAP m_opened_partitions;
public:
handler **get_child_handlers()
{
@@ -836,6 +838,10 @@ public:
virtual int info(uint);
void get_dynamic_partition_info(PARTITION_STATS *stat_info,
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_opt(enum ha_extra_function operation, ulong cachesize);
virtual int reset(void);
diff --git a/sql/handler.cc b/sql/handler.cc
index c030cea033e..2218d27e9f9 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -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
*/
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;
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_ASSERT(alloc_root_inited(&table->mem_root));
+ set_partitions_to_open(partitions_to_open);
+
if ((error=open(name,mode,test_if_locked)))
{
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
diff --git a/sql/handler.h b/sql/handler.h
index 78e41693ef1..713ffdd7e4e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2990,7 +2990,7 @@ public:
/* ha_ methods: pubilc wrappers for private virtual API */
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)
{
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 void get_dynamic_partition_info(PARTITION_STATS *stat_info,
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)
{ return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 819ba69a147..9a1a5e111a5 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -256,16 +256,16 @@ bool partition_info::set_read_partitions(List<char> *partition_names)
Prune away partitions not mentioned in the PARTITION () clause,
if used.
- @param table_list Table list pointing to table to prune.
+ @param partition_names list of names of partitions.
@return Operation status
@retval true Failure
@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));
- uint num_names= table_list->partition_names->elements;
+ List_iterator<String> partition_names_it(*(partition_names));
+ uint num_names= partition_names->elements;
uint i= 0;
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
- @param table_list Possible TABLE_LIST which can contain
- list of partition names to query
+ @param partition_names list of partition names to query
@return Operation status
@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.
*/
-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");
@@ -315,16 +314,15 @@ bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
if (!bitmaps_are_initialized)
DBUG_RETURN(TRUE);
- if (table_list &&
- table_list->partition_names &&
- table_list->partition_names->elements)
+ if (partition_names &&
+ partition_names->elements)
{
if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
{
my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(true);
}
- if (prune_partition_bitmaps(table_list))
+ if (prune_partition_bitmaps(partition_names))
DBUG_RETURN(TRUE);
}
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
up with the names.
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 67a62874fcd..4a37008811a 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -325,7 +325,8 @@ public:
partition_info *get_clone(THD *thd);
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 */
bool is_sub_partitioned()
{
@@ -386,7 +387,7 @@ private:
char *create_default_subpartition_name(THD *thd, uint subpart_no,
const char *part_name);
// 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);
public:
bool set_read_partitions(List<char> *partition_names);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 45efa6330b0..bd2bc54efb4 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1512,6 +1512,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
MDL_ticket *mdl_ticket;
TABLE_SHARE *share;
uint gts_flags;
+ int part_names_error=0;
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->query_id= thd->query_id;
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;
}
/*
@@ -1892,6 +1899,12 @@ retry_share:
{
DBUG_ASSERT(table->file != NULL);
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
{
@@ -1904,7 +1917,8 @@ retry_share:
error= open_table_from_share(thd, share, alias,
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
EXTRA_RECORD,
- thd->open_options, table, FALSE);
+ thd->open_options, table, FALSE,
+ table_list->partition_names);
if (error)
{
@@ -1953,9 +1967,12 @@ retry_share:
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->part_info)
{
- /* Set all [named] partitions as used. */
- if (table->part_info->set_partition_bitmaps(table_list))
+ /* Partitions specified were incorrect.*/
+ if (part_names_error)
+ {
+ table->file->print_error(part_names_error, MYF(0));
DBUG_RETURN(true);
+ }
}
else if (table_list->partition_names)
{
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 8168397da85..4fb1891baab 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -802,8 +802,8 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
DBUG_RETURN(true);
partition_names_list.push_back(str_partition_name, thd->mem_root);
}
- first_table->partition_names= &partition_names_list;
- if (first_table->table->part_info->set_partition_bitmaps(first_table))
+ if (first_table->table->
+ part_info->set_partition_bitmaps(&partition_names_list))
DBUG_RETURN(true);
if (lock_tables(thd, first_table, table_counter, 0))
diff --git a/sql/table.cc b/sql/table.cc
index cd635d32b71..e6b6ea63e0e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3100,6 +3100,7 @@ static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
prgflag READ_ALL etc..
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
outparam result table
+ partitions_to_open open only these partitions.
RETURN VALUES
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,
const char *alias, uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
- bool is_create_table)
+ bool is_create_table, List<String> *partitions_to_open)
{
enum open_frm_error error;
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,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
- ha_open_flags);
+ ha_open_flags, 0, partitions_to_open);
if (ha_err)
{
share->open_errno= ha_err;
diff --git a/sql/table.h b/sql/table.h
index 48e9bbb42ce..173bb49bc2b 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -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,
const char *alias, uint db_stat, uint prgflag,
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_for_read(THD *thd, Field *field,
Virtual_column_info *vcol);