diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2020-04-16 00:44:20 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2020-10-22 05:21:35 +0900 |
commit | ac8d20579512e05001f9bf8193187e47c870d35a (patch) | |
tree | eb39aeb0a3dd3e9565f53b399659074cde2481ef /sql/ha_partition.cc | |
parent | fdf87973cb5246c2edbd11945e65aedb06889bcc (diff) | |
download | mariadb-git-ac8d20579512e05001f9bf8193187e47c870d35a.tar.gz |
MDEV-20100 MariaDB 13.3.9 Crash "[ERROR] mysqld got signal 11 ;"
Some functions on ha_partition call functions on all partitions, but handler->reset() is only called that pruned by m_partitions_to_reset. So Spider didn't clear pointer on unpruned partitions, if the unpruned partitions are used by next query, Spider reference the pointer that is already freed.
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index f745acda75f..5a48af51d3d 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -11148,7 +11148,7 @@ TABLE_LIST *ha_partition::get_next_global_for_child() const COND *ha_partition::cond_push(const COND *cond) { - handler **file= m_file; + uint i; COND *res_cond= NULL; DBUG_ENTER("ha_partition::cond_push"); @@ -11158,26 +11158,35 @@ const COND *ha_partition::cond_push(const COND *cond) We want to do this in a separate loop to not come into a situation where we have only done cond_push() to some of the tables */ - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - if (((*file)->set_top_table_and_fields(top_table, - top_table_field, - top_table_fields))) - DBUG_RETURN(cond); // Abort cond push, no error - } while (*(++file)); - file= m_file; + if (bitmap_is_set(&m_opened_partitions, i)) + { + if ((m_file[i]->set_top_table_and_fields(top_table, + top_table_field, + top_table_fields))) + DBUG_RETURN(cond); // Abort cond push, no error + } + } } - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - if ((*file)->pushed_cond != cond) + if (bitmap_is_set(&m_opened_partitions, i)) { - if ((*file)->cond_push(cond)) - res_cond= (COND *) cond; - else - (*file)->pushed_cond= cond; + if (m_file[i]->pushed_cond != cond) + { + if (m_file[i]->cond_push(cond)) + res_cond= (COND *) cond; + else + m_file[i]->pushed_cond= cond; + } } - } while (*(++file)); + } DBUG_RETURN(res_cond); } @@ -11189,13 +11198,18 @@ const COND *ha_partition::cond_push(const COND *cond) void ha_partition::cond_pop() { - handler **file= m_file; + uint i; DBUG_ENTER("ha_partition::cond_pop"); - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - (*file)->cond_pop(); - } while (*(++file)); + if (bitmap_is_set(&m_opened_partitions, i)) + { + m_file[i]->cond_pop(); + } + } DBUG_VOID_RETURN; } @@ -11779,23 +11793,29 @@ int ha_partition::pre_direct_delete_rows() int ha_partition::info_push(uint info_type, void *info) { - int error= 0; - handler **file= m_file; + int error= 0, tmp; + uint i; DBUG_ENTER("ha_partition::info_push"); - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - int tmp; - if ((tmp= (*file)->info_push(info_type, info))) - error= tmp; - } while (*(++file)); + if (bitmap_is_set(&m_opened_partitions, i)) + { + if ((tmp= m_file[i]->info_push(info_type, info))) + { + error= tmp; + } + } + } DBUG_RETURN(error); } void ha_partition::clear_top_table_fields() { - handler **file; + uint i; DBUG_ENTER("ha_partition::clear_top_table_fields"); if (set_top_table_fields) @@ -11804,8 +11824,15 @@ void ha_partition::clear_top_table_fields() top_table= NULL; top_table_field= NULL; top_table_fields= 0; - for (file= m_file; *file; file++) - (*file)->clear_top_table_fields(); + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) + { + if (bitmap_is_set(&m_opened_partitions, i)) + { + m_file[i]->clear_top_table_fields(); + } + } } DBUG_VOID_RETURN; } |