This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new 386c5213721 [fix](test) Match Parquet TopN predicate nullability on
branch-4.2 (#69692)
386c5213721 is described below
commit 386c5213721c8a4e676523a3f26fe957a3b2201e
Author: Gabriel <[email protected]>
AuthorDate: Wed Oct 28 09:20:00 2026 +0800
[fix](test) Match Parquet TopN predicate nullability on branch-4.2 (#69692)
### What problem does this PR solve?
Issue Number: N/A
Related PR: #69661
Problem Summary: The Parquet TopN test helper declares a non-nullable
Boolean result even when its input is nullable. Once a bound is
published, the comparison returns Nullable(Boolean), so expression
result validation rejects two dictionary TopN tests. Derive the
predicate nullability from its input, matching the production
constructor. Add coverage for integer and string inputs, with and
without nullability, before and after bound publication.
### Release note
None
### Check List (For Author)
- Test: Unit Test.
- ASAN: all 81 tests in `ParquetScanTest.*` and
`ParquetRuntimeFilterDirectReaderTest.*` passed, including both
dictionary TopN cases.
- The new result-type regression test failed before the fixture fix and
passed afterward.
- clang-format 16 passed for the changed C++ file.
- Behavior changed: No; test fixture and coverage only.
- Does this need documentation: No.
---
be/test/format_v2/parquet/parquet_scan_test.cpp | 41 ++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/be/test/format_v2/parquet/parquet_scan_test.cpp
b/be/test/format_v2/parquet/parquet_scan_test.cpp
index d8934a4f690..78ff462acc4 100644
--- a/be/test/format_v2/parquet/parquet_scan_test.cpp
+++ b/be/test/format_v2/parquet/parquet_scan_test.cpp
@@ -1056,7 +1056,8 @@ PreparedTopNConjunct create_topn_conjunct(RuntimeState*
state, int column_id,
TExprNode topn_node;
topn_node.__set_type(std::make_shared<DataTypeUInt8>()->to_thrift());
- topn_node.__set_is_nullable(false);
+ // Match create_vtopn_pred(): comparing a nullable input yields a nullable
Boolean result.
+ topn_node.__set_is_nullable(data_type->is_nullable());
auto topn = VTopNPred::create_shared(topn_node, 10, nullptr);
topn->add_child(VSlotRef::create_shared(column_id, column_id, -1,
data_type, "topn_column"));
auto conjunct = VExprContext::create_shared(std::move(topn));
@@ -1065,6 +1066,44 @@ PreparedTopNConjunct create_topn_conjunct(RuntimeState*
state, int column_id,
return {.query_context = std::move(query_context), .conjunct =
std::move(conjunct)};
}
+TEST(ParquetRuntimeFilterDirectReaderTest,
TopNResultTypeMatchesInputNullability) {
+ const std::vector<std::pair<DataTypePtr, Field>> inputs {
+ {std::make_shared<DataTypeInt32>(),
Field::create_field<TYPE_INT>(3)},
+ {std::make_shared<DataTypeString>(),
+ Field::create_field<TYPE_STRING>(std::string("charlie"))}};
+ for (const auto& [nested_type, bound] : inputs) {
+ for (bool nullable : {false, true}) {
+ const auto type = nullable ? make_nullable(nested_type) :
nested_type;
+ SCOPED_TRACE(type->get_name());
+ RuntimeState state {TQueryOptions(), TQueryGlobals()};
+ auto prepared = create_topn_conjunct(&state, 0, type, bound,
false);
+ auto column = type->create_column();
+ column->insert(nullable ? Field() : bound);
+ column->insert(bound);
+ Block block;
+ block.insert({std::move(column), type, "topn_column"});
+ for (bool publish_bound : {false, true}) {
+ if (publish_bound) {
+ ASSERT_TRUE(
+
prepared.query_context->get_runtime_predicate(10).update(bound).ok());
+ }
+ ColumnPtr result;
+ const auto status = prepared.conjunct->root()->execute_column(
+ prepared.conjunct.get(), &block, nullptr, 2, result);
+ ASSERT_TRUE(status.ok()) << status;
+ ASSERT_EQ(result->size(), 2);
+ const auto result_type =
prepared.conjunct->root()->data_type();
+ const auto type_status = result_type->check_column(*result);
+ EXPECT_TRUE(type_status.ok()) << type_status;
+ EXPECT_EQ(result_type->is_nullable(), nullable);
+ EXPECT_EQ(result->is_null_at(0), nullable && publish_bound);
+ EXPECT_EQ(result->get_bool(1), 1);
+ }
+ prepared.conjunct->close();
+ }
+ }
+}
+
template <PrimitiveType T>
void expect_fixed_comparison_raw_eligible(const DataTypePtr& type) {
const auto predicate = create_binary_predicate(
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]