Skip to content

Commit 7ae410f

Browse files
author
Tor Didriksen
committed
Bug#70622 error result when use between...and againest bigint unsigned
Bug#17606942 ERROR RESULT WHEN USE BETWEEN...AND AGAINEST BIGINT UNSIGNED Do value comparisons using unsigned arithmetic for unsigned values, signed arighmetic for signed values. Based on a contribution from xiaobin lin
1 parent 09a28a0 commit 7ae410f

File tree

3 files changed

+135
-36
lines changed

3 files changed

+135
-36
lines changed

mysql-test/r/bigint.result

+27
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,30 @@ a
506506
SELECT * FROM t1 WHERE a IN (0.8,0.9);
507507
a
508508
DROP TABLE t1;
509+
#
510+
# Bug#17606942 ERROR RESULT WHEN USE BETWEEN...AND
511+
# AGAINEST BIGINT UNSIGNED
512+
#
513+
# Bug#70622 error result when use between...and againest bigint unsigned
514+
create table t (id bigint unsigned, b int);
515+
insert into t values(8894754949779693574,1);
516+
insert into t values(8894754949779693579,2);
517+
insert into t values(17790886498483827171,3);
518+
select count(*) from t
519+
where id>=8894754949779693574 and id <=17790886498483827171;
520+
count(*)
521+
3
522+
select count(*) from t
523+
where id between 8894754949779693574 and 17790886498483827171;
524+
count(*)
525+
3
526+
alter table t add primary key (id);
527+
select count(*) from t
528+
where id>=8894754949779693574 and id <=17790886498483827171;
529+
count(*)
530+
3
531+
select count(*) from t
532+
where id between 8894754949779693574 and 17790886498483827171;
533+
count(*)
534+
3
535+
drop table t;

mysql-test/t/bigint.test

+29-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ select -(-(9223372036854775808));
330330
select --9223372036854775808, ---9223372036854775808, ----9223372036854775808;
331331
select -(-9223372036854775808), -(-(-9223372036854775808));
332332

333-
# Bug #28005 Partitions: can't use -9223372036854775808
333+
# Bug #28005 Partitions: cannot use -9223372036854775808
334334
create table t1 select -9223372036854775808 bi;
335335
describe t1;
336336
drop table t1;
@@ -419,3 +419,31 @@ SELECT * FROM t1 WHERE a=0.9;
419419
SELECT * FROM t1 WHERE a IN (0.8,0.9);
420420

421421
DROP TABLE t1;
422+
423+
--echo #
424+
--echo # Bug#17606942 ERROR RESULT WHEN USE BETWEEN...AND
425+
--echo # AGAINEST BIGINT UNSIGNED
426+
--echo #
427+
--echo # Bug#70622 error result when use between...and againest bigint unsigned
428+
429+
create table t (id bigint unsigned, b int);
430+
431+
insert into t values(8894754949779693574,1);
432+
insert into t values(8894754949779693579,2);
433+
insert into t values(17790886498483827171,3);
434+
435+
select count(*) from t
436+
where id>=8894754949779693574 and id <=17790886498483827171;
437+
438+
select count(*) from t
439+
where id between 8894754949779693574 and 17790886498483827171;
440+
441+
alter table t add primary key (id);
442+
443+
select count(*) from t
444+
where id>=8894754949779693574 and id <=17790886498483827171;
445+
446+
select count(*) from t
447+
where id between 8894754949779693574 and 17790886498483827171;
448+
449+
drop table t;

sql/item_cmpfunc.cc

+79-35
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -2654,8 +2654,68 @@ void Item_func_between::fix_length_and_dec()
26542654
}
26552655

26562656

2657+
/**
2658+
A helper function for Item_func_between::val_int() to avoid
2659+
over/underflow when comparing large values.
2660+
2661+
@tparam LLorULL ulonglong or longlong
2662+
2663+
@param compare_as_temporal_dates copy of Item_func_between member variable
2664+
@param compare_as_temporal_times copy of Item_func_between member variable
2665+
@param negated copy of Item_func_between member variable
2666+
@param args copy of Item_func_between member variable
2667+
@param null_value [out] set to true if result is not true/false
2668+
2669+
@retval true if: args[1] <= args[0] <= args[2]
2670+
*/
2671+
template<typename LLorULL>
2672+
longlong compare_between_int_result(bool compare_as_temporal_dates,
2673+
bool compare_as_temporal_times,
2674+
bool negated,
2675+
Item **args,
2676+
my_bool *null_value)
2677+
{
2678+
{
2679+
LLorULL a, b, value;
2680+
value= compare_as_temporal_times ? args[0]->val_time_temporal() :
2681+
compare_as_temporal_dates ? args[0]->val_date_temporal() :
2682+
args[0]->val_int();
2683+
if ((*null_value= args[0]->null_value))
2684+
return 0; /* purecov: inspected */
2685+
if (compare_as_temporal_times)
2686+
{
2687+
a= args[1]->val_time_temporal();
2688+
b= args[2]->val_time_temporal();
2689+
}
2690+
else if (compare_as_temporal_dates)
2691+
{
2692+
a= args[1]->val_date_temporal();
2693+
b= args[2]->val_date_temporal();
2694+
}
2695+
else
2696+
{
2697+
a= args[1]->val_int();
2698+
b= args[2]->val_int();
2699+
}
2700+
if (!args[1]->null_value && !args[2]->null_value)
2701+
return (longlong) ((value >= a && value <= b) != negated);
2702+
if (args[1]->null_value && args[2]->null_value)
2703+
*null_value= 1;
2704+
else if (args[1]->null_value)
2705+
{
2706+
*null_value= value <= b; // not null if false range.
2707+
}
2708+
else
2709+
{
2710+
*null_value= value >= a;
2711+
}
2712+
return value;
2713+
}
2714+
}
2715+
2716+
26572717
longlong Item_func_between::val_int()
2658-
{ // ANSI BETWEEN
2718+
{ // ANSI BETWEEN
26592719
DBUG_ASSERT(fixed == 1);
26602720
if (compare_as_dates_with_strings)
26612721
{
@@ -2670,7 +2730,7 @@ longlong Item_func_between::val_int()
26702730
return (longlong) ((ge_res >= 0 && le_res <=0) != negated);
26712731
else if (args[1]->null_value)
26722732
{
2673-
null_value= le_res > 0; // not null if false range.
2733+
null_value= le_res > 0; // not null if false range.
26742734
}
26752735
else
26762736
{
@@ -2704,46 +2764,30 @@ longlong Item_func_between::val_int()
27042764
}
27052765
else if (cmp_type == INT_RESULT)
27062766
{
2707-
longlong a, b, value;
2708-
value= compare_as_temporal_times ? args[0]->val_time_temporal() :
2709-
compare_as_temporal_dates ? args[0]->val_date_temporal() :
2710-
args[0]->val_int();
2711-
if ((null_value=args[0]->null_value))
2712-
return 0; /* purecov: inspected */
2713-
if (compare_as_temporal_times)
2714-
{
2715-
a= args[1]->val_time_temporal();
2716-
b= args[2]->val_time_temporal();
2717-
}
2718-
else if (compare_as_temporal_dates)
2719-
{
2720-
a= args[1]->val_date_temporal();
2721-
b= args[2]->val_date_temporal();
2722-
}
2767+
longlong value;
2768+
if (args[0]->unsigned_flag)
2769+
value= compare_between_int_result<ulonglong>(compare_as_temporal_dates,
2770+
compare_as_temporal_times,
2771+
negated,
2772+
args,
2773+
&null_value);
27232774
else
2724-
{
2725-
a= args[1]->val_int();
2726-
b= args[2]->val_int();
2727-
}
2775+
value= compare_between_int_result<longlong>(compare_as_temporal_dates,
2776+
compare_as_temporal_times,
2777+
negated,
2778+
args,
2779+
&null_value);
2780+
if (args[0]->null_value)
2781+
return 0; /* purecov: inspected */
27282782
if (!args[1]->null_value && !args[2]->null_value)
2729-
return (longlong) ((value >= a && value <= b) != negated);
2730-
if (args[1]->null_value && args[2]->null_value)
2731-
null_value=1;
2732-
else if (args[1]->null_value)
2733-
{
2734-
null_value= value <= b; // not null if false range.
2735-
}
2736-
else
2737-
{
2738-
null_value= value >= a;
2739-
}
2783+
return value;
27402784
}
27412785
else if (cmp_type == DECIMAL_RESULT)
27422786
{
27432787
my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
27442788
a_buf, *a_dec, b_buf, *b_dec;
27452789
if ((null_value=args[0]->null_value))
2746-
return 0; /* purecov: inspected */
2790+
return 0; /* purecov: inspected */
27472791
a_dec= args[1]->val_decimal(&a_buf);
27482792
b_dec= args[2]->val_decimal(&b_buf);
27492793
if (!args[1]->null_value && !args[2]->null_value)

0 commit comments

Comments
 (0)