diff --git a/dbt_semantic_interfaces/parsing/where_filter/where_filter_parser.py b/dbt_semantic_interfaces/parsing/where_filter/where_filter_parser.py index df81590d..9cc40ecb 100644 --- a/dbt_semantic_interfaces/parsing/where_filter/where_filter_parser.py +++ b/dbt_semantic_interfaces/parsing/where_filter/where_filter_parser.py @@ -1,25 +1,22 @@ from __future__ import annotations -from jinja2 import StrictUndefined -from jinja2.exceptions import SecurityError, TemplateSyntaxError, UndefinedError -from jinja2.sandbox import SandboxedEnvironment - from dbt_semantic_interfaces.call_parameter_sets import ( FilterCallParameterSets, ParseWhereFilterException, ) -from dbt_semantic_interfaces.parsing.where_filter.parameter_set_factory import ( - ParameterSetFactory, +from dbt_semantic_interfaces.enum_extension import assert_values_exhausted +from dbt_semantic_interfaces.parsing.text_input.ti_description import QueryItemType +from dbt_semantic_interfaces.parsing.text_input.ti_exceptions import ( + QueryItemJinjaException, ) -from dbt_semantic_interfaces.parsing.where_filter.where_filter_dimension import ( - WhereFilterDimensionFactory, +from dbt_semantic_interfaces.parsing.text_input.ti_processor import ( + QueryItemTextProcessor, ) -from dbt_semantic_interfaces.parsing.where_filter.where_filter_entity import ( - WhereFilterEntityFactory, - WhereFilterMetricFactory, +from dbt_semantic_interfaces.parsing.text_input.valid_method import ( + ConfiguredValidMethodMapping, ) -from dbt_semantic_interfaces.parsing.where_filter.where_filter_time_dimension import ( - WhereFilterTimeDimensionFactory, +from dbt_semantic_interfaces.parsing.where_filter.parameter_set_factory import ( + ParameterSetFactory, ) @@ -29,20 +26,14 @@ class WhereFilterParser: @staticmethod def parse_call_parameter_sets(where_sql_template: str) -> FilterCallParameterSets: """Return the result of extracting the semantic objects referenced in the where SQL template string.""" - time_dimension_factory = WhereFilterTimeDimensionFactory() - dimension_factory = WhereFilterDimensionFactory() - entity_factory = WhereFilterEntityFactory() - metric_factory = WhereFilterMetricFactory() + text_processor = QueryItemTextProcessor() try: - # the string that the sandbox renders is unused - SandboxedEnvironment(undefined=StrictUndefined).from_string(where_sql_template).render( - Dimension=dimension_factory.create, - TimeDimension=time_dimension_factory.create, - Entity=entity_factory.create, - Metric=metric_factory.create, + descriptions = text_processor.collect_descriptions_from_template( + jinja_template=where_sql_template, + valid_method_mapping=ConfiguredValidMethodMapping.DEFAULT_MAPPING, ) - except (UndefinedError, TemplateSyntaxError, SecurityError) as e: + except QueryItemJinjaException as e: raise ParseWhereFilterException(f"Error while parsing Jinja template:\n{where_sql_template}") from e """ @@ -50,21 +41,59 @@ def parse_call_parameter_sets(where_sql_template: str) -> FilterCallParameterSet added to time_dimension_call_parameter_sets otherwise they are add to dimension_call_parameter_sets """ dimension_call_parameter_sets = [] - for dimension in dimension_factory.created: - if dimension.time_granularity_name or dimension.date_part_name: - time_dimension_factory.time_dimension_call_parameter_sets.append( + time_dimension_call_parameter_sets = [] + entity_call_parameter_sets = [] + metric_call_parameter_sets = [] + + for description in descriptions: + item_type = description.item_type + + if item_type is QueryItemType.DIMENSION: + if description.time_granularity_name or description.date_part_name: + time_dimension_call_parameter_sets.append( + ParameterSetFactory.create_time_dimension( + time_dimension_name=description.item_name, + time_granularity_name=description.time_granularity_name, + entity_path=description.entity_path, + date_part_name=description.date_part_name, + ) + ) + else: + dimension_call_parameter_sets.append( + ParameterSetFactory.create_dimension( + dimension_name=description.item_name, + entity_path=description.entity_path, + ) + ) + elif item_type is QueryItemType.TIME_DIMENSION: + time_dimension_call_parameter_sets.append( ParameterSetFactory.create_time_dimension( - dimension.name, dimension.time_granularity_name, dimension.entity_path, dimension.date_part_name + time_dimension_name=description.item_name, + time_granularity_name=description.time_granularity_name, + entity_path=description.entity_path, + date_part_name=description.date_part_name, ) ) - else: - dimension_call_parameter_sets.append( - ParameterSetFactory.create_dimension(dimension.name, dimension.entity_path) + elif item_type is QueryItemType.ENTITY: + entity_call_parameter_sets.append( + ParameterSetFactory.create_entity( + entity_name=description.item_name, + entity_path=description.entity_path, + ) ) + elif item_type is QueryItemType.METRIC: + metric_call_parameter_sets.append( + ParameterSetFactory.create_metric( + metric_name=description.item_name, + group_by=description.group_by_for_metric_item, + ) + ) + else: + assert_values_exhausted(item_type) return FilterCallParameterSets( dimension_call_parameter_sets=tuple(dimension_call_parameter_sets), - time_dimension_call_parameter_sets=tuple(time_dimension_factory.time_dimension_call_parameter_sets), - entity_call_parameter_sets=tuple(entity_factory.entity_call_parameter_sets), - metric_call_parameter_sets=tuple(metric_factory.metric_call_parameter_sets), + time_dimension_call_parameter_sets=tuple(time_dimension_call_parameter_sets), + entity_call_parameter_sets=tuple(entity_call_parameter_sets), + metric_call_parameter_sets=tuple(metric_call_parameter_sets), )