mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Bug #30639: limit offset,rowcount wraps when rowcount >= 2^32 in windows
The parser uses ulonglong to store the LIMIT number. This number then is stored into a variable of type ha_rows. ha_rows is either 4 or 8 byte depending on the BIG_TABLES define from config.h So an overflow may occur (and LIMIT becomes zero) while storing an ulonglong value in ha_rows. Fixed by : 1. Using the maximum possible value for ha_rows on overflow 2. Defining BIG_TABLES for the windows builds (to match the others)
This commit is contained in:
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
/* Defines for Win32 to make it compatible for MySQL */
|
/* Defines for Win32 to make it compatible for MySQL */
|
||||||
|
|
||||||
|
#define BIG_TABLES
|
||||||
|
|
||||||
#ifdef __WIN2000__
|
#ifdef __WIN2000__
|
||||||
/* We have to do this define before including windows.h to get the AWE API
|
/* We have to do this define before including windows.h to get the AWE API
|
||||||
functions */
|
functions */
|
||||||
|
@ -4048,3 +4048,20 @@ Level Code Message
|
|||||||
Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
|
Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
create table t1(a INT, KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
|
||||||
|
a
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
|
||||||
|
a
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -3450,3 +3450,13 @@ SHOW WARNINGS;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #30639: limit offset,rowcount wraps when rowcount >= 2^32 in windows
|
||||||
|
#
|
||||||
|
create table t1(a INT, KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2;
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
|
||||||
|
SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -2372,10 +2372,19 @@ st_lex::copy_db_to(char **p_db, size_t *p_db_length) const
|
|||||||
void st_select_lex_unit::set_limit(st_select_lex *sl)
|
void st_select_lex_unit::set_limit(st_select_lex *sl)
|
||||||
{
|
{
|
||||||
ha_rows select_limit_val;
|
ha_rows select_limit_val;
|
||||||
|
ulonglong val;
|
||||||
|
|
||||||
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
|
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
|
||||||
select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() :
|
val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
|
||||||
HA_POS_ERROR);
|
select_limit_val= (ha_rows)val;
|
||||||
|
#ifndef BIG_TABLES
|
||||||
|
/*
|
||||||
|
Check for overflow : ha_rows can be smaller then ulonglong if
|
||||||
|
BIG_TABLES is off.
|
||||||
|
*/
|
||||||
|
if (val != (ulonglong)select_limit_val)
|
||||||
|
select_limit_val= HA_POS_ERROR;
|
||||||
|
#endif
|
||||||
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
|
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
|
||||||
ULL(0));
|
ULL(0));
|
||||||
select_limit_cnt= select_limit_val + offset_limit_cnt;
|
select_limit_cnt= select_limit_val + offset_limit_cnt;
|
||||||
|
Reference in New Issue
Block a user