Support arithmetic operations on numerical fields for scalar filtering (#16520)

Signed-off-by: Aivin V. Solatorio <avsolatorio@gmail.com>
pull/16571/head
Aivin V. Solatorio 2022-04-24 04:43:45 -04:00 committed by GitHub
parent b82f6a1a0a
commit 04fffb08ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 3306 additions and 114 deletions

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ struct TableStruct_plan_2eproto {
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[12]
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[14]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
@ -59,6 +59,12 @@ extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table
namespace milvus {
namespace proto {
namespace plan {
class BinaryArithOp;
class BinaryArithOpDefaultTypeInternal;
extern BinaryArithOpDefaultTypeInternal _BinaryArithOp_default_instance_;
class BinaryArithOpEvalRangeExpr;
class BinaryArithOpEvalRangeExprDefaultTypeInternal;
extern BinaryArithOpEvalRangeExprDefaultTypeInternal _BinaryArithOpEvalRangeExpr_default_instance_;
class BinaryExpr;
class BinaryExprDefaultTypeInternal;
extern BinaryExprDefaultTypeInternal _BinaryExpr_default_instance_;
@ -99,6 +105,8 @@ extern VectorANNSDefaultTypeInternal _VectorANNS_default_instance_;
} // namespace proto
} // namespace milvus
PROTOBUF_NAMESPACE_OPEN
template<> ::milvus::proto::plan::BinaryArithOp* Arena::CreateMaybeMessage<::milvus::proto::plan::BinaryArithOp>(Arena*);
template<> ::milvus::proto::plan::BinaryArithOpEvalRangeExpr* Arena::CreateMaybeMessage<::milvus::proto::plan::BinaryArithOpEvalRangeExpr>(Arena*);
template<> ::milvus::proto::plan::BinaryExpr* Arena::CreateMaybeMessage<::milvus::proto::plan::BinaryExpr>(Arena*);
template<> ::milvus::proto::plan::BinaryRangeExpr* Arena::CreateMaybeMessage<::milvus::proto::plan::BinaryRangeExpr>(Arena*);
template<> ::milvus::proto::plan::ColumnInfo* Arena::CreateMaybeMessage<::milvus::proto::plan::ColumnInfo>(Arena*);
@ -197,6 +205,35 @@ inline bool OpType_Parse(
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<OpType>(
OpType_descriptor(), name, value);
}
enum ArithOpType : int {
Unknown = 0,
Add = 1,
Sub = 2,
Mul = 3,
Div = 4,
Mod = 5,
ArithOpType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
ArithOpType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
};
bool ArithOpType_IsValid(int value);
constexpr ArithOpType ArithOpType_MIN = Unknown;
constexpr ArithOpType ArithOpType_MAX = Mod;
constexpr int ArithOpType_ARRAYSIZE = ArithOpType_MAX + 1;
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ArithOpType_descriptor();
template<typename T>
inline const std::string& ArithOpType_Name(T enum_t_value) {
static_assert(::std::is_same<T, ArithOpType>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function ArithOpType_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
ArithOpType_descriptor(), enum_t_value);
}
inline bool ArithOpType_Parse(
const std::string& name, ArithOpType* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ArithOpType>(
ArithOpType_descriptor(), name, value);
}
// ===================================================================
class GenericValue :
@ -1678,6 +1715,325 @@ class BinaryExpr :
};
// -------------------------------------------------------------------
class BinaryArithOp :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:milvus.proto.plan.BinaryArithOp) */ {
public:
BinaryArithOp();
virtual ~BinaryArithOp();
BinaryArithOp(const BinaryArithOp& from);
BinaryArithOp(BinaryArithOp&& from) noexcept
: BinaryArithOp() {
*this = ::std::move(from);
}
inline BinaryArithOp& operator=(const BinaryArithOp& from) {
CopyFrom(from);
return *this;
}
inline BinaryArithOp& operator=(BinaryArithOp&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
return GetMetadataStatic().descriptor;
}
static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
return GetMetadataStatic().reflection;
}
static const BinaryArithOp& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const BinaryArithOp* internal_default_instance() {
return reinterpret_cast<const BinaryArithOp*>(
&_BinaryArithOp_default_instance_);
}
static constexpr int kIndexInFileMessages =
9;
friend void swap(BinaryArithOp& a, BinaryArithOp& b) {
a.Swap(&b);
}
inline void Swap(BinaryArithOp* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
inline BinaryArithOp* New() const final {
return CreateMaybeMessage<BinaryArithOp>(nullptr);
}
BinaryArithOp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<BinaryArithOp>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void CopyFrom(const BinaryArithOp& from);
void MergeFrom(const BinaryArithOp& from);
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final;
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
void SerializeWithCachedSizes(
::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final;
::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
::PROTOBUF_NAMESPACE_ID::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
inline void SharedCtor();
inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(BinaryArithOp* other);
friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
return "milvus.proto.plan.BinaryArithOp";
}
private:
inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const {
return nullptr;
}
inline void* MaybeArenaPtr() const {
return nullptr;
}
public:
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
private:
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_plan_2eproto);
return ::descriptor_table_plan_2eproto.file_level_metadata[kIndexInFileMessages];
}
public:
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kColumnInfoFieldNumber = 1,
kRightOperandFieldNumber = 3,
kArithOpFieldNumber = 2,
};
// .milvus.proto.plan.ColumnInfo column_info = 1;
bool has_column_info() const;
void clear_column_info();
const ::milvus::proto::plan::ColumnInfo& column_info() const;
::milvus::proto::plan::ColumnInfo* release_column_info();
::milvus::proto::plan::ColumnInfo* mutable_column_info();
void set_allocated_column_info(::milvus::proto::plan::ColumnInfo* column_info);
// .milvus.proto.plan.GenericValue right_operand = 3;
bool has_right_operand() const;
void clear_right_operand();
const ::milvus::proto::plan::GenericValue& right_operand() const;
::milvus::proto::plan::GenericValue* release_right_operand();
::milvus::proto::plan::GenericValue* mutable_right_operand();
void set_allocated_right_operand(::milvus::proto::plan::GenericValue* right_operand);
// .milvus.proto.plan.ArithOpType arith_op = 2;
void clear_arith_op();
::milvus::proto::plan::ArithOpType arith_op() const;
void set_arith_op(::milvus::proto::plan::ArithOpType value);
// @@protoc_insertion_point(class_scope:milvus.proto.plan.BinaryArithOp)
private:
class _Internal;
::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
::milvus::proto::plan::ColumnInfo* column_info_;
::milvus::proto::plan::GenericValue* right_operand_;
int arith_op_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
friend struct ::TableStruct_plan_2eproto;
};
// -------------------------------------------------------------------
class BinaryArithOpEvalRangeExpr :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:milvus.proto.plan.BinaryArithOpEvalRangeExpr) */ {
public:
BinaryArithOpEvalRangeExpr();
virtual ~BinaryArithOpEvalRangeExpr();
BinaryArithOpEvalRangeExpr(const BinaryArithOpEvalRangeExpr& from);
BinaryArithOpEvalRangeExpr(BinaryArithOpEvalRangeExpr&& from) noexcept
: BinaryArithOpEvalRangeExpr() {
*this = ::std::move(from);
}
inline BinaryArithOpEvalRangeExpr& operator=(const BinaryArithOpEvalRangeExpr& from) {
CopyFrom(from);
return *this;
}
inline BinaryArithOpEvalRangeExpr& operator=(BinaryArithOpEvalRangeExpr&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
return GetMetadataStatic().descriptor;
}
static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
return GetMetadataStatic().reflection;
}
static const BinaryArithOpEvalRangeExpr& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const BinaryArithOpEvalRangeExpr* internal_default_instance() {
return reinterpret_cast<const BinaryArithOpEvalRangeExpr*>(
&_BinaryArithOpEvalRangeExpr_default_instance_);
}
static constexpr int kIndexInFileMessages =
10;
friend void swap(BinaryArithOpEvalRangeExpr& a, BinaryArithOpEvalRangeExpr& b) {
a.Swap(&b);
}
inline void Swap(BinaryArithOpEvalRangeExpr* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
inline BinaryArithOpEvalRangeExpr* New() const final {
return CreateMaybeMessage<BinaryArithOpEvalRangeExpr>(nullptr);
}
BinaryArithOpEvalRangeExpr* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<BinaryArithOpEvalRangeExpr>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void CopyFrom(const BinaryArithOpEvalRangeExpr& from);
void MergeFrom(const BinaryArithOpEvalRangeExpr& from);
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final;
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
void SerializeWithCachedSizes(
::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final;
::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
::PROTOBUF_NAMESPACE_ID::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
inline void SharedCtor();
inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(BinaryArithOpEvalRangeExpr* other);
friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
return "milvus.proto.plan.BinaryArithOpEvalRangeExpr";
}
private:
inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const {
return nullptr;
}
inline void* MaybeArenaPtr() const {
return nullptr;
}
public:
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
private:
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_plan_2eproto);
return ::descriptor_table_plan_2eproto.file_level_metadata[kIndexInFileMessages];
}
public:
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kColumnInfoFieldNumber = 1,
kRightOperandFieldNumber = 3,
kValueFieldNumber = 5,
kArithOpFieldNumber = 2,
kOpFieldNumber = 4,
};
// .milvus.proto.plan.ColumnInfo column_info = 1;
bool has_column_info() const;
void clear_column_info();
const ::milvus::proto::plan::ColumnInfo& column_info() const;
::milvus::proto::plan::ColumnInfo* release_column_info();
::milvus::proto::plan::ColumnInfo* mutable_column_info();
void set_allocated_column_info(::milvus::proto::plan::ColumnInfo* column_info);
// .milvus.proto.plan.GenericValue right_operand = 3;
bool has_right_operand() const;
void clear_right_operand();
const ::milvus::proto::plan::GenericValue& right_operand() const;
::milvus::proto::plan::GenericValue* release_right_operand();
::milvus::proto::plan::GenericValue* mutable_right_operand();
void set_allocated_right_operand(::milvus::proto::plan::GenericValue* right_operand);
// .milvus.proto.plan.GenericValue value = 5;
bool has_value() const;
void clear_value();
const ::milvus::proto::plan::GenericValue& value() const;
::milvus::proto::plan::GenericValue* release_value();
::milvus::proto::plan::GenericValue* mutable_value();
void set_allocated_value(::milvus::proto::plan::GenericValue* value);
// .milvus.proto.plan.ArithOpType arith_op = 2;
void clear_arith_op();
::milvus::proto::plan::ArithOpType arith_op() const;
void set_arith_op(::milvus::proto::plan::ArithOpType value);
// .milvus.proto.plan.OpType op = 4;
void clear_op();
::milvus::proto::plan::OpType op() const;
void set_op(::milvus::proto::plan::OpType value);
// @@protoc_insertion_point(class_scope:milvus.proto.plan.BinaryArithOpEvalRangeExpr)
private:
class _Internal;
::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
::milvus::proto::plan::ColumnInfo* column_info_;
::milvus::proto::plan::GenericValue* right_operand_;
::milvus::proto::plan::GenericValue* value_;
int arith_op_;
int op_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
friend struct ::TableStruct_plan_2eproto;
};
// -------------------------------------------------------------------
class Expr :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:milvus.proto.plan.Expr) */ {
public:
@ -1721,6 +2077,7 @@ class Expr :
kCompareExpr = 4,
kUnaryRangeExpr = 5,
kBinaryRangeExpr = 6,
kBinaryArithOpEvalRangeExpr = 7,
EXPR_NOT_SET = 0,
};
@ -1730,7 +2087,7 @@ class Expr :
&_Expr_default_instance_);
}
static constexpr int kIndexInFileMessages =
9;
11;
friend void swap(Expr& a, Expr& b) {
a.Swap(&b);
@ -1807,6 +2164,7 @@ class Expr :
kCompareExprFieldNumber = 4,
kUnaryRangeExprFieldNumber = 5,
kBinaryRangeExprFieldNumber = 6,
kBinaryArithOpEvalRangeExprFieldNumber = 7,
};
// .milvus.proto.plan.TermExpr term_expr = 1;
bool has_term_expr() const;
@ -1856,6 +2214,14 @@ class Expr :
::milvus::proto::plan::BinaryRangeExpr* mutable_binary_range_expr();
void set_allocated_binary_range_expr(::milvus::proto::plan::BinaryRangeExpr* binary_range_expr);
// .milvus.proto.plan.BinaryArithOpEvalRangeExpr binary_arith_op_eval_range_expr = 7;
bool has_binary_arith_op_eval_range_expr() const;
void clear_binary_arith_op_eval_range_expr();
const ::milvus::proto::plan::BinaryArithOpEvalRangeExpr& binary_arith_op_eval_range_expr() const;
::milvus::proto::plan::BinaryArithOpEvalRangeExpr* release_binary_arith_op_eval_range_expr();
::milvus::proto::plan::BinaryArithOpEvalRangeExpr* mutable_binary_arith_op_eval_range_expr();
void set_allocated_binary_arith_op_eval_range_expr(::milvus::proto::plan::BinaryArithOpEvalRangeExpr* binary_arith_op_eval_range_expr);
void clear_expr();
ExprCase expr_case() const;
// @@protoc_insertion_point(class_scope:milvus.proto.plan.Expr)
@ -1867,6 +2233,7 @@ class Expr :
void set_has_compare_expr();
void set_has_unary_range_expr();
void set_has_binary_range_expr();
void set_has_binary_arith_op_eval_range_expr();
inline bool has_expr() const;
inline void clear_has_expr();
@ -1880,6 +2247,7 @@ class Expr :
::milvus::proto::plan::CompareExpr* compare_expr_;
::milvus::proto::plan::UnaryRangeExpr* unary_range_expr_;
::milvus::proto::plan::BinaryRangeExpr* binary_range_expr_;
::milvus::proto::plan::BinaryArithOpEvalRangeExpr* binary_arith_op_eval_range_expr_;
} expr_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
::PROTOBUF_NAMESPACE_ID::uint32 _oneof_case_[1];
@ -1930,7 +2298,7 @@ class VectorANNS :
&_VectorANNS_default_instance_);
}
static constexpr int kIndexInFileMessages =
10;
12;
friend void swap(VectorANNS& a, VectorANNS& b) {
a.Swap(&b);
@ -2107,7 +2475,7 @@ class PlanNode :
&_PlanNode_default_instance_);
}
static constexpr int kIndexInFileMessages =
11;
13;
friend void swap(PlanNode& a, PlanNode& b) {
a.Swap(&b);
@ -3325,6 +3693,311 @@ inline void BinaryExpr::set_allocated_right(::milvus::proto::plan::Expr* right)
// -------------------------------------------------------------------
// BinaryArithOp
// .milvus.proto.plan.ColumnInfo column_info = 1;
inline bool BinaryArithOp::has_column_info() const {
return this != internal_default_instance() && column_info_ != nullptr;
}
inline void BinaryArithOp::clear_column_info() {
if (GetArenaNoVirtual() == nullptr && column_info_ != nullptr) {
delete column_info_;
}
column_info_ = nullptr;
}
inline const ::milvus::proto::plan::ColumnInfo& BinaryArithOp::column_info() const {
const ::milvus::proto::plan::ColumnInfo* p = column_info_;
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOp.column_info)
return p != nullptr ? *p : *reinterpret_cast<const ::milvus::proto::plan::ColumnInfo*>(
&::milvus::proto::plan::_ColumnInfo_default_instance_);
}
inline ::milvus::proto::plan::ColumnInfo* BinaryArithOp::release_column_info() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.BinaryArithOp.column_info)
::milvus::proto::plan::ColumnInfo* temp = column_info_;
column_info_ = nullptr;
return temp;
}
inline ::milvus::proto::plan::ColumnInfo* BinaryArithOp::mutable_column_info() {
if (column_info_ == nullptr) {
auto* p = CreateMaybeMessage<::milvus::proto::plan::ColumnInfo>(GetArenaNoVirtual());
column_info_ = p;
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.BinaryArithOp.column_info)
return column_info_;
}
inline void BinaryArithOp::set_allocated_column_info(::milvus::proto::plan::ColumnInfo* column_info) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == nullptr) {
delete column_info_;
}
if (column_info) {
::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
if (message_arena != submessage_arena) {
column_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
message_arena, column_info, submessage_arena);
}
} else {
}
column_info_ = column_info;
// @@protoc_insertion_point(field_set_allocated:milvus.proto.plan.BinaryArithOp.column_info)
}
// .milvus.proto.plan.ArithOpType arith_op = 2;
inline void BinaryArithOp::clear_arith_op() {
arith_op_ = 0;
}
inline ::milvus::proto::plan::ArithOpType BinaryArithOp::arith_op() const {
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOp.arith_op)
return static_cast< ::milvus::proto::plan::ArithOpType >(arith_op_);
}
inline void BinaryArithOp::set_arith_op(::milvus::proto::plan::ArithOpType value) {
arith_op_ = value;
// @@protoc_insertion_point(field_set:milvus.proto.plan.BinaryArithOp.arith_op)
}
// .milvus.proto.plan.GenericValue right_operand = 3;
inline bool BinaryArithOp::has_right_operand() const {
return this != internal_default_instance() && right_operand_ != nullptr;
}
inline void BinaryArithOp::clear_right_operand() {
if (GetArenaNoVirtual() == nullptr && right_operand_ != nullptr) {
delete right_operand_;
}
right_operand_ = nullptr;
}
inline const ::milvus::proto::plan::GenericValue& BinaryArithOp::right_operand() const {
const ::milvus::proto::plan::GenericValue* p = right_operand_;
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOp.right_operand)
return p != nullptr ? *p : *reinterpret_cast<const ::milvus::proto::plan::GenericValue*>(
&::milvus::proto::plan::_GenericValue_default_instance_);
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOp::release_right_operand() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.BinaryArithOp.right_operand)
::milvus::proto::plan::GenericValue* temp = right_operand_;
right_operand_ = nullptr;
return temp;
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOp::mutable_right_operand() {
if (right_operand_ == nullptr) {
auto* p = CreateMaybeMessage<::milvus::proto::plan::GenericValue>(GetArenaNoVirtual());
right_operand_ = p;
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.BinaryArithOp.right_operand)
return right_operand_;
}
inline void BinaryArithOp::set_allocated_right_operand(::milvus::proto::plan::GenericValue* right_operand) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == nullptr) {
delete right_operand_;
}
if (right_operand) {
::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
if (message_arena != submessage_arena) {
right_operand = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
message_arena, right_operand, submessage_arena);
}
} else {
}
right_operand_ = right_operand;
// @@protoc_insertion_point(field_set_allocated:milvus.proto.plan.BinaryArithOp.right_operand)
}
// -------------------------------------------------------------------
// BinaryArithOpEvalRangeExpr
// .milvus.proto.plan.ColumnInfo column_info = 1;
inline bool BinaryArithOpEvalRangeExpr::has_column_info() const {
return this != internal_default_instance() && column_info_ != nullptr;
}
inline void BinaryArithOpEvalRangeExpr::clear_column_info() {
if (GetArenaNoVirtual() == nullptr && column_info_ != nullptr) {
delete column_info_;
}
column_info_ = nullptr;
}
inline const ::milvus::proto::plan::ColumnInfo& BinaryArithOpEvalRangeExpr::column_info() const {
const ::milvus::proto::plan::ColumnInfo* p = column_info_;
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info)
return p != nullptr ? *p : *reinterpret_cast<const ::milvus::proto::plan::ColumnInfo*>(
&::milvus::proto::plan::_ColumnInfo_default_instance_);
}
inline ::milvus::proto::plan::ColumnInfo* BinaryArithOpEvalRangeExpr::release_column_info() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info)
::milvus::proto::plan::ColumnInfo* temp = column_info_;
column_info_ = nullptr;
return temp;
}
inline ::milvus::proto::plan::ColumnInfo* BinaryArithOpEvalRangeExpr::mutable_column_info() {
if (column_info_ == nullptr) {
auto* p = CreateMaybeMessage<::milvus::proto::plan::ColumnInfo>(GetArenaNoVirtual());
column_info_ = p;
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info)
return column_info_;
}
inline void BinaryArithOpEvalRangeExpr::set_allocated_column_info(::milvus::proto::plan::ColumnInfo* column_info) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == nullptr) {
delete column_info_;
}
if (column_info) {
::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
if (message_arena != submessage_arena) {
column_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
message_arena, column_info, submessage_arena);
}
} else {
}
column_info_ = column_info;
// @@protoc_insertion_point(field_set_allocated:milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info)
}
// .milvus.proto.plan.ArithOpType arith_op = 2;
inline void BinaryArithOpEvalRangeExpr::clear_arith_op() {
arith_op_ = 0;
}
inline ::milvus::proto::plan::ArithOpType BinaryArithOpEvalRangeExpr::arith_op() const {
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOpEvalRangeExpr.arith_op)
return static_cast< ::milvus::proto::plan::ArithOpType >(arith_op_);
}
inline void BinaryArithOpEvalRangeExpr::set_arith_op(::milvus::proto::plan::ArithOpType value) {
arith_op_ = value;
// @@protoc_insertion_point(field_set:milvus.proto.plan.BinaryArithOpEvalRangeExpr.arith_op)
}
// .milvus.proto.plan.GenericValue right_operand = 3;
inline bool BinaryArithOpEvalRangeExpr::has_right_operand() const {
return this != internal_default_instance() && right_operand_ != nullptr;
}
inline void BinaryArithOpEvalRangeExpr::clear_right_operand() {
if (GetArenaNoVirtual() == nullptr && right_operand_ != nullptr) {
delete right_operand_;
}
right_operand_ = nullptr;
}
inline const ::milvus::proto::plan::GenericValue& BinaryArithOpEvalRangeExpr::right_operand() const {
const ::milvus::proto::plan::GenericValue* p = right_operand_;
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand)
return p != nullptr ? *p : *reinterpret_cast<const ::milvus::proto::plan::GenericValue*>(
&::milvus::proto::plan::_GenericValue_default_instance_);
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOpEvalRangeExpr::release_right_operand() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand)
::milvus::proto::plan::GenericValue* temp = right_operand_;
right_operand_ = nullptr;
return temp;
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOpEvalRangeExpr::mutable_right_operand() {
if (right_operand_ == nullptr) {
auto* p = CreateMaybeMessage<::milvus::proto::plan::GenericValue>(GetArenaNoVirtual());
right_operand_ = p;
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand)
return right_operand_;
}
inline void BinaryArithOpEvalRangeExpr::set_allocated_right_operand(::milvus::proto::plan::GenericValue* right_operand) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == nullptr) {
delete right_operand_;
}
if (right_operand) {
::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
if (message_arena != submessage_arena) {
right_operand = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
message_arena, right_operand, submessage_arena);
}
} else {
}
right_operand_ = right_operand;
// @@protoc_insertion_point(field_set_allocated:milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand)
}
// .milvus.proto.plan.OpType op = 4;
inline void BinaryArithOpEvalRangeExpr::clear_op() {
op_ = 0;
}
inline ::milvus::proto::plan::OpType BinaryArithOpEvalRangeExpr::op() const {
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOpEvalRangeExpr.op)
return static_cast< ::milvus::proto::plan::OpType >(op_);
}
inline void BinaryArithOpEvalRangeExpr::set_op(::milvus::proto::plan::OpType value) {
op_ = value;
// @@protoc_insertion_point(field_set:milvus.proto.plan.BinaryArithOpEvalRangeExpr.op)
}
// .milvus.proto.plan.GenericValue value = 5;
inline bool BinaryArithOpEvalRangeExpr::has_value() const {
return this != internal_default_instance() && value_ != nullptr;
}
inline void BinaryArithOpEvalRangeExpr::clear_value() {
if (GetArenaNoVirtual() == nullptr && value_ != nullptr) {
delete value_;
}
value_ = nullptr;
}
inline const ::milvus::proto::plan::GenericValue& BinaryArithOpEvalRangeExpr::value() const {
const ::milvus::proto::plan::GenericValue* p = value_;
// @@protoc_insertion_point(field_get:milvus.proto.plan.BinaryArithOpEvalRangeExpr.value)
return p != nullptr ? *p : *reinterpret_cast<const ::milvus::proto::plan::GenericValue*>(
&::milvus::proto::plan::_GenericValue_default_instance_);
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOpEvalRangeExpr::release_value() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.BinaryArithOpEvalRangeExpr.value)
::milvus::proto::plan::GenericValue* temp = value_;
value_ = nullptr;
return temp;
}
inline ::milvus::proto::plan::GenericValue* BinaryArithOpEvalRangeExpr::mutable_value() {
if (value_ == nullptr) {
auto* p = CreateMaybeMessage<::milvus::proto::plan::GenericValue>(GetArenaNoVirtual());
value_ = p;
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.BinaryArithOpEvalRangeExpr.value)
return value_;
}
inline void BinaryArithOpEvalRangeExpr::set_allocated_value(::milvus::proto::plan::GenericValue* value) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == nullptr) {
delete value_;
}
if (value) {
::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr;
if (message_arena != submessage_arena) {
value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
message_arena, value, submessage_arena);
}
} else {
}
value_ = value;
// @@protoc_insertion_point(field_set_allocated:milvus.proto.plan.BinaryArithOpEvalRangeExpr.value)
}
// -------------------------------------------------------------------
// Expr
// .milvus.proto.plan.TermExpr term_expr = 1;
@ -3573,6 +4246,47 @@ inline ::milvus::proto::plan::BinaryRangeExpr* Expr::mutable_binary_range_expr()
return expr_.binary_range_expr_;
}
// .milvus.proto.plan.BinaryArithOpEvalRangeExpr binary_arith_op_eval_range_expr = 7;
inline bool Expr::has_binary_arith_op_eval_range_expr() const {
return expr_case() == kBinaryArithOpEvalRangeExpr;
}
inline void Expr::set_has_binary_arith_op_eval_range_expr() {
_oneof_case_[0] = kBinaryArithOpEvalRangeExpr;
}
inline void Expr::clear_binary_arith_op_eval_range_expr() {
if (has_binary_arith_op_eval_range_expr()) {
delete expr_.binary_arith_op_eval_range_expr_;
clear_has_expr();
}
}
inline ::milvus::proto::plan::BinaryArithOpEvalRangeExpr* Expr::release_binary_arith_op_eval_range_expr() {
// @@protoc_insertion_point(field_release:milvus.proto.plan.Expr.binary_arith_op_eval_range_expr)
if (has_binary_arith_op_eval_range_expr()) {
clear_has_expr();
::milvus::proto::plan::BinaryArithOpEvalRangeExpr* temp = expr_.binary_arith_op_eval_range_expr_;
expr_.binary_arith_op_eval_range_expr_ = nullptr;
return temp;
} else {
return nullptr;
}
}
inline const ::milvus::proto::plan::BinaryArithOpEvalRangeExpr& Expr::binary_arith_op_eval_range_expr() const {
// @@protoc_insertion_point(field_get:milvus.proto.plan.Expr.binary_arith_op_eval_range_expr)
return has_binary_arith_op_eval_range_expr()
? *expr_.binary_arith_op_eval_range_expr_
: *reinterpret_cast< ::milvus::proto::plan::BinaryArithOpEvalRangeExpr*>(&::milvus::proto::plan::_BinaryArithOpEvalRangeExpr_default_instance_);
}
inline ::milvus::proto::plan::BinaryArithOpEvalRangeExpr* Expr::mutable_binary_arith_op_eval_range_expr() {
if (!has_binary_arith_op_eval_range_expr()) {
clear_expr();
set_has_binary_arith_op_eval_range_expr();
expr_.binary_arith_op_eval_range_expr_ = CreateMaybeMessage< ::milvus::proto::plan::BinaryArithOpEvalRangeExpr >(
GetArenaNoVirtual());
}
// @@protoc_insertion_point(field_mutable:milvus.proto.plan.Expr.binary_arith_op_eval_range_expr)
return expr_.binary_arith_op_eval_range_expr_;
}
inline bool Expr::has_expr() const {
return expr_case() != EXPR_NOT_SET;
}
@ -3917,6 +4631,10 @@ inline PlanNode::NodeCase PlanNode::node_case() const {
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// @@protoc_insertion_point(namespace_scope)
@ -3941,6 +4659,11 @@ template <>
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::plan::OpType>() {
return ::milvus::proto::plan::OpType_descriptor();
}
template <> struct is_proto_enum< ::milvus::proto::plan::ArithOpType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::plan::ArithOpType>() {
return ::milvus::proto::plan::ArithOpType_descriptor();
}
PROTOBUF_NAMESPACE_CLOSE

View File

@ -112,6 +112,49 @@ enum class OpType {
NotEqual = 6,
};
enum class ArithOpType {
Unknown = 0,
Add = 1,
Sub = 2,
Mul = 3,
Div = 4,
Mod = 5,
};
static const std::map<std::string, ArithOpType> arith_op_mapping_ = {
// arith_op_name -> arith_op
{"add", ArithOpType::Add}, {"sub", ArithOpType::Sub}, {"mul", ArithOpType::Mul},
{"div", ArithOpType::Div}, {"mod", ArithOpType::Mod},
};
static const std::map<ArithOpType, std::string> mapping_arith_op_ = {
// arith_op_name -> arith_op
{ArithOpType::Add, "add"}, {ArithOpType::Sub, "sub"}, {ArithOpType::Mul, "mul"},
{ArithOpType::Div, "div"}, {ArithOpType::Mod, "mod"},
};
struct BinaryArithOpEvalRangeExpr : Expr {
const FieldOffset field_offset_;
const DataType data_type_;
const OpType op_type_;
const ArithOpType arith_op_;
protected:
// prevent accidential instantiation
BinaryArithOpEvalRangeExpr() = delete;
BinaryArithOpEvalRangeExpr(const FieldOffset field_offset,
const DataType data_type,
const OpType op_type,
const ArithOpType arith_op)
: field_offset_(field_offset), data_type_(data_type), op_type_(op_type), arith_op_(arith_op) {
}
public:
void
accept(ExprVisitor&) override;
};
static const std::map<std::string, OpType> mapping_ = {
// op_name -> op
{"lt", OpType::LessThan}, {"le", OpType::LessEqual}, {"lte", OpType::LessEqual},

View File

@ -33,6 +33,23 @@ struct TermExprImpl : TermExpr {
}
};
template <typename T>
struct BinaryArithOpEvalRangeExprImpl : BinaryArithOpEvalRangeExpr {
const T right_operand_;
const T value_;
BinaryArithOpEvalRangeExprImpl(const FieldOffset field_offset,
const DataType data_type,
const ArithOpType arith_op,
const T right_operand,
const OpType op_type,
const T value)
: BinaryArithOpEvalRangeExpr(field_offset, data_type, op_type, arith_op),
right_operand_(right_operand),
value_(value) {
}
};
template <typename T>
struct UnaryRangeExprImpl : UnaryRangeExpr {
const T value_;

View File

@ -243,6 +243,65 @@ Parser::ParseRangeNodeImpl(const FieldName& field_name, const Json& body) {
auto item = body.begin();
auto op_name = boost::algorithm::to_lower_copy(std::string(item.key()));
AssertInfo(mapping_.count(op_name), "op(" + op_name + ") not found");
// This is an expression with an arithmetic operation
if (item.value().is_object()) {
/* // This is the expected DSL expression
{
range: {
field_name: {
op: {
arith_op: {
right_operand: operand,
value: value
},
}
}
}
}
EXAMPLE:
{
range: {
field_name: {
"EQ": {
"ADD": {
right_operand: 10,
value: 25
},
}
}
}
}
*/
auto arith = item.value();
auto arith_body = arith.begin();
auto arith_op_name = boost::algorithm::to_lower_copy(std::string(arith_body.key()));
AssertInfo(arith_op_mapping_.count(arith_op_name), "arith op(" + arith_op_name + ") not found");
auto& arith_op_body = arith_body.value();
Assert(arith_op_body.is_object());
auto right_operand = arith_op_body["right_operand"];
auto value = arith_op_body["value"];
if constexpr (std::is_same_v<T, bool>) {
throw std::runtime_error("bool type is not supported");
} else if constexpr (std::is_integral_v<T>) {
Assert(right_operand.is_number_integer());
Assert(value.is_number_integer());
} else if constexpr (std::is_floating_point_v<T>) {
Assert(right_operand.is_number());
Assert(value.is_number());
} else {
static_assert(always_false<T>, "unsupported type");
}
return std::make_unique<BinaryArithOpEvalRangeExprImpl<T>>(
schema.get_offset(field_name), schema[field_name].get_data_type(), arith_op_mapping_.at(arith_op_name),
right_operand, mapping_.at(op_name), value);
}
if constexpr (std::is_same_v<T, bool>) {
Assert(item.value().is_boolean());
} else if constexpr (std::is_integral_v<T>) {

View File

@ -89,6 +89,31 @@ ExtractBinaryRangeExprImpl(FieldOffset field_offset, DataType data_type, const p
getValue(expr_proto.upper_value()));
}
template <typename T>
std::unique_ptr<BinaryArithOpEvalRangeExprImpl<T>>
ExtractBinaryArithOpEvalRangeExprImpl(FieldOffset field_offset,
DataType data_type,
const planpb::BinaryArithOpEvalRangeExpr& expr_proto) {
static_assert(std::is_fundamental_v<T>);
auto getValue = [&](const auto& value_proto) -> T {
if constexpr (std::is_same_v<T, bool>) {
// Handle bool here. Otherwise, it can go in `is_integral_v<T>`
static_assert(always_false<T>);
} else if constexpr (std::is_integral_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kInt64Val);
return static_cast<T>(value_proto.int64_val());
} else if constexpr (std::is_floating_point_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kFloatVal);
return static_cast<T>(value_proto.float_val());
} else {
static_assert(always_false<T>);
}
};
return std::make_unique<BinaryArithOpEvalRangeExprImpl<T>>(
field_offset, data_type, static_cast<ArithOpType>(expr_proto.arith_op()), getValue(expr_proto.right_operand()),
static_cast<OpType>(expr_proto.op()), getValue(expr_proto.value()));
}
std::unique_ptr<VectorPlanNode>
ProtoParser::PlanNodeFromProto(const planpb::PlanNode& plan_node_proto) {
// TODO: add more buffs
@ -337,6 +362,42 @@ ProtoParser::ParseBinaryExpr(const proto::plan::BinaryExpr& expr_pb) {
return std::make_unique<LogicalBinaryExpr>(op, left_expr, right_expr);
}
ExprPtr
ProtoParser::ParseBinaryArithOpEvalRangeExpr(const proto::plan::BinaryArithOpEvalRangeExpr& expr_pb) {
auto& column_info = expr_pb.column_info();
auto field_id = FieldId(column_info.field_id());
auto field_offset = schema.get_offset(field_id);
auto data_type = schema[field_offset].get_data_type();
Assert(data_type == static_cast<DataType>(column_info.data_type()));
auto result = [&]() -> ExprPtr {
switch (data_type) {
case DataType::INT8: {
return ExtractBinaryArithOpEvalRangeExprImpl<int8_t>(field_offset, data_type, expr_pb);
}
case DataType::INT16: {
return ExtractBinaryArithOpEvalRangeExprImpl<int16_t>(field_offset, data_type, expr_pb);
}
case DataType::INT32: {
return ExtractBinaryArithOpEvalRangeExprImpl<int32_t>(field_offset, data_type, expr_pb);
}
case DataType::INT64: {
return ExtractBinaryArithOpEvalRangeExprImpl<int64_t>(field_offset, data_type, expr_pb);
}
case DataType::FLOAT: {
return ExtractBinaryArithOpEvalRangeExprImpl<float>(field_offset, data_type, expr_pb);
}
case DataType::DOUBLE: {
return ExtractBinaryArithOpEvalRangeExprImpl<double>(field_offset, data_type, expr_pb);
}
default: {
PanicInfo("unsupported data type");
}
}
}();
return result;
}
ExprPtr
ProtoParser::ParseExpr(const proto::plan::Expr& expr_pb) {
using ppe = proto::plan::Expr;
@ -359,6 +420,9 @@ ProtoParser::ParseExpr(const proto::plan::Expr& expr_pb) {
case ppe::kCompareExpr: {
return ParseCompareExpr(expr_pb.compare_expr());
}
case ppe::kBinaryArithOpEvalRangeExpr: {
return ParseBinaryArithOpEvalRangeExpr(expr_pb.binary_arith_op_eval_range_expr());
}
default:
PanicInfo("unsupported expr proto node");
}

View File

@ -29,6 +29,9 @@ class ProtoParser {
// ExprPtr
// ExprFromProto(const proto::plan::Expr& expr_proto);
ExprPtr
ParseBinaryArithOpEvalRangeExpr(const proto::plan::BinaryArithOpEvalRangeExpr& expr_pb);
ExprPtr
ParseUnaryRangeExpr(const proto::plan::UnaryRangeExpr& expr_pb);

View File

@ -35,6 +35,9 @@ class ExecExprVisitor : public ExprVisitor {
void
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryArithOpEvalRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
@ -61,10 +64,18 @@ class ExecExprVisitor : public ExprVisitor {
auto
ExecRangeVisitorImpl(FieldOffset field_offset, IndexFunc func, ElementFunc element_func) -> BitsetType;
template <typename T, typename ElementFunc>
auto
ExecDataRangeVisitorImpl(FieldOffset field_offset, ElementFunc element_func) -> BitsetType;
template <typename T>
auto
ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> BitsetType;
template <typename T>
auto
ExecBinaryArithOpEvalRangeVisitorDispatcher(BinaryArithOpEvalRangeExpr& expr_raw) -> BitsetType;
template <typename T>
auto
ExecBinaryRangeVisitorDispatcher(BinaryRangeExpr& expr_raw) -> BitsetType;

View File

@ -35,6 +35,10 @@ UnaryRangeExpr::accept(ExprVisitor& visitor) {
visitor.visit(*this);
}
void
BinaryArithOpEvalRangeExpr::accept(ExprVisitor& visitor) {
visitor.visit(*this);
}
void
BinaryRangeExpr::accept(ExprVisitor& visitor) {
visitor.visit(*this);

View File

@ -31,6 +31,9 @@ class ExprVisitor {
virtual void
visit(UnaryRangeExpr&) = 0;
virtual void
visit(BinaryArithOpEvalRangeExpr&) = 0;
virtual void
visit(BinaryRangeExpr&) = 0;

View File

@ -30,6 +30,9 @@ class ExtractInfoExprVisitor : public ExprVisitor {
void
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryArithOpEvalRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;

View File

@ -31,6 +31,9 @@ class ShowExprVisitor : public ExprVisitor {
void
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryArithOpEvalRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
@ -39,6 +42,7 @@ class ShowExprVisitor : public ExprVisitor {
public:
Json
call_child(Expr& expr) {
assert(!json_opt_.has_value());
expr.accept(*this);

View File

@ -35,6 +35,9 @@ class VerifyExprVisitor : public ExprVisitor {
void
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryArithOpEvalRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;

View File

@ -48,6 +48,10 @@ class ExecExprVisitor : ExprVisitor {
auto
ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> BitsetType;
template <typename T>
auto
ExecBinaryArithOpEvalRangeVisitorDispatcher(BinaryArithOpEvalRangeExpr& expr_raw) -> BitsetType;
template <typename T>
auto
ExecBinaryRangeVisitorDispatcher(BinaryRangeExpr& expr_raw) -> BitsetType;
@ -174,6 +178,31 @@ ExecExprVisitor::ExecRangeVisitorImpl(FieldOffset field_offset, IndexFunc index_
return final_result;
}
template <typename T, typename ElementFunc>
auto
ExecExprVisitor::ExecDataRangeVisitorImpl(FieldOffset field_offset, ElementFunc element_func) -> BitsetType {
auto& schema = segment_.get_schema();
auto& field_meta = schema[field_offset];
auto size_per_chunk = segment_.size_per_chunk();
auto num_chunk = upper_div(row_count_, size_per_chunk);
std::deque<BitsetType> results;
for (auto chunk_id = 0; chunk_id < num_chunk; ++chunk_id) {
auto this_size = chunk_id == num_chunk - 1 ? row_count_ - chunk_id * size_per_chunk : size_per_chunk;
BitsetType result(this_size);
auto chunk = segment_.chunk_data<T>(field_offset, chunk_id);
const T* data = chunk.data();
for (int index = 0; index < this_size; ++index) {
result[index] = element_func(data[index]);
}
AssertInfo(result.size() == this_size, "[ExecExprVisitor]Chunk result size not equal to expected size");
results.emplace_back(std::move(result));
}
auto final_result = Assemble(results);
AssertInfo(final_result.size() == row_count_, "[ExecExprVisitor]Final result size not equal to row count");
return final_result;
}
#pragma clang diagnostic push
#pragma ide diagnostic ignored "Simplify"
template <typename T>
@ -222,6 +251,84 @@ ExecExprVisitor::ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> Bi
}
#pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma ide diagnostic ignored "Simplify"
template <typename T>
auto
ExecExprVisitor::ExecBinaryArithOpEvalRangeVisitorDispatcher(BinaryArithOpEvalRangeExpr& expr_raw) -> BitsetType {
auto& expr = static_cast<BinaryArithOpEvalRangeExprImpl<T>&>(expr_raw);
using Index = scalar::ScalarIndex<T>;
auto arith_op = expr.arith_op_;
auto right_operand = expr.right_operand_;
auto op = expr.op_type_;
auto val = expr.value_;
switch (op) {
case OpType::Equal: {
switch (arith_op) {
case ArithOpType::Add: {
auto elem_func = [val, right_operand](T x) { return ((x + right_operand) == val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Sub: {
auto elem_func = [val, right_operand](T x) { return ((x - right_operand) == val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Mul: {
auto elem_func = [val, right_operand](T x) { return ((x * right_operand) == val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Div: {
auto elem_func = [val, right_operand](T x) { return ((x / right_operand) == val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Mod: {
auto elem_func = [val, right_operand](T x) {
return (static_cast<T>(fmod(x, right_operand)) == val);
};
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
default: {
PanicInfo("unsupported arithmetic operation");
}
}
}
case OpType::NotEqual: {
switch (arith_op) {
case ArithOpType::Add: {
auto elem_func = [val, right_operand](T x) { return ((x + right_operand) != val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Sub: {
auto elem_func = [val, right_operand](T x) { return ((x - right_operand) != val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Mul: {
auto elem_func = [val, right_operand](T x) { return ((x * right_operand) != val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Div: {
auto elem_func = [val, right_operand](T x) { return ((x / right_operand) != val); };
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
case ArithOpType::Mod: {
auto elem_func = [val, right_operand](T x) {
return (static_cast<T>(fmod(x, right_operand)) != val);
};
return ExecDataRangeVisitorImpl<T>(expr.field_offset_, elem_func);
}
default: {
PanicInfo("unsupported arithmetic operation");
}
}
}
default: {
PanicInfo("unsupported range node with arithmetic operation");
}
}
}
#pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma ide diagnostic ignored "Simplify"
template <typename T>
@ -297,6 +404,44 @@ ExecExprVisitor::visit(UnaryRangeExpr& expr) {
bitset_opt_ = std::move(res);
}
void
ExecExprVisitor::visit(BinaryArithOpEvalRangeExpr& expr) {
auto& field_meta = segment_.get_schema()[expr.field_offset_];
AssertInfo(expr.data_type_ == field_meta.get_data_type(),
"[ExecExprVisitor]DataType of expr isn't field_meta data type");
BitsetType res;
switch (expr.data_type_) {
case DataType::INT8: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<int8_t>(expr);
break;
}
case DataType::INT16: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<int16_t>(expr);
break;
}
case DataType::INT32: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<int32_t>(expr);
break;
}
case DataType::INT64: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<int64_t>(expr);
break;
}
case DataType::FLOAT: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<float>(expr);
break;
}
case DataType::DOUBLE: {
res = ExecBinaryArithOpEvalRangeVisitorDispatcher<double>(expr);
break;
}
default:
PanicInfo("unsupported");
}
AssertInfo(res.size() == row_count_, "[ExecExprVisitor]Size of results not equal row count");
bitset_opt_ = std::move(res);
}
void
ExecExprVisitor::visit(BinaryRangeExpr& expr) {
auto& field_meta = segment_.get_schema()[expr.field_offset_];

View File

@ -59,4 +59,9 @@ ExtractInfoExprVisitor::visit(CompareExpr& expr) {
plan_info_.add_involved_field(expr.right_field_offset_);
}
void
ExtractInfoExprVisitor::visit(BinaryArithOpEvalRangeExpr& expr) {
plan_info_.add_involved_field(expr.field_offset_);
}
} // namespace milvus::query

View File

@ -248,4 +248,53 @@ ShowExprVisitor::visit(CompareExpr& expr) {
json_opt_ = res;
}
template <typename T>
static Json
BinaryArithOpEvalRangeExtract(const BinaryArithOpEvalRangeExpr& expr_raw) {
using proto::plan::ArithOpType;
using proto::plan::ArithOpType_Name;
using proto::plan::OpType;
using proto::plan::OpType_Name;
auto expr = dynamic_cast<const BinaryArithOpEvalRangeExprImpl<T>*>(&expr_raw);
AssertInfo(expr, "[ShowExprVisitor]BinaryArithOpEvalRangeExpr cast to BinaryArithOpEvalRangeExprImpl failed");
Json res{{"expr_type", "BinaryArithOpEvalRange"},
{"field_offset", expr->field_offset_.get()},
{"data_type", datatype_name(expr->data_type_)},
{"arith_op", ArithOpType_Name(static_cast<ArithOpType>(expr->arith_op_))},
{"right_operand", expr->right_operand_},
{"op", OpType_Name(static_cast<OpType>(expr->op_type_))},
{"value", expr->value_}};
return res;
}
void
ShowExprVisitor::visit(BinaryArithOpEvalRangeExpr& expr) {
AssertInfo(!json_opt_.has_value(), "[ShowExprVisitor]Ret json already has value before visit");
AssertInfo(datatype_is_vector(expr.data_type_) == false, "[ShowExprVisitor]Data type of expr isn't vector type");
switch (expr.data_type_) {
case DataType::INT8:
json_opt_ = BinaryArithOpEvalRangeExtract<int8_t>(expr);
return;
case DataType::INT16:
json_opt_ = BinaryArithOpEvalRangeExtract<int16_t>(expr);
return;
case DataType::INT32:
json_opt_ = BinaryArithOpEvalRangeExtract<int32_t>(expr);
return;
case DataType::INT64:
json_opt_ = BinaryArithOpEvalRangeExtract<int64_t>(expr);
return;
case DataType::DOUBLE:
json_opt_ = BinaryArithOpEvalRangeExtract<double>(expr);
return;
case DataType::FLOAT:
json_opt_ = BinaryArithOpEvalRangeExtract<float>(expr);
return;
default:
PanicInfo("unsupported type");
}
}
} // namespace milvus::query

View File

@ -32,6 +32,11 @@ VerifyExprVisitor::visit(UnaryRangeExpr& expr) {
// TODO
}
void
VerifyExprVisitor::visit(BinaryArithOpEvalRangeExpr& expr) {
// TODO
}
void
VerifyExprVisitor::visit(BinaryRangeExpr& expr) {
// TODO

View File

@ -581,3 +581,364 @@ TEST(Expr, TestCompare) {
}
}
}
TEST(Expr, TestBinaryArithOpEvalRange) {
using namespace milvus::query;
using namespace milvus::segcore;
std::vector<std::tuple<std::string, std::function<bool(int)>, DataType>> testcases = {
// Add test cases for BinaryArithOpEvalRangeExpr EQ of various data types
{R"("EQ": {
"ADD": {
"right_operand": 4,
"value": 8
}
})", [](int8_t v) { return (v + 4) == 8; }, DataType::INT8},
{R"("EQ": {
"SUB": {
"right_operand": 500,
"value": 1500
}
})", [](int16_t v) { return (v - 500) == 1500; }, DataType::INT16},
{R"("EQ": {
"MUL": {
"right_operand": 2,
"value": 4000
}
})", [](int32_t v) { return (v * 2) == 4000; }, DataType::INT32},
{R"("EQ": {
"DIV": {
"right_operand": 2,
"value": 1000
}
})", [](int64_t v) { return (v / 2) == 1000; }, DataType::INT64},
{R"("EQ": {
"MOD": {
"right_operand": 100,
"value": 0
}
})", [](int32_t v) { return (v % 100) == 0; }, DataType::INT32},
{R"("EQ": {
"ADD": {
"right_operand": 500,
"value": 2500
}
})", [](float v) { return (v + 500) == 2500; }, DataType::FLOAT},
{R"("EQ": {
"ADD": {
"right_operand": 500,
"value": 2500
}
})", [](double v) { return (v + 500) == 2500; }, DataType::DOUBLE},
// Add test cases for BinaryArithOpEvalRangeExpr NE of various data types
{R"("NE": {
"ADD": {
"right_operand": 500,
"value": 2500
}
})", [](float v) { return (v + 500) != 2500; }, DataType::FLOAT},
{R"("NE": {
"SUB": {
"right_operand": 500,
"value": 2500
}
})", [](double v) { return (v - 500) != 2500; }, DataType::DOUBLE},
{R"("NE": {
"MUL": {
"right_operand": 2,
"value": 2
}
})", [](int8_t v) { return (v * 2) != 2; }, DataType::INT8},
{R"("NE": {
"DIV": {
"right_operand": 2,
"value": 1000
}
})", [](int16_t v) { return (v / 2) != 1000; }, DataType::INT16},
{R"("NE": {
"MOD": {
"right_operand": 100,
"value": 0
}
})", [](int32_t v) { return (v % 100) != 0; }, DataType::INT32},
{R"("NE": {
"ADD": {
"right_operand": 500,
"value": 2500
}
})", [](int64_t v) { return (v + 500) != 2500; }, DataType::INT64},
};
std::string dsl_string_tmp = R"({
"bool": {
"must": [
{
"range": {
@@@@@
}
},
{
"vector": {
"fakevec": {
"metric_type": "L2",
"params": {
"nprobe": 10
},
"query": "$0",
"topk": 10,
"round_decimal": 3
}
}
}
]
}
})";
std::string dsl_string_int8 = R"(
"age8": {
@@@@
})";
std::string dsl_string_int16 = R"(
"age16": {
@@@@
})";
std::string dsl_string_int32 = R"(
"age32": {
@@@@
})";
std::string dsl_string_int64 = R"(
"age64": {
@@@@
})";
std::string dsl_string_float = R"(
"age_float": {
@@@@
})";
std::string dsl_string_double = R"(
"age_double": {
@@@@
})";
auto schema = std::make_shared<Schema>();
schema->AddDebugField("fakevec", DataType::VECTOR_FLOAT, 16, MetricType::METRIC_L2);
schema->AddDebugField("age8", DataType::INT8);
schema->AddDebugField("age16", DataType::INT16);
schema->AddDebugField("age32", DataType::INT32);
schema->AddDebugField("age64", DataType::INT64);
schema->AddDebugField("age_float", DataType::FLOAT);
schema->AddDebugField("age_double", DataType::DOUBLE);
auto seg = CreateGrowingSegment(schema);
int N = 1000;
std::vector<int8_t> age8_col;
std::vector<int16_t> age16_col;
std::vector<int32_t> age32_col;
std::vector<int64_t> age64_col;
std::vector<float> age_float_col;
std::vector<double> age_double_col;
int num_iters = 100;
for (int iter = 0; iter < num_iters; ++iter) {
auto raw_data = DataGen(schema, N, iter);
auto new_age8_col = raw_data.get_col<int8_t>(1);
auto new_age16_col = raw_data.get_col<int16_t>(2);
auto new_age32_col = raw_data.get_col<int32_t>(3);
auto new_age64_col = raw_data.get_col<int64_t>(4);
auto new_age_float_col = raw_data.get_col<float>(5);
auto new_age_double_col = raw_data.get_col<double>(6);
age8_col.insert(age8_col.end(), new_age8_col.begin(), new_age8_col.end());
age16_col.insert(age16_col.end(), new_age16_col.begin(), new_age16_col.end());
age32_col.insert(age32_col.end(), new_age32_col.begin(), new_age32_col.end());
age64_col.insert(age64_col.end(), new_age64_col.begin(), new_age64_col.end());
age_float_col.insert(age_float_col.end(), new_age_float_col.begin(), new_age_float_col.end());
age_double_col.insert(age_double_col.end(), new_age_double_col.begin(), new_age_double_col.end());
seg->PreInsert(N);
seg->Insert(iter * N, N, raw_data.row_ids_.data(), raw_data.timestamps_.data(), raw_data.raw_);
}
auto seg_promote = dynamic_cast<SegmentGrowingImpl*>(seg.get());
ExecExprVisitor visitor(*seg_promote, seg_promote->get_row_count(), MAX_TIMESTAMP);
for (auto [clause, ref_func, dtype] : testcases) {
auto loc = dsl_string_tmp.find("@@@@@");
auto dsl_string = dsl_string_tmp;
if (dtype == DataType::INT8) {
dsl_string.replace(loc, 5, dsl_string_int8);
} else if (dtype == DataType::INT16) {
dsl_string.replace(loc, 5, dsl_string_int16);
} else if (dtype == DataType::INT32) {
dsl_string.replace(loc, 5, dsl_string_int32);
} else if (dtype == DataType::INT64) {
dsl_string.replace(loc, 5, dsl_string_int64);
} else if (dtype == DataType::FLOAT) {
dsl_string.replace(loc, 5, dsl_string_float);
} else if (dtype == DataType::DOUBLE) {
dsl_string.replace(loc, 5, dsl_string_double);
} else {
ASSERT_TRUE(false) << "No test case defined for this data type";
}
loc = dsl_string.find("@@@@");
dsl_string.replace(loc, 4, clause);
auto plan = CreatePlan(*schema, dsl_string);
auto final = visitor.call_child(*plan->plan_node_->predicate_.value());
EXPECT_EQ(final.size(), N * num_iters);
for (int i = 0; i < N * num_iters; ++i) {
auto ans = final[i];
if (dtype == DataType::INT8) {
auto val = age8_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else if (dtype == DataType::INT16) {
auto val = age16_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else if (dtype == DataType::INT32) {
auto val = age32_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else if (dtype == DataType::INT64) {
auto val = age64_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else if (dtype == DataType::FLOAT) {
auto val = age_float_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else if (dtype == DataType::DOUBLE) {
auto val = age_double_col[i];
auto ref = ref_func(val);
ASSERT_EQ(ans, ref) << clause << "@" << i << "!!" << val;
} else {
ASSERT_TRUE(false) << "No test case defined for this data type";
}
}
}
}
TEST(Expr, TestBinaryArithOpEvalRangeExceptions) {
using namespace milvus::query;
using namespace milvus::segcore;
std::vector<std::tuple<std::string, std::string, DataType>> testcases = {
// Add test for data type mismatch
{R"("EQ": {
"ADD": {
"right_operand": 500,
"value": 2500.00
}
})", "Assert \"(value.is_number_integer())\"", DataType::INT32},
{R"("EQ": {
"ADD": {
"right_operand": 500.0,
"value": 2500
}
})", "Assert \"(right_operand.is_number_integer())\"", DataType::INT32},
{R"("EQ": {
"ADD": {
"right_operand": 500.0,
"value": true
}
})", "Assert \"(value.is_number())\"", DataType::FLOAT},
{R"("EQ": {
"ADD": {
"right_operand": "500",
"value": 2500.0
}
})", "Assert \"(right_operand.is_number())\"", DataType::FLOAT},
// Check unsupported arithmetic operator type
{R"("EQ": {
"EXP": {
"right_operand": 500,
"value": 2500
}
})", "arith op(exp) not found", DataType::INT32},
// Check unsupported data type
{R"("EQ": {
"ADD": {
"right_operand": true,
"value": false
}
})", "bool type is not supported", DataType::BOOL},
};
std::string dsl_string_tmp = R"({
"bool": {
"must": [
{
"range": {
@@@@@
}
},
{
"vector": {
"fakevec": {
"metric_type": "L2",
"params": {
"nprobe": 10
},
"query": "$0",
"topk": 10,
"round_decimal": 3
}
}
}
]
}
})";
std::string dsl_string_int = R"(
"age": {
@@@@
})";
std::string dsl_string_num = R"(
"FloatN": {
@@@@
})";
std::string dsl_string_bool = R"(
"BoolField": {
@@@@
})";
auto schema = std::make_shared<Schema>();
schema->AddDebugField("fakevec", DataType::VECTOR_FLOAT, 16, MetricType::METRIC_L2);
schema->AddDebugField("age", DataType::INT32);
schema->AddDebugField("FloatN", DataType::FLOAT);
schema->AddDebugField("BoolField", DataType::BOOL);
for (auto [clause, assert_info, dtype] : testcases) {
auto loc = dsl_string_tmp.find("@@@@@");
auto dsl_string = dsl_string_tmp;
if (dtype == DataType::INT32) {
dsl_string.replace(loc, 5, dsl_string_int);
} else if (dtype == DataType::FLOAT) {
dsl_string.replace(loc, 5, dsl_string_num);
} else if (dtype == DataType::BOOL) {
dsl_string.replace(loc, 5, dsl_string_bool);
} else {
ASSERT_TRUE(false) << "No test case defined for this data type";
}
loc = dsl_string.find("@@@@");
dsl_string.replace(loc, 4, clause);
try {
auto plan = CreatePlan(*schema, dsl_string);
FAIL() << "Expected AssertionError: " << assert_info << " not thrown";
}
catch(const std::exception& err) {
std::string err_msg = err.what();
ASSERT_TRUE(err_msg.find(assert_info) != std::string::npos);
}
catch(...) {
FAIL() << "Expected AssertionError: " << assert_info << " not thrown";
}
}
}

View File

@ -543,4 +543,96 @@ vector_anns: <
auto ref_plan = CreatePlan(*schema, dsl_text);
plan->check_identical(*ref_plan);
}
}
TEST_P(PlanProtoTest, BinaryArithOpEvalRange) {
// xxx.query(predicates = "int64field > 3", topk = 10, ...)
auto data_type = std::get<0>(GetParam());
auto data_type_str = spb::DataType_Name(data_type);
auto field_id = 100 + (int)data_type;
auto field_name = data_type_str + "Field";
string value_tag = "bool_val";
if (datatype_is_floating((DataType)data_type)) {
value_tag = "float_val";
} else if (datatype_is_integer((DataType)data_type)) {
value_tag = "int64_val";
}
auto fmt1 = boost::format(R"(
vector_anns: <
field_id: 201
predicates: <
binary_arith_op_eval_range_expr: <
column_info: <
field_id: %1%
data_type: %2%
>
arith_op: Add
right_operand: <
%3%: 1029
>
op: Equal
value: <
%3%: 2016
>
>
>
query_info: <
topk: 10
round_decimal: 3
metric_type: "L2"
search_params: "{\"nprobe\": 10}"
>
placeholder_tag: "$0"
>
)") % field_id % data_type_str %
value_tag;
auto proto_text = fmt1.str();
planpb::PlanNode node_proto;
google::protobuf::TextFormat::ParseFromString(proto_text, &node_proto);
// std::cout << node_proto.DebugString();
auto plan = ProtoParser(*schema).CreatePlan(node_proto);
ShowPlanNodeVisitor visitor;
auto json = visitor.call_child(*plan->plan_node_);
// std::cout << json.dump(2);
auto extra_info = plan->extra_info_opt_.value();
std::string dsl_text = boost::str(boost::format(R"(
{
"bool": {
"must": [
{
"range": {
"%1%": {
"EQ": {
"ADD": {
"right_operand": 1029,
"value": 2016
}
}
}
}
},
{
"vector": {
"FloatVectorField": {
"metric_type": "L2",
"params": {
"nprobe": 10
},
"query": "$0",
"topk": 10,
"round_decimal": 3
}
}
}
]
}
}
)") % field_name);
auto ref_plan = CreatePlan(*schema, dsl_text);
plan->check_identical(*ref_plan);
}

View File

@ -168,6 +168,22 @@ DataGen(SchemaPtr schema, int64_t N, uint64_t seed = 42, uint64_t ts_offset = 0)
insert_cols(data);
break;
}
case engine::DataType::INT16: {
vector<int16_t> data(N);
for (auto& x : data) {
x = er() % (2 * N);
}
insert_cols(data);
break;
}
case engine::DataType::INT8: {
vector<int8_t> data(N);
for (auto& x : data) {
x = er() % (2 * N);
}
insert_cols(data);
break;
}
case engine::DataType::FLOAT: {
vector<float> data(N);
for (auto& x : data) {

View File

@ -14,6 +14,15 @@ enum OpType {
NotEqual = 6;
};
enum ArithOpType {
Unknown = 0;
Add = 1;
Sub = 2;
Mul = 3;
Div = 4;
Mod = 5;
};
message GenericValue {
oneof val {
bool bool_val = 1;
@ -82,6 +91,20 @@ message BinaryExpr {
Expr right = 3;
}
message BinaryArithOp {
ColumnInfo column_info = 1;
ArithOpType arith_op = 2;
GenericValue right_operand = 3;
}
message BinaryArithOpEvalRangeExpr {
ColumnInfo column_info = 1;
ArithOpType arith_op = 2;
GenericValue right_operand = 3;
OpType op = 4;
GenericValue value = 5;
}
message Expr {
oneof expr {
TermExpr term_expr = 1;
@ -90,6 +113,7 @@ message Expr {
CompareExpr compare_expr = 4;
UnaryRangeExpr unary_range_expr = 5;
BinaryRangeExpr binary_range_expr = 6;
BinaryArithOpEvalRangeExpr binary_arith_op_eval_range_expr = 7;
};
}

View File

@ -61,6 +61,43 @@ func (OpType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{0}
}
type ArithOpType int32
const (
ArithOpType_Unknown ArithOpType = 0
ArithOpType_Add ArithOpType = 1
ArithOpType_Sub ArithOpType = 2
ArithOpType_Mul ArithOpType = 3
ArithOpType_Div ArithOpType = 4
ArithOpType_Mod ArithOpType = 5
)
var ArithOpType_name = map[int32]string{
0: "Unknown",
1: "Add",
2: "Sub",
3: "Mul",
4: "Div",
5: "Mod",
}
var ArithOpType_value = map[string]int32{
"Unknown": 0,
"Add": 1,
"Sub": 2,
"Mul": 3,
"Div": 4,
"Mod": 5,
}
func (x ArithOpType) String() string {
return proto.EnumName(ArithOpType_name, int32(x))
}
func (ArithOpType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{1}
}
type UnaryExpr_UnaryOp int32
const (
@ -680,6 +717,132 @@ func (m *BinaryExpr) GetRight() *Expr {
return nil
}
type BinaryArithOp struct {
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
ArithOp ArithOpType `protobuf:"varint,2,opt,name=arith_op,json=arithOp,proto3,enum=milvus.proto.plan.ArithOpType" json:"arith_op,omitempty"`
RightOperand *GenericValue `protobuf:"bytes,3,opt,name=right_operand,json=rightOperand,proto3" json:"right_operand,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BinaryArithOp) Reset() { *m = BinaryArithOp{} }
func (m *BinaryArithOp) String() string { return proto.CompactTextString(m) }
func (*BinaryArithOp) ProtoMessage() {}
func (*BinaryArithOp) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{9}
}
func (m *BinaryArithOp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BinaryArithOp.Unmarshal(m, b)
}
func (m *BinaryArithOp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BinaryArithOp.Marshal(b, m, deterministic)
}
func (m *BinaryArithOp) XXX_Merge(src proto.Message) {
xxx_messageInfo_BinaryArithOp.Merge(m, src)
}
func (m *BinaryArithOp) XXX_Size() int {
return xxx_messageInfo_BinaryArithOp.Size(m)
}
func (m *BinaryArithOp) XXX_DiscardUnknown() {
xxx_messageInfo_BinaryArithOp.DiscardUnknown(m)
}
var xxx_messageInfo_BinaryArithOp proto.InternalMessageInfo
func (m *BinaryArithOp) GetColumnInfo() *ColumnInfo {
if m != nil {
return m.ColumnInfo
}
return nil
}
func (m *BinaryArithOp) GetArithOp() ArithOpType {
if m != nil {
return m.ArithOp
}
return ArithOpType_Unknown
}
func (m *BinaryArithOp) GetRightOperand() *GenericValue {
if m != nil {
return m.RightOperand
}
return nil
}
type BinaryArithOpEvalRangeExpr struct {
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
ArithOp ArithOpType `protobuf:"varint,2,opt,name=arith_op,json=arithOp,proto3,enum=milvus.proto.plan.ArithOpType" json:"arith_op,omitempty"`
RightOperand *GenericValue `protobuf:"bytes,3,opt,name=right_operand,json=rightOperand,proto3" json:"right_operand,omitempty"`
Op OpType `protobuf:"varint,4,opt,name=op,proto3,enum=milvus.proto.plan.OpType" json:"op,omitempty"`
Value *GenericValue `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BinaryArithOpEvalRangeExpr) Reset() { *m = BinaryArithOpEvalRangeExpr{} }
func (m *BinaryArithOpEvalRangeExpr) String() string { return proto.CompactTextString(m) }
func (*BinaryArithOpEvalRangeExpr) ProtoMessage() {}
func (*BinaryArithOpEvalRangeExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{10}
}
func (m *BinaryArithOpEvalRangeExpr) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BinaryArithOpEvalRangeExpr.Unmarshal(m, b)
}
func (m *BinaryArithOpEvalRangeExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BinaryArithOpEvalRangeExpr.Marshal(b, m, deterministic)
}
func (m *BinaryArithOpEvalRangeExpr) XXX_Merge(src proto.Message) {
xxx_messageInfo_BinaryArithOpEvalRangeExpr.Merge(m, src)
}
func (m *BinaryArithOpEvalRangeExpr) XXX_Size() int {
return xxx_messageInfo_BinaryArithOpEvalRangeExpr.Size(m)
}
func (m *BinaryArithOpEvalRangeExpr) XXX_DiscardUnknown() {
xxx_messageInfo_BinaryArithOpEvalRangeExpr.DiscardUnknown(m)
}
var xxx_messageInfo_BinaryArithOpEvalRangeExpr proto.InternalMessageInfo
func (m *BinaryArithOpEvalRangeExpr) GetColumnInfo() *ColumnInfo {
if m != nil {
return m.ColumnInfo
}
return nil
}
func (m *BinaryArithOpEvalRangeExpr) GetArithOp() ArithOpType {
if m != nil {
return m.ArithOp
}
return ArithOpType_Unknown
}
func (m *BinaryArithOpEvalRangeExpr) GetRightOperand() *GenericValue {
if m != nil {
return m.RightOperand
}
return nil
}
func (m *BinaryArithOpEvalRangeExpr) GetOp() OpType {
if m != nil {
return m.Op
}
return OpType_Invalid
}
func (m *BinaryArithOpEvalRangeExpr) GetValue() *GenericValue {
if m != nil {
return m.Value
}
return nil
}
type Expr struct {
// Types that are valid to be assigned to Expr:
// *Expr_TermExpr
@ -688,6 +851,7 @@ type Expr struct {
// *Expr_CompareExpr
// *Expr_UnaryRangeExpr
// *Expr_BinaryRangeExpr
// *Expr_BinaryArithOpEvalRangeExpr
Expr isExpr_Expr `protobuf_oneof:"expr"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -698,7 +862,7 @@ func (m *Expr) Reset() { *m = Expr{} }
func (m *Expr) String() string { return proto.CompactTextString(m) }
func (*Expr) ProtoMessage() {}
func (*Expr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{9}
return fileDescriptor_2d655ab2f7683c23, []int{11}
}
func (m *Expr) XXX_Unmarshal(b []byte) error {
@ -747,6 +911,10 @@ type Expr_BinaryRangeExpr struct {
BinaryRangeExpr *BinaryRangeExpr `protobuf:"bytes,6,opt,name=binary_range_expr,json=binaryRangeExpr,proto3,oneof"`
}
type Expr_BinaryArithOpEvalRangeExpr struct {
BinaryArithOpEvalRangeExpr *BinaryArithOpEvalRangeExpr `protobuf:"bytes,7,opt,name=binary_arith_op_eval_range_expr,json=binaryArithOpEvalRangeExpr,proto3,oneof"`
}
func (*Expr_TermExpr) isExpr_Expr() {}
func (*Expr_UnaryExpr) isExpr_Expr() {}
@ -759,6 +927,8 @@ func (*Expr_UnaryRangeExpr) isExpr_Expr() {}
func (*Expr_BinaryRangeExpr) isExpr_Expr() {}
func (*Expr_BinaryArithOpEvalRangeExpr) isExpr_Expr() {}
func (m *Expr) GetExpr() isExpr_Expr {
if m != nil {
return m.Expr
@ -808,6 +978,13 @@ func (m *Expr) GetBinaryRangeExpr() *BinaryRangeExpr {
return nil
}
func (m *Expr) GetBinaryArithOpEvalRangeExpr() *BinaryArithOpEvalRangeExpr {
if x, ok := m.GetExpr().(*Expr_BinaryArithOpEvalRangeExpr); ok {
return x.BinaryArithOpEvalRangeExpr
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*Expr) XXX_OneofWrappers() []interface{} {
return []interface{}{
@ -817,6 +994,7 @@ func (*Expr) XXX_OneofWrappers() []interface{} {
(*Expr_CompareExpr)(nil),
(*Expr_UnaryRangeExpr)(nil),
(*Expr_BinaryRangeExpr)(nil),
(*Expr_BinaryArithOpEvalRangeExpr)(nil),
}
}
@ -835,7 +1013,7 @@ func (m *VectorANNS) Reset() { *m = VectorANNS{} }
func (m *VectorANNS) String() string { return proto.CompactTextString(m) }
func (*VectorANNS) ProtoMessage() {}
func (*VectorANNS) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{10}
return fileDescriptor_2d655ab2f7683c23, []int{12}
}
func (m *VectorANNS) XXX_Unmarshal(b []byte) error {
@ -906,7 +1084,7 @@ func (m *PlanNode) Reset() { *m = PlanNode{} }
func (m *PlanNode) String() string { return proto.CompactTextString(m) }
func (*PlanNode) ProtoMessage() {}
func (*PlanNode) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{11}
return fileDescriptor_2d655ab2f7683c23, []int{13}
}
func (m *PlanNode) XXX_Unmarshal(b []byte) error {
@ -981,6 +1159,7 @@ func (*PlanNode) XXX_OneofWrappers() []interface{} {
func init() {
proto.RegisterEnum("milvus.proto.plan.OpType", OpType_name, OpType_value)
proto.RegisterEnum("milvus.proto.plan.ArithOpType", ArithOpType_name, ArithOpType_value)
proto.RegisterEnum("milvus.proto.plan.UnaryExpr_UnaryOp", UnaryExpr_UnaryOp_name, UnaryExpr_UnaryOp_value)
proto.RegisterEnum("milvus.proto.plan.BinaryExpr_BinaryOp", BinaryExpr_BinaryOp_name, BinaryExpr_BinaryOp_value)
proto.RegisterType((*GenericValue)(nil), "milvus.proto.plan.GenericValue")
@ -992,6 +1171,8 @@ func init() {
proto.RegisterType((*TermExpr)(nil), "milvus.proto.plan.TermExpr")
proto.RegisterType((*UnaryExpr)(nil), "milvus.proto.plan.UnaryExpr")
proto.RegisterType((*BinaryExpr)(nil), "milvus.proto.plan.BinaryExpr")
proto.RegisterType((*BinaryArithOp)(nil), "milvus.proto.plan.BinaryArithOp")
proto.RegisterType((*BinaryArithOpEvalRangeExpr)(nil), "milvus.proto.plan.BinaryArithOpEvalRangeExpr")
proto.RegisterType((*Expr)(nil), "milvus.proto.plan.Expr")
proto.RegisterType((*VectorANNS)(nil), "milvus.proto.plan.VectorANNS")
proto.RegisterType((*PlanNode)(nil), "milvus.proto.plan.PlanNode")
@ -1000,75 +1181,84 @@ func init() {
func init() { proto.RegisterFile("plan.proto", fileDescriptor_2d655ab2f7683c23) }
var fileDescriptor_2d655ab2f7683c23 = []byte{
// 1108 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcd, 0x72, 0x1b, 0xc5,
0x13, 0xd7, 0x6a, 0x25, 0x79, 0xb7, 0xa5, 0x48, 0xf2, 0x5e, 0xfe, 0xce, 0xdf, 0x04, 0x9b, 0x25,
0x45, 0x04, 0x54, 0xec, 0x22, 0x09, 0x4e, 0x11, 0x0a, 0xca, 0x5f, 0xc1, 0x52, 0x11, 0x6c, 0xb3,
0x18, 0x1f, 0xb8, 0x6c, 0x8d, 0x76, 0xc7, 0xd2, 0x54, 0x56, 0x33, 0xeb, 0xd9, 0x59, 0x11, 0x9d,
0xb9, 0x71, 0xe3, 0x25, 0xe0, 0x0c, 0x37, 0xde, 0x81, 0x07, 0xe0, 0xce, 0x8b, 0x50, 0xd3, 0xb3,
0xd6, 0x47, 0x4a, 0x76, 0x4c, 0x55, 0x6e, 0x33, 0xbf, 0xe9, 0xee, 0xe9, 0x5f, 0x7f, 0xcd, 0x00,
0xa4, 0x09, 0xe1, 0x5b, 0xa9, 0x14, 0x4a, 0x78, 0xab, 0x23, 0x96, 0x8c, 0xf3, 0xcc, 0xec, 0xb6,
0xf4, 0xc1, 0xff, 0x1b, 0x59, 0x34, 0xa4, 0x23, 0x62, 0x20, 0xff, 0x17, 0x0b, 0x1a, 0x47, 0x94,
0x53, 0xc9, 0xa2, 0x73, 0x92, 0xe4, 0xd4, 0x5b, 0x07, 0xa7, 0x2f, 0x44, 0x12, 0x8e, 0x49, 0xb2,
0x66, 0x6d, 0x5a, 0x1d, 0xa7, 0x5b, 0x0a, 0x56, 0x34, 0x72, 0x4e, 0x12, 0xef, 0x1e, 0xb8, 0x8c,
0xab, 0x9d, 0x27, 0x78, 0x5a, 0xde, 0xb4, 0x3a, 0x76, 0xb7, 0x14, 0x38, 0x08, 0x15, 0xc7, 0x17,
0x89, 0x20, 0x0a, 0x8f, 0xed, 0x4d, 0xab, 0x63, 0xe9, 0x63, 0x84, 0xf4, 0xf1, 0x06, 0x40, 0xa6,
0x24, 0xe3, 0x03, 0x3c, 0xaf, 0x6c, 0x5a, 0x1d, 0xb7, 0x5b, 0x0a, 0x5c, 0x83, 0x9d, 0x93, 0x64,
0xbf, 0x0a, 0xf6, 0x98, 0x24, 0xfe, 0xcf, 0x16, 0xb8, 0xdf, 0xe6, 0x54, 0x4e, 0x7a, 0xfc, 0x42,
0x78, 0x1e, 0x54, 0x94, 0x48, 0x5f, 0xa2, 0x33, 0x76, 0x80, 0x6b, 0x6f, 0x03, 0xea, 0x23, 0xaa,
0x24, 0x8b, 0x42, 0x35, 0x49, 0x29, 0x5e, 0xe5, 0x06, 0x60, 0xa0, 0xb3, 0x49, 0x4a, 0xbd, 0xf7,
0xe1, 0x4e, 0x46, 0x89, 0x8c, 0x86, 0x61, 0x4a, 0x24, 0x19, 0x65, 0xe6, 0xb6, 0xa0, 0x61, 0xc0,
0x53, 0xc4, 0xb4, 0x90, 0x14, 0x39, 0x8f, 0xc3, 0x98, 0x46, 0x6c, 0x44, 0x92, 0xb5, 0x2a, 0x5e,
0xd1, 0x40, 0xf0, 0xd0, 0x60, 0xfe, 0xaf, 0x16, 0xc0, 0x81, 0x48, 0xf2, 0x11, 0x47, 0x6f, 0xee,
0x82, 0x73, 0xc1, 0x68, 0x12, 0x87, 0x2c, 0x2e, 0x3c, 0x5a, 0xc1, 0x7d, 0x2f, 0xf6, 0x9e, 0x81,
0x1b, 0x13, 0x45, 0x8c, 0x4b, 0x3a, 0x38, 0xcd, 0x47, 0xf7, 0xb6, 0x16, 0xe2, 0x5f, 0x44, 0xfe,
0x90, 0x28, 0xa2, 0xbd, 0x0c, 0x9c, 0xb8, 0x58, 0x79, 0xf7, 0xa1, 0xc9, 0xb2, 0x30, 0x95, 0x6c,
0x44, 0xe4, 0x24, 0x7c, 0x49, 0x27, 0xc8, 0xc9, 0x09, 0x1a, 0x2c, 0x3b, 0x35, 0xe0, 0xd7, 0x74,
0xe2, 0xad, 0x83, 0xcb, 0xb2, 0x90, 0xe4, 0x4a, 0xf4, 0x0e, 0x91, 0x91, 0x13, 0x38, 0x2c, 0xdb,
0xc3, 0xbd, 0xff, 0x87, 0x05, 0xcd, 0xef, 0x39, 0x91, 0x93, 0x80, 0xf0, 0x01, 0x7d, 0xfe, 0x2a,
0x95, 0xde, 0x97, 0x50, 0x8f, 0xd0, 0xf5, 0x90, 0xf1, 0x0b, 0x81, 0xfe, 0xd6, 0x5f, 0xf7, 0x09,
0x8b, 0x65, 0x46, 0x30, 0x80, 0x68, 0x46, 0xf6, 0x43, 0x28, 0x8b, 0xb4, 0xa0, 0x72, 0x77, 0x89,
0xda, 0x49, 0x8a, 0x34, 0xca, 0x22, 0xf5, 0x3e, 0x85, 0xea, 0x58, 0xd7, 0x0f, 0xfa, 0x5d, 0x7f,
0xb4, 0xb1, 0x44, 0x7a, 0xbe, 0xcc, 0x02, 0x23, 0xed, 0xff, 0x56, 0x86, 0xd6, 0x3e, 0x7b, 0xbb,
0x5e, 0x3f, 0x80, 0x56, 0x22, 0x7e, 0xa4, 0x32, 0x64, 0x3c, 0x4a, 0xf2, 0x8c, 0x8d, 0x4d, 0x36,
0x9c, 0xa0, 0x89, 0x70, 0xef, 0x0a, 0xd5, 0x82, 0x79, 0x9a, 0x2e, 0x08, 0x9a, 0xa8, 0x37, 0x11,
0x9e, 0x09, 0xee, 0x42, 0xdd, 0x58, 0x34, 0x14, 0x2b, 0xb7, 0xa3, 0x08, 0xa8, 0x63, 0xba, 0x6a,
0x17, 0xea, 0xe6, 0x2a, 0x63, 0xa1, 0x7a, 0x4b, 0x0b, 0xa8, 0x83, 0x6b, 0xff, 0x2f, 0x0b, 0xea,
0x07, 0x62, 0x94, 0x12, 0x69, 0xa2, 0x74, 0x04, 0xed, 0x84, 0x5e, 0xa8, 0xf0, 0x3f, 0x87, 0xaa,
0xa9, 0xd5, 0xe6, 0x2a, 0xba, 0x07, 0xab, 0x92, 0x0d, 0x86, 0x8b, 0x96, 0xca, 0xb7, 0xb1, 0xd4,
0x42, 0xbd, 0x83, 0xd7, 0xeb, 0xc5, 0xbe, 0x45, 0xbd, 0xf8, 0x3f, 0x59, 0xe0, 0x9c, 0x51, 0x39,
0x7a, 0x2b, 0x19, 0x7f, 0x0a, 0x35, 0x8c, 0x6b, 0xb6, 0x56, 0xde, 0xb4, 0x6f, 0x13, 0xd8, 0x42,
0x5c, 0x4f, 0x3f, 0x17, 0x7b, 0x06, 0xdd, 0x78, 0x82, 0xee, 0x5b, 0xe8, 0xfe, 0xfd, 0x25, 0x26,
0xa6, 0x92, 0x66, 0x75, 0x92, 0x62, 0xe5, 0x3f, 0x84, 0x6a, 0x34, 0x64, 0x49, 0x5c, 0xc4, 0xec,
0x7f, 0x4b, 0x14, 0xb5, 0x4e, 0x60, 0xa4, 0xfc, 0x0d, 0x58, 0x29, 0xb4, 0xbd, 0x3a, 0xac, 0xf4,
0xf8, 0x98, 0x24, 0x2c, 0x6e, 0x97, 0xbc, 0x15, 0xb0, 0x8f, 0x85, 0x6a, 0x5b, 0xfe, 0xdf, 0x16,
0x80, 0x69, 0x09, 0x74, 0x6a, 0x67, 0xce, 0xa9, 0x0f, 0x96, 0xd8, 0x9e, 0x89, 0x16, 0xcb, 0xc2,
0xad, 0x8f, 0xa1, 0xa2, 0x13, 0xfd, 0x26, 0xaf, 0x50, 0x48, 0x73, 0xc0, 0x5c, 0x16, 0xdd, 0x7b,
0x3d, 0x07, 0x94, 0xf2, 0x77, 0xc0, 0xb9, 0xba, 0x6b, 0x91, 0x44, 0x13, 0xe0, 0x85, 0x18, 0xb0,
0x88, 0x24, 0x7b, 0x3c, 0x6e, 0x5b, 0xde, 0x1d, 0x70, 0x8b, 0xfd, 0x89, 0x6c, 0x97, 0xfd, 0xdf,
0x6d, 0xa8, 0x20, 0xa9, 0x67, 0xe0, 0x2a, 0x2a, 0x47, 0x21, 0x7d, 0x95, 0xca, 0x22, 0xdd, 0xeb,
0x4b, 0xee, 0xbc, 0x2a, 0x10, 0xfd, 0x8a, 0xa8, 0xab, 0x62, 0xf9, 0x02, 0x20, 0xd7, 0x77, 0x1b,
0x65, 0x43, 0xef, 0x9d, 0x9b, 0xb2, 0xa5, 0xdf, 0x98, 0x7c, 0x1a, 0xcf, 0x5d, 0xa8, 0xf7, 0xd9,
0x4c, 0xdf, 0xbe, 0xb6, 0xd6, 0x66, 0x81, 0xed, 0x96, 0x02, 0xe8, 0xcf, 0x32, 0x72, 0x00, 0x8d,
0xc8, 0x34, 0xa2, 0x31, 0x61, 0xc6, 0xc1, 0xbb, 0x4b, 0xcb, 0x75, 0xda, 0xaf, 0xdd, 0x52, 0x50,
0x8f, 0xe6, 0xda, 0xf7, 0x1b, 0x68, 0x1b, 0x16, 0x52, 0xcf, 0x3d, 0x63, 0xc8, 0x4c, 0x85, 0xf7,
0xae, 0xe3, 0x32, 0x9d, 0x90, 0xdd, 0x52, 0xd0, 0xcc, 0x17, 0x67, 0xe6, 0x29, 0xac, 0x16, 0xac,
0xe6, 0xec, 0xd5, 0xd0, 0x9e, 0x7f, 0x2d, 0xb7, 0x79, 0x83, 0xad, 0xfe, 0x22, 0xb4, 0x5f, 0x83,
0x8a, 0x36, 0xe2, 0xff, 0x63, 0x01, 0x9c, 0xd3, 0x48, 0x09, 0xb9, 0x77, 0x7c, 0xfc, 0x5d, 0xf1,
0x04, 0x19, 0x61, 0xf3, 0x3f, 0xd0, 0x4f, 0x90, 0xb1, 0xb7, 0xf0, 0x38, 0x96, 0x17, 0x1f, 0xc7,
0xa7, 0x00, 0xa9, 0xa4, 0x31, 0x8b, 0x88, 0xa2, 0xd9, 0x9b, 0xca, 0x6c, 0x4e, 0xd4, 0xfb, 0x1c,
0xe0, 0x52, 0xff, 0x05, 0xcc, 0x68, 0xa8, 0x5c, 0x9b, 0xee, 0xe9, 0x87, 0x21, 0x70, 0x2f, 0xa7,
0x7f, 0x87, 0x07, 0xd0, 0x4a, 0x13, 0x12, 0xd1, 0xa1, 0x48, 0x62, 0x2a, 0x43, 0x45, 0x06, 0x18,
0x64, 0x37, 0x68, 0xce, 0xc1, 0x67, 0x64, 0xe0, 0xff, 0x69, 0x81, 0x73, 0x9a, 0x10, 0x7e, 0x2c,
0x62, 0x1c, 0xd6, 0x63, 0x64, 0x1c, 0x12, 0xce, 0xb3, 0x1b, 0xc6, 0xd1, 0x2c, 0x2e, 0xba, 0x44,
0x8c, 0xce, 0x1e, 0xe7, 0x99, 0xf7, 0xd9, 0x02, 0xdb, 0x9b, 0x5b, 0x50, 0xab, 0xce, 0xf1, 0xed,
0x40, 0x5b, 0xe4, 0x2a, 0xcd, 0x55, 0x78, 0x15, 0x4a, 0x1d, 0x2e, 0xbb, 0x63, 0x07, 0x4d, 0x83,
0x7f, 0x65, 0x22, 0x9a, 0xe9, 0x0c, 0x71, 0x11, 0xd3, 0x8f, 0x38, 0xd4, 0xcc, 0x60, 0x5d, 0xec,
0xc5, 0x16, 0xd4, 0x8f, 0x24, 0x25, 0x8a, 0xca, 0xb3, 0x21, 0xe1, 0x6d, 0xcb, 0x6b, 0x43, 0xa3,
0x00, 0x9e, 0x5f, 0xe6, 0x24, 0x69, 0x97, 0xbd, 0x06, 0x38, 0x2f, 0x68, 0x96, 0xe1, 0xb9, 0x8d,
0xcd, 0x4a, 0xb3, 0xcc, 0x1c, 0x56, 0x3c, 0x17, 0xaa, 0x66, 0x59, 0xd5, 0x72, 0xc7, 0x42, 0x99,
0x5d, 0x6d, 0xff, 0xf1, 0x0f, 0x9f, 0x0c, 0x98, 0x1a, 0xe6, 0xfd, 0xad, 0x48, 0x8c, 0xb6, 0x0d,
0xa9, 0x87, 0x4c, 0x14, 0xab, 0x6d, 0xc6, 0x15, 0x95, 0x9c, 0x24, 0xdb, 0xc8, 0x73, 0x5b, 0xf3,
0x4c, 0xfb, 0xfd, 0x1a, 0xee, 0x1e, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xeb, 0xf1, 0x90, 0xdc,
0x9d, 0x0a, 0x00, 0x00,
// 1262 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x4b, 0x73, 0x13, 0xc7,
0x13, 0xd7, 0x6a, 0x25, 0x6b, 0xb7, 0x25, 0xcb, 0xcb, 0x5e, 0xfe, 0x3c, 0xfe, 0x60, 0x67, 0x43,
0x05, 0x87, 0x14, 0x76, 0x05, 0x08, 0x14, 0xa4, 0x92, 0xc2, 0x0f, 0x62, 0xb9, 0x02, 0xb6, 0xb3,
0x18, 0x1f, 0x72, 0xd9, 0x1a, 0xed, 0x8e, 0xa5, 0x29, 0x46, 0x33, 0xcb, 0xec, 0xae, 0x40, 0xe7,
0xdc, 0x72, 0xcb, 0x97, 0x48, 0xee, 0xb9, 0xe5, 0x94, 0x2f, 0x90, 0x43, 0x8e, 0xb9, 0xe7, 0x8b,
0xa4, 0xa6, 0x67, 0xad, 0x07, 0x25, 0x81, 0xa9, 0x50, 0x95, 0xdb, 0x4c, 0x4f, 0x77, 0x4f, 0xff,
0xfa, 0x0d, 0x90, 0x72, 0x22, 0x36, 0x52, 0x25, 0x73, 0xe9, 0x5f, 0x18, 0x30, 0x3e, 0x2c, 0x32,
0x73, 0xdb, 0xd0, 0x0f, 0x97, 0x5b, 0x59, 0xdc, 0xa7, 0x03, 0x62, 0x48, 0xc1, 0x4f, 0x16, 0xb4,
0xf6, 0xa8, 0xa0, 0x8a, 0xc5, 0x27, 0x84, 0x17, 0xd4, 0xbf, 0x02, 0x4e, 0x57, 0x4a, 0x1e, 0x0d,
0x09, 0xbf, 0x68, 0xad, 0x59, 0xeb, 0x4e, 0xa7, 0x12, 0x36, 0x34, 0xe5, 0x84, 0x70, 0xff, 0x2a,
0xb8, 0x4c, 0xe4, 0xf7, 0xee, 0xe2, 0x6b, 0x75, 0xcd, 0x5a, 0xb7, 0x3b, 0x95, 0xd0, 0x41, 0x52,
0xf9, 0x7c, 0xca, 0x25, 0xc9, 0xf1, 0xd9, 0x5e, 0xb3, 0xd6, 0x2d, 0xfd, 0x8c, 0x24, 0xfd, 0xbc,
0x0a, 0x90, 0xe5, 0x8a, 0x89, 0x1e, 0xbe, 0xd7, 0xd6, 0xac, 0x75, 0xb7, 0x53, 0x09, 0x5d, 0x43,
0x3b, 0x21, 0x7c, 0xbb, 0x0e, 0xf6, 0x90, 0xf0, 0xe0, 0x47, 0x0b, 0xdc, 0xef, 0x0a, 0xaa, 0x46,
0xfb, 0xe2, 0x54, 0xfa, 0x3e, 0xd4, 0x72, 0x99, 0xbe, 0x40, 0x63, 0xec, 0x10, 0xcf, 0xfe, 0x2a,
0x34, 0x07, 0x34, 0x57, 0x2c, 0x8e, 0xf2, 0x51, 0x4a, 0xf1, 0x2b, 0x37, 0x04, 0x43, 0x3a, 0x1e,
0xa5, 0xd4, 0xff, 0x18, 0x96, 0x33, 0x4a, 0x54, 0xdc, 0x8f, 0x52, 0xa2, 0xc8, 0x20, 0x33, 0xbf,
0x85, 0x2d, 0x43, 0x3c, 0x42, 0x9a, 0x66, 0x52, 0xb2, 0x10, 0x49, 0x94, 0xd0, 0x98, 0x0d, 0x08,
0xbf, 0x58, 0xc7, 0x2f, 0x5a, 0x48, 0xdc, 0x35, 0xb4, 0xe0, 0x67, 0x0b, 0x60, 0x47, 0xf2, 0x62,
0x20, 0xd0, 0x9a, 0x4b, 0xe0, 0x9c, 0x32, 0xca, 0x93, 0x88, 0x25, 0xa5, 0x45, 0x0d, 0xbc, 0xef,
0x27, 0xfe, 0x43, 0x70, 0x13, 0x92, 0x13, 0x63, 0x92, 0x76, 0x4e, 0xfb, 0xf6, 0xd5, 0x8d, 0x19,
0xff, 0x97, 0x9e, 0xdf, 0x25, 0x39, 0xd1, 0x56, 0x86, 0x4e, 0x52, 0x9e, 0xfc, 0xeb, 0xd0, 0x66,
0x59, 0x94, 0x2a, 0x36, 0x20, 0x6a, 0x14, 0xbd, 0xa0, 0x23, 0xc4, 0xe4, 0x84, 0x2d, 0x96, 0x1d,
0x19, 0xe2, 0xb7, 0x74, 0xe4, 0x5f, 0x01, 0x97, 0x65, 0x11, 0x29, 0x72, 0xb9, 0xbf, 0x8b, 0x88,
0x9c, 0xd0, 0x61, 0xd9, 0x16, 0xde, 0x83, 0x5f, 0x2d, 0x68, 0x3f, 0x17, 0x44, 0x8d, 0x42, 0x22,
0x7a, 0xf4, 0xf1, 0xeb, 0x54, 0xf9, 0x5f, 0x43, 0x33, 0x46, 0xd3, 0x23, 0x26, 0x4e, 0x25, 0xda,
0xdb, 0x7c, 0xd3, 0x26, 0x4c, 0x96, 0x09, 0xc0, 0x10, 0xe2, 0x09, 0xd8, 0x4f, 0xa1, 0x2a, 0xd3,
0x12, 0xca, 0xa5, 0x39, 0x62, 0x87, 0x29, 0xc2, 0xa8, 0xca, 0xd4, 0xff, 0x02, 0xea, 0x43, 0x9d,
0x3f, 0x68, 0x77, 0xf3, 0xf6, 0xea, 0x1c, 0xee, 0xe9, 0x34, 0x0b, 0x0d, 0x77, 0xf0, 0x4b, 0x15,
0x56, 0xb6, 0xd9, 0x87, 0xb5, 0xfa, 0x06, 0xac, 0x70, 0xf9, 0x8a, 0xaa, 0x88, 0x89, 0x98, 0x17,
0x19, 0x1b, 0x9a, 0x68, 0x38, 0x61, 0x1b, 0xc9, 0xfb, 0x67, 0x54, 0xcd, 0x58, 0xa4, 0xe9, 0x0c,
0xa3, 0xf1, 0x7a, 0x1b, 0xc9, 0x13, 0xc6, 0x47, 0xd0, 0x34, 0x1a, 0x0d, 0xc4, 0xda, 0xf9, 0x20,
0x02, 0xca, 0x98, 0xaa, 0x7a, 0x04, 0x4d, 0xf3, 0x95, 0xd1, 0x50, 0x3f, 0xa7, 0x06, 0x94, 0xc1,
0x73, 0xf0, 0x87, 0x05, 0xcd, 0x1d, 0x39, 0x48, 0x89, 0x32, 0x5e, 0xda, 0x03, 0x8f, 0xd3, 0xd3,
0x3c, 0x7a, 0x6f, 0x57, 0xb5, 0xb5, 0xd8, 0x54, 0x46, 0xef, 0xc3, 0x05, 0xc5, 0x7a, 0xfd, 0x59,
0x4d, 0xd5, 0xf3, 0x68, 0x5a, 0x41, 0xb9, 0x9d, 0x37, 0xf3, 0xc5, 0x3e, 0x47, 0xbe, 0x04, 0x3f,
0x58, 0xe0, 0x1c, 0x53, 0x35, 0xf8, 0x20, 0x11, 0xbf, 0x0f, 0x4b, 0xe8, 0xd7, 0xec, 0x62, 0x75,
0xcd, 0x3e, 0x8f, 0x63, 0x4b, 0x76, 0xdd, 0xfd, 0x5c, 0xac, 0x19, 0x34, 0xe3, 0x2e, 0x9a, 0x6f,
0xa1, 0xf9, 0xd7, 0xe7, 0xa8, 0x18, 0x73, 0x9a, 0xd3, 0x61, 0x8a, 0x99, 0x7f, 0x0b, 0xea, 0x71,
0x9f, 0xf1, 0xa4, 0xf4, 0xd9, 0xff, 0xe6, 0x08, 0x6a, 0x99, 0xd0, 0x70, 0x05, 0xab, 0xd0, 0x28,
0xa5, 0xfd, 0x26, 0x34, 0xf6, 0xc5, 0x90, 0x70, 0x96, 0x78, 0x15, 0xbf, 0x01, 0xf6, 0x81, 0xcc,
0x3d, 0x2b, 0xf8, 0xcb, 0x02, 0x30, 0x25, 0x81, 0x46, 0xdd, 0x9b, 0x32, 0xea, 0x93, 0x39, 0xba,
0x27, 0xac, 0xe5, 0xb1, 0x34, 0xeb, 0x33, 0xa8, 0xe9, 0x40, 0xbf, 0xcb, 0x2a, 0x64, 0xd2, 0x18,
0x30, 0x96, 0x65, 0xf5, 0x2e, 0xc6, 0x80, 0x5c, 0xc1, 0x3d, 0x70, 0xce, 0xfe, 0x9a, 0x05, 0xd1,
0x06, 0x78, 0x22, 0x7b, 0x2c, 0x26, 0x7c, 0x4b, 0x24, 0x9e, 0xe5, 0x2f, 0x83, 0x5b, 0xde, 0x0f,
0x95, 0x57, 0x0d, 0xfe, 0xb4, 0x60, 0xd9, 0x08, 0x6e, 0x29, 0x96, 0xf7, 0x0f, 0xd3, 0x7f, 0x1d,
0xf9, 0x07, 0xe0, 0x10, 0xad, 0x2a, 0x1a, 0xf7, 0xa9, 0x6b, 0x73, 0x84, 0xcb, 0xdf, 0x30, 0xf9,
0x1a, 0xa4, 0xfc, 0x7a, 0x17, 0x96, 0x4d, 0xde, 0xcb, 0x94, 0x2a, 0x22, 0x92, 0xf3, 0x76, 0xae,
0x16, 0x4a, 0x1d, 0x1a, 0xa1, 0xe0, 0xf7, 0x2a, 0x5c, 0x9e, 0x81, 0xf4, 0x78, 0x48, 0xf8, 0x87,
0xeb, 0x65, 0xff, 0x35, 0xbe, 0xb2, 0xa4, 0x6b, 0xef, 0x35, 0x02, 0xea, 0xef, 0x37, 0x02, 0x6a,
0x50, 0x43, 0x5f, 0x3d, 0x04, 0x37, 0xa7, 0x6a, 0x10, 0xd1, 0xd7, 0xa9, 0x2a, 0x3d, 0x75, 0x65,
0x8e, 0x8e, 0xb3, 0xae, 0xa1, 0x57, 0x8b, 0xfc, 0xac, 0x83, 0x7c, 0x05, 0x50, 0xe8, 0x20, 0x18,
0x61, 0x93, 0xf3, 0xff, 0x7f, 0x5b, 0x09, 0xeb, 0xc5, 0xa3, 0x18, 0x17, 0xd9, 0x23, 0x68, 0x76,
0xd9, 0x44, 0xde, 0x5e, 0x18, 0xa6, 0x49, 0xb5, 0x75, 0x2a, 0x21, 0x74, 0x27, 0x65, 0xba, 0x03,
0xad, 0xd8, 0x74, 0x67, 0xa3, 0xc2, 0xcc, 0x88, 0x6b, 0x73, 0x23, 0x3d, 0x6e, 0xe2, 0x9d, 0x4a,
0xd8, 0x8c, 0xa7, 0x7a, 0xfa, 0x53, 0xf0, 0x0c, 0x0a, 0xa5, 0x13, 0xc8, 0x28, 0x32, 0xce, 0xfc,
0x68, 0x11, 0x96, 0x71, 0xaa, 0x75, 0x2a, 0x61, 0xbb, 0x98, 0x1d, 0xa4, 0x47, 0x70, 0xa1, 0x44,
0x35, 0xa5, 0x6f, 0x09, 0xf5, 0x05, 0x0b, 0xb1, 0x4d, 0x2b, 0x5c, 0xe9, 0xbe, 0x31, 0x9a, 0x73,
0x58, 0x2d, 0x35, 0x9e, 0x65, 0x65, 0x44, 0x87, 0x84, 0x4f, 0xeb, 0x6f, 0xa0, 0xfe, 0x5b, 0x0b,
0xf5, 0xcf, 0x2b, 0x93, 0x4e, 0x25, 0xbc, 0xdc, 0x5d, 0xf8, 0xba, 0xbd, 0x04, 0x35, 0xad, 0x3a,
0xf8, 0xdb, 0x02, 0x38, 0xa1, 0x71, 0x2e, 0xd5, 0xd6, 0xc1, 0xc1, 0xb3, 0x72, 0x1b, 0x32, 0x72,
0x66, 0x55, 0xd5, 0xdb, 0x90, 0xf9, 0x65, 0x66, 0x4f, 0xab, 0xce, 0xee, 0x69, 0xf7, 0x01, 0x52,
0x45, 0x13, 0x16, 0x93, 0x9c, 0x66, 0xef, 0xea, 0x78, 0x53, 0xac, 0xfe, 0x97, 0x00, 0x2f, 0xf5,
0x5a, 0x6a, 0x6a, 0xb9, 0xb6, 0x30, 0xc9, 0xc6, 0xbb, 0x6b, 0xe8, 0xbe, 0x1c, 0xaf, 0xb1, 0x37,
0x60, 0x25, 0xe5, 0x24, 0xa6, 0x7d, 0xc9, 0x13, 0xaa, 0xa2, 0x9c, 0xf4, 0x30, 0xb4, 0x6e, 0xd8,
0x9e, 0x22, 0x1f, 0x93, 0x5e, 0xf0, 0x9b, 0x05, 0xce, 0x11, 0x27, 0xe2, 0x40, 0x26, 0xb8, 0x37,
0x0c, 0x11, 0x71, 0x44, 0x84, 0xc8, 0xde, 0xd2, 0x3f, 0x26, 0x7e, 0xd1, 0x89, 0x69, 0x64, 0xb6,
0x84, 0xc8, 0xfc, 0x07, 0x33, 0x68, 0xdf, 0x3e, 0x0d, 0xb4, 0xe8, 0x14, 0xde, 0x75, 0xf0, 0x64,
0x91, 0xa7, 0x45, 0x1e, 0x9d, 0xb9, 0x52, 0xbb, 0xcb, 0x5e, 0xb7, 0xc3, 0xb6, 0xa1, 0x7f, 0x63,
0x3c, 0x9a, 0xe9, 0x08, 0x09, 0x99, 0xd0, 0x9b, 0x02, 0x96, 0x4c, 0x43, 0x98, 0x1d, 0x0b, 0x2b,
0xd0, 0xdc, 0x53, 0x94, 0xe4, 0x54, 0x1d, 0xf7, 0x89, 0xf0, 0x2c, 0xdf, 0x83, 0x56, 0x49, 0x78,
0xfc, 0xb2, 0x20, 0xdc, 0xab, 0xfa, 0x2d, 0x70, 0x9e, 0xd0, 0x2c, 0xc3, 0x77, 0x1b, 0xe7, 0x06,
0xcd, 0x32, 0xf3, 0x58, 0xf3, 0x5d, 0xa8, 0x9b, 0x63, 0x5d, 0xf3, 0x1d, 0xc8, 0xdc, 0xdc, 0x96,
0x6e, 0xee, 0x41, 0x73, 0xaa, 0xf7, 0xe9, 0x4f, 0x9f, 0x8b, 0x17, 0x42, 0xbe, 0x12, 0x66, 0xa0,
0x6e, 0x25, 0x7a, 0x08, 0x35, 0xc0, 0x7e, 0x56, 0x74, 0xbd, 0xaa, 0x3e, 0x3c, 0x2d, 0xb8, 0x67,
0xeb, 0xc3, 0x2e, 0x1b, 0x7a, 0x35, 0xa4, 0xc8, 0xc4, 0xab, 0x6f, 0xdf, 0xf9, 0xfe, 0xf3, 0x1e,
0xcb, 0xfb, 0x45, 0x77, 0x23, 0x96, 0x83, 0x4d, 0xe3, 0x9d, 0x5b, 0x4c, 0x96, 0xa7, 0x4d, 0x26,
0x72, 0xaa, 0x04, 0xe1, 0x9b, 0xe8, 0xb0, 0x4d, 0xed, 0xb0, 0xb4, 0xdb, 0x5d, 0xc2, 0xdb, 0x9d,
0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x95, 0x5c, 0x14, 0x9a, 0x71, 0x0d, 0x00, 0x00,
}

View File

@ -72,8 +72,17 @@ func (optimizer *optimizer) Exit(node *ant_ast.Node) {
floatNodeRight, rightFloat := node.Right.(*ant_ast.FloatNode)
integerNodeRight, rightInteger := node.Right.(*ant_ast.IntegerNode)
// Check IdentifierNodes
identifierNodeLeft, leftIdentifier := node.Left.(*ant_ast.IdentifierNode)
identifierNodeRight, rightIdentifier := node.Right.(*ant_ast.IdentifierNode)
switch node.Operator {
case "+":
funcName, err := getFuncNameByNodeOp(node.Operator)
if err != nil {
optimizer.err = err
return
}
if leftFloat && rightFloat {
patch(&ant_ast.FloatNode{Value: floatNodeLeft.Value + floatNodeRight.Value})
} else if leftFloat && rightInteger {
@ -82,11 +91,24 @@ func (optimizer *optimizer) Exit(node *ant_ast.Node) {
patch(&ant_ast.FloatNode{Value: float64(integerNodeLeft.Value) + floatNodeRight.Value})
} else if leftInteger && rightInteger {
patch(&ant_ast.IntegerNode{Value: integerNodeLeft.Value + integerNodeRight.Value})
} else if leftIdentifier && rightFloat {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, floatNodeRight}})
} else if leftIdentifier && rightInteger {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, integerNodeRight}})
} else if leftFloat && rightIdentifier {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeRight, floatNodeLeft}})
} else if leftInteger && rightIdentifier {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeRight, integerNodeLeft}})
} else {
optimizer.err = fmt.Errorf("invalid data type")
return
}
case "-":
funcName, err := getFuncNameByNodeOp(node.Operator)
if err != nil {
optimizer.err = err
return
}
if leftFloat && rightFloat {
patch(&ant_ast.FloatNode{Value: floatNodeLeft.Value - floatNodeRight.Value})
} else if leftFloat && rightInteger {
@ -95,11 +117,26 @@ func (optimizer *optimizer) Exit(node *ant_ast.Node) {
patch(&ant_ast.FloatNode{Value: float64(integerNodeLeft.Value) - floatNodeRight.Value})
} else if leftInteger && rightInteger {
patch(&ant_ast.IntegerNode{Value: integerNodeLeft.Value - integerNodeRight.Value})
} else if leftIdentifier && rightFloat {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, floatNodeRight}})
} else if leftIdentifier && rightInteger {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, integerNodeRight}})
} else if leftFloat && rightIdentifier {
optimizer.err = fmt.Errorf("field as right operand is not yet supported for (%s) operator", node.Operator)
return
} else if leftInteger && rightIdentifier {
optimizer.err = fmt.Errorf("field as right operand is not yet supported for (%s) operator", node.Operator)
return
} else {
optimizer.err = fmt.Errorf("invalid data type")
return
}
case "*":
funcName, err := getFuncNameByNodeOp(node.Operator)
if err != nil {
optimizer.err = err
return
}
if leftFloat && rightFloat {
patch(&ant_ast.FloatNode{Value: floatNodeLeft.Value * floatNodeRight.Value})
} else if leftFloat && rightInteger {
@ -108,11 +145,24 @@ func (optimizer *optimizer) Exit(node *ant_ast.Node) {
patch(&ant_ast.FloatNode{Value: float64(integerNodeLeft.Value) * floatNodeRight.Value})
} else if leftInteger && rightInteger {
patch(&ant_ast.IntegerNode{Value: integerNodeLeft.Value * integerNodeRight.Value})
} else if leftIdentifier && rightFloat {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, floatNodeRight}})
} else if leftIdentifier && rightInteger {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, integerNodeRight}})
} else if leftFloat && rightIdentifier {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeRight, floatNodeLeft}})
} else if leftInteger && rightIdentifier {
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeRight, integerNodeLeft}})
} else {
optimizer.err = fmt.Errorf("invalid data type")
return
}
case "/":
funcName, err := getFuncNameByNodeOp(node.Operator)
if err != nil {
optimizer.err = err
return
}
if leftFloat && rightFloat {
if floatNodeRight.Value == 0 {
optimizer.err = fmt.Errorf("divide by zero")
@ -137,17 +187,49 @@ func (optimizer *optimizer) Exit(node *ant_ast.Node) {
return
}
patch(&ant_ast.IntegerNode{Value: integerNodeLeft.Value / integerNodeRight.Value})
} else if leftIdentifier && rightFloat {
if floatNodeRight.Value == 0 {
optimizer.err = fmt.Errorf("divide by zero")
return
}
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, floatNodeRight}})
} else if leftIdentifier && rightInteger {
if integerNodeRight.Value == 0 {
optimizer.err = fmt.Errorf("divide by zero")
return
}
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, integerNodeRight}})
} else if leftFloat && rightIdentifier {
optimizer.err = fmt.Errorf("field as right operand is not yet supported for (%s) operator", node.Operator)
return
} else if leftInteger && rightIdentifier {
optimizer.err = fmt.Errorf("field as right operand is not yet supported for (%s) operator", node.Operator)
return
} else {
optimizer.err = fmt.Errorf("invalid data type")
return
}
case "%":
funcName, err := getFuncNameByNodeOp(node.Operator)
if err != nil {
optimizer.err = err
return
}
if leftInteger && rightInteger {
if integerNodeRight.Value == 0 {
optimizer.err = fmt.Errorf("modulo by zero")
return
}
patch(&ant_ast.IntegerNode{Value: integerNodeLeft.Value % integerNodeRight.Value})
} else if leftIdentifier && rightInteger {
if integerNodeRight.Value == 0 {
optimizer.err = fmt.Errorf("modulo by zero")
return
}
patch(&ant_ast.FunctionNode{Name: funcName, Arguments: []ant_ast.Node{identifierNodeLeft, integerNodeRight}})
} else if leftInteger && rightIdentifier {
optimizer.err = fmt.Errorf("field as right operand is not yet supported for (%s) operator", node.Operator)
return
} else {
optimizer.err = fmt.Errorf("invalid data type")
return
@ -254,6 +336,46 @@ func getLogicalOpType(opStr string) planpb.BinaryExpr_BinaryOp {
}
}
func getArithOpType(funcName string) (planpb.ArithOpType, error) {
var op planpb.ArithOpType
switch funcName {
case "add":
op = planpb.ArithOpType_Add
case "sub":
op = planpb.ArithOpType_Sub
case "mul":
op = planpb.ArithOpType_Mul
case "div":
op = planpb.ArithOpType_Div
case "mod":
op = planpb.ArithOpType_Mod
default:
return op, fmt.Errorf("unsupported or invalid arith op type: %s", funcName)
}
return op, nil
}
func getFuncNameByNodeOp(nodeOp string) (string, error) {
var funcName string
switch nodeOp {
case "+":
funcName = "add"
case "-":
funcName = "sub"
case "*":
funcName = "mul"
case "/":
funcName = "div"
case "%":
funcName = "mod"
default:
return funcName, fmt.Errorf("no defined funcName assigned to nodeOp: %s", nodeOp)
}
return funcName, nil
}
func parseBoolNode(nodeRaw *ant_ast.Node) *ant_ast.BoolNode {
switch node := (*nodeRaw).(type) {
case *ant_ast.IdentifierNode:
@ -352,10 +474,54 @@ func (pc *parserContext) createCmpExpr(left, right ant_ast.Node, operator string
return expr, nil
}
func (pc *parserContext) createBinaryArithOpEvalExpr(left *ant_ast.FunctionNode, right *ant_ast.Node, operator string) (*planpb.Expr, error) {
switch operator {
case "==", "!=":
binArithOp, err := pc.handleFunction(left)
if err != nil {
return nil, fmt.Errorf("createBinaryArithOpEvalExpr: %v", err)
}
op := getCompareOpType(operator, false)
val, err := pc.handleLeafValue(right, binArithOp.ColumnInfo.DataType)
if err != nil {
return nil, err
}
expr := &planpb.Expr{
Expr: &planpb.Expr_BinaryArithOpEvalRangeExpr{
BinaryArithOpEvalRangeExpr: &planpb.BinaryArithOpEvalRangeExpr{
ColumnInfo: binArithOp.ColumnInfo,
ArithOp: binArithOp.ArithOp,
RightOperand: binArithOp.RightOperand,
Op: op,
Value: val,
},
},
}
return expr, nil
}
return nil, fmt.Errorf("operator(%s) not yet supported for function nodes", operator)
}
func (pc *parserContext) handleCmpExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
return pc.createCmpExpr(node.Left, node.Right, node.Operator)
}
func (pc *parserContext) handleBinaryArithCmpExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
leftNode, funcNodeLeft := node.Left.(*ant_ast.FunctionNode)
_, funcNodeRight := node.Right.(*ant_ast.FunctionNode)
if funcNodeRight {
return nil, fmt.Errorf("right node as a function is not supported yet")
} else if !funcNodeLeft {
// Both left and right are not function nodes, pass to createCmpExpr
return pc.createCmpExpr(node.Left, node.Right, node.Operator)
} else {
// Only the left node is a function node
return pc.createBinaryArithOpEvalExpr(leftNode, &node.Right, node.Operator)
}
}
func (pc *parserContext) handleLogicalExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
op := getLogicalOpType(node.Operator)
if op == planpb.BinaryExpr_Invalid {
@ -517,6 +683,12 @@ func (pc *parserContext) handleMultiCmpExpr(node *ant_ast.BinaryNode) (*planpb.E
}
func (pc *parserContext) handleBinaryExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
_, arithExpr := node.Left.(*ant_ast.FunctionNode)
if arithExpr {
return pc.handleBinaryArithCmpExpr(node)
}
switch node.Operator {
case "<", "<=", ">", ">=":
return pc.handleMultiCmpExpr(node)
@ -597,6 +769,37 @@ func (pc *parserContext) handleLeafValue(nodeRaw *ant_ast.Node, dataType schemap
return gv, nil
}
func (pc *parserContext) handleFunction(node *ant_ast.FunctionNode) (*planpb.BinaryArithOp, error) {
funcArithOp, err := getArithOpType(node.Name)
if err != nil {
return nil, err
}
idNode, ok := node.Arguments[0].(*ant_ast.IdentifierNode)
if !ok {
return nil, fmt.Errorf("left operand of the function must be an identifier")
}
field, err := pc.handleIdentifier(idNode)
if err != nil {
return nil, err
}
valueNode := node.Arguments[1]
val, err := pc.handleLeafValue(&valueNode, field.DataType)
if err != nil {
return nil, err
}
arithOp := &planpb.BinaryArithOp{
ColumnInfo: createColumnInfo(field),
ArithOp: funcArithOp,
RightOperand: val,
}
return arithOp, nil
}
func (pc *parserContext) handleIdentifier(node *ant_ast.IdentifierNode) (*schemapb.FieldSchema, error) {
fieldName := node.Value
field, err := pc.schema.GetFieldFromName(fieldName)

View File

@ -157,6 +157,66 @@ func TestParseExpr_Naive(t *testing.T) {
assert.Nil(t, exprProto)
}
})
t.Run("test BinaryArithOpNode", func(t *testing.T) {
exprStrs := []string{
// "+"
"FloatField + 1.2 == 3",
"Int64Field + 3 == 5",
"1.2 + FloatField != 3",
"3 + Int64Field != 5",
// "-"
"FloatField - 1.2 == 3",
"Int64Field - 3 != 5",
// "*"
"FloatField * 1.2 == 3",
"Int64Field * 3 == 5",
"1.2 * FloatField != 3",
"3 * Int64Field != 5",
// "/"
"FloatField / 1.2 == 3",
"Int64Field / 3 != 5",
// "%"
"Int64Field % 7 == 5",
}
for _, exprStr := range exprStrs {
exprProto, err := parseExpr(schema, exprStr)
assert.Nil(t, err)
str := proto.MarshalTextString(exprProto)
println(str)
}
})
t.Run("test BinaryArithOpNode invalid", func(t *testing.T) {
exprStrs := []string{
// "+"
"FloatField + FloatField == 20",
"Int64Field + Int64Field != 10",
// "-"
"FloatField - FloatField == 20.0",
"Int64Field - Int64Field != 10",
"10 - FloatField == 20",
"20 - Int64Field != 10",
// "*"
"FloatField * FloatField == 20",
"Int64Field * Int64Field != 10",
// "/"
"FloatField / FloatField == 20",
"Int64Field / Int64Field != 10",
"FloatField / 0 == 20",
"Int64Field / 0 != 10",
// "%"
"Int64Field % Int64Field != 10",
"FloatField % 0 == 20",
"Int64Field % 0 != 10",
"FloatField % 2.3 == 20",
}
for _, exprStr := range exprStrs {
exprProto, err := parseExpr(schema, exprStr)
assert.Error(t, err)
assert.Nil(t, exprProto)
}
})
}
func TestParsePlanNode_Naive(t *testing.T) {
@ -330,6 +390,79 @@ func TestExprFieldCompare_Str(t *testing.T) {
}
}
func TestExprBinaryArithOp_Str(t *testing.T) {
exprStrs := []string{
// Basic arithmetic
"(age1 + 5) == 2",
// Float data type
"(FloatN - 5.2) == 0",
// Other operators
"(age1 - 5) == 1",
"(age1 * 5) == 6",
"(age1 / 5) == 1",
"(age1 % 5) == 0",
// Allow for commutative property for + and *
"(6 + age1) != 2",
"(age1 * 4) != 9",
"(5 * FloatN) != 0",
"(9 * FloatN) != 0",
}
unsupportedExprStrs := []string{
// Comparison operators except for "==" and "!=" are unsupported
"(age1 + 2) > 4",
"(age1 + 2) >= 4",
"(age1 + 2) < 4",
"(age1 + 2) <= 4",
// Functional nodes at the right of the comparison are not allowed
"0 == (age1 + 3)",
// Field as the right operand for -, /, and % operators are not supported
"(10 - age1) == 0",
"(20 / age1) == 0",
"(30 % age1) == 0",
// Modulo is not supported in the parser but the engine can handle it since fmod is used
"(FloatN % 2.1) == 0",
// Different data types are not supported
"(age1 + 20.16) == 35.16",
// Left operand of the function must be an identifier
"(10.5 / floatN) == 5.75",
}
fields := []*schemapb.FieldSchema{
{FieldID: 100, Name: "fakevec", DataType: schemapb.DataType_FloatVector},
{FieldID: 101, Name: "age1", DataType: schemapb.DataType_Int64},
{FieldID: 102, Name: "FloatN", DataType: schemapb.DataType_Float},
}
schema := &schemapb.CollectionSchema{
Name: "default-collection",
Description: "",
AutoID: true,
Fields: fields,
}
queryInfo := &planpb.QueryInfo{
Topk: 10,
MetricType: "L2",
SearchParams: "{\"nprobe\": 10}",
}
for offset, exprStr := range exprStrs {
fmt.Printf("case %d: %s\n", offset, exprStr)
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
assert.Nil(t, err)
dbgStr := proto.MarshalTextString(planProto)
println(dbgStr)
}
for offset, exprStr := range unsupportedExprStrs {
fmt.Printf("case %d: %s\n", offset, exprStr)
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
assert.Error(t, err)
dbgStr := proto.MarshalTextString(planProto)
println(dbgStr)
}
}
func TestPlanParseAPIs(t *testing.T) {
t.Run("get compare op type", func(t *testing.T) {
var op planpb.OpType