Refactor `RangeExpr` & `CompareExpr` (#6786)

* Changed `RangeExpr` proto to `UnaryRangeExpr` & `BinaryRangeExpr`
Several unit test unpassed.

Signed-off-by: xaxys <tpnnghd@163.com>

* Fix bugs to pass unit test. Fix format.

Signed-off-by: xaxys <tpnnghd@163.com>

* Remove debug information.

Signed-off-by: xaxys <tpnnghd@163.com>

* Fix format.
Remove debug information.
Unify variable name.
Add error information.
Remove `CompareExpr` test in `test_c_api.cpp`.

Signed-off-by: xaxys <tpnnghd@163.com>

* Fix code format.

Signed-off-by: xaxys <tpnnghd@163.com>

* Update `Plan.cpp`.

Signed-off-by: xaxys <tpnnghd@163.com>
pull/6800/head^2
xaxys 2021-07-25 10:23:19 +08:00 committed by GitHub
parent 2962d31a5f
commit e43b43e7d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 2642 additions and 1263 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,6 @@ struct LogicalBinaryExpr : BinaryExprBase {
struct TermExpr : Expr {
FieldOffset field_offset_;
DataType data_type_ = DataType::NONE;
// std::vector<std::any> terms_;
protected:
// prevent accidential instantiation
@ -80,7 +79,7 @@ enum class OpType {
LessThan = 3,
LessEqual = 4,
Equal = 5,
NotEqual = 6
NotEqual = 6,
};
static const std::map<std::string, OpType> mapping_ = {
@ -90,14 +89,29 @@ static const std::map<std::string, OpType> mapping_ = {
{"eq", OpType::Equal}, {"ne", OpType::NotEqual},
};
struct RangeExpr : Expr {
struct UnaryRangeExpr : Expr {
FieldOffset field_offset_;
DataType data_type_ = DataType::NONE;
OpType op_type_;
// std::vector<std::tuple<OpType, std::any>> conditions_;
protected:
// prevent accidential instantiation
RangeExpr() = default;
UnaryRangeExpr() = default;
public:
void
accept(ExprVisitor&) override;
};
struct BinaryRangeExpr : Expr {
FieldOffset field_offset_;
DataType data_type_ = DataType::NONE;
bool lower_inclusive_;
bool upper_inclusive_;
protected:
// prevent accidential instantiation
BinaryRangeExpr() = default;
public:
void
@ -105,9 +119,11 @@ struct RangeExpr : Expr {
};
struct CompareExpr : Expr {
std::vector<FieldOffset> field_offsets_;
std::vector<DataType> data_types_;
OpType op;
FieldOffset left_field_offset_;
FieldOffset right_field_offset_;
DataType left_data_type_;
DataType right_data_type_;
OpType op_type_;
public:
void

View File

@ -22,8 +22,13 @@ struct TermExprImpl : TermExpr {
};
template <typename T>
struct RangeExprImpl : RangeExpr {
std::vector<std::tuple<OpType, T>> conditions_;
struct UnaryRangeExprImpl : UnaryRangeExpr {
T value_;
};
template <typename T>
struct BinaryRangeExprImpl : BinaryRangeExpr {
T lower_value_;
T upper_value_;
};
} // namespace milvus::query

View File

@ -10,12 +10,7 @@
// or implied. See the License for the specific language governing permissions and limitations under the License
#include "query/Plan.h"
#include "query/PlanImpl.h"
#include "query/PlanNode.h"
#include "query/ExprImpl.h"
#include "utils/Json.h"
#include "exceptions/EasyAssert.h"
#include "pb/milvus.pb.h"
#include <vector>
#include <memory>
#include <boost/algorithm/string.hpp>
@ -108,16 +103,22 @@ Parser::ParseCompareNode(const Json& out_body) {
AssertInfo(mapping_.count(op_name), "op(" + op_name + ") not found");
auto body = out_iter.value();
Assert(body.is_array());
Assert(body.size() == 2);
auto expr = std::make_unique<CompareExpr>();
expr->op = mapping_.at(op_name);
for (auto& item : body) {
Assert(item.is_string());
auto field_name = FieldName(item.get<std::string>());
auto& field_meta = schema[field_name];
auto data_type = field_meta.get_data_type();
expr->data_types_.emplace_back(data_type);
expr->field_offsets_.emplace_back(schema.get_offset(field_name));
}
expr->op_type_ = mapping_.at(op_name);
auto& item0 = body[0];
Assert(item0.is_string());
auto left_field_name = FieldName(item0.get<std::string>());
expr->left_data_type_ = schema[left_field_name].get_data_type();
expr->left_field_offset_ = schema.get_offset(left_field_name);
auto& item1 = body[1];
Assert(item1.is_string());
auto right_field_name = FieldName(item1.get<std::string>());
expr->right_data_type_ = schema[right_field_name].get_data_type();
expr->right_field_offset_ = schema.get_offset(right_field_name);
return expr;
}
@ -277,17 +278,11 @@ Parser::ParseTermNodeImpl(const FieldName& field_name, const Json& body) {
template <typename T>
ExprPtr
Parser::ParseRangeNodeImpl(const FieldName& field_name, const Json& body) {
auto expr = std::make_unique<RangeExprImpl<T>>();
auto& field_meta = schema[field_name];
auto data_type = field_meta.get_data_type();
expr->data_type_ = data_type;
expr->field_offset_ = schema.get_offset(field_name);
Assert(body.is_object());
for (auto& item : body.items()) {
if (body.size() == 1) {
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");
auto op = mapping_.at(op_name);
if constexpr (std::is_same_v<T, bool>) {
Assert(item.value().is_boolean());
} else if constexpr (std::is_integral_v<T>) {
@ -298,11 +293,62 @@ Parser::ParseRangeNodeImpl(const FieldName& field_name, const Json& body) {
static_assert(always_false<T>, "unsupported type");
__builtin_unreachable();
}
T value = item.value();
expr->conditions_.emplace_back(op, value);
auto expr = std::make_unique<UnaryRangeExprImpl<T>>();
expr->data_type_ = schema[field_name].get_data_type();
expr->field_offset_ = schema.get_offset(field_name);
expr->op_type_ = mapping_.at(op_name);
expr->value_ = item.value();
return expr;
} else if (body.size() == 2) {
bool has_lower_value = false;
bool has_upper_value = false;
bool lower_inclusive = false;
bool upper_inclusive = false;
T lower_value;
T upper_value;
for (auto& item : body.items()) {
auto op_name = boost::algorithm::to_lower_copy(std::string(item.key()));
AssertInfo(mapping_.count(op_name), "op(" + op_name + ") not found");
if constexpr (std::is_same_v<T, bool>) {
Assert(item.value().is_boolean());
} else if constexpr (std::is_integral_v<T>) {
Assert(item.value().is_number_integer());
} else if constexpr (std::is_floating_point_v<T>) {
Assert(item.value().is_number());
} else {
static_assert(always_false<T>, "unsupported type");
__builtin_unreachable();
}
auto op = mapping_.at(op_name);
switch (op) {
case OpType::GreaterEqual:
lower_inclusive = true;
case OpType::GreaterThan:
lower_value = item.value();
has_lower_value = true;
break;
case OpType::LessEqual:
upper_inclusive = true;
case OpType::LessThan:
upper_value = item.value();
has_upper_value = true;
break;
default:
PanicInfo("unsupported operator in binary-range node");
}
}
AssertInfo(has_lower_value && has_upper_value, "illegal binary-range node");
auto expr = std::make_unique<BinaryRangeExprImpl<T>>();
expr->data_type_ = schema[field_name].get_data_type();
expr->field_offset_ = schema.get_offset(field_name);
expr->lower_inclusive_ = lower_inclusive;
expr->upper_inclusive_ = upper_inclusive;
expr->lower_value_ = lower_value;
expr->upper_value_ = upper_value;
return expr;
} else {
PanicInfo("illegal range node, too more or too few ops");
}
std::sort(expr->conditions_.begin(), expr->conditions_.end());
return expr;
}
std::unique_ptr<PlaceholderGroup>

View File

@ -10,13 +10,10 @@
// or implied. See the License for the specific language governing permissions and limitations under the License
#include "query/PlanProto.h"
#include "PlanNode.h"
#include "ExprImpl.h"
#include "pb/plan.pb.h"
#include <google/protobuf/text_format.h>
#include <query/generated/ExtractInfoPlanNodeVisitor.h>
#include "query/generated/ExtractInfoExprVisitor.h"
#include "common/Types.h"
namespace milvus::query {
namespace planpb = milvus::proto::plan;
@ -48,31 +45,56 @@ ExtractTermExprImpl(FieldOffset field_offset, DataType data_type, const planpb::
}
template <typename T>
std::unique_ptr<RangeExprImpl<T>>
ExtractRangeExprImpl(FieldOffset field_offset, DataType data_type, const planpb::RangeExpr& expr_proto) {
std::unique_ptr<UnaryRangeExprImpl<T>>
ExtractUnaryRangeExprImpl(FieldOffset field_offset, DataType data_type, const planpb::UnaryRangeExpr& expr_proto) {
static_assert(std::is_fundamental_v<T>);
auto result = std::make_unique<RangeExprImpl<T>>();
auto result = std::make_unique<UnaryRangeExprImpl<T>>();
result->field_offset_ = field_offset;
result->data_type_ = data_type;
Assert(expr_proto.ops_size() == expr_proto.values_size());
auto sz = expr_proto.ops_size();
result->op_type_ = static_cast<OpType>(expr_proto.op());
for (int i = 0; i < sz; ++i) {
auto op = static_cast<OpType>(expr_proto.ops(i));
auto& value_proto = expr_proto.values(i);
auto setValue = [&](T& v, const auto& value_proto) {
if constexpr (std::is_same_v<T, bool>) {
Assert(value_proto.val_case() == planpb::GenericValue::kBoolVal);
result->conditions_.emplace_back(op, static_cast<T>(value_proto.bool_val()));
v = static_cast<T>(value_proto.bool_val());
} else if constexpr (std::is_integral_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kInt64Val);
result->conditions_.emplace_back(op, static_cast<T>(value_proto.int64_val()));
v = static_cast<T>(value_proto.int64_val());
} else if constexpr (std::is_floating_point_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kFloatVal);
result->conditions_.emplace_back(op, static_cast<T>(value_proto.float_val()));
v = static_cast<T>(value_proto.float_val());
} else {
static_assert(always_false<T>);
}
}
};
setValue(result->value_, expr_proto.value());
return result;
}
template <typename T>
std::unique_ptr<BinaryRangeExprImpl<T>>
ExtractBinaryRangeExprImpl(FieldOffset field_offset, DataType data_type, const planpb::BinaryRangeExpr& expr_proto) {
static_assert(std::is_fundamental_v<T>);
auto result = std::make_unique<BinaryRangeExprImpl<T>>();
result->field_offset_ = field_offset;
result->data_type_ = data_type;
auto setValue = [&](T& v, const auto& value_proto) {
if constexpr (std::is_same_v<T, bool>) {
Assert(value_proto.val_case() == planpb::GenericValue::kBoolVal);
v = static_cast<T>(value_proto.bool_val());
} else if constexpr (std::is_integral_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kInt64Val);
v = static_cast<T>(value_proto.int64_val());
} else if constexpr (std::is_floating_point_v<T>) {
Assert(value_proto.val_case() == planpb::GenericValue::kFloatVal);
v = static_cast<T>(value_proto.float_val());
} else {
static_assert(always_false<T>);
}
};
setValue(result->lower_value_, expr_proto.lower_value());
setValue(result->upper_value_, expr_proto.upper_value());
return result;
}
@ -136,36 +158,74 @@ ProtoParser::CreatePlan(const proto::plan::PlanNode& plan_node_proto) {
}
ExprPtr
ProtoParser::ParseRangeExpr(const proto::plan::RangeExpr& expr_pb) {
auto& columen_info = expr_pb.column_info();
auto field_id = FieldId(columen_info.field_id());
ProtoParser::ParseUnaryRangeExpr(const proto::plan::UnaryRangeExpr& 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 == (DataType)columen_info.data_type());
Assert(data_type == static_cast<DataType>(column_info.data_type()));
// auto& field_meta = schema[field_offset];
auto result = [&]() -> ExprPtr {
switch (data_type) {
case DataType::BOOL: {
return ExtractRangeExprImpl<bool>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<bool>(field_offset, data_type, expr_pb);
}
case DataType::INT8: {
return ExtractRangeExprImpl<int8_t>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<int8_t>(field_offset, data_type, expr_pb);
}
case DataType::INT16: {
return ExtractRangeExprImpl<int16_t>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<int16_t>(field_offset, data_type, expr_pb);
}
case DataType::INT32: {
return ExtractRangeExprImpl<int32_t>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<int32_t>(field_offset, data_type, expr_pb);
}
case DataType::INT64: {
return ExtractRangeExprImpl<int64_t>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<int64_t>(field_offset, data_type, expr_pb);
}
case DataType::FLOAT: {
return ExtractRangeExprImpl<float>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<float>(field_offset, data_type, expr_pb);
}
case DataType::DOUBLE: {
return ExtractRangeExprImpl<double>(field_offset, data_type, expr_pb);
return ExtractUnaryRangeExprImpl<double>(field_offset, data_type, expr_pb);
}
default: {
PanicInfo("unsupported data type");
}
}
}();
return result;
}
ExprPtr
ProtoParser::ParseBinaryRangeExpr(const proto::plan::BinaryRangeExpr& expr_pb) {
auto& columnInfo = expr_pb.column_info();
auto field_id = FieldId(columnInfo.field_id());
auto field_offset = schema.get_offset(field_id);
auto data_type = schema[field_offset].get_data_type();
Assert(data_type == (DataType)columnInfo.data_type());
auto result = [&]() -> ExprPtr {
switch (data_type) {
case DataType::BOOL: {
return ExtractBinaryRangeExprImpl<bool>(field_offset, data_type, expr_pb);
}
case DataType::INT8: {
return ExtractBinaryRangeExprImpl<int8_t>(field_offset, data_type, expr_pb);
}
case DataType::INT16: {
return ExtractBinaryRangeExprImpl<int16_t>(field_offset, data_type, expr_pb);
}
case DataType::INT32: {
return ExtractBinaryRangeExprImpl<int32_t>(field_offset, data_type, expr_pb);
}
case DataType::INT64: {
return ExtractBinaryRangeExprImpl<int64_t>(field_offset, data_type, expr_pb);
}
case DataType::FLOAT: {
return ExtractBinaryRangeExprImpl<float>(field_offset, data_type, expr_pb);
}
case DataType::DOUBLE: {
return ExtractBinaryRangeExprImpl<double>(field_offset, data_type, expr_pb);
}
default: {
PanicInfo("unsupported data type");
@ -177,35 +237,36 @@ ProtoParser::ParseRangeExpr(const proto::plan::RangeExpr& expr_pb) {
ExprPtr
ProtoParser::ParseCompareExpr(const proto::plan::CompareExpr& expr_pb) {
auto& column_infos = expr_pb.columns_info();
std::vector<FieldOffset> field_offsets;
std::vector<DataType> data_types;
for (auto& column_info : column_infos) {
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 == (DataType)column_info.data_type());
field_offsets.emplace_back(field_offset);
data_types.emplace_back(data_type);
}
auto& left_column_info = expr_pb.left_column_info();
auto left_field_id = FieldId(left_column_info.field_id());
auto left_field_offset = schema.get_offset(left_field_id);
auto left_data_type = schema[left_field_offset].get_data_type();
Assert(left_data_type == static_cast<DataType>(left_column_info.data_type()));
auto& right_column_info = expr_pb.right_column_info();
auto right_field_id = FieldId(right_column_info.field_id());
auto right_field_offset = schema.get_offset(right_field_id);
auto right_data_type = schema[right_field_offset].get_data_type();
Assert(right_data_type == static_cast<DataType>(right_column_info.data_type()));
// auto& field_meta = schema[field_offset];
return [&]() -> ExprPtr {
auto result = std::make_unique<CompareExpr>();
result->field_offsets_ = field_offsets;
result->data_types_ = data_types;
result->op = static_cast<OpType>(expr_pb.op());
result->left_field_offset_ = left_field_offset;
result->left_data_type_ = left_data_type;
result->right_field_offset_ = right_field_offset;
result->right_data_type_ = right_data_type;
result->op_type_ = static_cast<OpType>(expr_pb.op());
return result;
}();
}
ExprPtr
ProtoParser::ParseTermExpr(const proto::plan::TermExpr& expr_pb) {
auto& columen_info = expr_pb.column_info();
auto field_id = FieldId(columen_info.field_id());
auto& columnInfo = expr_pb.column_info();
auto field_id = FieldId(columnInfo.field_id());
auto field_offset = schema.get_offset(field_id);
auto data_type = schema[field_offset].get_data_type();
Assert(data_type == (DataType)columen_info.data_type());
Assert(data_type == (DataType)columnInfo.data_type());
// auto& field_meta = schema[field_offset];
auto result = [&]() -> ExprPtr {
@ -275,8 +336,11 @@ ProtoParser::ParseExpr(const proto::plan::Expr& expr_pb) {
case ppe::kTermExpr: {
return ParseTermExpr(expr_pb.term_expr());
}
case ppe::kRangeExpr: {
return ParseRangeExpr(expr_pb.range_expr());
case ppe::kUnaryRangeExpr: {
return ParseUnaryRangeExpr(expr_pb.unary_range_expr());
}
case ppe::kBinaryRangeExpr: {
return ParseBinaryRangeExpr(expr_pb.binary_range_expr());
}
case ppe::kCompareExpr: {
return ParseCompareExpr(expr_pb.compare_expr());

View File

@ -27,7 +27,10 @@ class ProtoParser {
// ExprFromProto(const proto::plan::Expr& expr_proto);
ExprPtr
ParseRangeExpr(const proto::plan::RangeExpr& expr_pb);
ParseUnaryRangeExpr(const proto::plan::UnaryRangeExpr& expr_pb);
ExprPtr
ParseBinaryRangeExpr(const proto::plan::BinaryRangeExpr& expr_pb);
ExprPtr
ParseCompareExpr(const proto::plan::CompareExpr& expr_pb);

View File

@ -34,7 +34,10 @@ class ExecExprVisitor : public ExprVisitor {
visit(TermExpr& expr) override;
void
visit(RangeExpr& expr) override;
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
void
visit(CompareExpr& expr) override;
@ -49,19 +52,23 @@ class ExecExprVisitor : public ExprVisitor {
Assert(!ret_.has_value());
expr.accept(*this);
Assert(ret_.has_value());
auto ret = std::move(ret_);
auto res = std::move(ret_);
ret_ = std::nullopt;
return std::move(ret.value());
return std::move(res.value());
}
public:
template <typename T, typename IndexFunc, typename ElementFunc>
auto
ExecRangeVisitorImpl(RangeExprImpl<T>& expr, IndexFunc func, ElementFunc element_func) -> RetType;
ExecRangeVisitorImpl(FieldOffset field_offset, IndexFunc func, ElementFunc element_func) -> RetType;
template <typename T>
auto
ExecRangeVisitorDispatcher(RangeExpr& expr_raw) -> RetType;
ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> RetType;
template <typename T>
auto
ExecBinaryRangeVisitorDispatcher(BinaryRangeExpr& expr_raw) -> RetType;
template <typename T>
auto

View File

@ -31,7 +31,12 @@ TermExpr::accept(ExprVisitor& visitor) {
}
void
RangeExpr::accept(ExprVisitor& visitor) {
UnaryRangeExpr::accept(ExprVisitor& visitor) {
visitor.visit(*this);
}
void
BinaryRangeExpr::accept(ExprVisitor& visitor) {
visitor.visit(*this);
}

View File

@ -29,7 +29,10 @@ class ExprVisitor {
visit(TermExpr&) = 0;
virtual void
visit(RangeExpr&) = 0;
visit(UnaryRangeExpr&) = 0;
virtual void
visit(BinaryRangeExpr&) = 0;
virtual void
visit(CompareExpr&) = 0;

View File

@ -28,7 +28,10 @@ class ExtractInfoExprVisitor : public ExprVisitor {
visit(TermExpr& expr) override;
void
visit(RangeExpr& expr) override;
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
void
visit(CompareExpr& expr) override;

View File

@ -13,8 +13,6 @@
// Generated File
// DO NOT EDIT
#include "query/Plan.h"
#include "exceptions/EasyAssert.h"
#include "utils/Json.h"
#include <utility>
#include "ExprVisitor.h"
@ -31,7 +29,10 @@ class ShowExprVisitor : public ExprVisitor {
visit(TermExpr& expr) override;
void
visit(RangeExpr& expr) override;
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
void
visit(CompareExpr& expr) override;

View File

@ -34,7 +34,10 @@ class VerifyExprVisitor : public ExprVisitor {
visit(TermExpr& expr) override;
void
visit(RangeExpr& expr) override;
visit(UnaryRangeExpr& expr) override;
void
visit(BinaryRangeExpr& expr) override;
void
visit(CompareExpr& expr) override;

View File

@ -42,11 +42,15 @@ class ExecExprVisitor : ExprVisitor {
public:
template <typename T, typename IndexFunc, typename ElementFunc>
auto
ExecRangeVisitorImpl(RangeExprImpl<T>& expr, IndexFunc func, ElementFunc element_func) -> RetType;
ExecRangeVisitorImpl(FieldOffset field_offset, IndexFunc func, ElementFunc element_func) -> RetType;
template <typename T>
auto
ExecRangeVisitorDispatcher(RangeExpr& expr_raw) -> RetType;
ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> RetType;
template <typename T>
auto
ExecBinaryRangeVisitorDispatcher(BinaryRangeExpr& expr_raw) -> RetType;
template <typename T>
auto
@ -137,10 +141,9 @@ Assemble(const std::deque<boost::dynamic_bitset<>>& srcs) -> boost::dynamic_bits
template <typename T, typename IndexFunc, typename ElementFunc>
auto
ExecExprVisitor::ExecRangeVisitorImpl(RangeExprImpl<T>& expr, IndexFunc index_func, ElementFunc element_func)
ExecExprVisitor::ExecRangeVisitorImpl(FieldOffset field_offset, IndexFunc index_func, ElementFunc element_func)
-> RetType {
auto& schema = segment_.get_schema();
auto field_offset = expr.field_offset_;
auto& field_meta = schema[field_offset];
auto indexing_barrier = segment_.num_chunk_index(field_offset);
auto size_per_chunk = segment_.size_per_chunk();
@ -176,116 +179,157 @@ ExecExprVisitor::ExecRangeVisitorImpl(RangeExprImpl<T>& expr, IndexFunc index_fu
#pragma ide diagnostic ignored "Simplify"
template <typename T>
auto
ExecExprVisitor::ExecRangeVisitorDispatcher(RangeExpr& expr_raw) -> RetType {
auto& expr = static_cast<RangeExprImpl<T>&>(expr_raw);
auto conditions = expr.conditions_;
std::sort(conditions.begin(), conditions.end());
ExecExprVisitor::ExecUnaryRangeVisitorDispatcher(UnaryRangeExpr& expr_raw) -> RetType {
auto& expr = static_cast<UnaryRangeExprImpl<T>&>(expr_raw);
using Index = knowhere::scalar::StructuredIndex<T>;
using Operator = knowhere::scalar::OperatorType;
if (conditions.size() == 1) {
auto cond = conditions[0];
// auto [op, val] = cond; // strange bug on capture
auto op = std::get<0>(cond);
auto val = std::get<1>(cond);
switch (op) {
case OpType::Equal: {
auto index_func = [val](Index* index) { return index->In(1, &val); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x == val); });
}
case OpType::NotEqual: {
auto index_func = [val](Index* index) { return index->NotIn(1, &val); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x != val); });
}
case OpType::GreaterEqual: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::GE); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x >= val); });
}
case OpType::GreaterThan: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::GT); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x > val); });
}
case OpType::LessEqual: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::LE); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x <= val); });
}
case OpType::LessThan: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::LT); };
return ExecRangeVisitorImpl(expr, index_func, [val](T x) { return (x < val); });
}
default: {
PanicInfo("unsupported range node");
}
auto op = expr.op_type_;
auto val = expr.value_;
switch (op) {
case OpType::Equal: {
auto index_func = [val](Index* index) { return index->In(1, &val); };
auto elem_func = [val](T x) { return (x == val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
} else if (conditions.size() == 2) {
OpType op1, op2;
T val1, val2;
std::tie(op1, val1) = conditions[0];
std::tie(op2, val2) = conditions[1];
// TODO: disable check?
if (val1 > val2) {
RetType res(row_count_, false);
return res;
case OpType::NotEqual: {
auto index_func = [val](Index* index) { return index->NotIn(1, &val); };
auto elem_func = [val](T x) { return (x != val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
auto ops = std::make_tuple(op1, op2);
if (false) {
} else if (ops == std::make_tuple(OpType::GreaterThan, OpType::LessThan)) {
auto index_func = [val1, val2](Index* index) { return index->Range(val1, false, val2, false); };
return ExecRangeVisitorImpl(expr, index_func, [val1, val2](T x) { return (val1 < x && x < val2); });
} else if (ops == std::make_tuple(OpType::GreaterThan, OpType::LessEqual)) {
auto index_func = [val1, val2](Index* index) { return index->Range(val1, false, val2, true); };
return ExecRangeVisitorImpl(expr, index_func, [val1, val2](T x) { return (val1 < x && x <= val2); });
} else if (ops == std::make_tuple(OpType::GreaterEqual, OpType::LessThan)) {
auto index_func = [val1, val2](Index* index) { return index->Range(val1, true, val2, false); };
return ExecRangeVisitorImpl(expr, index_func, [val1, val2](T x) { return (val1 <= x && x < val2); });
} else if (ops == std::make_tuple(OpType::GreaterEqual, OpType::LessEqual)) {
auto index_func = [val1, val2](Index* index) { return index->Range(val1, true, val2, true); };
return ExecRangeVisitorImpl(expr, index_func, [val1, val2](T x) { return (val1 <= x && x <= val2); });
} else {
case OpType::GreaterEqual: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::GE); };
auto elem_func = [val](T x) { return (x >= val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
case OpType::GreaterThan: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::GT); };
auto elem_func = [val](T x) { return (x > val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
case OpType::LessEqual: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::LE); };
auto elem_func = [val](T x) { return (x <= val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
case OpType::LessThan: {
auto index_func = [val](Index* index) { return index->Range(val, Operator::LT); };
auto elem_func = [val](T x) { return (x < val); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
default: {
PanicInfo("unsupported range node");
}
}
}
#pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma ide diagnostic ignored "Simplify"
template <typename T>
auto
ExecExprVisitor::ExecBinaryRangeVisitorDispatcher(BinaryRangeExpr& expr_raw) -> RetType {
auto& expr = static_cast<BinaryRangeExprImpl<T>&>(expr_raw);
using Index = knowhere::scalar::StructuredIndex<T>;
using Operator = knowhere::scalar::OperatorType;
bool lower_inclusive = expr.lower_inclusive_;
bool upper_inclusive = expr.upper_inclusive_;
T val1 = expr.lower_value_;
T val2 = expr.upper_value_;
// TODO: disable check?
if (val1 > val2 || (val1 == val2 && !(lower_inclusive && upper_inclusive))) {
RetType res(row_count_, false);
return res;
}
auto index_func = [=](Index* index) { return index->Range(val1, lower_inclusive, val2, upper_inclusive); };
if (lower_inclusive && upper_inclusive) {
auto elem_func = [val1, val2](T x) { return (val1 <= x && x <= val2); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
} else if (lower_inclusive && !upper_inclusive) {
auto elem_func = [val1, val2](T x) { return (val1 <= x && x < val2); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
} else if (!lower_inclusive && upper_inclusive) {
auto elem_func = [val1, val2](T x) { return (val1 < x && x <= val2); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
} else {
PanicInfo("unsupported range node");
auto elem_func = [val1, val2](T x) { return (val1 < x && x < val2); };
return ExecRangeVisitorImpl<T>(expr.field_offset_, index_func, elem_func);
}
}
#pragma clang diagnostic pop
void
ExecExprVisitor::visit(RangeExpr& expr) {
ExecExprVisitor::visit(UnaryRangeExpr& expr) {
auto& field_meta = segment_.get_schema()[expr.field_offset_];
Assert(expr.data_type_ == field_meta.get_data_type());
RetType res;
switch (expr.data_type_) {
case DataType::BOOL: {
res = ExecRangeVisitorDispatcher<bool>(expr);
res = ExecUnaryRangeVisitorDispatcher<bool>(expr);
break;
}
case DataType::INT8: {
res = ExecRangeVisitorDispatcher<int8_t>(expr);
res = ExecUnaryRangeVisitorDispatcher<int8_t>(expr);
break;
}
case DataType::INT16: {
res = ExecRangeVisitorDispatcher<int16_t>(expr);
res = ExecUnaryRangeVisitorDispatcher<int16_t>(expr);
break;
}
case DataType::INT32: {
res = ExecRangeVisitorDispatcher<int32_t>(expr);
res = ExecUnaryRangeVisitorDispatcher<int32_t>(expr);
break;
}
case DataType::INT64: {
res = ExecRangeVisitorDispatcher<int64_t>(expr);
res = ExecUnaryRangeVisitorDispatcher<int64_t>(expr);
break;
}
case DataType::FLOAT: {
res = ExecRangeVisitorDispatcher<float>(expr);
res = ExecUnaryRangeVisitorDispatcher<float>(expr);
break;
}
case DataType::DOUBLE: {
res = ExecRangeVisitorDispatcher<double>(expr);
res = ExecUnaryRangeVisitorDispatcher<double>(expr);
break;
}
default:
PanicInfo("unsupported");
}
Assert(res.size() == row_count_);
ret_ = std::move(res);
}
void
ExecExprVisitor::visit(BinaryRangeExpr& expr) {
auto& field_meta = segment_.get_schema()[expr.field_offset_];
Assert(expr.data_type_ == field_meta.get_data_type());
RetType res;
switch (expr.data_type_) {
case DataType::BOOL: {
res = ExecBinaryRangeVisitorDispatcher<bool>(expr);
break;
}
case DataType::INT8: {
res = ExecBinaryRangeVisitorDispatcher<int8_t>(expr);
break;
}
case DataType::INT16: {
res = ExecBinaryRangeVisitorDispatcher<int16_t>(expr);
break;
}
case DataType::INT32: {
res = ExecBinaryRangeVisitorDispatcher<int32_t>(expr);
break;
}
case DataType::INT64: {
res = ExecBinaryRangeVisitorDispatcher<int64_t>(expr);
break;
}
case DataType::FLOAT: {
res = ExecBinaryRangeVisitorDispatcher<float>(expr);
break;
}
case DataType::DOUBLE: {
res = ExecBinaryRangeVisitorDispatcher<double>(expr);
break;
}
default:
@ -309,11 +353,10 @@ struct relational {
}
};
using number = boost::variant<bool, int8_t, int16_t, int32_t, int64_t, float, double>;
template <typename Op>
auto
ExecExprVisitor::ExecCompareExprDispatcher(CompareExpr& expr, Op op) -> RetType {
using number = boost::variant<bool, int8_t, int16_t, int32_t, int64_t, float, double>;
auto size_per_chunk = segment_.size_per_chunk();
auto num_chunk = upper_div(row_count_, size_per_chunk);
std::deque<RetType> bitsets;
@ -322,39 +365,39 @@ ExecExprVisitor::ExecCompareExprDispatcher(CompareExpr& expr, Op op) -> RetType
auto getChunkData = [&, chunk_id](DataType type, FieldOffset offset) -> std::function<const number(int)> {
switch (type) {
case DataType::BOOL: {
auto chunk = segment_.chunk_data<bool>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<bool>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::INT8: {
auto chunk = segment_.chunk_data<int8_t>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<int8_t>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::INT16: {
auto chunk = segment_.chunk_data<int16_t>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<int16_t>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::INT32: {
auto chunk = segment_.chunk_data<int32_t>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<int32_t>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::INT64: {
auto chunk = segment_.chunk_data<int64_t>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<int64_t>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::FLOAT: {
auto chunk = segment_.chunk_data<float>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<float>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
case DataType::DOUBLE: {
auto chunk = segment_.chunk_data<double>(offset, chunk_id);
return [chunk](int i) -> const number { return chunk.data()[i]; };
auto chunk_data = segment_.chunk_data<double>(offset, chunk_id).data();
return [chunk_data](int i) -> const number { return chunk_data[i]; };
}
default:
PanicInfo("unsupported datatype");
}
};
auto left = getChunkData(expr.data_types_[0], expr.field_offsets_[0]);
auto right = getChunkData(expr.data_types_[1], expr.field_offsets_[1]);
auto left = getChunkData(expr.left_data_type_, expr.left_field_offset_);
auto right = getChunkData(expr.right_data_type_, expr.right_field_offset_);
boost::dynamic_bitset<> bitset(size);
for (int i = 0; i < size; ++i) {
@ -370,17 +413,14 @@ ExecExprVisitor::ExecCompareExprDispatcher(CompareExpr& expr, Op op) -> RetType
void
ExecExprVisitor::visit(CompareExpr& expr) {
Assert(expr.data_types_.size() == expr.field_offsets_.size());
Assert(expr.data_types_.size() == 2);
auto& schema = segment_.get_schema();
for (auto i = 0; i < expr.field_offsets_.size(); i++) {
auto& field_meta = schema[expr.field_offsets_[i]];
Assert(expr.data_types_[i] == field_meta.get_data_type());
}
auto& left_field_meta = schema[expr.left_field_offset_];
auto& right_field_meta = schema[expr.right_field_offset_];
Assert(expr.left_data_type_ == left_field_meta.get_data_type());
Assert(expr.right_data_type_ == right_field_meta.get_data_type());
RetType res;
switch (expr.op) {
switch (expr.op_type_) {
case OpType::Equal: {
res = ExecCompareExprDispatcher(expr, std::equal_to<>{});
break;
@ -426,9 +466,7 @@ ExecExprVisitor::ExecTermVisitorImpl(TermExpr& expr_raw) -> RetType {
std::deque<RetType> bitsets;
for (int64_t chunk_id = 0; chunk_id < num_chunk; ++chunk_id) {
Span<T> chunk = segment_.chunk_data<T>(field_offset, chunk_id);
auto size = chunk_id == num_chunk - 1 ? row_count_ - chunk_id * size_per_chunk : size_per_chunk;
boost::dynamic_bitset<> bitset(size);
for (int i = 0; i < size; ++i) {
auto value = chunk.data()[i];

View File

@ -45,15 +45,19 @@ ExtractInfoExprVisitor::visit(TermExpr& expr) {
}
void
ExtractInfoExprVisitor::visit(RangeExpr& expr) {
ExtractInfoExprVisitor::visit(UnaryRangeExpr& expr) {
plan_info_.add_involved_field(expr.field_offset_);
}
void
ExtractInfoExprVisitor::visit(BinaryRangeExpr& expr) {
plan_info_.add_involved_field(expr.field_offset_);
}
void
ExtractInfoExprVisitor::visit(CompareExpr& expr) {
for (auto& field_offset : expr.field_offsets_) {
plan_info_.add_involved_field(field_offset);
}
plan_info_.add_involved_field(expr.left_field_offset_);
plan_info_.add_involved_field(expr.right_field_offset_);
}
} // namespace milvus::query

View File

@ -10,12 +10,9 @@
// or implied. See the License for the specific language governing permissions and limitations under the License
#include "query/Plan.h"
#include "exceptions/EasyAssert.h"
#include "utils/Json.h"
#include <utility>
#include "query/generated/ShowExprVisitor.h"
#include "query/ExprImpl.h"
#include "pb/plan.pb.h"
namespace milvus::query {
using Json = nlohmann::json;
@ -145,49 +142,96 @@ ShowExprVisitor::visit(TermExpr& expr) {
template <typename T>
static Json
ConditionExtract(const RangeExpr& expr_raw) {
UnaryRangeExtract(const UnaryRangeExpr& expr_raw) {
using proto::plan::OpType;
using proto::plan::OpType_Name;
auto expr = dynamic_cast<const RangeExprImpl<T>*>(&expr_raw);
auto expr = dynamic_cast<const UnaryRangeExprImpl<T>*>(&expr_raw);
Assert(expr);
std::map<std::string, T> mapping;
for (auto [op, v] : expr->conditions_) {
auto op_name = OpType_Name(static_cast<OpType>(op));
mapping[op_name] = v;
}
return mapping;
Json res{{"expr_type", "UnaryRange"},
{"field_offset", expr->field_offset_.get()},
{"data_type", datatype_name(expr->data_type_)},
{"op", OpType_Name(static_cast<OpType>(expr->op_type_))},
{"value", expr->value_}};
return res;
}
void
ShowExprVisitor::visit(RangeExpr& expr) {
ShowExprVisitor::visit(UnaryRangeExpr& expr) {
Assert(!ret_.has_value());
Assert(datatype_is_vector(expr.data_type_) == false);
auto conditions = [&] {
switch (expr.data_type_) {
case DataType::BOOL:
return ConditionExtract<bool>(expr);
case DataType::INT8:
return ConditionExtract<int8_t>(expr);
case DataType::INT16:
return ConditionExtract<int16_t>(expr);
case DataType::INT32:
return ConditionExtract<int32_t>(expr);
case DataType::INT64:
return ConditionExtract<int64_t>(expr);
case DataType::DOUBLE:
return ConditionExtract<double>(expr);
case DataType::FLOAT:
return ConditionExtract<float>(expr);
default:
PanicInfo("unsupported type");
}
}();
switch (expr.data_type_) {
case DataType::BOOL:
ret_ = UnaryRangeExtract<bool>(expr);
return;
case DataType::INT8:
ret_ = UnaryRangeExtract<int8_t>(expr);
return;
case DataType::INT16:
ret_ = UnaryRangeExtract<int16_t>(expr);
return;
case DataType::INT32:
ret_ = UnaryRangeExtract<int32_t>(expr);
return;
case DataType::INT64:
ret_ = UnaryRangeExtract<int64_t>(expr);
return;
case DataType::DOUBLE:
ret_ = UnaryRangeExtract<double>(expr);
return;
case DataType::FLOAT:
ret_ = UnaryRangeExtract<float>(expr);
return;
default:
PanicInfo("unsupported type");
}
}
Json res{{"expr_type", "Range"},
{"field_offset", expr.field_offset_.get()},
{"data_type", datatype_name(expr.data_type_)},
{"conditions", std::move(conditions)}};
ret_ = res;
template <typename T>
static Json
BinaryRangeExtract(const BinaryRangeExpr& expr_raw) {
using proto::plan::OpType;
using proto::plan::OpType_Name;
auto expr = dynamic_cast<const BinaryRangeExprImpl<T>*>(&expr_raw);
Assert(expr);
Json res{{"expr_type", "BinaryRange"},
{"field_offset", expr->field_offset_.get()},
{"data_type", datatype_name(expr->data_type_)},
{"lower_inclusive", expr->lower_inclusive_},
{"upper_inclusive", expr->upper_inclusive_},
{"lower_value", expr->lower_value_},
{"upper_value", expr->upper_value_}};
return res;
}
void
ShowExprVisitor::visit(BinaryRangeExpr& expr) {
Assert(!ret_.has_value());
Assert(datatype_is_vector(expr.data_type_) == false);
switch (expr.data_type_) {
case DataType::BOOL:
ret_ = BinaryRangeExtract<bool>(expr);
return;
case DataType::INT8:
ret_ = BinaryRangeExtract<int8_t>(expr);
return;
case DataType::INT16:
ret_ = BinaryRangeExtract<int16_t>(expr);
return;
case DataType::INT32:
ret_ = BinaryRangeExtract<int32_t>(expr);
return;
case DataType::INT64:
ret_ = BinaryRangeExtract<int64_t>(expr);
return;
case DataType::DOUBLE:
ret_ = BinaryRangeExtract<double>(expr);
return;
case DataType::FLOAT:
ret_ = BinaryRangeExtract<float>(expr);
return;
default:
PanicInfo("unsupported type");
}
}
void
@ -196,19 +240,12 @@ ShowExprVisitor::visit(CompareExpr& expr) {
using proto::plan::OpType_Name;
Assert(!ret_.has_value());
Json offsets;
for (auto& offset : expr.field_offsets_) {
offsets.emplace_back(offset.get());
}
Json types;
for (auto& datatype : expr.data_types_) {
types.emplace_back(datatype_name(datatype));
}
Json res{{"expr_type", "Compare"},
{"fields_offset", offsets},
{"datas_type", types},
{"op", OpType_Name(static_cast<OpType>(expr.op))}};
{"left_field_offset", expr.left_field_offset_.get()},
{"left_data_type", datatype_name(expr.left_data_type_)},
{"right_field_offset", expr.right_field_offset_.get()},
{"right_data_type", datatype_name(expr.right_data_type_)},
{"op", OpType_Name(static_cast<OpType>(expr.op_type_))}};
ret_ = res;
}
} // namespace milvus::query

View File

@ -28,7 +28,17 @@ VerifyExprVisitor::visit(TermExpr& expr) {
}
void
VerifyExprVisitor::visit(RangeExpr& expr) {
VerifyExprVisitor::visit(UnaryRangeExpr& expr) {
// TODO
}
void
VerifyExprVisitor::visit(BinaryRangeExpr& expr) {
// TODO
}
void
VerifyExprVisitor::visit(CompareExpr& expr) {
// TODO
}

View File

@ -146,11 +146,15 @@ generate_collection_schema(std::string metric_type, int dim, bool is_binary) {
dim_param->set_value(std::to_string(dim));
auto other_field_schema = collection_schema.add_fields();
;
other_field_schema->set_name("counter");
other_field_schema->set_fieldid(101);
other_field_schema->set_data_type(schema::DataType::Int64);
auto other_field_schema2 = collection_schema.add_fields();
other_field_schema2->set_name("doubleField");
other_field_schema2->set_fieldid(102);
other_field_schema2->set_data_type(schema::DataType::Double);
std::string schema_string;
auto marshal = google::protobuf::TextFormat::PrintToString(collection_schema, &schema_string);
assert(marshal == true);
@ -1107,25 +1111,25 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Range) {
binary_expr: <
op: LogicalAnd
left: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: GreaterEqual
values: <
op: GreaterEqual
value: <
int64_val: 420000
>
>
>
right: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: LessThan
values: <
op: LessThan
value: <
int64_val: 420010
>
>
@ -1385,95 +1389,39 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Term) {
dataset.raw_.raw_data, dataset.raw_.sizeof_per_row, dataset.raw_.count);
assert(ins_res.error_code == Success);
const char* serialized_expr_plan = R"(vector_anns: <
field_id: 100
predicates: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420000
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420001
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420002
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420003
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420004
>
>
>
>
>
query_info: <
topk: 5
metric_type: "L2"
search_params: "{\"nprobe\": 10}"
>
placeholder_tag: "$0"
>)";
const char* serialized_expr_plan = R"(
vector_anns: <
field_id: 100
predicates: <
term_expr: <
column_info: <
field_id: 101
data_type: Int64
>
values: <
int64_val: 420000
>
values: <
int64_val: 420001
>
values: <
int64_val: 420002
>
values: <
int64_val: 420003
>
values: <
int64_val: 420004
>
>
>
query_info: <
topk: 5
metric_type: "L2"
search_params: "{\"nprobe\": 10}"
>
placeholder_tag: "$0"
>)";
// create place_holder_group
int num_queries = 5;
@ -1728,25 +1676,25 @@ TEST(CApiTest, Indexing_Expr_With_binary_Predicate_Range) {
binary_expr: <
op: LogicalAnd
left: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: GreaterEqual
values: <
op: GreaterEqual
value: <
int64_val: 420000
>
>
>
right: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: LessThan
values: <
op: LessThan
value: <
int64_val: 420010
>
>
@ -2015,95 +1963,39 @@ TEST(CApiTest, Indexing_Expr_With_binary_Predicate_Term) {
dataset.raw_.raw_data, dataset.raw_.sizeof_per_row, dataset.raw_.count);
assert(ins_res.error_code == Success);
const char* serialized_expr_plan = R"(vector_anns: <
field_id: 100
predicates: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
binary_expr: <
op: LogicalOr
left: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420000
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420001
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420002
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420003
>
>
>
>
>
right: <
range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: Equal
values: <
int64_val: 420004
>
>
>
>
>
query_info: <
topk: 5
metric_type: "JACCARD"
search_params: "{\"nprobe\": 10}"
>
placeholder_tag: "$0"
>)";
const char* serialized_expr_plan = R"(
vector_anns: <
field_id: 100
predicates: <
term_expr: <
column_info: <
field_id: 101
data_type: Int64
>
values: <
int64_val: 420000
>
values: <
int64_val: 420001
>
values: <
int64_val: 420002
>
values: <
int64_val: 420003
>
values: <
int64_val: 420004
>
>
>
query_info: <
topk: 5
metric_type: "JACCARD"
search_params: "{\"nprobe\": 10}"
>
placeholder_tag: "$0"
>)";
// create place_holder_group
int num_queries = 5;
@ -2422,25 +2314,25 @@ TEST(CApiTest, SealedSegment_search_float_With_Expr_Predicate_Range) {
binary_expr: <
op: LogicalAnd
left: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: GreaterEqual
values: <
op: GreaterEqual
value: <
int64_val: 420000
>
>
>
right: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 101
data_type: Int64
>
ops: LessThan
values: <
op: LessThan
value: <
int64_val: 420010
>
>

View File

@ -11,7 +11,6 @@
#include <tuple>
#include <map>
#include <math.h>
#include <gtest/gtest.h>
#include <google/protobuf/text_format.h>
@ -21,7 +20,6 @@
#include "indexbuilder/IndexWrapper.h"
#include "indexbuilder/index_c.h"
#include "test_utils/DataGen.h"
#include "index/knowhere/knowhere/index/vector_index/VecIndexFactory.h"
#include "indexbuilder/utils.h"
#include "test_utils/indexbuilder_test_utils.h"
@ -355,27 +353,26 @@ TEST(BinIdMapWrapper, Build) {
INSTANTIATE_TEST_CASE_P(
IndexTypeParameters,
IndexWrapperTest,
::testing::Values(std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IDMAP, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFPQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFFLAT, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFSQ8, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT,
milvus::knowhere::Metric::JACCARD),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT,
milvus::knowhere::Metric::TANIMOTO),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP, milvus::knowhere::Metric::JACCARD),
::testing::Values(
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IDMAP, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFPQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFFLAT, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_IVFSQ8, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT, milvus::knowhere::Metric::JACCARD),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT, milvus::knowhere::Metric::TANIMOTO),
std::pair(milvus::knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP, milvus::knowhere::Metric::JACCARD),
#ifdef MILVUS_SUPPORT_SPTAG
std::pair(milvus::knowhere::IndexEnum::INDEX_SPTAG_KDT_RNT, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_SPTAG_BKT_RNT, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_SPTAG_KDT_RNT, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_SPTAG_BKT_RNT, milvus::knowhere::Metric::L2),
#endif
std::pair(milvus::knowhere::IndexEnum::INDEX_HNSW, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_ANNOY, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWFlat, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWPQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWSQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NGTPANNG, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NGTONNG, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NSG, milvus::knowhere::Metric::L2)));
std::pair(milvus::knowhere::IndexEnum::INDEX_HNSW, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_ANNOY, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWFlat, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWPQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_RHNSWSQ, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NGTPANNG, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NGTONNG, milvus::knowhere::Metric::L2),
std::pair(milvus::knowhere::IndexEnum::INDEX_NSG, milvus::knowhere::Metric::L2)));
TEST_P(IndexWrapperTest, Constructor) {
auto index =

View File

@ -79,13 +79,13 @@ TEST_P(PlanProtoTest, Range) {
vector_anns: <
field_id: 201
predicates: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: %1%
data_type: %2%
>
ops: GreaterThan
values: <
op: GreaterThan
value: <
%3%: 3
>
>
@ -229,7 +229,7 @@ vector_anns: <
plan->check_identical(*ref_plan);
}
TEST(PlanProtoXTest, NotExpr) {
TEST(PlanProtoTest, NotExpr) {
auto schema = getStandardSchema();
// xxx.query(predicates = "not (int64field > 3)", topk = 10, ...)
auto data_type = spb::DataType::Int64;
@ -250,13 +250,13 @@ vector_anns: <
unary_expr: <
op: Not
child: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: %1%
data_type: %2%
>
ops: GreaterThan
values: <
op: GreaterThan
value: <
%3%: 3
>
>
@ -320,7 +320,7 @@ vector_anns: <
plan->check_identical(*ref_plan);
}
TEST(PlanProtoXTest, AndOrExpr) {
TEST(PlanProtoTest, AndOrExpr) {
auto schema = getStandardSchema();
// xxx.query(predicates = "(int64field < 3) && (int64field > 2 || int64field == 1)", topk = 10, ...)
auto data_type = spb::DataType::Int64;
@ -341,13 +341,13 @@ vector_anns: <
binary_expr: <
op: LogicalAnd
left: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 105
data_type: Int64
>
ops: LessThan
values: <
op: LessThan
value: <
int64_val: 3
>
>
@ -356,25 +356,25 @@ vector_anns: <
binary_expr: <
op: LogicalOr
left: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 105
data_type: Int64
>
ops: GreaterThan
values: <
op: GreaterThan
value: <
int64_val: 2
>
>
>
right: <
range_expr: <
unary_range_expr: <
column_info: <
field_id: 105
data_type: Int64
>
ops: Equal
values: <
op: Equal
value: <
int64_val: 1
>
>
@ -470,11 +470,11 @@ vector_anns: <
field_id: 201
predicates: <
compare_expr: <
columns_info: <
left_column_info: <
field_id: 128
data_type: Int64
>
columns_info: <
right_column_info: <
field_id: %1%
data_type: %2%
>

View File

@ -35,15 +35,24 @@ message ColumnInfo {
bool is_autoID = 4;
}
message RangeExpr {
message UnaryRangeExpr {
ColumnInfo column_info = 1;
repeated OpType ops = 2;
repeated GenericValue values = 3;
OpType op = 2;
GenericValue value = 3;
}
message BinaryRangeExpr {
ColumnInfo column_info = 1;
bool lower_inclusive = 2;
bool upper_inclusive = 3;
GenericValue lower_value = 4;
GenericValue upper_value = 5;
}
message CompareExpr {
repeated ColumnInfo columns_info = 1;
OpType op = 2;
ColumnInfo left_column_info = 1;
ColumnInfo right_column_info = 2;
OpType op = 3;
}
message TermExpr {
@ -73,11 +82,12 @@ message BinaryExpr {
message Expr {
oneof expr {
RangeExpr range_expr = 1;
TermExpr term_expr = 2;
UnaryExpr unary_expr = 3;
BinaryExpr binary_expr = 4;
CompareExpr compare_expr = 5;
TermExpr term_expr = 1;
UnaryExpr unary_expr = 2;
BinaryExpr binary_expr = 3;
CompareExpr compare_expr = 4;
UnaryRangeExpr unary_range_expr = 5;
BinaryRangeExpr binary_range_expr = 6;
};
}

View File

@ -83,7 +83,7 @@ func (x UnaryExpr_UnaryOp) String() string {
}
func (UnaryExpr_UnaryOp) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{6, 0}
return fileDescriptor_2d655ab2f7683c23, []int{7, 0}
}
type BinaryExpr_BinaryOp int32
@ -111,7 +111,7 @@ func (x BinaryExpr_BinaryOp) String() string {
}
func (BinaryExpr_BinaryOp) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{7, 0}
return fileDescriptor_2d655ab2f7683c23, []int{8, 0}
}
type GenericValue struct {
@ -327,74 +327,146 @@ func (m *ColumnInfo) GetIsAutoID() bool {
return false
}
type RangeExpr struct {
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
Ops []OpType `protobuf:"varint,2,rep,packed,name=ops,proto3,enum=milvus.proto.plan.OpType" json:"ops,omitempty"`
Values []*GenericValue `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
type UnaryRangeExpr struct {
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
Op OpType `protobuf:"varint,2,opt,name=op,proto3,enum=milvus.proto.plan.OpType" json:"op,omitempty"`
Value *GenericValue `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RangeExpr) Reset() { *m = RangeExpr{} }
func (m *RangeExpr) String() string { return proto.CompactTextString(m) }
func (*RangeExpr) ProtoMessage() {}
func (*RangeExpr) Descriptor() ([]byte, []int) {
func (m *UnaryRangeExpr) Reset() { *m = UnaryRangeExpr{} }
func (m *UnaryRangeExpr) String() string { return proto.CompactTextString(m) }
func (*UnaryRangeExpr) ProtoMessage() {}
func (*UnaryRangeExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{3}
}
func (m *RangeExpr) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RangeExpr.Unmarshal(m, b)
func (m *UnaryRangeExpr) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UnaryRangeExpr.Unmarshal(m, b)
}
func (m *RangeExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RangeExpr.Marshal(b, m, deterministic)
func (m *UnaryRangeExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UnaryRangeExpr.Marshal(b, m, deterministic)
}
func (m *RangeExpr) XXX_Merge(src proto.Message) {
xxx_messageInfo_RangeExpr.Merge(m, src)
func (m *UnaryRangeExpr) XXX_Merge(src proto.Message) {
xxx_messageInfo_UnaryRangeExpr.Merge(m, src)
}
func (m *RangeExpr) XXX_Size() int {
return xxx_messageInfo_RangeExpr.Size(m)
func (m *UnaryRangeExpr) XXX_Size() int {
return xxx_messageInfo_UnaryRangeExpr.Size(m)
}
func (m *RangeExpr) XXX_DiscardUnknown() {
xxx_messageInfo_RangeExpr.DiscardUnknown(m)
func (m *UnaryRangeExpr) XXX_DiscardUnknown() {
xxx_messageInfo_UnaryRangeExpr.DiscardUnknown(m)
}
var xxx_messageInfo_RangeExpr proto.InternalMessageInfo
var xxx_messageInfo_UnaryRangeExpr proto.InternalMessageInfo
func (m *RangeExpr) GetColumnInfo() *ColumnInfo {
func (m *UnaryRangeExpr) GetColumnInfo() *ColumnInfo {
if m != nil {
return m.ColumnInfo
}
return nil
}
func (m *RangeExpr) GetOps() []OpType {
func (m *UnaryRangeExpr) GetOp() OpType {
if m != nil {
return m.Ops
return m.Op
}
return OpType_Invalid
}
func (m *UnaryRangeExpr) GetValue() *GenericValue {
if m != nil {
return m.Value
}
return nil
}
func (m *RangeExpr) GetValues() []*GenericValue {
type BinaryRangeExpr struct {
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
LowerInclusive bool `protobuf:"varint,2,opt,name=lower_inclusive,json=lowerInclusive,proto3" json:"lower_inclusive,omitempty"`
UpperInclusive bool `protobuf:"varint,3,opt,name=upper_inclusive,json=upperInclusive,proto3" json:"upper_inclusive,omitempty"`
LowerValue *GenericValue `protobuf:"bytes,4,opt,name=lower_value,json=lowerValue,proto3" json:"lower_value,omitempty"`
UpperValue *GenericValue `protobuf:"bytes,5,opt,name=upper_value,json=upperValue,proto3" json:"upper_value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BinaryRangeExpr) Reset() { *m = BinaryRangeExpr{} }
func (m *BinaryRangeExpr) String() string { return proto.CompactTextString(m) }
func (*BinaryRangeExpr) ProtoMessage() {}
func (*BinaryRangeExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{4}
}
func (m *BinaryRangeExpr) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BinaryRangeExpr.Unmarshal(m, b)
}
func (m *BinaryRangeExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BinaryRangeExpr.Marshal(b, m, deterministic)
}
func (m *BinaryRangeExpr) XXX_Merge(src proto.Message) {
xxx_messageInfo_BinaryRangeExpr.Merge(m, src)
}
func (m *BinaryRangeExpr) XXX_Size() int {
return xxx_messageInfo_BinaryRangeExpr.Size(m)
}
func (m *BinaryRangeExpr) XXX_DiscardUnknown() {
xxx_messageInfo_BinaryRangeExpr.DiscardUnknown(m)
}
var xxx_messageInfo_BinaryRangeExpr proto.InternalMessageInfo
func (m *BinaryRangeExpr) GetColumnInfo() *ColumnInfo {
if m != nil {
return m.Values
return m.ColumnInfo
}
return nil
}
func (m *BinaryRangeExpr) GetLowerInclusive() bool {
if m != nil {
return m.LowerInclusive
}
return false
}
func (m *BinaryRangeExpr) GetUpperInclusive() bool {
if m != nil {
return m.UpperInclusive
}
return false
}
func (m *BinaryRangeExpr) GetLowerValue() *GenericValue {
if m != nil {
return m.LowerValue
}
return nil
}
func (m *BinaryRangeExpr) GetUpperValue() *GenericValue {
if m != nil {
return m.UpperValue
}
return nil
}
type CompareExpr struct {
ColumnsInfo []*ColumnInfo `protobuf:"bytes,1,rep,name=columns_info,json=columnsInfo,proto3" json:"columns_info,omitempty"`
Op OpType `protobuf:"varint,2,opt,name=op,proto3,enum=milvus.proto.plan.OpType" json:"op,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
LeftColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=left_column_info,json=leftColumnInfo,proto3" json:"left_column_info,omitempty"`
RightColumnInfo *ColumnInfo `protobuf:"bytes,2,opt,name=right_column_info,json=rightColumnInfo,proto3" json:"right_column_info,omitempty"`
Op OpType `protobuf:"varint,3,opt,name=op,proto3,enum=milvus.proto.plan.OpType" json:"op,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CompareExpr) Reset() { *m = CompareExpr{} }
func (m *CompareExpr) String() string { return proto.CompactTextString(m) }
func (*CompareExpr) ProtoMessage() {}
func (*CompareExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{4}
return fileDescriptor_2d655ab2f7683c23, []int{5}
}
func (m *CompareExpr) XXX_Unmarshal(b []byte) error {
@ -415,9 +487,16 @@ func (m *CompareExpr) XXX_DiscardUnknown() {
var xxx_messageInfo_CompareExpr proto.InternalMessageInfo
func (m *CompareExpr) GetColumnsInfo() []*ColumnInfo {
func (m *CompareExpr) GetLeftColumnInfo() *ColumnInfo {
if m != nil {
return m.ColumnsInfo
return m.LeftColumnInfo
}
return nil
}
func (m *CompareExpr) GetRightColumnInfo() *ColumnInfo {
if m != nil {
return m.RightColumnInfo
}
return nil
}
@ -441,7 +520,7 @@ func (m *TermExpr) Reset() { *m = TermExpr{} }
func (m *TermExpr) String() string { return proto.CompactTextString(m) }
func (*TermExpr) ProtoMessage() {}
func (*TermExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{5}
return fileDescriptor_2d655ab2f7683c23, []int{6}
}
func (m *TermExpr) XXX_Unmarshal(b []byte) error {
@ -488,7 +567,7 @@ func (m *UnaryExpr) Reset() { *m = UnaryExpr{} }
func (m *UnaryExpr) String() string { return proto.CompactTextString(m) }
func (*UnaryExpr) ProtoMessage() {}
func (*UnaryExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{6}
return fileDescriptor_2d655ab2f7683c23, []int{7}
}
func (m *UnaryExpr) XXX_Unmarshal(b []byte) error {
@ -536,7 +615,7 @@ func (m *BinaryExpr) Reset() { *m = BinaryExpr{} }
func (m *BinaryExpr) String() string { return proto.CompactTextString(m) }
func (*BinaryExpr) ProtoMessage() {}
func (*BinaryExpr) Descriptor() ([]byte, []int) {
return fileDescriptor_2d655ab2f7683c23, []int{7}
return fileDescriptor_2d655ab2f7683c23, []int{8}
}
func (m *BinaryExpr) XXX_Unmarshal(b []byte) error {
@ -580,11 +659,12 @@ func (m *BinaryExpr) GetRight() *Expr {
type Expr struct {
// Types that are valid to be assigned to Expr:
// *Expr_RangeExpr
// *Expr_TermExpr
// *Expr_UnaryExpr
// *Expr_BinaryExpr
// *Expr_CompareExpr
// *Expr_UnaryRangeExpr
// *Expr_BinaryRangeExpr
Expr isExpr_Expr `protobuf_oneof:"expr"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -595,7 +675,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{8}
return fileDescriptor_2d655ab2f7683c23, []int{9}
}
func (m *Expr) XXX_Unmarshal(b []byte) error {
@ -620,27 +700,29 @@ type isExpr_Expr interface {
isExpr_Expr()
}
type Expr_RangeExpr struct {
RangeExpr *RangeExpr `protobuf:"bytes,1,opt,name=range_expr,json=rangeExpr,proto3,oneof"`
}
type Expr_TermExpr struct {
TermExpr *TermExpr `protobuf:"bytes,2,opt,name=term_expr,json=termExpr,proto3,oneof"`
TermExpr *TermExpr `protobuf:"bytes,1,opt,name=term_expr,json=termExpr,proto3,oneof"`
}
type Expr_UnaryExpr struct {
UnaryExpr *UnaryExpr `protobuf:"bytes,3,opt,name=unary_expr,json=unaryExpr,proto3,oneof"`
UnaryExpr *UnaryExpr `protobuf:"bytes,2,opt,name=unary_expr,json=unaryExpr,proto3,oneof"`
}
type Expr_BinaryExpr struct {
BinaryExpr *BinaryExpr `protobuf:"bytes,4,opt,name=binary_expr,json=binaryExpr,proto3,oneof"`
BinaryExpr *BinaryExpr `protobuf:"bytes,3,opt,name=binary_expr,json=binaryExpr,proto3,oneof"`
}
type Expr_CompareExpr struct {
CompareExpr *CompareExpr `protobuf:"bytes,5,opt,name=compare_expr,json=compareExpr,proto3,oneof"`
CompareExpr *CompareExpr `protobuf:"bytes,4,opt,name=compare_expr,json=compareExpr,proto3,oneof"`
}
func (*Expr_RangeExpr) isExpr_Expr() {}
type Expr_UnaryRangeExpr struct {
UnaryRangeExpr *UnaryRangeExpr `protobuf:"bytes,5,opt,name=unary_range_expr,json=unaryRangeExpr,proto3,oneof"`
}
type Expr_BinaryRangeExpr struct {
BinaryRangeExpr *BinaryRangeExpr `protobuf:"bytes,6,opt,name=binary_range_expr,json=binaryRangeExpr,proto3,oneof"`
}
func (*Expr_TermExpr) isExpr_Expr() {}
@ -650,6 +732,10 @@ func (*Expr_BinaryExpr) isExpr_Expr() {}
func (*Expr_CompareExpr) isExpr_Expr() {}
func (*Expr_UnaryRangeExpr) isExpr_Expr() {}
func (*Expr_BinaryRangeExpr) isExpr_Expr() {}
func (m *Expr) GetExpr() isExpr_Expr {
if m != nil {
return m.Expr
@ -657,13 +743,6 @@ func (m *Expr) GetExpr() isExpr_Expr {
return nil
}
func (m *Expr) GetRangeExpr() *RangeExpr {
if x, ok := m.GetExpr().(*Expr_RangeExpr); ok {
return x.RangeExpr
}
return nil
}
func (m *Expr) GetTermExpr() *TermExpr {
if x, ok := m.GetExpr().(*Expr_TermExpr); ok {
return x.TermExpr
@ -692,14 +771,29 @@ func (m *Expr) GetCompareExpr() *CompareExpr {
return nil
}
func (m *Expr) GetUnaryRangeExpr() *UnaryRangeExpr {
if x, ok := m.GetExpr().(*Expr_UnaryRangeExpr); ok {
return x.UnaryRangeExpr
}
return nil
}
func (m *Expr) GetBinaryRangeExpr() *BinaryRangeExpr {
if x, ok := m.GetExpr().(*Expr_BinaryRangeExpr); ok {
return x.BinaryRangeExpr
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*Expr) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*Expr_RangeExpr)(nil),
(*Expr_TermExpr)(nil),
(*Expr_UnaryExpr)(nil),
(*Expr_BinaryExpr)(nil),
(*Expr_CompareExpr)(nil),
(*Expr_UnaryRangeExpr)(nil),
(*Expr_BinaryRangeExpr)(nil),
}
}
@ -718,7 +812,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{9}
return fileDescriptor_2d655ab2f7683c23, []int{10}
}
func (m *VectorANNS) XXX_Unmarshal(b []byte) error {
@ -788,7 +882,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{10}
return fileDescriptor_2d655ab2f7683c23, []int{11}
}
func (m *PlanNode) XXX_Unmarshal(b []byte) error {
@ -854,7 +948,8 @@ func init() {
proto.RegisterType((*GenericValue)(nil), "milvus.proto.plan.GenericValue")
proto.RegisterType((*QueryInfo)(nil), "milvus.proto.plan.QueryInfo")
proto.RegisterType((*ColumnInfo)(nil), "milvus.proto.plan.ColumnInfo")
proto.RegisterType((*RangeExpr)(nil), "milvus.proto.plan.RangeExpr")
proto.RegisterType((*UnaryRangeExpr)(nil), "milvus.proto.plan.UnaryRangeExpr")
proto.RegisterType((*BinaryRangeExpr)(nil), "milvus.proto.plan.BinaryRangeExpr")
proto.RegisterType((*CompareExpr)(nil), "milvus.proto.plan.CompareExpr")
proto.RegisterType((*TermExpr)(nil), "milvus.proto.plan.TermExpr")
proto.RegisterType((*UnaryExpr)(nil), "milvus.proto.plan.UnaryExpr")
@ -867,65 +962,71 @@ func init() {
func init() { proto.RegisterFile("plan.proto", fileDescriptor_2d655ab2f7683c23) }
var fileDescriptor_2d655ab2f7683c23 = []byte{
// 951 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcf, 0x6e, 0x1b, 0x45,
0x18, 0xf7, 0x7a, 0x9d, 0x64, 0xf7, 0xb3, 0xeb, 0x9a, 0xb9, 0x90, 0x12, 0x4a, 0xa2, 0xa5, 0x02,
0x43, 0xd5, 0x44, 0xa4, 0x55, 0x2a, 0x15, 0x15, 0x35, 0x49, 0x4b, 0x13, 0x51, 0x39, 0x61, 0x09,
0x39, 0x70, 0x59, 0x8d, 0x77, 0xc7, 0xf6, 0xa8, 0xb3, 0x33, 0x93, 0xd9, 0x59, 0xab, 0xe6, 0xc0,
0x85, 0x27, 0xe0, 0x25, 0xb8, 0xf3, 0x24, 0x5c, 0xb9, 0xf3, 0x22, 0x68, 0x66, 0xd6, 0xeb, 0x18,
0x39, 0xa9, 0x90, 0xb8, 0xcd, 0x7c, 0x7f, 0xe6, 0xfb, 0xfd, 0xbe, 0x7f, 0x03, 0x20, 0x19, 0xe6,
0xbb, 0x52, 0x09, 0x2d, 0xd0, 0x07, 0x39, 0x65, 0xd3, 0xb2, 0x70, 0xb7, 0x5d, 0xa3, 0xf8, 0xa8,
0x53, 0xa4, 0x13, 0x92, 0x63, 0x27, 0x8a, 0x24, 0x74, 0x5e, 0x13, 0x4e, 0x14, 0x4d, 0x2f, 0x31,
0x2b, 0x09, 0xda, 0x82, 0x60, 0x28, 0x04, 0x4b, 0xa6, 0x98, 0x6d, 0x7a, 0x3b, 0x5e, 0x3f, 0x38,
0x69, 0xc4, 0x1b, 0x46, 0x72, 0x89, 0x19, 0xba, 0x0f, 0x21, 0xe5, 0xfa, 0xe0, 0x89, 0xd5, 0x36,
0x77, 0xbc, 0xbe, 0x7f, 0xd2, 0x88, 0x03, 0x2b, 0xaa, 0xd4, 0x23, 0x26, 0xb0, 0xb6, 0x6a, 0x7f,
0xc7, 0xeb, 0x7b, 0x46, 0x6d, 0x45, 0x97, 0x98, 0x1d, 0xad, 0x81, 0x3f, 0xc5, 0x2c, 0x22, 0x10,
0x7e, 0x5f, 0x12, 0x35, 0x3b, 0xe5, 0x23, 0x81, 0x10, 0xb4, 0xb4, 0x90, 0x6f, 0x6d, 0x28, 0x3f,
0xb6, 0x67, 0xb4, 0x0d, 0xed, 0x9c, 0x68, 0x45, 0xd3, 0x44, 0xcf, 0x24, 0xb1, 0x0f, 0x85, 0x31,
0x38, 0xd1, 0xc5, 0x4c, 0x12, 0xf4, 0x29, 0xdc, 0x29, 0x08, 0x56, 0xe9, 0x24, 0x91, 0x58, 0xe1,
0xbc, 0xd8, 0x6c, 0x59, 0x93, 0x8e, 0x13, 0x9e, 0x5b, 0x59, 0xf4, 0xbb, 0x07, 0x70, 0x2c, 0x58,
0x99, 0x73, 0x1b, 0xe8, 0x1e, 0x04, 0x23, 0x4a, 0x58, 0x96, 0xd0, 0xac, 0x0a, 0xb6, 0x61, 0xef,
0xa7, 0x19, 0x7a, 0x06, 0x61, 0x86, 0x35, 0x76, 0xd1, 0x0c, 0xab, 0xee, 0xfe, 0xfd, 0xdd, 0xa5,
0xbc, 0x55, 0x19, 0x7b, 0x89, 0x35, 0x36, 0x00, 0xe2, 0x20, 0xab, 0x4e, 0xe8, 0x01, 0x74, 0x69,
0x91, 0x48, 0x45, 0x73, 0xac, 0x66, 0xc9, 0x5b, 0x32, 0xb3, 0x70, 0x83, 0xb8, 0x43, 0x8b, 0x73,
0x27, 0xfc, 0x8e, 0xcc, 0xd0, 0x16, 0x84, 0xb4, 0x48, 0x70, 0xa9, 0xc5, 0xe9, 0x4b, 0x0b, 0x36,
0x88, 0x03, 0x5a, 0x1c, 0xda, 0x7b, 0xf4, 0x87, 0x07, 0x61, 0x8c, 0xf9, 0x98, 0xbc, 0x7a, 0x27,
0x15, 0xfa, 0x06, 0xda, 0xa9, 0x45, 0x9d, 0x50, 0x3e, 0x12, 0x16, 0x6a, 0xfb, 0xdf, 0x70, 0x6c,
0x7d, 0x17, 0xdc, 0x62, 0x48, 0x17, 0x3c, 0x1f, 0x82, 0x2f, 0x64, 0xb1, 0xd9, 0xdc, 0xf1, 0xfb,
0xdd, 0xfd, 0x7b, 0x2b, 0xfc, 0xce, 0xa4, 0xa5, 0x60, 0xac, 0xd0, 0x53, 0x58, 0x9f, 0x9a, 0xaa,
0x17, 0x9b, 0xfe, 0x8e, 0xdf, 0x6f, 0xef, 0x6f, 0xaf, 0xb0, 0xbf, 0xde, 0x1d, 0x71, 0x65, 0x1e,
0xfd, 0x0c, 0xed, 0x63, 0x91, 0x4b, 0xac, 0x1c, 0xe8, 0x17, 0xd0, 0x71, 0x10, 0x8a, 0x39, 0x6a,
0xff, 0xfd, 0xa8, 0x2b, 0x9e, 0x85, 0x85, 0xfd, 0x05, 0x34, 0x85, 0xac, 0x92, 0x7f, 0x0b, 0xea,
0xa6, 0x90, 0xd1, 0xaf, 0x1e, 0x04, 0x17, 0x44, 0xe5, 0xff, 0x4b, 0xba, 0x16, 0x19, 0x68, 0xfe,
0xb7, 0x0c, 0xfc, 0xe6, 0x41, 0xf8, 0x23, 0xc7, 0x6a, 0x66, 0x61, 0x3c, 0xb1, 0xf0, 0x3d, 0x0b,
0xff, 0xc1, 0x8a, 0x27, 0x6a, 0x4b, 0x77, 0x3a, 0x93, 0x86, 0x09, 0x7a, 0x04, 0x6b, 0xe9, 0x84,
0xb2, 0xcc, 0xf2, 0x6e, 0xef, 0x7f, 0xb8, 0xc2, 0xd1, 0xf8, 0xc4, 0xce, 0x2a, 0xda, 0x86, 0x8d,
0xca, 0x1b, 0xb5, 0x61, 0xe3, 0x94, 0x4f, 0x31, 0xa3, 0x59, 0xaf, 0x81, 0x36, 0xc0, 0x1f, 0x08,
0xdd, 0xf3, 0xa2, 0xbf, 0x3c, 0x80, 0x23, 0x5a, 0x83, 0x3a, 0xb8, 0x06, 0xea, 0xb3, 0x15, 0x6f,
0x2f, 0x4c, 0xab, 0x63, 0x05, 0xeb, 0x21, 0xb4, 0x18, 0x19, 0xe9, 0xf7, 0xa1, 0xb2, 0x46, 0x86,
0x83, 0xa2, 0xe3, 0x89, 0xb6, 0x7d, 0x7f, 0x1b, 0x07, 0x6b, 0x15, 0x1d, 0x40, 0x30, 0x8f, 0xb5,
0x4c, 0xa2, 0x0b, 0xf0, 0x46, 0x8c, 0x69, 0x8a, 0xd9, 0x21, 0xcf, 0x7a, 0x1e, 0xba, 0x03, 0x61,
0x75, 0x3f, 0x53, 0xbd, 0x66, 0xf4, 0x67, 0x13, 0x5a, 0x96, 0xd4, 0x73, 0x00, 0x65, 0x86, 0x25,
0x21, 0xef, 0xa4, 0xaa, 0xea, 0xfd, 0xf1, 0x8a, 0xa0, 0xf5, 0x44, 0x9d, 0x34, 0xe2, 0x50, 0xd5,
0xe3, 0xf5, 0x0c, 0x42, 0x4d, 0x54, 0xee, 0xbc, 0x1d, 0xc1, 0xad, 0x15, 0xde, 0xf3, 0xfe, 0x32,
0xfb, 0x4b, 0xcf, 0x7b, 0xed, 0x39, 0x40, 0x69, 0xa0, 0x3b, 0x67, 0xff, 0xc6, 0xd0, 0x75, 0xb1,
0x4d, 0xe8, 0xb2, 0x2e, 0xc7, 0x0b, 0x68, 0x0f, 0xe9, 0xc2, 0xbf, 0x75, 0x63, 0xab, 0x2e, 0xea,
0x72, 0xd2, 0x88, 0x61, 0xb8, 0x28, 0xe8, 0xb1, 0x19, 0x33, 0x3b, 0x75, 0xee, 0x89, 0x35, 0xfb,
0xc4, 0x27, 0x2b, 0xbb, 0xbd, 0x1e, 0xce, 0x93, 0x86, 0x99, 0xb4, 0xfa, 0x7a, 0xb4, 0x0e, 0x2d,
0xe3, 0x1c, 0xfd, 0xed, 0x01, 0x5c, 0x92, 0x54, 0x0b, 0x75, 0x38, 0x18, 0xfc, 0x50, 0xad, 0x28,
0x17, 0xcc, 0x2d, 0x7e, 0xb3, 0xa2, 0x1c, 0x94, 0xa5, 0xe5, 0xd9, 0x5c, 0x5e, 0x9e, 0x4f, 0x01,
0xa4, 0x22, 0x19, 0x4d, 0xb1, 0xb6, 0x6b, 0xe4, 0xd6, 0x26, 0xb8, 0x66, 0x8a, 0xbe, 0x06, 0xb8,
0x32, 0xdf, 0x80, 0x1b, 0xdc, 0xd6, 0x8d, 0xd9, 0xac, 0xff, 0x8a, 0x38, 0xbc, 0xaa, 0xbf, 0x8d,
0xcf, 0xe1, 0xae, 0x64, 0x38, 0x25, 0x13, 0xc1, 0x32, 0xa2, 0x12, 0x8d, 0xc7, 0x36, 0x19, 0x61,
0xdc, 0xbd, 0x26, 0xbe, 0xc0, 0xe3, 0xe8, 0x17, 0x08, 0xce, 0x19, 0xe6, 0x03, 0x91, 0x11, 0x53,
0x80, 0xa9, 0x25, 0x9c, 0x60, 0xce, 0x8b, 0x5b, 0x76, 0xc5, 0x22, 0x2d, 0xa6, 0x00, 0xce, 0xe7,
0x90, 0xf3, 0x02, 0xf5, 0xa1, 0x27, 0x4a, 0x2d, 0x4b, 0x9d, 0xcc, 0xd3, 0xe1, 0xf6, 0x86, 0x1f,
0x77, 0x9d, 0xfc, 0x5b, 0x97, 0x95, 0xc2, 0x64, 0x99, 0x8b, 0x8c, 0x7c, 0xc9, 0x61, 0xdd, 0xad,
0xae, 0xe5, 0x6e, 0xbf, 0x0b, 0xed, 0xd7, 0x8a, 0x60, 0x4d, 0xd4, 0xc5, 0x04, 0xf3, 0x9e, 0x87,
0x7a, 0xd0, 0xa9, 0x04, 0xaf, 0xae, 0x4a, 0xcc, 0x7a, 0x4d, 0xd4, 0x81, 0xe0, 0x0d, 0x29, 0x0a,
0xab, 0xf7, 0xed, 0x38, 0x90, 0xa2, 0x70, 0xca, 0x16, 0x0a, 0x61, 0xcd, 0x1d, 0xd7, 0x8c, 0xdd,
0x40, 0x68, 0x77, 0x5b, 0x3f, 0x7a, 0xfc, 0xd3, 0x57, 0x63, 0xaa, 0x27, 0xe5, 0x70, 0x37, 0x15,
0xf9, 0x9e, 0xa3, 0xf6, 0x88, 0x8a, 0xea, 0xb4, 0x47, 0xb9, 0x26, 0x8a, 0x63, 0xb6, 0x67, 0xd9,
0xee, 0x19, 0xb6, 0x72, 0x38, 0x5c, 0xb7, 0xb7, 0xc7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x4b,
0x51, 0xe7, 0xad, 0x39, 0x08, 0x00, 0x00,
// 1055 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x72, 0xdb, 0x44,
0x14, 0xb6, 0x2c, 0xdb, 0x91, 0x8e, 0x5c, 0xdb, 0xd1, 0x0d, 0x29, 0xa1, 0x24, 0x88, 0x0e, 0x0d,
0x30, 0x4d, 0x86, 0xb6, 0xa4, 0x33, 0x65, 0x60, 0xf2, 0xd3, 0x12, 0x7b, 0x28, 0x49, 0x10, 0x21,
0x17, 0xdc, 0x68, 0xd6, 0xd2, 0xc6, 0xde, 0xe9, 0x5a, 0xab, 0xac, 0x56, 0xa6, 0xbe, 0xe1, 0x86,
0x27, 0xe0, 0x25, 0xe0, 0x1a, 0x9e, 0x83, 0x07, 0xe0, 0x9e, 0x17, 0x61, 0xf6, 0xac, 0xe2, 0x9f,
0x8e, 0xd3, 0xa6, 0x33, 0xbd, 0x5b, 0x9d, 0x3d, 0x7f, 0xdf, 0x77, 0x7e, 0x56, 0x00, 0x19, 0x27,
0xe9, 0x76, 0x26, 0x85, 0x12, 0xfe, 0xea, 0x88, 0xf1, 0x71, 0x91, 0x9b, 0xaf, 0x6d, 0x7d, 0xf1,
0x7e, 0x33, 0x8f, 0x87, 0x74, 0x44, 0x8c, 0x28, 0xc8, 0xa0, 0x79, 0x44, 0x53, 0x2a, 0x59, 0x7c,
0x4e, 0x78, 0x41, 0xfd, 0x75, 0x70, 0xfa, 0x42, 0xf0, 0x68, 0x4c, 0xf8, 0x9a, 0xb5, 0x69, 0x6d,
0x39, 0xdd, 0x4a, 0xb8, 0xa2, 0x25, 0xe7, 0x84, 0xfb, 0x77, 0xc0, 0x65, 0xa9, 0xda, 0x7d, 0x84,
0xb7, 0xd5, 0x4d, 0x6b, 0xcb, 0xee, 0x56, 0x42, 0x07, 0x45, 0xe5, 0xf5, 0x05, 0x17, 0x44, 0xe1,
0xb5, 0xbd, 0x69, 0x6d, 0x59, 0xfa, 0x1a, 0x45, 0xe7, 0x84, 0x1f, 0xd4, 0xc1, 0x1e, 0x13, 0x1e,
0x50, 0x70, 0x7f, 0x28, 0xa8, 0x9c, 0xf4, 0xd2, 0x0b, 0xe1, 0xfb, 0x50, 0x53, 0x22, 0x7b, 0x81,
0xa1, 0xec, 0x10, 0xcf, 0xfe, 0x06, 0x78, 0x23, 0xaa, 0x24, 0x8b, 0x23, 0x35, 0xc9, 0x28, 0x3a,
0x72, 0x43, 0x30, 0xa2, 0xb3, 0x49, 0x46, 0xfd, 0x8f, 0xe1, 0x56, 0x4e, 0x89, 0x8c, 0x87, 0x51,
0x46, 0x24, 0x19, 0xe5, 0x6b, 0x35, 0x54, 0x69, 0x1a, 0xe1, 0x29, 0xca, 0x82, 0x3f, 0x2c, 0x80,
0x43, 0xc1, 0x8b, 0x51, 0x8a, 0x81, 0x6e, 0x83, 0x73, 0xc1, 0x28, 0x4f, 0x22, 0x96, 0x94, 0xc1,
0x56, 0xf0, 0xbb, 0x97, 0xf8, 0x4f, 0xc0, 0x4d, 0x88, 0x22, 0x26, 0x9a, 0x46, 0xd5, 0x7a, 0x70,
0x67, 0x7b, 0x81, 0xb7, 0x92, 0xb1, 0xa7, 0x44, 0x11, 0x9d, 0x40, 0xe8, 0x24, 0xe5, 0xc9, 0xbf,
0x0b, 0x2d, 0x96, 0x47, 0x99, 0x64, 0x23, 0x22, 0x27, 0xd1, 0x0b, 0x3a, 0xc1, 0x74, 0x9d, 0xb0,
0xc9, 0xf2, 0x53, 0x23, 0xfc, 0x8e, 0x4e, 0xfc, 0x75, 0x70, 0x59, 0x1e, 0x91, 0x42, 0x89, 0xde,
0x53, 0x4c, 0xd6, 0x09, 0x1d, 0x96, 0xef, 0xe3, 0x77, 0xf0, 0xb7, 0x05, 0xad, 0x9f, 0x52, 0x22,
0x27, 0x21, 0x49, 0x07, 0xf4, 0xd9, 0xcb, 0x4c, 0xfa, 0xdf, 0x80, 0x17, 0x63, 0xea, 0x11, 0x4b,
0x2f, 0x04, 0xe6, 0xeb, 0xbd, 0x9a, 0x13, 0x16, 0x79, 0x06, 0x30, 0x84, 0x78, 0x06, 0xf6, 0x53,
0xa8, 0x8a, 0xac, 0x84, 0x72, 0x7b, 0x89, 0xd9, 0x49, 0x86, 0x30, 0xaa, 0x22, 0xf3, 0xbf, 0x84,
0xfa, 0x58, 0x17, 0x1e, 0xf3, 0xf6, 0x1e, 0x6c, 0x2c, 0xd1, 0x9e, 0xef, 0x8f, 0xd0, 0x68, 0x07,
0x7f, 0x56, 0xa1, 0x7d, 0xc0, 0xde, 0x6d, 0xd6, 0xf7, 0xa0, 0xcd, 0xc5, 0x2f, 0x54, 0x46, 0x2c,
0x8d, 0x79, 0x91, 0xb3, 0xb1, 0xa9, 0x86, 0x13, 0xb6, 0x50, 0xdc, 0xbb, 0x92, 0x6a, 0xc5, 0x22,
0xcb, 0x16, 0x14, 0x0d, 0xeb, 0x2d, 0x14, 0xcf, 0x14, 0xf7, 0xc0, 0x33, 0x1e, 0x0d, 0xc4, 0xda,
0xcd, 0x20, 0x02, 0xda, 0x98, 0x71, 0xd8, 0x03, 0xcf, 0x84, 0x32, 0x1e, 0xea, 0x37, 0xf4, 0x80,
0x36, 0x78, 0x0e, 0xfe, 0xb1, 0xc0, 0x3b, 0x14, 0xa3, 0x8c, 0x48, 0xc3, 0xd2, 0x11, 0x74, 0x38,
0xbd, 0x50, 0xd1, 0x5b, 0x53, 0xd5, 0xd2, 0x66, 0x73, 0x1d, 0xdd, 0x83, 0x55, 0xc9, 0x06, 0xc3,
0x45, 0x4f, 0xd5, 0x9b, 0x78, 0x6a, 0xa3, 0xdd, 0xe1, 0xab, 0xfd, 0x62, 0xdf, 0xa0, 0x5f, 0x82,
0xdf, 0x2c, 0x70, 0xce, 0xa8, 0x1c, 0xbd, 0x93, 0x8a, 0x3f, 0x86, 0x06, 0xf2, 0x9a, 0xaf, 0x55,
0x37, 0xed, 0x9b, 0x10, 0x5b, 0xaa, 0x07, 0xbf, 0x5b, 0xe0, 0xe2, 0xcc, 0x60, 0x1a, 0x8f, 0x30,
0x7d, 0x0b, 0xd3, 0xbf, 0xbb, 0xc4, 0xc5, 0x54, 0xd3, 0x9c, 0x4e, 0x32, 0xec, 0xfc, 0xfb, 0x50,
0x8f, 0x87, 0x8c, 0x27, 0x25, 0x67, 0xef, 0x2d, 0x31, 0xd4, 0x36, 0xa1, 0xd1, 0x0a, 0x36, 0x60,
0xa5, 0xb4, 0xf6, 0x3d, 0x58, 0xe9, 0xa5, 0x63, 0xc2, 0x59, 0xd2, 0xa9, 0xf8, 0x2b, 0x60, 0x1f,
0x0b, 0xd5, 0xb1, 0x82, 0x7f, 0x2d, 0x00, 0x33, 0x12, 0x98, 0xd4, 0xee, 0x5c, 0x52, 0x9f, 0x2c,
0xf1, 0x3d, 0x53, 0x2d, 0x8f, 0x65, 0x5a, 0x9f, 0x43, 0x4d, 0x17, 0xfa, 0x4d, 0x59, 0xa1, 0x92,
0xc6, 0x80, 0xb5, 0x2c, 0xa7, 0xf7, 0x7a, 0x0c, 0xa8, 0x15, 0xec, 0x82, 0x73, 0x15, 0x6b, 0x11,
0x44, 0x0b, 0xe0, 0xb9, 0x18, 0xb0, 0x98, 0xf0, 0xfd, 0x34, 0xe9, 0x58, 0xfe, 0x2d, 0x70, 0xcb,
0xef, 0x13, 0xd9, 0xa9, 0x06, 0x7f, 0xd9, 0x50, 0x43, 0x50, 0x4f, 0xc0, 0x55, 0x54, 0x8e, 0x22,
0xfa, 0x32, 0x93, 0x65, 0xb9, 0xd7, 0x97, 0xc4, 0xbc, 0x6a, 0x10, 0xbd, 0xfe, 0xd5, 0x55, 0xb3,
0x7c, 0x0d, 0x50, 0xe8, 0xd8, 0xc6, 0xd8, 0xc0, 0xfb, 0xe0, 0x75, 0xd5, 0xea, 0x56, 0x42, 0xb7,
0x98, 0xf2, 0xb9, 0x07, 0x5e, 0x9f, 0xcd, 0xec, 0xed, 0x6b, 0x7b, 0x6d, 0x46, 0x6c, 0xb7, 0x12,
0x42, 0x7f, 0x56, 0x91, 0x43, 0x68, 0xc6, 0x66, 0x10, 0x8d, 0x0b, 0xb3, 0x0e, 0x3e, 0x5c, 0xda,
0xae, 0xd3, 0x79, 0xed, 0x56, 0x42, 0x2f, 0x9e, 0x1b, 0xdf, 0xef, 0xa1, 0x63, 0x50, 0x48, 0xbd,
0xf7, 0x8c, 0x23, 0xb3, 0x15, 0x3e, 0xba, 0x0e, 0xcb, 0x74, 0x43, 0x76, 0x2b, 0x61, 0xab, 0x58,
0xdc, 0x99, 0xa7, 0xb0, 0x5a, 0xa2, 0x9a, 0xf3, 0xd7, 0x40, 0x7f, 0xc1, 0xb5, 0xd8, 0xe6, 0x1d,
0xb6, 0xfb, 0x8b, 0xa2, 0x83, 0x06, 0xd4, 0xb4, 0x93, 0xe0, 0x3f, 0x0b, 0xe0, 0x9c, 0xc6, 0x4a,
0xc8, 0xfd, 0xe3, 0xe3, 0x1f, 0xcb, 0x27, 0xc8, 0x28, 0x9b, 0x87, 0x5d, 0x3f, 0x41, 0xc6, 0xdf,
0xc2, 0xe3, 0x58, 0x5d, 0x7c, 0x1c, 0x1f, 0x03, 0x64, 0x92, 0x26, 0x2c, 0x26, 0x8a, 0xe6, 0x6f,
0x6a, 0xb3, 0x39, 0x55, 0xff, 0x2b, 0x80, 0x4b, 0xfd, 0xcc, 0x9b, 0xd5, 0x50, 0xbb, 0xb6, 0xdc,
0xd3, 0x7f, 0x81, 0xd0, 0xbd, 0x9c, 0xfe, 0x16, 0xdc, 0x83, 0x76, 0xc6, 0x49, 0x4c, 0x87, 0x82,
0x27, 0x54, 0x46, 0x8a, 0x0c, 0x90, 0x64, 0x37, 0x6c, 0xcd, 0x89, 0xcf, 0xc8, 0x20, 0xf8, 0x15,
0x9c, 0x53, 0x4e, 0xd2, 0x63, 0x91, 0xe0, 0xae, 0x1e, 0x23, 0xe0, 0x88, 0xa4, 0x69, 0xfe, 0x9a,
0x6d, 0x34, 0xa3, 0x45, 0x77, 0x88, 0xb1, 0xd9, 0x4f, 0xd3, 0xdc, 0xdf, 0x82, 0x8e, 0x28, 0x54,
0x56, 0xa8, 0xe8, 0x8a, 0x0e, 0xb3, 0x99, 0xec, 0xb0, 0x65, 0xe4, 0xdf, 0x1a, 0x56, 0x72, 0xcd,
0x72, 0x2a, 0x12, 0xfa, 0x59, 0x0a, 0x0d, 0xb3, 0x1c, 0x17, 0xe7, 0xa9, 0x0d, 0xde, 0x91, 0xa4,
0x44, 0x51, 0x79, 0x36, 0x24, 0x69, 0xc7, 0xf2, 0x3b, 0xd0, 0x2c, 0x05, 0xcf, 0x2e, 0x0b, 0xc2,
0x3b, 0x55, 0xbf, 0x09, 0xce, 0x73, 0x9a, 0xe7, 0x78, 0x6f, 0xe3, 0xc0, 0xd1, 0x3c, 0x37, 0x97,
0x35, 0xdf, 0x85, 0xba, 0x39, 0xd6, 0xb5, 0xde, 0xb1, 0x50, 0xe6, 0xab, 0x71, 0xf0, 0xf0, 0xe7,
0x2f, 0x06, 0x4c, 0x0d, 0x8b, 0xfe, 0x76, 0x2c, 0x46, 0x3b, 0x06, 0xda, 0x7d, 0x26, 0xca, 0xd3,
0x0e, 0x4b, 0x15, 0x95, 0x29, 0xe1, 0x3b, 0x88, 0x76, 0x47, 0xa3, 0xcd, 0xfa, 0xfd, 0x06, 0x7e,
0x3d, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xda, 0x8a, 0xf0, 0x6c, 0x19, 0x0a, 0x00, 0x00,
}

View File

@ -197,10 +197,10 @@ func (context *ParserContext) createColumnInfo(field *schemapb.FieldSchema) *pla
}
}
func isSameOrder(a, b string) bool {
isLessA := a == "<" || a == "<="
isLessB := b == "<" || b == "<="
return isLessA == isLessB
func isSameOrder(opStr1, opStr2 string) bool {
isLess1 := opStr1 == "<" || opStr1 == "<="
isLess2 := opStr2 == "<" || opStr2 == "<="
return isLess1 == isLess2
}
func getCompareOpType(opStr string, reverse bool) planpb.OpType {
@ -271,16 +271,14 @@ func (context *ParserContext) createCmpExpr(left, right ant_ast.Node, operator s
}
op := getCompareOpType(operator, false)
if op == planpb.OpType_Invalid {
return nil, fmt.Errorf("invalid binary operator %s", operator)
return nil, fmt.Errorf("invalid binary operator(%s)", operator)
}
expr := &planpb.Expr{
Expr: &planpb.Expr_CompareExpr{
CompareExpr: &planpb.CompareExpr{
ColumnsInfo: []*planpb.ColumnInfo{
context.createColumnInfo(leftField),
context.createColumnInfo(rightField),
},
Op: op,
LeftColumnInfo: context.createColumnInfo(leftField),
RightColumnInfo: context.createColumnInfo(rightField),
Op: op,
},
},
}
@ -314,15 +312,15 @@ func (context *ParserContext) createCmpExpr(left, right ant_ast.Node, operator s
op := getCompareOpType(operator, isReversed)
if op == planpb.OpType_Invalid {
return nil, fmt.Errorf("invalid binary operator %s", operator)
return nil, fmt.Errorf("invalid binary operator(%s)", operator)
}
expr := &planpb.Expr{
Expr: &planpb.Expr_RangeExpr{
RangeExpr: &planpb.RangeExpr{
Expr: &planpb.Expr_UnaryRangeExpr{
UnaryRangeExpr: &planpb.UnaryRangeExpr{
ColumnInfo: context.createColumnInfo(field),
Ops: []planpb.OpType{op},
Values: []*planpb.GenericValue{val},
Op: op,
Value: val,
},
},
}
@ -336,7 +334,7 @@ func (context *ParserContext) handleCmpExpr(node *ant_ast.BinaryNode) (*planpb.E
func (context *ParserContext) handleLogicalExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
op := getLogicalOpType(node.Operator)
if op == planpb.BinaryExpr_Invalid {
return nil, fmt.Errorf("invalid logical op(%s)", node.Operator)
return nil, fmt.Errorf("invalid logical operator(%s)", node.Operator)
}
leftExpr, err := context.handleExpr(&node.Left)
@ -379,7 +377,7 @@ func (context *ParserContext) handleArrayExpr(node *ant_ast.Node, dataType schem
func (context *ParserContext) handleInExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
if node.Operator != "in" && node.Operator != "not in" {
return nil, fmt.Errorf("invalid Operator(%s)", node.Operator)
return nil, fmt.Errorf("invalid operator(%s)", node.Operator)
}
idNode, ok := node.Left.(*ant_ast.IdentifierNode)
if !ok {
@ -409,10 +407,33 @@ func (context *ParserContext) handleInExpr(node *ant_ast.BinaryNode) (*planpb.Ex
return expr, nil
}
func (context *ParserContext) combineUnaryRangeExpr(a, b *planpb.UnaryRangeExpr) *planpb.Expr {
if a.Op == planpb.OpType_LessEqual || a.Op == planpb.OpType_LessThan {
a, b = b, a
}
lowerInclusive := (a.Op == planpb.OpType_GreaterEqual)
upperInclusive := (b.Op == planpb.OpType_LessEqual)
expr := &planpb.Expr{
Expr: &planpb.Expr_BinaryRangeExpr{
BinaryRangeExpr: &planpb.BinaryRangeExpr{
ColumnInfo: a.ColumnInfo,
LowerInclusive: lowerInclusive,
UpperInclusive: upperInclusive,
LowerValue: a.Value,
UpperValue: b.Value,
},
},
}
return expr
}
func (context *ParserContext) handleMultiCmpExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
exprs := []*planpb.Expr{}
curNode := node
// handle multiple relational operator
for {
binNodeLeft, LeftOk := curNode.Left.(*ant_ast.BinaryNode)
if !LeftOk {
@ -430,26 +451,28 @@ func (context *ParserContext) handleMultiCmpExpr(node *ant_ast.BinaryNode) (*pla
}
exprs = append(exprs, expr)
curNode = binNodeLeft
} else {
return nil, fmt.Errorf("illegal multi-range expr")
}
}
var lastExpr *planpb.Expr_RangeExpr
// combine UnaryRangeExpr to BinaryRangeExpr
var lastExpr *planpb.UnaryRangeExpr
for i := len(exprs) - 1; i >= 0; i-- {
if expr, ok := exprs[i].Expr.(*planpb.Expr_RangeExpr); ok {
if lastExpr != nil && expr.RangeExpr.ColumnInfo.FieldId == lastExpr.RangeExpr.ColumnInfo.FieldId {
exprs = append(exprs[0:i+1], exprs[i+2:]...)
if len(lastExpr.RangeExpr.Ops) > 1 {
return nil, fmt.Errorf("invalid compare combination of fieldID: %v", lastExpr.RangeExpr.ColumnInfo.FieldId)
}
expr.RangeExpr.Ops = append(expr.RangeExpr.Ops, lastExpr.RangeExpr.Ops...)
expr.RangeExpr.Values = append(expr.RangeExpr.Values, lastExpr.RangeExpr.Values...)
if expr, ok := exprs[i].Expr.(*planpb.Expr_UnaryRangeExpr); ok {
if lastExpr != nil && expr.UnaryRangeExpr.ColumnInfo.FieldId == lastExpr.ColumnInfo.FieldId {
binaryRangeExpr := context.combineUnaryRangeExpr(expr.UnaryRangeExpr, lastExpr)
exprs = append(exprs[0:i], append([]*planpb.Expr{binaryRangeExpr}, exprs[i+2:]...)...)
lastExpr = nil
} else {
lastExpr = expr.UnaryRangeExpr
}
lastExpr = expr
} else {
lastExpr = nil
}
}
// use `&&` to connect exprs
combinedExpr := exprs[len(exprs)-1]
for i := len(exprs) - 2; i >= 0; i-- {
expr := exprs[i]