diff options
author | Varun Gupta <varunraiko1803@gmail.com> | 2018-04-02 13:14:30 +0300 |
---|---|---|
committer | Varun Gupta <varunraiko1803@gmail.com> | 2018-04-02 13:14:30 +0300 |
commit | 10f6b7001bd7b683c013ae407c2c48793caa3633 (patch) | |
tree | 490dca62fe625e6ea7a6417df72c90b398099aa8 /sql/sql_statistics.cc | |
parent | 6aff5fa27ae863670608ae88b134453fe53c3e17 (diff) | |
download | mariadb-git-10f6b7001bd7b683c013ae407c2c48793caa3633.tar.gz |
MDEV-9744: session optimizer_use_condition_selectivity=5 causing SQL Error (1918):
Encountered illegal value '' when converting to DECIMAL
The issue was that EITS data was allocated but then not read for some reason (one being to avoid a deadlock),
then the optimizer was using these bzero'ed buffers as EITS statistics.
This should not be allowed, we should use statistcs for a table only when we have successfully loaded/read
the stats from the statistical tables.
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 70080a6b4f1..6c42efd6068 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2944,18 +2944,19 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) return FALSE; /* - Do not read statistics for any query over non-user tables. - If the query references some statistical tables, but not all - of them, reading the statistics may lead to a deadlock - */ + Do not read statistics for any query that explicity involves + statistical tables, failure to to do so we may end up + in a deadlock. + */ + for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { if (!tl->is_view_or_derived() && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && - (table_share->table_category != TABLE_CATEGORY_USER || - table_share->tmp_table != NO_TMP_TABLE)) + table_share->table_category != TABLE_CATEGORY_USER + && is_stat_table(tl->db, tl->alias)) return FALSE; } } @@ -3634,6 +3635,15 @@ double get_column_range_cardinality(Field *field, if (!col_stats) return tab_records; + /* + Use statistics for a table only when we have actually read + the statistics from the stat tables. For example due to + chances of getting a deadlock we disable reading statistics for + a table. + */ + + if (!table->stats_is_read) + return tab_records; double col_nulls= tab_records * col_stats->get_nulls_ratio(); @@ -3840,3 +3850,20 @@ double Histogram::point_selectivity(double pos, double avg_sel) return sel; } +/* + Check whether the table is one of the persistent statistical tables. +*/ +bool is_stat_table(const char *db, const char *table) +{ + DBUG_ASSERT(db && table); + + if (!memcmp(db, stat_tables_db_name.str, stat_tables_db_name.length)) + { + for (uint i= 0; i < STATISTICS_TABLES; i ++) + { + if (!memcmp(table, stat_table_name[i].str, stat_table_name[i].length)) + return true; + } + } + return false; +}
\ No newline at end of file |