diff options
author | Georgi Kodinov <joro@sun.com> | 2010-01-29 17:04:37 +0200 |
---|---|---|
committer | Georgi Kodinov <joro@sun.com> | 2010-01-29 17:04:37 +0200 |
commit | 6d38c898a6c69c2c7f862d40a323f7feec8934d5 (patch) | |
tree | 1878d495d8135589ef763899da62d853133a53c5 | |
parent | b8eaa81dd95259a0a77ecc6fe9a5d736dc1dfcd6 (diff) | |
download | mariadb-git-6d38c898a6c69c2c7f862d40a323f7feec8934d5.tar.gz |
Bug #49324: more valgrind errors in test_if_skip_sort_order
Fixed 2 problems :
1. test_if_order_by_key() was continuing on the primary key
as if it has a primary key suffix (as the secondary keys do).
This leads to crashes in ORDER BY <pk>,<pk>.
Fixed by not treating the primary key as the secondary one
and not depending on it being clustered with a primary key.
2. The cost calculation was trying to read the records
per key when operating on ORDER BYs that order on all of the
secondary key + some of the primary key.
This leads to crashes because of out-of-bounds array access.
Fixed by assuming we'll find 1 record per key in such cases.
-rw-r--r-- | mysql-test/r/innodb_mysql.result | 8 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql.test | 10 | ||||
-rw-r--r-- | sql/sql_select.cc | 22 |
3 files changed, 33 insertions, 7 deletions
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 402ab3c1b16..b54fb90b412 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2273,4 +2273,12 @@ END| DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1,t2; +# +# Bug #49324: more valgrind errors in test_if_skip_sort_order +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; +#should not cause valgrind warnings +SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index a2a1113598d..d9fecccfbdc 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -536,4 +536,14 @@ DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1,t2; + +--echo # +--echo # Bug #49324: more valgrind errors in test_if_skip_sort_order +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; +--echo #should not cause valgrind warnings +SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bdd139edafc..8744f77d6b1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12813,7 +12813,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, key_part_end=key_part+table->key_info[idx].key_parts; key_part_map const_key_parts=table->const_key_parts[idx]; int reverse=0; - my_bool on_primary_key= FALSE; + my_bool on_pk_suffix= FALSE; DBUG_ENTER("test_if_order_by_key"); for (; order ; order=order->next, const_key_parts>>=1) @@ -12835,11 +12835,12 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, key as a suffix to the secondary keys. If it has continue to check the primary key as a suffix. */ - if (!on_primary_key && + if (!on_pk_suffix && (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && - table->s->primary_key != MAX_KEY) + table->s->primary_key != MAX_KEY && + table->s->primary_key != idx) { - on_primary_key= TRUE; + on_pk_suffix= TRUE; key_part= table->key_info[table->s->primary_key].key_part; key_part_end=key_part+table->key_info[table->s->primary_key].key_parts; const_key_parts=table->const_key_parts[table->s->primary_key]; @@ -12871,7 +12872,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, reverse=flag; // Remember if reverse key_part++; } - if (on_primary_key) + if (on_pk_suffix) { uint used_key_parts_secondary= table->key_info[idx].key_parts; uint used_key_parts_pk= @@ -13360,8 +13361,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, select_limit= table_records; if (group) { - rec_per_key= used_key_parts ? keyinfo->rec_per_key[used_key_parts-1] - : 1; + /* + Used_key_parts can be larger than keyinfo->key_parts + when using a secondary index clustered with a primary + key (e.g. as in Innodb). + See Bug #28591 for details. + */ + rec_per_key= used_key_parts && + used_key_parts <= keyinfo->key_parts ? + keyinfo->rec_per_key[used_key_parts-1] : 1; set_if_bigger(rec_per_key, 1); /* With a grouping query each group containing on average |