diff --git a/dbt_semantic_interfaces/implementations/saved_query.py b/dbt_semantic_interfaces/implementations/saved_query.py index 0c6da416..a45c7c74 100644 --- a/dbt_semantic_interfaces/implementations/saved_query.py +++ b/dbt_semantic_interfaces/implementations/saved_query.py @@ -48,3 +48,4 @@ def _implements_protocol(self) -> SavedQuery: metadata: Optional[PydanticMetadata] = None label: Optional[str] = None exports: List[PydanticExport] = Field(default_factory=list) + tags: List[str] = Field(default_factory=list) 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 613bffd7..be0d6234 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 @@ -703,6 +703,19 @@ }, "query_params": { "$ref": "#/definitions/saved_query_query_params_schema" + }, + "tags": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] } }, "required": [ diff --git a/dbt_semantic_interfaces/parsing/schemas.py b/dbt_semantic_interfaces/parsing/schemas.py index 66652535..4316d26f 100644 --- a/dbt_semantic_interfaces/parsing/schemas.py +++ b/dbt_semantic_interfaces/parsing/schemas.py @@ -458,6 +458,15 @@ "query_params": {"$ref": "saved_query_query_params_schema"}, "label": {"type": "string"}, "exports": {"type": "array", "items": {"$ref": "export_schema"}}, + "tags": { + "oneOf": [ + {"type": "string"}, + { + "type": "array", + "items": {"type": "string"}, + }, + ], + }, }, "required": ["name", "query_params"], "additionalProperties": False, diff --git a/dbt_semantic_interfaces/protocols/saved_query.py b/dbt_semantic_interfaces/protocols/saved_query.py index 6f02866e..a8e33ce7 100644 --- a/dbt_semantic_interfaces/protocols/saved_query.py +++ b/dbt_semantic_interfaces/protocols/saved_query.py @@ -73,3 +73,9 @@ def label(self) -> Optional[str]: def exports(self) -> Sequence[Export]: """Exports that can run using this saved query.""" pass + + @property + @abstractmethod + def tags(self) -> Sequence[str]: + """List of tags to be used as part of resource selection in dbt.""" + pass diff --git a/tests/parsing/test_saved_query_parsing.py b/tests/parsing/test_saved_query_parsing.py index 20b8f4b3..1c298cc2 100644 --- a/tests/parsing/test_saved_query_parsing.py +++ b/tests/parsing/test_saved_query_parsing.py @@ -99,6 +99,9 @@ def test_saved_query_group_by() -> None: """\ saved_query: name: test_saved_query_group_bys + tags: + - "tag_1" + - "tag_2" query_params: metrics: - test_metric_a @@ -144,6 +147,50 @@ def test_saved_query_where() -> None: assert where == saved_query.query_params.where.where_filters[0].where_sql_template +def test_saved_query_tags() -> None: + """Test for parsing tags in a saved query.""" + yaml_contents = textwrap.dedent( + """\ + saved_query: + name: test_saved_query_group_bys + tags: + - "tag_1" + - "tag_2" + query_params: + metrics: + - test_metric_a + """ + ) + file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents) + + build_result = parse_yaml_files_to_semantic_manifest(files=[file, EXAMPLE_PROJECT_CONFIGURATION_YAML_CONFIG_FILE]) + assert len(build_result.semantic_manifest.saved_queries) == 1 + saved_query = build_result.semantic_manifest.saved_queries[0] + assert saved_query.tags is not None + assert len(saved_query.tags) == 2 + assert saved_query.tags == ["tag_1", "tag_2"] + + +def test_saved_query_with_no_tags_defaults_to_empty_list() -> None: + """Test for parsing tags in a saved query.""" + yaml_contents = textwrap.dedent( + """\ + saved_query: + name: test_saved_query_group_bys + query_params: + metrics: + - test_metric_a + """ + ) + file = YamlConfigFile(filepath="test_dir/inline_for_test", contents=yaml_contents) + + build_result = parse_yaml_files_to_semantic_manifest(files=[file, EXAMPLE_PROJECT_CONFIGURATION_YAML_CONFIG_FILE]) + assert len(build_result.semantic_manifest.saved_queries) == 1 + saved_query = build_result.semantic_manifest.saved_queries[0] + assert saved_query.tags is not None + assert saved_query.tags == [] + + def test_saved_query_exports() -> None: """Test for parsing exports referenced in a saved query.""" yaml_contents = textwrap.dedent(