Browse Source

fix(spans): Return proper type for span duration (#72414)

The attribute span.duration needs to be marked as a duration type on all
query builders so that conditions on it resolve correctly, but this was
only done for the `SpansIndexedQueryBuilder`. This ensures it also
correctly classified for the other spans indexed dataset related query
builders.
Tony Xiao 9 months ago
parent
commit
6b856d91dc

+ 15 - 11
src/sentry/search/events/builder/spans_indexed.py

@@ -7,15 +7,8 @@ from sentry.search.events.fields import custom_time_processor
 from sentry.search.events.types import SelectType
 
 
-class SpansIndexedQueryBuilder(QueryBuilder):
-    requires_organization_condition = False
-    uuid_fields = {"transaction.id", "replay.id", "profile.id", "trace"}
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        self.value_resolver_map[
-            constants.SPAN_STATUS
-        ] = lambda status: SPAN_STATUS_CODE_TO_NAME.get(status)
+class SpansIndexedQueryBuilderMixin:
+    meta_resolver_map: dict[str, str]
 
     def get_field_type(self, field: str) -> str | None:
         if field in self.meta_resolver_map:
@@ -26,7 +19,18 @@ class SpansIndexedQueryBuilder(QueryBuilder):
         return None
 
 
-class TimeseriesSpanIndexedQueryBuilder(TimeseriesQueryBuilder):
+class SpansIndexedQueryBuilder(SpansIndexedQueryBuilderMixin, QueryBuilder):
+    requires_organization_condition = False
+    uuid_fields = {"transaction.id", "replay.id", "profile.id", "trace"}
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.value_resolver_map[
+            constants.SPAN_STATUS
+        ] = lambda status: SPAN_STATUS_CODE_TO_NAME.get(status)
+
+
+class TimeseriesSpanIndexedQueryBuilder(SpansIndexedQueryBuilderMixin, TimeseriesQueryBuilder):
     @property
     def time_column(self) -> SelectType:
         return custom_time_processor(
@@ -34,7 +38,7 @@ class TimeseriesSpanIndexedQueryBuilder(TimeseriesQueryBuilder):
         )
 
 
-class TopEventsSpanIndexedQueryBuilder(TopEventsQueryBuilder):
+class TopEventsSpanIndexedQueryBuilder(SpansIndexedQueryBuilderMixin, TopEventsQueryBuilder):
     @property
     def time_column(self) -> SelectType:
         return custom_time_processor(

+ 13 - 0
tests/sentry/api/endpoints/test_organization_traces.py

@@ -1091,6 +1091,19 @@ class OrganizationTracesStatsEndpointTest(OrganizationTracesEndpointTestBase):
             ],
         }
 
+    def test_span_duration_filter(self):
+        for q in [
+            ["span.duration:>100"],
+        ]:
+            query = {
+                "yAxis": ["count()"],
+                "query": q,
+                "project": [self.project.id],
+            }
+
+            response = self.do_request(query)
+            assert response.status_code == 200, response.data
+
     def test_stats(self):
         project_1 = self.create_project()
         project_2 = self.create_project()