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 dfc6aad5f07b050b47412496fb3b283f1ec264c4
Author: Beto Dealmeida <[email protected]>
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

Reply via email to