diff --git a/.changes/unreleased/Features-20230926-182305.yaml b/.changes/unreleased/Features-20230926-182305.yaml new file mode 100644 index 00000000..83658d22 --- /dev/null +++ b/.changes/unreleased/Features-20230926-182305.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Add options to protocol for null value coalescing +time: 2023-09-26T18:23:05.191433-07:00 +custom: + Author: QMalcolm + Issue: "142" diff --git a/dbt_semantic_interfaces/implementations/metric.py b/dbt_semantic_interfaces/implementations/metric.py index edfa174d..014e1e09 100644 --- a/dbt_semantic_interfaces/implementations/metric.py +++ b/dbt_semantic_interfaces/implementations/metric.py @@ -30,6 +30,8 @@ class PydanticMetricInputMeasure(PydanticCustomInputParser, HashableBaseModel): name: str filter: Optional[PydanticWhereFilter] alias: Optional[str] + join_to_timespine: bool = False + fill_nulls_with: Optional[int] = None @classmethod def _from_yaml_value(cls, input: PydanticParseableValueType) -> PydanticMetricInputMeasure: diff --git a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json index ebc1bf4d..d8d469a1 100644 --- a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json +++ b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json @@ -221,9 +221,15 @@ "alias": { "type": "string" }, + "fill_nulls_with": { + "type": "integer" + }, "filter": { "type": "string" }, + "join_to_timespine": { + "type": "boolean" + }, "name": { "type": "string" } diff --git a/dbt_semantic_interfaces/parsing/schemas.py b/dbt_semantic_interfaces/parsing/schemas.py index efbc7914..7c150136 100644 --- a/dbt_semantic_interfaces/parsing/schemas.py +++ b/dbt_semantic_interfaces/parsing/schemas.py @@ -46,6 +46,8 @@ "name": {"type": "string"}, "filter": {"type": "string"}, "alias": {"type": "string"}, + "join_to_timespine": {"type": "boolean"}, + "fill_nulls_with": {"type": "integer"}, }, "additionalProperties": False, }, diff --git a/dbt_semantic_interfaces/protocols/metric.py b/dbt_semantic_interfaces/protocols/metric.py index 5895ad9a..e9eab48a 100644 --- a/dbt_semantic_interfaces/protocols/metric.py +++ b/dbt_semantic_interfaces/protocols/metric.py @@ -43,6 +43,18 @@ def post_aggregation_measure_reference(self) -> MeasureReference: """Property accessor to get the MeasureReference with the aliased name, if appropriate.""" ... + @property + @abstractmethod + def join_to_timespine(self) -> bool: + """If the measure should be joined to the timespine.""" + pass + + @property + @abstractmethod + def fill_nulls_with(self) -> Optional[int]: + """What null values should be filled with if set.""" + pass + class MetricTimeWindow(Protocol): """Describes the window of time the metric should be accumulated over, e.g., '1 day', '2 weeks', etc.""" diff --git a/tests/parsing/test_metric_parsing.py b/tests/parsing/test_metric_parsing.py index 71aec839..51362bfa 100644 --- a/tests/parsing/test_metric_parsing.py +++ b/tests/parsing/test_metric_parsing.py @@ -54,6 +54,8 @@ def test_legacy_metric_input_measure_object_parsing() -> None: measure: name: legacy_measure_from_object filter: "{{ dimension('some_bool') }}" + join_to_timespine: true + fill_nulls_with: 1 """ ) file = YamlConfigFile(filepath="inline_for_test", contents=yaml_contents) @@ -65,6 +67,8 @@ def test_legacy_metric_input_measure_object_parsing() -> None: assert metric.type_params.measure == PydanticMetricInputMeasure( name="legacy_measure_from_object", filter=PydanticWhereFilter(where_sql_template="""{{ dimension('some_bool') }}"""), + join_to_timespine=True, + fill_nulls_with=1, )