fix: [2.6] term expr to correctly handle in of string in json (#45956)

issue: https://github.com/milvus-io/milvus/issues/45887
pr: https://github.com/milvus-io/milvus/pull/45955

---------

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
This commit is contained in:
Buqian Zheng 2025-11-29 21:55:09 +08:00 committed by GitHub
parent 45bda55716
commit 5b77d45a27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -31,6 +31,18 @@
namespace milvus { namespace milvus {
namespace exec { namespace exec {
// Transparent string hash for heterogeneous lookup in unordered_dense::set
// See: https://github.com/martinus/unordered_dense#324-heterogeneous-overloads-using-is_transparent
struct StringHash {
using is_transparent = void; // enable heterogeneous overloads
using is_avalanching = void; // mark as high quality avalanching hash
[[nodiscard]] auto
operator()(std::string_view str) const noexcept -> uint64_t {
return ankerl::unordered_dense::hash<std::string_view>{}(str);
}
};
class BaseElement { class BaseElement {
public: public:
virtual ~BaseElement() = default; virtual ~BaseElement() = default;
@ -223,6 +235,13 @@ class FlatVectorElement : public MultiElement {
return true; return true;
} }
} }
// Handle string_view -> string comparison when T is std::string
if constexpr (std::is_same_v<T, std::string>) {
if (auto sv = std::get_if<std::string_view>(&value)) {
return std::find(values_.begin(), values_.end(), *sv) !=
values_.end();
}
}
return false; return false;
} }
@ -242,6 +261,13 @@ class FlatVectorElement : public MultiElement {
template <typename T> template <typename T>
class SetElement : public MultiElement { class SetElement : public MultiElement {
// Use transparent hash for std::string to enable heterogeneous lookup
// This allows O(1) lookup with string_view without string copy
using SetType = std::conditional_t<
std::is_same_v<T, std::string>,
ankerl::unordered_dense::set<T, StringHash, std::equal_to<>>,
ankerl::unordered_dense::set<T>>;
public: public:
explicit SetElement(const std::vector<proto::plan::GenericValue>& values) { explicit SetElement(const std::vector<proto::plan::GenericValue>& values) {
for (auto& value : values) { for (auto& value : values) {
@ -263,7 +289,13 @@ class SetElement : public MultiElement {
bool bool
In(const ValueType& value) const override { In(const ValueType& value) const override {
if (std::holds_alternative<T>(value)) { if (std::holds_alternative<T>(value)) {
return values_.count(std::get<T>(value)) > 0; return values_.find(std::get<T>(value)) != values_.end();
}
// Handle string_view -> string comparison when T is std::string
if constexpr (std::is_same_v<T, std::string>) {
if (auto sv = std::get_if<std::string_view>(&value)) {
return values_.find(*sv) != values_.end();
}
} }
return false; return false;
} }
@ -284,7 +316,7 @@ class SetElement : public MultiElement {
} }
public: public:
ankerl::unordered_dense::set<T> values_; SetType values_;
}; };
template <> template <>