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]