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

Mryange 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 4af60fe073c [fix](expr) Enforce nullable column output matching 
(#68388)
4af60fe073c is described below

commit 4af60fe073c3fb039de8d2b396efa29e132fcdaf
Author: Mryange <[email protected]>
AuthorDate: Wed Sep 23 14:31:51 2026 +0800

    [fix](expr) Enforce nullable column output matching (#68388)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: None
    
    Problem Summary: VExpr::execute_column accepted a non-nullable column
    when the expression declared Nullable(T), even though DataTypeNullable
    requires a ColumnNullable representation. Remove this expression-only
    fallback so data type nullability and column nullability remain aligned.
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test: No need to test (pipeline validation requested)
    - Behavior changed: Yes (strictly enforce nullable column output
    matching)
    - Does this need documentation: No
---
 be/src/exprs/vexpr.cpp       | 12 +++---------
 be/test/exprs/vexpr_test.cpp |  6 +++---
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/be/src/exprs/vexpr.cpp b/be/src/exprs/vexpr.cpp
index 557d04a4e1f..e49bb037865 100644
--- a/be/src/exprs/vexpr.cpp
+++ b/be/src/exprs/vexpr.cpp
@@ -1074,16 +1074,10 @@ Status VExpr::execute_column(VExprContext* context, 
const Block* block, const Se
     if (!check_and_get_column<ColumnNothing>(result_column.get())) {
         auto result_type = execute_type(block);
         if (result_type != nullptr) {
-            Status st = result_type->check_column(*result_column);
-            if (!st.ok()) {
-                // Nullable(T) may legitimately produce a non-nullable T 
column when all rows are
-                // non-null (use_default_implementation_for_nulls 
optimization). Allow this.
-                const auto* nullable_type =
-                        
check_and_get_data_type<DataTypeNullable>(result_type.get());
-                if (nullable_type && 
!check_and_get_column<ColumnNullable>(result_column.get())) {
-                    st = 
nullable_type->get_nested_type()->check_column(*result_column);
-                }
+            if (result_type->is_nullable() && !result_column->is_nullable()) {
+                result_column = make_nullable(result_column, false);
             }
+            Status st = result_type->check_column(*result_column);
             if (!st.ok()) {
                 return Status::InternalError(
                         "Expr {} return column type mismatch: declared={}, 
actual={}", expr_name(),
diff --git a/be/test/exprs/vexpr_test.cpp b/be/test/exprs/vexpr_test.cpp
index 10bdfb815d7..6138fc89ea3 100644
--- a/be/test/exprs/vexpr_test.cpp
+++ b/be/test/exprs/vexpr_test.cpp
@@ -893,11 +893,10 @@ TEST(VExprExecuteColumnTest, TypeMismatchFails) {
     EXPECT_FALSE(st.ok());
 }
 
-TEST(VExprExecuteColumnTest, NullableTypeWithNonNullableColumnPasses) {
+TEST(VExprExecuteColumnTest, NullableTypeWithNonNullableColumnIsWrapped) {
     using namespace doris;
     FakeVExpr expr;
-    // Declared type is Nullable(Int32) but result is Int32 (non-nullable).
-    // This mirrors the use_default_implementation_for_nulls optimization and 
must pass.
+    // Declared type is Nullable(Int32), so the result must carry a nullable 
column wrapper.
     
expr.set_data_type(std::make_shared<DataTypeNullable>(std::make_shared<DataTypeInt32>()));
 
     auto col = ColumnInt32::create();
@@ -907,6 +906,7 @@ TEST(VExprExecuteColumnTest, 
NullableTypeWithNonNullableColumnPasses) {
     ColumnPtr result;
     auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
     EXPECT_TRUE(st.ok());
+    EXPECT_TRUE(result->is_nullable());
 }
 
 TEST(VExprExecuteColumnTest, ColumnNothingPassesTypeCheck) {


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

Reply via email to