Skip to content

Commit

Permalink
Merge branch 'main' into ct-1284
Browse files Browse the repository at this point in the history
  • Loading branch information
aranke authored Dec 13, 2022
2 parents 51b4312 + fafd5ed commit b54fe08
Show file tree
Hide file tree
Showing 28 changed files with 1,508 additions and 3,493 deletions.
7 changes: 7 additions & 0 deletions .changes/unreleased/Under the Hood-20221211-214240.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Under the Hood
body: Refactor and clean up manifest nodes
time: 2022-12-11T21:42:40.560074-05:00
custom:
Author: gshank
Issue: "6426"
PR: "6427"
15 changes: 9 additions & 6 deletions core/dbt/adapters/base/relation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from collections.abc import Hashable
from dataclasses import dataclass, field
from typing import Optional, TypeVar, Any, Type, Dict, Union, Iterator, Tuple, Set
from typing import Optional, TypeVar, Any, Type, Dict, Iterator, Tuple, Set

from dbt.contracts.graph.nodes import SourceDefinition, ParsedNode
from dbt.contracts.graph.nodes import SourceDefinition, ManifestNode, ResultNode, ParsedNode
from dbt.contracts.relation import (
RelationType,
ComponentName,
Expand Down Expand Up @@ -210,7 +210,7 @@ def add_ephemeral_prefix(name: str):
def create_ephemeral_from_node(
cls: Type[Self],
config: HasQuoting,
node: ParsedNode,
node: ManifestNode,
) -> Self:
# Note that ephemeral models are based on the name.
identifier = cls.add_ephemeral_prefix(node.name)
Expand All @@ -223,7 +223,7 @@ def create_ephemeral_from_node(
def create_from_node(
cls: Type[Self],
config: HasQuoting,
node: ParsedNode,
node: ManifestNode,
quote_policy: Optional[Dict[str, bool]] = None,
**kwargs: Any,
) -> Self:
Expand All @@ -244,7 +244,7 @@ def create_from_node(
def create_from(
cls: Type[Self],
config: HasQuoting,
node: Union[ParsedNode, SourceDefinition],
node: ResultNode,
**kwargs: Any,
) -> Self:
if node.resource_type == NodeType.Source:
Expand All @@ -254,8 +254,11 @@ def create_from(
)
return cls.create_from_source(node, **kwargs)
else:
# Can't use ManifestNode here because of parameterized generics
if not isinstance(node, (ParsedNode)):
raise InternalException(f"type mismatch, expected ParsedNode but got {type(node)}")
raise InternalException(
f"type mismatch, expected ManifestNode but got {type(node)}"
)
return cls.create_from_node(config, node, **kwargs)

@classmethod
Expand Down
9 changes: 2 additions & 7 deletions core/dbt/adapters/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
Generic,
TypeVar,
Tuple,
Union,
Dict,
Any,
)
Expand All @@ -17,7 +16,7 @@
import agate

from dbt.contracts.connection import Connection, AdapterRequiredConfig, AdapterResponse
from dbt.contracts.graph.nodes import ParsedNode, SourceDefinition, ManifestNode
from dbt.contracts.graph.nodes import ResultNode, ManifestNode
from dbt.contracts.graph.model_config import BaseConfig
from dbt.contracts.graph.manifest import Manifest
from dbt.contracts.relation import Policy, HasQuoting
Expand Down Expand Up @@ -47,11 +46,7 @@ def get_default_quote_policy(cls) -> Policy:
...

@classmethod
def create_from(
cls: Type[Self],
config: HasQuoting,
node: Union[ParsedNode, SourceDefinition],
) -> Self:
def create_from(cls: Type[Self], config: HasQuoting, node: ResultNode) -> Self:
...


Expand Down
40 changes: 18 additions & 22 deletions core/dbt/compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
from dbt.context.providers import generate_runtime_model_context
from dbt.contracts.graph.manifest import Manifest, UniqueID
from dbt.contracts.graph.nodes import (
ParsedNode,
ManifestNode,
ManifestSQLNode,
GenericTestNode,
GraphMemberNode,
InjectedCTE,
SeedNode,
)
from dbt.exceptions import (
dependency_not_found,
Expand Down Expand Up @@ -167,7 +168,7 @@ def initialize(self):
# a dict for jinja rendering of SQL
def _create_node_context(
self,
node: ManifestNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Dict[str, Any],
) -> Dict[str, Any]:
Expand All @@ -186,14 +187,6 @@ def add_ephemeral_prefix(self, name: str):
relation_cls = adapter.Relation
return relation_cls.add_ephemeral_prefix(name)

def _get_relation_name(self, node: ParsedNode):
relation_name = None
if node.is_relational and not node.is_ephemeral_model:
adapter = get_adapter(self.config)
relation_cls = adapter.Relation
relation_name = str(relation_cls.create_from(self.config, node))
return relation_name

def _inject_ctes_into_sql(self, sql: str, ctes: List[InjectedCTE]) -> str:
"""
`ctes` is a list of InjectedCTEs like:
Expand Down Expand Up @@ -252,10 +245,10 @@ def _inject_ctes_into_sql(self, sql: str, ctes: List[InjectedCTE]) -> str:

def _recursively_prepend_ctes(
self,
model: ManifestNode,
model: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]],
) -> Tuple[ManifestNode, List[InjectedCTE]]:
) -> Tuple[ManifestSQLNode, List[InjectedCTE]]:
"""This method is called by the 'compile_node' method. Starting
from the node that it is passed in, it will recursively call
itself using the 'extra_ctes'. The 'ephemeral' models do
Expand All @@ -270,7 +263,8 @@ def _recursively_prepend_ctes(

# Just to make it plain that nothing is actually injected for this case
if not model.extra_ctes:
model.extra_ctes_injected = True
if not isinstance(model, SeedNode):
model.extra_ctes_injected = True
manifest.update_node(model)
return (model, model.extra_ctes)

Expand All @@ -289,6 +283,7 @@ def _recursively_prepend_ctes(
f"could not be resolved: {cte.id}"
)
cte_model = manifest.nodes[cte.id]
assert not isinstance(cte_model, SeedNode)

if not cte_model.is_ephemeral_model:
raise InternalException(f"{cte.id} is not ephemeral")
Expand Down Expand Up @@ -332,16 +327,16 @@ def _recursively_prepend_ctes(

return model, prepended_ctes

# Sets compiled fields in the ManifestNode passed in,
# Sets compiled fields in the ManifestSQLNode passed in,
# creates a "context" dictionary for jinja rendering,
# and then renders the "compiled_code" using the node, the
# raw_code and the context.
def _compile_node(
self,
node: ManifestNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]] = None,
) -> ManifestNode:
) -> ManifestSQLNode:
if extra_context is None:
extra_context = {}

Expand Down Expand Up @@ -383,8 +378,6 @@ def _compile_node(
node,
)

node.relation_name = self._get_relation_name(node)

node.compiled = True

return node
Expand Down Expand Up @@ -494,8 +487,11 @@ def compile(self, manifest: Manifest, write=True, add_test_edges=False) -> Graph
return Graph(linker.graph)

# writes the "compiled_code" into the target/compiled directory
def _write_node(self, node: ManifestNode) -> ManifestNode:
if not node.extra_ctes_injected or node.resource_type == NodeType.Snapshot:
def _write_node(self, node: ManifestSQLNode) -> ManifestSQLNode:
if not node.extra_ctes_injected or node.resource_type in (
NodeType.Snapshot,
NodeType.Seed,
):
return node
fire_event(WritingInjectedSQLForNode(node_info=get_node_info()))

Expand All @@ -507,11 +503,11 @@ def _write_node(self, node: ManifestNode) -> ManifestNode:

def compile_node(
self,
node: ManifestNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]] = None,
write: bool = True,
) -> ManifestNode:
) -> ManifestSQLNode:
"""This is the main entry point into this code. It's called by
CompileRunner.compile, GenericRPCRunner.compile, and
RunTask.get_hook_sql. It calls '_compile_node' to convert
Expand Down
10 changes: 5 additions & 5 deletions core/dbt/contracts/graph/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
GenericTestNode,
Exposure,
Metric,
HasUniqueID,
UnpatchedSourceDefinition,
ManifestNode,
GraphMemberNode,
ResultNode,
BaseNode,
)
from dbt.contracts.graph.unparsed import SourcePatch
from dbt.contracts.files import SourceFile, SchemaSourceFile, FileHash, AnySourceFile
Expand Down Expand Up @@ -320,7 +320,7 @@ def _sort_values(dct):


def build_node_edges(nodes: List[ManifestNode]):
"""Build the forward and backward edges on the given list of ParsedNodes
"""Build the forward and backward edges on the given list of ManifestNodes
and return them as two separate dictionaries, each mapping unique IDs to
lists of edges.
"""
Expand All @@ -338,10 +338,10 @@ def build_node_edges(nodes: List[ManifestNode]):
# Build a map of children of macros and generic tests
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
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:
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)
Expand Down Expand Up @@ -1235,7 +1235,7 @@ def __post_serialize__(self, dct):
return dct


def _check_duplicates(value: HasUniqueID, src: Mapping[str, HasUniqueID]):
def _check_duplicates(value: BaseNode, src: Mapping[str, BaseNode]):
if value.unique_id in src:
raise_duplicate_resource_name(value, src[value.unique_id])

Expand Down
Loading

0 comments on commit b54fe08

Please sign in to comment.