Commit b9e210bb authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-32555 wrong result with an index and a partially null-rejecting condition

ref->null_rejecting is a key_part_map. we need to check
the bit corresponding to the particular store_key.
Note that there are no store_key objects for const ref parts.
parent d2a867cd
drop table if exists x1;
drop table if exists x2;
set @tmp_subselect_nulls=@@optimizer_switch; set @tmp_subselect_nulls=@@optimizer_switch;
set optimizer_switch='semijoin=off'; set optimizer_switch='semijoin=off';
create table x1(k int primary key, d1 int, d2 int); create table x1(k int primary key, d1 int, d2 int);
...@@ -115,9 +113,44 @@ k d1 d2 ...@@ -115,9 +113,44 @@ k d1 d2
set optimizer_switch= @tmp_subselect_nulls; set optimizer_switch= @tmp_subselect_nulls;
drop table x1; drop table x1;
drop table x2; drop table x2;
#
# MDEV-7339 Server crashes in Item_func_trig_cond::val_int
#
select (select 1, 2) in (select 3, 4); select (select 1, 2) in (select 3, 4);
(select 1, 2) in (select 3, 4) (select 1, 2) in (select 3, 4)
0 0
select (select NULL, NULL) in (select 3, 4); select (select NULL, NULL) in (select 3, 4);
(select NULL, NULL) in (select 3, 4) (select NULL, NULL) in (select 3, 4)
NULL NULL
#
# End of 5.5 tests
#
#
# MDEV-32555 wrong result with an index and a partially null-rejecting condition
#
create table t1 (a int primary key);
insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (
b int not null,
c int default null,
d int not null,
e int not null,
unique key (d,b,c)
);
insert t2 values (1,null,1,1),(1,null,2,2),(1,null,3,3),(1,null,4,4),(2,null,1,2),(3,null,1,3),(4,null,2,2),(4,null,1,4);
select (
select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1
) x from t2 left join t1 on a = b;
x
1
2
3
4
1
4
1
1
drop table t1, t2;
#
# End of 10.10 tests
#
# Initialize tables for the test
--disable_warnings
drop table if exists x1;
drop table if exists x2;
--enable_warnings
set @tmp_subselect_nulls=@@optimizer_switch; set @tmp_subselect_nulls=@@optimizer_switch;
set optimizer_switch='semijoin=off'; set optimizer_switch='semijoin=off';
...@@ -98,8 +91,39 @@ set optimizer_switch= @tmp_subselect_nulls; ...@@ -98,8 +91,39 @@ set optimizer_switch= @tmp_subselect_nulls;
drop table x1; drop table x1;
drop table x2; drop table x2;
# --echo #
# MDEV-7339 Server crashes in Item_func_trig_cond::val_int --echo # MDEV-7339 Server crashes in Item_func_trig_cond::val_int
# --echo #
select (select 1, 2) in (select 3, 4); select (select 1, 2) in (select 3, 4);
select (select NULL, NULL) in (select 3, 4); select (select NULL, NULL) in (select 3, 4);
--echo #
--echo # End of 5.5 tests
--echo #
--echo #
--echo # MDEV-32555 wrong result with an index and a partially null-rejecting condition
--echo #
create table t1 (a int primary key);
insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (
b int not null,
c int default null,
d int not null,
e int not null,
unique key (d,b,c)
);
insert t2 values (1,null,1,1),(1,null,2,2),(1,null,3,3),(1,null,4,4),(2,null,1,2),(3,null,1,3),(4,null,2,2),(4,null,1,4);
select (
select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1
) x from t2 left join t1 on a = b;
drop table t1, t2;
--echo #
--echo # End of 10.10 tests
--echo #
...@@ -151,6 +151,7 @@ void Expression_cache_tmptable::init() ...@@ -151,6 +151,7 @@ void Expression_cache_tmptable::init()
} }
cache_table->s->keys= 1; cache_table->s->keys= 1;
ref.null_rejecting= 1; ref.null_rejecting= 1;
ref.const_ref_part_map= 0;
ref.disable_cache= FALSE; ref.disable_cache= FALSE;
ref.has_record= 0; ref.has_record= 0;
ref.use_count= 0; ref.use_count= 0;
......
...@@ -26078,12 +26078,15 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) ...@@ -26078,12 +26078,15 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields; enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
bool result= 0; bool result= 0;
key_part_map map= 1;
thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->count_cuted_fields= CHECK_FIELD_IGNORE;
for (store_key **copy=ref->key_copy ; *copy ; copy++) for (store_key **copy=ref->key_copy ; *copy ; copy++, map <<= 1)
{ {
while (map & ref->const_ref_part_map) // skip const ref parts
map <<= 1; // no store_key objects for them
if ((*copy)->copy(thd) & 1 || if ((*copy)->copy(thd) & 1 ||
(ref->null_rejecting && (*copy)->null_key)) ((ref->null_rejecting & map) && (*copy)->null_key))
{ {
result= 1; result= 1;
break; break;
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