summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-11-23 00:58:07 +0100
committerSergei Golubchik <serg@mariadb.org>2022-12-02 16:19:13 +0100
commitcfb47ddde2bbbdc3065ed2b959bd4719247fbd30 (patch)
tree98385bd47504b46ba85be8b94696d5440920543b
parentda3fc33e88c70bc526a7e03dfe9c3e701a1a1892 (diff)
downloadmariadb-git-cfb47ddde2bbbdc3065ed2b959bd4719247fbd30.tar.gz
MDEV-30066 (limit + offset) union all (...) limit = incorrect result
select_union_direct::send_data() only sends a record when the LIMIT ... OFFSET clause of the individual select won't skip it. Thus, select_union_direct::send_data() should not do any actions related to a sending a record if the offset of a select isn't reached yet
-rw-r--r--mysql-test/main/union.result15
-rw-r--r--mysql-test/main/union.test9
-rw-r--r--sql/sql_union.cc13
3 files changed, 32 insertions, 5 deletions
diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result
index bf65bbd44d1..8d9d9752e1d 100644
--- a/mysql-test/main/union.result
+++ b/mysql-test/main/union.result
@@ -2748,5 +2748,20 @@ a b c d
3 4 2 197
drop table t1,t2;
#
+# MDEV-30066 (limit + offset) union all (...) limit = incorrect result
+#
+create table t1(id int primary key auto_increment, c1 int);
+insert into t1(c1) values(1),(2),(3);
+(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc);
+id c1
+1 1
+2 2
+3 3
+(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc) limit 2;
+id c1
+1 1
+2 2
+drop table t1;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test
index eff3cfd260b..ba9ee278228 100644
--- a/mysql-test/main/union.test
+++ b/mysql-test/main/union.test
@@ -1983,5 +1983,14 @@ union (select 0 as a, 99 as b,
drop table t1,t2;
--echo #
+--echo # MDEV-30066 (limit + offset) union all (...) limit = incorrect result
+--echo #
+create table t1(id int primary key auto_increment, c1 int);
+insert into t1(c1) values(1),(2),(3);
+(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc);
+(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc) limit 2;
+drop table t1;
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index e831e2a479c..902e25d084e 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -551,14 +551,17 @@ int select_union_direct::send_data(List<Item> &items)
{
if (!limit)
return false;
- limit--;
- if (offset)
+ if (!unit->offset_limit_cnt)
{
- offset--;
- return false;
+ limit--;
+ if (offset)
+ {
+ offset--;
+ return false;
+ }
+ send_records++;
}
- send_records++;
fill_record(thd, table, table->field, items, true, false);
if (unlikely(thd->is_error()))
return true; /* purecov: inspected */