mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-11-30 02:48:45 +08:00
enhance: Support more relational operators for binary expressions (#30902)
issue: #30677 Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
This commit is contained in:
parent
ee8d6f236c
commit
1aa97a5c21
@ -119,7 +119,10 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForJson() {
|
||||
auto op_type = expr_->op_type_;
|
||||
auto arith_type = expr_->arith_op_type_;
|
||||
auto value = GetValueFromProto<ValueType>(expr_->value_);
|
||||
auto right_operand = GetValueFromProto<ValueType>(expr_->right_operand_);
|
||||
auto right_operand =
|
||||
arith_type != proto::plan::ArithOpType::ArrayLength
|
||||
? GetValueFromProto<ValueType>(expr_->right_operand_)
|
||||
: ValueType();
|
||||
|
||||
#define BinaryArithRangeJSONCompare(cmp) \
|
||||
do { \
|
||||
@ -260,6 +263,202 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForJson() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeJSONCompare(x.value() + right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeJSONCompare(x.value() - right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeJSONCompare(x.value() * right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeJSONCompare(x.value() / right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeJSONCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(x.value(), right_operand)) > val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
int array_length = 0;
|
||||
auto doc = data[i].doc();
|
||||
auto array = doc.at_pointer(pointer).get_array();
|
||||
if (!array.error()) {
|
||||
array_length = array.count_elements();
|
||||
}
|
||||
res[i] = array_length > val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeJSONCompare(x.value() + right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeJSONCompare(x.value() - right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeJSONCompare(x.value() * right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeJSONCompare(x.value() / right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeJSONCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(x.value(), right_operand)) >= val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
int array_length = 0;
|
||||
auto doc = data[i].doc();
|
||||
auto array = doc.at_pointer(pointer).get_array();
|
||||
if (!array.error()) {
|
||||
array_length = array.count_elements();
|
||||
}
|
||||
res[i] = array_length >= val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeJSONCompare(x.value() + right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeJSONCompare(x.value() - right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeJSONCompare(x.value() * right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeJSONCompare(x.value() / right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeJSONCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(x.value(), right_operand)) < val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
int array_length = 0;
|
||||
auto doc = data[i].doc();
|
||||
auto array = doc.at_pointer(pointer).get_array();
|
||||
if (!array.error()) {
|
||||
array_length = array.count_elements();
|
||||
}
|
||||
res[i] = array_length < val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeJSONCompare(x.value() + right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeJSONCompare(x.value() - right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeJSONCompare(x.value() * right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeJSONCompare(x.value() / right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeJSONCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(x.value(), right_operand)) <= val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
int array_length = 0;
|
||||
auto doc = data[i].doc();
|
||||
auto array = doc.at_pointer(pointer).get_array();
|
||||
if (!array.error()) {
|
||||
array_length = array.count_elements();
|
||||
}
|
||||
res[i] = array_length <= val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(OpTypeInvalid,
|
||||
"unsupported operator type for binary "
|
||||
@ -413,6 +612,178 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForArray() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeArrayCompare(value + right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeArrayCompare(value - right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeArrayCompare(value * right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeArrayCompare(value / right_operand >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeArrayCompare(
|
||||
static_cast<ValueType>(fmod(value, right_operand)) >
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
res[i] = data[i].length() > val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeArrayCompare(value + right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeArrayCompare(value - right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeArrayCompare(value * right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeArrayCompare(value / right_operand >=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeArrayCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(value, right_operand)) >= val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
res[i] = data[i].length() >= val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeArrayCompare(value + right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeArrayCompare(value - right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeArrayCompare(value * right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeArrayCompare(value / right_operand <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeArrayCompare(
|
||||
static_cast<ValueType>(fmod(value, right_operand)) <
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
res[i] = data[i].length() < val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
BinaryArithRangeArrayCompare(value + right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
BinaryArithRangeArrayCompare(value - right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
BinaryArithRangeArrayCompare(value * right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
BinaryArithRangeArrayCompare(value / right_operand <=
|
||||
val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
BinaryArithRangeArrayCompare(
|
||||
static_cast<ValueType>(
|
||||
fmod(value, right_operand)) <= val);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::ArrayLength: {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
res[i] = data[i].length() <= val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(OpTypeInvalid,
|
||||
"unsupported operator type for binary "
|
||||
@ -579,6 +950,230 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForIndex() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpIndexFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
res = std::move(func(
|
||||
index_ptr, sub_batch_size, value, right_operand));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(OpTypeInvalid,
|
||||
"unsupported operator type for binary "
|
||||
@ -727,6 +1322,210 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForData() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterThan,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::GreaterEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::GreaterEqual,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessThan: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessThan,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case proto::plan::OpType::LessEqual: {
|
||||
switch (arith_type) {
|
||||
case proto::plan::ArithOpType::Add: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Add>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Sub: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Sub>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mul: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Mul>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Div: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Div>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
case proto::plan::ArithOpType::Mod: {
|
||||
ArithOpElementFunc<T,
|
||||
proto::plan::OpType::LessEqual,
|
||||
proto::plan::ArithOpType::Mod>
|
||||
func;
|
||||
func(data, size, value, right_operand, res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format("unsupported arith type for binary "
|
||||
"arithmetic eval expr: {}",
|
||||
arith_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PanicInfo(OpTypeInvalid,
|
||||
"unsupported operator type for binary "
|
||||
|
@ -88,6 +88,94 @@ struct ArithOpElementFunc {
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::GreaterThan) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (src[i] + right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (src[i] - right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (src[i] * right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (src[i] / right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] = (fmod(src[i], right_operand)) > val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::GreaterEqual) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (src[i] + right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (src[i] - right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (src[i] * right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (src[i] / right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] = (fmod(src[i], right_operand)) >= val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::LessThan) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (src[i] + right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (src[i] - right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (src[i] * right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (src[i] / right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] = (fmod(src[i], right_operand)) < val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::LessEqual) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (src[i] + right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (src[i] - right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (src[i] * right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (src[i] / right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] = (fmod(src[i], right_operand)) <= val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,6 +245,98 @@ struct ArithOpIndexFunc {
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::GreaterThan) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (index->Reverse_Lookup(i) + right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (index->Reverse_Lookup(i) - right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (index->Reverse_Lookup(i) * right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (index->Reverse_Lookup(i) / right_operand) > val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] =
|
||||
(fmod(index->Reverse_Lookup(i), right_operand)) > val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::GreaterEqual) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (index->Reverse_Lookup(i) + right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (index->Reverse_Lookup(i) - right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (index->Reverse_Lookup(i) * right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (index->Reverse_Lookup(i) / right_operand) >= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] =
|
||||
(fmod(index->Reverse_Lookup(i), right_operand)) >= val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::LessThan) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (index->Reverse_Lookup(i) + right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (index->Reverse_Lookup(i) - right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (index->Reverse_Lookup(i) * right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (index->Reverse_Lookup(i) / right_operand) < val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] =
|
||||
(fmod(index->Reverse_Lookup(i), right_operand)) < val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
} else if constexpr (cmp_op == proto::plan::OpType::LessEqual) {
|
||||
if constexpr (arith_op == proto::plan::ArithOpType::Add) {
|
||||
res[i] = (index->Reverse_Lookup(i) + right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Sub) {
|
||||
res[i] = (index->Reverse_Lookup(i) - right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mul) {
|
||||
res[i] = (index->Reverse_Lookup(i) * right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Div) {
|
||||
res[i] = (index->Reverse_Lookup(i) / right_operand) <= val;
|
||||
} else if constexpr (arith_op ==
|
||||
proto::plan::ArithOpType::Mod) {
|
||||
res[i] =
|
||||
(fmod(index->Reverse_Lookup(i), right_operand)) <= val;
|
||||
} else {
|
||||
PanicInfo(
|
||||
OpTypeInvalid,
|
||||
fmt::format(
|
||||
"unsupported arith type:{} for ArithOpElementFunc",
|
||||
arith_op));
|
||||
}
|
||||
}
|
||||
}
|
||||
return res_vec;
|
||||
|
@ -1274,6 +1274,74 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val + 2 != 5;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:Add
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterThan
|
||||
value:<int64_val:5 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val + 2 > 5;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:Add
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterEqual
|
||||
value:<int64_val:5 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val + 2 >= 5;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:Add
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessThan
|
||||
value:<int64_val:5 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val + 2 < 5;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:Add
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessEqual
|
||||
value:<int64_val:5 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val + 2 <= 5;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
@ -1308,6 +1376,74 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val - 1 != 144;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Sub
|
||||
right_operand:<int64_val:1 >
|
||||
op:GreaterThan
|
||||
value:<int64_val:144 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val - 1 > 144;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Sub
|
||||
right_operand:<int64_val:1 >
|
||||
op:GreaterEqual
|
||||
value:<int64_val:144 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val - 1 >= 144;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Sub
|
||||
right_operand:<int64_val:1 >
|
||||
op:LessThan
|
||||
value:<int64_val:144 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val - 1 < 144;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Sub
|
||||
right_operand:<int64_val:1 >
|
||||
op:LessEqual
|
||||
value:<int64_val:144 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val - 1 <= 144;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 103
|
||||
@ -1410,6 +1546,74 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val * 2 != 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mul
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterThan
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val * 2 > 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mul
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterEqual
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val * 2 >= 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mul
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessThan
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val * 2 < 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mul
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessEqual
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val * 2 <= 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
@ -1444,6 +1648,74 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val / 2 != 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Div
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterThan
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val / 2 > 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Div
|
||||
right_operand:<int64_val:2 >
|
||||
op:GreaterEqual
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val / 2 >= 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Div
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessThan
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val / 2 < 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Div
|
||||
right_operand:<int64_val:2 >
|
||||
op:LessEqual
|
||||
value:<int64_val:20 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val / 2 <= 20;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
@ -1478,6 +1750,74 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val % 3 != 2;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mod
|
||||
right_operand:<int64_val:3 >
|
||||
op:GreaterThan
|
||||
value:<int64_val:2 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val % 3 > 2;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mod
|
||||
right_operand:<int64_val:3 >
|
||||
op:GreaterEqual
|
||||
value:<int64_val:2 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val % 3 >= 2;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mod
|
||||
right_operand:<int64_val:3 >
|
||||
op:LessThan
|
||||
value:<int64_val:2 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val % 3 < 2;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 102
|
||||
data_type: Array
|
||||
nested_path:"0"
|
||||
element_type:Int64
|
||||
>
|
||||
arith_op:Mod
|
||||
right_operand:<int64_val:3 >
|
||||
op:LessEqual
|
||||
value:<int64_val:2 >
|
||||
>)",
|
||||
"long",
|
||||
[](milvus::Array& array) {
|
||||
auto val = array.get_data<int64_t>(0);
|
||||
return val % 3 <= 2;
|
||||
}},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 103
|
||||
@ -1704,6 +2044,54 @@ TEST(Expr, TestArrayBinaryArith) {
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) { return array.length() != 8; }},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:ArrayLength
|
||||
op:GreaterThan
|
||||
value:<int64_val:8 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) { return array.length() > 8; }},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:ArrayLength
|
||||
op:GreaterEqual
|
||||
value:<int64_val:8 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) { return array.length() >= 8; }},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:ArrayLength
|
||||
op:LessThan
|
||||
value:<int64_val:8 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) { return array.length() < 8; }},
|
||||
{R"(binary_arith_op_eval_range_expr: <
|
||||
column_info: <
|
||||
field_id: 101
|
||||
data_type: Array
|
||||
element_type:Int8
|
||||
>
|
||||
arith_op:ArrayLength
|
||||
op:LessEqual
|
||||
value:<int64_val:8 >
|
||||
>)",
|
||||
"int",
|
||||
[](milvus::Array& array) { return array.length() <= 8; }},
|
||||
};
|
||||
|
||||
std::string raw_plan_tmp = R"(vector_anns: <
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -218,6 +218,15 @@ func TestExpr_BinaryArith(t *testing.T) {
|
||||
`Int64Field % 10 != 9`,
|
||||
`Int64Field + 1.1 == 2.1`,
|
||||
`A % 10 != 2`,
|
||||
`Int8Field + 1 < 2`,
|
||||
`Int16Field - 3 <= 4`,
|
||||
`Int32Field * 5 > 6`,
|
||||
`Int64Field / 7 >= 8`,
|
||||
`FloatField + 11 < 12`,
|
||||
`DoubleField - 13 <= 14`,
|
||||
`A * 15 > 16`,
|
||||
`JSONField['A'] / 17 >= 18`,
|
||||
`ArrayField[0] % 19 >= 20`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
@ -225,13 +234,6 @@ func TestExpr_BinaryArith(t *testing.T) {
|
||||
|
||||
// TODO: enable these after execution backend is ready.
|
||||
unsupported := []string{
|
||||
`Int8Field + 1 < 2`,
|
||||
`Int16Field - 3 <= 4`,
|
||||
`Int32Field * 5 > 6`,
|
||||
`Int64Field / 7 >= 8`,
|
||||
`FloatField + 11 < 12`,
|
||||
`DoubleField - 13 < 14`,
|
||||
`A - 15 < 16`,
|
||||
`JSONField + 15 == 16`,
|
||||
`15 + JSONField == 16`,
|
||||
`ArrayField + 15 == 16`,
|
||||
@ -1172,6 +1174,10 @@ func Test_ArrayLength(t *testing.T) {
|
||||
`array_length(B) != 1`,
|
||||
`not (array_length(C[0]) == 1)`,
|
||||
`not (array_length(C["D"]) != 1)`,
|
||||
`array_length(StringArrayField) < 1`,
|
||||
`array_length(StringArrayField) <= 1`,
|
||||
`array_length(StringArrayField) > 5`,
|
||||
`array_length(StringArrayField) >= 5`,
|
||||
}
|
||||
for _, expr = range exprs {
|
||||
_, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{
|
||||
@ -1193,7 +1199,6 @@ func Test_ArrayLength(t *testing.T) {
|
||||
`0 < array_length(a-b) < 2`,
|
||||
`0 < array_length(StringArrayField) < 1`,
|
||||
`100 > array_length(ArrayField) > 10`,
|
||||
`array_length(StringArrayField) < 1`,
|
||||
`array_length(A) % 10 == 2`,
|
||||
`array_length(A) / 10 == 2`,
|
||||
`array_length(A) + 1 == 2`,
|
||||
|
@ -259,14 +259,6 @@ func combineArrayLengthExpr(op planpb.OpType, arithOp planpb.ArithOpType, column
|
||||
}
|
||||
|
||||
func handleBinaryArithExpr(op planpb.OpType, arithExpr *planpb.BinaryArithExpr, valueExpr *planpb.ValueExpr) (*planpb.Expr, error) {
|
||||
switch op {
|
||||
case planpb.OpType_Equal, planpb.OpType_NotEqual:
|
||||
break
|
||||
default:
|
||||
// TODO: enable this after execution is ready.
|
||||
return nil, fmt.Errorf("%s is not supported in execution backend", op)
|
||||
}
|
||||
|
||||
leftExpr, leftValue := arithExpr.Left.GetColumnExpr(), arithExpr.Left.GetValueExpr()
|
||||
rightExpr, rightValue := arithExpr.Right.GetColumnExpr(), arithExpr.Right.GetValueExpr()
|
||||
arithOp := arithExpr.GetOp()
|
||||
|
240
tests/integration/expression/expression_test.go
Normal file
240
tests/integration/expression/expression_test.go
Normal file
@ -0,0 +1,240 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/pkg/common"
|
||||
"github.com/milvus-io/milvus/pkg/log"
|
||||
"github.com/milvus-io/milvus/pkg/util/funcutil"
|
||||
"github.com/milvus-io/milvus/pkg/util/merr"
|
||||
"github.com/milvus-io/milvus/pkg/util/metric"
|
||||
"github.com/milvus-io/milvus/tests/integration"
|
||||
)
|
||||
|
||||
type ExpressionSuite struct {
|
||||
integration.MiniClusterSuite
|
||||
dbName string
|
||||
collectionName string
|
||||
dim int
|
||||
rowNum int
|
||||
}
|
||||
|
||||
func (s *ExpressionSuite) setParams() {
|
||||
prefix := "TestExpression"
|
||||
s.dbName = ""
|
||||
s.collectionName = prefix + funcutil.GenRandomStr()
|
||||
s.dim = 128
|
||||
s.rowNum = 100
|
||||
}
|
||||
|
||||
func newJSONData(fieldName string, rowNum int) *schemapb.FieldData {
|
||||
jsonData := make([][]byte, 0, rowNum)
|
||||
for i := 0; i < rowNum; i++ {
|
||||
data := map[string]interface{}{
|
||||
"A": i,
|
||||
"B": rowNum - i,
|
||||
"C": []int{i, rowNum - i},
|
||||
"D": fmt.Sprintf("name-%d", i),
|
||||
"E": map[string]interface{}{
|
||||
"F": i,
|
||||
"G": i + 10,
|
||||
},
|
||||
"str1": `abc\"def-` + string(rune(i)),
|
||||
"str2": fmt.Sprintf("abc\"def-%d", i),
|
||||
"str3": fmt.Sprintf("abc\ndef-%d", i),
|
||||
"str4": fmt.Sprintf("abc\367-%d", i),
|
||||
}
|
||||
if i%2 == 0 {
|
||||
data = map[string]interface{}{
|
||||
"B": rowNum - i,
|
||||
"C": []int{i, rowNum - i},
|
||||
"D": fmt.Sprintf("name-%d", i),
|
||||
"E": map[string]interface{}{
|
||||
"F": i,
|
||||
"G": i + 10,
|
||||
},
|
||||
}
|
||||
}
|
||||
if i == 100 {
|
||||
data = nil
|
||||
}
|
||||
jsonBytes, err := json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
jsonData = append(jsonData, jsonBytes)
|
||||
}
|
||||
return &schemapb.FieldData{
|
||||
Type: schemapb.DataType_JSON,
|
||||
FieldName: fieldName,
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_JsonData{
|
||||
JsonData: &schemapb.JSONArray{
|
||||
Data: jsonData,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ExpressionSuite) insertFlushIndexLoad(ctx context.Context, fieldData []*schemapb.FieldData) {
|
||||
hashKeys := integration.GenerateHashKeys(s.rowNum)
|
||||
insertResult, err := s.Cluster.Proxy.Insert(ctx, &milvuspb.InsertRequest{
|
||||
DbName: s.dbName,
|
||||
CollectionName: s.collectionName,
|
||||
FieldsData: fieldData,
|
||||
HashKeys: hashKeys,
|
||||
NumRows: uint32(s.rowNum),
|
||||
})
|
||||
s.NoError(err)
|
||||
s.NoError(merr.Error(insertResult.GetStatus()))
|
||||
|
||||
// flush
|
||||
flushResp, err := s.Cluster.Proxy.Flush(ctx, &milvuspb.FlushRequest{
|
||||
DbName: s.dbName,
|
||||
CollectionNames: []string{s.collectionName},
|
||||
})
|
||||
s.NoError(err)
|
||||
segmentIDs, has := flushResp.GetCollSegIDs()[s.collectionName]
|
||||
ids := segmentIDs.GetData()
|
||||
s.Require().NotEmpty(segmentIDs)
|
||||
s.Require().True(has)
|
||||
flushTs, has := flushResp.GetCollFlushTs()[s.collectionName]
|
||||
s.True(has)
|
||||
|
||||
segments, err := s.Cluster.MetaWatcher.ShowSegments()
|
||||
s.NoError(err)
|
||||
s.NotEmpty(segments)
|
||||
for _, segment := range segments {
|
||||
log.Info("ShowSegments result", zap.String("segment", segment.String()))
|
||||
}
|
||||
s.WaitForFlush(ctx, ids, flushTs, s.dbName, s.collectionName)
|
||||
|
||||
// create index
|
||||
createIndexStatus, err := s.Cluster.Proxy.CreateIndex(context.TODO(), &milvuspb.CreateIndexRequest{
|
||||
CollectionName: s.collectionName,
|
||||
FieldName: integration.FloatVecField,
|
||||
IndexName: "_default",
|
||||
ExtraParams: integration.ConstructIndexParam(s.dim, integration.IndexFaissIvfFlat, metric.IP),
|
||||
})
|
||||
s.NoError(err)
|
||||
err = merr.Error(createIndexStatus)
|
||||
s.NoError(err)
|
||||
s.WaitForIndexBuilt(context.TODO(), s.collectionName, integration.FloatVecField)
|
||||
log.Info("=========================Index created=========================")
|
||||
|
||||
// load
|
||||
loadStatus, err := s.Cluster.Proxy.LoadCollection(ctx, &milvuspb.LoadCollectionRequest{
|
||||
DbName: s.dbName,
|
||||
CollectionName: s.collectionName,
|
||||
})
|
||||
s.NoError(err)
|
||||
err = merr.Error(loadStatus)
|
||||
s.NoError(err)
|
||||
s.WaitForLoad(context.TODO(), s.collectionName)
|
||||
log.Info("=========================Collection loaded=========================")
|
||||
}
|
||||
|
||||
func (s *ExpressionSuite) setupData() {
|
||||
c := s.Cluster
|
||||
ctx, cancel := context.WithCancel(c.GetContext())
|
||||
defer cancel()
|
||||
|
||||
schema := integration.ConstructSchema(s.collectionName, s.dim, true)
|
||||
schema.EnableDynamicField = true
|
||||
marshaledSchema, err := proto.Marshal(schema)
|
||||
s.NoError(err)
|
||||
|
||||
createCollectionStatus, err := c.Proxy.CreateCollection(ctx, &milvuspb.CreateCollectionRequest{
|
||||
DbName: s.dbName,
|
||||
CollectionName: s.collectionName,
|
||||
Schema: marshaledSchema,
|
||||
ShardsNum: 2,
|
||||
})
|
||||
s.NoError(err)
|
||||
err = merr.Error(createCollectionStatus)
|
||||
s.NoError(err)
|
||||
|
||||
showCollectionsResp, err := c.Proxy.ShowCollections(ctx, &milvuspb.ShowCollectionsRequest{})
|
||||
s.NoError(err)
|
||||
err = merr.Error(showCollectionsResp.GetStatus())
|
||||
s.NoError(err)
|
||||
|
||||
describeCollectionResp, err := c.Proxy.DescribeCollection(ctx, &milvuspb.DescribeCollectionRequest{CollectionName: s.collectionName})
|
||||
s.NoError(err)
|
||||
err = merr.Error(describeCollectionResp.GetStatus())
|
||||
s.NoError(err)
|
||||
s.True(describeCollectionResp.Schema.EnableDynamicField)
|
||||
s.Equal(2, len(describeCollectionResp.GetSchema().GetFields()))
|
||||
|
||||
fVecColumn := integration.NewFloatVectorFieldData(integration.FloatVecField, s.rowNum, s.dim)
|
||||
jsonData := newJSONData(common.MetaFieldName, s.rowNum)
|
||||
jsonData.IsDynamic = true
|
||||
s.insertFlushIndexLoad(ctx, []*schemapb.FieldData{fVecColumn, jsonData})
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
expr string
|
||||
topK int
|
||||
resNum int
|
||||
}
|
||||
|
||||
func (s *ExpressionSuite) searchWithExpression() {
|
||||
testcases := []testCase{
|
||||
{"A + 5 > 0", 10, 10},
|
||||
{"B - 5 >= 0", 10, 10},
|
||||
{"C[0] * 5 < 500", 10, 10},
|
||||
{"E['F'] / 5 <= 100", 10, 10},
|
||||
{"E['G'] % 5 == 4", 10, 10},
|
||||
{"A / 5 != 4", 10, 10},
|
||||
}
|
||||
for _, c := range testcases {
|
||||
params := integration.GetSearchParams(integration.IndexFaissIDMap, metric.IP)
|
||||
searchReq := integration.ConstructSearchRequest(s.dbName, s.collectionName, c.expr,
|
||||
integration.FloatVecField, schemapb.DataType_FloatVector, nil, metric.IP, params, 1, s.dim, c.topK, -1)
|
||||
|
||||
searchResult, err := s.Cluster.Proxy.Search(context.Background(), searchReq)
|
||||
s.NoError(err)
|
||||
err = merr.Error(searchResult.GetStatus())
|
||||
s.NoError(err)
|
||||
s.Equal(c.resNum, len(searchResult.GetResults().GetScores()))
|
||||
log.Info(fmt.Sprintf("=========================Search done with expr:%s =========================", c.expr))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ExpressionSuite) TestExpression() {
|
||||
s.setParams()
|
||||
s.setupData()
|
||||
s.searchWithExpression()
|
||||
}
|
||||
|
||||
func TestExpression(t *testing.T) {
|
||||
suite.Run(t, new(ExpressionSuite))
|
||||
}
|
@ -627,12 +627,8 @@ class TestCollectionSearchInvalid(TestcaseBase):
|
||||
|
||||
# 2. search
|
||||
expression = "int32_array[0] - 1 < 1"
|
||||
error = {ct.err_code: 65535,
|
||||
ct.err_msg: f"failed to create query plan: cannot parse expression: {expression}, "
|
||||
f"error: LessThan is not supported in execution backend"}
|
||||
collection_w.search(vectors[:default_nq], default_search_field,
|
||||
default_search_params, nb, expression,
|
||||
check_task=CheckTasks.err_res, check_items=error)
|
||||
default_search_params, nb, expression)
|
||||
|
||||
@pytest.mark.tags(CaseLabel.L2)
|
||||
def test_search_partition_invalid_type(self, get_invalid_partition):
|
||||
|
Loading…
Reference in New Issue
Block a user