From 8ed6fd0bd58a3d3ab8582b42b420d2edca21cc66 Mon Sep 17 00:00:00 2001 From: "michael.wallis" Date: Fri, 27 Jun 2025 19:42:23 +0100 Subject: [PATCH] update default value for end_time to be +1 day --- sqlmesh/core/renderer.py | 7 +++--- tests/core/test_audit.py | 2 +- tests/core/test_config.py | 1 + tests/core/test_model.py | 34 +++++++++++++++++++++++++-- tests/core/test_snapshot_evaluator.py | 2 +- tests/web/test_lineage.py | 2 +- 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/sqlmesh/core/renderer.py b/sqlmesh/core/renderer.py index 6622094da3..32a78c3ab5 100644 --- a/sqlmesh/core/renderer.py +++ b/sqlmesh/core/renderer.py @@ -3,6 +3,7 @@ import logging import typing as t from contextlib import contextmanager +from datetime import timedelta from functools import partial from pathlib import Path @@ -83,12 +84,12 @@ def _render( runtime_stage: RuntimeStage = RuntimeStage.LOADING, **kwargs: t.Any, ) -> t.List[t.Optional[exp.Expression]]: - """Renders a expression, expanding macros with provided kwargs + """Renders an expression, expanding macros with provided kwargs Args: start: The start datetime to render. Defaults to epoch start. end: The end datetime to render. Defaults to epoch start. - execution_time: The date/time time reference to use for execution time. + execution_time: The datetime/time reference to use for execution time. snapshots: All upstream snapshots (by model name) to use for expansion and mapping of physical locations. table_mapping: Table mapping of physical locations. Takes precedence over snapshot mappings. deployability_index: Determines snapshots that are deployable in the context of this evaluation. @@ -173,7 +174,7 @@ def _resolve_table(table: str | exp.Table) -> str: ) start_time, end_time = ( - make_inclusive(start or c.EPOCH, end or c.EPOCH, self._dialect) + make_inclusive(start or c.EPOCH, end or c.EPOCH + timedelta(days=1), self._dialect) if not self._only_execution_time else (None, None) ) diff --git a/tests/core/test_audit.py b/tests/core/test_audit.py index 1befb1148c..1c49c6d4c9 100644 --- a/tests/core/test_audit.py +++ b/tests/core/test_audit.py @@ -809,7 +809,7 @@ def test_condition_with_macro_var(model: Model): ) assert ( rendered_query.sql(dialect="duckdb") - == """SELECT * FROM (SELECT * FROM "db"."test_model" AS "test_model" WHERE "ds" BETWEEN '1970-01-01' AND '1970-01-01') AS "_q_0" WHERE "x" IS NULL AND "dt" BETWEEN CAST('1970-01-01 00:00:00+00:00' AS TIMESTAMPTZ) AND CAST('1970-01-01 23:59:59.999999+00:00' AS TIMESTAMPTZ)""" + == """SELECT * FROM (SELECT * FROM "db"."test_model" AS "test_model" WHERE "ds" BETWEEN '1970-01-01' AND '1970-01-01') AS "_q_0" WHERE "x" IS NULL AND "dt" BETWEEN CAST('1970-01-01 00:00:00+00:00' AS TIMESTAMPTZ) AND CAST('1970-01-02 23:59:59.999999+00:00' AS TIMESTAMPTZ)""" ) diff --git a/tests/core/test_config.py b/tests/core/test_config.py index b3457345a8..7627b3334f 100644 --- a/tests/core/test_config.py +++ b/tests/core/test_config.py @@ -990,6 +990,7 @@ def test_environment_statements_config(tmp_path): def test_pydantic_import_error() -> None: class TestConfig(DuckDBConnectionConfig): pass + TestConfig.model_rebuild() TestConfig() diff --git a/tests/core/test_model.py b/tests/core/test_model.py index 8d16c9422b..26b80ea8af 100644 --- a/tests/core/test_model.py +++ b/tests/core/test_model.py @@ -2161,7 +2161,7 @@ def test_render_query(assert_exp_eq, sushi_context): CAST("o"."event_date" AS DATE) AS "event_date" FROM "memory"."sushi"."orders" AS "o" WHERE - "o"."event_date" <= CAST('1970-01-01' AS DATE) AND "o"."event_date" >= CAST('1970-01-01' AS DATE) + "o"."event_date" <= CAST('1970-01-02' AS DATE) AND "o"."event_date" >= CAST('1970-01-01' AS DATE) """, ) @@ -2261,6 +2261,36 @@ def test_render_query(assert_exp_eq, sushi_context): ) +def test_render_temporal_variables_give_different_hashes(sushi_context): + model_with_start = SqlModel( + name="test", + cron="1 0 * * *", + kind=IncrementalByTimeRangeKind(time_column=TimeColumn(column="y")), + query=d.parse_one( + """ + SELECT y + FROM x + WHERE + y = @start_ds + """ + ), + ) + model_with_end = SqlModel( + name="test", + cron="1 0 * * *", + kind=IncrementalByTimeRangeKind(time_column=TimeColumn(column="y")), + query=d.parse_one( + """ + SELECT y + FROM x + WHERE + y = @end_ds + """ + ), + ) + assert model_with_start.data_hash != model_with_end.data_hash + + def test_time_column(): expressions = d.parse( """ @@ -2478,7 +2508,7 @@ def test_parse(assert_exp_eq): "ds" AS "ds" FROM "x" AS "x" WHERE - "ds" BETWEEN '1970-01-01' AND '1970-01-01' + "ds" BETWEEN '1970-01-01' AND '1970-01-02' """, ) diff --git a/tests/core/test_snapshot_evaluator.py b/tests/core/test_snapshot_evaluator.py index d131e6aa95..0ccc84f1ff 100644 --- a/tests/core/test_snapshot_evaluator.py +++ b/tests/core/test_snapshot_evaluator.py @@ -1237,7 +1237,7 @@ def test_migrate_missing_table(mocker: MockerFixture, make_snapshot): [ call('CREATE TABLE "pre" ("a" INT)'), call( - 'CREATE TABLE IF NOT EXISTS "sqlmesh__test_schema"."test_schema__test_model__1" AS SELECT "c" AS "c", "a" AS "a" FROM "tbl" AS "tbl" WHERE "ds" BETWEEN \'1970-01-01\' AND \'1970-01-01\' AND FALSE LIMIT 0' + 'CREATE TABLE IF NOT EXISTS "sqlmesh__test_schema"."test_schema__test_model__1" AS SELECT "c" AS "c", "a" AS "a" FROM "tbl" AS "tbl" WHERE "ds" BETWEEN \'1970-01-01\' AND \'1970-01-02\' AND FALSE LIMIT 0' ), call('DROP TABLE "pre"'), ] diff --git a/tests/web/test_lineage.py b/tests/web/test_lineage.py index 0cffd3ecc3..22be7e5557 100644 --- a/tests/web/test_lineage.py +++ b/tests/web/test_lineage.py @@ -25,7 +25,7 @@ def test_get_lineage(client: TestClient, web_sushi_context: Context) -> None: CAST("o"."event_date" AS DATE) AS "event_date" FROM "memory"."sushi"."orders" AS "o" WHERE - "o"."event_date" <= CAST('1970-01-01' AS DATE) + "o"."event_date" <= CAST('1970-01-02' AS DATE) AND "o"."event_date" >= CAST('1970-01-01' AS DATE)""", "expression": 'CAST("o"."event_date" AS DATE) AS "event_date"', "models": {'"memory"."sushi"."orders"': ["event_date"]},