Просмотр исходного кода

fix(discover) Display tags that look like function aggregates (#19611)

When using a tag like `count_diff` the API endpoint would incorrectly
hint that the output type was an integer when the value was a string.
This was caused by a greedy pattern in the metadata formatter. We should
only retype values that are not strings in snuba/clickhouse.
Mark Story 4 лет назад
Родитель
Сommit
b19efe2475

+ 3 - 2
src/sentry/api/event_search.py

@@ -985,8 +985,9 @@ def get_json_meta_type(field_alias, snuba_type):
     alias_definition = FIELD_ALIASES.get(field_alias)
     if alias_definition and alias_definition.get("result_type"):
         return alias_definition.get("result_type")
+    snuba_json = get_json_type(snuba_type)
     function_match = FUNCTION_ALIAS_PATTERN.match(field_alias)
-    if function_match:
+    if function_match and snuba_json != "string":
         function_definition = FUNCTIONS.get(function_match.group(1))
         if function_definition and function_definition.get("result_type"):
             return function_definition.get("result_type")
@@ -994,7 +995,7 @@ def get_json_meta_type(field_alias, snuba_type):
         return "duration"
     if field_alias == "transaction.status":
         return "string"
-    return get_json_type(snuba_type)
+    return snuba_json
 
 
 FUNCTION_PATTERN = re.compile(r"^(?P<function>[^\(]+)\((?P<columns>[^\)]*)\)$")

+ 15 - 12
tests/sentry/api/test_event_search.py

@@ -41,18 +41,21 @@ def test_get_json_meta_type():
     assert get_json_meta_type("transaction", "Char") == "string"
     assert get_json_meta_type("foo", "unknown") == "string"
     assert get_json_meta_type("other", "") == "string"
-    assert get_json_meta_type("avg_duration", "number") == "duration"
-    assert get_json_meta_type("duration", "number") == "duration"
-    assert get_json_meta_type("p50", "number") == "duration"
-    assert get_json_meta_type("p75", "number") == "duration"
-    assert get_json_meta_type("p95", "number") == "duration"
-    assert get_json_meta_type("p99", "number") == "duration"
-    assert get_json_meta_type("p100", "number") == "duration"
-    assert get_json_meta_type("apdex_transaction_duration_300", "number") == "number"
-    assert get_json_meta_type("failure_rate", "number") == "percentage"
-    assert get_json_meta_type("impact_300", "number") == "number"
-    assert get_json_meta_type("user_misery_300", "number") == "number"
-    assert get_json_meta_type("percentile_transaction_duration_0_95", "number") == "duration"
+    assert get_json_meta_type("avg_duration", "") == "duration"
+    assert get_json_meta_type("duration", "UInt64") == "duration"
+    assert get_json_meta_type("p50", "Float32") == "duration"
+    assert get_json_meta_type("p75", "Float32") == "duration"
+    assert get_json_meta_type("p95", "Float32") == "duration"
+    assert get_json_meta_type("p99", "Float32") == "duration"
+    assert get_json_meta_type("p100", "Float32") == "duration"
+    assert get_json_meta_type("apdex_transaction_duration_300", "Float32") == "number"
+    assert get_json_meta_type("failure_rate", "Float32") == "percentage"
+    assert get_json_meta_type("impact_300", "Float32") == "number"
+    assert get_json_meta_type("user_misery_300", "Float32") == "number"
+    assert get_json_meta_type("percentile_transaction_duration_0_95", "Float32") == "duration"
+    assert get_json_meta_type("count_thing", "UInt64") == "integer"
+    assert get_json_meta_type("count_thing", "String") == "string"
+    assert get_json_meta_type("count_thing", "Nullable(String)") == "string"
 
 
 class ParseSearchQueryTest(unittest.TestCase):

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

@@ -1839,6 +1839,38 @@ class OrganizationEventsV2EndpointTest(APITestCase, SnubaTestCase):
             assert len(data) == 1
             assert data[0]["count_id"] == 0
 
+    def test_tag_that_looks_like_aggregation(self):
+        self.login_as(user=self.user)
+
+        project = self.create_project()
+        data = {
+            "message": "Failure state",
+            "timestamp": self.two_min_ago,
+            "tags": {"count_diff": 99},
+        }
+        self.store_event(data, project_id=project.id)
+        with self.feature("organizations:discover-basic"):
+            response = self.client.get(
+                self.url,
+                format="json",
+                data={
+                    "field": ["message", "count_diff", "count()"],
+                    "query": "",
+                    "project": [project.id],
+                    "statsPeriod": "24h",
+                },
+            )
+            assert response.status_code == 200, response.content
+            meta = response.data["meta"]
+            assert "string" == meta["count_diff"], "tags should not be counted as integers"
+            assert "string" == meta["message"]
+            assert "integer" == meta["count"]
+            assert 1 == len(response.data["data"])
+            data = response.data["data"][0]
+            assert "99" == data["count_diff"]
+            assert "Failure state" == data["message"]
+            assert 1 == data["count"]
+
     def test_aggregate_negation(self):
         self.login_as(user=self.user)