Commit 4aa04022 authored by kaa@polly.(none)'s avatar kaa@polly.(none)

Fix for bug #30666: Incorrect order when using range conditions on 2

tables or more

The problem was that the optimizer used the join buffer in cases when
the result set is ordered by filesort. This resulted in the ORDER BY
clause being ignored, and the records being returned in the order
determined by the order of matching records in the last table in join.

Fixed by relaxing the condition in make_join_readinfo() to take
filesort-ordered result sets into account, not only index-ordered ones.
parent 99f4b743
...@@ -4096,4 +4096,43 @@ SELECT `x` FROM v3; ...@@ -4096,4 +4096,43 @@ SELECT `x` FROM v3;
x x
1 1
DROP VIEW v1, v2, v3; DROP VIEW v1, v2, v3;
CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
c22 INT DEFAULT NULL,
KEY(c21, c22));
CREATE TABLE t3 (c31 INT UNSIGNED NOT NULL DEFAULT 0,
c32 INT DEFAULT NULL,
c33 INT NOT NULL,
c34 INT UNSIGNED DEFAULT 0,
KEY (c33, c34, c32));
INSERT INTO t1 values (),(),(),(),();
INSERT INTO t2 SELECT a.c11, b.c11 FROM t1 a, t1 b;
INSERT INTO t3 VALUES (1, 1, 1, 0),
(2, 2, 0, 0),
(3, 3, 1, 0),
(4, 4, 0, 0),
(5, 5, 1, 0);
SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
t3.c33 = 1 AND t2.c22 in (1, 3)
ORDER BY c32;
c32
1
1
3
3
5
5
SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
t3.c33 = 1 AND t2.c22 in (1, 3)
ORDER BY c32 DESC;
c32
5
5
3
3
1
1
DROP TABLE t1, t2, t3;
End of 5.0 tests End of 5.0 tests
...@@ -3484,4 +3484,40 @@ DROP VIEW v1, v2, v3; ...@@ -3484,4 +3484,40 @@ DROP VIEW v1, v2, v3;
--enable_ps_protocol --enable_ps_protocol
#
# Bug #30666: Incorrect order when using range conditions on 2 tables or more
#
CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
c22 INT DEFAULT NULL,
KEY(c21, c22));
CREATE TABLE t3 (c31 INT UNSIGNED NOT NULL DEFAULT 0,
c32 INT DEFAULT NULL,
c33 INT NOT NULL,
c34 INT UNSIGNED DEFAULT 0,
KEY (c33, c34, c32));
INSERT INTO t1 values (),(),(),(),();
INSERT INTO t2 SELECT a.c11, b.c11 FROM t1 a, t1 b;
INSERT INTO t3 VALUES (1, 1, 1, 0),
(2, 2, 0, 0),
(3, 3, 1, 0),
(4, 4, 0, 0),
(5, 5, 1, 0);
# Show that ORDER BY produces the correct results order
SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
t3.c33 = 1 AND t2.c22 in (1, 3)
ORDER BY c32;
# Show that ORDER BY DESC produces the correct results order
SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
t3.c33 = 1 AND t2.c22 in (1, 3)
ORDER BY c32 DESC;
DROP TABLE t1, t2, t3;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -6071,10 +6071,9 @@ make_join_readinfo(JOIN *join, ulonglong options) ...@@ -6071,10 +6071,9 @@ make_join_readinfo(JOIN *join, ulonglong options)
ordered. If there is a temp table the ordering is done as a last ordered. If there is a temp table the ordering is done as a last
operation and doesn't prevent join cache usage. operation and doesn't prevent join cache usage.
*/ */
if (!ordered_set && !join->need_tmp && if (!ordered_set && !join->need_tmp &&
((table == join->sort_by_table && (table == join->sort_by_table ||
(!join->order || join->skip_sort_order)) || (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
(join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
ordered_set= 1; ordered_set= 1;
switch (tab->type) { switch (tab->type) {
......
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