From e2107883399a4b9f89a1215bd4d0db9a8cfcfb34 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 1 Aug 2024 19:32:15 -0700 Subject: [PATCH] /* PR_START p--sq-order-by-limit 03 */ Add validation for the limit in a saved query. --- .../validations/saved_query.py | 23 ++++++ tests/validations/test_saved_query_limit.py | 76 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 tests/validations/test_saved_query_limit.py diff --git a/dbt_semantic_interfaces/validations/saved_query.py b/dbt_semantic_interfaces/validations/saved_query.py index 4dd24473..bc978341 100644 --- a/dbt_semantic_interfaces/validations/saved_query.py +++ b/dbt_semantic_interfaces/validations/saved_query.py @@ -246,6 +246,28 @@ def _check_order_by(saved_query: SavedQuery) -> Sequence[ValidationIssue]: return validation_issues + @staticmethod + @validate_safely("Validate the order-by field in a saved query.") + def _check_limit(saved_query: SavedQuery) -> Sequence[ValidationIssue]: + validation_issues: List[ValidationIssue] = [] + limit = saved_query.query_params.limit + if limit is None: + return validation_issues + + if limit < 0: + validation_issues.append( + ValidationError( + message=f"Invalid limit value: {limit} (should be >= 0)", + context=SavedQueryContext( + file_context=FileContext.from_metadata(metadata=saved_query.metadata), + element_type=SavedQueryElementType.LIMIT, + element_value=str(limit), + ), + ) + ) + + return validation_issues + @staticmethod @validate_safely("Validate all saved queries in a semantic manifest.") def validate_manifest(semantic_manifest: SemanticManifestT) -> Sequence[ValidationIssue]: # noqa: D @@ -269,6 +291,7 @@ def validate_manifest(semantic_manifest: SemanticManifestT) -> Sequence[Validati ) issues += SavedQueryRule._check_where(saved_query) issues += SavedQueryRule._check_order_by(saved_query) + issues += SavedQueryRule._check_limit(saved_query) return issues diff --git a/tests/validations/test_saved_query_limit.py b/tests/validations/test_saved_query_limit.py new file mode 100644 index 00000000..0064462b --- /dev/null +++ b/tests/validations/test_saved_query_limit.py @@ -0,0 +1,76 @@ +import copy + +from dbt_semantic_interfaces.implementations.saved_query import ( + PydanticSavedQuery, + PydanticSavedQueryQueryParams, +) +from dbt_semantic_interfaces.implementations.semantic_manifest import ( + PydanticSemanticManifest, +) +from dbt_semantic_interfaces.validations.saved_query import SavedQueryRule +from dbt_semantic_interfaces.validations.semantic_manifest_validator import ( + SemanticManifestValidator, +) +from tests.validations.test_saved_query import check_only_one_error_with_message + + +def test_invalid_limit( # noqa: D + simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest, +) -> None: + manifest = copy.deepcopy(simple_semantic_manifest__with_primary_transforms) + manifest.saved_queries = [ + PydanticSavedQuery( + name="Example Saved Query", + description="Example description.", + query_params=PydanticSavedQueryQueryParams( + metrics=["listings"], + limit=-1, + ), + ), + ] + + manifest_validator = SemanticManifestValidator[PydanticSemanticManifest]([SavedQueryRule()]) + check_only_one_error_with_message( + manifest_validator.validate_semantic_manifest(manifest), + "Invalid limit value", + ) + + +def test_valid_limit( # noqa: D + simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest, +) -> None: + manifest = copy.deepcopy(simple_semantic_manifest__with_primary_transforms) + manifest.saved_queries = [ + PydanticSavedQuery( + name="Example Saved Query", + description="Example description.", + query_params=PydanticSavedQueryQueryParams( + metrics=["listings"], + limit=1, + ), + ), + ] + + manifest_validator = SemanticManifestValidator[PydanticSemanticManifest]([SavedQueryRule()]) + results = manifest_validator.validate_semantic_manifest(manifest) + assert results.all_issues == () + + +def test_zero_limit( # noqa: D + simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest, +) -> None: + manifest = copy.deepcopy(simple_semantic_manifest__with_primary_transforms) + manifest.saved_queries = [ + PydanticSavedQuery( + name="Example Saved Query", + description="Example description.", + query_params=PydanticSavedQueryQueryParams( + metrics=["listings"], + limit=0, + ), + ), + ] + + manifest_validator = SemanticManifestValidator[PydanticSemanticManifest]([SavedQueryRule()]) + results = manifest_validator.validate_semantic_manifest(manifest) + assert results.all_issues == ()