From aeccdddedd5d3d306dd317e6b366d50bc807726b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= <vicentiu@mariadb.org>
Date: Sun, 18 Apr 2021 22:58:34 +0300
Subject: [PATCH] MDEV-25441 WITH TIES is not respected with SQL_BUFFER_RESULT
 and constant in ORDER BY

Pushing LIMIT to temp aggregation table is possible, but not when WITH
TIES is used. In a degenerate case with constant ORDER BY, the constant
gets removed and the code assumed the limit is push-able.

Ensure that if WITH TIES is present, that this does not happen.
---
 mysql-test/main/fetch_first.result | 34 ++++++++++++++++++++++++++++++
 mysql-test/main/fetch_first.test   | 11 ++++++++++
 sql/sql_select.cc                  |  8 ++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/mysql-test/main/fetch_first.result b/mysql-test/main/fetch_first.result
index 1e63581e0a5..7bb89633081 100644
--- a/mysql-test/main/fetch_first.result
+++ b/mysql-test/main/fetch_first.result
@@ -1334,3 +1334,37 @@ a	b	sum(a)
 1	2	1
 1	3	1
 drop table t1;
+#
+# MDEV-25441
+# WITH TIES is not respected with SQL_BUFFER_RESULT and constant in ORDER BY
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+explain SELECT SQL_BUFFER_RESULT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	10	Using temporary
+SELECT SQL_BUFFER_RESULT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
+f
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+SELECT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
+f
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+drop table t1;
diff --git a/mysql-test/main/fetch_first.test b/mysql-test/main/fetch_first.test
index 6995c1cb5b1..76c0a8b8b39 100644
--- a/mysql-test/main/fetch_first.test
+++ b/mysql-test/main/fetch_first.test
@@ -1028,6 +1028,17 @@ group by a, b
 order by (select 1), a
 fetch first 1 rows with ties;
 
+drop table t1;
+
+--echo #
+--echo # MDEV-25441
+--echo # WITH TIES is not respected with SQL_BUFFER_RESULT and constant in ORDER BY
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
 
+explain SELECT SQL_BUFFER_RESULT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
+SELECT SQL_BUFFER_RESULT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
+SELECT 1 AS f FROM t1 ORDER BY f FETCH NEXT 2 ROW WITH TIES;
 
 drop table t1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7dc3612c011..eeae53f6816 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3856,10 +3856,16 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
     when there is ORDER BY or GROUP BY or there is no GROUP BY, but
     there are aggregate functions, because in all these cases we need
     all result rows.
+
+    We also can not push limit if the limit is WITH TIES, as we do not know
+    how many rows we will actually have. This can happen if ORDER BY was
+    a constant and removed (during remove_const), thus we have an "unlimited"
+    WITH TIES.
   */
   ha_rows table_rows_limit= ((order == NULL || skip_sort_order) &&
                               !table_group &&
-                              !select_lex->with_sum_func) ? select_limit
+                              !select_lex->with_sum_func &&
+                              !unit->lim.is_with_ties()) ? select_limit
                                                           : HA_POS_ERROR;
 
   if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param)))
-- 
2.30.9