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

yiguolei 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 f9264215767 [Fix](expr) Fix case when wrong result and relative date 
types false alarm (#60040)
f9264215767 is described below

commit f9264215767bea13aaeff630edfd50fcf274753b
Author: zclllyybb <[email protected]>
AuthorDate: Tue Jan 20 17:24:41 2026 +0800

    [Fix](expr) Fix case when wrong result and relative date types false alarm 
(#60040)
    
    ### What problem does this PR solve?
    
    Issue Number: close #xxx
    
    Related PR: #xxx
    
    Problem Summary:
    
    before if there's null return for `case-when` expr and the type is a
    datelike type. may raise false alarm caused by invalid nested value:
    ```
    ERROR 1105 (HY000): errCode = 2, detailMessage = 
(10.16.10.3)[INVALID_ARGUMENT]Operation to_date meets invalid data:
    ```
    now fixed it.
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [x] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] 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/vec/columns/column_const.h                  |  13 ++
 be/src/vec/columns/column_vector.h                 |   5 +-
 be/src/vec/exprs/vcase_expr.h                      |  15 ++-
 .../data/correctness_p0/test_case_when_date.out    |  50 +++++++
 .../correctness_p0/test_case_when_date.groovy      | 144 +++++++++++++++++++++
 5 files changed, 220 insertions(+), 7 deletions(-)

diff --git a/be/src/vec/columns/column_const.h 
b/be/src/vec/columns/column_const.h
index bd14c01840c..ebab72c13e5 100644
--- a/be/src/vec/columns/column_const.h
+++ b/be/src/vec/columns/column_const.h
@@ -290,6 +290,19 @@ public:
                         "Method replace_column_data is not supported for " + 
get_name());
     }
 
+    void replace_column_null_data(const uint8_t* __restrict null_map) override 
{
+        // For ColumnConst, the null_map has only 1 element (the const value's 
null status)
+        // If the const value is null, replace the nested data with default 
value
+        if (null_map[0]) {
+            data = std::move(*data).mutate();
+            data->replace_column_null_data(null_map);
+        }
+    }
+
+    bool support_replace_column_null_data() const override {
+        return data->support_replace_column_null_data();
+    }
+
     void finalize() override { data->finalize(); }
 
     void erase(size_t start, size_t length) override {
diff --git a/be/src/vec/columns/column_vector.h 
b/be/src/vec/columns/column_vector.h
index e3cdbba8c7f..e3da600eeee 100644
--- a/be/src/vec/columns/column_vector.h
+++ b/be/src/vec/columns/column_vector.h
@@ -382,9 +382,6 @@ public:
     size_t serialize_impl(char* pos, const size_t row) const override;
     size_t deserialize_impl(const char* pos) override;
     size_t serialize_size_at(size_t row) const override { return 
sizeof(value_type); }
-
-protected:
-    uint32_t _crc32c_hash(uint32_t hash, size_t idx) const;
     // when run function which need_replace_null_data_to_default, use the 
value far from 0 to avoid
     // raise errors for null cell.
     static value_type default_value() {
@@ -395,6 +392,8 @@ protected:
         }
     }
 
+protected:
+    uint32_t _crc32c_hash(uint32_t hash, size_t idx) const;
     Container data;
 };
 
diff --git a/be/src/vec/exprs/vcase_expr.h b/be/src/vec/exprs/vcase_expr.h
index 9001b2fb9eb..db31a42a457 100644
--- a/be/src/vec/exprs/vcase_expr.h
+++ b/be/src/vec/exprs/vcase_expr.h
@@ -204,7 +204,15 @@ private:
 
         // set default value
         for (int i = 0; i < rows_count; i++) {
-            result_raw_data[i] = {};
+            if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
+                          std::is_same_v<ColumnType, ColumnDateTime> ||
+                          std::is_same_v<ColumnType, ColumnDateV2> ||
+                          std::is_same_v<ColumnType, ColumnDateTimeV2> ||
+                          std::is_same_v<ColumnType, ColumnTimeStampTz>) {
+                result_raw_data[i] = ColumnType::default_value();
+            } else {
+                result_raw_data[i] = {};
+            }
         }
 
         for (IndexType i = 0; i < then_columns.size(); i++) {
@@ -222,9 +230,8 @@ private:
                           std::is_same_v<ColumnType, ColumnDateTimeV2> ||
                           std::is_same_v<ColumnType, ColumnTimeStampTz>) {
                 for (int row_idx = 0; row_idx < rows_count; row_idx++) {
-                    result_raw_data[row_idx] =
-                            (then_idx[row_idx] == i ? column_raw_data[row_idx]
-                                                    : typename 
ColumnType::value_type());
+                    result_raw_data[row_idx] = (then_idx[row_idx] == i) ? 
column_raw_data[row_idx]
+                                                                        : 
result_raw_data[row_idx];
                 }
             } else {
                 for (int row_idx = 0; row_idx < rows_count; row_idx++) {
diff --git a/regression-test/data/correctness_p0/test_case_when_date.out 
b/regression-test/data/correctness_p0/test_case_when_date.out
new file mode 100644
index 00000000000..5ada1fd2b1e
--- /dev/null
+++ b/regression-test/data/correctness_p0/test_case_when_date.out
@@ -0,0 +1,50 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !case_when_to_date --
+1      2023-01-01
+2      2023-02-15
+3      2023-03-20
+4      2023-04-11
+5      2023-05-26
+
+-- !case_when_date_3branches --
+1      2023-01-01
+2      2023-02-25
+3      2023-03-20
+4      2023-04-10
+5      2023-05-25
+
+-- !case_when_month --
+1      1
+2      2
+3      3
+4      4
+5      5
+
+-- !case_when_dayofmonth --
+1      1
+2      15
+3      20
+4      10
+5      25
+
+-- !case_when_datetime --
+1      2023-01-01T10:00
+2      2023-02-15T12:30
+3      2023-03-20T15:45
+4      2023-04-10T08:00
+5      2023-05-25T20:00
+
+-- !case_when_datetimev2_to_date --
+1      2023-01-01
+2      2023-02-15
+3      2023-03-20
+4      2023-04-10
+5      2023-05-25
+
+-- !case_when_nested --
+1      2023-01-01
+2      2023-02-15
+3      2023-03-20
+4      2023-04-10
+5      2023-05-25
+
diff --git a/regression-test/suites/correctness_p0/test_case_when_date.groovy 
b/regression-test/suites/correctness_p0/test_case_when_date.groovy
new file mode 100644
index 00000000000..25738023355
--- /dev/null
+++ b/regression-test/suites/correctness_p0/test_case_when_date.groovy
@@ -0,0 +1,144 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("test_case_when_date") {
+    sql """ DROP TABLE IF EXISTS test_case_when_date_tbl """
+    sql """
+        CREATE TABLE test_case_when_date_tbl
+        (
+            id INT NOT NULL,
+            col_date DATE NULL,
+            col_date_not_null DATE NOT NULL,
+            col_datev2 DATEV2 NULL,
+            col_datev2_not_null DATEV2 NOT NULL,
+            col_datetime DATETIME NULL,
+            col_datetime_not_null DATETIME NOT NULL,
+            col_datetimev2 DATETIMEV2 NULL,
+            col_datetimev2_not_null DATETIMEV2 NOT NULL
+        )
+        DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES("replication_num" = "1");
+    """
+
+    // Insert test data with various date values
+    sql """
+        INSERT INTO test_case_when_date_tbl VALUES
+        (1, '2023-01-01', '2023-01-01', '2023-01-01', '2023-01-01', 
'2023-01-01 10:00:00', '2023-01-01 10:00:00', '2023-01-01 10:00:00', 
'2023-01-01 10:00:00'),
+        (2, '2023-02-15', '2023-02-15', '2023-02-15', '2023-02-15', 
'2023-02-15 12:30:00', '2023-02-15 12:30:00', '2023-02-15 12:30:00', 
'2023-02-15 12:30:00'),
+        (3, '2023-03-20', '2023-03-20', '2023-03-20', '2023-03-20', 
'2023-03-20 15:45:00', '2023-03-20 15:45:00', '2023-03-20 15:45:00', 
'2023-03-20 15:45:00'),
+        (4, NULL, '2023-04-10', NULL, '2023-04-10', NULL, '2023-04-10 
08:00:00', NULL, '2023-04-10 08:00:00'),
+        (5, '2023-05-25', '2023-05-25', '2023-05-25', '2023-05-25', 
'2023-05-25 20:00:00', '2023-05-25 20:00:00', '2023-05-25 20:00:00', 
'2023-05-25 20:00:00');
+    """
+
+    // Test 1: CASE WHEN with multiple branches on DATEV2, applying TO_DATE 
function
+    // This was the original failing case - multi-branch CASE WHEN with date 
functions
+    qt_case_when_to_date """
+        SELECT id,
+            TO_DATE(
+                CASE
+                    WHEN col_datev2 IN ('2023-01-01', '2023-02-15') THEN 
col_datev2_not_null
+                    WHEN col_datev2 = '2023-03-20' THEN col_datev2_not_null
+                    ELSE DATE_ADD(col_datev2_not_null, INTERVAL 1 DAY)
+                END
+            ) AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 2: CASE WHEN with 3 branches on DATE type
+    qt_case_when_date_3branches """
+        SELECT id,
+            CASE
+                WHEN id = 1 THEN col_date_not_null
+                WHEN id = 2 THEN DATE_ADD(col_date_not_null, INTERVAL 10 DAY)
+                ELSE col_date_not_null
+            END AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 3: CASE WHEN with MONTH function on result
+    qt_case_when_month """
+        SELECT id,
+            MONTH(
+                CASE
+                    WHEN id <= 2 THEN col_datev2_not_null
+                    WHEN id = 3 THEN col_datev2_not_null
+                    ELSE col_datev2_not_null
+                END
+            ) AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 4: CASE WHEN with DAYOFMONTH function
+    qt_case_when_dayofmonth """
+        SELECT id,
+            DAYOFMONTH(
+                CASE
+                    WHEN id = 1 THEN col_datev2_not_null
+                    WHEN id IN (2, 3) THEN col_datev2_not_null
+                    ELSE col_datev2_not_null
+                END
+            ) AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 5: CASE WHEN on DATETIME type with multiple branches
+    qt_case_when_datetime """
+        SELECT id,
+            CASE
+                WHEN id = 1 THEN col_datetime_not_null
+                WHEN id = 2 THEN col_datetime_not_null
+                WHEN id = 3 THEN col_datetime_not_null
+                ELSE col_datetime_not_null
+            END AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 6: CASE WHEN on DATETIMEV2 with date functions
+    qt_case_when_datetimev2_to_date """
+        SELECT id,
+            TO_DATE(
+                CASE
+                    WHEN id <= 2 THEN col_datetimev2_not_null
+                    WHEN id = 3 THEN col_datetimev2_not_null
+                    ELSE col_datetimev2_not_null
+                END
+            ) AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+
+    // Test 7: Nested CASE WHEN with date types
+    qt_case_when_nested """
+        SELECT id,
+            CASE
+                WHEN id = 1 THEN
+                    CASE
+                        WHEN col_datev2 IS NOT NULL THEN col_datev2_not_null
+                        ELSE col_datev2_not_null
+                    END
+                WHEN id = 2 THEN col_datev2_not_null
+                ELSE col_datev2_not_null
+            END AS result
+        FROM test_case_when_date_tbl
+        ORDER BY id;
+    """
+}


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

Reply via email to