Skip to content

Commit

Permalink
Fix: python api error detect. (#1508)
Browse files Browse the repository at this point in the history
### What problem does this PR solve?

1. Remove all hardcode error number.
2. match tensor expression is needed when fusion method is "match
tensor".

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)

---------

Co-authored-by: Jin Hai <haijin.chn@gmail.com>
  • Loading branch information
small-turtle-1 and JinHai-CN authored Jul 21, 2024
1 parent f25f591 commit 0822053
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 44 deletions.
3 changes: 2 additions & 1 deletion python/infinity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
from infinity.infinity import InfinityConnection
from infinity.remote_thrift.infinity import RemoteThriftInfinityConnection
from infinity.local_infinity.infinity import LocalInfinityConnection
from infinity.errors import ErrorCode

def connect(uri) -> InfinityConnection:
if isinstance(uri, NetworkAddress):
return RemoteThriftInfinityConnection(uri)
elif isinstance(uri, str) and len(uri) != 0:
return LocalInfinityConnection(uri)
else:
raise InfinityException(7016, f"Unknown uri: {uri}")
raise InfinityException(ErrorCode.INVALID_SERVER_ADDRESS, f"Unknown uri: {uri}")
5 changes: 3 additions & 2 deletions python/infinity/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from infinity.embedded_infinity_ext import IndexType as LocalIndexType
from infinity.embedded_infinity_ext import InitParameter as LocalInitParameter
from infinity.embedded_infinity_ext import WrapIndexInfo as LocalIndexInfo
from infinity.errors import ErrorCode

class IndexType(Enum):
IVFFlat = 1
Expand Down Expand Up @@ -47,7 +48,7 @@ def to_ttype(self):
case IndexType.BMP:
return ttypes.IndexType.BMP
case _:
raise InfinityException(3060, "Unknown index type")
raise InfinityException(ErrorCode.INVALID_INDEX_TYPE, "Unknown index type")

def to_local_type(self):
match self:
Expand All @@ -66,7 +67,7 @@ def to_local_type(self):
case IndexType.BMP:
return LocalIndexType.kBMP
case _:
raise InfinityException(3060, "Unknown index type")
raise InfinityException(ErrorCode.INVALID_INDEX_TYPE, "Unknown index type")

class InitParameter:
def __init__(self, param_name: str, param_value: str):
Expand Down
20 changes: 10 additions & 10 deletions python/infinity/local_infinity/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_constant_expr(column_info):
constant_expression.literal_type = LiteralType.kDoubleArray
constant_expression.f64_array_value = default
else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")
return constant_expression

def get_ordinary_info(column_info, column_defs, column_name, index):
Expand Down Expand Up @@ -76,7 +76,7 @@ def get_ordinary_info(column_info, column_defs, column_name, index):
elif datatype == "bool":
proto_column_type.logical_type = LogicalType.kBoolean
else:
raise InfinityException(3051, f"Unknown datatype: {datatype}")
raise InfinityException(ErrorCode.INVALID_DATA_TYPE, f"Unknown datatype: {datatype}")

# process constraints
proto_column_def.column_type = proto_column_type
Expand All @@ -92,7 +92,7 @@ def get_ordinary_info(column_info, column_defs, column_name, index):
elif constraint == "unique":
proto_column_def.constraints.add(ConstraintType.kUnique)
else:
raise InfinityException(3055, f"Unknown constraint: {constraint}")
raise InfinityException(ErrorCode.INVALID_CONSTRAINT_TYPE, f"Unknown constraint: {constraint}")

proto_column_def.constant_expr = get_constant_expr(column_info)

Expand All @@ -117,7 +117,7 @@ def get_embedding_info(column_info, column_defs, column_name, index):
elif column_big_info[0] == "tensorarray":
column_type.logical_type = LogicalType.kTensorArray
else:
raise InfinityException(3053, f"Unknown column type: {column_big_info[0]}")
raise InfinityException(ErrorCode.FTS_INDEX_NOT_EXIST, f"Unknown column type: {column_big_info[0]}")

embedding_type = WrapEmbeddingType()
if element_type == "bit":
Expand All @@ -135,7 +135,7 @@ def get_embedding_info(column_info, column_defs, column_name, index):
elif element_type == "int64":
embedding_type.element_type = EmbeddingDataType.kElemInt64
else:
raise InfinityException(3057, f"Unknown element type: {element_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown element type: {element_type}")
embedding_type.dimension = int(length)
assert isinstance(embedding_type, WrapEmbeddingType)
assert embedding_type.element_type is not None
Expand Down Expand Up @@ -164,7 +164,7 @@ def get_sparse_info(column_info, column_defs, column_name, index):
if column_big_info[0] == "sparse":
column_type.logical_type = LogicalType.kSparse
else:
raise InfinityException(3053, f"Unknown column type: {column_big_info[0]}")
raise InfinityException(ErrorCode.FTS_INDEX_NOT_EXIST, f"Unknown column type: {column_big_info[0]}")

sparse_type = WrapSparseType()
# embedding_type = WrapEmbeddingType()
Expand All @@ -183,7 +183,7 @@ def get_sparse_info(column_info, column_defs, column_name, index):
elif element_type == "int64":
sparse_type.element_type = EmbeddingDataType.kElemInt64
else:
raise InfinityException(3057, f"Unknown element type: {element_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown element type: {element_type}")

if index_type == "int8":
sparse_type.index_type = EmbeddingDataType.kElemInt8
Expand All @@ -194,7 +194,7 @@ def get_sparse_info(column_info, column_defs, column_name, index):
elif index_type == "int64":
sparse_type.index_type = EmbeddingDataType.kElemInt64
else:
raise InfinityException(3057, f"Unknown index type: {index_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown index type: {index_type}")
sparse_type.dimension = int(length)

column_type.sparse_type = sparse_type
Expand Down Expand Up @@ -245,7 +245,7 @@ def create_table(self, table_name: str, columns_definition,
elif conflict_type == ConflictType.Replace:
create_table_conflict = LocalConflictType.kReplace
else:
raise InfinityException(3066, f"Invalid conflict type")
raise InfinityException(ErrorCode.INVALID_CONFLICT_TYPE, f"Invalid conflict type")
res = self._conn.create_table(db_name=self._db_name, table_name=table_name,
column_defs=column_defs,
conflict_type=create_table_conflict)
Expand All @@ -263,7 +263,7 @@ def drop_table(self, table_name, conflict_type: ConflictType = ConflictType.Erro
elif conflict_type == ConflictType.Ignore:
drop_table_conflict = LocalConflictType.kIgnore
else:
raise InfinityException(3066, "nvalid conflict type")
raise InfinityException(ErrorCode.INVALID_CONFLICT_TYPE, "nvalid conflict type")
res = self._conn.drop_table(db_name=self._db_name, table_name=table_name, conflict_type=drop_table_conflict)
if res.error_code == ErrorCode.OK or res.error_code == ErrorCode.TABLE_NOT_EXIST:
return res
Expand Down
2 changes: 1 addition & 1 deletion python/infinity/local_infinity/infinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def drop_database(self, db_name, conflict_type: ConflictType = ConflictType.Erro
elif conflict_type == ConflictType.Ignore:
drop_database_conflict = LocalConflictType.kIgnore
else:
raise InfinityException(3066, "Invalid conflict type")
raise InfinityException(ErrorCode.INVALID_CONFLICT_TYPE, "Invalid conflict type")

res = self._client.drop_database(db_name, drop_database_conflict)
if res.error_code == ErrorCode.OK:
Expand Down
14 changes: 7 additions & 7 deletions python/infinity/local_infinity/query_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from infinity.local_infinity.types import logic_type_to_dtype, make_match_tensor_expr
from infinity.local_infinity.utils import traverse_conditions, parse_expr
from infinity.table import ExplainType as BaseExplainType

from infinity.errors import ErrorCode

class Query(ABC):
def __init__(
Expand Down Expand Up @@ -82,7 +82,7 @@ def knn(

if not isinstance(topn, int):
raise InfinityException(
3073, f"Invalid topn, type should be embedded, but get {type(topn)}"
ErrorCode.INVALID_TOPK_TYPE, f"Invalid topn, type should be embedded, but get {type(topn)}"
)

# type casting
Expand All @@ -94,7 +94,7 @@ def knn(
embedding_data = embedding_data.tolist()
else:
raise InfinityException(
3051,
ErrorCode.INVALID_DATA_TYPE,
f"Invalid embedding data, type should be embedded, but get {type(embedding_data)}",
)

Expand Down Expand Up @@ -130,7 +130,7 @@ def knn(
elem_type = EmbeddingDataType.kElemDouble
data.f64_array_value = embedding_data
else:
raise InfinityException(3057, f"Invalid embedding {embedding_data[0]} type")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Invalid embedding {embedding_data[0]} type")

dist_type = KnnDistanceType.kInvalid
if distance_type == "l2":
Expand All @@ -142,7 +142,7 @@ def knn(
elif distance_type == "hamming":
dist_type = KnnDistanceType.kHamming
else:
raise InfinityException(3056, f"Invalid distance type {distance_type}")
raise InfinityException(ErrorCode.INVALID_KNN_DISTANCE_TYPE, f"Invalid distance type {distance_type}")

knn_opt_params = []
if knn_params != None:
Expand Down Expand Up @@ -181,7 +181,7 @@ def match_sparse(

if not isinstance(topn, int):
raise InfinityException(
3073, f"Invalid topn, type should be embedded, but get {type(topn)}"
ErrorCode.INVALID_TOPK_TYPE, f"Invalid topn, type should be embedded, but get {type(topn)}"
)

sparse_opt_params = []
Expand All @@ -205,7 +205,7 @@ def match_sparse(
sparse_expr.f64_array_value = sparse_data["values"]
else:
raise InfinityException(
3058, f"Invalid sparse data {sparse_data['values'][0]} type"
ErrorCode.INVALID_CONSTANT_TYPE, f"Invalid sparse data {sparse_data['values'][0]} type"
)
match_sparse_expr.sparse_expr = sparse_expr

Expand Down
18 changes: 9 additions & 9 deletions python/infinity/local_infinity/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,19 @@ def insert(self, data: Union[INSERT_DATA, list[INSERT_DATA]]):
constant_expression.i64_array_idx = value["indices"]
constant_expression.i64_array_value = value["values"]
else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")
elif isinstance(value["values"][0], float):
constant_expression.literal_type = LiteralType.kDoubleSparseArray
if isinstance(value["indices"][0], int):
constant_expression.i64_array_idx = value["indices"]
constant_expression.f64_array_value = value["values"]
else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")
else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")

else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")
parse_exprs.append(constant_expression)

fields.append(parse_exprs)
Expand Down Expand Up @@ -257,19 +257,19 @@ def import_data(self, file_path: str, import_options: {} = None):
elif file_type == 'fvecs':
options.copy_file_type = CopyFileType.kFVECS
else:
raise InfinityException(3037, f"Unrecognized export file type: {file_type}")
raise InfinityException(ErrorCode.IMPORT_FILE_FORMAT_ERROR, f"Unrecognized export file type: {file_type}")
elif key == 'delimiter':
delimiter = v.lower()
if len(delimiter) != 1:
raise InfinityException(3037, f"Unrecognized export file delimiter: {delimiter}")
raise InfinityException(ErrorCode.IMPORT_FILE_FORMAT_ERROR, f"Unrecognized export file delimiter: {delimiter}")
options.delimiter = delimiter[0]
elif key == 'header':
if isinstance(v, bool):
options.header = v
else:
raise InfinityException(3037, "Boolean value is expected in header field")
raise InfinityException(ErrorCode.IMPORT_FILE_FORMAT_ERROR, "Boolean value is expected in header field")
else:
raise InfinityException(3037, f"Unknown export parameter: {k}")
raise InfinityException(ErrorCode.IMPORT_FILE_FORMAT_ERROR, f"Unknown export parameter: {k}")

res = self._conn.import_data(db_name=self._db_name,
table_name=self._table_name,
Expand Down Expand Up @@ -383,7 +383,7 @@ def update(self, cond: Optional[str],
constant_expression.literal_type = LiteralType.kDoubleArray
constant_expression.f64_array_value = value
else:
raise InfinityException(3069, "Invalid constant expression")
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Invalid constant expression")

parsed_expr = WrapParsedExpr(ParsedExprType.kConstant)
parsed_expr.constant_expr = constant_expression
Expand Down
5 changes: 3 additions & 2 deletions python/infinity/local_infinity/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from numpy import dtype
from infinity.common import VEC, SPARSE, InfinityException, DEFAULT_MATCH_VECTOR_TOPN
from infinity.embedded_infinity_ext import *
from infinity.errors import ErrorCode

def logic_type_to_dtype(ttype: WrapDataType):
match ttype.logical_type:
Expand Down Expand Up @@ -275,7 +276,7 @@ def make_match_tensor_expr(vector_column_name: str, embedding_data: VEC, embeddi
data = EmbeddingData()
elem_type = EmbeddingDataType.kElemFloat
if embedding_data_type == 'bit':
raise InfinityException(3057, f"Invalid embedding {embedding_data[0]} type")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Invalid embedding {embedding_data[0]} type")
elif embedding_data_type == 'tinyint' or embedding_data_type == 'int8' or embedding_data_type == 'i8':
elem_type = EmbeddingDataType.kElemInt8
data.i8_array_value = np.asarray(embedding_data, dtype=np.int8).flatten()
Expand All @@ -295,7 +296,7 @@ def make_match_tensor_expr(vector_column_name: str, embedding_data: VEC, embeddi
elem_type = EmbeddingDataType.kElemDouble
data.f64_array_value = np.asarray(embedding_data, dtype=np.float64).flatten()
else:
raise InfinityException(3057, f"Invalid embedding {embedding_data[0]} type")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Invalid embedding {embedding_data[0]} type")

match_tensor_expr.embedding_data_type = elem_type
match_tensor_expr.embedding_data = data
Expand Down
6 changes: 3 additions & 3 deletions python/infinity/remote_thrift/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def get_embedding_info(column_info, column_defs, column_name, index):
elif element_type == "int64":
embedding_type.element_type = ttypes.ElementType.ElementInt64
else:
raise InfinityException(3057, f"Unknown element type: {element_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown element type: {element_type}")
embedding_type.dimension = int(length)
assert isinstance(embedding_type, ttypes.EmbeddingType)
assert embedding_type.element_type is not None
Expand Down Expand Up @@ -188,7 +188,7 @@ def get_sparse_info(column_info, column_defs, column_name, index):
elif value_type == "int64":
sparse_type.element_type = ttypes.ElementType.ElementInt64
else:
raise InfinityException(3057, f"Unknown value type: {value_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown value type: {value_type}")

if index_type == "int8":
sparse_type.index_type = ttypes.ElementType.ElementInt8
Expand All @@ -199,7 +199,7 @@ def get_sparse_info(column_info, column_defs, column_name, index):
elif index_type == "int64":
sparse_type.index_type = ttypes.ElementType.ElementInt64
else:
raise InfinityException(3057, f"Unknown index type: {index_type}")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Unknown index type: {index_type}")

sparse_type.dimension = int(length)

Expand Down
10 changes: 6 additions & 4 deletions python/infinity/remote_thrift/query_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def knn(

if not isinstance(topn, int):
raise InfinityException(
3073, f"Invalid topn, type should be embedded, but get {type(topn)}"
ErrorCode.INVALID_TOPK_TYPE, f"Invalid topn, type should be embedded, but get {type(topn)}"
)

# type casting
Expand Down Expand Up @@ -128,7 +128,7 @@ def knn(
elem_type = ElementType.ElementFloat32
if embedding_data_type == "bit":
elem_type = ElementType.ElementBit
raise InfinityException(3057, f"Invalid embedding {embedding_data[0]} type")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Invalid embedding {embedding_data[0]} type")
elif embedding_data_type == "tinyint":
elem_type = ElementType.ElementInt8
data.i8_array_value = embedding_data
Expand All @@ -148,7 +148,7 @@ def knn(
elem_type = ElementType.ElementFloat64
data.f64_array_value = embedding_data
else:
raise InfinityException(3057, f"Invalid embedding {embedding_data[0]} type")
raise InfinityException(ErrorCode.INVALID_EMBEDDING_DATA_TYPE, f"Invalid embedding {embedding_data[0]} type")

dist_type = KnnDistanceType.L2
if distance_type == "l2":
Expand All @@ -160,7 +160,7 @@ def knn(
elif distance_type == "hamming":
dist_type = KnnDistanceType.Hamming
else:
raise InfinityException(3056, f"Invalid distance type {distance_type}")
raise InfinityException(ErrorCode.INVALID_KNN_DISTANCE_TYPE, f"Invalid distance type {distance_type}")

knn_opt_params = []
if knn_params != None:
Expand Down Expand Up @@ -249,6 +249,8 @@ def fusion(
fusion_expr.options_text = options_text
if match_tensor_expr is not None:
fusion_expr.optional_match_tensor_expr = match_tensor_expr
elif fusion_expr.method == "match_tensor":
raise InfinityException(ErrorCode.INVALID_EXPRESSION, "Match tensor expression is required")
self._search.fusion_exprs.append(fusion_expr)
return self

Expand Down
Loading

0 comments on commit 0822053

Please sign in to comment.