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 b350f8cc433 [refine](expr) Check type and column match in
VExpr::execute_column (branch-4.2) #62614 (#69661)
b350f8cc433 is described below
commit b350f8cc43326ec9086caafd07ad9f5350fae7b7
Author: Mryange <[email protected]>
AuthorDate: Wed Oct 28 09:22:53 2026 +0800
[refine](expr) Check type and column match in VExpr::execute_column
(branch-4.2) #62614 (#69661)
### What problem does this PR solve?
Issue Number: N/A
Related PR: #62614
Problem Summary: Backport #62614 to branch-4.2. Expression evaluation
could return a column whose size or physical type does not match the
declared result, allowing inconsistencies to propagate downstream. Add
validation in `VExpr::execute_column` and move subclass implementations
to `execute_column_impl` with read-only selectors. Adapt type validation
to the 4.2 APIs, including valid non-nullable results for nullable
declared types.
### Release note
None
### Check List (For Author)
- Test:
- Validation: `BUILD_TYPE=ASAN sh build.sh --be --clean -j48` passed.
- Unit and regression tests were not run.
- Behavior changed: Yes. Invalid expression result sizes or types now
return an error.
- Does this need documentation: No.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
---
be/src/exprs/lambda_function/lambda_function.h | 2 +-
.../lambda_function/varray_filter_function.cpp | 6 +-
.../exprs/lambda_function/varray_map_function.cpp | 4 +-
.../exprs/lambda_function/varray_sort_function.cpp | 4 +-
be/src/exprs/short_circuit_evaluation_expr.cpp | 32 +--
be/src/exprs/short_circuit_evaluation_expr.h | 16 +-
be/src/exprs/vbloom_predicate.cpp | 8 +-
be/src/exprs/vbloom_predicate.h | 6 +-
be/src/exprs/vcase_expr.cpp | 5 +-
be/src/exprs/vcase_expr.h | 4 +-
be/src/exprs/vcast_expr.cpp | 10 +-
be/src/exprs/vcast_expr.h | 8 +-
be/src/exprs/vcolumn_ref.h | 4 +-
be/src/exprs/vcompound_pred.h | 7 +-
be/src/exprs/vcondition_expr.cpp | 18 +-
be/src/exprs/vcondition_expr.h | 12 +-
be/src/exprs/vdirect_in_predicate.h | 6 +-
be/src/exprs/vectorized_fn_call.cpp | 12 +-
be/src/exprs/vectorized_fn_call.h | 8 +-
be/src/exprs/vexpr.cpp | 35 ++-
be/src/exprs/vexpr.h | 22 +-
be/src/exprs/vin_predicate.cpp | 5 +-
be/src/exprs/vin_predicate.h | 4 +-
be/src/exprs/vinfo_func.cpp | 5 +-
be/src/exprs/vinfo_func.h | 4 +-
be/src/exprs/virtual_slot_ref.cpp | 5 +-
be/src/exprs/virtual_slot_ref.h | 4 +-
be/src/exprs/vlambda_function_call_expr.h | 4 +-
be/src/exprs/vlambda_function_expr.h | 4 +-
be/src/exprs/vliteral.cpp | 5 +-
be/src/exprs/vliteral.h | 4 +-
be/src/exprs/vmatch_predicate.cpp | 6 +-
be/src/exprs/vmatch_predicate.h | 4 +-
be/src/exprs/vruntimefilter_wrapper.cpp | 8 +-
be/src/exprs/vruntimefilter_wrapper.h | 4 +-
be/src/exprs/vsearch.cpp | 5 +-
be/src/exprs/vsearch.h | 4 +-
be/src/exprs/vslot_ref.cpp | 5 +-
be/src/exprs/vslot_ref.h | 4 +-
be/src/exprs/vtopn_pred.h | 4 +-
.../vruntimefilter_wrapper_sampling_test.cpp | 4 +-
be/test/exprs/expr_zonemap_filter_test.cpp | 8 +-
be/test/exprs/function/table_function_test.cpp | 6 +-
be/test/exprs/mock_vexpr.h | 4 +-
be/test/exprs/score_runtime_test.cpp | 11 +-
be/test/exprs/vcondition_expr_test.cpp | 5 +-
be/test/exprs/vexpr_test.cpp | 260 +++++++++++++--------
be/test/exprs/virtual_slot_ref_test.cpp | 15 +-
be/test/exprs/vsearch_expr_test.cpp | 21 +-
be/test/format/parquet/parquet_expr_test.cpp | 4 +-
.../index/ann/extract_query_vector_test.cpp | 4 +-
.../segment_iterator_apply_index_expr_test.cpp | 4 +-
.../segment/segment_iterator_expr_zonemap_test.cpp | 4 +-
53 files changed, 385 insertions(+), 282 deletions(-)
diff --git a/be/src/exprs/lambda_function/lambda_function.h
b/be/src/exprs/lambda_function/lambda_function.h
index b033617a88a..31976617a54 100644
--- a/be/src/exprs/lambda_function/lambda_function.h
+++ b/be/src/exprs/lambda_function/lambda_function.h
@@ -37,7 +37,7 @@ public:
}
virtual doris::Status execute(VExprContext* context, const doris::Block*
block,
- Selector* selector, size_t count, ColumnPtr&
result_column,
+ const Selector* selector, size_t count,
ColumnPtr& result_column,
const DataTypePtr& result_type,
const VExprSPtrs& children) const = 0;
diff --git a/be/src/exprs/lambda_function/varray_filter_function.cpp
b/be/src/exprs/lambda_function/varray_filter_function.cpp
index 9d4f781a72b..3f6979b587b 100644
--- a/be/src/exprs/lambda_function/varray_filter_function.cpp
+++ b/be/src/exprs/lambda_function/varray_filter_function.cpp
@@ -52,9 +52,9 @@ public:
std::string get_name() const override { return name; }
- doris::Status execute(VExprContext* context, const doris::Block* block,
Selector* expr_selector,
- size_t output_count, ColumnPtr& result_column,
- const DataTypePtr& result_type,
+ doris::Status execute(VExprContext* context, const doris::Block* block,
+ const Selector* expr_selector, size_t output_count,
+ ColumnPtr& result_column, const DataTypePtr&
result_type,
const VExprSPtrs& children) const override {
///* array_filter(array, array<boolean>) *///
diff --git a/be/src/exprs/lambda_function/varray_map_function.cpp
b/be/src/exprs/lambda_function/varray_map_function.cpp
index 07c6ee4a03f..e16443bce65 100644
--- a/be/src/exprs/lambda_function/varray_map_function.cpp
+++ b/be/src/exprs/lambda_function/varray_map_function.cpp
@@ -86,8 +86,8 @@ public:
_lambda_argument_binding);
}
- Status execute(VExprContext* context, const Block* block, Selector*
expr_selector, size_t count,
- ColumnPtr& result_column, const DataTypePtr& result_type,
+ Status execute(VExprContext* context, const Block* block, const Selector*
expr_selector,
+ size_t count, ColumnPtr& result_column, const DataTypePtr&
result_type,
const VExprSPtrs& children) const override {
LambdaArgs args_info;
diff --git a/be/src/exprs/lambda_function/varray_sort_function.cpp
b/be/src/exprs/lambda_function/varray_sort_function.cpp
index 3c786feee25..f071c2d7791 100644
--- a/be/src/exprs/lambda_function/varray_sort_function.cpp
+++ b/be/src/exprs/lambda_function/varray_sort_function.cpp
@@ -89,8 +89,8 @@ public:
return Status::OK();
}
- Status execute(VExprContext* context, const Block* block, Selector*
expr_selector, size_t count,
- ColumnPtr& result_column, const DataTypePtr& result_type,
+ Status execute(VExprContext* context, const Block* block, const Selector*
expr_selector,
+ size_t count, ColumnPtr& result_column, const DataTypePtr&
result_type,
const VExprSPtrs& children) const override {
///* array_sort(lambda, arg) *///
diff --git a/be/src/exprs/short_circuit_evaluation_expr.cpp
b/be/src/exprs/short_circuit_evaluation_expr.cpp
index 1ebc4bfa325..40ebed3a069 100644
--- a/be/src/exprs/short_circuit_evaluation_expr.cpp
+++ b/be/src/exprs/short_circuit_evaluation_expr.cpp
@@ -89,8 +89,8 @@ std::string ShortCircuitExpr::debug_string() const {
// These are issues with the exprs themselves, but for convenience, we handle
this case uniformly in short-circuit expr.
/// TODO: Once all exprs support size-0 columns in the future, this function
can be removed.
[[nodiscard]] Status try_early_return_on_empty(const VExprSPtr& expr,
VExprContext* context,
- const Block* block, Selector*
selector, size_t count,
- ColumnPtr& result_columnn) {
+ const Block* block, const
Selector* selector,
+ size_t count, ColumnPtr&
result_columnn) {
if (count == 0) {
result_columnn = expr->execute_type(block)->create_column();
DCHECK_EQ(result_columnn->size(), 0);
@@ -177,9 +177,9 @@ void execute_if_selector(const ColumnPtr& cond_column,
const Selector* selector,
condition_view.for_each(null_func, true_func, false_func);
}
-Status ShortCircuitIfExpr::execute_column(VExprContext* context, const Block*
block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status ShortCircuitIfExpr::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column) const
{
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK(selector == nullptr || selector->size() == count);
ColumnPtr cond_column;
@@ -255,9 +255,9 @@ void execute_case_selector(const ColumnPtr& cond_column,
const Selector* executo
}
}
-Status ShortCircuitCaseExpr::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status ShortCircuitCaseExpr::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column)
const {
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK(selector == nullptr || selector->size() == count);
@@ -274,7 +274,7 @@ Status ShortCircuitCaseExpr::execute_column(VExprContext*
context, const Block*
std::vector<ColumnAndSelector> columns_and_selectors;
columns_and_selectors.resize(num_branches);
- Selector* executor_selector = selector;
+ const Selector* executor_selector = selector;
size_t executor_count = count;
Selector* current_selector = nullptr;
@@ -374,9 +374,9 @@ void execute_ifnull_selector(const ColumnPtr& cond_column,
const Selector* selec
condition_view.for_each(null_func, not_null_func);
}
-Status ShortCircuitIfNullExpr::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status ShortCircuitIfNullExpr::execute_column_impl(VExprContext* context,
const Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column)
const {
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK(selector == nullptr || selector->size() == count);
ColumnPtr expr1_column;
@@ -440,9 +440,9 @@ void execute_coalesce_selector(const ColumnPtr&
cond_column, const Selector* exe
}
}
-Status ShortCircuitCoalesceExpr::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t
count,
- ColumnPtr& result_column)
const {
+Status ShortCircuitCoalesceExpr::execute_column_impl(VExprContext* context,
const Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column)
const {
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK(selector == nullptr || selector->size() == count);
@@ -450,7 +450,7 @@ Status
ShortCircuitCoalesceExpr::execute_column(VExprContext* context, const Blo
columns_and_selectors.resize(_children.size() +
1); // the last one represents the selector
for null output
- Selector* executor_selector = selector;
+ const Selector* executor_selector = selector;
size_t executor_count = count;
Selector* current_selector = nullptr;
diff --git a/be/src/exprs/short_circuit_evaluation_expr.h
b/be/src/exprs/short_circuit_evaluation_expr.h
index 050cdba34c8..7240207aaca 100644
--- a/be/src/exprs/short_circuit_evaluation_expr.h
+++ b/be/src/exprs/short_circuit_evaluation_expr.h
@@ -71,8 +71,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
private:
inline static const std::string IF_NAME = "if";
@@ -95,8 +95,8 @@ public:
*cloned_expr = ShortCircuitCaseExpr::create_shared(node);
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
private:
const bool _has_else_expr;
@@ -117,8 +117,8 @@ public:
*cloned_expr = ShortCircuitIfNullExpr::create_shared(node);
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
private:
inline static const std::string IFNULL_NAME = "ifnull";
@@ -137,8 +137,8 @@ public:
*cloned_expr = ShortCircuitCoalesceExpr::create_shared(node);
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
private:
inline static const std::string COALESCE_NAME = "coalesce";
diff --git a/be/src/exprs/vbloom_predicate.cpp
b/be/src/exprs/vbloom_predicate.cpp
index 996d2f1031f..45ba780944f 100644
--- a/be/src/exprs/vbloom_predicate.cpp
+++ b/be/src/exprs/vbloom_predicate.cpp
@@ -73,7 +73,7 @@ void VBloomPredicate::close(VExprContext* context,
FunctionContext::FunctionStat
}
Status VBloomPredicate::_do_execute(VExprContext* context, const Block* block,
- const uint8_t* __restrict filter,
Selector* selector,
+ const uint8_t* __restrict filter, const
Selector* selector,
size_t count, ColumnPtr& result_column)
const {
DCHECK(_open_finished || block == nullptr);
DCHECK(!(filter != nullptr && selector != nullptr))
@@ -97,9 +97,9 @@ Status VBloomPredicate::_do_execute(VExprContext* context,
const Block* block,
return Status::OK();
}
-Status VBloomPredicate::execute_column(VExprContext* context, const Block*
block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status VBloomPredicate::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
return _do_execute(context, block, nullptr, selector, count,
result_column);
}
diff --git a/be/src/exprs/vbloom_predicate.h b/be/src/exprs/vbloom_predicate.h
index 31824ae740e..964b8bd67e4 100644
--- a/be/src/exprs/vbloom_predicate.h
+++ b/be/src/exprs/vbloom_predicate.h
@@ -42,8 +42,8 @@ public:
VBloomPredicate(const TExprNode& node);
~VBloomPredicate() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status execute_runtime_filter(VExprContext* context, const Block* block,
const uint8_t* __restrict filter, size_t
count,
@@ -82,7 +82,7 @@ public:
private:
Status _do_execute(VExprContext* context, const Block* block, const
uint8_t* __restrict filter,
- Selector* selector, size_t count, ColumnPtr&
result_column) const;
+ const Selector* selector, size_t count, ColumnPtr&
result_column) const;
std::shared_ptr<BloomFilterFuncBase> _filter;
inline static const std::string EXPR_NAME = "bloom_predicate";
diff --git a/be/src/exprs/vcase_expr.cpp b/be/src/exprs/vcase_expr.cpp
index 9c38f6a55fb..ca8621f2194 100644
--- a/be/src/exprs/vcase_expr.cpp
+++ b/be/src/exprs/vcase_expr.cpp
@@ -76,8 +76,9 @@ void VCaseExpr::close(VExprContext* context,
FunctionContext::FunctionStateScope
VExpr::close(context, scope);
}
-Status VCaseExpr::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
{
+Status VCaseExpr::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
if (is_const_and_have_executed()) { // const have execute in open function
result_column = get_result_from_const(count);
return Status::OK();
diff --git a/be/src/exprs/vcase_expr.h b/be/src/exprs/vcase_expr.h
index 7e7cdd11f59..806ada9e379 100644
--- a/be/src/exprs/vcase_expr.h
+++ b/be/src/exprs/vcase_expr.h
@@ -55,8 +55,8 @@ class VCaseExpr final : public VExpr {
public:
VCaseExpr(const TExprNode& node);
~VCaseExpr() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
diff --git a/be/src/exprs/vcast_expr.cpp b/be/src/exprs/vcast_expr.cpp
index 755be44b545..98d3303829b 100644
--- a/be/src/exprs/vcast_expr.cpp
+++ b/be/src/exprs/vcast_expr.cpp
@@ -107,8 +107,9 @@ void VCastExpr::close(VExprContext* context,
FunctionContext::FunctionStateScope
VExpr::close(context, scope);
}
-Status VCastExpr::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
{
+Status VCastExpr::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
DCHECK(_open_finished || block == nullptr) << _open_finished << _expr_name;
if (is_const_and_have_executed()) { // const have executed in open function
result_column = get_result_from_const(count);
@@ -148,8 +149,9 @@ DataTypePtr TryCastExpr::original_cast_return_type() const {
}
}
-Status TryCastExpr::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column)
const {
+Status TryCastExpr::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
DCHECK(_open_finished || block == nullptr) << _open_finished << _expr_name;
if (is_const_and_have_executed()) { // const have executed in open function
result_column = get_result_from_const(count);
diff --git a/be/src/exprs/vcast_expr.h b/be/src/exprs/vcast_expr.h
index abed5e3d3b1..f049811634b 100644
--- a/be/src/exprs/vcast_expr.h
+++ b/be/src/exprs/vcast_expr.h
@@ -47,8 +47,8 @@ public:
VCastExpr(const TExprNode& node)
: VExpr(node), _is_strict_cast(node.__isset.is_strict_cast &&
node.is_strict_cast) {}
~VCastExpr() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
@@ -100,8 +100,8 @@ public:
TryCastExpr(const TExprNode& node)
: VCastExpr(node),
_original_cast_return_is_nullable(node.is_cast_nullable) {}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
~TryCastExpr() override = default;
std::string cast_name() const override { return "TRY CAST"; }
bool is_safe_to_execute_on_selected_rows() const override {
diff --git a/be/src/exprs/vcolumn_ref.h b/be/src/exprs/vcolumn_ref.h
index ad9624d1239..253c50f0627 100644
--- a/be/src/exprs/vcolumn_ref.h
+++ b/be/src/exprs/vcolumn_ref.h
@@ -59,8 +59,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
DCHECK(_open_finished || block == nullptr);
const int column_position = _get_column_position(context, block);
if (column_position < 0 || column_position >= block->columns()) {
diff --git a/be/src/exprs/vcompound_pred.h b/be/src/exprs/vcompound_pred.h
index 42e5f1f772c..6d783a2e468 100644
--- a/be/src/exprs/vcompound_pred.h
+++ b/be/src/exprs/vcompound_pred.h
@@ -398,13 +398,14 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
if (fast_execute(context, selector, count, result_column)) {
return Status::OK();
}
if (get_num_children() == 1 || _has_const_child()) {
- return VectorizedFnCall::execute_column(context, block, selector,
count, result_column);
+ return VectorizedFnCall::execute_column_impl(context, block,
selector, count,
+ result_column);
}
ColumnPtr lhs_column;
diff --git a/be/src/exprs/vcondition_expr.cpp b/be/src/exprs/vcondition_expr.cpp
index f4066b06940..057cadf0b2f 100644
--- a/be/src/exprs/vcondition_expr.cpp
+++ b/be/src/exprs/vcondition_expr.cpp
@@ -451,9 +451,9 @@ Status VectorizedIfExpr::_execute_impl_internal(Block&
block, const ColumnNumber
}
}
-Status VectorizedIfExpr::execute_column(VExprContext* context, const Block*
block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status VectorizedIfExpr::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK_EQ(_children.size(), 3) << "IF expr must have three children";
@@ -492,9 +492,9 @@ Status VectorizedIfExpr::execute_column(VExprContext*
context, const Block* bloc
return Status::OK();
}
-Status VectorizedIfNullExpr::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status VectorizedIfNullExpr::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column)
const {
DCHECK(_open_finished || block == nullptr) << debug_string();
DCHECK_EQ(_children.size(), 2) << "IFNULL expr must have two children";
@@ -652,9 +652,9 @@ Status filled_result_column(const DataTypePtr& data_type,
MutableColumnPtr& resu
return Status::OK();
}
-Status VectorizedCoalesceExpr::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t count,
- ColumnPtr& return_column) const {
+Status VectorizedCoalesceExpr::execute_column_impl(VExprContext* context,
const Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& return_column)
const {
DataTypePtr result_type = _data_type;
const auto input_rows_count = count;
diff --git a/be/src/exprs/vcondition_expr.h b/be/src/exprs/vcondition_expr.h
index a6c7bd68a2c..6beade74b3e 100644
--- a/be/src/exprs/vcondition_expr.h
+++ b/be/src/exprs/vcondition_expr.h
@@ -61,8 +61,8 @@ class VectorizedIfExpr : public VConditionExpr {
public:
VectorizedIfExpr(const TExprNode& node) : VConditionExpr(node) {}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
const std::string& expr_name() const override { return IF_NAME; }
Status clone_node(VExprSPtr* cloned_expr) const override {
@@ -135,16 +135,16 @@ public:
}
inline static const std::string IF_NULL_NAME = "ifnull";
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
};
class VectorizedCoalesceExpr : public VConditionExpr {
ENABLE_FACTORY_CREATOR(VectorizedCoalesceExpr);
public:
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
VectorizedCoalesceExpr(const TExprNode& node) : VConditionExpr(node) {}
const std::string& expr_name() const override { return NAME; }
Status clone_node(VExprSPtr* cloned_expr) const override {
diff --git a/be/src/exprs/vdirect_in_predicate.h
b/be/src/exprs/vdirect_in_predicate.h
index 5eb0087c95a..93e7095574c 100644
--- a/be/src/exprs/vdirect_in_predicate.h
+++ b/be/src/exprs/vdirect_in_predicate.h
@@ -85,8 +85,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
return _do_execute(context, block, nullptr, selector, count,
result_column, nullptr);
}
@@ -285,7 +285,7 @@ private:
}
Status _do_execute(VExprContext* context, const Block* block, const
uint8_t* __restrict filter,
- Selector* selector, size_t count, ColumnPtr&
result_column,
+ const Selector* selector, size_t count, ColumnPtr&
result_column,
ColumnPtr* arg_column) const {
DCHECK(_open_finished || block == nullptr);
DCHECK(!(filter != nullptr && selector != nullptr))
diff --git a/be/src/exprs/vectorized_fn_call.cpp
b/be/src/exprs/vectorized_fn_call.cpp
index 6e31d80d2c4..137fe34e97d 100644
--- a/be/src/exprs/vectorized_fn_call.cpp
+++ b/be/src/exprs/vectorized_fn_call.cpp
@@ -376,9 +376,9 @@ bool VectorizedFnCall::can_evaluate_bloom_filter() const {
_function->can_evaluate_bloom_filter(_children);
}
-Status VectorizedFnCall::_do_execute(VExprContext* context, const Block*
block, Selector* selector,
- size_t count, ColumnPtr& result_column,
- ColumnPtr* arg_column) const {
+Status VectorizedFnCall::_do_execute(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column, ColumnPtr*
arg_column) const {
if (is_const_and_have_executed()) { // const have executed in open function
result_column = get_result_from_const(count);
return Status::OK();
@@ -467,9 +467,9 @@ Status
VectorizedFnCall::execute_runtime_filter(VExprContext* context, const Blo
return _do_execute(context, block, nullptr, count, result_column,
arg_column);
}
-Status VectorizedFnCall::execute_column(VExprContext* context, const Block*
block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status VectorizedFnCall::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
return _do_execute(context, block, selector, count, result_column,
nullptr);
}
diff --git a/be/src/exprs/vectorized_fn_call.h
b/be/src/exprs/vectorized_fn_call.h
index 24d576ff0d8..05a2178fb30 100644
--- a/be/src/exprs/vectorized_fn_call.h
+++ b/be/src/exprs/vectorized_fn_call.h
@@ -53,8 +53,8 @@ public:
#endif
VectorizedFnCall(const TExprNode& node);
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status execute_runtime_filter(VExprContext* context, const Block* block,
const uint8_t* __restrict filter, size_t
count,
ColumnPtr& result_column, ColumnPtr*
arg_column) const override;
@@ -134,8 +134,8 @@ protected:
std::string _function_name;
private:
- Status _do_execute(VExprContext* context, const Block* block, Selector*
selector, size_t count,
- ColumnPtr& result_column, ColumnPtr* arg_column) const;
+ Status _do_execute(VExprContext* context, const Block* block, const
Selector* selector,
+ size_t count, ColumnPtr& result_column, ColumnPtr*
arg_column) const;
};
#include "common/compile_check_end.h"
diff --git a/be/src/exprs/vexpr.cpp b/be/src/exprs/vexpr.cpp
index f8a04eae516..cd4bb2d9940 100644
--- a/be/src/exprs/vexpr.cpp
+++ b/be/src/exprs/vexpr.cpp
@@ -34,6 +34,7 @@
#include "common/config.h"
#include "common/exception.h"
#include "common/status.h"
+#include "core/column/column_nothing.h"
#include "core/column/column_vector.h"
#include "core/data_type/data_type_array.h"
#include "core/data_type/data_type_decimal.h"
@@ -1107,7 +1108,39 @@ size_t VExpr::estimate_memory(const size_t rows) {
return estimate_size;
}
-bool VExpr::fast_execute(VExprContext* context, Selector* selector, size_t
count,
+Status VExpr::execute_column(VExprContext* context, const Block* block, const
Selector* selector,
+ size_t count, ColumnPtr& result_column) const {
+ RETURN_IF_ERROR(execute_column_impl(context, block, selector, count,
result_column));
+ if (result_column->size() != count) {
+ return Status::InternalError("Expr {} return column size {} not equal
to expected size {}",
+ expr_name(), result_column->size(),
count);
+ }
+ DCHECK(selector == nullptr || selector->size() == count);
+ // Validate type match. ColumnNothing is exempt (used as a placeholder in
tests/stubs).
+ 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 (!st.ok()) {
+ return Status::InternalError(
+ "Expr {} return column type mismatch: declared={},
actual={}", expr_name(),
+ result_type->get_name(), result_column->get_name());
+ }
+ }
+ }
+ return Status::OK();
+}
+
+bool VExpr::fast_execute(VExprContext* context, const Selector* selector,
size_t count,
ColumnPtr& result_column) const {
if (context->get_index_context() &&
context->get_index_context()->get_index_result_column().contains(this)) {
diff --git a/be/src/exprs/vexpr.h b/be/src/exprs/vexpr.h
index bee792db27e..dd149e3b86b 100644
--- a/be/src/exprs/vexpr.h
+++ b/be/src/exprs/vexpr.h
@@ -161,26 +161,12 @@ public:
// In the future this interface will add an additional parameter,
Selector, which specifies
// which rows in the block should be evaluated.
// If expr is executing constant expressions, then block should be nullptr.
- virtual Status execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column)
const {
- return execute_column_impl(context, block, selector, count,
result_column);
- }
-
- template <typename SelectorType,
std::enable_if_t<std::is_const_v<SelectorType>, int> = 0>
- Status execute_column(VExprContext* context, const Block* block,
SelectorType* selector,
- size_t count, ColumnPtr& result_column) const {
- // format_v2 treats selectors as read-only; the branch-4.1 expression
API still exposes
- // a mutable pointer even though implementations must not modify it.
- return execute_column(context, block, const_cast<Selector*>(selector),
count,
- result_column);
- }
+ Status execute_column(VExprContext* context, const Block* block, const
Selector* selector,
+ size_t count, ColumnPtr& result_column) const;
virtual Status execute_column_impl(VExprContext* context, const Block*
block,
const Selector* selector, size_t count,
- ColumnPtr& result_column) const {
- return execute_column(context, block, const_cast<Selector*>(selector),
count,
- result_column);
- }
+ ColumnPtr& result_column) const = 0;
// Currently, due to fe planning issues, for slot-ref expressions the type
of the returned Column may not match data_type.
// Therefore we need a function like this to return the actual type
produced by execution.
@@ -434,7 +420,7 @@ public:
virtual std::shared_ptr<HybridSetBase> get_set_func() const { return
nullptr; }
// fast_execute can direct copy expr filter result which build by apply
index in segment_iterator
- bool fast_execute(VExprContext* context, Selector* selector, size_t count,
+ bool fast_execute(VExprContext* context, const Selector* selector, size_t
count,
ColumnPtr& result_column) const;
virtual bool can_push_down_to_index() const { return false; }
diff --git a/be/src/exprs/vin_predicate.cpp b/be/src/exprs/vin_predicate.cpp
index 96058dd4fb9..223b953f174 100644
--- a/be/src/exprs/vin_predicate.cpp
+++ b/be/src/exprs/vin_predicate.cpp
@@ -309,8 +309,9 @@ Status VInPredicate::execute_on_raw_binary_values(const
StringRef* values, size_
return Status::OK();
}
-Status VInPredicate::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column)
const {
+Status VInPredicate::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
if (is_const_and_have_executed()) { // const have execute in open function
result_column = get_result_from_const(count);
return Status::OK();
diff --git a/be/src/exprs/vin_predicate.h b/be/src/exprs/vin_predicate.h
index 2fbbf8393f4..6e708915025 100644
--- a/be/src/exprs/vin_predicate.h
+++ b/be/src/exprs/vin_predicate.h
@@ -46,8 +46,8 @@ public:
VInPredicate() = default;
#endif
~VInPredicate() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
size_t estimate_memory(const size_t rows) override;
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
diff --git a/be/src/exprs/vinfo_func.cpp b/be/src/exprs/vinfo_func.cpp
index 90d0469194a..e220e5946d3 100644
--- a/be/src/exprs/vinfo_func.cpp
+++ b/be/src/exprs/vinfo_func.cpp
@@ -54,8 +54,9 @@ VInfoFunc::VInfoFunc(const TExprNode& node) : VExpr(node) {
this->_column_ptr = _data_type->create_column_const(1, field);
}
-Status VInfoFunc::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
{
+Status VInfoFunc::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
result_column = _column_ptr->clone_resized(count);
DCHECK_EQ(result_column->size(), count);
return Status::OK();
diff --git a/be/src/exprs/vinfo_func.h b/be/src/exprs/vinfo_func.h
index ee55c1c8340..750b3a89010 100644
--- a/be/src/exprs/vinfo_func.h
+++ b/be/src/exprs/vinfo_func.h
@@ -38,8 +38,8 @@ public:
~VInfoFunc() override = default;
const std::string& expr_name() const override { return _expr_name; }
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
private:
const std::string _expr_name = "vinfofunc expr";
diff --git a/be/src/exprs/virtual_slot_ref.cpp
b/be/src/exprs/virtual_slot_ref.cpp
index 01f8f708cab..8cad15961dd 100644
--- a/be/src/exprs/virtual_slot_ref.cpp
+++ b/be/src/exprs/virtual_slot_ref.cpp
@@ -103,8 +103,9 @@ Status VirtualSlotRef::open(RuntimeState* state,
VExprContext* context,
return Status::OK();
}
-Status VirtualSlotRef::execute_column(VExprContext* context, const Block*
block, Selector* selector,
- size_t count, ColumnPtr& result_column)
const {
+Status VirtualSlotRef::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
if (_column_id >= 0 && _column_id >= block->columns()) {
return Status::Error<ErrorCode::INTERNAL_ERROR>(
"input block not contain slot column {}, column_id={},
block={}", *_column_name,
diff --git a/be/src/exprs/virtual_slot_ref.h b/be/src/exprs/virtual_slot_ref.h
index 0969049670e..0e160e6242a 100644
--- a/be/src/exprs/virtual_slot_ref.h
+++ b/be/src/exprs/virtual_slot_ref.h
@@ -31,8 +31,8 @@ public:
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
const std::string& expr_name() const override;
std::string expr_label() override;
std::string debug_string() const override;
diff --git a/be/src/exprs/vlambda_function_call_expr.h
b/be/src/exprs/vlambda_function_call_expr.h
index 41b46d97ba7..a3764fc13fd 100644
--- a/be/src/exprs/vlambda_function_call_expr.h
+++ b/be/src/exprs/vlambda_function_call_expr.h
@@ -63,8 +63,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
DCHECK(_open_finished || block == nullptr);
return _lambda_function->execute(context, block, selector, count,
result_column, _data_type,
_children);
diff --git a/be/src/exprs/vlambda_function_expr.h
b/be/src/exprs/vlambda_function_expr.h
index 2f8c6f93af2..9b8f7474287 100644
--- a/be/src/exprs/vlambda_function_expr.h
+++ b/be/src/exprs/vlambda_function_expr.h
@@ -52,8 +52,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
DCHECK(_open_finished || block == nullptr);
return get_child(0)->execute_column(context, block, selector, count,
result_column);
}
diff --git a/be/src/exprs/vliteral.cpp b/be/src/exprs/vliteral.cpp
index 048b2951fc4..6f2f178b711 100644
--- a/be/src/exprs/vliteral.cpp
+++ b/be/src/exprs/vliteral.cpp
@@ -43,8 +43,9 @@ Status VLiteral::prepare(RuntimeState* state, const
RowDescriptor& desc, VExprCo
return Status::OK();
}
-Status VLiteral::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const {
+Status VLiteral::execute_column_impl(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
DCHECK(selector == nullptr || selector->size() == count);
result_column = _column_ptr->clone_resized(count);
DCHECK_EQ(result_column->size(), count);
diff --git a/be/src/exprs/vliteral.h b/be/src/exprs/vliteral.h
index 678927c895c..89988e2ba31 100644
--- a/be/src/exprs/vliteral.h
+++ b/be/src/exprs/vliteral.h
@@ -59,8 +59,8 @@ public:
#endif
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
const std::string& expr_name() const override { return _expr_name; }
std::string debug_string() const override;
diff --git a/be/src/exprs/vmatch_predicate.cpp
b/be/src/exprs/vmatch_predicate.cpp
index 5fef6a778f4..9839dff3d15 100644
--- a/be/src/exprs/vmatch_predicate.cpp
+++ b/be/src/exprs/vmatch_predicate.cpp
@@ -181,9 +181,9 @@ const std::string& VMatchPredicate::get_analyzer_key()
const {
return _analyzer_ctx->analyzer_key;
}
-Status VMatchPredicate::execute_column(VExprContext* context, const Block*
block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
+Status VMatchPredicate::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector, size_t
count,
+ ColumnPtr& result_column) const {
DCHECK(_open_finished || block == nullptr);
if (fast_execute(context, selector, count, result_column)) {
return Status::OK();
diff --git a/be/src/exprs/vmatch_predicate.h b/be/src/exprs/vmatch_predicate.h
index 20c647390b8..4c513733105 100644
--- a/be/src/exprs/vmatch_predicate.h
+++ b/be/src/exprs/vmatch_predicate.h
@@ -47,8 +47,8 @@ class VMatchPredicate final : public VExpr {
public:
VMatchPredicate(const TExprNode& node);
~VMatchPredicate() override;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
diff --git a/be/src/exprs/vruntimefilter_wrapper.cpp
b/be/src/exprs/vruntimefilter_wrapper.cpp
index 94a2b2221de..7ee29ecf943 100644
--- a/be/src/exprs/vruntimefilter_wrapper.cpp
+++ b/be/src/exprs/vruntimefilter_wrapper.cpp
@@ -118,10 +118,10 @@ void VRuntimeFilterWrapper::close(VExprContext* context,
_impl->close(context, scope);
}
-Status VRuntimeFilterWrapper::execute_column(VExprContext* context, const
Block* block,
- Selector* selector, size_t count,
- ColumnPtr& result_column) const {
- return Status::InternalError("Not implement
VRuntimeFilterWrapper::execute_column");
+Status VRuntimeFilterWrapper::execute_column_impl(VExprContext* context, const
Block* block,
+ const Selector* selector,
size_t count,
+ ColumnPtr& result_column)
const {
+ return Status::InternalError("Not implement
VRuntimeFilterWrapper::execute_column_impl");
}
const std::string& VRuntimeFilterWrapper::expr_name() const {
diff --git a/be/src/exprs/vruntimefilter_wrapper.h
b/be/src/exprs/vruntimefilter_wrapper.h
index d6b736eeebe..da0cce9f60e 100644
--- a/be/src/exprs/vruntimefilter_wrapper.h
+++ b/be/src/exprs/vruntimefilter_wrapper.h
@@ -56,8 +56,8 @@ public:
bool null_aware, int filter_id,
int sampling_frequency =
RuntimeFilterSelectivity::DISABLE_SAMPLING);
~VRuntimeFilterWrapper() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
Status prepare(RuntimeState* state, const RowDescriptor& desc,
VExprContext* context) override;
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
diff --git a/be/src/exprs/vsearch.cpp b/be/src/exprs/vsearch.cpp
index 8d292ae2836..dac696c1c5a 100644
--- a/be/src/exprs/vsearch.cpp
+++ b/be/src/exprs/vsearch.cpp
@@ -350,8 +350,9 @@ const std::string& VSearchExpr::expr_name() const {
return name;
}
-Status VSearchExpr::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column)
const {
+Status VSearchExpr::execute_column_impl(VExprContext* context, const Block*
block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
if (fast_execute(context, selector, count, result_column)) {
return Status::OK();
}
diff --git a/be/src/exprs/vsearch.h b/be/src/exprs/vsearch.h
index d662c9d3bbe..bb4f8170905 100644
--- a/be/src/exprs/vsearch.h
+++ b/be/src/exprs/vsearch.h
@@ -27,8 +27,8 @@ class VSearchExpr : public VExpr {
public:
VSearchExpr(const TExprNode& node);
~VSearchExpr() override = default;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
const std::string& expr_name() const override;
Status evaluate_inverted_index(VExprContext* context, uint32_t
segment_num_rows) override;
diff --git a/be/src/exprs/vslot_ref.cpp b/be/src/exprs/vslot_ref.cpp
index 35b9f5468cb..f02ef50d575 100644
--- a/be/src/exprs/vslot_ref.cpp
+++ b/be/src/exprs/vslot_ref.cpp
@@ -104,8 +104,9 @@ Status VSlotRef::execute(VExprContext* context, Block*
block, int* result_column
return Status::OK();
}
-Status VSlotRef::execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const {
+Status VSlotRef::execute_column_impl(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const {
if (_column_id >= 0 && _column_id >= block->columns()) {
return Status::Error<ErrorCode::INTERNAL_ERROR>(
"input block not contain slot column {}, column_id={},
block={}", *_column_name,
diff --git a/be/src/exprs/vslot_ref.h b/be/src/exprs/vslot_ref.h
index f98c8f0f523..680d8b36761 100644
--- a/be/src/exprs/vslot_ref.h
+++ b/be/src/exprs/vslot_ref.h
@@ -49,8 +49,8 @@ public:
Status open(RuntimeState* state, VExprContext* context,
FunctionContext::FunctionStateScope scope) override;
Status execute(VExprContext* context, Block* block, int* result_column_id)
const override;
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override;
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override;
DataTypePtr execute_type(const Block* block) const override;
const std::string& expr_name() const override;
diff --git a/be/src/exprs/vtopn_pred.h b/be/src/exprs/vtopn_pred.h
index d3f07754f0e..7ed15bb5e08 100644
--- a/be/src/exprs/vtopn_pred.h
+++ b/be/src/exprs/vtopn_pred.h
@@ -88,8 +88,8 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
if (!_predicate->has_value()) {
result_column = create_always_true_column(count,
_data_type->is_nullable());
return Status::OK();
diff --git
a/be/test/exec/runtime_filter/vruntimefilter_wrapper_sampling_test.cpp
b/be/test/exec/runtime_filter/vruntimefilter_wrapper_sampling_test.cpp
index 45d0cb93098..1044189ca64 100644
--- a/be/test/exec/runtime_filter/vruntimefilter_wrapper_sampling_test.cpp
+++ b/be/test/exec/runtime_filter/vruntimefilter_wrapper_sampling_test.cpp
@@ -40,8 +40,8 @@ public:
Status execute(VExprContext*, Block*, int*) const override { return
Status::OK(); }
- Status execute_column(VExprContext*, const Block*, Selector*, size_t,
- ColumnPtr&) const override {
+ Status execute_column_impl(VExprContext*, const Block*, const Selector*,
size_t,
+ ColumnPtr&) const override {
return Status::OK();
}
diff --git a/be/test/exprs/expr_zonemap_filter_test.cpp
b/be/test/exprs/expr_zonemap_filter_test.cpp
index b3ab962d574..03b5159262b 100644
--- a/be/test/exprs/expr_zonemap_filter_test.cpp
+++ b/be/test/exprs/expr_zonemap_filter_test.cpp
@@ -232,8 +232,8 @@ public:
const std::string& expr_name() const override { return _expr_name; }
- Status execute_column(VExprContext*, const Block*, Selector*, size_t,
- ColumnPtr&) const override {
+ Status execute_column_impl(VExprContext*, const Block*, const Selector*,
size_t,
+ ColumnPtr&) const override {
return Status::InternalError("FixedZonemapExpr is only used by zonemap
tests");
}
@@ -299,8 +299,8 @@ public:
const std::string& expr_name() const override { return _expr_name; }
- Status execute_column(VExprContext*, const Block*, Selector*, size_t,
- ColumnPtr&) const override {
+ Status execute_column_impl(VExprContext*, const Block*, const Selector*,
size_t,
+ ColumnPtr&) const override {
return Status::InternalError("UnsupportedSingleSlotExpr is only used
by zonemap tests");
}
diff --git a/be/test/exprs/function/table_function_test.cpp
b/be/test/exprs/function/table_function_test.cpp
index 19e9b96034b..f5b70595b77 100644
--- a/be/test/exprs/function/table_function_test.cpp
+++ b/be/test/exprs/function/table_function_test.cpp
@@ -67,9 +67,9 @@ protected:
EXPECT_CALL(*_children[i], execute(_, _, _))
.WillRepeatedly(DoAll(SetArgPointee<2>(_column_ids[i]),
Return(Status::OK())));
const int col_id = _column_ids[i];
- EXPECT_CALL(*_children[i], execute_column(_, _, _, _, _))
- .WillRepeatedly(Invoke([col_id](VExprContext*, const
Block* block, Selector*,
- size_t, ColumnPtr& result)
{
+ EXPECT_CALL(*_children[i], execute_column_impl(_, _, _, _, _))
+ .WillRepeatedly(Invoke([col_id](VExprContext*, const
Block* block,
+ const Selector*, size_t,
ColumnPtr& result) {
result = block->get_by_position(col_id).column;
return Status::OK();
}));
diff --git a/be/test/exprs/mock_vexpr.h b/be/test/exprs/mock_vexpr.h
index 87f2ddae7e8..73fe3c1c755 100644
--- a/be/test/exprs/mock_vexpr.h
+++ b/be/test/exprs/mock_vexpr.h
@@ -29,8 +29,8 @@ public:
MOCK_CONST_METHOD0(clone, VExprSPtr());
MOCK_CONST_METHOD0(expr_name, const std::string&());
MOCK_CONST_METHOD3(execute, Status(VExprContext* context, Block* block,
int* result_column_id));
- MOCK_CONST_METHOD5(execute_column,
- Status(VExprContext* context, const Block* block,
Selector* selector,
+ MOCK_CONST_METHOD5(execute_column_impl,
+ Status(VExprContext* context, const Block* block, const
Selector* selector,
size_t count, ColumnPtr& result_column));
}; // class MockVExpr
diff --git a/be/test/exprs/score_runtime_test.cpp
b/be/test/exprs/score_runtime_test.cpp
index 682710870ab..6d5b068664d 100644
--- a/be/test/exprs/score_runtime_test.cpp
+++ b/be/test/exprs/score_runtime_test.cpp
@@ -24,6 +24,8 @@
#include <memory>
+#include "core/column/column_nothing.h"
+#include "core/data_type/data_type_nothing.h"
#include "exprs/vexpr_context.h"
#include "exprs/virtual_slot_ref.h"
@@ -40,9 +42,14 @@ public:
return kName;
}
+ DataTypePtr execute_type(const Block* block) const override {
+ return std::make_shared<DataTypeNothing>();
+ }
+
Status execute(VExprContext*, Block*, int*) const override { return
Status::OK(); }
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
+ result_column = ColumnNothing::create(count);
return Status::OK();
}
};
diff --git a/be/test/exprs/vcondition_expr_test.cpp
b/be/test/exprs/vcondition_expr_test.cpp
index 8605ca496b0..e111f7f65ce 100644
--- a/be/test/exprs/vcondition_expr_test.cpp
+++ b/be/test/exprs/vcondition_expr_test.cpp
@@ -84,8 +84,9 @@ public:
return Status::OK();
}
- Status execute_column(VExprContext* /*context*/, const Block* /*block*/,
Selector* /*selector*/,
- size_t /*count*/, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* /*context*/, const Block*
/*block*/,
+ const Selector* /*selector*/, size_t /*count*/,
+ ColumnPtr& result_column) const override {
result_column = _column;
return Status::OK();
}
diff --git a/be/test/exprs/vexpr_test.cpp b/be/test/exprs/vexpr_test.cpp
index 5c67746cfbb..3ece04b06b2 100644
--- a/be/test/exprs/vexpr_test.cpp
+++ b/be/test/exprs/vexpr_test.cpp
@@ -36,7 +36,11 @@
#include "common/object_pool.h"
#include "core/block/block.h"
+#include "core/column/column_nothing.h"
+#include "core/column/column_vector.h"
#include "core/data_type/data_type_factory.hpp"
+#include "core/data_type/data_type_nothing.h"
+#include "core/data_type/data_type_number.h"
#include "core/data_type/define_primitive_type.h"
#include "core/field.h"
#include "core/types.h"
@@ -421,106 +425,92 @@ TEST(TEST_VEXPR, LITERALTEST) {
// bool
{
VLiteral literal(create_literal<TYPE_BOOLEAN>(true));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_BOOLEAN>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_BOOLEAN>();
EXPECT_EQ(v, true);
EXPECT_EQ("1", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_BOOLEAN, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_BOOLEAN, 0,
0), true);
EXPECT_EQ("1", node->value());
}
// smallint
{
VLiteral literal(create_literal<TYPE_SMALLINT>(1024));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_SMALLINT>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_SMALLINT>();
EXPECT_EQ(v, 1024);
EXPECT_EQ("1024", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_SMALLINT, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_SMALLINT, 0,
0), true);
EXPECT_EQ("1024", node->value());
}
// int
{
VLiteral literal(create_literal<TYPE_INT>(1024));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_INT>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_INT>();
EXPECT_EQ(v, 1024);
EXPECT_EQ("1024", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_INT, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_INT, 0, 0),
true);
EXPECT_EQ("1024", node->value());
}
// bigint
{
VLiteral literal(create_literal<TYPE_BIGINT>(1024));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_BIGINT>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_BIGINT>();
EXPECT_EQ(v, 1024);
EXPECT_EQ("1024", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_BIGINT, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_BIGINT, 0,
0), true);
EXPECT_EQ("1024", node->value());
}
// large int
{
VLiteral literal(create_literal<TYPE_LARGEINT, __int128_t>(1024));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_LARGEINT>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_LARGEINT>();
EXPECT_EQ(v, 1024);
EXPECT_EQ("1024", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_LARGEINT, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_LARGEINT, 0,
0), true);
EXPECT_EQ("1024", node->value());
}
// float
{
VLiteral literal(create_literal<TYPE_FLOAT, float>(1024.0f));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_FLOAT>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_FLOAT>();
EXPECT_FLOAT_EQ(v, 1024.0f);
EXPECT_EQ("1024", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_FLOAT, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_FLOAT, 0, 0),
true);
EXPECT_EQ("1024", node->value());
}
// double
{
VLiteral literal(create_literal<TYPE_DOUBLE, double>(1024.0));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_DOUBLE>();
- EXPECT_FLOAT_EQ(v, 1024.0) << ctn.column->get_name();
- EXPECT_EQ("1024", literal.value()) << ctn.column->get_name();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_DOUBLE>();
+ EXPECT_FLOAT_EQ(v, 1024.0) << result_column->get_name();
+ EXPECT_EQ("1024", literal.value()) << result_column->get_name();
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DOUBLE, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_DOUBLE, 0,
0), true);
EXPECT_EQ("1024", node->value());
}
// datetime
@@ -535,14 +525,12 @@ TEST(TEST_VEXPR, LITERALTEST) {
}
std::cout << data_time_value.type() << std::endl;
VLiteral literal(create_literal<TYPE_DATETIME,
std::string>(std::string(date)));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
EXPECT_EQ("2021-04-07 00:00:00", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DATETIME, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_DATETIME, 0,
0), true);
EXPECT_EQ("2021-04-07 00:00:00", node->value());
}
// datetimev2
@@ -559,14 +547,12 @@ TEST(TEST_VEXPR, LITERALTEST) {
std::string date = datetime_v2.to_string();
VLiteral literal(create_literal<TYPE_DATETIMEV2, std::string>(date,
4));
- Block block;
- int ret = -1;
- EXPECT_TRUE(literal.execute(nullptr, &block, &ret).ok());
+ ColumnPtr result_column;
+ EXPECT_TRUE(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column).ok());
EXPECT_EQ("1997-11-18 09:12:47.0000", literal.value());
- auto ctn = block.safe_get_by_position(ret);
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DATETIMEV2, 0,
4), true);
+ create_texpr_node_from((*result_column)[0], TYPE_DATETIMEV2,
0, 4), true);
EXPECT_EQ("1997-11-18 09:12:47.0000", node->value());
}
// timestamptz
@@ -590,14 +576,12 @@ TEST(TEST_VEXPR, LITERALTEST) {
std::string tz_value_str = tz_value.to_string(tz, scale);
VLiteral literal(create_literal<TYPE_TIMESTAMPTZ,
std::string>(tz_value_str, scale));
- Block block;
- int ret = -1;
- EXPECT_TRUE(literal.execute(nullptr, &block, &ret).ok());
+ ColumnPtr result_column;
+ EXPECT_TRUE(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column).ok());
EXPECT_EQ("1997-11-18 01:12:46.999999+00:00", literal.value());
- auto ctn = block.safe_get_by_position(ret);
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_TIMESTAMPTZ, 0,
scale), true);
+ create_texpr_node_from((*result_column)[0], TYPE_TIMESTAMPTZ,
0, scale), true);
EXPECT_EQ("1997-11-18 01:12:46.999999+00:00", node->value());
node = std::make_shared<VLiteral>(
@@ -618,14 +602,12 @@ TEST(TEST_VEXPR, LITERALTEST) {
__int64_t dt;
memcpy(&dt, &date_time_value, sizeof(__int64_t));
VLiteral literal(create_literal<TYPE_DATE,
std::string>(std::string(date)));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
EXPECT_EQ("2021-04-07", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DATE, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_DATE, 0, 0),
true);
EXPECT_EQ("2021-04-07", node->value());
}
// datev2
@@ -640,16 +622,14 @@ TEST(TEST_VEXPR, LITERALTEST) {
uint32_t dt;
memcpy(&dt, &data_time_value, sizeof(uint32_t));
VLiteral literal(create_literal<TYPE_DATEV2,
std::string>(std::string(date)));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_DATEV2>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_DATEV2>();
EXPECT_EQ(v, dt);
EXPECT_EQ("2021-04-07", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DATEV2, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_DATEV2, 0,
0), true);
EXPECT_EQ("2021-04-07", node->value());
}
config::allow_zero_date = true;
@@ -711,26 +691,22 @@ TEST(TEST_VEXPR, LITERALTEST) {
{
std::string j = R"([null,true,false,100,6.18,"abc"])";
VLiteral literal(create_literal<TYPE_JSONB, std::string>(j));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
EXPECT_EQ(j, literal.value());
}
// string
{
std::string s = "I am Amory, 24";
VLiteral literal(create_literal<TYPE_STRING,
std::string>(std::string("I am Amory, 24")));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_STRING>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_STRING>();
EXPECT_EQ(v, s);
EXPECT_EQ(s, literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_STRING, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_STRING, 0,
0), true);
EXPECT_EQ(s, node->value());
}
// varbinary
@@ -760,31 +736,27 @@ TEST(TEST_VEXPR, LITERALTEST) {
// decimalv2
{
VLiteral literal(create_literal<TYPE_DECIMALV2,
std::string>(std::string("1234.56")));
- Block block;
- int ret = -1;
- static_cast<void>(literal.execute(nullptr, &block, &ret));
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_DECIMALV2>();
+ ColumnPtr result_column;
+ static_cast<void>(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column));
+ auto v = (*result_column)[0].get<TYPE_DECIMALV2>();
EXPECT_FLOAT_EQ(((double)v.value()) / (std::pow(10, 9)), 1234.56);
EXPECT_EQ("1234.560000000", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_DECIMALV2, 27,
9), true);
+ create_texpr_node_from((*result_column)[0], TYPE_DECIMALV2,
27, 9), true);
EXPECT_EQ("1234.560000000", node->value());
}
// timev2
{
VLiteral literal(create_literal<TYPE_TIMEV2, double>(12123400, 4));
- Block block;
- int ret = -1;
- EXPECT_TRUE(literal.execute(nullptr, &block, &ret).ok());
- auto ctn = block.safe_get_by_position(ret);
- auto v = (*ctn.column)[0].get<TYPE_TIMEV2>();
+ ColumnPtr result_column;
+ EXPECT_TRUE(literal.execute_column(nullptr, nullptr, nullptr, 1,
result_column).ok());
+ auto v = (*result_column)[0].get<TYPE_TIMEV2>();
EXPECT_FLOAT_EQ(v / 1000000, 12.1234);
EXPECT_EQ("00:00:12.1234", literal.value());
auto node = std::make_shared<VLiteral>(
- create_texpr_node_from((*ctn.column)[0], TYPE_TIMEV2, 0, 0),
true);
+ create_texpr_node_from((*result_column)[0], TYPE_TIMEV2, 0,
0), true);
EXPECT_EQ("00:00:12", node->value());
}
// deciaml32
@@ -862,3 +834,107 @@ TEST(TEST_VEXPR, LITERALTEST) {
}
config::allow_zero_date = false;
}
+
+namespace doris {
+
+// A concrete VExpr that returns a column provided at construction time.
+// The declared type is set via set_data_type(); the returned column may
differ.
+class FakeVExpr final : public VExpr {
+public:
+ FakeVExpr() = default;
+ const std::string& expr_name() const override {
+ static const std::string name = "FakeVExpr";
+ return name;
+ }
+ Status execute_column_impl(VExprContext* /*context*/, const Block*
/*block*/,
+ const Selector* /*selector*/, size_t /*count*/,
+ ColumnPtr& result_column) const override {
+ result_column = _column;
+ return Status::OK();
+ }
+ void set_column(ColumnPtr col) { _column = std::move(col); }
+ void set_data_type(DataTypePtr type) { _data_type = std::move(type); }
+
+private:
+ ColumnPtr _column;
+};
+
+} // namespace doris
+
+// Tests for VExpr::execute_column post-condition checks.
+TEST(VExprExecuteColumnTest, SizeCheckFails) {
+ using namespace doris;
+ FakeVExpr expr;
+ auto type = std::make_shared<DataTypeInt32>();
+ expr.set_data_type(type);
+
+ // Column has 2 rows but count == 1 → size mismatch
+ auto col = ColumnInt32::create();
+ col->insert_value(1);
+ col->insert_value(2);
+ expr.set_column(std::move(col));
+
+ ColumnPtr result;
+ auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
+ EXPECT_FALSE(st.ok());
+ EXPECT_TRUE(st.to_string().find("not equal to expected size") !=
std::string::npos);
+}
+
+TEST(VExprExecuteColumnTest, TypeMismatchFails) {
+ using namespace doris;
+ FakeVExpr expr;
+ // Declare type as Int32, but return a Float64 column — clear type mismatch
+ expr.set_data_type(std::make_shared<DataTypeInt32>());
+
+ auto col = ColumnFloat64::create();
+ col->insert_value(3.14);
+ expr.set_column(std::move(col));
+
+ ColumnPtr result;
+ auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
+ EXPECT_FALSE(st.ok());
+}
+
+TEST(VExprExecuteColumnTest, NullableTypeWithNonNullableColumnPasses) {
+ 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.
+
expr.set_data_type(std::make_shared<DataTypeNullable>(std::make_shared<DataTypeInt32>()));
+
+ auto col = ColumnInt32::create();
+ col->insert_value(7);
+ expr.set_column(std::move(col));
+
+ ColumnPtr result;
+ auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
+ EXPECT_TRUE(st.ok());
+}
+
+TEST(VExprExecuteColumnTest, ColumnNothingPassesTypeCheck) {
+ using namespace doris;
+ FakeVExpr expr;
+ // Declare type as Int32, but return ColumnNothing — check should be
skipped
+ expr.set_data_type(std::make_shared<DataTypeInt32>());
+ expr.set_column(ColumnNothing::create(1));
+
+ ColumnPtr result;
+ auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
+ EXPECT_TRUE(st.ok());
+}
+
+TEST(VExprExecuteColumnTest, CorrectColumnPasses) {
+ using namespace doris;
+ FakeVExpr expr;
+ auto type = std::make_shared<DataTypeInt32>();
+ expr.set_data_type(type);
+
+ auto col = ColumnInt32::create();
+ col->insert_value(42);
+ expr.set_column(std::move(col));
+
+ ColumnPtr result;
+ auto st = expr.execute_column(nullptr, nullptr, nullptr, 1, result);
+ EXPECT_TRUE(st.ok());
+ EXPECT_EQ(result->size(), 1u);
+}
diff --git a/be/test/exprs/virtual_slot_ref_test.cpp
b/be/test/exprs/virtual_slot_ref_test.cpp
index d96f64675a7..171e0fbf698 100644
--- a/be/test/exprs/virtual_slot_ref_test.cpp
+++ b/be/test/exprs/virtual_slot_ref_test.cpp
@@ -191,8 +191,9 @@ TEST_F(VirtualSlotRefTest,
EqualsFunction_WithDifferentTypes) {
Status execute(VExprContext* context, Block* block, int*
result_column_id) const override {
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const override {
return Status::OK();
}
@@ -312,8 +313,9 @@ TEST_F(VirtualSlotRefTest, EqualsFunction_TestAllBranches) {
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const override {
return Status::OK();
}
@@ -337,8 +339,9 @@ TEST_F(VirtualSlotRefTest, EqualsFunction_TestAllBranches) {
Status execute(VExprContext* context, Block* block, int*
result_column_id) const override {
return Status::OK();
}
- Status execute_column(VExprContext* context, const Block* block,
Selector* selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
+ const Selector* selector, size_t count,
+ ColumnPtr& result_column) const override {
return Status::OK();
}
const std::string& expr_name() const override {
diff --git a/be/test/exprs/vsearch_expr_test.cpp
b/be/test/exprs/vsearch_expr_test.cpp
index afcf69384cd..7d120066c33 100644
--- a/be/test/exprs/vsearch_expr_test.cpp
+++ b/be/test/exprs/vsearch_expr_test.cpp
@@ -25,7 +25,9 @@
#include <vector>
#include "core/block/block.h"
+#include "core/column/column_nothing.h"
#include "core/column/column_vector.h"
+#include "core/data_type/data_type_nothing.h"
#include "core/data_type/data_type_number.h"
#include "core/data_type/data_type_string.h"
#include "exprs/vexpr_context.h"
@@ -79,8 +81,8 @@ public:
}
Status execute(VExprContext*, Block*, int*) const override { return
Status::OK(); }
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
return Status::OK();
}
};
@@ -853,21 +855,6 @@ TEST_F(VSearchExprTest, TestSingleChildBooleanClause) {
ASSERT_NE(nullptr, vsearch_expr);
}
-TEST_F(VSearchExprTest, TestExecuteWithNullBlock) {
- auto vsearch_expr = VSearchExpr::create_shared(test_node);
-
- // Create a basic VExprContext without inverted index context
- auto dummy_expr = VSearchExpr::create_shared(test_node);
- VExprContext context(dummy_expr);
-
- // Test with null block (should not crash)
-
- ColumnPtr result_column;
- auto status = vsearch_expr->execute_column(&context, nullptr, nullptr, 0,
result_column);
- EXPECT_FALSE(status.ok());
- EXPECT_TRUE(status.code() == ErrorCode::INTERNAL_ERROR);
-}
-
TEST_F(VSearchExprTest, TestEvaluateInvertedIndexWithWhitespaceOnlyDSL) {
TExprNode whitespace_node;
whitespace_node.node_type = TExprNodeType::SEARCH_EXPR;
diff --git a/be/test/format/parquet/parquet_expr_test.cpp
b/be/test/format/parquet/parquet_expr_test.cpp
index be0c7200550..cc09f4e02db 100644
--- a/be/test/format/parquet/parquet_expr_test.cpp
+++ b/be/test/format/parquet/parquet_expr_test.cpp
@@ -122,8 +122,8 @@ public:
const std::string& expr_name() const override { return _expr_name; }
- Status execute_column(VExprContext*, const Block*, Selector*, size_t,
- ColumnPtr&) const override {
+ Status execute_column_impl(VExprContext*, const Block*, const Selector*,
size_t,
+ ColumnPtr&) const override {
return Status::InternalError("TestPageZonemapExpr is only used by
zonemap tests");
}
diff --git a/be/test/storage/index/ann/extract_query_vector_test.cpp
b/be/test/storage/index/ann/extract_query_vector_test.cpp
index 8fd6850218e..3f55c43627e 100644
--- a/be/test/storage/index/ann/extract_query_vector_test.cpp
+++ b/be/test/storage/index/ann/extract_query_vector_test.cpp
@@ -54,8 +54,8 @@ public:
bool is_constant() const override { return _is_constant; }
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
return Status::OK();
}
diff --git a/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
b/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
index ed51625e325..affef9bb943 100644
--- a/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
+++ b/be/test/storage/segment/segment_iterator_apply_index_expr_test.cpp
@@ -66,8 +66,8 @@ public:
Status execute(VExprContext*, Block*, int*) const override { return
Status::OK(); }
- Status execute_column(VExprContext* context, const Block* block, Selector*
selector,
- size_t count, ColumnPtr& result_column) const
override {
+ Status execute_column_impl(VExprContext* context, const Block* block,
const Selector* selector,
+ size_t count, ColumnPtr& result_column) const
override {
return Status::OK();
}
diff --git a/be/test/storage/segment/segment_iterator_expr_zonemap_test.cpp
b/be/test/storage/segment/segment_iterator_expr_zonemap_test.cpp
index 6739cad82e0..e1008084e89 100644
--- a/be/test/storage/segment/segment_iterator_expr_zonemap_test.cpp
+++ b/be/test/storage/segment/segment_iterator_expr_zonemap_test.cpp
@@ -60,8 +60,8 @@ public:
const std::string& expr_name() const override { return _expr_name; }
- Status execute_column(VExprContext*, const Block*, Selector*, size_t,
- ColumnPtr&) const override {
+ Status execute_column_impl(VExprContext*, const Block*, const Selector*,
size_t,
+ ColumnPtr&) const override {
return Status::InternalError("IntMaxAtLeastExpr is only used by
zonemap tests");
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]