Skip to content

Commit f1a2bb0

Browse files
authored
Fix(clickhouse): specify DateTime64 precision for model partitioning expression (#3582)
1 parent 9d7c385 commit f1a2bb0

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

sqlmesh/core/model/definition.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,15 +2290,15 @@ def clickhouse_partition_func(
22902290
if col_type.is_type(exp.DataType.Type.UNKNOWN):
22912291
return exp.func(
22922292
"toMonday",
2293-
exp.cast(column, exp.DataType.build("DateTime64('UTC')", dialect="clickhouse")),
2293+
exp.cast(column, exp.DataType.build("DateTime64(9, 'UTC')", dialect="clickhouse")),
22942294
dialect="clickhouse",
22952295
)
22962296

22972297
# if input column type is known but not conformable, cast input to DateTime64 and cast output back to original type
22982298
return exp.cast(
22992299
exp.func(
23002300
"toMonday",
2301-
exp.cast(column, exp.DataType.build("DateTime64('UTC')", dialect="clickhouse")),
2301+
exp.cast(column, exp.DataType.build("DateTime64(9, 'UTC')", dialect="clickhouse")),
23022302
dialect="clickhouse",
23032303
),
23042304
col_type,

tests/core/engine_adapter/integration/test_integration_clickhouse.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,51 @@ def test_insert_overwrite_by_condition_inc_by_partition(ctx: TestContext):
497497
]
498498
),
499499
)
500+
501+
502+
def test_inc_by_time_auto_partition_string(ctx: TestContext):
503+
# ensure automatic time partitioning works when the time column is not a Date/DateTime type
504+
existing_table_name = _create_table_and_insert_existing_data(
505+
ctx,
506+
columns_to_types={
507+
"id": exp.DataType.build("Int8", "clickhouse"),
508+
"ds": exp.DataType.build("String", "clickhouse"), # String time column
509+
},
510+
table_name="data_existing",
511+
partitioned_by=None,
512+
)
513+
514+
sqlmesh_context, model = ctx.upsert_sql_model(
515+
f"""
516+
MODEL (
517+
name test.inc_by_time_no_partition,
518+
kind INCREMENTAL_BY_TIME_RANGE (
519+
time_column ds
520+
),
521+
dialect clickhouse,
522+
start '2023-01-01'
523+
);
524+
525+
SELECT
526+
id::Int8,
527+
ds::String
528+
FROM {existing_table_name.sql()}
529+
WHERE ds BETWEEN @start_ds AND @end_ds
530+
"""
531+
)
532+
533+
plan = sqlmesh_context.plan(no_prompts=True, auto_apply=True)
534+
535+
physical_location = ctx.engine_adapter.get_data_objects(
536+
plan.environment.snapshots[0].physical_schema
537+
)[0]
538+
539+
partitions = ctx.engine_adapter.fetchall(
540+
exp.select("_partition_id")
541+
.distinct()
542+
.from_(f"{physical_location.schema_name}.{physical_location.name}")
543+
)
544+
545+
# The automatic time partitioning creates one partition per week. The 4 input data points
546+
# are located in three distinct weeks, which should have one partition each.
547+
assert len(partitions) == 3

tests/core/engine_adapter/test_clickhouse.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,8 @@ def test_partitioned_by_expr(make_mocked_engine_adapter: t.Callable):
371371
)
372372

373373
assert (
374-
model.partitioned_by[0].sql("clickhouse") == """toMonday(CAST("ds" AS DateTime64('UTC')))"""
374+
model.partitioned_by[0].sql("clickhouse")
375+
== """toMonday(CAST("ds" AS DateTime64(9, 'UTC')))"""
375376
)
376377

377378
# user specifies without time column, unknown time column type
@@ -396,7 +397,7 @@ def test_partitioned_by_expr(make_mocked_engine_adapter: t.Callable):
396397
)
397398

398399
assert [p.sql("clickhouse") for p in model.partitioned_by] == [
399-
"""toMonday(CAST("ds" AS DateTime64('UTC')))""",
400+
"""toMonday(CAST("ds" AS DateTime64(9, 'UTC')))""",
400401
'"x"',
401402
]
402403

@@ -444,7 +445,7 @@ def test_partitioned_by_expr(make_mocked_engine_adapter: t.Callable):
444445

445446
assert (
446447
model.partitioned_by[0].sql("clickhouse")
447-
== """CAST(toMonday(CAST("ds" AS DateTime64('UTC'))) AS String)"""
448+
== """CAST(toMonday(CAST("ds" AS DateTime64(9, 'UTC'))) AS String)"""
448449
)
449450

450451
# user specifies partitioned_by with time column

0 commit comments

Comments
 (0)