Bug#37075: offset of limit clause might be truncated on 32-bits server w/o big tables
The problem is that the offset argument of the limit clause might be truncated on a 32-bits server built without big tables support. The truncation was happening because the original 64-bits long argument was being cast to a 32-bits (ha_rows) offset counter. The solution is to check if the conversing resulted in value truncation and if so, the offset is set to the maximum possible value that can fit on the type.
This commit is contained in:
parent
d4c75b7d0f
commit
4ab10baace
@ -111,3 +111,6 @@ set @a=-14632475938453979136;
|
||||
execute s using @a, @a;
|
||||
ERROR HY000: Incorrect arguments to EXECUTE
|
||||
End of 5.0 tests
|
||||
select 1 as a limit 4294967296,10;
|
||||
a
|
||||
End of 5.1 tests
|
||||
|
@ -95,3 +95,11 @@ set @a=-14632475938453979136;
|
||||
execute s using @a, @a;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
||||
#
|
||||
# Bug#37075: offset of limit clause might be truncated to 0 on 32-bits server w/o big tables
|
||||
#
|
||||
|
||||
select 1 as a limit 4294967296,10;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -2041,12 +2041,26 @@ st_lex::copy_db_to(char **p_db, uint *p_db_length) const
|
||||
void st_select_lex_unit::set_limit(SELECT_LEX *sl)
|
||||
{
|
||||
ha_rows select_limit_val;
|
||||
ulonglong val;
|
||||
|
||||
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
|
||||
select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() :
|
||||
HA_POS_ERROR);
|
||||
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
|
||||
ULL(0));
|
||||
val= sl->select_limit ? sl->select_limit->val_uint() : 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
|
||||
val= sl->offset_limit ? sl->offset_limit->val_uint() : ULL(0);
|
||||
offset_limit_cnt= (ha_rows)val;
|
||||
#ifndef BIG_TABLES
|
||||
/* Check for truncation. */
|
||||
if (val != (ulonglong)offset_limit_cnt)
|
||||
offset_limit_cnt= HA_POS_ERROR;
|
||||
#endif
|
||||
select_limit_cnt= select_limit_val + offset_limit_cnt;
|
||||
if (select_limit_cnt < select_limit_val)
|
||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||
|
Loading…
x
Reference in New Issue
Block a user