Bug #46159: simple query that never returns
The external 'for' loop in remove_dup_with_compare() handled HA_ERR_RECORD_DELETED by just starting over without advancing to the next record which caused an infinite loop. This condition could be triggered on certain data by a SELECT query containing DISTINCT, GROUP BY and HAVING clauses. Fixed remove_dup_with_compare() so that we always advance to the next record when receiving HA_ERR_RECORD_DELETED from rnd_next(). mysql-test/r/distinct.result: Added a test case for bug #46159. mysql-test/t/distinct.test: Added a test case for bug #46159. sql/sql_select.cc: Fixed remove_dup_with_compare() so that we always advance to the next record when receiving HA_ERR_RECORD_DELETED from rnd_next().
This commit is contained in:
parent
354f5f7bac
commit
505346028f
@ -763,4 +763,34 @@ a b d c
|
||||
1 2 0 2
|
||||
1 2 0 3
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug #46159: simple query that never returns
|
||||
#
|
||||
SET @old_max_heap_table_size = @@max_heap_table_size;
|
||||
SET @@max_heap_table_size = 16384;
|
||||
SET @old_sort_buffer_size = @@sort_buffer_size;
|
||||
SET @@sort_buffer_size = 32804;
|
||||
CREATE TABLE t1(c1 int, c2 VARCHAR(20));
|
||||
INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4');
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4;
|
||||
c1 c2 COUNT(*)
|
||||
1 1 2
|
||||
2 2 1
|
||||
3 1 2
|
||||
4 4 1
|
||||
SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1;
|
||||
c2
|
||||
1
|
||||
5
|
||||
DROP TABLE t1;
|
||||
SET @@sort_buffer_size = @old_sort_buffer_size;
|
||||
SET @@max_heap_table_size = @old_max_heap_table_size;
|
||||
End of 5.1 tests
|
||||
|
@ -573,4 +573,44 @@ SELECT DISTINCT a, b, d, c FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #46159: simple query that never returns
|
||||
--echo #
|
||||
|
||||
# Set max_heap_table_size to the minimum value so that GROUP BY table in the
|
||||
# SELECT query below gets converted to MyISAM
|
||||
SET @old_max_heap_table_size = @@max_heap_table_size;
|
||||
SET @@max_heap_table_size = 16384;
|
||||
|
||||
# Set sort_buffer_size to the mininum value so that remove_duplicates() calls
|
||||
# remove_dup_with_compare()
|
||||
SET @old_sort_buffer_size = @@sort_buffer_size;
|
||||
SET @@sort_buffer_size = 32804;
|
||||
|
||||
CREATE TABLE t1(c1 int, c2 VARCHAR(20));
|
||||
INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4');
|
||||
# Now we just need to pad the table with random data so we have enough unique
|
||||
# values to force conversion of the GROUP BY table to MyISAM
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
|
||||
|
||||
# First rows of the GROUP BY table that will be processed by
|
||||
# remove_dup_with_compare()
|
||||
SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4;
|
||||
|
||||
# The actual test case
|
||||
SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1;
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP TABLE t1;
|
||||
SET @@sort_buffer_size = @old_sort_buffer_size;
|
||||
SET @@max_heap_table_size = @old_max_heap_table_size;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -13665,7 +13665,10 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
|
||||
if (error)
|
||||
{
|
||||
if (error == HA_ERR_RECORD_DELETED)
|
||||
continue;
|
||||
{
|
||||
error= file->rnd_next(record);
|
||||
continue;
|
||||
}
|
||||
if (error == HA_ERR_END_OF_FILE)
|
||||
break;
|
||||
goto err;
|
||||
|
Loading…
x
Reference in New Issue
Block a user