Skip to content

Commit 733115f

Browse files
committed
Leave some comments for future reference
1 parent f256690 commit 733115f

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

sqlmesh/core/model/common.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,22 @@ def _is_metadata_var(
7575
) -> t.Optional[bool]:
7676
is_metadata_so_far = used_variables.get(name, True)
7777
if is_metadata_so_far is False:
78+
# We've concluded this variable is definitely not metadata-only
7879
return False
7980

8081
appears_under_metadata_macro_func = expr_under_metadata_macro_func.get(id(expression))
8182
if is_metadata_so_far and (
8283
appears_in_metadata_expression or appears_under_metadata_macro_func
8384
):
85+
# The variable appears in a metadata expression, e.g., audits (...),
86+
# or in the AST of metadata-only macro call, e.g., @FOO(@x)
8487
return True
8588

89+
# The variable appears in the AST of a macro call, but we don't know if it's metadata-only
8690
if appears_under_metadata_macro_func is False:
8791
return None
8892

93+
# The variable appears elsewhere, e.g., in the model's query: SELECT @x
8994
return False
9095

9196
def _is_metadata_macro(name: str, appears_in_metadata_expression: bool) -> bool:
@@ -131,6 +136,12 @@ def _is_metadata_macro(name: str, appears_in_metadata_expression: bool) -> bool:
131136
var_name, macro_func_or_var, is_metadata
132137
)
133138
elif id(macro_func_or_var) not in visited_macro_funcs:
139+
# We only care about the top-level macro func calls to determine the metadata
140+
# status of the variables referenced in their ASTs. If the top-level call is
141+
# known to be metadata-only or appear in a metadata expression, then we don't
142+
# need to traverse the sub-macro func calls in its AST, hence why we track
143+
# visited macro funcs and the outermost macro func call ancestors by var name.
144+
134145
var_refs, _expr_under_metadata_macro_func, _visited_macro_funcs = (
135146
_extract_macro_func_variable_references(macro_func_or_var, is_metadata)
136147
)
@@ -192,7 +203,7 @@ def _extract_macro_func_variable_references(
192203
macro_func: exp.Expression,
193204
is_metadata: bool,
194205
) -> t.Tuple[t.Set[str], t.Dict[int, bool], t.Set[int]]:
195-
references = set()
206+
var_references = set()
196207
visited_macro_funcs = set()
197208
expr_under_metadata_macro_func = {}
198209

@@ -204,19 +215,19 @@ def _extract_macro_func_variable_references(
204215
args = this.expressions
205216

206217
if this.name.lower() in (c.VAR, c.BLUEPRINT_VAR) and args and args[0].is_string:
207-
references.add(args[0].this.lower())
218+
var_references.add(args[0].this.lower())
208219
expr_under_metadata_macro_func[id(n)] = is_metadata
209220
elif isinstance(n, d.MacroVar):
210-
references.add(n.name.lower())
221+
var_references.add(n.name.lower())
211222
expr_under_metadata_macro_func[id(n)] = is_metadata
212223
elif isinstance(n, (exp.Identifier, d.MacroStrReplace, d.MacroSQL)) and "@" in n.name:
213-
references.update(
224+
var_references.update(
214225
(braced_identifier or identifier).lower()
215226
for _, identifier, braced_identifier, _ in MacroStrTemplate.pattern.findall(n.name)
216227
)
217228
expr_under_metadata_macro_func[id(n)] = is_metadata
218229

219-
return (references, expr_under_metadata_macro_func, visited_macro_funcs)
230+
return (var_references, expr_under_metadata_macro_func, visited_macro_funcs)
220231

221232

222233
def _add_variables_to_python_env(
@@ -238,16 +249,22 @@ def _add_variables_to_python_env(
238249
for var_name, is_metadata in python_used_variables.items():
239250
used_variables[var_name] = is_metadata and used_variables.get(var_name, True)
240251

241-
# Variables are treated as metadata when:
242-
# - They are only referenced in metadata-only contexts, such as `audits (...)`, virtual statements, etc
243-
# - They are only referenced in metadata-only macros, either as their arguments or within their definitions
252+
# Variables are treated as metadata-only when all of their references either:
253+
# - appear in metadata-only expressions, such as `audits (...)`, virtual statements, etc
254+
# - appear in the ASTs or definitions of metadata-only macros
255+
#
256+
# See also: https://github.com/TobikoData/sqlmesh/pull/4936#issuecomment-3136339936,
257+
# specifically the "Terminology" and "Observations" section.
244258
metadata_used_variables = {
245259
var_name for var_name, is_metadata in used_variables.items() if is_metadata
246260
}
247261
for used_var, outermost_macro_func in (outermost_macro_func_ancestor_by_var or {}).items():
248262
used_var_is_metadata = used_variables.get(used_var)
249263
if used_var_is_metadata is False:
250264
continue
265+
266+
# At this point we can decide whether a variable reference in a macro call's AST is
267+
# metadata-only, because we've annotated the corresponding macro call in the python env.
251268
if outermost_macro_func in python_env and python_env[outermost_macro_func].is_metadata:
252269
metadata_used_variables.add(used_var)
253270

0 commit comments

Comments
 (0)