Browse Source

fix(mep): Fix bug with metricsEnhanced and timestamp (#62090)

- This fixes a bug with primary/secondary queries if a timestamp is
included where the timezone would remain and clickhouse would error
- Fixes SENTRY-2BBG
William Mak 1 year ago
parent
commit
c8ba90a2ad

+ 13 - 4
src/sentry/search/events/builder/metrics.py

@@ -1148,17 +1148,26 @@ class MetricsQueryBuilder(QueryBuilder):
                     f"{referrer}.{referrer_suffix}",
                     use_cache,
                 )
+                for meta in current_result["meta"]:
+                    meta_dict[meta["name"]] = meta["type"]
                 for row in current_result["data"]:
                     # Arrays in clickhouse cannot contain multiple types, and since groupby values
                     # can contain any type, we must use tuples instead
-                    groupby_key = tuple(row[key] for key in groupby_aliases)
-                    value_map_key = ",".join(str(value) for value in groupby_key)
+                    groupby_key = tuple()
+                    value_map_strings = []
+                    for key in groupby_aliases:
+                        value = row[key]
+                        if meta_dict.get(key) == "DateTime":
+                            value = datetime.fromisoformat(value).replace(tzinfo=None)
+                            groupby_key += (str(value),)
+                        else:
+                            groupby_key += (value,)
+                        value_map_strings.append(str(value))
+                    value_map_key = ",".join(value_map_strings)
                     # First time we're seeing this value, add it to the values we're going to filter by
                     if value_map_key not in value_map and groupby_key:
                         groupby_values.append(groupby_key)
                     value_map[value_map_key].update(row)
-                for meta in current_result["meta"]:
-                    meta_dict[meta["name"]] = meta["type"]
 
         result["data"] = list(value_map.values())
         result["meta"] = [{"name": key, "type": value} for key, value in meta_dict.items()]

+ 32 - 0
tests/snuba/api/endpoints/test_organization_events_mep.py

@@ -3061,6 +3061,34 @@ class OrganizationEventsMetricsEnhancedPerformanceEndpointTest(MetricsEnhancedPe
 
         assert meta["isMetricsData"]
 
+    def test_timestamp_groupby(self):
+        self.store_transaction_metric(
+            0.03,
+            tags={"transaction": "foo_transaction", "user": "foo"},
+            timestamp=self.min_ago,
+        )
+
+        response = self.do_request(
+            {
+                "field": [
+                    "transaction",
+                    "timestamp",
+                    "count()",
+                    "count_unique(user)",
+                ],
+                "query": "event.type:transaction",
+                "dataset": "metricsEnhanced",
+                "per_page": 50,
+            }
+        )
+        assert response.status_code == 200, response.content
+        assert len(response.data["data"]) == 1
+        data = response.data["data"]
+        meta = response.data["meta"]
+
+        assert data[0]["transaction"] == "foo_transaction"
+        assert meta["dataset"] == "metricsEnhanced"
+
 
 class OrganizationEventsMetricsEnhancedPerformanceEndpointTestWithOnDemandMetrics(
     MetricsEnhancedPerformanceTestCase
@@ -3216,3 +3244,7 @@ class OrganizationEventsMetricsEnhancedPerformanceEndpointTestWithMetricLayer(
     @pytest.mark.xfail(reason="Not implemented")
     def test_count_starts(self):
         super().test_count_starts()
+
+    @pytest.mark.xfail(reason="Not implemented")
+    def test_timestamp_groupby(self):
+        super().test_timestamp_groupby()