From 760d46af5cca359b575dce439f39fa0ee932657e Mon Sep 17 00:00:00 2001 From: Jacob Beck Date: Wed, 22 Jan 2020 12:24:24 -0700 Subject: [PATCH] when going through the partial parsing, ignore cached nodes that do not match the current parser resource type --- core/dbt/parser/manifest.py | 7 ++++-- core/dbt/parser/results.py | 8 ++++++- .../test_duplicate_model.py | 22 +++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/core/dbt/parser/manifest.py b/core/dbt/parser/manifest.py index fc4fecbe35d..e9abffd2337 100644 --- a/core/dbt/parser/manifest.py +++ b/core/dbt/parser/manifest.py @@ -129,13 +129,14 @@ def parse_with_cache( old_results: Optional[ParseResult], ) -> None: block = self._get_file(path, parser) - if not self._get_cached(block, old_results): + if not self._get_cached(block, old_results, parser): parser.parse_file(block) def _get_cached( self, block: FileBlock, old_results: Optional[ParseResult], + parser: BaseParser, ) -> bool: # TODO: handle multiple parsers w/ same files, by # tracking parser type vs node type? Or tracking actual @@ -143,7 +144,9 @@ def _get_cached( if old_results is None: return False if old_results.has_file(block.file): - return self.results.sanitized_update(block.file, old_results) + return self.results.sanitized_update( + block.file, old_results, parser.resource_type + ) return False def _get_file(self, path: FilePath, parser: BaseParser) -> FileBlock: diff --git a/core/dbt/parser/results.py b/core/dbt/parser/results.py index 8782cacefd0..983edefab68 100644 --- a/core/dbt/parser/results.py +++ b/core/dbt/parser/results.py @@ -14,6 +14,7 @@ raise_duplicate_resource_name, raise_duplicate_patch_name, CompilationException, InternalException ) +from dbt.node_types import NodeType from dbt.version import __version__ @@ -149,7 +150,10 @@ def _process_node( ) def sanitized_update( - self, source_file: SourceFile, old_result: 'ParseResult', + self, + source_file: SourceFile, + old_result: 'ParseResult', + resource_type: NodeType, ) -> bool: """Perform a santized update. If the file can't be updated, invalidate it and return false. @@ -180,6 +184,8 @@ def sanitized_update( # the node ID could be in old_result.disabled AND in old_result.nodes. # In that case, we have to make sure the path also matches. for node_id in old_file.nodes: + if old_result.nodes[node_id].resource_type != resource_type: + continue self._process_node(node_id, source_file, old_file, old_result) for name in old_file.patches: diff --git a/test/integration/025_duplicate_model_test/test_duplicate_model.py b/test/integration/025_duplicate_model_test/test_duplicate_model.py index ff1981ca1a8..a000973f7d5 100644 --- a/test/integration/025_duplicate_model_test/test_duplicate_model.py +++ b/test/integration/025_duplicate_model_test/test_duplicate_model.py @@ -167,3 +167,25 @@ def test_postgres_duplicate_model_disabled_across_packages(self): .format(schema=self.unique_schema()) result = self.run_sql(query, fetch="one")[0] assert result == 1 + + +class TestModelTestOverlap(DBTIntegrationTest): + + @property + def schema(self): + return "duplicate_model_025" + + @property + def models(self): + return "models-3" + + @property + def project_config(self): + return {'test-paths': [self.models]} + + @use_profile('postgres') + def test_postgres_duplicate_test_model_paths(self): + # this should be ok: test/model overlap is fine + self.run_dbt(['compile']) + self.run_dbt(['--partial-parse', 'compile']) + self.run_dbt(['--partial-parse', 'compile'])