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.
2
2
3
3
This program is free software; you can redistribute it and/or modify
4
4
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()
2654
2654
}
2655
2655
2656
2656
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
+
2657
2717
longlong Item_func_between::val_int ()
2658
- { // ANSI BETWEEN
2718
+ { // ANSI BETWEEN
2659
2719
DBUG_ASSERT (fixed == 1 );
2660
2720
if (compare_as_dates_with_strings)
2661
2721
{
@@ -2670,7 +2730,7 @@ longlong Item_func_between::val_int()
2670
2730
return (longlong) ((ge_res >= 0 && le_res <=0 ) != negated);
2671
2731
else if (args[1 ]->null_value )
2672
2732
{
2673
- null_value= le_res > 0 ; // not null if false range.
2733
+ null_value= le_res > 0 ; // not null if false range.
2674
2734
}
2675
2735
else
2676
2736
{
@@ -2704,46 +2764,30 @@ longlong Item_func_between::val_int()
2704
2764
}
2705
2765
else if (cmp_type == INT_RESULT)
2706
2766
{
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);
2723
2774
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 */
2728
2782
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;
2740
2784
}
2741
2785
else if (cmp_type == DECIMAL_RESULT)
2742
2786
{
2743
2787
my_decimal dec_buf, *dec= args[0 ]->val_decimal (&dec_buf),
2744
2788
a_buf, *a_dec, b_buf, *b_dec;
2745
2789
if ((null_value=args[0 ]->null_value ))
2746
- return 0 ; /* purecov: inspected */
2790
+ return 0 ; /* purecov: inspected */
2747
2791
a_dec= args[1 ]->val_decimal (&a_buf);
2748
2792
b_dec= args[2 ]->val_decimal (&b_buf);
2749
2793
if (!args[1 ]->null_value && !args[2 ]->null_value )
0 commit comments