@@ -48,39 +48,63 @@ Status collect_search_inputs(const VSearchExpr& expr, VExprContext* context,
4848
4949 auto index_context = context->get_inverted_index_context ();
5050 if (index_context == nullptr ) {
51- return Status::OK ();
51+ LOG (WARNING) << " collect_search_inputs: No inverted index context available" ;
52+ return Status::InternalError (" No inverted index context available" );
5253 }
5354
55+ // Get field bindings for variant subcolumn support
56+ const auto & search_param = expr.get_search_param ();
57+ const auto & field_bindings = search_param.field_bindings ;
58+
59+ int child_index = 0 ; // Index for iterating through children
5460 for (const auto & child : expr.children ()) {
5561 if (child->is_slot_ref ()) {
5662 auto * column_slot_ref = assert_cast<VSlotRef*>(child.get ());
5763 int column_id = column_slot_ref->column_id ();
5864 auto * iterator = index_context->get_inverted_index_iterator_by_column_id (column_id);
59- if (iterator == nullptr ) {
60- continue ;
65+
66+ // Determine the field_name from field_bindings (for variant subcolumns)
67+ // field_bindings and children should have the same order
68+ std::string field_name;
69+ if (child_index < field_bindings.size ()) {
70+ // Use field_name from binding (may include "parent.subcolumn" for variant)
71+ field_name = field_bindings[child_index].field_name ;
72+ } else {
73+ // Fallback to column_name if binding not found
74+ field_name = column_slot_ref->column_name ();
6175 }
6276
63- const auto * storage_name_type =
64- index_context->get_storage_name_and_type_by_column_id (column_id);
65- if (storage_name_type == nullptr ) {
66- auto err_msg = fmt::format (
67- " storage_name_type cannot be found for column {} while in {} evaluate" ,
68- column_id, expr.expr_name ());
69- LOG (ERROR) << err_msg;
70- return Status::InternalError (err_msg);
77+ // Only collect fields that have iterators (materialized columns with indexes)
78+ if (iterator != nullptr ) {
79+ const auto * storage_name_type =
80+ index_context->get_storage_name_and_type_by_column_id (column_id);
81+ if (storage_name_type == nullptr ) {
82+ return Status::InternalError (" storage_name_type not found for column {} in {}" ,
83+ column_id, expr.expr_name ());
84+ }
85+
86+ bundle->iterators .emplace (field_name, iterator);
87+ bundle->field_types .emplace (field_name, *storage_name_type);
88+ bundle->column_ids .emplace_back (column_id);
7189 }
7290
73- auto column_name = column_slot_ref->column_name ();
74- bundle->iterators .emplace (column_name, iterator);
75- bundle->field_types .emplace (column_name, *storage_name_type);
76- bundle->column_ids .emplace_back (column_id);
91+ child_index++;
7792 } else if (child->is_literal ()) {
7893 auto * literal = assert_cast<VLiteral*>(child.get ());
7994 bundle->literal_args .emplace_back (literal->get_column_ptr (), literal->get_data_type (),
8095 literal->expr_name ());
8196 } else {
82- LOG (WARNING) << " VSearchExpr: Unsupported child node type encountered" ;
83- return Status::InvalidArgument (" search expression child type unsupported" );
97+ // Check if this is ElementAt expression (for variant subcolumn access)
98+ if (child->expr_name () == " element_at" && child_index < field_bindings.size () &&
99+ field_bindings[child_index].__isset .is_variant_subcolumn &&
100+ field_bindings[child_index].is_variant_subcolumn ) {
101+ // Variant subcolumn not materialized - skip, will create empty BitmapQuery in function_search
102+ child_index++;
103+ continue ;
104+ }
105+
106+ // Not a supported child type
107+ return Status::InvalidArgument (" Unsupported child node type: {}" , child->expr_name ());
84108 }
85109 }
86110
@@ -94,16 +118,6 @@ VSearchExpr::VSearchExpr(const TExprNode& node) : VExpr(node) {
94118 _search_param = node.search_param ;
95119 _original_dsl = _search_param.original_dsl ;
96120 }
97-
98- LOG (INFO) << " VSearchExpr constructor: dsl='" << _original_dsl
99- << " ', num_children=" << node.num_children
100- << " , has_search_param=" << node.__isset .search_param
101- << " , children_size=" << _children.size ();
102-
103- for (size_t i = 0 ; i < _children.size (); i++) {
104- LOG (INFO) << " VSearchExpr constructor: child[" << i
105- << " ] expr_name=" << _children[i]->expr_name ();
106- }
107121}
108122
109123const std::string& VSearchExpr::expr_name () const {
@@ -120,7 +134,7 @@ Status VSearchExpr::execute(VExprContext* context, Block* block, int* result_col
120134}
121135
122136Status VSearchExpr::evaluate_inverted_index (VExprContext* context, uint32_t segment_num_rows) {
123- LOG (INFO) << " VSearchExpr::evaluate_inverted_index called with DSL: " << _original_dsl ;
137+ LOG (INFO) << " VSearchExpr::evaluate_inverted_index called, DSL: " << _search_param. original_dsl ;
124138
125139 if (_search_param.original_dsl .empty ()) {
126140 return Status::InvalidArgument (" search DSL is empty" );
@@ -135,8 +149,14 @@ Status VSearchExpr::evaluate_inverted_index(VExprContext* context, uint32_t segm
135149 SearchInputBundle bundle;
136150 RETURN_IF_ERROR (collect_search_inputs (*this , context, &bundle));
137151
152+ VLOG_DEBUG << " VSearchExpr: bundle.iterators.size()=" << bundle.iterators .size ();
153+
138154 if (bundle.iterators .empty ()) {
139- LOG (WARNING) << " VSearchExpr: No indexed columns available for evaluation" ;
155+ LOG (WARNING) << " VSearchExpr: No indexed columns available for evaluation, DSL: "
156+ << _original_dsl;
157+ auto empty_bitmap = InvertedIndexResultBitmap (std::make_shared<roaring::Roaring>(),
158+ std::make_shared<roaring::Roaring>());
159+ index_context->set_inverted_index_result_for_expr (this , std::move (empty_bitmap));
140160 return Status::OK ();
141161 }
142162
@@ -155,15 +175,6 @@ Status VSearchExpr::evaluate_inverted_index(VExprContext* context, uint32_t segm
155175 index_context->set_true_for_inverted_index_status (this , column_id);
156176 }
157177
158- const auto & data_bitmap = result_bitmap.get_data_bitmap ();
159- const uint64_t match_count = data_bitmap ? data_bitmap->cardinality () : 0 ;
160- if (match_count > 0 ) {
161- LOG (INFO) << " VSearchExpr: Found " << match_count
162- << " matching rows for DSL: " << _search_param.original_dsl ;
163- } else {
164- LOG (INFO) << " VSearchExpr: No matches found for DSL: " << _search_param.original_dsl ;
165- }
166-
167178 return Status::OK ();
168179}
169180
0 commit comments