diff --git a/sqlmesh/core/renderer.py b/sqlmesh/core/renderer.py index 18377e0258..9e750159be 100644 --- a/sqlmesh/core/renderer.py +++ b/sqlmesh/core/renderer.py @@ -6,7 +6,7 @@ from functools import partial from pathlib import Path -from sqlglot import exp, parse +from sqlglot import exp, Dialect from sqlglot.errors import SqlglotError from sqlglot.helper import ensure_list from sqlglot.optimizer.annotate_types import annotate_types @@ -249,15 +249,24 @@ def _resolve_table(table: str | exp.Table) -> str: ) from ex if rendered_expression.strip(): - try: - expressions = [e for e in parse(rendered_expression, read=self._dialect) if e] - - if not expressions: - raise ConfigError(f"Failed to parse an expression:\n{self._expression}") - except Exception as ex: - raise ConfigError( - f"Could not parse the rendered jinja at '{self._path}'.\n{ex}" - ) from ex + # ensure there is actual SQL and not just comments and non-SQL jinja + dialect = Dialect.get_or_raise(self._dialect) + tokens = dialect.tokenize(rendered_expression) + + if tokens: + try: + expressions = [ + e for e in dialect.parser().parse(tokens, rendered_expression) if e + ] + + if not expressions: + raise ConfigError( + f"Failed to parse an expression:\n{rendered_expression}" + ) + except Exception as ex: + raise ConfigError( + f"Could not parse the rendered jinja at '{self._path}'.\n{ex}" + ) from ex if this_model: render_kwargs["this_model"] = this_model diff --git a/tests/dbt/test_model.py b/tests/dbt/test_model.py index caa409807f..7bcfe98768 100644 --- a/tests/dbt/test_model.py +++ b/tests/dbt/test_model.py @@ -873,3 +873,24 @@ def test_load_model_dbt_node_name(tmp_path: Path) -> None: # Verify that node_name is the equivalent dbt one model = context.snapshots[model_fqn].model assert model.dbt_name == "model.test_project.simple_model" + + +@pytest.mark.slow +def test_jinja_config_no_query(tmp_path, create_empty_project): + project_dir, model_dir = create_empty_project() + + # model definition contains only a comment and non-SQL jinja + model_contents = "/* comment */ {{ config(materialized='table') }}" + model_file = model_dir / "comment_config_model.sql" + with open(model_file, "w", encoding="utf-8") as f: + f.write(model_contents) + + schema_yaml = {"version": 2, "models": [{"name": "comment_config_model"}]} + schema_file = model_dir / "schema.yml" + with open(schema_file, "w", encoding="utf-8") as f: + YAML().dump(schema_yaml, f) + + context = Context(paths=project_dir) + + # loads without error and contains empty query (which will error at runtime) + assert not context.snapshots['"local"."main"."comment_config_model"'].model.render_query()