From 8c04dd33dd7ab1c261bd15ace2009832af7a2f98 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 13 Mar 2014 12:20:57 +0100 Subject: [PATCH 1/3] MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON - With big_tables=ON, materialized table will use Aria (or MyISAM) SE, which allows prefix key reads. However, the temp.table has rec_per_key=NULL which causes the optimizer to crash when attempting to read index statistics for a prefix index read. - Fixed by providing a rec_per_key array with zeros (i.e. "no statistics data") --- mysql-test/r/subselect_mat.result | 14 ++++++++++++++ mysql-test/r/subselect_sj_mat.result | 14 ++++++++++++++ mysql-test/t/subselect_sj_mat.test | 18 ++++++++++++++++++ sql/sql_select.cc | 15 ++++++++++++++- 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index c47881d5434..7743e804f17 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2041,6 +2041,20 @@ EXECUTE stmt; a DROP TABLE t1, t2; DROP VIEW v2; +# +# MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON +# +SET @tmp_mdev5811= @@big_tables; +SET big_tables = ON; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +SELECT * FROM t1 AS t1_1, t1 AS t1_2 +WHERE ( t1_1.a, t1_2.a ) IN ( SELECT MAX(b), MIN(b) FROM t2 ); +a a +DROP TABLE t1,t2; +SET big_tables=@tmp_mdev5811; # End of 5.3 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index f267f32c887..9f3cb5ce0b8 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2081,4 +2081,18 @@ EXECUTE stmt; a DROP TABLE t1, t2; DROP VIEW v2; +# +# MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON +# +SET @tmp_mdev5811= @@big_tables; +SET big_tables = ON; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +SELECT * FROM t1 AS t1_1, t1 AS t1_2 +WHERE ( t1_1.a, t1_2.a ) IN ( SELECT MAX(b), MIN(b) FROM t2 ); +a a +DROP TABLE t1,t2; +SET big_tables=@tmp_mdev5811; # End of 5.3 tests diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index bf5360dd4a7..5e7103aa6e9 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1726,4 +1726,22 @@ EXECUTE stmt; DROP TABLE t1, t2; DROP VIEW v2; +--echo # +--echo # MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON +--echo # +SET @tmp_mdev5811= @@big_tables; +SET big_tables = ON; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); + +SELECT * FROM t1 AS t1_1, t1 AS t1_2 + WHERE ( t1_1.a, t1_2.a ) IN ( SELECT MAX(b), MIN(b) FROM t2 ); + +DROP TABLE t1,t2; +SET big_tables=@tmp_mdev5811; + --echo # End of 5.3 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ec71cb3b1b2..3fc691a4429 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14976,7 +14976,20 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, keyinfo->key_length= 0; // Will compute the sum of the parts below. keyinfo->name= (char*) "distinct_key"; keyinfo->algorithm= HA_KEY_ALG_UNDEF; - keyinfo->rec_per_key=0; + /* + Needed by non-merged semi-joins: SJ-Materialized table must have a valid + rec_per_key array, because it participates in join optimization. Since + the table has no data, the only statistics we can provide is "unknown", + i.e. zero values. + + (For table record count, we calculate and set JOIN_TAB::found_records, + see get_delayed_table_estimates()). + */ + size_t rpk_size= keyinfo->key_parts* sizeof(keyinfo->rec_per_key[0]); + if (!(keyinfo->rec_per_key= (ulong*) alloc_root(&table->mem_root, + rpk_size))) + goto err; + bzero(keyinfo->rec_per_key, rpk_size); /* Create an extra field to hold NULL bits so that unique indexes on From 2eb920b2622ac90691efde818c659615bdf212bf Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Mar 2014 12:23:09 +0200 Subject: [PATCH 2/3] Fix to make it compiling with valgrind. --- sql/opt_range.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8d332d00dab..dbfb9497291 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -13324,7 +13324,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() } else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) result= 0; /* There is a result in any case. */ - my_afree(tmp_key_buff); + my_afree(key_buf); } } From 63d0918807739dd19578ce9db80acbfd8ea158e6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 23 Mar 2014 16:02:56 +0400 Subject: [PATCH 3/3] MDEV-5783 Assertion `0' failed in make_sortkey(SORTPARAM*, uchar*, uchar*) on ORDER BY HEX( UNCOMPRESSED_LENGTH( pk ) ) --- mysql-test/r/func_compress.result | 20 ++++++++++++++++++++ mysql-test/t/func_compress.test | 21 +++++++++++++++++++++ sql/item_strfunc.h | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 37f7c475148..105f2a53926 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -127,3 +127,23 @@ NULL 825307441 EXPLAIN EXTENDED SELECT * FROM (SELECT UNCOMPRESSED_LENGTH(c1) FROM t1) AS s; DROP TABLE t1; End of 5.0 tests +# +# Start of 5.3 tests +# +# +# MDEV-5783 Assertion `0' failed in make_sortkey(SORTPARAM*, uchar*, uchar*) on ORDER BY HEX(UNCOMPRESSED_LENGTH(pk)) +# +CREATE TABLE t1 (pk INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2); +SELECT UNCOMPRESSED_LENGTH(pk) FROM t1; +UNCOMPRESSED_LENGTH(pk) +NULL +NULL +Warnings: +Error 1259 ZLIB: Input data corrupted +Error 1259 ZLIB: Input data corrupted +SELECT * FROM t1 ORDER BY HEX(UNCOMPRESSED_LENGTH(pk)); +DROP TABLE t1; +# +# End of 5.3 tests +# diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 207f3a436d0..eaed0c88fe1 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -115,3 +115,24 @@ DROP TABLE t1; set @@global.max_allowed_packet=default; --enable_result_log --enable_query_log + + +--echo # +--echo # Start of 5.3 tests +--echo # + +--echo # +--echo # MDEV-5783 Assertion `0' failed in make_sortkey(SORTPARAM*, uchar*, uchar*) on ORDER BY HEX(UNCOMPRESSED_LENGTH(pk)) +--echo # +CREATE TABLE t1 (pk INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2); +SELECT UNCOMPRESSED_LENGTH(pk) FROM t1; +# ORDER is not strict, so disable results +--disable_result_log +SELECT * FROM t1 ORDER BY HEX(UNCOMPRESSED_LENGTH(pk)); +--enable_result_log +DROP TABLE t1; + +--echo # +--echo # End of 5.3 tests +--echo # diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index bb2fc0d9a33..9e3cb877803 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -822,7 +822,7 @@ class Item_func_uncompressed_length : public Item_int_func public: Item_func_uncompressed_length(Item *a):Item_int_func(a){} const char *func_name() const{return "uncompressed_length";} - void fix_length_and_dec() { max_length=10; } + void fix_length_and_dec() { max_length=10; maybe_null= true; } longlong val_int(); };