summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2021-10-05 17:08:16 +0300
committerMonty <monty@mariadb.org>2022-11-29 15:12:43 +0200
commit02fad722c597372e6ef7d1e79c526f7e266c90a9 (patch)
treec499f5a4d0ec3fb82d9e17e3f99eb62475e548cc
parentdc220b25b70126848c7ef548aa08eedd4aeb59de (diff)
downloadmariadb-git-02fad722c597372e6ef7d1e79c526f7e266c90a9.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.result8
-rw-r--r--mysql-test/main/derived_cond_pushdown.result6
-rw-r--r--mysql-test/main/mysql_upgrade_noengine.result4
-rw-r--r--mysql-test/main/selectivity_innodb.result2
-rw-r--r--mysql-test/main/sql_safe_updates.result13
-rw-r--r--mysql-test/main/sql_safe_updates.test7
-rw-r--r--mysql-test/main/stat_tables.result2
-rw-r--r--mysql-test/main/stat_tables_innodb.result2
-rw-r--r--mysql-test/suite/gcol/r/gcol_bugfixes.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result12
-rw-r--r--mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result2
-rw-r--r--sql/opt_range.cc26
-rw-r--r--sql/sql_help.cc23
-rw-r--r--sql/sql_statistics.cc9
-rw-r--r--storage/blackhole/ha_blackhole.cc11
16 files changed, 85 insertions, 50 deletions
diff --git a/mysql-test/main/analyze_stmt_privileges2.result b/mysql-test/main/analyze_stmt_privileges2.result
index 2b75f736a22..4a499e0c7ef 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 e07f2550297..90ef51b005a 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -19281,7 +19281,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;
#
@@ -19749,7 +19749,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY <derived2> ref key0 key0 5 test.t3.id 2
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
-2 DERIVED cp2 range NULL a 5 NULL 8 Using index for group-by
+2 DERIVED cp2 range NULL a 5 NULL 7 Using index for group-by
explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3
where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2);
EXPLAIN
@@ -19830,7 +19830,7 @@ EXPLAIN
"key": "a",
"key_length": "5",
"used_key_parts": ["a"],
- "rows": 8,
+ "rows": 7,
"filtered": 100,
"using_index_for_group_by": true
}
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/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result
index 4f37fcddbec..1b77d152677 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 947dcabcd77..126fda6ddc7 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 f124ebe611c..7b70f61df03 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 aa8cc118ce6..3383d4b6826 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 6825918cb89..19d65f52ee1 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2683,11 +2683,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();
@@ -2696,10 +2701,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;
@@ -2726,8 +2729,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");
{
@@ -2893,7 +2896,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;
@@ -2992,7 +2996,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;
@@ -3034,7 +3038,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if ((group_trp= get_best_group_min_max(&param, 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()))
@@ -3059,6 +3063,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(&param, TRUE)) || quick->init())
{
delete quick;
@@ -3092,7 +3097,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 40760c1e2eb..5930ebd8256 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -3741,10 +3741,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);