You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/10/20 01:09:46 UTC
(superset) 01/03: Working on GroupFilter
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch explorable
in repository https://gitbox.apache.org/repos/asf/superset.git
commit b232a7fd96bfa2d3c742b7ed8c177166efef7608
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Fri Oct 17 14:38:31 2025 -0400
Working on GroupFilter
---
superset/semantic_layers/snowflake_.py | 56 ++++++++++++++++++++++++++++++++--
superset/semantic_layers/types.py | 18 +++++++++++
2 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/superset/semantic_layers/snowflake_.py b/superset/semantic_layers/snowflake_.py
index c86305934e..15eb8c1048 100644
--- a/superset/semantic_layers/snowflake_.py
+++ b/superset/semantic_layers/snowflake_.py
@@ -47,12 +47,14 @@ from superset.semantic_layers.types import (
Dimension,
Filter,
FilterValues,
+ GroupLimit,
INTEGER,
Metric,
NativeFilter,
NUMBER,
OBJECT,
Operator,
+ OrderDirection,
PredicateType,
STRING,
TIME,
@@ -608,8 +610,11 @@ class SnowflakeExplorable:
metrics: list[Metric],
dimensions: list[Dimension],
filters: set[Filter | NativeFilter] | None = None,
+ order: list[tuple[Metric | Dimension, OrderDirection]] | None = None,
limit: int | None = None,
offset: int | None = None,
+ *,
+ group_limit: GroupLimit | None = None,
) -> DataFrame:
"""
Execute a query and return the results as a Pandas DataFrame.
@@ -617,18 +622,60 @@ class SnowflakeExplorable:
if not metrics and not dimensions:
return DataFrame()
- query, parameters = self._get_query(metrics, dimensions, filters, limit, offset)
+ query, parameters = self._get_query(
+ metrics,
+ dimensions,
+ filters,
+ order,
+ limit,
+ offset,
+ group_limit,
+ )
connection_parameters = get_connection_parameters(self.configuration)
with connect(**connection_parameters) as connection:
return connection.cursor().execute(query, parameters).fetch_pandas_all()
+ def get_row_count(
+ self,
+ metrics: list[Metric],
+ dimensions: list[Dimension],
+ filters: set[Filter | NativeFilter] | None = None,
+ order: list[tuple[Metric | Dimension, OrderDirection]] | None = None,
+ limit: int | None = None,
+ offset: int | None = None,
+ *,
+ group_limit: GroupLimit | None = None,
+ ) -> int:
+ """
+ Execute a query and return the number of rows the result would have.
+ """
+ if not metrics and not dimensions:
+ return 0
+
+ query, parameters = self._get_query(
+ metrics,
+ dimensions,
+ filters,
+ order,
+ limit,
+ offset,
+ group_limit,
+ )
+ query = f"SELECT COUNT(*) FROM ({query}) AS subquery" # noqa: S608
+ connection_parameters = get_connection_parameters(self.configuration)
+ with connect(**connection_parameters) as connection:
+ return connection.cursor().execute(query, parameters).fechone()[0]
+
def _get_query(
self,
metrics: list[Metric],
dimensions: list[Dimension],
filters: set[Filter | NativeFilter] | None = None,
+ order: list[tuple[Metric | Dimension, OrderDirection]] | None = None,
limit: int | None = None,
offset: int | None = None,
+ *,
+ group_limit: GroupLimit | None = None,
) -> tuple[str, tuple[FilterValues]]:
"""
Build a query to fetch data from the explorable.
@@ -653,6 +700,9 @@ class SnowflakeExplorable:
having_clause, having_parameters = self._build_predicates(
{filter_ for filter_ in filters if filter_.type == PredicateType.HAVING}
)
+ order_clause = ", ".join(
+ f"{element.id} {direction.value}" for element, direction in (order or [])
+ )
query = dedent(
f"""
@@ -663,13 +713,13 @@ class SnowflakeExplorable:
{"WHERE " + where_clause if where_clause else ""}
)
{"HAVING " + having_clause if having_clause else ""}
+ {"ORDER BY " + order_clause if order_clause else ""}
{"LIMIT " + str(limit) if limit is not None else ""}
{"OFFSET " + str(offset) if offset is not None else ""}
""" # noqa: S608
)
- parameters = where_parameters + having_parameters
- return query, parameters
+ return query, where_parameters + having_parameters
__repr__ = uid
diff --git a/superset/semantic_layers/types.py b/superset/semantic_layers/types.py
index 048fbb6ab3..c43d46b691 100644
--- a/superset/semantic_layers/types.py
+++ b/superset/semantic_layers/types.py
@@ -198,3 +198,21 @@ class Filter:
class NativeFilter:
type: PredicateType
definition: str
+
+
+class OrderDirection(enum.Enum):
+ ASC = "ASC"
+ DESC = "DESC"
+
+
+@dataclass(frozen=True)
+class GroupLimit:
+ """
+ Limit query to top/bottom N combinations of specified dimensions.
+ """
+
+ dimensions: list[Dimension]
+ top: int
+ metric: Metric | None
+ direction: OrderDirection = OrderDirection.DESC
+ group_others: bool = False