diff --git a/pyproject.toml b/pyproject.toml index 812f3c4f14..0f530f16ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "sentry-arroyo>=2.39.2", "sentry-conventions>=0.12.0", "sentry-kafka-schemas>=2.1.36", - "sentry-protos>=0.32.0", + "sentry-protos>=0.34.0", "sentry-redis-tools>=0.5.1", "sentry-relay>=0.9.25", "sentry-sdk>=2.35.0", diff --git a/snuba/web/rpc/v1/endpoint_trace_item_attribute_names.py b/snuba/web/rpc/v1/endpoint_trace_item_attribute_names.py index 891cf0ba06..e570171baa 100644 --- a/snuba/web/rpc/v1/endpoint_trace_item_attribute_names.py +++ b/snuba/web/rpc/v1/endpoint_trace_item_attribute_names.py @@ -52,6 +52,10 @@ ] NON_STORED_ATTRIBUTE_KEYS = ["sentry.service"] +MATCH_MODES = { + TraceItemAttributeNamesRequest.MatchMode.MATCH_MODE_ANY: f.hasAny, + TraceItemAttributeNamesRequest.MatchMode.MATCH_MODE_ALL: f.hasAll, +} def _order_by_count(request: TraceItemAttributeNamesRequest) -> bool: @@ -244,7 +248,7 @@ def get_co_occurring_attributes( if attribute_keys_to_search: condition = and_cond( condition, - f.hasAll( + MATCH_MODES.get(request.match_mode, f.hasAll)( column("attribute_keys_hash"), f.array(*[f.cityHash64(k) for k in attribute_keys_to_search]), ), diff --git a/tests/web/rpc/v1/test_endpoint_trace_item_attribute_names.py b/tests/web/rpc/v1/test_endpoint_trace_item_attribute_names.py index 858de05281..8ec1f4324c 100644 --- a/tests/web/rpc/v1/test_endpoint_trace_item_attribute_names.py +++ b/tests/web/rpc/v1/test_endpoint_trace_item_attribute_names.py @@ -9,7 +9,7 @@ ) from sentry_protos.snuba.v1.request_common_pb2 import RequestMeta from sentry_protos.snuba.v1.trace_item_attribute_pb2 import AttributeKey -from sentry_protos.snuba.v1.trace_item_filter_pb2 import ExistsFilter, TraceItemFilter +from sentry_protos.snuba.v1.trace_item_filter_pb2 import AndFilter, ExistsFilter, TraceItemFilter from sentry_protos.snuba.v1.trace_item_pb2 import AnyValue from snuba.datasets.storages.factory import get_storage @@ -240,6 +240,46 @@ def test_basic_co_occurring_attrs(self) -> None: ] assert res.attributes == expected + def test_basic_co_occurring_attrs_with_match_any(self) -> None: + req = TraceItemAttributeNamesRequest( + meta=RequestMeta( + project_ids=[1, 2, 3], + organization_id=1, + cogs_category="something", + referrer="something", + start_timestamp=Timestamp(seconds=int((BASE_TIME - timedelta(days=1)).timestamp())), + end_timestamp=Timestamp(seconds=int((BASE_TIME + timedelta(days=1)).timestamp())), + ), + limit=TOTAL_GENERATED_ATTR_PER_TYPE, + intersecting_attributes_filter=TraceItemFilter( + and_filter=AndFilter( + filters=[ + TraceItemFilter( + exists_filter=ExistsFilter( + key=AttributeKey(type=AttributeKey.TYPE_STRING, name=key) + ) + ) + for key in ["a_tag_000", "a_tag_001"] + ] + ) + ), + match_mode=TraceItemAttributeNamesRequest.MatchMode.MATCH_MODE_ANY, + type=AttributeKey.Type.TYPE_STRING, + ) + res = EndpointTraceItemAttributeNames().execute(req) + assert ( + TraceItemAttributeNamesResponse.Attribute( + name="a_tag_000", type=AttributeKey.Type.TYPE_STRING + ) + in res.attributes + ) + assert ( + TraceItemAttributeNamesResponse.Attribute( + name="a_tag_001", type=AttributeKey.Type.TYPE_STRING + ) + in res.attributes + ) + def test_co_occurring_attrs_excludes_unsearchable_keys_without_in_set(self) -> None: """Regression guard for SNUBA-B82 (mixed-version distributed reads). diff --git a/uv.lock b/uv.lock index 8a916198be..d527bb6708 100644 --- a/uv.lock +++ b/uv.lock @@ -935,7 +935,7 @@ wheels = [ [[package]] name = "sentry-protos" -version = "0.32.0" +version = "0.34.0" source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "grpc-stubs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, @@ -943,7 +943,7 @@ dependencies = [ { name = "protobuf", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/sentry_protos-0.32.0-py3-none-any.whl", hash = "sha256:793f8725ccc82f0c6a75e9703e8f21bfd815b4b4886e708398715af0814bec7a" }, + { url = "https://pypi.devinfra.sentry.io/wheels/sentry_protos-0.34.0-py3-none-any.whl", hash = "sha256:917fc77bc17662680fbbb93ed056de5a44201982c367a1179842e355ae5ca244" }, ] [[package]] @@ -1141,7 +1141,7 @@ requires-dist = [ { name = "sentry-arroyo", specifier = ">=2.39.2" }, { name = "sentry-conventions", specifier = ">=0.12.0" }, { name = "sentry-kafka-schemas", specifier = ">=2.1.36" }, - { name = "sentry-protos", specifier = ">=0.32.0" }, + { name = "sentry-protos", specifier = ">=0.34.0" }, { name = "sentry-redis-tools", specifier = ">=0.5.1" }, { name = "sentry-relay", specifier = ">=0.9.25" }, { name = "sentry-sdk", specifier = ">=2.35.0" },