Commit 6d38c898 authored by Georgi Kodinov's avatar Georgi Kodinov

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.
parent b8eaa81d
...@@ -2273,4 +2273,12 @@ END| ...@@ -2273,4 +2273,12 @@ END|
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1,t2; 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 End of 5.1 tests
...@@ -536,4 +536,14 @@ DROP PROCEDURE p1; ...@@ -536,4 +536,14 @@ DROP PROCEDURE p1;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1,t2; 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 --echo End of 5.1 tests
...@@ -12813,7 +12813,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, ...@@ -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_end=key_part+table->key_info[idx].key_parts;
key_part_map const_key_parts=table->const_key_parts[idx]; key_part_map const_key_parts=table->const_key_parts[idx];
int reverse=0; int reverse=0;
my_bool on_primary_key= FALSE; my_bool on_pk_suffix= FALSE;
DBUG_ENTER("test_if_order_by_key"); DBUG_ENTER("test_if_order_by_key");
for (; order ; order=order->next, const_key_parts>>=1) 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, ...@@ -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 key as a suffix to the secondary keys. If it has continue to check
the primary key as a suffix. 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->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= table->key_info[table->s->primary_key].key_part;
key_part_end=key_part+table->key_info[table->s->primary_key].key_parts; 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]; 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, ...@@ -12871,7 +12872,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
reverse=flag; // Remember if reverse reverse=flag; // Remember if reverse
key_part++; 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_secondary= table->key_info[idx].key_parts;
uint used_key_parts_pk= uint used_key_parts_pk=
...@@ -13360,8 +13361,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, ...@@ -13360,8 +13361,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
select_limit= table_records; select_limit= table_records;
if (group) 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); set_if_bigger(rec_per_key, 1);
/* /*
With a grouping query each group containing on average With a grouping query each group containing on average
......
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