diff --git a/internal/core/src/query/Parser.cpp b/internal/core/src/query/Parser.cpp index 43af189d81..0f06e3d191 100644 --- a/internal/core/src/query/Parser.cpp +++ b/internal/core/src/query/Parser.cpp @@ -101,6 +101,7 @@ Parser::ParseRangeNode(const Json& out_body) { switch (data_type) { case DataType::BOOL: return ParseRangeNodeImpl(field_name, body); + case DataType::INT8: return ParseRangeNodeImpl(field_name, body); case DataType::INT16: @@ -109,6 +110,7 @@ Parser::ParseRangeNode(const Json& out_body) { return ParseRangeNodeImpl(field_name, body); case DataType::INT64: return ParseRangeNodeImpl(field_name, body); + case DataType::FLOAT: return ParseRangeNodeImpl(field_name, body); case DataType::DOUBLE: @@ -323,19 +325,32 @@ Parser::ParseRangeNodeImpl(const FieldName& field_name, const Json& body) { if constexpr (std::is_same_v) { Assert(item.value().is_boolean()); + return std::make_unique>( + ColumnInfo(schema.get_field_id(field_name), + schema[field_name].get_data_type()), + mapping_.at(op_name), + item.value(), + proto::plan::GenericValue::ValCase::kBoolVal); } else if constexpr (std::is_integral_v) { Assert(item.value().is_number_integer()); + // see also: https://github.com/milvus-io/milvus/issues/23646. + return std::make_unique>( + ColumnInfo(schema.get_field_id(field_name), + schema[field_name].get_data_type()), + mapping_.at(op_name), + item.value(), + proto::plan::GenericValue::ValCase::kInt64Val); } else if constexpr (std::is_floating_point_v) { Assert(item.value().is_number()); + return std::make_unique>( + ColumnInfo(schema.get_field_id(field_name), + schema[field_name].get_data_type()), + mapping_.at(op_name), + item.value(), + proto::plan::GenericValue::ValCase::kFloatVal); } else { static_assert(always_false, "unsupported type"); } - return std::make_unique>( - ColumnInfo(schema.get_field_id(field_name), - schema[field_name].get_data_type()), - mapping_.at(op_name), - item.value(), - proto::plan::GenericValue::ValCase::VAL_NOT_SET); } else if (body.size() == 2) { bool has_lower_value = false; bool has_upper_value = false; diff --git a/internal/core/src/query/PlanProto.cpp b/internal/core/src/query/PlanProto.cpp index e3adf4d7ec..bca61c934b 100644 --- a/internal/core/src/query/PlanProto.cpp +++ b/internal/core/src/query/PlanProto.cpp @@ -279,22 +279,16 @@ ProtoParser::ParseUnaryRangeExpr(const proto::plan::UnaryRangeExpr& expr_pb) { return ExtractUnaryRangeExprImpl( field_id, data_type, expr_pb); } - case DataType::INT8: { - return ExtractUnaryRangeExprImpl( - field_id, data_type, expr_pb); - } - case DataType::INT16: { - return ExtractUnaryRangeExprImpl( - field_id, data_type, expr_pb); - } - case DataType::INT32: { - return ExtractUnaryRangeExprImpl( - field_id, data_type, expr_pb); - } + + // see also: https://github.com/milvus-io/milvus/issues/23646. + case DataType::INT8: + case DataType::INT16: + case DataType::INT32: case DataType::INT64: { return ExtractUnaryRangeExprImpl( field_id, data_type, expr_pb); } + case DataType::FLOAT: { return ExtractUnaryRangeExprImpl( field_id, data_type, expr_pb); diff --git a/internal/core/src/query/Utils.h b/internal/core/src/query/Utils.h index 7063a7d11e..30a5d2bad4 100644 --- a/internal/core/src/query/Utils.h +++ b/internal/core/src/query/Utils.h @@ -53,10 +53,21 @@ Match(const std::string_view& str, } } +template >> +inline bool +gt_ub(int64_t t) { + return t > std::numeric_limits::max(); +} + +template >> +inline bool +lt_lb(int64_t t) { + return t < std::numeric_limits::min(); +} + template >> inline bool out_of_range(int64_t t) { - return t > std::numeric_limits::max() || - t < std::numeric_limits::min(); + return gt_ub(t) || lt_lb(t); } } // namespace milvus::query diff --git a/internal/core/src/query/generated/ExecExprVisitor.h b/internal/core/src/query/generated/ExecExprVisitor.h index 3c608043e4..93bc969663 100644 --- a/internal/core/src/query/generated/ExecExprVisitor.h +++ b/internal/core/src/query/generated/ExecExprVisitor.h @@ -82,6 +82,10 @@ class ExecExprVisitor : public ExprVisitor { IndexFunc index_func, ElementFunc element_func) -> BitsetType; + template + auto + ExecUnaryRangeVisitorDispatcherImpl(UnaryRangeExpr& expr_raw) -> BitsetType; + template auto ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> BitsetType; diff --git a/internal/core/src/query/visitors/ExecExprVisitor.cpp b/internal/core/src/query/visitors/ExecExprVisitor.cpp index b741fa6370..0406952f3f 100644 --- a/internal/core/src/query/visitors/ExecExprVisitor.cpp +++ b/internal/core/src/query/visitors/ExecExprVisitor.cpp @@ -66,6 +66,10 @@ class ExecExprVisitor : ExprVisitor { IndexFunc func, ElementFunc element_func) -> BitsetType; + template + auto + ExecUnaryRangeVisitorDispatcherImpl(UnaryRangeExpr& expr_raw) -> BitsetType; + template auto ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> BitsetType; @@ -351,7 +355,7 @@ ExecExprVisitor::ExecDataRangeVisitorImpl(FieldId field_id, #pragma ide diagnostic ignored "Simplify" template auto -ExecExprVisitor::ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) +ExecExprVisitor::ExecUnaryRangeVisitorDispatcherImpl(UnaryRangeExpr& expr_raw) -> BitsetType { typedef std:: conditional_t, std::string, T> @@ -423,6 +427,58 @@ ExecExprVisitor::ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) } #pragma clang diagnostic pop +template +auto +ExecExprVisitor::ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) + -> BitsetType { + if constexpr (std::is_integral_v) { + auto& expr = static_cast&>(expr_raw); + auto val = expr.value_; + + if (!out_of_range(val)) { + return ExecUnaryRangeVisitorDispatcherImpl(expr_raw); + } + + // see also: https://github.com/milvus-io/milvus/issues/23646. + switch (expr.op_type_) { + case proto::plan::GreaterThan: + case proto::plan::GreaterEqual: { + BitsetType r(row_count_); + if (lt_lb(val)) { + r.set(); + } + return r; + } + + case proto::plan::LessThan: + case proto::plan::LessEqual: { + BitsetType r(row_count_); + if (gt_ub(val)) { + r.set(); + } + return r; + } + + case proto::plan::Equal: { + BitsetType r(row_count_); + r.reset(); + return r; + } + + case proto::plan::NotEqual: { + BitsetType r(row_count_); + r.set(); + return r; + } + + default: { + PanicInfo("unsupported range node"); + } + } + } + return ExecUnaryRangeVisitorDispatcherImpl(expr_raw); +} + template auto ExecExprVisitor::ExecUnaryRangeVisitorDispatcherJson(UnaryRangeExpr& expr_raw) diff --git a/internal/core/src/query/visitors/ShowExprVisitor.cpp b/internal/core/src/query/visitors/ShowExprVisitor.cpp index d82080fbf7..5d75770e4a 100644 --- a/internal/core/src/query/visitors/ShowExprVisitor.cpp +++ b/internal/core/src/query/visitors/ShowExprVisitor.cpp @@ -173,18 +173,15 @@ ShowExprVisitor::visit(UnaryRangeExpr& expr) { case DataType::BOOL: json_opt_ = UnaryRangeExtract(expr); return; + + // see also: https://github.com/milvus-io/milvus/issues/23646. case DataType::INT8: - json_opt_ = UnaryRangeExtract(expr); - return; case DataType::INT16: - json_opt_ = UnaryRangeExtract(expr); - return; case DataType::INT32: - json_opt_ = UnaryRangeExtract(expr); - return; case DataType::INT64: json_opt_ = UnaryRangeExtract(expr); return; + case DataType::DOUBLE: json_opt_ = UnaryRangeExtract(expr); return;