You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by hu...@apache.org on 2022/08/27 02:12:32 UTC

[superset] branch master updated: fix: add back custom sql filtering with Query as source (#21190)

This is an automated email from the ASF dual-hosted git repository.

hugh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new c61a507e14 fix: add back custom sql filtering with Query as source (#21190)
c61a507e14 is described below

commit c61a507e14491b400c8d5155317960a8671ab3e2
Author: Hugh A. Miles II <hu...@gmail.com>
AuthorDate: Fri Aug 26 19:12:21 2022 -0700

    fix: add back custom sql filtering with Query as source (#21190)
---
 .../getControlValuesCompatibleWithDatasource.ts    |  2 ++
 superset/config.py                                 |  2 +-
 superset/db_engine_specs/trino.py                  |  2 +-
 superset/models/helpers.py                         | 31 +++++++++++++---------
 superset/models/sql_lab.py                         |  4 +++
 5 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts b/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts
index e070e82464..346768557c 100644
--- a/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts
+++ b/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts
@@ -23,6 +23,7 @@ import {
   isAdhocMetricSimple,
   isSavedMetric,
   isSimpleAdhocFilter,
+  isFreeFormAdhocFilter,
   JsonValue,
   SimpleAdhocFilter,
 } from '@superset-ui/core';
@@ -70,6 +71,7 @@ const isControlValueCompatibleWithDatasource = (
         column.column_name === (value as SimpleAdhocFilter).subject,
     );
   }
+  if (isFreeFormAdhocFilter(value)) return true;
   return false;
 };
 
diff --git a/superset/config.py b/superset/config.py
index bf5106d0e5..647dc81ea7 100644
--- a/superset/config.py
+++ b/superset/config.py
@@ -211,7 +211,7 @@ SQLALCHEMY_CUSTOM_PASSWORD_STORE = None
 #
 # e.g.:
 #
-# class AesGcmEncryptedAdapter(  # pylint: disable=too-few-public-methods
+# class AesGcmEncryptedAdapter(
 #     AbstractEncryptedFieldAdapter
 # ):
 #     def create(
diff --git a/superset/db_engine_specs/trino.py b/superset/db_engine_specs/trino.py
index 2a23d1c969..9aa89ce34a 100644
--- a/superset/db_engine_specs/trino.py
+++ b/superset/db_engine_specs/trino.py
@@ -35,7 +35,7 @@ if TYPE_CHECKING:
     from superset.models.core import Database
 
     try:
-        from trino.dbapi import Cursor  # pylint: disable=unused-import
+        from trino.dbapi import Cursor
     except ImportError:
         pass
 
diff --git a/superset/models/helpers.py b/superset/models/helpers.py
index a476fa0c81..bc58cee8c6 100644
--- a/superset/models/helpers.py
+++ b/superset/models/helpers.py
@@ -750,6 +750,9 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
     def get_extra_cache_keys(query_obj: Dict[str, Any]) -> List[str]:
         raise NotImplementedError()
 
+    def get_template_processor(self, **kwargs: Any) -> BaseTemplateProcessor:
+        raise NotImplementedError()
+
     def _process_sql_expression(  # pylint: disable=no-self-use
         self,
         expression: Optional[str],
@@ -1291,9 +1294,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
         column: Dict[str, Any],
         time_grain: Optional[str],
         label: Optional[str] = None,
-        template_processor: Optional[  # pylint: disable=unused-argument
-            BaseTemplateProcessor
-        ] = None,
+        template_processor: Optional[BaseTemplateProcessor] = None,
     ) -> Union[TimestampExpression, Label]:
         """
         Return a SQLAlchemy Core element representation of self to be used in a query.
@@ -1307,6 +1308,11 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
         column_spec = self.db_engine_spec.get_column_spec(column.get("type"))
         type_ = column_spec.sqla_type if column_spec else sa.DateTime
         col = sa.column(column.get("column_name"), type_=type_)
+
+        if template_processor:
+            expression = template_processor.process_template(column["column_name"])
+            col = sa.literal_column(expression, type_=type_)
+
         time_expr = self.db_engine_spec.get_timestamp_expr(col, None, time_grain)
         return self.make_sqla_column_compatible(time_expr, label)
 
@@ -1377,7 +1383,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
         applied_template_filters: List[str] = []
         template_kwargs["removed_filters"] = removed_filters
         template_kwargs["applied_filters"] = applied_template_filters
-        template_processor = None  # self.get_template_processor(**template_kwargs)
+        template_processor = self.get_template_processor(**template_kwargs)
         db_engine_spec = self.db_engine_spec
         prequeries: List[str] = []
         orderby = orderby or []
@@ -1487,7 +1493,10 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
                         table_col = columns_by_name[selected]
                         if isinstance(table_col, dict):
                             outer = self.get_timestamp_expression(
-                                table_col, time_grain, selected, template_processor
+                                column=table_col,
+                                time_grain=time_grain,
+                                label=selected,
+                                template_processor=template_processor,
                             )
                         else:
                             outer = table_col.get_timestamp_expression(
@@ -1550,7 +1559,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
             if is_timeseries:
                 if isinstance(dttm_col, dict):
                     timestamp = self.get_timestamp_expression(
-                        dttm_col, time_grain, template_processor
+                        dttm_col, time_grain, template_processor=template_processor
                     )
                 else:
                     timestamp = dttm_col.get_timestamp_expression(
@@ -1639,7 +1648,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
                 elif col_obj and filter_grain:
                     if isinstance(col_obj, dict):
                         sqla_col = self.get_timestamp_expression(
-                            col_obj, time_grain, template_processor
+                            col_obj, time_grain, template_processor=template_processor
                         )
                     else:
                         sqla_col = col_obj.get_timestamp_expression(
@@ -1770,9 +1779,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
             where = extras.get("where")
             if where:
                 try:
-                    where = template_processor.process_template(  # type: ignore
-                        f"({where})"
-                    )
+                    where = template_processor.process_template(f"{where}")
                 except TemplateError as ex:
                     raise QueryObjectValidationError(
                         _(
@@ -1784,9 +1791,7 @@ class ExploreMixin:  # pylint: disable=too-many-public-methods
             having = extras.get("having")
             if having:
                 try:
-                    having = template_processor.process_template(  # type: ignore
-                        f"({having})"
-                    )
+                    having = template_processor.process_template(f"{having}")
                 except TemplateError as ex:
                     raise QueryObjectValidationError(
                         _(
diff --git a/superset/models/sql_lab.py b/superset/models/sql_lab.py
index d0e0470d4b..d12af49081 100644
--- a/superset/models/sql_lab.py
+++ b/superset/models/sql_lab.py
@@ -42,6 +42,7 @@ from sqlalchemy.engine.url import URL
 from sqlalchemy.orm import backref, relationship
 
 from superset import security_manager
+from superset.jinja_context import BaseTemplateProcessor, get_template_processor
 from superset.models.helpers import (
     AuditMixinNullable,
     ExploreMixin,
@@ -126,6 +127,9 @@ class Query(
 
     __table_args__ = (sqla.Index("ti_user_id_changed_on", user_id, changed_on),)
 
+    def get_template_processor(self, **kwargs: Any) -> BaseTemplateProcessor:
+        return get_template_processor(query=self, database=self.database, **kwargs)
+
     def to_dict(self) -> Dict[str, Any]:
         return {
             "changedOn": self.changed_on,