Skip to content

Commit

Permalink
Expand partial parsing tests; fix macro partial parsing [#3449]
Browse files Browse the repository at this point in the history
  • Loading branch information
gshank committed Jun 29, 2021
1 parent bfe8f0a commit f3d2a81
Show file tree
Hide file tree
Showing 18 changed files with 354 additions and 100 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- Dispatch the core SQL statement of the new test materialization, to benefit adapter maintainers ([#3465](https://github.com/fishtown-analytics/dbt/pull/3465), [#3461](https://github.com/fishtown-analytics/dbt/pull/3461))
- Minimal validation of yaml dictionaries prior to partial parsing ([#3246](https://github.com/fishtown-analytics/dbt/issues/3246), [#3460](https://github.com/fishtown-analytics/dbt/pull/3460))
- Add partial parsing tests and improve partial parsing handling of macros ([#3449](https://github.com/fishtown-analytics/dbt/issues/3449), [#3505](https://github.com/fishtown-analytics/dbt/pull/3505))

Contributors:
- [@swanderz](https://github.com/swanderz) ([#3461](https://github.com/fishtown-analytics/dbt/pull/3461))
Expand Down
41 changes: 40 additions & 1 deletion core/dbt/contracts/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def remote(cls, contents: str, project_name: str) -> 'SourceFile':
class SchemaSourceFile(BaseSourceFile):
dfy: Dict[str, Any] = field(default_factory=dict)
# these are in the manifest.nodes dictionary
tests: List[str] = field(default_factory=list)
tests: Dict[str, Any] = field(default_factory=dict)
sources: List[str] = field(default_factory=list)
exposures: List[str] = field(default_factory=list)
# node patches contain models, seeds, snapshots, analyses
Expand Down Expand Up @@ -255,5 +255,44 @@ def __post_serialize__(self, dct):
def append_patch(self, yaml_key, unique_id):
self.node_patches.append(unique_id)

def add_test(self, node_unique_id, test_from):
name = test_from['name']
key = test_from['key']
if key not in self.tests:
self.tests[key] = {}
if name not in self.tests[key]:
self.tests[key][name] = []
self.tests[key][name].append(node_unique_id)

def remove_tests(self, yaml_key, name):
if yaml_key in self.tests:
if name in self.tests[yaml_key]:
del self.tests[yaml_key][name]

def get_tests(self, yaml_key, name):
if yaml_key in self.tests:
if name in self.tests[yaml_key]:
return self.tests[yaml_key][name]
return []

def get_key_and_name_for_test(self, test_unique_id):
yaml_key = None
block_name = None
for key in self.tests.keys():
for name in self.tests[key]:
for unique_id in self.tests[key][name]:
if unique_id == test_unique_id:
yaml_key = key
block_name = name
break
return (yaml_key, block_name)

def get_all_test_ids(self):
test_ids = []
for key in self.tests.keys():
for name in self.tests[key]:
test_ids.extend(self.tests[key][name])
return test_ids


AnySourceFile = Union[SchemaSourceFile, SourceFile]
34 changes: 28 additions & 6 deletions core/dbt/contracts/graph/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def _sort_values(dct):
return {k: sorted(v) for k, v in dct.items()}


def build_edges(nodes: List[ManifestNode]):
def build_node_edges(nodes: List[ManifestNode]):
"""Build the forward and backward edges on the given list of ParsedNodes
and return them as two separate dictionaries, each mapping unique IDs to
lists of edges.
Expand All @@ -259,6 +259,18 @@ def build_edges(nodes: List[ManifestNode]):
return _sort_values(forward_edges), _sort_values(backward_edges)


# Build a map of children of macros
def build_macro_edges(nodes: List[Any]):
forward_edges: Dict[str, List[str]] = {
n.unique_id: [] for n in nodes if n.unique_id.startswith('macro') or n.depends_on.macros
}
for node in nodes:
for unique_id in node.depends_on.macros:
if unique_id in forward_edges.keys():
forward_edges[unique_id].append(node.unique_id)
return _sort_values(forward_edges)


def _deepcopy(value):
return value.from_dict(value.to_dict(omit_none=True))

Expand Down Expand Up @@ -784,10 +796,18 @@ def build_parent_and_child_maps(self):
self.sources.values(),
self.exposures.values(),
))
forward_edges, backward_edges = build_edges(edge_members)
forward_edges, backward_edges = build_node_edges(edge_members)
self.child_map = forward_edges
self.parent_map = backward_edges

def build_macro_child_map(self):
edge_members = list(chain(
self.nodes.values(),
self.macros.values(),
))
forward_edges = build_macro_edges(edge_members)
return forward_edges

def writable_manifest(self):
self.build_parent_and_child_maps()
return WritableManifest(
Expand Down Expand Up @@ -1021,10 +1041,11 @@ def add_node_nofile(self, node: ManifestNodes):
_check_duplicates(node, self.nodes)
self.nodes[node.unique_id] = node

def add_node(self, source_file: AnySourceFile, node: ManifestNodes):
def add_node(self, source_file: AnySourceFile, node: ManifestNodes, test_from=None):
self.add_node_nofile(node)
if isinstance(source_file, SchemaSourceFile):
source_file.tests.append(node.unique_id)
assert test_from
source_file.add_test(node.unique_id, test_from)
else:
source_file.nodes.append(node.unique_id)

Expand All @@ -1039,10 +1060,11 @@ def add_disabled_nofile(self, node: CompileResultNode):
else:
self._disabled[node.unique_id] = [node]

def add_disabled(self, source_file: AnySourceFile, node: CompileResultNode):
def add_disabled(self, source_file: AnySourceFile, node: CompileResultNode, test_from=None):
self.add_disabled_nofile(node)
if isinstance(source_file, SchemaSourceFile):
source_file.tests.append(node.unique_id)
assert test_from
source_file.add_test(node.unique_id, test_from)
else:
source_file.nodes.append(node.unique_id)

Expand Down
Loading

0 comments on commit f3d2a81

Please sign in to comment.