Commit 674842be authored by Monty's avatar Monty

MDEV-28858 Wrong result with table elimination combined with not_null_range_scan

The bug was that build_notnull_conds_for_range_scans() did not take into
account the join_tab is not yet sorted with constant tables first.
Fixed the bug by testing explicitely if a table is a const table.
parent 27309fc6
...@@ -3635,6 +3635,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL; ...@@ -3635,6 +3635,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
a pk b a pk b
DROP TABLE t1, t2; DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch; SET @@optimizer_switch= @save_optimizer_switch;
# MDEV-28858 Wrong result with table elimination combined with
# not_null_range_scan
#
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,1),(null,2);
CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
SET @save_optimizer_switch= @@optimizer_switch;
SET optimizer_switch= 'not_null_range_scan=on';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
b
2
SET optimizer_switch= 'not_null_range_scan=off';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
b
2
SET @@optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
# #
# End of 10.5 tests # End of 10.5 tests
# #
......
...@@ -2492,6 +2492,24 @@ DROP TABLE t1, t2; ...@@ -2492,6 +2492,24 @@ DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch; SET @@optimizer_switch= @save_optimizer_switch;
--echo
--echo # MDEV-28858 Wrong result with table elimination combined with
--echo # not_null_range_scan
--echo #
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,1),(null,2);
CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
SET @save_optimizer_switch= @@optimizer_switch;
SET optimizer_switch= 'not_null_range_scan=on';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
SET optimizer_switch= 'not_null_range_scan=off';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
SET @@optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
--echo # --echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo # --echo #
......
...@@ -3624,6 +3624,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL; ...@@ -3624,6 +3624,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
a pk b a pk b
DROP TABLE t1, t2; DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch; SET @@optimizer_switch= @save_optimizer_switch;
# MDEV-28858 Wrong result with table elimination combined with
# not_null_range_scan
#
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10,1),(null,2);
CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
SET @save_optimizer_switch= @@optimizer_switch;
SET optimizer_switch= 'not_null_range_scan=on';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
b
2
SET optimizer_switch= 'not_null_range_scan=off';
SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
b
2
SET @@optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
# #
# End of 10.5 tests # End of 10.5 tests
# #
......
...@@ -29573,11 +29573,12 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond, ...@@ -29573,11 +29573,12 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond,
DBUG_ENTER("build_notnull_conds_for_range_scans"); DBUG_ENTER("build_notnull_conds_for_range_scans");
for (JOIN_TAB *s= join->join_tab + join->const_tables ; for (JOIN_TAB *s= join->join_tab;
s < join->join_tab + join->table_count ; s++) s < join->join_tab + join->table_count ; s++)
{ {
/* Clear all needed bitmaps to mark found fields */ /* Clear all needed bitmaps to mark found fields */
if (allowed & s->table->map) if ((allowed & s->table->map) &&
!(s->table->map && join->const_table_map))
bitmap_clear_all(&s->table->tmp_set); bitmap_clear_all(&s->table->tmp_set);
} }
...@@ -29592,17 +29593,18 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond, ...@@ -29592,17 +29593,18 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond,
For each table t from 'allowed' build a conjunction of NOT NULL predicates For each table t from 'allowed' build a conjunction of NOT NULL predicates
constructed for all found fields if they are included in some indexes. constructed for all found fields if they are included in some indexes.
If the construction of the conjunction succeeds attach the formula to If the construction of the conjunction succeeds attach the formula to
t->table->notnull_cond. The condition will be used to look for complementary t->table->notnull_cond. The condition will be used to look for
range scans. complementary range scans.
*/ */
for (JOIN_TAB *s= join->join_tab + join->const_tables ; for (JOIN_TAB *s= join->join_tab ;
s < join->join_tab + join->table_count ; s++) s < join->join_tab + join->table_count ; s++)
{ {
TABLE *tab= s->table; TABLE *tab= s->table;
List<Item> notnull_list; List<Item> notnull_list;
Item *notnull_cond= 0; Item *notnull_cond= 0;
if (!(allowed & tab->map)) if (!(allowed & tab->map) ||
(s->table->map && join->const_table_map))
continue; continue;
for (Field** field_ptr= tab->field; *field_ptr; field_ptr++) for (Field** field_ptr= tab->field; *field_ptr; field_ptr++)
......
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