Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20230424-163611.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Optimize template rendering for common parse scenarios
time: 2023-04-24T16:36:11.24088-04:00
custom:
Author: peterallenwebb
Issue: "7449"
22 changes: 18 additions & 4 deletions core/dbt/clients/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,30 +565,44 @@ def _requote_result(raw_value: str, rendered: str) -> str:
# is small enough that I've just chosen the more readable option.
_HAS_RENDER_CHARS_PAT = re.compile(r"({[{%#]|[#}%]})")

_render_cache: Dict[str, Any] = dict()


def get_rendered(
string: str,
ctx: Dict[str, Any],
node=None,
capture_macros: bool = False,
native: bool = False,
) -> str:
) -> Any:
# performance optimization: if there are no jinja control characters in the
# string, we can just return the input. Fall back to jinja if the type is
# not a string or if native rendering is enabled (so '1' -> 1, etc...)
# If this is desirable in the native env as well, we could handle the
# native=True case by passing the input string to ast.literal_eval, like
# the native renderer does.
if not native and isinstance(string, str) and _HAS_RENDER_CHARS_PAT.search(string) is None:
return string
has_render_chars = not isinstance(string, str) or _HAS_RENDER_CHARS_PAT.search(string)

if not has_render_chars:
if not native:
return string
elif string in _render_cache:
return _render_cache[string]

template = get_template(
string,
ctx,
node,
capture_macros=capture_macros,
native=native,
)
return render_template(template, ctx, node)

rendered = render_template(template, ctx, node)

if not has_render_chars and native:
_render_cache[string] = rendered

return rendered


def undefined_error(msg) -> NoReturn:
Expand Down