|
31 | 31 | ModelDefaultsConfig, |
32 | 32 | LinterConfig, |
33 | 33 | ) |
| 34 | +from sqlmesh.core import constants as c |
34 | 35 | from sqlmesh.core.context import Context, ExecutionContext |
35 | 36 | from sqlmesh.core.dialect import parse |
36 | 37 | from sqlmesh.core.engine_adapter.base import MERGE_SOURCE_ALIAS, MERGE_TARGET_ALIAS |
37 | 38 | from sqlmesh.core.engine_adapter.duckdb import DuckDBEngineAdapter |
38 | 39 | from sqlmesh.core.macros import MacroEvaluator, macro |
39 | | -from sqlmesh.core import constants as c |
40 | 40 | from sqlmesh.core.model import ( |
41 | 41 | CustomKind, |
42 | 42 | PythonModel, |
@@ -198,29 +198,64 @@ def test_model_multiple_select_statements(): |
198 | 198 | load_sql_based_model(expressions) |
199 | 199 |
|
200 | 200 |
|
201 | | -@pytest.mark.parametrize( |
202 | | - "query, error", |
203 | | - [ |
204 | | - ("y::int, x::int AS y", "duplicate"), |
205 | | - ("* FROM db.table", "require inferrable column types"), |
206 | | - ], |
207 | | -) |
208 | | -def test_model_validation(query, error): |
| 201 | +def test_model_validation(tmp_path): |
209 | 202 | expressions = d.parse( |
210 | 203 | f""" |
211 | 204 | MODEL ( |
212 | 205 | name db.table, |
213 | 206 | kind FULL, |
214 | 207 | ); |
215 | 208 |
|
216 | | - SELECT {query} |
| 209 | + SELECT |
| 210 | + y::int, |
| 211 | + x::int AS y |
| 212 | + FROM db.ext |
| 213 | + """ |
| 214 | + ) |
| 215 | + |
| 216 | + ctx = Context( |
| 217 | + config=Config(linter=LinterConfig(enabled=True, rules=["noambiguousprojections"])), |
| 218 | + paths=tmp_path, |
| 219 | + ) |
| 220 | + ctx.upsert_model(load_sql_based_model(expressions, default_catalog="memory")) |
| 221 | + |
| 222 | + errors = ctx.lint_models(["db.table"], raise_on_error=False) |
| 223 | + assert errors, "Expected NoAmbiguousProjections violation" |
| 224 | + assert errors[0].violation_msg == "Found duplicate outer select name 'y'" |
| 225 | + |
| 226 | + expressions = d.parse( |
| 227 | + """ |
| 228 | + MODEL ( |
| 229 | + name db.table, |
| 230 | + kind FULL, |
| 231 | + ); |
| 232 | +
|
| 233 | + SELECT a, a UNION SELECT c, c |
| 234 | + """ |
| 235 | + ) |
| 236 | + |
| 237 | + ctx.upsert_model(load_sql_based_model(expressions, default_catalog="memory")) |
| 238 | + |
| 239 | + errors = ctx.lint_models(["db.table"], raise_on_error=False) |
| 240 | + assert errors, "Expected NoAmbiguousProjections violation" |
| 241 | + assert errors[0].violation_msg == "Found duplicate outer select name 'a'" |
| 242 | + |
| 243 | + expressions = d.parse( |
| 244 | + f""" |
| 245 | + MODEL ( |
| 246 | + name db.table, |
| 247 | + kind FULL, |
| 248 | + ); |
| 249 | +
|
| 250 | + SELECT * FROM db.table |
217 | 251 | """ |
218 | 252 | ) |
219 | 253 |
|
220 | 254 | model = load_sql_based_model(expressions) |
221 | 255 | with pytest.raises(ConfigError) as ex: |
222 | 256 | model.validate_definition() |
223 | | - assert error in str(ex.value) |
| 257 | + |
| 258 | + assert "require inferrable column types" in str(ex.value) |
224 | 259 |
|
225 | 260 |
|
226 | 261 | def test_model_union_query(sushi_context, assert_exp_eq): |
@@ -405,23 +440,6 @@ def get_date(evaluator): |
405 | 440 | ) |
406 | 441 |
|
407 | 442 |
|
408 | | -def test_model_validation_union_query(): |
409 | | - expressions = d.parse( |
410 | | - """ |
411 | | - MODEL ( |
412 | | - name db.table, |
413 | | - kind FULL, |
414 | | - ); |
415 | | -
|
416 | | - SELECT a, a UNION SELECT c, c |
417 | | - """ |
418 | | - ) |
419 | | - |
420 | | - model = load_sql_based_model(expressions) |
421 | | - with pytest.raises(ConfigError, match=r"Found duplicate outer select name 'a'"): |
422 | | - model.validate_definition() |
423 | | - |
424 | | - |
425 | 443 | @use_terminal_console |
426 | 444 | def test_model_qualification(tmp_path: Path): |
427 | 445 | with patch.object(get_console(), "log_warning") as mock_logger: |
|
0 commit comments