Skip to content

Commit b9e210b

Browse files
committed
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.
1 parent d2a867c commit b9e210b

File tree

4 files changed

+75
-14
lines changed

4 files changed

+75
-14
lines changed

mysql-test/main/subselect_nulls.result

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
drop table if exists x1;
2-
drop table if exists x2;
31
set @tmp_subselect_nulls=@@optimizer_switch;
42
set optimizer_switch='semijoin=off';
53
create table x1(k int primary key, d1 int, d2 int);
@@ -115,9 +113,44 @@ k d1 d2
115113
set optimizer_switch= @tmp_subselect_nulls;
116114
drop table x1;
117115
drop table x2;
116+
#
117+
# MDEV-7339 Server crashes in Item_func_trig_cond::val_int
118+
#
118119
select (select 1, 2) in (select 3, 4);
119120
(select 1, 2) in (select 3, 4)
120121
0
121122
select (select NULL, NULL) in (select 3, 4);
122123
(select NULL, NULL) in (select 3, 4)
123124
NULL
125+
#
126+
# End of 5.5 tests
127+
#
128+
#
129+
# MDEV-32555 wrong result with an index and a partially null-rejecting condition
130+
#
131+
create table t1 (a int primary key);
132+
insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
133+
create table t2 (
134+
b int not null,
135+
c int default null,
136+
d int not null,
137+
e int not null,
138+
unique key (d,b,c)
139+
);
140+
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);
141+
select (
142+
select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1
143+
) x from t2 left join t1 on a = b;
144+
x
145+
1
146+
2
147+
3
148+
4
149+
1
150+
4
151+
1
152+
1
153+
drop table t1, t2;
154+
#
155+
# End of 10.10 tests
156+
#

mysql-test/main/subselect_nulls.test

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
# Initialize tables for the test
2-
3-
--disable_warnings
4-
drop table if exists x1;
5-
drop table if exists x2;
6-
--enable_warnings
7-
81
set @tmp_subselect_nulls=@@optimizer_switch;
92
set optimizer_switch='semijoin=off';
103

@@ -98,8 +91,39 @@ set optimizer_switch= @tmp_subselect_nulls;
9891
drop table x1;
9992
drop table x2;
10093

101-
#
102-
# MDEV-7339 Server crashes in Item_func_trig_cond::val_int
103-
#
94+
--echo #
95+
--echo # MDEV-7339 Server crashes in Item_func_trig_cond::val_int
96+
--echo #
10497
select (select 1, 2) in (select 3, 4);
10598
select (select NULL, NULL) in (select 3, 4);
99+
100+
--echo #
101+
--echo # End of 5.5 tests
102+
--echo #
103+
104+
--echo #
105+
--echo # MDEV-32555 wrong result with an index and a partially null-rejecting condition
106+
--echo #
107+
108+
create table t1 (a int primary key);
109+
insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
110+
111+
create table t2 (
112+
b int not null,
113+
c int default null,
114+
d int not null,
115+
e int not null,
116+
unique key (d,b,c)
117+
);
118+
119+
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);
120+
121+
select (
122+
select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1
123+
) x from t2 left join t1 on a = b;
124+
125+
drop table t1, t2;
126+
127+
--echo #
128+
--echo # End of 10.10 tests
129+
--echo #

sql/sql_expression_cache.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ void Expression_cache_tmptable::init()
151151
}
152152
cache_table->s->keys= 1;
153153
ref.null_rejecting= 1;
154+
ref.const_ref_part_map= 0;
154155
ref.disable_cache= FALSE;
155156
ref.has_record= 0;
156157
ref.use_count= 0;

sql/sql_select.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26078,12 +26078,15 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
2607826078
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
2607926079
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
2608026080
bool result= 0;
26081+
key_part_map map= 1;
2608126082

2608226083
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
26083-
for (store_key **copy=ref->key_copy ; *copy ; copy++)
26084+
for (store_key **copy=ref->key_copy ; *copy ; copy++, map <<= 1)
2608426085
{
26086+
while (map & ref->const_ref_part_map) // skip const ref parts
26087+
map <<= 1; // no store_key objects for them
2608526088
if ((*copy)->copy(thd) & 1 ||
26086-
(ref->null_rejecting && (*copy)->null_key))
26089+
((ref->null_rejecting & map) && (*copy)->null_key))
2608726090
{
2608826091
result= 1;
2608926092
break;

0 commit comments

Comments
 (0)