diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2019-10-02 16:04:52 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2019-10-07 13:30:22 +0400 |
commit | adefaeffcce7c4ae0844f72dd920603b35285d40 (patch) | |
tree | e5396eeec14a2283b36f5b0ff208562a21e7ef99 /sql/sql_statistics.cc | |
parent | e43791d4dc8feb2c02a08ce73c0bb0e2c320018c (diff) | |
download | mariadb-git-adefaeffcce7c4ae0844f72dd920603b35285d40.tar.gz |
MDEV-19536 - Server crash or ASAN heap-use-after-free in is_temporary_table /
read_statistics_for_tables_if_needed
Regression after 279a907, read_statistics_for_tables_if_needed() was
called after open_normal_and_derived_tables() failure.
Fixed by moving read_statistics_for_tables() call to a branch of
get_schema_stat_record() where result of open_normal_and_derived_tables()
is checked.
Removed THD::force_read_stats, added read_statistics_for_tables() instead.
Simplified away statistics_for_command_is_needed().
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 83 |
1 files changed, 27 insertions, 56 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e18cec589be..4a1ed9cde4e 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2161,54 +2161,6 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) /** - @brief - Check whether any persistent statistics for the processed command is needed - - @param - thd The thread handle - - @details - The function checks whether any persitent statistics for the processed - command is needed to be read. - - @retval - TRUE statistics is needed to be read - @retval - FALSE Otherwise -*/ - -static -inline bool statistics_for_command_is_needed(THD *thd) -{ - if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) - return FALSE; - - if (thd->force_read_stats) - return TRUE; - - switch(thd->lex->sql_command) { - case SQLCOM_SELECT: - case SQLCOM_INSERT: - case SQLCOM_INSERT_SELECT: - case SQLCOM_UPDATE: - case SQLCOM_UPDATE_MULTI: - case SQLCOM_DELETE: - case SQLCOM_DELETE_MULTI: - case SQLCOM_REPLACE: - case SQLCOM_REPLACE_SELECT: - case SQLCOM_CREATE_TABLE: - case SQLCOM_SET_OPTION: - case SQLCOM_DO: - break; - default: - return FALSE; - } - - return TRUE; -} - - -/** @brief Allocate memory for the statistical data used by a table share @@ -2255,9 +2207,6 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share) DEBUG_SYNC(thd, "statistics_mem_alloc_start1"); DEBUG_SYNC(thd, "statistics_mem_alloc_start2"); - if (!statistics_for_command_is_needed(thd)) - DBUG_RETURN(1); - mysql_mutex_lock(&table_share->LOCK_share); if (stats_cb->stats_can_be_read) @@ -3110,9 +3059,6 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) { if (!tables) return FALSE; - - if (!statistics_for_command_is_needed(thd)) - return FALSE; /* Do not read statistics for any query that explicity involves @@ -3245,14 +3191,39 @@ int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) { + switch (thd->lex->sql_command) { + case SQLCOM_SELECT: + case SQLCOM_INSERT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: + case SQLCOM_DELETE: + case SQLCOM_DELETE_MULTI: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_CREATE_TABLE: + case SQLCOM_SET_OPTION: + case SQLCOM_DO: + return read_statistics_for_tables(thd, tables); + default: + return 0; + } +} + + +int read_statistics_for_tables(THD *thd, TABLE_LIST *tables) +{ TABLE_LIST stat_tables[STATISTICS_TABLES]; Open_tables_backup open_tables_backup; - DBUG_ENTER("read_statistics_for_tables_if_needed"); + DBUG_ENTER("read_statistics_for_tables"); + + if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) + DBUG_RETURN(0); for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (get_use_stat_tables_mode(thd) > NEVER && tl->table) + if (tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && table_share->table_category == TABLE_CATEGORY_USER && |