This is an automated email from the ASF dual-hosted git repository. beto pushed a commit to branch semantic-layer-implementation in repository https://gitbox.apache.org/repos/asf/superset.git
commit b437421a8edac1b7845a0bb72501f8e707d56617 Author: Beto Dealmeida <[email protected]> AuthorDate: Thu Dec 11 15:06:13 2025 -0500 Fix filter --- superset/semantic_layers/mapper.py | 65 +++++++++++++++------- .../semantic_layers/snowflake/semantic_view.py | 5 -- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/superset/semantic_layers/mapper.py b/superset/semantic_layers/mapper.py index 5c4896d395..f6bfbeb0fb 100644 --- a/superset/semantic_layers/mapper.py +++ b/superset/semantic_layers/mapper.py @@ -277,6 +277,8 @@ def map_query_object(query_object: ValidatedQueryObject) -> list[SemanticQuery]: This function maps the `QueryObject` into query objects that focus less on visualization and more on semantics. """ + print("BETO") + print(query_object) semantic_view = query_object.datasource.implementation all_metrics = {metric.name: metric for metric in semantic_view.metrics} @@ -321,6 +323,7 @@ def map_query_object(query_object: ValidatedQueryObject) -> list[SemanticQuery]: time_offset, all_dimensions, ) + print(">>", filters) queries.append( SemanticQuery( @@ -373,9 +376,15 @@ def _get_filters_from_query_object( # 4. Add all other filters from query_object.filter for filter_ in query_object.filter: - converted_filter = _convert_query_object_filter(filter_, all_dimensions) - if converted_filter: - filters.add(converted_filter) + # Skip temporal range filters - we're using inner bounds instead + if ( + filter_.get("op") == FilterOperator.TEMPORAL_RANGE.value + and query_object.granularity + ): + continue + + if converted_filters := _convert_query_object_filter(filter_, all_dimensions): + filters.update(converted_filters) return filters @@ -503,17 +512,12 @@ def _get_time_bounds( def _convert_query_object_filter( filter_: ValidatedQueryObjectFilterClause, all_dimensions: dict[str, Dimension], -) -> Filter | AdhocFilter | None: +) -> set[Filter] | None: """ Convert a QueryObject filter dict to a semantic layer Filter or AdhocFilter. """ operator_str = filter_["op"] - # Handle TEMPORAL_RANGE filters (these are already handled by _get_time_filter) - if operator_str == FilterOperator.TEMPORAL_RANGE.value: - # Skip - already handled in _get_time_filter - return None - # Handle simple column filters col = filter_.get("col") if col not in all_dimensions: @@ -530,6 +534,25 @@ def _convert_query_object_filter( else: value = val_str + # Special case for temporal range + if operator_str == FilterOperator.TEMPORAL_RANGE.value: + # XXX + start, end = value.split(" : ") + return { + Filter( + type=PredicateType.WHERE, + column=dimension, + operator=Operator.GREATER_THAN_OR_EQUAL, + value=start, + ), + Filter( + type=PredicateType.WHERE, + column=dimension, + operator=Operator.LESS_THAN, + value=end, + ), + } + # Map QueryObject operators to semantic layer operators operator_mapping = { FilterOperator.EQUALS.value: Operator.EQUALS, @@ -551,12 +574,14 @@ def _convert_query_object_filter( # Unknown operator - create adhoc filter return None - return Filter( - type=PredicateType.WHERE, - column=dimension, - operator=operator, - value=value, - ) + return { + Filter( + type=PredicateType.WHERE, + column=dimension, + operator=operator, + value=value, + ) + } def _get_order_from_query_object( @@ -693,12 +718,14 @@ def _get_group_limit_filters( # Add all other non-temporal filters from query_object.filter for filter_ in query_object.filter: # Skip temporal range filters - we're using inner bounds instead - if filter_.get("op") == FilterOperator.TEMPORAL_RANGE.value: + if ( + filter_.get("op") == FilterOperator.TEMPORAL_RANGE.value + and query_object.granularity + ): continue - converted_filter = _convert_query_object_filter(filter_, all_dimensions) - if converted_filter: - filters.add(converted_filter) + if converted_filters := _convert_query_object_filter(filter_, all_dimensions): + filters.update(converted_filters) return filters if filters else None diff --git a/superset/semantic_layers/snowflake/semantic_view.py b/superset/semantic_layers/snowflake/semantic_view.py index 8ce849af2f..654a9e58ef 100644 --- a/superset/semantic_layers/snowflake/semantic_view.py +++ b/superset/semantic_layers/snowflake/semantic_view.py @@ -305,7 +305,6 @@ class SnowflakeSemanticView(SemanticViewImplementation): """ Execute a query and return the results as a Pandas DataFrame. """ - print("AM HERE") if not metrics and not dimensions: return DataFrame() @@ -327,11 +326,7 @@ class SnowflakeSemanticView(SemanticViewImplementation): **{dimension.id: dimension.name for dimension in dimensions}, **{metric.id: metric.name for metric in metrics}, } - print("BETO") - print(df.columns) - print(mapping) df.rename(columns=mapping, inplace=True) - print(df.columns) return SemanticResult( requests=[
