This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new adc9e9a1613 [fix](function) Fix undefined behavior caused by 
bit_shift_left exceeding the 64-bit range. (#47080)
adc9e9a1613 is described below

commit adc9e9a161337612acffd67bdd5fe47c9b81f3a8
Author: Mryange <yanxuech...@selectdb.com>
AuthorDate: Thu Jan 16 21:13:24 2025 +0800

    [fix](function) Fix undefined behavior caused by bit_shift_left exceeding 
the 64-bit range. (#47080)
    
    ### What problem does this PR solve?
    It is part of this PR's https://github.com/apache/doris/pull/35769
    content.
    
    
    ```
    SELECT a, b, bit_shift_left(nullable(a), nullable(b)) from t01;
    
+----------------------+-----+-----------------------------------------------------------+
    | a                    | b   | bit_shift_left(nullable(a), cast(nullable(b) 
as TINYINT)) |
    
+----------------------+-----+-----------------------------------------------------------+
    | -4388843650233597359 | 127 | -9223372036854775808                         
             |
    | 306567258363819813   | 3   | 2452538066910558504                          
             |
    | 306567258363819813   | 127 | -9223372036854775808                         
             |
    | 3456789123456789123  | 127 | -9223372036854775808                         
             |
    
+----------------------+-----+-----------------------------------------------------------+
    ```
    now
    ```
    SELECT a, b, bit_shift_left(nullable(a), nullable(b)) from t01;
    
+----------------------+-----+-----------------------------------------------------------+
    | a                    | b   | bit_shift_left(nullable(a), cast(nullable(b) 
as TINYINT)) |
    
+----------------------+-----+-----------------------------------------------------------+
    | -4388843650233597359 | 127 | 0                                            
             |
    | 306567258363819813   | 3   | 2452538066910558504                          
             |
    | 306567258363819813   | 127 | 0                                            
             |
    | 3456789123456789123  | 127 | 0                                            
             |
    
+----------------------+-----+-----------------------------------------------------------+
    ```
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 be/src/vec/functions/function_bit_shift.cpp              | 16 ++++++++++------
 .../data/correctness_p0/test_bit_shift_lagency.out       |  8 ++++----
 .../data/correctness_p0/test_bit_shift_nereids.out       |  8 ++++----
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/be/src/vec/functions/function_bit_shift.cpp 
b/be/src/vec/functions/function_bit_shift.cpp
index 36a5c59e3cb..9812e874a91 100644
--- a/be/src/vec/functions/function_bit_shift.cpp
+++ b/be/src/vec/functions/function_bit_shift.cpp
@@ -22,6 +22,7 @@
 #include <stdexcept>
 #include <type_traits>
 
+#include "common/compiler_util.h"
 #include "common/exception.h"
 #include "common/logging.h"
 #include "common/status.h"
@@ -53,9 +54,10 @@ struct BitShiftLeftImpl {
         } else {
             // return zero if b < 0, keep consistent with mysql
             // cast to unsigned so that we can do logical shift by default, 
keep consistent with mysql
-            return b < 0 ? 0
-                         : static_cast<typename std::make_unsigned<A>::type>(a)
-                                   << static_cast<Result>(b);
+            if (UNLIKELY(b >= 64 || b < 0)) {
+                return 0;
+            }
+            return static_cast<typename std::make_unsigned<A>::type>(a) << 
static_cast<Result>(b);
         }
     }
 };
@@ -72,9 +74,11 @@ struct BitShiftRightImpl {
         } else {
             // return zero if b < 0, keep consistent with mysql
             // cast to unsigned so that we can do logical shift by default, 
keep consistent with mysql
-            return b < 0 ? 0
-                         : static_cast<typename 
std::make_unsigned<A>::type>(a) >>
-                                   static_cast<Result>(b);
+            if (UNLIKELY(b >= 64 || b < 0)) {
+                return 0;
+            }
+
+            return static_cast<typename std::make_unsigned<A>::type>(a) >> 
static_cast<Result>(b);
         }
     }
 };
diff --git a/regression-test/data/correctness_p0/test_bit_shift_lagency.out 
b/regression-test/data/correctness_p0/test_bit_shift_lagency.out
index 1c956fe3c74..7c8883653bf 100644
--- a/regression-test/data/correctness_p0/test_bit_shift_lagency.out
+++ b/regression-test/data/correctness_p0/test_bit_shift_lagency.out
@@ -24,7 +24,7 @@ testing big_shift_left
 -9223372036854775808
 
 -- !3 --
-1
+0
 
 -- !select --
 254
@@ -39,7 +39,7 @@ testing big_shift_left
 -9223372036854775808   0
 
 -- !select --
-127    -9223372036854775808
+127    0
 
 -- !select --
 -128   0
@@ -64,7 +64,7 @@ testing big_shift_right
 0
 
 -- !select --
-9223372036854775807
+0
 
 -- !select --
 2
@@ -73,7 +73,7 @@ testing big_shift_right
 1
 
 -- !select --
--9223372036854775808
+0
 
 -- !select --
 0
diff --git a/regression-test/data/correctness_p0/test_bit_shift_nereids.out 
b/regression-test/data/correctness_p0/test_bit_shift_nereids.out
index 1c956fe3c74..7c8883653bf 100644
--- a/regression-test/data/correctness_p0/test_bit_shift_nereids.out
+++ b/regression-test/data/correctness_p0/test_bit_shift_nereids.out
@@ -24,7 +24,7 @@ testing big_shift_left
 -9223372036854775808
 
 -- !3 --
-1
+0
 
 -- !select --
 254
@@ -39,7 +39,7 @@ testing big_shift_left
 -9223372036854775808   0
 
 -- !select --
-127    -9223372036854775808
+127    0
 
 -- !select --
 -128   0
@@ -64,7 +64,7 @@ testing big_shift_right
 0
 
 -- !select --
-9223372036854775807
+0
 
 -- !select --
 2
@@ -73,7 +73,7 @@ testing big_shift_right
 1
 
 -- !select --
--9223372036854775808
+0
 
 -- !select --
 0


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to