Hi Matrin,
Pls, see comments inline.
Regards, Evgen.
Martin Hansson wrote:
> #At file:///data0/martin/bzr/bug48459/5.1bt/ based on
> revid:jorgen.loland@stripped
>
> 3201 Martin Hansson 2009-11-17
> Bug#48459: valgrind errors with query using 'Range checked
> for each record'
>
> There was an error in an internal structure in the range
> optimizer. Bad design causes parts of a data structure not
> to be initialized when it is in a certain state. All client
> code must check that this state is not present before trying
> to access the structure's data before checking the
> state. Fixed by checking the state before trying to access
> data.
> @ mysql-test/r/range.result
> Bug#48459: Test result.
> @ mysql-test/t/range.test
> Bug#48459: Test case.
> @ sql/opt_range.cc
> Bug#48459: Fix: swapped two lines.
>
> modified:
> mysql-test/r/range.result
> mysql-test/t/range.test
> sql/opt_range.cc
> === modified file 'mysql-test/r/range.result'
> --- a/mysql-test/r/range.result 2009-11-02 12:24:07 +0000
> +++ b/mysql-test/r/range.result 2009-11-17 14:50:26 +0000
> @@ -1603,4 +1603,40 @@ SELECT str_to_date('', '%Y-%m-%d');
> str_to_date('', '%Y-%m-%d')
> 0000-00-00
> DROP TABLE t1, t2;
> +#
> +# Bug#48459: valgrind errors with query using 'Range checked for each
> +# record'
> +#
> +CREATE TABLE t1 (
> +a INT,
> +b CHAR(2),
> +c INT,
> +d INT,
> +KEY ( c ),
> +KEY ( d, a, b ( 2 ) ),
> +KEY ( b ( 1 ) )
> +);
> +INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
> +( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
> +CREATE TABLE t2 (
> +a INT,
> +c INT,
> +e INT,
> +KEY ( e )
> +);
> +INSERT INTO t2 VALUES ( 1, 1, '' ), ( 1, 1, '' );
> +Warnings:
> +Warning 1366 Incorrect integer value: '' for column 'e' at row 1
> +Warning 1366 Incorrect integer value: '' for column 'e' at row 2
There is no point in inserting wrong data. You can simply insert 0 instead of ''.
> +# Should not give Valgrind warnings
> +SELECT 1
> +FROM t1, t2
> +WHERE t1.d <> '1' AND t1.b > '1'
> +AND t1.a = t2.a AND t1.c = t2.c;
> +1
> +1
> +1
> +1
> +1
> +DROP TABLE t1, t2;
> End of 5.1 tests
>
> === modified file 'mysql-test/t/range.test'
> --- a/mysql-test/t/range.test 2009-11-02 12:24:07 +0000
> +++ b/mysql-test/t/range.test 2009-11-17 14:50:26 +0000
> @@ -1260,4 +1260,38 @@ SELECT str_to_date('', '%Y-%m-%d');
>
> DROP TABLE t1, t2;
>
> +--echo #
> +--echo # Bug#48459: valgrind errors with query using 'Range checked for each
> +--echo # record'
> +--echo #
> +CREATE TABLE t1 (
> + a INT,
> + b CHAR(2),
> + c INT,
> + d INT,
> + KEY ( c ),
> + KEY ( d, a, b ( 2 ) ),
> + KEY ( b ( 1 ) )
> +);
> +
> +INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
> + ( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
> +
> +CREATE TABLE t2 (
> + a INT,
> + c INT,
> + e INT,
> + KEY ( e )
> +);
> +
> +INSERT INTO t2 VALUES ( 1, 1, '' ), ( 1, 1, '' );
> +
> +--echo # Should not give Valgrind warnings
> +SELECT 1
> +FROM t1, t2
> +WHERE t1.d <> '1' AND t1.b > '1'
> +AND t1.a = t2.a AND t1.c = t2.c;
> +
> +DROP TABLE t1, t2;
> +
> --echo End of 5.1 tests
>
> === modified file 'sql/opt_range.cc'
> --- a/sql/opt_range.cc 2009-11-02 12:24:07 +0000
> +++ b/sql/opt_range.cc 2009-11-17 14:50:26 +0000
> @@ -7557,8 +7557,8 @@ check_quick_keys(PARAM *param, uint idx,
> param->first_null_comp= key_tree->part+1;
>
> if (key_tree->next_key_part &&
> - key_tree->next_key_part->part == key_tree->part+1 &&
> - key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
> + key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
> + key_tree->next_key_part->part == key_tree->part+1)
There is few more similar places where next_key_part->part is checked prior to
next_key_part->type. Please grep & swap.
> { // const key as prefix
> if (min_key_length == max_key_length &&
> !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
>
>
> ------------------------------------------------------------------------
>
>