diff options
author | Monty <monty@mariadb.org> | 2021-10-05 17:08:16 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2022-07-07 18:15:25 +0300 |
commit | cf10de163eafd5e73f2bd9f3b64f7f65b14e819b (patch) | |
tree | b63606f1c5cd17978814c24f51b2700b7bab9020 | |
parent | e764e6501bf8d3a647ac4253d4ad03ea0986e708 (diff) | |
download | mariadb-git-cf10de163eafd5e73f2bd9f3b64f7f65b14e819b.tar.gz |
Ensure that test_quick_select doesn't return more rows than in the table
Other changes:
- In test_quick_select(), assume that if table->used_stats_records is 0
then the table has 0 rows.
- Fixed prepare_simple_select() to populate table->used_stat_records
- Enusre that set_statistics_for_tables() doesn't cause used_stats_records
to be 0 when using stat_tables.
- To get blackhole to work with replication, set stats.records to 2 so
that test_quick_select() doesn't assume the table is empty.
-rw-r--r-- | mysql-test/main/analyze_stmt_privileges2.result | 8 | ||||
-rw-r--r-- | mysql-test/main/derived_cond_pushdown.result | 2 | ||||
-rw-r--r-- | mysql-test/main/mysql_upgrade_noengine.result | 4 | ||||
-rw-r--r-- | mysql-test/main/mysqld--help.test | 1 | ||||
-rw-r--r-- | mysql-test/main/selectivity_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/main/sql_safe_updates.result | 13 | ||||
-rw-r--r-- | mysql-test/main/sql_safe_updates.test | 7 | ||||
-rw-r--r-- | mysql-test/main/stat_tables.result | 2 | ||||
-rw-r--r-- | mysql-test/main/stat_tables_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/gcol/r/gcol_bugfixes.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_mysql.result | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 26 | ||||
-rw-r--r-- | sql/sql_help.cc | 23 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 9 | ||||
-rw-r--r-- | storage/blackhole/ha_blackhole.cc | 11 |
17 files changed, 84 insertions, 48 deletions
diff --git a/mysql-test/main/analyze_stmt_privileges2.result b/mysql-test/main/analyze_stmt_privileges2.result index f269aaf540b..4f5bd6708c9 100644 --- a/mysql-test/main/analyze_stmt_privileges2.result +++ b/mysql-test/main/analyze_stmt_privileges2.result @@ -1445,10 +1445,10 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f DELETE FROM t1 WHERE a = 10; EXPLAIN DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE ANALYZE DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DELETE FROM t1 USING t1, t2; EXPLAIN DELETE FROM t1 USING t1, t2; id select_type table type possible_keys key key_len ref rows Extra @@ -1790,10 +1790,10 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f DELETE FROM t1 WHERE a = 10; EXPLAIN DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE ANALYZE DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DELETE FROM t1 USING t1, t2; EXPLAIN DELETE FROM t1 USING t1, t2; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 5b0cc4a08f5..d598a1e7eb4 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -16917,7 +16917,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: -Note 1003 /* select#1 */ select NULL AS `f`,`v2`.`f` AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0 +Note 1003 /* select#1 */ select NULL AS `f`,NULL AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0 DROP VIEW v1,v2; DROP TABLE t1; # diff --git a/mysql-test/main/mysql_upgrade_noengine.result b/mysql-test/main/mysql_upgrade_noengine.result index 459a1a6ce34..830b574fb9c 100644 --- a/mysql-test/main/mysql_upgrade_noengine.result +++ b/mysql-test/main/mysql_upgrade_noengine.result @@ -11,7 +11,7 @@ table_name t1 table_type BASE TABLE engine BLACKHOLE row_format Fixed -table_rows 0 +table_rows 2 data_length 0 table_comment select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test' and table_name='t2'; @@ -610,7 +610,7 @@ table_name t1 table_type BASE TABLE engine BLACKHOLE row_format Fixed -table_rows 0 +table_rows 2 data_length 0 table_comment select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test' and table_name='t2'; diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index 95ae49b5c89..d72d4a31cf5 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -38,6 +38,7 @@ perl; test-sql-discovery query-cache-info password-reuse-check query-response-time metadata-lock-info locales unix-socket wsrep file-key-management cracklib-password-check user-variables + provider-bzip2 provider-lzma provider-lzo thread-pool-groups thread-pool-queues thread-pool-stats thread-pool-waits/; # And substitute the content some environment variables with their diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index 07cdf15163c..b60eb9681bb 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -946,7 +946,7 @@ set optimizer_switch='index_condition_pushdown=off'; EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a > 9; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 5 NULL 1 0.00 Using where +1 SIMPLE t1 range a a 5 NULL 1 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` > 9 diff --git a/mysql-test/main/sql_safe_updates.result b/mysql-test/main/sql_safe_updates.result index f2944e60489..099aaa9bca6 100644 --- a/mysql-test/main/sql_safe_updates.result +++ b/mysql-test/main/sql_safe_updates.result @@ -9,18 +9,23 @@ select @@sql_safe_updates; # create table t1 (a int, b int, primary key (a), key (b)); update t1 set b=2 where a=1 or b=2; -ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column explain update t1 set b=2 where a=1 or b=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t1 where a=1 or b=2; -ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column explain delete from t1 where a=1 or b=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8); +explain update t1 set b=2 where a=1 or b=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,b PRIMARY,b 4,5 NULL 2 Using union(PRIMARY,b); Using where; Using buffer update t1 set b=2 where a=1 or b=2; +set @@optimizer_switch="index_merge=off"; +update t1 set b=2 where a=1 or b=2; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where a=1 or b=2; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column drop table t1; # # End of 10.3 tests diff --git a/mysql-test/main/sql_safe_updates.test b/mysql-test/main/sql_safe_updates.test index 25fe4a15ca2..becabb6881e 100644 --- a/mysql-test/main/sql_safe_updates.test +++ b/mysql-test/main/sql_safe_updates.test @@ -7,14 +7,17 @@ select @@sql_safe_updates; --echo # MDEV-18304 sql_safe_updates does not work with OR clauses --echo # create table t1 (a int, b int, primary key (a), key (b)); ---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE update t1 set b=2 where a=1 or b=2; explain update t1 set b=2 where a=1 or b=2; ---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE delete from t1 where a=1 or b=2; explain delete from t1 where a=1 or b=2; insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8); +explain update t1 set b=2 where a=1 or b=2; update t1 set b=2 where a=1 or b=2; +set @@optimizer_switch="index_merge=off"; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +update t1 set b=2 where a=1 or b=2; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE delete from t1 where a=1 or b=2; drop table t1; diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index 22f5bfafb8e..afcf315b47f 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -412,7 +412,7 @@ EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 WHERE name IN ( 'AUS','YEM' ) AND id = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where ANALYZE TABLE t2; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 5b62f228b1f..13f990ed54f 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -444,7 +444,7 @@ EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 WHERE name IN ( 'AUS','YEM' ) AND id = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where ANALYZE TABLE t2; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected diff --git a/mysql-test/suite/gcol/r/gcol_bugfixes.result b/mysql-test/suite/gcol/r/gcol_bugfixes.result index 6d93c63fc2f..1d4fbef3aeb 100644 --- a/mysql-test/suite/gcol/r/gcol_bugfixes.result +++ b/mysql-test/suite/gcol/r/gcol_bugfixes.result @@ -638,10 +638,10 @@ DEFAULT SUBSTRING_INDEX(USER(),'@',1) ); EXPLAIN UPDATE gafld SET nuigafld = 0 WHERE nuigafld = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gafld ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE EXPLAIN UPDATE gafld SET nuigafld = 0 WHERE nuigafld = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gafld ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DROP TABLE gafld; # (duplicate) MDEV-17653 replace into generated columns is unstable # Some columns are snipped from the MDEV test diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 309ca847efb..06cc899e5b2 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -191,8 +191,8 @@ min(7) 7 explain select min(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 -1 SIMPLE t2i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) select min(7) from t2i join t1i; min(7) NULL @@ -207,8 +207,8 @@ max(7) 7 explain select max(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 -1 SIMPLE t2i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) select max(7) from t2i join t1i; max(7) NULL @@ -239,7 +239,7 @@ select 1, max(1) from t1i where 1=99; explain select count(*), min(7), max(7) from t1m, t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 select count(*), min(7), max(7) from t1m, t1i; count(*) min(7) max(7) 0 NULL NULL @@ -253,7 +253,7 @@ count(*) min(7) max(7) explain select count(*), min(7), max(7) from t2m, t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2m system NULL NULL NULL NULL 1 -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 select count(*), min(7), max(7) from t2m, t1i; count(*) min(7) max(7) 0 NULL NULL diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result b/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result index 1f8471304d5..b1e6bb7fa72 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result @@ -24,7 +24,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted' ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted'; table_rows 0 @@ -38,7 +38,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted' ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted'; table_rows 0 diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result b/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result index 91bb2bf3ecd..a6627417d1a 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result @@ -22,7 +22,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_nonexistent ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_nonexistent'; table_rows 0 diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7909f5b35f9..8a0392fefb2 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2678,11 +2678,16 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, Item *notnull_cond= NULL; TABLE_READ_PLAN *best_trp= NULL; SEL_ARG **backup_keys= 0; + ha_rows table_records= head->stat_records(); + /* We trust that if stat_records() is 0 the table is really empty! */ + bool impossible_range= table_records == 0; DBUG_ENTER("SQL_SELECT::test_quick_select"); DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables, (ulong) const_tables)); - DBUG_PRINT("info", ("records: %lu", (ulong) head->stat_records())); + DBUG_PRINT("info", ("records: %llu", (ulonglong) table_records)); + DBUG_ASSERT(table_records || !head->file->stats.records); + delete quick; quick=0; needed_reg.clear_all(); @@ -2691,10 +2696,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_ASSERT(!head->is_filled_at_execution()); if (keys_to_use.is_clear_all() || head->is_filled_at_execution()) DBUG_RETURN(0); - records= head->stat_records(); + records= table_records; notnull_cond= head->notnull_cond; - if (!records) - records++; /* purecov: inspected */ if (head->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) only_single_index_range_scan= 1; @@ -2721,8 +2724,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_PRINT("info",("Time to scan table: %g", read_time)); - Json_writer_object table_records(thd); - table_records.add_table_name(head); + Json_writer_object table_info(thd); + table_info.add_table_name(head); Json_writer_object trace_range(thd, "range_analysis"); { @@ -2888,7 +2891,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { if (tree->type == SEL_TREE::IMPOSSIBLE) { - records=0L; /* Return -1 from this function. */ + records= 0; + impossible_range= 1; /* Return -1 from this function. */ read_time= (double) HA_POS_ERROR; trace_range.add("impossible_range", true); goto free_mem; @@ -2987,7 +2991,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, } if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) && - head->stat_records() != 0 && !only_single_index_range_scan) + table_records != 0 && !only_single_index_range_scan) { /* Try creating index_merge/ROR-union scan. */ SEL_IMERGE *imerge; @@ -3029,7 +3033,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if ((group_trp= get_best_group_min_max(¶m, tree, read_time))) { param.table->opt_range_condition_rows= MY_MIN(group_trp->records, - head->stat_records()); + table_records); Json_writer_object grp_summary(thd, "best_group_range_summary"); if (unlikely(thd->trace_started())) @@ -3054,6 +3058,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (best_trp) { records= best_trp->records; + impossible_range= records == 0; // No matching rows if (!(quick= best_trp->make_quick(¶m, TRUE)) || quick->init()) { delete quick; @@ -3087,7 +3092,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, Assume that if the user is using 'limit' we will only need to scan limit rows if we are using a key */ - DBUG_RETURN(records ? MY_TEST(quick) : -1); + set_if_smaller(records, table_records); + DBUG_RETURN(impossible_range ? -1 : MY_TEST(quick)); } /**************************************************************************** diff --git a/sql/sql_help.cc b/sql/sql_help.cc index f9932f11798..51fdd58b9c4 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -664,16 +664,19 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, /* Assume that no indexes cover all required fields */ table->covering_keys.clear_all(); + table->file->info(HA_STATUS_VARIABLE); + table->used_stat_records= table->file->stats.records; SQL_SELECT *res= make_select(table, 0, 0, cond, 0, 0, error); - if (unlikely(*error) || - (likely(res) && unlikely(res->check_quick(thd, 0, HA_POS_ERROR))) || - (likely(res) && res->quick && unlikely(res->quick->reset()))) - { - delete res; - res=0; - } - return res; + if (unlikely(!res) || unlikely(*error)) + goto error; + (void) res->check_quick(thd, 0, HA_POS_ERROR); + if (!res->quick || res->quick->reset() == 0) + return res; + +error: + delete res; + return 0; } /* @@ -1076,7 +1079,9 @@ error: new_trans.restore_old_transaction(); error2: - DBUG_RETURN(TRUE); + if (!thd->is_error()) + my_eof(thd); + DBUG_RETURN(thd->is_error()); } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 3c5e3859939..dd59ba23b0d 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3627,10 +3627,15 @@ void set_statistics_for_table(THD *thd, TABLE *table) { TABLE_STATISTICS_CB *stats_cb= &table->s->stats_cb; Table_statistics *read_stats= stats_cb->table_stats; - table->used_stat_records= + + /* + The MAX below is to ensure that we don't return 0 rows for a table if it + not guaranteed to be empty. + */ + table->used_stat_records= (!check_eits_preferred(thd) || !table->stats_is_read || read_stats->cardinality_is_null) ? - table->file->stats.records : read_stats->cardinality; + table->file->stats.records : MY_MAX(read_stats->cardinality, 1); /* For partitioned table, EITS statistics is based on data from all partitions. diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 0134032351e..343f3c70286 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -182,6 +182,17 @@ int ha_blackhole::info(uint flag) DBUG_ENTER("ha_blackhole::info"); bzero((char*) &stats, sizeof(stats)); + /* + The following is required to get replication to work as otherwise + test_quick_select() will think the table is empty and thus any + update/delete will not have any rows to update. + */ + stats.records= 2; + /* + Block size should not be 0 as this will cause division by zero + in scan_time() + */ + stats.block_size= 8192; if (flag & HA_STATUS_AUTO) stats.auto_increment_value= 1; DBUG_RETURN(0); |