Skip to content

Commit b990231

Browse files
authored
ref(query-builder): Cleanup query_framework code (#54586)
- This is mostly a cleanup that came about trying to add more logic around the query frameworks to query both transactions & span data in a single request. But we realized that sorting/querying wouldn't work so reverted all that. This is still good cleanup since it removes a bunch of code repeat
1 parent f2cc9f8 commit b990231

File tree

1 file changed

+35
-81
lines changed

1 file changed

+35
-81
lines changed

src/sentry/search/events/builder/metrics.py

Lines changed: 35 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ def get_snql_query(self) -> Request:
712712
tenant_ids=self.tenant_ids,
713713
)
714714

715-
def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]:
715+
def _get_base_query_framework(self) -> Dict[str, QueryFramework]:
716716
prefix = "generic_" if self.dataset is Dataset.PerformanceMetrics else ""
717717
query_framework: Dict[str, QueryFramework] = {
718718
"distribution": QueryFramework(
@@ -748,85 +748,44 @@ def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]:
748748
entity=Entity(f"{prefix}metrics_distributions", sample=self.sample_rate),
749749
),
750750
}
751+
return query_framework
752+
753+
def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]:
754+
query_framework = self._get_base_query_framework()
751755
primary = None
752-
# Metrics layer can't have aliases in the functions for some reason
753-
metrics_layer_without_aliases = [
754-
function.exp if isinstance(function, AliasedExpression) else function
755-
for function in self.metrics_layer_functions
756-
]
757-
percentiles_without_aliases = [
758-
function.exp if isinstance(function, AliasedExpression) else function
759-
for function in self.percentiles
760-
]
761756
# if orderby spans more than one table, the query isn't possible with metrics
762757
for orderby in self.orderby:
763-
if orderby.exp in self.sets:
764-
query_framework["set"].orderby.append(orderby)
765-
if primary not in [None, "set"]:
766-
raise IncompatibleMetricsQuery("Can't order across tables")
767-
primary = "set"
768-
elif orderby.exp in self.counters:
769-
query_framework["counter"].orderby.append(orderby)
770-
if primary not in [None, "counter"]:
771-
raise IncompatibleMetricsQuery("Can't order across tables")
772-
primary = "counter"
773-
elif orderby.exp in self.distributions:
774-
query_framework["distribution"].orderby.append(orderby)
775-
if primary not in [None, "distribution"]:
776-
raise IncompatibleMetricsQuery("Can't order across tables")
777-
primary = "distribution"
778-
elif orderby.exp in metrics_layer_without_aliases:
779-
query_framework["metrics_layer"].orderby.append(orderby)
780-
if primary not in [None, "metrics_layer"]:
781-
raise IncompatibleMetricsQuery("Can't order across tables")
782-
primary = "metrics_layer"
783-
elif orderby.exp in percentiles_without_aliases:
784-
query_framework["percentiles"].orderby.append(orderby)
785-
if primary not in [None, "percentiles"]:
786-
raise IncompatibleMetricsQuery("Can't order across tables")
787-
primary = "percentiles"
758+
for entity, framework in query_framework.items():
759+
# Metrics layer can't have aliases in the functions for some reason
760+
if self.use_metrics_layer:
761+
framework_functions = [
762+
function.exp if isinstance(function, AliasedExpression) else function
763+
for function in framework.functions
764+
]
765+
else:
766+
framework_functions = framework.functions
767+
if orderby.exp in framework_functions:
768+
framework.orderby.append(orderby)
769+
if primary not in [None, entity]:
770+
raise IncompatibleMetricsQuery("Can't order across tables")
771+
primary = entity
772+
break
788773
else:
789774
# An orderby that isn't on a function add it to all of them
790775
for framework in query_framework.values():
791776
framework.orderby.append(orderby)
792777

793778
having_entity: Optional[str] = None
794779
for condition in self.flattened_having:
795-
if condition.lhs in self.sets:
796-
if having_entity is None:
797-
having_entity = "set"
798-
elif having_entity != "set":
799-
raise IncompatibleMetricsQuery(
800-
"Can only have aggregate conditions on one entity"
801-
)
802-
elif condition.lhs in self.counters:
803-
if having_entity is None:
804-
having_entity = "counter"
805-
elif having_entity != "counter":
806-
raise IncompatibleMetricsQuery(
807-
"Can only have aggregate conditions on one entity"
808-
)
809-
elif condition.lhs in self.distributions:
810-
if having_entity is None:
811-
having_entity = "distribution"
812-
elif having_entity != "distribution":
813-
raise IncompatibleMetricsQuery(
814-
"Can only have aggregate conditions on one entity"
815-
)
816-
elif condition.lhs in self.metrics_layer_functions:
817-
if having_entity is None:
818-
having_entity = "metrics_layer"
819-
elif having_entity != "metrics_layer":
820-
raise IncompatibleMetricsQuery(
821-
"Can only have aggregate conditions on one entity"
822-
)
823-
elif condition.lhs in self.percentiles:
824-
if having_entity is None:
825-
having_entity = "percentiles"
826-
elif having_entity != "percentiles":
827-
raise IncompatibleMetricsQuery(
828-
"Can only have aggregate conditions on one entity"
829-
)
780+
for entity, framework in query_framework.items():
781+
if condition.lhs in framework.functions:
782+
if having_entity is None:
783+
having_entity = entity
784+
elif having_entity != entity:
785+
raise IncompatibleMetricsQuery(
786+
"Can only have aggregate conditions on one entity"
787+
)
788+
break
830789

831790
if primary is not None and having_entity is not None and having_entity != primary:
832791
raise IncompatibleMetricsQuery(
@@ -837,18 +796,13 @@ def _create_query_framework(self) -> Tuple[str, Dict[str, QueryFramework]]:
837796
if primary is None:
838797
if having_entity is not None:
839798
primary = having_entity
840-
elif len(self.counters) > 0:
841-
primary = "counter"
842-
elif len(self.sets) > 0:
843-
primary = "set"
844-
elif len(self.distributions) > 0:
845-
primary = "distribution"
846-
elif len(self.metrics_layer_functions) > 0:
847-
primary = "metrics_layer"
848-
elif len(self.percentiles) > 0:
849-
primary = "percentiles"
850799
else:
851-
raise IncompatibleMetricsQuery("Need at least one function")
800+
for entity, framework in query_framework.items():
801+
if len(framework.functions) > 0:
802+
primary = entity
803+
break
804+
else:
805+
raise IncompatibleMetricsQuery("Need at least one function")
852806

853807
query_framework[primary].having = self.having
854808

0 commit comments

Comments
 (0)