mirror of https://github.com/milvus-io/milvus.git
fix: text match panics when enable_match is set be false (#38950)
fix: https://github.com/milvus-io/milvus/issues/38949 --------- Signed-off-by: SpadeA-Tang <tangchenjie1210@gmail.com>pull/38980/head
parent
d7623ab635
commit
4245c5bed1
|
@ -69,6 +69,7 @@ enum ErrorCode {
|
||||||
FollyCancel = 2038,
|
FollyCancel = 2038,
|
||||||
OutOfRange = 2039,
|
OutOfRange = 2039,
|
||||||
GcpNativeError = 2040,
|
GcpNativeError = 2040,
|
||||||
|
TextIndexNotFound = 2041,
|
||||||
|
|
||||||
KnowhereError = 2099
|
KnowhereError = 2099
|
||||||
};
|
};
|
||||||
|
|
|
@ -863,7 +863,11 @@ SegmentGrowingImpl::AddTexts(milvus::FieldId field_id,
|
||||||
int64_t offset_begin) {
|
int64_t offset_begin) {
|
||||||
std::unique_lock lock(mutex_);
|
std::unique_lock lock(mutex_);
|
||||||
auto iter = text_indexes_.find(field_id);
|
auto iter = text_indexes_.find(field_id);
|
||||||
AssertInfo(iter != text_indexes_.end(), "text index not found");
|
if (iter == text_indexes_.end()) {
|
||||||
|
throw SegcoreError(
|
||||||
|
ErrorCode::TextIndexNotFound,
|
||||||
|
fmt::format("text index not found for field {}", field_id.get()));
|
||||||
|
}
|
||||||
iter->second->AddTexts(n, texts, texts_valid_data, offset_begin);
|
iter->second->AddTexts(n, texts, texts_valid_data, offset_begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -396,8 +396,11 @@ index::TextMatchIndex*
|
||||||
SegmentInternalInterface::GetTextIndex(FieldId field_id) const {
|
SegmentInternalInterface::GetTextIndex(FieldId field_id) const {
|
||||||
std::shared_lock lock(mutex_);
|
std::shared_lock lock(mutex_);
|
||||||
auto iter = text_indexes_.find(field_id);
|
auto iter = text_indexes_.find(field_id);
|
||||||
AssertInfo(iter != text_indexes_.end(),
|
if (iter == text_indexes_.end()) {
|
||||||
"failed to get text index, text index not found");
|
throw SegcoreError(
|
||||||
|
ErrorCode::TextIndexNotFound,
|
||||||
|
fmt::format("text index not found for field {}", field_id.get()));
|
||||||
|
}
|
||||||
return iter->second.get();
|
return iter->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -486,6 +486,10 @@ func (v *ParserVisitor) VisitTextMatch(ctx *parser.TextMatchContext) interface{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
columnInfo := toColumnInfo(column)
|
||||||
|
if !v.schema.IsFieldTextMatchEnabled(columnInfo.FieldId) {
|
||||||
|
return fmt.Errorf("field %v does not enable text match", columnInfo.FieldId)
|
||||||
|
}
|
||||||
if !typeutil.IsStringType(column.dataType) {
|
if !typeutil.IsStringType(column.dataType) {
|
||||||
return fmt.Errorf("text match operation on non-string is unsupported")
|
return fmt.Errorf("text match operation on non-string is unsupported")
|
||||||
}
|
}
|
||||||
|
@ -499,7 +503,7 @@ func (v *ParserVisitor) VisitTextMatch(ctx *parser.TextMatchContext) interface{}
|
||||||
expr: &planpb.Expr{
|
expr: &planpb.Expr{
|
||||||
Expr: &planpb.Expr_UnaryRangeExpr{
|
Expr: &planpb.Expr_UnaryRangeExpr{
|
||||||
UnaryRangeExpr: &planpb.UnaryRangeExpr{
|
UnaryRangeExpr: &planpb.UnaryRangeExpr{
|
||||||
ColumnInfo: toColumnInfo(column),
|
ColumnInfo: columnInfo,
|
||||||
Op: planpb.OpType_TextMatch,
|
Op: planpb.OpType_TextMatch,
|
||||||
Value: NewString(queryText),
|
Value: NewString(queryText),
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||||
"github.com/milvus-io/milvus/pkg/common"
|
"github.com/milvus-io/milvus/pkg/common"
|
||||||
|
@ -53,6 +54,16 @@ func newTestSchema(EnableDynamicField bool) *schemapb.CollectionSchema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enableMatch(schema *schemapb.CollectionSchema) {
|
||||||
|
for _, field := range schema.Fields {
|
||||||
|
if typeutil.IsStringType(field.DataType) {
|
||||||
|
field.TypeParams = append(field.TypeParams, &commonpb.KeyValuePair{
|
||||||
|
Key: "enable_match", Value: "True",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newTestSchemaHelper(t *testing.T) *typeutil.SchemaHelper {
|
func newTestSchemaHelper(t *testing.T) *typeutil.SchemaHelper {
|
||||||
schema := newTestSchema(true)
|
schema := newTestSchema(true)
|
||||||
schemaHelper, err := typeutil.CreateSchemaHelper(schema)
|
schemaHelper, err := typeutil.CreateSchemaHelper(schema)
|
||||||
|
@ -221,6 +232,11 @@ func TestExpr_TextMatch(t *testing.T) {
|
||||||
exprStrs := []string{
|
exprStrs := []string{
|
||||||
`text_match(VarCharField, "query")`,
|
`text_match(VarCharField, "query")`,
|
||||||
}
|
}
|
||||||
|
for _, exprStr := range exprStrs {
|
||||||
|
assertInvalidExpr(t, helper, exprStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
enableMatch(schema)
|
||||||
for _, exprStr := range exprStrs {
|
for _, exprStr := range exprStrs {
|
||||||
assertValidExpr(t, helper, exprStr)
|
assertValidExpr(t, helper, exprStr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,6 +389,14 @@ func (helper *SchemaHelper) IsFieldLoaded(fieldID int64) bool {
|
||||||
return helper.loadFields.Contain(fieldID)
|
return helper.loadFields.Contain(fieldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (helper *SchemaHelper) IsFieldTextMatchEnabled(fieldId int64) bool {
|
||||||
|
sche, err := helper.GetFieldFromID(fieldId)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return CreateFieldSchemaHelper(sche).EnableMatch()
|
||||||
|
}
|
||||||
|
|
||||||
func (helper *SchemaHelper) getDefaultJSONField(fieldName string) (*schemapb.FieldSchema, error) {
|
func (helper *SchemaHelper) getDefaultJSONField(fieldName string) (*schemapb.FieldSchema, error) {
|
||||||
for _, f := range helper.schema.GetFields() {
|
for _, f := range helper.schema.GetFields() {
|
||||||
if f.DataType == schemapb.DataType_JSON && f.IsDynamic {
|
if f.DataType == schemapb.DataType_JSON && f.IsDynamic {
|
||||||
|
|
Loading…
Reference in New Issue