@@ -404,6 +404,109 @@ def test_delta_timestamps(make_mocked_engine_adapter: t.Callable):
404404 }
405405
406406
407+ def test_trino_to_delta_timestamp_mapping ():
408+ """Test that trino_to_delta_timestamp_mapping config property is properly defined and accessible."""
409+ config = TrinoConnectionConfig (
410+ user = "user" ,
411+ host = "host" ,
412+ catalog = "catalog" ,
413+ )
414+
415+ adapter = config .create_engine_adapter ()
416+ assert adapter .trino_to_delta_timestamp_mapping is None
417+
418+ config = TrinoConnectionConfig (
419+ user = "user" ,
420+ host = "host" ,
421+ catalog = "catalog" ,
422+ trino_to_delta_timestamp_mapping = {
423+ "TIMESTAMP" : "TIMESTAMP" ,
424+ "TIMESTAMP(3)" : "TIMESTAMP_NTZ" ,
425+ },
426+ )
427+ adapter = config .create_engine_adapter ()
428+ assert adapter .trino_to_delta_timestamp_mapping is not None
429+ assert adapter .trino_to_delta_timestamp_mapping [
430+ exp .DataType .build ("TIMESTAMP" )
431+ ] == exp .DataType .build ("TIMESTAMP" )
432+
433+
434+ def test_delta_timestamps_with_custom_mapping (make_mocked_engine_adapter : t .Callable ):
435+ """Test that _to_delta_ts respects custom trino_to_delta_timestamp_mapping."""
436+ # Create config with custom timestamp mapping using valid Delta Lake types
437+ # Delta Lake only supports: TIMESTAMP (TZ-aware) and TIMESTAMP_NTZ (no TZ)
438+ config = TrinoConnectionConfig (
439+ user = "user" ,
440+ host = "host" ,
441+ catalog = "catalog" ,
442+ trino_to_delta_timestamp_mapping = {
443+ "TIMESTAMP" : "TIMESTAMP" ,
444+ "TIMESTAMP(1)" : "TIMESTAMP" ,
445+ "TIMESTAMP WITH TIME ZONE" : "TIMESTAMP" ,
446+ "TIMESTAMP(1) WITH TIME ZONE" : "TIMESTAMP" ,
447+ },
448+ )
449+
450+ adapter = make_mocked_engine_adapter (
451+ TrinoEngineAdapter , trino_to_delta_timestamp_mapping = config .trino_to_delta_timestamp_mapping
452+ )
453+
454+ ts3_tz = exp .DataType .build ("timestamp(3) with time zone" )
455+
456+ columns_to_types = {
457+ "ts" : exp .DataType .build ("TIMESTAMP" ),
458+ "ts_1" : exp .DataType .build ("TIMESTAMP(1)" ),
459+ "ts_tz" : exp .DataType .build ("TIMESTAMP WITH TIME ZONE" ),
460+ "ts_tz_1" : exp .DataType .build ("TIMESTAMP(1) WITH TIME ZONE" ),
461+ }
462+
463+ delta_columns_to_types = adapter ._to_delta_ts (columns_to_types )
464+
465+ # All types mapped to Delta's TIMESTAMP get converted to TIMESTAMPTZ then ts3_tz
466+ assert delta_columns_to_types == {
467+ "ts" : ts3_tz ,
468+ "ts_1" : ts3_tz ,
469+ "ts_tz" : ts3_tz ,
470+ "ts_tz_1" : ts3_tz ,
471+ }
472+
473+
474+ def test_delta_timestamps_with_partial_mapping (make_mocked_engine_adapter : t .Callable ):
475+ """Test that _to_delta_ts uses custom mapping for specified types and defaults for others."""
476+ config = TrinoConnectionConfig (
477+ user = "user" ,
478+ host = "host" ,
479+ catalog = "catalog" ,
480+ trino_to_delta_timestamp_mapping = {
481+ "TIMESTAMP" : "TIMESTAMP" ,
482+ },
483+ )
484+
485+ adapter = make_mocked_engine_adapter (
486+ TrinoEngineAdapter , trino_to_delta_timestamp_mapping = config .trino_to_delta_timestamp_mapping
487+ )
488+
489+ ts6 = exp .DataType .build ("timestamp(6)" )
490+ ts3_tz = exp .DataType .build ("timestamp(3) with time zone" )
491+
492+ columns_to_types = {
493+ "ts" : exp .DataType .build ("TIMESTAMP" ),
494+ "ts_1" : exp .DataType .build ("TIMESTAMP(1)" ),
495+ "ts_tz" : exp .DataType .build ("TIMESTAMP WITH TIME ZONE" ),
496+ }
497+
498+ delta_columns_to_types = adapter ._to_delta_ts (columns_to_types )
499+
500+ # TIMESTAMP is in mapping → TIMESTAMP → TIMESTAMPTZ → ts3_tz
501+ # TIMESTAMP(1) is NOT in mapping (exact match), uses default TIMESTAMP → ts6
502+ # TIMESTAMP WITH TIME ZONE is NOT in mapping, uses default TIMESTAMPTZ → ts3_tz
503+ assert delta_columns_to_types == {
504+ "ts" : ts3_tz ,
505+ "ts_1" : ts6 , # Not in mapping, uses default
506+ "ts_tz" : ts3_tz ,
507+ }
508+
509+
407510def test_table_format (trino_mocked_engine_adapter : TrinoEngineAdapter , mocker : MockerFixture ):
408511 adapter = trino_mocked_engine_adapter
409512 mocker .patch (
@@ -755,3 +858,73 @@ def test_insert_overwrite_time_partition_iceberg(
755858 'DELETE FROM "my_catalog"."schema"."test_table" WHERE "b" BETWEEN \' 2022-01-01\' AND \' 2022-01-02\' ' ,
756859 'INSERT INTO "my_catalog"."schema"."test_table" ("a", "b") SELECT "a", "b" FROM (SELECT "a", "b" FROM "tbl") AS "_subquery" WHERE "b" BETWEEN \' 2022-01-01\' AND \' 2022-01-02\' ' ,
757860 ]
861+
862+
863+ def test_delta_timestamps_with_non_timestamp_columns (make_mocked_engine_adapter : t .Callable ):
864+ """Test that _to_delta_ts handles non-timestamp columns alongside custom mapping."""
865+ config = TrinoConnectionConfig (
866+ user = "user" ,
867+ host = "host" ,
868+ catalog = "catalog" ,
869+ trino_to_delta_timestamp_mapping = {
870+ "TIMESTAMP" : "TIMESTAMP" ,
871+ },
872+ )
873+
874+ adapter = make_mocked_engine_adapter (
875+ TrinoEngineAdapter , trino_to_delta_timestamp_mapping = config .trino_to_delta_timestamp_mapping
876+ )
877+
878+ ts6 = exp .DataType .build ("timestamp(6)" )
879+ ts3_tz = exp .DataType .build ("timestamp(3) with time zone" )
880+
881+ columns_to_types = {
882+ "ts" : exp .DataType .build ("TIMESTAMP" ),
883+ "ts_1" : exp .DataType .build ("TIMESTAMP(1)" ),
884+ "int_col" : exp .DataType .build ("INT" ),
885+ "varchar_col" : exp .DataType .build ("VARCHAR(100)" ),
886+ "decimal_col" : exp .DataType .build ("DECIMAL(10,2)" ),
887+ }
888+
889+ delta_columns_to_types = adapter ._to_delta_ts (columns_to_types )
890+
891+ # TIMESTAMP is in mapping → TIMESTAMP → TIMESTAMPTZ → ts3_tz
892+ # TIMESTAMP(1) is NOT in mapping (exact match), uses default TIMESTAMP → ts6
893+ # Non-timestamp columns should pass through unchanged
894+ assert delta_columns_to_types == {
895+ "ts" : ts3_tz ,
896+ "ts_1" : ts6 , # Not in mapping, uses default
897+ "int_col" : exp .DataType .build ("INT" ),
898+ "varchar_col" : exp .DataType .build ("VARCHAR(100)" ),
899+ "decimal_col" : exp .DataType .build ("DECIMAL(10,2)" ),
900+ }
901+
902+
903+ def test_delta_timestamps_with_empty_mapping (make_mocked_engine_adapter : t .Callable ):
904+ """Test that _to_delta_ts handles empty custom mapping dictionary."""
905+ config = TrinoConnectionConfig (
906+ user = "user" ,
907+ host = "host" ,
908+ catalog = "catalog" ,
909+ trino_to_delta_timestamp_mapping = {},
910+ )
911+
912+ adapter = make_mocked_engine_adapter (
913+ TrinoEngineAdapter , trino_to_delta_timestamp_mapping = config .trino_to_delta_timestamp_mapping
914+ )
915+
916+ ts6 = exp .DataType .build ("timestamp(6)" )
917+ ts3_tz = exp .DataType .build ("timestamp(3) with time zone" )
918+
919+ columns_to_types = {
920+ "ts" : exp .DataType .build ("TIMESTAMP" ),
921+ "ts_tz" : exp .DataType .build ("TIMESTAMP WITH TIME ZONE" ),
922+ }
923+
924+ delta_columns_to_types = adapter ._to_delta_ts (columns_to_types )
925+
926+ # With empty custom mapping, should fall back to defaults
927+ assert delta_columns_to_types == {
928+ "ts" : ts6 ,
929+ "ts_tz" : ts3_tz ,
930+ }
0 commit comments