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

panxiaolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 2e34bee48bb [Exec](vec) speed update date_floor (#50392)
2e34bee48bb is described below

commit 2e34bee48bb8aef404408c685c9bbe9b10ae0f6d
Author: HappenLee <[email protected]>
AuthorDate: Mon May 5 21:45:56 2025 +0800

    [Exec](vec) speed update date_floor (#50392)
    
    ### What problem does this PR solve?
    
    before can div 60%:
    ```
    mysql> select count(date_floor(l_commitdate, interval 5 minute)) from 
lineitem;
    +-----------------------------------------------------+
    | count(date_floor(l_commitdate, interval 5 minute)) |
    +-----------------------------------------------------+
    |                                           600037902 |
    +-----------------------------------------------------+
    1 row in set (32.99 sec)
    ```
    
    after can div:
    ```
    mysql> select count(date_floor(l_commitdate, interval 5 minute)) from 
lineitem;
    +----------------------------------------------------+
    | count(date_floor(l_commitdate, interval 5 minute)) |
    +----------------------------------------------------+
    |                                          600037902 |
    +----------------------------------------------------+
    1 row in set (6.10 sec)
    ```
    
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [x] No need to test or manual test. Explain why:
    - [x] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [x] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [x] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 be/src/util/time_lut.cpp                           | 29 ----------
 be/src/util/time_lut.h                             |  2 -
 .../vec/functions/function_datetime_floor_ceil.cpp | 65 ++++++++++++++++++----
 be/src/vec/runtime/vdatetime_value.cpp             | 23 +++-----
 be/src/vec/runtime/vdatetime_value.h               | 44 +++++++++++++--
 5 files changed, 101 insertions(+), 62 deletions(-)

diff --git a/be/src/util/time_lut.cpp b/be/src/util/time_lut.cpp
index cb2aecb7289..9864dd9923b 100644
--- a/be/src/util/time_lut.cpp
+++ b/be/src/util/time_lut.cpp
@@ -91,35 +91,6 @@ uint8_t calc_weekday(uint64_t day_nr, bool 
is_sunday_first_day) {
     return (day_nr + 5L + (is_sunday_first_day ? 1L : 0L)) % 7;
 }
 
-uint32_t calc_daynr(uint16_t year, uint8_t month, uint8_t day) {
-    // date_day_offet_dict range from [1900-01-01, 2039-12-31]
-    if (date_day_offset_dict::can_speed_up_calc_daynr(year) &&
-        LIKELY(date_day_offset_dict::get_dict_init())) {
-        return date_day_offset_dict::get().daynr(year, month, day);
-    }
-
-    uint32_t delsum = 0;
-    int y = year;
-
-    if (year == 0 && month == 0) {
-        return 0;
-    }
-
-    /* Cast to int to be able to handle month == 0 */
-    delsum = 365 * y + 31 * (month - 1) + day;
-    if (month <= 2) {
-        // No leap year
-        y--;
-    } else {
-        // This is great!!!
-        // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
-        // 0, 0, 3, 3, 4, 4, 5, 5, 5,  6,  7,  8
-        delsum -= (month * 4 + 23) / 10;
-    }
-    // Every 400 year has 97 leap year, 100, 200, 300 are not leap year.
-    return delsum + y / 4 - y / 100 + y / 400;
-}
-
 uint32_t year_week(uint16_t yy, uint8_t month, uint8_t day) {
     //not covered by year_week_table, calculate at runtime
     uint16_t to_year = 0;
diff --git a/be/src/util/time_lut.h b/be/src/util/time_lut.h
index f98560c45e1..4764cf00220 100644
--- a/be/src/util/time_lut.h
+++ b/be/src/util/time_lut.h
@@ -32,8 +32,6 @@ constexpr uint32_t NUM_DAYS = 31;
 
 uint32_t year_week(uint16_t yy, uint8_t month, uint8_t day);
 
-uint32_t calc_daynr(uint16_t year, uint8_t month, uint8_t day);
-
 uint8_t calc_weekday(uint64_t day_nr, bool is_sunday_first_day);
 
 inline bool is_leap(uint32_t year) {
diff --git a/be/src/vec/functions/function_datetime_floor_ceil.cpp 
b/be/src/vec/functions/function_datetime_floor_ceil.cpp
index 0e5cd2f2f58..fad31b0e12c 100644
--- a/be/src/vec/functions/function_datetime_floor_ceil.cpp
+++ b/be/src/vec/functions/function_datetime_floor_ceil.cpp
@@ -178,7 +178,6 @@ public:
                     vector_const_const(sources->get_data(), arg1.get<Int32>(),
                                        arg2.get<NativeType>(), 
col_to->get_data(),
                                        null_map->get_data());
-
                 } else if (arg1_const && !arg2_const) {
                     Field arg1;
                     arg1_col->get(0, arg1);
@@ -244,18 +243,42 @@ private:
             memset(null_map.data(), 1, sizeof(UInt8) * dates.size());
             return;
         }
-        for (int i = 0; i < dates.size(); ++i) {
-            SET_NULLMAP_IF_FALSE((time_round_reinterpret_two_args(dates[i], 
period, res[i])));
+
+        // expand codes for const input periods
+#define EXPAND_CODE_FOR_CONST_INPUT(X)                                         
                   \
+    case X: {                                                                  
                   \
+        for (int i = 0; i < dates.size(); ++i) {                               
                   \
+            SET_NULLMAP_IF_FALSE((time_round_reinterpret_two_args<X>(dates[i], 
period, res[i]))); \
+        }                                                                      
                   \
+        return;                                                                
                   \
+    }
+#define EXPANDER(z, n, text) EXPAND_CODE_FOR_CONST_INPUT(n)
+        switch (period) {
+            // expand for some constant period
+            BOOST_PP_REPEAT(12, EXPANDER, ~)
+        default:
+            for (int i = 0; i < dates.size(); ++i) {
+                
SET_NULLMAP_IF_FALSE((time_round_reinterpret_two_args(dates[i], period, 
res[i])));
+            }
         }
+#undef EXPAND_CODE_FOR_CONST_INPUT
+#undef EXPANDER
     }
 
     static void vector_const_const(const PaddedPODArray<NativeType>& dates, 
const Int32 period,
                                    NativeType origin_date, 
PaddedPODArray<NativeType>& res,
                                    NullMap& null_map) {
+        if (auto cast_date = binary_cast<NativeType, 
DateValueType>(origin_date);
+            cast_date == DateValueType::FIRST_DAY) {
+            vector_const_period(dates, period, res, null_map);
+            return;
+        }
+
         if (period < 1) {
             memset(null_map.data(), 1, sizeof(UInt8) * dates.size());
             return;
         }
+
         // expand codes for const input periods
 #define EXPAND_CODE_FOR_CONST_INPUT(X)                                   \
     case X: {                                                            \
@@ -264,7 +287,7 @@ private:
             res[i] = origin_date;                                        \
             auto ts2 = binary_cast<NativeType, DateValueType>(dates[i]); \
             auto& ts1 = (DateValueType&)(res[i]);                        \
-            SET_NULLMAP_IF_FALSE(time_round_two_args(ts2, X, ts1))       \
+            SET_NULLMAP_IF_FALSE(time_round_two_args<X>(ts2, X, ts1))    \
         }                                                                \
         return;                                                          \
     }
@@ -368,17 +391,27 @@ private:
         }
     }
 
-    ALWAYS_INLINE static bool time_round_reinterpret_two_args(NativeType date, 
Int32 period,
-                                                              NativeType& res) 
{
+    template <int const_period = 0>
+    static bool time_round_reinterpret_two_args(NativeType date, Int32 period, 
NativeType& res) {
         auto ts_arg = binary_cast<NativeType, DateValueType>(date);
         auto& ts_res = (DateValueType&)(res);
 
-        if (can_use_optimize(period)) {
-            floor_opt(ts_arg, ts_res, period);
-            return true;
+        if constexpr (const_period == 0) {
+            if (can_use_optimize(period)) {
+                floor_opt(ts_arg, ts_res, period);
+                return true;
+            } else {
+                ts_res = DateValueType::FIRST_DAY;
+                return time_round_two_args(ts_arg, period, ts_res);
+            }
         } else {
-            ts_res = DateValueType::FIRST_DAY;
-            return time_round_two_args(ts_arg, period, ts_res);
+            if (can_use_optimize(const_period)) {
+                floor_opt(ts_arg, ts_res, const_period);
+                return true;
+            } else {
+                ts_res = DateValueType::FIRST_DAY;
+                return time_round_two_args<const_period>(ts_arg, const_period, 
ts_res);
+            }
         }
     }
 
@@ -443,6 +476,7 @@ private:
         }
     }
 
+    template <Int32 const_period = 0>
     static bool time_round_two_args(const DateValueType& ts_arg, const Int32 
period,
                                     DateValueType& ts_res) {
         int64_t diff;
@@ -582,7 +616,14 @@ private:
         }
 
         //round down/up inside time period(several time-units)
-        int64_t delta_inside_period = diff >= 0 ? diff % period : (diff % 
period + period) % period;
+        int64_t delta_inside_period;
+        if constexpr (const_period != 0) {
+            delta_inside_period = diff >= 0 ? diff % const_period
+                                            : (diff % const_period + 
const_period) % const_period;
+        } else {
+            delta_inside_period = diff >= 0 ? diff % period : (diff % period + 
period) % period;
+        }
+
         int64_t step = diff - delta_inside_period +
                        (Flag::Type == FLOOR        ? 0
                         : delta_inside_period == 0 ? 0
diff --git a/be/src/vec/runtime/vdatetime_value.cpp 
b/be/src/vec/runtime/vdatetime_value.cpp
index 1b83a890c69..9e27c163876 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -2777,14 +2777,6 @@ bool date_day_offset_dict::DATE_DAY_OFFSET_ITEMS_INIT = 
false;
 
 date_day_offset_dict date_day_offset_dict::instance = date_day_offset_dict();
 
-date_day_offset_dict& date_day_offset_dict::get() {
-    return instance;
-}
-
-bool date_day_offset_dict::get_dict_init() {
-    return DATE_DAY_OFFSET_ITEMS_INIT;
-}
-
 date_day_offset_dict::date_day_offset_dict() {
     DateV2Value<DateV2ValueType> d;
     // Init days before epoch.
@@ -2813,10 +2805,6 @@ date_day_offset_dict::date_day_offset_dict() {
     DATE_DAY_OFFSET_ITEMS_INIT = true;
 }
 
-int date_day_offset_dict::daynr(int year, int month, int day) const {
-    return DATE_DAY_OFFSET_DICT[year - START_YEAR][month - 1][day - 1];
-}
-
 template <typename T>
 uint8_t DateV2Value<T>::week(uint8_t mode) const {
     uint16_t year = 0;
@@ -3011,9 +2999,14 @@ bool DateV2Value<T>::date_add_interval(const 
TimeInterval& interval) {
             return false;
         }
         if constexpr (is_datetime) {
-            PROPAGATE_FALSE(this->check_range_and_set_time(0, 0, 0, seconds / 
3600,
-                                                           (seconds / 60) % 
60, seconds % 60,
-                                                           microseconds, 
true));
+            if constexpr (need_check) {
+                PROPAGATE_FALSE(this->check_range_and_set_time(0, 0, 0, 
seconds / 3600,
+                                                               (seconds / 60) 
% 60, seconds % 60,
+                                                               microseconds, 
true));
+            } else {
+                this->unchecked_set_time(seconds / 3600, (seconds / 60) % 60, 
seconds % 60,
+                                         microseconds);
+            }
         }
     } else if constexpr (unit == YEAR) {
         // This only change year information
diff --git a/be/src/vec/runtime/vdatetime_value.h 
b/be/src/vec/runtime/vdatetime_value.h
index 77df894f21c..f46ce163c11 100644
--- a/be/src/vec/runtime/vdatetime_value.h
+++ b/be/src/vec/runtime/vdatetime_value.h
@@ -219,6 +219,8 @@ static RE2 
time_zone_offset_format_reg(R"(^[+-]{1}\d{2}\:\d{2}$)");
 
 uint8_t mysql_week_mode(uint32_t mode);
 
+inline uint32_t calc_daynr(uint16_t year, uint8_t month, uint8_t day);
+
 struct DateV2ValueType {
     uint32_t day_ : 5;
     uint32_t month_ : 4;
@@ -1370,7 +1372,7 @@ private:
 };
 
 template <typename T>
-inline const DateV2Value<T> DateV2Value<T>::FIRST_DAY = DateV2Value<T>(1, 1, 
1, 0, 0, 0, 0);
+inline const DateV2Value<T> DateV2Value<T>::FIRST_DAY = DateV2Value<T>(0001, 
1, 1, 0, 0, 0, 0);
 
 // only support DATE - DATE (no support DATETIME - DATETIME)
 std::size_t operator-(const VecDateTimeValue& v1, const VecDateTimeValue& v2);
@@ -1613,9 +1615,9 @@ public:
         return res >= 0 ? res <= DAY_AFTER_EPOCH : -res <= DAY_BEFORE_EPOCH;
     }
 
-    static date_day_offset_dict& get();
+    static date_day_offset_dict& get() { return instance; }
 
-    static bool get_dict_init();
+    static bool get_dict_init() { return DATE_DAY_OFFSET_ITEMS_INIT; }
 
     inline DateV2Value<DateV2ValueType> operator[](int day) const {
         int index = day + DAY_BEFORE_EPOCH;
@@ -1627,9 +1629,43 @@ public:
         }
     }
 
-    int daynr(int year, int month, int day) const;
+    int daynr(int year, int month, int day) const {
+        return DATE_DAY_OFFSET_DICT[year - START_YEAR][month - 1][day - 1];
+    }
 };
 
+inline uint32_t calc_daynr(uint16_t year, uint8_t month, uint8_t day) {
+    // date_day_offet_dict range from [1900-01-01, 2039-12-31]
+    if (date_day_offset_dict::can_speed_up_calc_daynr(year) &&
+        LIKELY(date_day_offset_dict::get_dict_init())) {
+        return date_day_offset_dict::get().daynr(year, month, day);
+    }
+
+    uint32_t delsum = 0;
+    int y = year;
+
+    if (year == 0 && month == 0) {
+        return 0;
+    }
+    if (year == 0 && month == 1 && day == 1) {
+        return 1;
+    }
+
+    /* Cast to int to be able to handle month == 0 */
+    delsum = 365 * y + 31 * (month - 1) + day;
+    if (month <= 2) {
+        // No leap year
+        y--;
+    } else {
+        // This is great!!!
+        // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
+        // 0, 0, 3, 3, 4, 4, 5, 5, 5,  6,  7,  8
+        delsum -= (month * 4 + 23) / 10;
+    }
+    // Every 400 year has 97 leap year, 100, 200, 300 are not leap year.
+    return delsum + y / 4 - y / 100 + y / 400;
+}
+
 template <typename T>
 struct DateTraits {};
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to