Files
dbt-core/core/dbt/parser/functions.py
Quigley Malcolm cb7c4a7dce Partial Parsing support for function nodes (#12074)
* Explicitly support functions during partial parsing

* Emit a `Note` event when partial parsing is skipped due to there being no changes

* Begin testing partial parsing support of function nodes

* Add changie doc

* Move test_pp_functions to use `EventCatcher` from dbt-common

* Remove from `functions` instead of `nodes` during partial parsing function deletion

* Fix the partial parsing scheduling of function sql and yaml files

Previously we were treating the partial parsing scheduling of function
files as if they were only defined by YAML files. However functions consist
of a "raw code file" (typically a .sql file) and a YAML file. We needed
to update the the deletion handling + scheduling of functions during partial
parsing to act more similar to "mssat" files in order to achieve this.
This work was primarily done agentically, but then simplified by myself
afterwards.

* Test that changing the alias of a function doesn't require reparsing of the downstream nodes that reference it
2025-11-24 16:53:17 -06:00

34 lines
1.2 KiB
Python

from dbt.artifacts.resources.types import NodeType
from dbt.contracts.files import SourceFile
from dbt.contracts.graph.nodes import FunctionNode, ManifestNode
from dbt.parser.base import SimpleParser
from dbt.parser.search import FileBlock
class FunctionParser(SimpleParser[FileBlock, FunctionNode]):
def parse_from_dict(self, dct, validate=True) -> FunctionNode:
if validate:
FunctionNode.validate(dct)
return FunctionNode.from_dict(dct)
@property
def resource_type(self) -> NodeType:
return NodeType.Function
@classmethod
def get_compiled_path(cls, block: FileBlock):
return block.path.relative_path
# overrides SimpleSQLParser.add_result_node
def add_result_node(self, block: FileBlock, node: ManifestNode):
assert isinstance(node, FunctionNode), "Got non FunctionNode in FunctionParser"
file = block.file
assert isinstance(file, SourceFile)
if node.config.enabled:
self.manifest.add_function(file, node)
else:
self.manifest.add_disabled(file, node)
def parse_file(self, file_block: FileBlock) -> None:
self.parse_node(file_block)