HappenLee commented on code in PR #55458:
URL: https://github.com/apache/doris/pull/55458#discussion_r2335537250
##########
be/src/olap/rowset/segment_v2/ann_index/ann_topn_runtime.cpp:
##########
@@ -71,27 +71,97 @@ Status AnnTopNRuntime::prepare(RuntimeState* state, const
RowDescriptor& row_des
std::dynamic_pointer_cast<vectorized::VectorizedFnCall>(vir_col_expr);
if (distance_fn_call == nullptr) {
- return Status::InternalError("Ann topn expr expect FuncationCall,
got\n{}",
- vir_col_expr->debug_string());
+ return Status::InvalidArgument("Ann topn expr expect FuncationCall,
got\n{}",
+ vir_col_expr->debug_string());
}
std::shared_ptr<vectorized::VSlotRef> slot_ref =
std::dynamic_pointer_cast<vectorized::VSlotRef>(distance_fn_call->children()[0]);
if (slot_ref == nullptr) {
- return Status::InternalError("Ann topn expr expect SlotRef, got\n{}",
-
distance_fn_call->children()[0]->debug_string());
+ return Status::InvalidArgument("Ann topn expr expect SlotRef, got\n{}",
+
distance_fn_call->children()[0]->debug_string());
}
// slot_ref->column_id() is acutually the columnd idx in block.
_src_column_idx = slot_ref->column_id();
- std::shared_ptr<vectorized::VArrayLiteral> array_literal =
-
std::dynamic_pointer_cast<vectorized::VArrayLiteral>(distance_fn_call->children()[1]);
- if (array_literal == nullptr) {
- return Status::InternalError("Ann topn expr expect ArrayLiteral,
got\n{}",
-
distance_fn_call->children()[1]->debug_string());
+ if (distance_fn_call->children()[1]->is_constant() == false) {
+ return Status::InvalidArgument("Ann topn expr expect constant
ArrayLiteral, got\n{}",
+
distance_fn_call->children()[1]->debug_string());
}
- _query_array = array_literal->get_column_ptr();
+
+ // Accept either ArrayLiteral([..]) or CAST('..' AS
Nullable(Array(Nullable(Float32))))
+ // First, check the expr node type for clarity.
+ auto arg_expr = distance_fn_call->children()[1];
+ bool is_array_literal =
+ std::dynamic_pointer_cast<vectorized::VArrayLiteral>(arg_expr) !=
nullptr;
+ bool is_cast_expr =
std::dynamic_pointer_cast<vectorized::VCastExpr>(arg_expr) != nullptr;
+ if (!is_array_literal && !is_cast_expr) {
+ return Status::InvalidArgument(
+ "Ann topn expr constant must be ArrayLiteral or CAST to array,
got\n{}",
+ arg_expr->debug_string());
+ }
+
+ // We'll validate shape by inspecting the materialized constant column
below.
+
+ std::shared_ptr<ColumnPtrWrapper> column_wrapper;
+ RETURN_IF_ERROR(distance_fn_call->children()[1]->get_const_col(nullptr,
&column_wrapper));
+
+ // Execute the constant array literal and extract its float elements into
_query_array
+ vectorized::IColumn::Ptr col_ptr =
+ column_wrapper->column_ptr->convert_to_full_column_if_const();
+
+ // The expected runtime column layout for the literal is:
+ // Nullable(ColumnArray(Nullable(ColumnFloat32))) with exactly 1 row (one
array literal)
+ const vectorized::IColumn* top_col = col_ptr.get();
+ const vectorized::IColumn* array_holder_col = top_col;
+ // Handle outer Nullable and remember result nullability preference
+ if (auto* nullable_col =
+
vectorized::check_and_get_column<vectorized::ColumnNullable>(*top_col)) {
+ if (nullable_col->has_null()) {
+ return Status::InvalidArgument("Ann topn query vector cannot be
NULL");
+ }
+ array_holder_col = &nullable_col->get_nested_column();
+ }
+
+ // Must be an array column with single row
+ const auto* array_col =
+
vectorized::check_and_get_column<vectorized::ColumnArray>(*array_holder_col);
+ if (array_col == nullptr || array_col->size() != 1) {
+ return Status::InvalidArgument(
+ "Ann topn expr constant should be an Array literal, got
column: {}",
+ array_holder_col->get_name());
+ }
+
+ // Fetch nested data column: Nullable(ColumnFloat32) or ColumnFloat32
+ const vectorized::IColumn& nested_data_any = array_col->get_data();
+ const vectorized::IColumn* values_holder_col = &nested_data_any;
+ size_t value_count = array_col->get_offsets()[0];
+
+ if (value_count == 0) {
+ return Status::InvalidArgument("Ann topn query vector cannot be
empty");
+ }
+
+ if (auto* value_nullable_col =
+
vectorized::check_and_get_column<vectorized::ColumnNullable>(nested_data_any)) {
+ if (value_nullable_col->has_null(0, value_count)) {
+ return Status::InvalidArgument(
+ "Ann topn query vector elements cannot contain NULL
values");
+ }
+ values_holder_col = &value_nullable_col->get_nested_column();
+ }
+
+ // Now must be ColumnFloat32
+ const auto* value_col = assert_cast<const
vectorized::ColumnFloat32*>(values_holder_col);
+
+ _query_array_size = value_count;
Review Comment:
why here we need copy not direct use the mem of values_holder_col ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]