mirror of
https://github.com/qdrant/qdrant-client.git
synced 2026-09-21 13:37:55 -05:00
fix: pin keyword index prefix=False round-trip behavior over gRPC (#1356)
grpc.KeywordPrefixParams is an empty message: presence is the only signal, so an explicit prefix=False cannot be represented in gRPC. It is sent as absent (same server-side semantics, disabled) and is recovered as None. Document this at both conversion sites and pin the behavior with a reverse-direction (rest->grpc->rest) test.
This commit is contained in:
@@ -1689,6 +1689,8 @@ class GrpcToRest:
|
||||
on_disk=model.on_disk if model.HasField("on_disk") else None,
|
||||
memory=cls.convert_memory(model.memory) if model.HasField("memory") else None,
|
||||
enable_hnsw=model.enable_hnsw if model.HasField("enable_hnsw") else None,
|
||||
# presence of grpc.KeywordPrefixParams is the only signal, an explicit `prefix=False`
|
||||
# cannot be represented in grpc and comes back as `None`
|
||||
prefix=True if model.HasField("prefix") else None,
|
||||
)
|
||||
|
||||
@@ -4383,6 +4385,9 @@ class RestToGrpc:
|
||||
is_tenant=model.is_tenant,
|
||||
on_disk=model.on_disk,
|
||||
enable_hnsw=model.enable_hnsw,
|
||||
# grpc.KeywordPrefixParams is an empty message, its presence enables prefix matching,
|
||||
# so an explicit `prefix=False` is sent as absent (which the server also treats as
|
||||
# disabled) and is recovered as `None` when converting back
|
||||
prefix=grpc.KeywordPrefixParams() if model.prefix else None,
|
||||
memory=cls.convert_memory(model.memory) if model.memory is not None else None,
|
||||
)
|
||||
|
||||
@@ -643,3 +643,30 @@ def test_convert_points_update_operation_falsy_shard_key():
|
||||
"shard_key_selector"
|
||||
), f"{type(operation).__name__} dropped shard_key={shard_key!r}"
|
||||
assert GrpcToRest.convert_shard_key_selector(inner.shard_key_selector) == shard_key
|
||||
|
||||
|
||||
def test_convert_keyword_index_params_prefix():
|
||||
from qdrant_client import models
|
||||
from qdrant_client.conversions.conversion import GrpcToRest, RestToGrpc
|
||||
|
||||
def round_trip(prefix):
|
||||
rest_params = models.KeywordIndexParams(
|
||||
type=models.KeywordIndexType.KEYWORD, prefix=prefix
|
||||
)
|
||||
grpc_params = RestToGrpc.convert_keyword_index_params(rest_params)
|
||||
return grpc_params, GrpcToRest.convert_keyword_index_params(grpc_params)
|
||||
|
||||
grpc_params, recovered = round_trip(True)
|
||||
assert grpc_params.HasField("prefix")
|
||||
assert recovered.prefix is True
|
||||
|
||||
grpc_params, recovered = round_trip(None)
|
||||
assert not grpc_params.HasField("prefix")
|
||||
assert recovered.prefix is None
|
||||
|
||||
# grpc.KeywordPrefixParams is an empty message whose presence enables prefix matching,
|
||||
# so an explicit `prefix=False` cannot be represented in grpc: it is sent as absent
|
||||
# (which the server also treats as disabled) and is recovered as `None`
|
||||
grpc_params, recovered = round_trip(False)
|
||||
assert not grpc_params.HasField("prefix")
|
||||
assert recovered.prefix is None
|
||||
|
||||
Reference in New Issue
Block a user