airborne12 commented on code in PR #66449:
URL: https://github.com/apache/doris/pull/66449#discussion_r3719079134


##########
be/src/exprs/vsearch.cpp:
##########
@@ -60,6 +58,58 @@ void add_search_binding_diagnostic(const IndexExecContext* 
index_context,
     }
 }
 
+Status collect_slot_search_input(const VSearchExpr& expr, const VSlotRef& 
slot_ref,
+                                 const TSearchFieldBinding* binding,
+                                 IndexExecContext* index_context, 
SearchInputBundle* bundle) {
+    DCHECK(index_context != nullptr);
+    DCHECK(bundle != nullptr);
+
+    // VSlotRef::column_id() is the scan-schema position used by 
IndexExecContext.
+    const int column_index = slot_ref.column_id();
+    const std::string field_name =
+            binding != nullptr ? binding->field_name : slot_ref.column_name();
+    const bool is_variant_subcolumn = binding != nullptr && 
binding->__isset.is_variant_subcolumn &&
+                                      binding->is_variant_subcolumn;
+
+    bundle->field_name_to_column_id[field_name] = column_index;
+
+    auto* iterator = 
index_context->get_inverted_index_iterator_by_column_id(column_index);
+    if (iterator == nullptr) {
+        // For example, `data.items.message` has its own SlotRef in the scan 
schema. The
+        // storage layer may inherit index metadata from `data`, but it still 
constructs a
+        // child iterator whose stored field name contains the complete 
Variant path.
+        if (is_variant_subcolumn) {
+            add_search_binding_diagnostic(
+                    index_context,
+                    fmt::format("[VariantSearchBinding] phase=collect_inputs "
+                                "result=no_iterator logical_field={} 
column_index={} "
+                                "reason=slot_iterator_missing",
+                                field_name, column_index));
+        }
+        return Status::OK();

Review Comment:
   **[P1] Preserve UNKNOWN for a missing Variant child iterator**
   
   Returning here leaves `bundle.iterators` empty when this is the only SEARCH 
field. The fast path in `VSearchExpr::evaluate_inverted_index()` then stores 
empty data and empty null bitmaps, which represents `FALSE`. An outer `NOT 
search(...)` complements that result to the entire segment.
   
   This conflicts with the existing missing-Variant invariant in 
`FunctionSearch::build_leaf_query()` and 
`TestBuildLeafQueryVariantMissingFieldReturnsUnknown`: an unbound Variant field 
is `UNKNOWN` (`data = {}`, `null = all segment rows`).
   
   Please keep the child-only physical binding, but allow missing Variant 
bindings to reach `FieldReaderResolver`. Both empty-input shortcuts in 
`vsearch.cpp` and `function_search.cpp` need to preserve `UNKNOWN`. The new 
test should also assert data cardinality `0`, null cardinality `32`, and verify 
that an outer `NOT` produces no true rows.



-- 
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]

Reply via email to