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 5b2c066b4d5 [refine](column) Normalize constant expression results
(#69679)
5b2c066b4d5 is described below
commit 5b2c066b4d55498d5a3e2c7c279c6e26a3ffa9b8
Author: Mryange <[email protected]>
AuthorDate: Thu Oct 29 10:09:35 2026 +0800
[refine](column) Normalize constant expression results (#69679)
### What problem does this PR solve?
Issue Number: N/A
Related PR: #66614
Problem Summary:
Root cause: expression constness does not guarantee a physical
`ColumnConst`. Cached constant expressions can return either a const
wrapper or a single-row data column, while scan consumers sometimes cast
the result directly to `ColumnConst`.
Store an owned single-row data column in `ConstantExprResult`, unwrap
`ColumnConst` without copying, and expose read-only accessors. Migrate
scan, scalar-function, and ANN consumers, and recreate `ColumnConst`
when broadcasting the cached value. Preserve current function
initialization and NULL handling.
### Release note
Handle constant expressions that return ordinary single-row columns
consistently in scan predicate processing.
### Check List (For Author)
- Test:
- ASAN BE UT build passed. Ran 276 tests across 16 affected suites: 275
passed and the existing `MathFunctionTest.random_test` was skipped.
Coverage includes zero-copy normalization, nullable values and
ownership, arrays with nested NULLs, invalid multi-row input,
broadcasting, scan predicates, function constant arguments, and ANN
extraction.
- clang-format 16, `git diff --check`, and BE build hygiene checks
passed.
- clang-tidy checked all 43 modified C++ files. New diagnostics were
fixed and rechecked; existing complexity diagnostics remain on unchanged
lines in column and LIKE tests.
- Behavior changed: Yes. Scan consumers accept cached single-row
constants regardless of their original physical representation;
malformed multi-row cache inputs fail at construction.
- Does this need documentation: No. No SQL syntax, configuration, or
serialization changes.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
---
be/src/core/column/column.cpp | 11 +++
be/src/core/column/column.h | 15 +++-
be/src/exec/operator/file_scan_operator.cpp | 6 +-
be/src/exec/operator/mock_scan_operator.h | 6 +-
be/src/exec/operator/olap_scan_operator.cpp | 16 ++--
be/src/exec/operator/scan_operator.cpp | 43 ++--------
be/src/exprs/function/array/function_array_index.h | 2 +-
be/src/exprs/function/function_collection_in.h | 2 +-
be/src/exprs/function/function_convert_tz.cpp | 8 +-
.../function/function_datetime_string_to_string.h | 2 +-
be/src/exprs/function/function_dict_get.cpp | 3 +-
be/src/exprs/function/function_dict_get_many.cpp | 2 +-
be/src/exprs/function/function_jsonb.cpp | 10 +--
.../function/function_other_types_to_date.cpp | 2 +-
be/src/exprs/function/function_regexp.cpp | 8 +-
be/src/exprs/function/function_string_concat.h | 2 +-
be/src/exprs/function/function_string_misc.cpp | 4 +-
be/src/exprs/function/in.h | 4 +-
be/src/exprs/function/like.cpp | 12 +--
be/src/exprs/function/random.cpp | 2 +-
be/src/exprs/function_context.cpp | 4 +-
be/src/exprs/function_context.h | 8 +-
be/src/exprs/vexpr.cpp | 10 +--
be/src/exprs/vexpr.h | 4 +-
be/src/storage/index/ann/ann_topn_runtime.cpp | 9 +-
be/test/core/column/column_const_test.cpp | 66 +++++++++++++++
be/test/exec/operator/olap_scan_operator_test.cpp | 96 ++++++++++++++++++++++
.../operator/scan_normalize_predicate_test.cpp | 72 ++++++----------
.../exprs/function/function_array_remove_test.cpp | 6 +-
.../exprs/function/function_array_shuffle_test.cpp | 6 +-
.../exprs/function/function_array_trim_test.cpp | 6 +-
.../function/function_constant_argument_test.cpp | 10 +--
.../exprs/function/function_dict_get_many_test.cpp | 8 +-
be/test/exprs/function/function_dict_get_test.cpp | 8 +-
be/test/exprs/function/function_h3_test.cpp | 4 +-
be/test/exprs/function/function_like_test.cpp | 30 +++----
be/test/exprs/function/function_math_test.cpp | 6 +-
be/test/exprs/function/function_string_test.cpp | 4 +-
be/test/exprs/function/function_test_util.h | 6 +-
.../index/ann/extract_query_vector_test.cpp | 4 +-
.../query/logical/gram/regex_gram_recall_test.cpp | 4 +-
be/test/testutil/mock/mock_fn_call.cpp | 21 ++++-
be/test/testutil/mock/mock_fn_call.h | 6 +-
be/test/testutil/mock/mock_literal_expr.h | 8 +-
44 files changed, 352 insertions(+), 214 deletions(-)
diff --git a/be/src/core/column/column.cpp b/be/src/core/column/column.cpp
index ef0d61076b1..a070b01b96c 100644
--- a/be/src/core/column/column.cpp
+++ b/be/src/core/column/column.cpp
@@ -51,6 +51,17 @@ bool contains_boolean_value_column(const IColumn& column) {
} // namespace
+ConstantExprResult::ConstantExprResult(ColumnPtr column) {
+ DORIS_CHECK(column.get() != nullptr);
+ // Constant expressions can return either ColumnConst or a plain
single-row column.
+ if (const auto* const_column =
check_and_get_column<ColumnConst>(column.get())) {
+ _column_ptr = const_column->get_data_column_ptr();
+ } else {
+ _column_ptr = std::move(column);
+ }
+ DORIS_CHECK_EQ(_column_ptr->size(), 1);
+}
+
std::string IColumn::dump_structure() const {
std::stringstream res;
res << get_name() << "(size = " << size();
diff --git a/be/src/core/column/column.h b/be/src/core/column/column.h
index ad2b6cba3e1..d92351001dc 100644
--- a/be/src/core/column/column.h
+++ b/be/src/core/column/column.h
@@ -893,11 +893,18 @@ bool is_column_const(const IColumn& column);
bool is_column_nullable(const IColumn& column);
} // namespace doris
-// Wrap `ColumnPtr` because `ColumnPtr` can't be used in forward declaration.
+// Hold a constant expression's single-row result column. For example, both a
one-row Int64
+// column and ColumnConst(Int64, N) store the same Int64 row here; broadcast
wraps it again.
+// This class also allows forward declarations where the ColumnPtr alias
cannot be used.
namespace doris {
-struct ColumnPtrWrapper {
- ColumnPtr column_ptr;
+class ConstantExprResult {
+public:
+ explicit ConstantExprResult(ColumnPtr column);
+
+ const IColumn& column() const { return *_column_ptr; }
+ const ColumnPtr& column_ptr() const { return _column_ptr; }
- ColumnPtrWrapper(ColumnPtr col) : column_ptr(std::move(col)) {}
+private:
+ ColumnPtr _column_ptr;
};
} // namespace doris
diff --git a/be/src/exec/operator/file_scan_operator.cpp
b/be/src/exec/operator/file_scan_operator.cpp
index 5f6d41c8b1d..5eb2abf1b16 100644
--- a/be/src/exec/operator/file_scan_operator.cpp
+++ b/be/src/exec/operator/file_scan_operator.cpp
@@ -86,11 +86,9 @@ PushDownType
FileScanLocalState::_should_push_down_binary_predicate(
DCHECK(children.size() == 2);
DCHECK_EQ(children[0]->node_type(), TExprNodeType::SLOT_REF);
if (children[1]->is_constant()) {
- std::shared_ptr<ColumnPtrWrapper> const_col_wrapper;
+ std::shared_ptr<ConstantExprResult> const_col_wrapper;
THROW_IF_ERROR(children[1]->get_const_col(expr_ctx,
&const_col_wrapper));
- const auto* const_column =
- assert_cast<const
ColumnConst*>(const_col_wrapper->column_ptr.get());
- constant_val = const_column->operator[](0);
+ constant_val = const_col_wrapper->column()[0];
return PushDownType::PARTIAL_ACCEPTABLE;
} else {
// only handle constant value
diff --git a/be/src/exec/operator/mock_scan_operator.h
b/be/src/exec/operator/mock_scan_operator.h
index 27f1f8ef53d..62128258e6c 100644
--- a/be/src/exec/operator/mock_scan_operator.h
+++ b/be/src/exec/operator/mock_scan_operator.h
@@ -61,11 +61,9 @@ private:
DCHECK(children.size() == 2);
DCHECK_EQ(children[0]->node_type(), TExprNodeType::SLOT_REF);
if (children[1]->is_constant()) {
- std::shared_ptr<ColumnPtrWrapper> const_col_wrapper;
+ std::shared_ptr<ConstantExprResult> const_col_wrapper;
THROW_IF_ERROR(children[1]->get_const_col(expr_ctx,
&const_col_wrapper));
- const auto* const_column =
- assert_cast<const
ColumnConst*>(const_col_wrapper->column_ptr.get());
- constant_val = const_column->operator[](0);
+ constant_val = const_col_wrapper->column()[0];
return PushDownType::ACCEPTABLE;
} else {
// only handle constant value
diff --git a/be/src/exec/operator/olap_scan_operator.cpp
b/be/src/exec/operator/olap_scan_operator.cpp
index aecb90e02a8..d6239fa4cb2 100644
--- a/be/src/exec/operator/olap_scan_operator.cpp
+++ b/be/src/exec/operator/olap_scan_operator.cpp
@@ -114,11 +114,9 @@ PushDownType
OlapScanLocalState::_should_push_down_binary_predicate(
DCHECK(children.size() == 2);
DCHECK_EQ(VExpr::expr_without_cast(children[0])->node_type(),
TExprNodeType::SLOT_REF);
if (children[1]->is_constant()) {
- std::shared_ptr<ColumnPtrWrapper> const_col_wrapper;
+ std::shared_ptr<ConstantExprResult> const_col_wrapper;
THROW_IF_ERROR(children[1]->get_const_col(expr_ctx,
&const_col_wrapper));
- const auto* const_column =
- assert_cast<const
ColumnConst*>(const_col_wrapper->column_ptr.get());
- constant_val = const_column->operator[](0);
+ constant_val = const_col_wrapper->column()[0];
return PushDownType::ACCEPTABLE;
} else {
// only handle constant value
@@ -585,15 +583,15 @@ Status
OlapScanLocalState::_should_push_down_function_filter(VectorizedFnCall* f
return Status::OK();
} else {
DCHECK(is_string_type(children[1 -
i]->data_type()->get_primitive_type()));
- std::shared_ptr<ColumnPtrWrapper> const_col_wrapper;
+ std::shared_ptr<ConstantExprResult> const_col_wrapper;
RETURN_IF_ERROR(children[1 - i]->get_const_col(expr_ctx,
&const_col_wrapper));
- if (const auto* const_column =
-
check_and_get_column<ColumnConst>(const_col_wrapper->column_ptr.get())) {
- *constant_str = const_column->get_data_at(0);
- } else {
+ // LIKE/NOT LIKE with a NULL pattern must retain expression
evaluation: the storage
+ // predicate only receives a StringRef and would interpret NULL as
an empty pattern.
+ if (const_col_wrapper->column().is_null_at(0)) {
pdt = PushDownType::UNACCEPTABLE;
return Status::OK();
}
+ *constant_str = const_col_wrapper->column().get_data_at(0);
}
}
*fn_ctx = func_cxt;
diff --git a/be/src/exec/operator/scan_operator.cpp
b/be/src/exec/operator/scan_operator.cpp
index e01fdc33bf0..0874c525c98 100644
--- a/be/src/exec/operator/scan_operator.cpp
+++ b/be/src/exec/operator/scan_operator.cpp
@@ -658,43 +658,14 @@ Status
ScanLocalStateBase::_eval_const_conjuncts(VExprContext* expr_ctx, PushDow
// Used to handle constant expressions, such as '1 = 1'
_eval_const_conjuncts does not handle cases like 'colA = 1'
const char* constant_val = nullptr;
if (vexpr->is_constant()) {
- std::shared_ptr<ColumnPtrWrapper> const_col_wrapper;
+ std::shared_ptr<ConstantExprResult> const_col_wrapper;
RETURN_IF_ERROR(vexpr->get_const_col(expr_ctx, &const_col_wrapper));
- if (const auto* const_column =
-
check_and_get_column<ColumnConst>(const_col_wrapper->column_ptr.get())) {
- constant_val = const_column->get_data_at(0).data;
- if (constant_val == nullptr || !*reinterpret_cast<const
bool*>(constant_val)) {
- *pdt = PushDownType::ACCEPTABLE;
- _eos = true;
- _scan_dependency->set_ready();
- }
- } else if (const auto* bool_column =
-
check_and_get_column<ColumnUInt8>(const_col_wrapper->column_ptr.get())) {
- // TODO: If `vexpr->is_constant()` is true, a const column is
expected here.
- // But now we still don't cover all predicates for const
expression.
- // For example, for query `SELECT col FROM tbl WHERE 'PROMOTION'
LIKE 'AAA%'`,
- // predicate `like` will return a ColumnVector<UInt8> which
contains a single value.
- LOG(WARNING) << "VExpr[" << vexpr->debug_string()
- << "] should return a const column but actually is "
- << const_col_wrapper->column_ptr->get_name();
- DCHECK_EQ(bool_column->size(), 1);
- /// TODO: There is a DCHECK here, but an additional check is still
needed. It should return an error code.
- if (bool_column->size() == 1) {
- constant_val = bool_column->get_data_at(0).data;
- if (constant_val == nullptr || !*reinterpret_cast<const
bool*>(constant_val)) {
- *pdt = PushDownType::ACCEPTABLE;
- _eos = true;
- _scan_dependency->set_ready();
- }
- } else {
- LOG(WARNING) << "Constant predicate in scan node should return
a bool column with "
- "`size == 1` but actually is "
- << bool_column->size();
- }
- } else {
- LOG(WARNING) << "VExpr[" << vexpr->debug_string()
- << "] should return a const column but actually is "
- << const_col_wrapper->column_ptr->get_name();
+ constant_val = const_col_wrapper->column().get_data_at(0).data;
+ // A constant NULL, like constant false, rejects every row in a WHERE
predicate.
+ if (constant_val == nullptr || !*reinterpret_cast<const
bool*>(constant_val)) {
+ *pdt = PushDownType::ACCEPTABLE;
+ _eos = true;
+ _scan_dependency->set_ready();
}
}
return Status::OK();
diff --git a/be/src/exprs/function/array/function_array_index.h
b/be/src/exprs/function/array/function_array_index.h
index 14e00f2ad7d..0430d062ce9 100644
--- a/be/src/exprs/function/array/function_array_index.h
+++ b/be/src/exprs/function/array/function_array_index.h
@@ -122,7 +122,7 @@ public:
std::shared_ptr<ParamValue> state = std::make_shared<ParamValue>();
Field field;
if (context->get_constant_col(1)) {
- context->get_constant_col(1)->column_ptr->get(0, field);
+ context->get_constant_col(1)->column().get(0, field);
state->value = field;
state->type = context->get_arg_type(1)->get_primitive_type();
context->set_function_state(scope, state);
diff --git a/be/src/exprs/function/function_collection_in.h
b/be/src/exprs/function/function_collection_in.h
index 0e5c29bdc8c..1099c4f2173 100644
--- a/be/src/exprs/function/function_collection_in.h
+++ b/be/src/exprs/function/function_collection_in.h
@@ -112,7 +112,7 @@ public:
const auto& const_column_ptr = context->get_constant_col(i);
// Types like struct, array, and map only support constant
expressions.
DCHECK(const_column_ptr != nullptr);
- const auto& [col, _] =
unpack_if_const(const_column_ptr->column_ptr);
+ const auto& col = const_column_ptr->column_ptr();
if (const auto* null_col =
check_and_get_column<ColumnNullable>(col.get())) {
if (null_col->has_null()) {
state->null_in_set = true;
diff --git a/be/src/exprs/function/function_convert_tz.cpp
b/be/src/exprs/function/function_convert_tz.cpp
index e2feed2006a..e3d34c323a6 100644
--- a/be/src/exprs/function/function_convert_tz.cpp
+++ b/be/src/exprs/function/function_convert_tz.cpp
@@ -123,10 +123,10 @@ public:
}
void init_convert_tz_state(std::shared_ptr<ConvertTzState> state,
- const ColumnPtrWrapper* const_from_tz,
- const ColumnPtrWrapper* const_to_tz) {
- auto const_data_from_tz = const_from_tz->column_ptr->get_data_at(0);
- auto const_data_to_tz = const_to_tz->column_ptr->get_data_at(0);
+ const ConstantExprResult* const_from_tz,
+ const ConstantExprResult* const_to_tz) {
+ auto const_data_from_tz = const_from_tz->column().get_data_at(0);
+ auto const_data_to_tz = const_to_tz->column().get_data_at(0);
// from_tz and to_tz must both be non-null.
if (const_data_from_tz.data == nullptr || const_data_to_tz.data ==
nullptr) {
diff --git a/be/src/exprs/function/function_datetime_string_to_string.h
b/be/src/exprs/function/function_datetime_string_to_string.h
index 89e172f1ddd..5747a8d4f01 100644
--- a/be/src/exprs/function/function_datetime_string_to_string.h
+++ b/be/src/exprs/function/function_datetime_string_to_string.h
@@ -108,7 +108,7 @@ public:
"The second parameter of the function {} must be a
constant.", get_name());
}
- auto string_vale = column_string->column_ptr->get_data_at(0);
+ auto string_vale = column_string->column().get_data_at(0);
if (string_vale.data == nullptr) {
// func(col , null);
state->is_valid = false;
diff --git a/be/src/exprs/function/function_dict_get.cpp
b/be/src/exprs/function/function_dict_get.cpp
index 8ca79599902..fcc1ea8fd93 100644
--- a/be/src/exprs/function/function_dict_get.cpp
+++ b/be/src/exprs/function/function_dict_get.cpp
@@ -27,6 +27,7 @@
#include "exprs/function/dictionary_factory.h"
#include "exprs/function/function.h"
#include "exprs/function/simple_function_factory.h"
+#include "runtime/exec_env.h"
namespace doris {
@@ -71,7 +72,7 @@ public:
dict_fn->version_id);
if (!dict) {
std::string dict_name =
-
context->get_constant_col(0)->column_ptr->get_data_at(0).to_string();
+
context->get_constant_col(0)->column().get_data_at(0).to_string();
throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
"can not find dict name : {} , dict_id : {}
, version_id : {} ",
dict_name, dict_fn->dictionary_id,
dict_fn->version_id);
diff --git a/be/src/exprs/function/function_dict_get_many.cpp
b/be/src/exprs/function/function_dict_get_many.cpp
index a2cb5a4d1f7..5f8f42c89be 100644
--- a/be/src/exprs/function/function_dict_get_many.cpp
+++ b/be/src/exprs/function/function_dict_get_many.cpp
@@ -77,7 +77,7 @@ public:
dict_fn->version_id);
if (!dict) {
std::string dict_name =
-
context->get_constant_col(0)->column_ptr->get_data_at(0).to_string();
+
context->get_constant_col(0)->column().get_data_at(0).to_string();
throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
"can not find dict name : {} , dict_id : {}
, version_id : {} ",
dict_name, dict_fn->dictionary_id,
dict_fn->version_id);
diff --git a/be/src/exprs/function/function_jsonb.cpp
b/be/src/exprs/function/function_jsonb.cpp
index 40150754ba9..202975d0059 100644
--- a/be/src/exprs/function/function_jsonb.cpp
+++ b/be/src/exprs/function/function_jsonb.cpp
@@ -150,11 +150,11 @@ public:
if (state) {
if (context->get_num_args() == 2) {
if (context->is_col_constant(1)) {
- const auto default_value_col =
context->get_constant_col(1)->column_ptr;
- if (default_value_col->is_null_at(0)) {
+ const auto& default_value_col =
context->get_constant_col(1)->column();
+ if (default_value_col.is_null_at(0)) {
state->default_is_null = true;
} else {
- const auto& default_value =
default_value_col->get_data_at(0);
+ const auto& default_value =
default_value_col.get_data_at(0);
state->default_value = default_value;
state->has_const_default_value = true;
@@ -2540,8 +2540,8 @@ public:
if (context->is_col_constant(2)) {
std::shared_ptr<LikeState> state = std::make_shared<LikeState>();
state->is_like_pattern = true;
- const auto pattern_col = context->get_constant_col(2)->column_ptr;
- const auto& pattern = pattern_col->get_data_at(0);
+ const auto& pattern_col = context->get_constant_col(2)->column();
+ const auto& pattern = pattern_col.get_data_at(0);
RETURN_IF_ERROR(
FunctionLike::construct_like_const_state(context, pattern,
state, false));
context->set_function_state(scope, state);
diff --git a/be/src/exprs/function/function_other_types_to_date.cpp
b/be/src/exprs/function/function_other_types_to_date.cpp
index 8867745fbfd..cdcdaea146b 100644
--- a/be/src/exprs/function/function_other_types_to_date.cpp
+++ b/be/src/exprs/function/function_other_types_to_date.cpp
@@ -486,7 +486,7 @@ struct DateTrunc {
if (!context->is_col_constant(DateArgIsFirst ? 1 : 0)) {
return Status::OK();
}
- const auto& unit_column = context->get_constant_col(DateArgIsFirst ? 1
: 0)->column_ptr;
+ const auto& unit_column = context->get_constant_col(DateArgIsFirst ? 1
: 0)->column_ptr();
// The nullable wrapper returns NULL without calling execute when the
constant unit is NULL.
if (unit_column->is_null_at(0)) {
return Status::OK();
diff --git a/be/src/exprs/function/function_regexp.cpp
b/be/src/exprs/function/function_regexp.cpp
index 9457997f14c..b3005685531 100644
--- a/be/src/exprs/function/function_regexp.cpp
+++ b/be/src/exprs/function/function_regexp.cpp
@@ -388,7 +388,7 @@ public:
if (scope == FunctionContext::FunctionStateScope::THREAD_LOCAL) {
if (context->is_col_constant(1)) {
DCHECK(!context->get_function_state(scope));
- const auto pattern_col =
context->get_constant_col(1)->column_ptr;
+ const auto pattern_col =
context->get_constant_col(1)->column_ptr();
const auto& pattern = pattern_col->get_data_at(0);
if (pattern.size == 0) {
return Status::OK();
@@ -484,7 +484,7 @@ public:
if (scope == FunctionContext::FunctionStateScope::THREAD_LOCAL) {
if (context->is_col_constant(1)) {
DCHECK(!context->get_function_state(scope));
- const auto pattern_col =
context->get_constant_col(1)->column_ptr;
+ const auto pattern_col =
context->get_constant_col(1)->column_ptr();
StringRef options_value;
if constexpr (std::is_same_v<FourParamTypes, ParamTypes>) {
DCHECK_EQ(context->get_num_args(), 4);
@@ -493,7 +493,7 @@ public:
if (!context->is_col_constant(3)) {
return Status::OK();
}
- const auto options_col =
context->get_constant_col(3)->column_ptr;
+ const auto options_col =
context->get_constant_col(3)->column_ptr();
// A NULL options argument makes the result NULL before
regexp compilation.
if (options_col->is_null_at(0)) {
return Status::OK();
@@ -1019,7 +1019,7 @@ public:
if (context->is_col_constant(Impl::PATTERN_ARG_IDX)) {
DCHECK(!context->get_function_state(scope));
const auto pattern_col =
-
context->get_constant_col(Impl::PATTERN_ARG_IDX)->column_ptr;
+
context->get_constant_col(Impl::PATTERN_ARG_IDX)->column_ptr();
const auto& pattern = pattern_col->get_data_at(0);
if (pattern.size == 0) {
return Status::OK();
diff --git a/be/src/exprs/function/function_string_concat.h
b/be/src/exprs/function/function_string_concat.h
index d109d78a048..568f97c2b8a 100644
--- a/be/src/exprs/function/function_string_concat.h
+++ b/be/src/exprs/function/function_string_concat.h
@@ -87,7 +87,7 @@ public:
state->use_state = false;
return IFunction::open(context, scope);
}
- auto string_vale = column_string->column_ptr->get_data_at(0);
+ auto string_vale = column_string->column().get_data_at(0);
if (string_vale.data == nullptr) {
// For concat(col, null), it is handled by
default_implementation_for_nulls
state->use_state = false;
diff --git a/be/src/exprs/function/function_string_misc.cpp
b/be/src/exprs/function/function_string_misc.cpp
index 131cc74acbc..b3cb7caa46c 100644
--- a/be/src/exprs/function/function_string_misc.cpp
+++ b/be/src/exprs/function/function_string_misc.cpp
@@ -416,7 +416,7 @@ public:
return Status::InvalidArgument(
"character argument to convert function must be
constant.");
}
- const auto& character_data =
context->get_constant_col(1)->column_ptr->get_data_at(0);
+ const auto& character_data =
context->get_constant_col(1)->column().get_data_at(0);
if (!iequal(character_data.to_string(), "gbk")) {
return Status::RuntimeError(
"Illegal second argument column of function convert. now
only support "
@@ -1621,7 +1621,7 @@ public:
}
auto* const_col = context->get_constant_col(1);
- auto mode_ref = const_col->column_ptr->get_data_at(0);
+ auto mode_ref = const_col->column().get_data_at(0);
std::string lower_mode =
doris::to_lower(std::string(doris::trim(mode_ref.to_string())));
UErrorCode status = U_ZERO_ERROR;
diff --git a/be/src/exprs/function/in.h b/be/src/exprs/function/in.h
index f2a62dc48f6..ee8d8ce77ef 100644
--- a/be/src/exprs/function/in.h
+++ b/be/src/exprs/function/in.h
@@ -92,7 +92,7 @@ public:
for (int i = 1; i < context->get_num_args(); ++i) {
const auto& const_column_ptr = context->get_constant_col(i);
if (const_column_ptr != nullptr) {
- auto const_data = const_column_ptr->column_ptr->get_data_at(0);
+ auto const_data = const_column_ptr->column().get_data_at(0);
if (const_data.data != nullptr) {
sz++;
}
@@ -127,7 +127,7 @@ public:
for (int i = 1; i < context->get_num_args(); ++i) {
const auto& const_column_ptr = context->get_constant_col(i);
if (const_column_ptr != nullptr) {
- auto const_data = const_column_ptr->column_ptr->get_data_at(0);
+ auto const_data = const_column_ptr->column().get_data_at(0);
state->hybrid_set->insert((void*)const_data.data,
const_data.size);
} else {
state->use_set = false;
diff --git a/be/src/exprs/function/like.cpp b/be/src/exprs/function/like.cpp
index bdff040c190..ebdfd0b11fc 100644
--- a/be/src/exprs/function/like.cpp
+++ b/be/src/exprs/function/like.cpp
@@ -1024,8 +1024,8 @@ Status FunctionLike::open(FunctionContext* context,
FunctionContext::FunctionSta
state->scalar_function = like_fn_scalar;
if (context->is_col_constant(2)) {
state->has_custom_escape = true;
- const auto escape_col = context->get_constant_col(2)->column_ptr;
- const auto& escape = escape_col->get_data_at(0);
+ const auto& escape_col = context->get_constant_col(2)->column();
+ const auto& escape = escape_col.get_data_at(0);
if (escape.size != 1) {
return Status::InternalError("Escape character must be a single
character, got: {}",
escape.to_string());
@@ -1033,8 +1033,8 @@ Status FunctionLike::open(FunctionContext* context,
FunctionContext::FunctionSta
state->escape_char = escape.data[0];
}
if (context->is_col_constant(1)) {
- const auto pattern_col = context->get_constant_col(1)->column_ptr;
- const auto& pattern = pattern_col->get_data_at(0);
+ const auto& pattern_col = context->get_constant_col(1)->column();
+ const auto& pattern = pattern_col.get_data_at(0);
RETURN_IF_ERROR(construct_like_const_state(context, pattern, state));
}
context->set_function_state(scope, state);
@@ -1056,8 +1056,8 @@ Status FunctionRegexpLike::open(FunctionContext* context,
state->function = regexp_fn;
state->scalar_function = regexp_fn_scalar;
if (context->is_col_constant(1)) {
- const auto pattern_col = context->get_constant_col(1)->column_ptr;
- const auto& pattern = pattern_col->get_data_at(0);
+ const auto& pattern_col = context->get_constant_col(1)->column();
+ const auto& pattern = pattern_col.get_data_at(0);
std::string pattern_str = pattern.to_string();
std::string search_string;
diff --git a/be/src/exprs/function/random.cpp b/be/src/exprs/function/random.cpp
index 071abc1cb04..0fa0e4827b7 100644
--- a/be/src/exprs/function/random.cpp
+++ b/be/src/exprs/function/random.cpp
@@ -70,7 +70,7 @@ public:
// constant expression such as an arithmetic one is not
evaluated in open. Then the
// generator is seeded with the first row in execute.
if (context->is_col_constant(0)) {
-
state->generator.seed(get_seed(*context->get_constant_col(0)->column_ptr));
+
state->generator.seed(get_seed(*context->get_constant_col(0)->column_ptr()));
} else {
state->seed_in_execute = true;
}
diff --git a/be/src/exprs/function_context.cpp
b/be/src/exprs/function_context.cpp
index 74bea9af90a..d4717149eda 100644
--- a/be/src/exprs/function_context.cpp
+++ b/be/src/exprs/function_context.cpp
@@ -46,7 +46,7 @@ std::unique_ptr<doris::FunctionContext>
FunctionContext::create_context(
}
void FunctionContext::set_constant_cols(
- const std::vector<std::shared_ptr<doris::ColumnPtrWrapper>>&
constant_cols) {
+ const std::vector<std::shared_ptr<doris::ConstantExprResult>>&
constant_cols) {
_constant_cols = constant_cols;
}
@@ -119,7 +119,7 @@ bool FunctionContext::is_col_constant(int i) const {
return _constant_cols[i] != nullptr;
}
-doris::ColumnPtrWrapper* FunctionContext::get_constant_col(int i) const {
+doris::ConstantExprResult* FunctionContext::get_constant_col(int i) const {
if (i < 0 || i >= _constant_cols.size()) {
return nullptr;
}
diff --git a/be/src/exprs/function_context.h b/be/src/exprs/function_context.h
index bc892991a49..66663aa1f06 100644
--- a/be/src/exprs/function_context.h
+++ b/be/src/exprs/function_context.h
@@ -30,7 +30,7 @@
namespace doris {
-struct ColumnPtrWrapper;
+class ConstantExprResult;
struct StringRef;
class RuntimeState;
@@ -73,7 +73,7 @@ public:
/// it.
std::unique_ptr<doris::FunctionContext> clone();
- void set_constant_cols(const
std::vector<std::shared_ptr<doris::ColumnPtrWrapper>>& cols);
+ void set_constant_cols(const
std::vector<std::shared_ptr<doris::ConstantExprResult>>& cols);
RuntimeState* state() { return _state; }
@@ -159,7 +159,7 @@ public:
// including the FunctionContext* argument). Returns nullptr if the
argument is not
// constant. This function can be used to obtain user-specified constants
in a UDF's
// Init() or Close() functions.
- doris::ColumnPtrWrapper* get_constant_col(int arg_idx) const;
+ doris::ConstantExprResult* get_constant_col(int arg_idx) const;
// Creates a StringRef, which memory is available when this function
context is used next time
StringRef create_temp_string_val(int64_t len);
@@ -196,7 +196,7 @@ private:
// Type descriptors for each argument of the function.
std::vector<DataTypePtr> _arg_types;
- std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> _constant_cols;
+ std::vector<std::shared_ptr<doris::ConstantExprResult>> _constant_cols;
// UDF execute timer
RuntimeProfile::Counter* _udf_execute_timer = nullptr;
diff --git a/be/src/exprs/vexpr.cpp b/be/src/exprs/vexpr.cpp
index f2cddfdd2d5..34d9130d3e3 100644
--- a/be/src/exprs/vexpr.cpp
+++ b/be/src/exprs/vexpr.cpp
@@ -830,7 +830,7 @@ bool VExpr::is_constant() const {
}
Status VExpr::get_const_col(VExprContext* context,
- std::shared_ptr<ColumnPtrWrapper>* column_wrapper)
{
+ std::shared_ptr<ConstantExprResult>*
column_wrapper) {
if (!is_constant()) {
return Status::OK();
}
@@ -844,7 +844,7 @@ Status VExpr::get_const_col(VExprContext* context,
ColumnPtr result;
RETURN_IF_ERROR(execute_column(context, nullptr, nullptr, 1, result));
- _constant_col = std::make_shared<ColumnPtrWrapper>(result);
+ _constant_col = std::make_shared<ConstantExprResult>(result);
if (column_wrapper != nullptr) {
*column_wrapper = _constant_col;
}
@@ -866,9 +866,9 @@ Status VExpr::init_function_context(RuntimeState* state,
VExprContext* context,
const FunctionBasePtr& function) const {
FunctionContext* fn_ctx = context->fn_context(_fn_context_index);
if (scope == FunctionContext::FunctionStateScope::FRAGMENT_LOCAL) {
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (auto c : _children) {
- std::shared_ptr<ColumnPtrWrapper> const_col;
+ std::shared_ptr<ConstantExprResult> const_col;
RETURN_IF_ERROR(c->get_const_col(context, &const_col));
constant_cols.push_back(const_col);
}
@@ -924,7 +924,7 @@ uint64_t VExpr::get_digest(uint64_t seed) const {
}
ColumnPtr VExpr::get_result_from_const(size_t count) const {
- return ColumnConst::create(_constant_col->column_ptr, count);
+ return ColumnConst::create(_constant_col->column_ptr(), count);
}
Status VExpr::_evaluate_inverted_index(VExprContext* context, const
FunctionBasePtr& function,
diff --git a/be/src/exprs/vexpr.h b/be/src/exprs/vexpr.h
index 134b606ea69..aee8c2870b7 100644
--- a/be/src/exprs/vexpr.h
+++ b/be/src/exprs/vexpr.h
@@ -386,7 +386,7 @@ public:
/// owned by this expr. This should only be called after Open() has been
called on this
/// expr.
MOCK_FUNCTION Status get_const_col(VExprContext* context,
- std::shared_ptr<ColumnPtrWrapper>*
column_wrapper);
+ std::shared_ptr<ConstantExprResult>*
column_wrapper);
int fn_context_index() const { return _fn_context_index; }
@@ -526,7 +526,7 @@ protected:
// If this expr is constant, this will store and cache the value generated
by
// get_const_col()
- std::shared_ptr<ColumnPtrWrapper> _constant_col;
+ std::shared_ptr<ConstantExprResult> _constant_col;
bool _prepared = false; // for base class VExpr
// for concrete classes
bool _prepare_finished = false;
diff --git a/be/src/storage/index/ann/ann_topn_runtime.cpp
b/be/src/storage/index/ann/ann_topn_runtime.cpp
index 38998f145ac..f85f967c811 100644
--- a/be/src/storage/index/ann/ann_topn_runtime.cpp
+++ b/be/src/storage/index/ann/ann_topn_runtime.cpp
@@ -27,7 +27,6 @@
#include "common/status.h"
#include "core/column/column.h"
#include "core/column/column_array.h"
-#include "core/column/column_const.h"
#include "core/column/column_nullable.h"
#include "core/column/column_vector.h"
#include "core/data_type/primitive_type.h"
@@ -49,18 +48,14 @@ Result<ColumnFloat32::Ptr>
extract_query_vector(std::shared_ptr<VExpr> arg_expr)
arg_expr->debug_string()));
}
- std::shared_ptr<ColumnPtrWrapper> column_wrapper;
+ std::shared_ptr<ConstantExprResult> column_wrapper;
auto st = arg_expr->get_const_col(nullptr, &column_wrapper);
if (!st.ok()) {
return ResultError(Status::InvalidArgument("Failed to get constant
column, error: {}",
st.to_string()));
}
- // Unwrap ColumnConst without copy to get the underlying single-row column
- IColumn::Ptr col_ptr = column_wrapper->column_ptr;
- if (const auto* const_col = check_and_get_column<ColumnConst>(*col_ptr)) {
- col_ptr = const_col->get_data_column_ptr();
- }
+ IColumn::Ptr col_ptr = column_wrapper->column_ptr();
// The expected runtime column layout for the literal is:
// Nullable(ColumnArray(Nullable(ColumnFloat32))) with exactly 1 row (one
array literal)
diff --git a/be/test/core/column/column_const_test.cpp
b/be/test/core/column/column_const_test.cpp
index 3056d5276a8..e3cf2fbdc71 100644
--- a/be/test/core/column/column_const_test.cpp
+++ b/be/test/core/column/column_const_test.cpp
@@ -42,6 +42,72 @@ TEST(ColumnConstTest, TestCreate) {
EXPECT_TRUE(!is_column_const(column_const2->get_data_column()));
}
+TEST(ConstantExprResultTest, StoresSingleRowDataColumn) {
+ auto data_column = ColumnHelper::create_column<DataTypeInt64>({7});
+
+ ConstantExprResult data_wrapper(data_column);
+ EXPECT_EQ(data_wrapper.column_ptr().get(), data_column.get());
+ EXPECT_EQ(data_wrapper.column().get_int(0), 7);
+ EXPECT_FALSE(is_column_const(data_wrapper.column()));
+
+ auto const_column = ColumnConst::create(data_column, 3);
+ ConstantExprResult const_wrapper(std::move(const_column));
+ EXPECT_EQ(const_wrapper.column_ptr().get(), data_column.get());
+ EXPECT_EQ(const_wrapper.column().get_int(0), 7);
+ EXPECT_FALSE(is_column_const(const_wrapper.column()));
+}
+
+TEST(ConstantExprResultTest, RejectsNonConstMultiRowColumn) {
+ auto column = ColumnHelper::create_column<DataTypeInt64>({7, 8});
+#ifdef NDEBUG
+ EXPECT_THROW(static_cast<void>(ConstantExprResult(column)), Exception);
+#elif DCHECK_IS_ON()
+ EXPECT_DEATH(static_cast<void>(ConstantExprResult(column)), "Check
failed");
+#endif
+}
+
+static void check_nullable_constant_result(uint8_t is_null) {
+ auto data_column =
ColumnHelper::create_nullable_column<DataTypeInt64>({7}, {is_null});
+ const auto* original = data_column.get();
+ ConstantExprResult direct_wrapper(data_column);
+ ConstantExprResult const_wrapper(ColumnConst::create(data_column, 3));
+ data_column.reset();
+
+ EXPECT_EQ(direct_wrapper.column_ptr().get(), original);
+ EXPECT_EQ(const_wrapper.column_ptr().get(), original);
+ EXPECT_TRUE(const_wrapper.column().is_nullable());
+ EXPECT_EQ(const_wrapper.column().is_null_at(0), is_null != 0);
+ auto broadcast = ColumnConst::create(const_wrapper.column_ptr(), 5);
+ EXPECT_EQ(broadcast->get_data_column_ptr().get(), original);
+ EXPECT_EQ(broadcast->size(), 5);
+ EXPECT_EQ(broadcast->is_null_at(4), is_null != 0);
+ if (!is_null) {
+ EXPECT_EQ((*broadcast)[4].get<TYPE_BIGINT>(), 7);
+ }
+}
+
+TEST(ConstantExprResultTest, PreservesNullableValuesAndOwnership) {
+ check_nullable_constant_result(0);
+ check_nullable_constant_result(1);
+}
+
+TEST(ConstantExprResultTest, PreservesArrayRowAndNestedNulls) {
+ auto elements = ColumnHelper::create_nullable_column<DataTypeInt64>({7,
8}, {0, 1});
+ auto offsets = ColumnArray::ColumnOffsets::create();
+ offsets->insert_value(2);
+ ColumnPtr array = ColumnArray::create(elements, std::move(offsets));
+ ConstantExprResult wrapper(ColumnConst::create(array, 3));
+ EXPECT_EQ(wrapper.column_ptr().get(), array.get());
+ auto broadcast = ColumnConst::create(wrapper.column_ptr(), 5);
+ EXPECT_EQ(broadcast->size(), 5);
+ EXPECT_EQ(broadcast->get_data_column().compare_at(0, 0, *array, 1), 0);
+
+ const auto& data = assert_cast<const ColumnArray&>(wrapper.column());
+ EXPECT_EQ(data.get_data_ptr().get(), elements.get());
+ EXPECT_EQ(data.get_data()[0].get<TYPE_BIGINT>(), 7);
+ EXPECT_TRUE(data.get_data().is_null_at(1));
+}
+
TEST(ColumnConstTest, IsExclusiveChecksNestedColumn) {
auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
auto column_const = ColumnConst::create(column_data, 3);
diff --git a/be/test/exec/operator/olap_scan_operator_test.cpp
b/be/test/exec/operator/olap_scan_operator_test.cpp
index fec9ff1d5ce..068d38f982c 100644
--- a/be/test/exec/operator/olap_scan_operator_test.cpp
+++ b/be/test/exec/operator/olap_scan_operator_test.cpp
@@ -23,12 +23,19 @@
#include <optional>
#include "common/object_pool.h"
+#include "core/column/column_const.h"
+#include "core/data_type/data_type_nullable.h"
#include "core/data_type/data_type_number.h"
+#include "core/data_type/data_type_string.h"
+#include "exprs/vexpr_context.h"
#include "gen_cpp/PlanNodes_types.h"
#include "gen_cpp/QueryCache_types.h"
#include "storage/rowset/beta_rowset.h"
+#include "testutil/column_helper.h"
#include "testutil/desc_tbl_builder.h"
+#include "testutil/mock/mock_fn_call.h"
#include "testutil/mock/mock_runtime_state.h"
+#include "testutil/mock/mock_slot_ref.h"
namespace doris {
@@ -95,6 +102,95 @@ TEST_F(OlapScanOperatorChangelogPushDownTest,
AppendOnlyKeepsValuePredicatePushD
EXPECT_TRUE(_local_state->can_push_down_column_predicate(_value_slot));
}
+class OlapScanLikeConstantPatternTest : public
OlapScanOperatorChangelogPushDownTest {
+protected:
+ void check_pattern(bool wrap_const, uint8_t is_null, const std::string&
value, bool opposite) {
+ ColumnPtr column =
ColumnHelper::create_nullable_column<DataTypeString>({value}, {is_null});
+ if (wrap_const) {
+ column = ColumnConst::create(column, 1);
+ }
+ auto pattern = MockFnCall::create("pattern");
+ pattern->_mock_is_constant = true;
+ pattern->_data_type =
make_nullable(std::make_shared<DataTypeString>());
+ pattern->set_const_expr_col(std::move(column));
+ auto like = MockFnCall::create("like");
+ like->add_child(std::make_shared<MockSlotRef>(0,
std::make_shared<DataTypeString>()));
+ like->add_child(pattern);
+ VExprSPtr root = like;
+ if (opposite) {
+ auto not_expr = MockFnCall::create("not");
+ not_expr->_node_type = TExprNodeType::COMPOUND_PRED;
+ not_expr->add_child(like);
+ root = not_expr;
+ }
+ auto ctx = VExprContext::create_shared(root);
+ like->_fn_context_index = ctx->register_function_context(
+ _state.get(), make_nullable(std::make_shared<DataTypeBool>()),
+ {std::make_shared<DataTypeString>(), pattern->data_type()});
+ auto pdt = PushDownType::ACCEPTABLE;
+ StringRef constant_str;
+ FunctionContext* fn_ctx = nullptr;
+ auto st = _local_state->_should_push_down_function_filter(like.get(),
ctx.get(),
+
&constant_str, &fn_ctx, pdt);
+ ASSERT_TRUE(st.ok()) << st.to_string();
+ EXPECT_EQ(pdt, is_null ? PushDownType::UNACCEPTABLE :
PushDownType::ACCEPTABLE);
+ if (is_null) {
+ check_expression_fallback(ctx.get());
+ } else {
+ EXPECT_EQ(constant_str.to_string(), value);
+ EXPECT_EQ(fn_ctx, ctx->fn_context(like->_fn_context_index));
+ }
+ }
+
+ void check_expression_fallback(VExprContext* ctx) {
+ // Rejecting pushdown must leave both LIKE and NOT LIKE for expression
evaluation.
+ std::vector<std::shared_ptr<ColumnPredicate>> predicates;
+ auto pdt = PushDownType::UNACCEPTABLE;
+ auto st = _local_state->_normalize_function_filters(ctx, _key_slot,
predicates, &pdt);
+ ASSERT_TRUE(st.ok()) << st.to_string();
+ EXPECT_TRUE(predicates.empty());
+ EXPECT_EQ(pdt, PushDownType::UNACCEPTABLE);
+ }
+};
+
+TEST_F(OlapScanLikeConstantPatternTest,
NullPatternsRetainExpressionEvaluation) {
+ for (bool wrap_const : {false, true}) {
+ for (bool opposite : {false, true}) {
+ check_pattern(wrap_const, 1, "", opposite);
+ // A nonempty NULL payload must never be read as a LIKE pattern.
+ check_pattern(wrap_const, 1, "ignored%", opposite);
+ }
+ }
+}
+
+TEST_F(OlapScanLikeConstantPatternTest,
EmptyAndNonemptyPatternsRemainPushable) {
+ for (bool wrap_const : {false, true}) {
+ check_pattern(wrap_const, 0, "", false);
+ check_pattern(wrap_const, 0, "prefix%", false);
+ }
+}
+
+TEST_F(OlapScanLikeConstantPatternTest, BinaryPredicatePreservesNullConstant) {
+ for (bool wrap_const : {false, true}) {
+ ColumnPtr column =
ColumnHelper::create_nullable_column<DataTypeInt32>({42}, {1});
+ if (wrap_const) {
+ column = ColumnConst::create(column, 1);
+ }
+ auto constant = MockFnCall::create("constant");
+ constant->_mock_is_constant = true;
+ constant->set_const_expr_col(std::move(column));
+ auto eq = MockFnCall::create("eq");
+ eq->add_child(std::make_shared<MockSlotRef>(0,
std::make_shared<DataTypeInt32>()));
+ eq->add_child(constant);
+ auto ctx = VExprContext::create_shared(eq);
+ Field value;
+ EXPECT_EQ(_local_state->_should_push_down_binary_predicate(eq.get(),
ctx.get(), value,
+ {"eq"}),
+ PushDownType::ACCEPTABLE);
+ EXPECT_TRUE(value.is_null());
+ }
+}
+
class OlapScanOperatorTsoPruningTest : public
OlapScanOperatorChangelogPushDownTest {
protected:
void SetUp() override {
diff --git a/be/test/exec/operator/scan_normalize_predicate_test.cpp
b/be/test/exec/operator/scan_normalize_predicate_test.cpp
index d61a0541a74..49ec1d5dcfc 100644
--- a/be/test/exec/operator/scan_normalize_predicate_test.cpp
+++ b/be/test/exec/operator/scan_normalize_predicate_test.cpp
@@ -52,6 +52,25 @@ struct ScanNormalizePredicate : public ::testing::Test {
std::vector<DataTypePtr> {std::make_shared<DataTypeInt64>()},
&pool};
op->_output_tuple_desc = op->_row_descriptor.tuple_descriptors()[0];
}
+ void check_nullable_constant_conjunct(bool wrap_const, uint8_t is_null,
bool value) {
+ auto local_state = std::make_shared<MockScanLocalState>(state.get(),
op.get());
+ local_state->_scan_dependency = Dependency::create_shared(0, 0,
"DEPENDENCY");
+ ColumnPtr column =
ColumnHelper::create_nullable_column<DataTypeBool>({value}, {is_null});
+ if (wrap_const) {
+ column = ColumnConst::create(column, 1);
+ }
+ auto fn = MockFnCall::create("eq");
+ fn->_mock_is_constant = true;
+ fn->set_const_expr_col(std::move(column));
+ auto ctx = VExprContext::create_shared(fn);
+ auto pdt = PushDownType::UNACCEPTABLE;
+ auto st = local_state->_eval_const_conjuncts(ctx.get(), &pdt);
+ ASSERT_TRUE(st.ok()) << st.to_string();
+ const bool rejects_rows = is_null || !value;
+ EXPECT_EQ(local_state->_eos, rejects_rows);
+ EXPECT_EQ(local_state->_scan_dependency->ready(), rejects_rows);
+ EXPECT_EQ(pdt == PushDownType::ACCEPTABLE, rejects_rows);
+ }
ObjectPool pool;
std::shared_ptr<MockRuntimeState> state;
std::shared_ptr<MockScanOperatorX> op;
@@ -128,51 +147,14 @@ TEST_F(ScanNormalizePredicate,
test_eval_const_conjuncts2) {
EXPECT_TRUE(local_state->_eos);
}
-TEST_F(ScanNormalizePredicate, test_eval_const_conjuncts3) {
- // case
- // Predicate false and xxx and xxx ....
- // The returned column is not a constant column, but the size is not equal
to 1
- auto local_state = std::make_shared<MockScanLocalState>(state.get(),
op.get());
-
- auto fn_eq = MockFnCall::create("eq");
- fn_eq->_mock_is_constant = true;
-
fn_eq->set_const_expr_col(ColumnHelper::create_column<DataTypeBool>({false,
false}));
- EXPECT_TRUE(fn_eq->is_constant());
-
- auto ctx = VExprContext::create_shared(fn_eq);
- ctx->_prepared = true;
- ctx->_opened = true;
-
- VExprSPtr new_root;
- auto conjunct_expr_root = ctx;
- // There is a DCHECK in the code to ensure size must be equal to 1, wait
for this part of the code to be removed later
- // auto st = local_state->_normalize_predicate(
- // conjunct_expr_root.get(),
new_root);
- // EXPECT_FALSE(st.ok());
- // std::cout << st.msg() << std::endl;
-}
-
-TEST_F(ScanNormalizePredicate, test_eval_const_conjuncts4) {
- // case
- // Predicate false and xxx and xxx ....
- // The returned column is neither a constant column nor a boolean column
- auto local_state = std::make_shared<MockScanLocalState>(state.get(),
op.get());
-
- auto fn_eq = MockFnCall::create("eq");
- fn_eq->_mock_is_constant = true;
-
fn_eq->set_const_expr_col(ColumnHelper::create_column<DataTypeInt32>({false,
false}));
- EXPECT_TRUE(fn_eq->is_constant());
-
- auto ctx = VExprContext::create_shared(fn_eq);
- ctx->_prepared = true;
- ctx->_opened = true;
-
- VExprSPtr new_root;
- auto conjunct_expr_root = ctx;
- auto st = local_state->_normalize_predicate(conjunct_expr_root.get(),
- conjunct_expr_root->root(),
new_root);
- EXPECT_TRUE(st.ok());
- std::cout << st.msg() << std::endl;
+TEST_F(ScanNormalizePredicate, NullableConstantConjuncts) {
+ for (bool wrap_const : {false, true}) {
+ for (uint8_t is_null : {0, 1}) {
+ for (bool value : {false, true}) {
+ check_nullable_constant_conjunct(wrap_const, is_null, value);
+ }
+ }
+ }
}
TEST_F(ScanNormalizePredicate, test_is_predicate_acting_on_slot1) {
diff --git a/be/test/exprs/function/function_array_remove_test.cpp
b/be/test/exprs/function/function_array_remove_test.cpp
index 7be1f72bef1..a502d3b3e67 100644
--- a/be/test/exprs/function/function_array_remove_test.cpp
+++ b/be/test/exprs/function/function_array_remove_test.cpp
@@ -56,12 +56,12 @@ static void check_array_remove_case(DataTypePtr array_type,
DataTypePtr element_
ColumnNumbers arguments = {0, 1};
std::vector<DataTypePtr> arg_types = {array_type, element_type};
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols = {nullptr,
nullptr};
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols = {nullptr,
nullptr};
if (const_array) {
- constant_cols[0] =
std::make_shared<ColumnPtrWrapper>(block.get_by_position(0).column);
+ constant_cols[0] =
std::make_shared<ConstantExprResult>(block.get_by_position(0).column);
}
if (const_target) {
- constant_cols[1] =
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column);
+ constant_cols[1] =
std::make_shared<ConstantExprResult>(block.get_by_position(1).column);
}
FunctionUtils fn_utils(return_type, arg_types, false);
diff --git a/be/test/exprs/function/function_array_shuffle_test.cpp
b/be/test/exprs/function/function_array_shuffle_test.cpp
index 149cf1a7d40..0b365aff063 100644
--- a/be/test/exprs/function/function_array_shuffle_test.cpp
+++ b/be/test/exprs/function/function_array_shuffle_test.cpp
@@ -73,9 +73,9 @@ static Status run_array_shuffle(const std::vector<TestArray>&
arrays, bool const
block.insert({array_ptr, array_type, "array"});
DataTypes arg_types = {array_type};
ColumnNumbers arguments = {0};
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols = {nullptr};
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols = {nullptr};
if (const_array) {
- constant_cols[0] = std::make_shared<ColumnPtrWrapper>(array_ptr);
+ constant_cols[0] = std::make_shared<ConstantExprResult>(array_ptr);
}
if (!seeds.empty()) {
MutableColumnPtr seed_column = seed_type->create_column();
@@ -86,7 +86,7 @@ static Status run_array_shuffle(const std::vector<TestArray>&
arrays, bool const
constant_cols.push_back(nullptr);
if (seeds.size() == 1) {
seed_ptr = ColumnConst::create(seed_ptr, row_size);
- constant_cols[1] = std::make_shared<ColumnPtrWrapper>(seed_ptr);
+ constant_cols[1] = std::make_shared<ConstantExprResult>(seed_ptr);
} else {
EXPECT_EQ(seeds.size(), row_size);
}
diff --git a/be/test/exprs/function/function_array_trim_test.cpp
b/be/test/exprs/function/function_array_trim_test.cpp
index 440a5c2c7e7..910e7dac73e 100644
--- a/be/test/exprs/function/function_array_trim_test.cpp
+++ b/be/test/exprs/function/function_array_trim_test.cpp
@@ -62,12 +62,12 @@ static void check_array_trim_case(const DataSet& data_set,
bool const_array, boo
"trim_array", block.get_columns_with_type_and_name(), array_type);
ASSERT_NE(function, nullptr);
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_columns(2);
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_columns(2);
if (const_array) {
- constant_columns[0] =
std::make_shared<ColumnPtrWrapper>(block.get_by_position(0).column);
+ constant_columns[0] =
std::make_shared<ConstantExprResult>(block.get_by_position(0).column);
}
if (const_size) {
- constant_columns[1] =
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column);
+ constant_columns[1] =
std::make_shared<ConstantExprResult>(block.get_by_position(1).column);
}
FunctionUtils function_utils(array_type, {array_type, size_type}, false);
diff --git a/be/test/exprs/function/function_constant_argument_test.cpp
b/be/test/exprs/function/function_constant_argument_test.cpp
index b0fff06b039..7e432022336 100644
--- a/be/test/exprs/function/function_constant_argument_test.cpp
+++ b/be/test/exprs/function/function_constant_argument_test.cpp
@@ -56,7 +56,7 @@ protected:
// for an argument that is not evaluated in open. The result is appended
to each block.
static Status execute(const std::string& name, std::vector<Block>& blocks,
const DataTypePtr& return_type,
- const
std::vector<std::shared_ptr<ColumnPtrWrapper>>& constant_cols) {
+ const
std::vector<std::shared_ptr<ConstantExprResult>>& constant_cols) {
auto arguments = blocks[0].get_columns_with_type_and_name();
FunctionBasePtr function =
SimpleFunctionFactory::instance().get_function(name,
arguments, return_type);
@@ -92,7 +92,7 @@ protected:
}
static Status execute(const std::string& name, Block& block, const
DataTypePtr& return_type,
- const
std::vector<std::shared_ptr<ColumnPtrWrapper>>& constant_cols) {
+ const
std::vector<std::shared_ptr<ConstantExprResult>>& constant_cols) {
std::vector<Block> blocks;
blocks.push_back(std::move(block));
Status status = execute(name, blocks, return_type, constant_cols);
@@ -100,8 +100,8 @@ protected:
return status;
}
- static std::shared_ptr<ColumnPtrWrapper> constant(const ColumnPtr& column)
{
- return std::make_shared<ColumnPtrWrapper>(column);
+ static std::shared_ptr<ConstantExprResult> constant(const ColumnPtr&
column) {
+ return std::make_shared<ConstantExprResult>(column);
}
static ColumnPtr strings(const std::vector<std::string>& values) {
@@ -347,7 +347,7 @@ TEST_F(FunctionConstantArgumentTest, date_trunc_null_unit) {
block.insert({dates, date_type, "date"});
block.insert({unit, string_type, "unit"});
}
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols(2);
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols(2);
constant_cols[unit_first ? 0 : 1] = constant(unit);
Status status = execute("date_trunc", block, return_type,
constant_cols);
ASSERT_TRUE(status.ok()) << status.to_string();
diff --git a/be/test/exprs/function/function_dict_get_many_test.cpp
b/be/test/exprs/function/function_dict_get_many_test.cpp
index e7d72f210d5..6e1dd7cc537 100644
--- a/be/test/exprs/function/function_dict_get_many_test.cpp
+++ b/be/test/exprs/function/function_dict_get_many_test.cpp
@@ -40,8 +40,8 @@ TEST(FunctionDictGetManyTest, test_without_dict_function) {
FunctionContext fn_context {};
fn_context._arg_types.resize(3);
- std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> constant_cols {
- std::make_shared<doris::ColumnPtrWrapper>(
+ std::vector<std::shared_ptr<doris::ConstantExprResult>> constant_cols {
+ std::make_shared<doris::ConstantExprResult>(
ColumnHelper::create_column<DataTypeString>({"test"})),
};
@@ -64,8 +64,8 @@ TEST(FunctionDictGetManyTest, test_without_dict_id) {
FunctionContext fn_context {};
fn_context._arg_types.resize(3);
- std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> constant_cols {
- std::make_shared<doris::ColumnPtrWrapper>(
+ std::vector<std::shared_ptr<doris::ConstantExprResult>> constant_cols {
+ std::make_shared<doris::ConstantExprResult>(
ColumnHelper::create_column<DataTypeString>({"test"})),
};
diff --git a/be/test/exprs/function/function_dict_get_test.cpp
b/be/test/exprs/function/function_dict_get_test.cpp
index 255b27846e4..8aefd272d7a 100644
--- a/be/test/exprs/function/function_dict_get_test.cpp
+++ b/be/test/exprs/function/function_dict_get_test.cpp
@@ -40,8 +40,8 @@ TEST(FunctionDictGetTest, test_without_dict_function) {
FunctionContext fn_context {};
fn_context._arg_types.resize(3);
- std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> constant_cols {
- std::make_shared<doris::ColumnPtrWrapper>(
+ std::vector<std::shared_ptr<doris::ConstantExprResult>> constant_cols {
+ std::make_shared<doris::ConstantExprResult>(
ColumnHelper::create_column<DataTypeString>({"test"})),
};
@@ -64,8 +64,8 @@ TEST(FunctionDictGetTest, test_without_dict_id) {
FunctionContext fn_context {};
fn_context._arg_types.resize(3);
- std::vector<std::shared_ptr<doris::ColumnPtrWrapper>> constant_cols {
- std::make_shared<doris::ColumnPtrWrapper>(
+ std::vector<std::shared_ptr<doris::ConstantExprResult>> constant_cols {
+ std::make_shared<doris::ConstantExprResult>(
ColumnHelper::create_column<DataTypeString>({"test"})),
};
diff --git a/be/test/exprs/function/function_h3_test.cpp
b/be/test/exprs/function/function_h3_test.cpp
index 215d4a799f9..b0f71019c3e 100644
--- a/be/test/exprs/function/function_h3_test.cpp
+++ b/be/test/exprs/function/function_h3_test.cpp
@@ -108,9 +108,9 @@ static void check_coordinates(bool boundary, bool constant,
bool only_null, size
ASSERT_NE(function, nullptr);
FunctionUtils utils(output_type, {input_type}, false);
auto* context = utils.get_fn_ctx();
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constants(1);
+ std::vector<std::shared_ptr<ConstantExprResult>> constants(1);
if (constant) {
- constants[0] =
std::make_shared<ColumnPtrWrapper>(block.get_by_position(0).column);
+ constants[0] =
std::make_shared<ConstantExprResult>(block.get_by_position(0).column);
}
context->set_constant_cols(constants);
ASSERT_TRUE(function->open(context,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL).ok());
diff --git a/be/test/exprs/function/function_like_test.cpp
b/be/test/exprs/function/function_like_test.cpp
index 42fb0be73ed..018b41c4cab 100644
--- a/be/test/exprs/function/function_like_test.cpp
+++ b/be/test/exprs/function/function_like_test.cpp
@@ -82,9 +82,9 @@ Status execute_single_pattern(const TQueryOptions&
query_options, const std::str
? ColumnPtr(std::move(patterns))
:
ColumnConst::create(std::move(patterns), 1);
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_columns(2);
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_columns(2);
if (mode == PatternMode::CONST_AT_OPEN) {
- constant_columns[1] =
std::make_shared<ColumnPtrWrapper>(pattern_column);
+ constant_columns[1] =
std::make_shared<ConstantExprResult>(pattern_column);
}
context->set_constant_cols(constant_columns);
@@ -144,8 +144,8 @@ void check_constant_pattern_batch(const
std::vector<std::string>& values,
pattern_data->insert_data(pattern.data(), pattern.size());
ColumnPtr pattern_column = ColumnConst::create(std::move(pattern_data),
values.size());
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_columns(2);
- constant_columns[1] = std::make_shared<ColumnPtrWrapper>(pattern_column);
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_columns(2);
+ constant_columns[1] = std::make_shared<ConstantExprResult>(pattern_column);
context->set_constant_cols(constant_columns);
Function function;
@@ -623,7 +623,7 @@ TEST(FunctionLikeTest, regexp_extract_all_array) { //
NOLINT(readability-functio
FunctionUtils fn_utils({}, arg_types, false);
auto* fn_ctx = fn_utils.get_fn_ctx();
fn_ctx->set_constant_cols(
- {nullptr,
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column)});
+ {nullptr,
std::make_shared<ConstantExprResult>(block.get_by_position(1).column)});
ASSERT_EQ(Status::OK(),
func->open(fn_ctx,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL));
@@ -703,7 +703,7 @@ TEST(FunctionLikeTest, regexp_extract_all_array) { //
NOLINT(readability-functio
FunctionUtils fn_utils({}, arg_types, false);
auto* fn_ctx = fn_utils.get_fn_ctx();
fn_ctx->set_constant_cols(
- {nullptr,
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column)});
+ {nullptr,
std::make_shared<ConstantExprResult>(block.get_by_position(1).column)});
ASSERT_EQ(Status::OK(),
func->open(fn_ctx,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL));
@@ -743,7 +743,7 @@ TEST(FunctionLikeTest, regexp_extract_all_array) { //
NOLINT(readability-functio
FunctionUtils fn_utils({}, arg_types, false);
auto* fn_ctx = fn_utils.get_fn_ctx();
fn_ctx->set_constant_cols(
- {nullptr,
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column)});
+ {nullptr,
std::make_shared<ConstantExprResult>(block.get_by_position(1).column)});
ASSERT_EQ(Status::OK(),
func->open(fn_ctx,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL));
@@ -787,7 +787,7 @@ TEST(FunctionLikeTest,
regexp_extract_all_boost_zero_width_match) {
query_options.__set_enable_extended_regex(true);
fn_ctx->state()->set_query_options(query_options);
fn_ctx->set_constant_cols(
- {nullptr,
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column)});
+ {nullptr,
std::make_shared<ConstantExprResult>(block.get_by_position(1).column)});
ASSERT_EQ(Status::OK(),
func->open(fn_ctx,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL));
@@ -959,7 +959,7 @@ TEST(FunctionLikeTest, regexp_invalid_column_pattern_fails)
{
Block block;
ColumnNumbers arguments;
std::vector<DataTypePtr> arg_types;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (auto& arg : arg_cols) {
arguments.push_back(static_cast<unsigned int>(block.columns()));
arg_types.push_back(arg.type);
@@ -1082,12 +1082,12 @@ TEST(FunctionLikeTest,
regexp_null_pattern_hides_invalid_payload) {
Block block;
ColumnNumbers arguments;
std::vector<DataTypePtr> arg_types;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (auto& arg : arg_cols) {
arguments.push_back(static_cast<unsigned int>(block.columns()));
arg_types.push_back(arg.type);
constant_cols.push_back(is_column_const(*arg.column)
- ?
std::make_shared<ColumnPtrWrapper>(arg.column)
+ ?
std::make_shared<ConstantExprResult>(arg.column)
: nullptr);
block.insert(std::move(arg));
}
@@ -1218,12 +1218,12 @@ TEST(FunctionLikeTest,
regexp_count_non_nullable_arguments) {
Block block;
ColumnNumbers arguments;
std::vector<DataTypePtr> arg_types;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (auto& arg : arg_cols) {
arguments.push_back(static_cast<unsigned int>(block.columns()));
arg_types.push_back(arg.type);
constant_cols.push_back(is_column_const(*arg.column)
- ?
std::make_shared<ColumnPtrWrapper>(arg.column)
+ ?
std::make_shared<ConstantExprResult>(arg.column)
: nullptr);
block.insert(std::move(arg));
}
@@ -1309,12 +1309,12 @@ TEST(FunctionLikeTest, regexp_non_nullable_arguments) {
Block block;
ColumnNumbers arguments;
std::vector<DataTypePtr> arg_types;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (auto& arg : arg_cols) {
arguments.push_back(static_cast<unsigned int>(block.columns()));
arg_types.push_back(arg.type);
constant_cols.push_back(is_column_const(*arg.column)
- ?
std::make_shared<ColumnPtrWrapper>(arg.column)
+ ?
std::make_shared<ConstantExprResult>(arg.column)
: nullptr);
block.insert(std::move(arg));
}
diff --git a/be/test/exprs/function/function_math_test.cpp
b/be/test/exprs/function/function_math_test.cpp
index 463d9bf4a5c..7c3cc5daefd 100644
--- a/be/test/exprs/function/function_math_test.cpp
+++ b/be/test/exprs/function/function_math_test.cpp
@@ -755,9 +755,9 @@ TEST(MathFunctionTest, uniform_mixed_const_probe_test) {
FunctionUtils fn_utils(return_type, {input_type, input_type, input_type},
false);
auto* fn_ctx = fn_utils.get_fn_ctx();
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols {
-
std::make_shared<ColumnPtrWrapper>(block.get_by_position(0).column),
-
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column),
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols {
+
std::make_shared<ConstantExprResult>(block.get_by_position(0).column),
+
std::make_shared<ConstantExprResult>(block.get_by_position(1).column),
nullptr,
};
fn_ctx->set_constant_cols(constant_cols);
diff --git a/be/test/exprs/function/function_string_test.cpp
b/be/test/exprs/function/function_string_test.cpp
index 90d1ae63e5a..1b4b1806dbb 100644
--- a/be/test/exprs/function/function_string_test.cpp
+++ b/be/test/exprs/function/function_string_test.cpp
@@ -2979,8 +2979,8 @@ TEST(function_string_test,
function_translate_mixed_const_map_test) {
FunctionUtils function_utils(type, {type, type, type}, false);
auto* context = function_utils.get_fn_ctx();
context->set_constant_cols(
- {nullptr,
std::make_shared<ColumnPtrWrapper>(block.get_by_position(1).column),
-
std::make_shared<ColumnPtrWrapper>(block.get_by_position(2).column)});
+ {nullptr,
std::make_shared<ConstantExprResult>(block.get_by_position(1).column),
+
std::make_shared<ConstantExprResult>(block.get_by_position(2).column)});
ASSERT_TRUE(
function->open(context,
FunctionContext::FunctionStateScope::FRAGMENT_LOCAL).ok());
ASSERT_TRUE(
diff --git a/be/test/exprs/function/function_test_util.h
b/be/test/exprs/function/function_test_util.h
index 72473ba3455..3f24b42bfcc 100644
--- a/be/test/exprs/function/function_test_util.h
+++ b/be/test/exprs/function/function_test_util.h
@@ -364,15 +364,15 @@ Status check_function(const std::string& func_name, const
InputTypeSet& input_ty
// 1.2 prepare args for function call
ColumnNumbers arguments;
std::vector<DataTypePtr> arg_types;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_col_ptrs;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_cols;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_col_ptrs;
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_cols;
for (size_t i = 0; i < descs.size(); ++i) {
auto& desc = descs[i];
arguments.push_back(static_cast<unsigned int>(i));
arg_types.push_back(desc.data_type);
if (desc.is_const) {
constant_col_ptrs.push_back(
-
std::make_shared<ColumnPtrWrapper>(block.get_by_position(i).column));
+
std::make_shared<ConstantExprResult>(block.get_by_position(i).column));
constant_cols.push_back(constant_col_ptrs.back());
} else {
constant_cols.push_back(nullptr);
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 3b72e4f4ca6..cef3c45ffc9 100644
--- a/be/test/storage/index/ann/extract_query_vector_test.cpp
+++ b/be/test/storage/index/ann/extract_query_vector_test.cpp
@@ -47,8 +47,8 @@ public:
MockConstVExpr() : VExpr(make_tnode()) {}
Status get_const_col(VExprContext* /*context*/,
- std::shared_ptr<ColumnPtrWrapper>* output) override {
- *output = std::make_shared<ColumnPtrWrapper>(_col);
+ std::shared_ptr<ConstantExprResult>* output) override
{
+ *output = std::make_shared<ConstantExprResult>(_col);
return Status::OK();
}
diff --git
a/be/test/storage/index/inverted/query/logical/gram/regex_gram_recall_test.cpp
b/be/test/storage/index/inverted/query/logical/gram/regex_gram_recall_test.cpp
index b4bb3d3ff64..6704fc37536 100644
---
a/be/test/storage/index/inverted/query/logical/gram/regex_gram_recall_test.cpp
+++
b/be/test/storage/index/inverted/query/logical/gram/regex_gram_recall_test.cpp
@@ -130,7 +130,7 @@ Status scalar_matches(const std::string& pattern, const
std::vector<std::string>
patterns->insert_data(pattern.data(), pattern.size());
}
ColumnPtr pattern_column;
- std::vector<std::shared_ptr<ColumnPtrWrapper>> constant_columns(2);
+ std::vector<std::shared_ptr<ConstantExprResult>> constant_columns(2);
if (dynamic_pattern) {
// Prove vector_non_const will reach the scalar regex function, where
RE2 is
// constructed locally. No scalar or vector string fast path accepts
these patterns.
@@ -144,7 +144,7 @@ Status scalar_matches(const std::string& pattern, const
std::vector<std::string>
pattern_column = std::move(patterns);
} else {
pattern_column = ColumnConst::create(std::move(patterns), rows.size());
- constant_columns[1] =
std::make_shared<ColumnPtrWrapper>(pattern_column);
+ constant_columns[1] =
std::make_shared<ConstantExprResult>(pattern_column);
}
context->set_constant_cols(constant_columns);
diff --git a/be/test/testutil/mock/mock_fn_call.cpp
b/be/test/testutil/mock/mock_fn_call.cpp
index 672ff8230b0..6459b98a793 100644
--- a/be/test/testutil/mock/mock_fn_call.cpp
+++ b/be/test/testutil/mock/mock_fn_call.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
+#include "core/column/column_const.h"
#include "core/data_type/data_type_number.h"
#include "testutil/column_helper.h"
@@ -28,10 +29,24 @@ TEST(MockFnCallTest, test) {
auto fn = MockFnCall::create("test");
EXPECT_EQ(fn->fn().name.function_name, "test");
fn->set_const_expr_col(ColumnHelper::create_column<DataTypeInt64>({1}));
- std::shared_ptr<ColumnPtrWrapper> column_wrapper;
+ std::shared_ptr<ConstantExprResult> column_wrapper;
EXPECT_TRUE(fn->get_const_col(nullptr, &column_wrapper));
- EXPECT_EQ(column_wrapper->column_ptr->size(), 1);
- EXPECT_EQ(column_wrapper->column_ptr->get_int(0), 1);
+ EXPECT_EQ(column_wrapper->column().size(), 1);
+ EXPECT_EQ(column_wrapper->column().get_int(0), 1);
+}
+
+TEST(MockFnCallTest, BroadcastCachedConstant) {
+ auto fn = MockFnCall::create("test");
+ auto data = ColumnHelper::create_column<DataTypeInt64>({7});
+ fn->_constant_col =
std::make_shared<ConstantExprResult>(ColumnConst::create(data, 3));
+ for (size_t count : {0, 1, 5}) {
+ auto result = fn->get_result_from_const(count);
+ const auto* broadcast =
check_and_get_column<ColumnConst>(result.get());
+ ASSERT_NE(broadcast, nullptr);
+ EXPECT_EQ(broadcast->size(), count);
+ EXPECT_EQ(broadcast->get_data_column_ptr().get(), data.get());
+ EXPECT_EQ(broadcast->get_data_column().get_int(0), 7);
+ }
}
} // namespace doris
diff --git a/be/test/testutil/mock/mock_fn_call.h
b/be/test/testutil/mock/mock_fn_call.h
index 952b640e82d..27e0aa413bb 100644
--- a/be/test/testutil/mock/mock_fn_call.h
+++ b/be/test/testutil/mock/mock_fn_call.h
@@ -35,7 +35,7 @@ public:
}
Status get_const_col(VExprContext* context,
- std::shared_ptr<ColumnPtrWrapper>* column_wrapper)
override {
+ std::shared_ptr<ConstantExprResult>* column_wrapper)
override {
*column_wrapper = _mock_const_expr_col;
return Status::OK();
}
@@ -54,7 +54,7 @@ public:
}
void set_const_expr_col(ColumnPtr col) {
- _mock_const_expr_col = std::make_shared<ColumnPtrWrapper>(col);
+ _mock_const_expr_col = std::make_shared<ConstantExprResult>(col);
}
static std::shared_ptr<MockFnCall> create(const std::string& fn_name) {
@@ -65,7 +65,7 @@ public:
private:
const std::string _name = "MockFnCall";
- std::shared_ptr<ColumnPtrWrapper> _mock_const_expr_col;
+ std::shared_ptr<ConstantExprResult> _mock_const_expr_col;
bool _mock_is_constant = false;
};
diff --git a/be/test/testutil/mock/mock_literal_expr.h
b/be/test/testutil/mock/mock_literal_expr.h
index 6b27205cae1..566dc51bf94 100644
--- a/be/test/testutil/mock/mock_literal_expr.h
+++ b/be/test/testutil/mock/mock_literal_expr.h
@@ -44,9 +44,9 @@ public:
_expr_name = data.name;
if (!check_and_get_column<ColumnConst>(data.column.get())) {
_mock_const_expr_col =
-
std::make_shared<ColumnPtrWrapper>(ColumnConst::create(data.column, 1));
+
std::make_shared<ConstantExprResult>(ColumnConst::create(data.column, 1));
} else {
- _mock_const_expr_col =
std::make_shared<ColumnPtrWrapper>(data.column);
+ _mock_const_expr_col =
std::make_shared<ConstantExprResult>(data.column);
}
}
@@ -107,14 +107,14 @@ public:
}
Status get_const_col(VExprContext* context,
- std::shared_ptr<ColumnPtrWrapper>* column_wrapper)
override {
+ std::shared_ptr<ConstantExprResult>* column_wrapper)
override {
*column_wrapper = _mock_const_expr_col;
return Status::OK();
}
private:
const std::string _name = "MockLiteral";
- std::shared_ptr<ColumnPtrWrapper> _mock_const_expr_col;
+ std::shared_ptr<ConstantExprResult> _mock_const_expr_col;
};
} // namespace doris
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]