Commit 0b590282 authored by Sergey Petrunya's avatar Sergey Petrunya

BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...

- Create/use do_copy_nullable_row_to_notnull() function for ref access, which is used 
  when copying from not-NULL field in table that can be NULL-complemented to not-NULL field.
parent cd55894a
...@@ -2152,4 +2152,21 @@ c c ...@@ -2152,4 +2152,21 @@ c c
set optimizer_prune_level= @opl_901399; set optimizer_prune_level= @opl_901399;
set optimizer_switch= @os_091399; set optimizer_switch= @os_091399;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
#
CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
INSERT INTO t1 VALUES ('k'),('l');
CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
INSERT INTO t2 VALUES ('k'),('l');
CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
INSERT INTO t3 VALUES ('m'),('n');
SELECT a, COUNT(*) FROM t1
WHERE a IN (
SELECT b FROM t2 force index(b), t3 force index(c)
WHERE c = b AND b = a
);
a COUNT(*)
NULL 0
DROP TABLE t1, t2, t3;
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
...@@ -2166,6 +2166,23 @@ c c ...@@ -2166,6 +2166,23 @@ c c
set optimizer_prune_level= @opl_901399; set optimizer_prune_level= @opl_901399;
set optimizer_switch= @os_091399; set optimizer_switch= @os_091399;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
#
CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
INSERT INTO t1 VALUES ('k'),('l');
CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
INSERT INTO t2 VALUES ('k'),('l');
CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
INSERT INTO t3 VALUES ('m'),('n');
SELECT a, COUNT(*) FROM t1
WHERE a IN (
SELECT b FROM t2 force index(b), t3 force index(c)
WHERE c = b AND b = a
);
a COUNT(*)
NULL 0
DROP TABLE t1, t2, t3;
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
# #
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
......
...@@ -1997,6 +1997,25 @@ set optimizer_switch= @os_091399; ...@@ -1997,6 +1997,25 @@ set optimizer_switch= @os_091399;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
--echo #
CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
INSERT INTO t1 VALUES ('k'),('l');
CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
INSERT INTO t2 VALUES ('k'),('l');
CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
INSERT INTO t3 VALUES ('m'),('n');
SELECT a, COUNT(*) FROM t1
WHERE a IN (
SELECT b FROM t2 force index(b), t3 force index(c)
WHERE c = b AND b = a
);
DROP TABLE t1, t2, t3;
# The following command must be the last one the file # The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
...@@ -248,6 +248,25 @@ static void do_outer_field_null(Copy_field *copy) ...@@ -248,6 +248,25 @@ static void do_outer_field_null(Copy_field *copy)
} }
} }
/*
Copy: (not-NULL field in table that can be NULL-complemented) -> (not-NULL
field)
*/
static void do_copy_nullable_row_to_notnull(Copy_field *copy)
{
if (*copy->null_row ||
(copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
{
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
copy->to_field->reset();
}
else
{
(copy->do_copy2)(copy);
}
}
/* Copy: (NULL-able field) -> (not NULL-able field) */ /* Copy: (NULL-able field) -> (not NULL-able field) */
static void do_copy_not_null(Copy_field *copy) static void do_copy_not_null(Copy_field *copy)
...@@ -638,7 +657,15 @@ void Copy_field::set(Field *to,Field *from,bool save) ...@@ -638,7 +657,15 @@ void Copy_field::set(Field *to,Field *from,bool save)
else if (to_field == to_field->table->next_number_field) else if (to_field == to_field->table->next_number_field)
do_copy= do_copy_next_number; do_copy= do_copy_next_number;
else else
do_copy= do_copy_not_null; {
if (!from_null_ptr)
{
null_row= &from->table->null_row;
do_copy= do_copy_nullable_row_to_notnull;
}
else
do_copy= do_copy_not_null;
}
} }
} }
else if (to_field->real_maybe_null()) else if (to_field->real_maybe_null())
......
...@@ -646,6 +646,9 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -646,6 +646,9 @@ JOIN::prepare(Item ***rref_pointer_array,
aggregate functions and non-aggregate fields, any non-aggregated field aggregate functions and non-aggregate fields, any non-aggregated field
may produce a NULL value. Set all fields of each table as nullable before may produce a NULL value. Set all fields of each table as nullable before
semantic analysis to take into account this change of nullability. semantic analysis to take into account this change of nullability.
Note: this loop doesn't touch tables inside merged semi-joins, because
subquery-to-semijoin conversion has not been done yet. This is intended.
*/ */
if (mixed_implicit_grouping) if (mixed_implicit_grouping)
tbl->table->maybe_null= 1; tbl->table->maybe_null= 1;
......
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