Commit 9a4110aa authored by Monty's avatar Monty

MDEV-30256 Wrong result (missing rows) upon join with empty table

The problem was an assignment in test_quick_select() that flagged empty
tables with "Impossible where". This test was however wrong as it
didn't work correctly for left join.

Removed the test, but added checking of empty tables in DELETE and UPDATE
to get similar EXPLAIN as before.

The new tests is a bit more strict (better) than before as it catches all
cases of empty tables in single table DELETE/UPDATE.
parent e3f56254
......@@ -258,7 +258,7 @@ drop table t1;
create table t1 (i int);
analyze delete from t1 returning *;
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 0 0.00 100.00 100.00
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
drop table t1;
#
# MDEV-6396: ANALYZE INSERT/REPLACE is accepted, but does not produce a plan
......
......@@ -21096,7 +21096,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`,NULL AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0
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
DROP VIEW v1,v2;
DROP TABLE t1;
#
......
......@@ -145,7 +145,7 @@ DROP TABLE t1;
create table t1 (i int);
explain partitions update t1 set i = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 0
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
create table t2 (a int, b int) partition by hash(a) partitions 5;
insert into t2 values (0,0),(1,1),(2,2),(3,3),(4,4);
explain partitions update t2 set b=3 where a in (3,4);
......
......@@ -63,6 +63,7 @@ c27 TEXT,
c28 TEXT,
primary key (pk)
);
insert into t1 (pk) values (1),(2),(3);
CALL mtr.add_suppression("Out of sort memory");
DELETE IGNORE FROM t1 ORDER BY c26,c7,c23,c4,c25,c5,c20,
c19,c21,c8,c1,c27,c28,c3,c9,c22,c24,c6,c2,pk LIMIT 2;
......
......@@ -86,6 +86,8 @@ CREATE TABLE t1 (
primary key (pk)
);
insert into t1 (pk) values (1),(2),(3);
CALL mtr.add_suppression("Out of sort memory");
--error ER_OUT_OF_SORTMEMORY
......
......@@ -3435,4 +3435,24 @@ SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.
COUNT(*)
2
DROP TABLE t1, t2, t3;
# End of 10.5 tests
#
# MDEV-30256 Wrong result (missing rows) upon join with empty table
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (3),(4);
CREATE TABLE t3 (c INT PRIMARY KEY);
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 0 Using index; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b);
a b c
1 NULL NULL
2 NULL NULL
DROP TABLE t1,t2,t3;
#
# End of 11.0 tests
#
......@@ -1838,4 +1838,19 @@ SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
DROP TABLE t1, t2, t3;
--echo # End of 10.5 tests
--echo #
--echo # MDEV-30256 Wrong result (missing rows) upon join with empty table
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (3),(4);
CREATE TABLE t3 (c INT PRIMARY KEY);
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b);
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b);
DROP TABLE t1,t2,t3;
--echo #
--echo # End of 11.0 tests
--echo #
......@@ -2978,8 +2978,7 @@ JOIN t1 AS a12 ON a12.c1 = a11.c1
) d1
);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
DROP TABLE t1, t2, t3;
#73
CREATE TABLE t1 (id INT);
......@@ -3106,7 +3105,7 @@ CALL p10();
DROP PROCEDURE p10;
CALL p9();
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 0
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
DROP PROCEDURE p9;
CALL p8();
DROP PROCEDURE p8;
......
......@@ -5552,13 +5552,11 @@ CREATE TABLE t2 (c2 INT) ENGINE=MyISAM;
CREATE TABLE t3 (c3 INT) ENGINE=MyISAM;
EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
PREPARE stmt FROM "EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 )";
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2, t3;
#
......
......@@ -2338,11 +2338,7 @@ Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave
UPDATE t1 SET a=1 LIMIT 1;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
DELETE FROM t1 LIMIT 1;
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
CREATE PROCEDURE p1()
BEGIN
INSERT INTO t1 SELECT * FROM t1 LIMIT 1;
......
......@@ -2716,8 +2716,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
SEL_ARG **backup_keys= 0;
ha_rows table_records= head->stat_records();
handler *file= head->file;
/* We trust that if stat_records() is 0 the table is really empty! */
bool impossible_range= table_records == 0;
bool impossible_range= 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,
......
......@@ -526,7 +526,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error);
if (unlikely(error))
DBUG_RETURN(TRUE);
if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
if (unlikely((select && select->check_quick(thd, safe_update, limit)) ||
table->stat_records() == 0 ||
!limit))
{
query_plan.set_impossible_where();
if (thd->lex->describe || thd->lex->analyze_stmt)
......
......@@ -581,8 +581,10 @@ int mysql_update(THD *thd,
set_statistics_for_table(thd, table);
select= make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error);
if (unlikely(error || !limit || thd->is_error() ||
(select && select->check_quick(thd, safe_update, limit))))
if (unlikely(error || thd->is_error() || !limit ||
(select && select->check_quick(thd, safe_update, limit)) ||
table->stat_records() == 0))
{
query_plan.set_impossible_where();
if (thd->lex->describe || thd->lex->analyze_stmt)
......
......@@ -481,7 +481,6 @@ DELETE FROM t1;
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
TRUNCATE t1;
Warnings:
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
......
......@@ -481,7 +481,6 @@ DELETE FROM t1;
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
TRUNCATE t1;
Warnings:
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment