diff --git a/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts b/superset-frontend/src/explore/controlUtils/getControlValuesCompatibleWithDatasource.ts index e070e82464d..346768557c9 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 bf5106d0e51..647dc81ea78 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 2a23d1c9695..9aa89ce34a0 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 a476fa0c810..bc58cee8c6c 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 d0e0470d4b1..d12af490818 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,