Skip to content

Commit

Permalink
Update WhereFilterParser to use QueryItemTextProcessor.
Browse files Browse the repository at this point in the history
  • Loading branch information
plypaul committed Aug 1, 2024
1 parent 8bb530f commit 0aff0b9
Showing 1 changed file with 63 additions and 34 deletions.
97 changes: 63 additions & 34 deletions dbt_semantic_interfaces/parsing/where_filter/where_filter_parser.py
Original file line number Diff line number Diff line change
@@ -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,
)


Expand All @@ -29,42 +26,74 @@ 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

"""
Dimensions that are created with a grain or date_part parameter, for instance Dimension(...).grain(...), are
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),
)

0 comments on commit 0aff0b9

Please sign in to comment.