|
3 | 3 |
|
4 | 4 | from typing_extensions import Self |
5 | 5 | from unittest.mock import call, patch, Mock |
| 6 | +import contextlib |
6 | 7 | import re |
7 | 8 | import logging |
8 | 9 | import pytest |
@@ -2077,6 +2078,68 @@ def columns(table_name): |
2077 | 2078 | ) |
2078 | 2079 |
|
2079 | 2080 |
|
| 2081 | +def test_temp_table_includes_schema_for_ignore_changes( |
| 2082 | + mocker: MockerFixture, |
| 2083 | + make_snapshot, |
| 2084 | + make_mocked_engine_adapter, |
| 2085 | +): |
| 2086 | + """Test that temp table creation includes the physical schema when on_destructive_change or on_additive_change is IGNORE.""" |
| 2087 | + # Create a model with on_destructive_change=IGNORE to trigger temp table creation |
| 2088 | + model = SqlModel( |
| 2089 | + name="test_schema.test_model", |
| 2090 | + kind=IncrementalByTimeRangeKind( |
| 2091 | + time_column="a", on_destructive_change=OnDestructiveChange.IGNORE |
| 2092 | + ), |
| 2093 | + query=parse_one("SELECT c, a FROM tbl WHERE ds BETWEEN @start_ds and @end_ds"), |
| 2094 | + ) |
| 2095 | + snapshot = make_snapshot(model, version="1") |
| 2096 | + snapshot.categorize_as(SnapshotChangeCategory.BREAKING) |
| 2097 | + |
| 2098 | + # Set up the mocked adapter |
| 2099 | + adapter = make_mocked_engine_adapter(EngineAdapter) |
| 2100 | + adapter.with_settings = lambda **kwargs: adapter # type: ignore |
| 2101 | + adapter.table_exists = lambda _: True # type: ignore |
| 2102 | + |
| 2103 | + # Mock columns method to return existing columns |
| 2104 | + def columns(table_name): |
| 2105 | + return { |
| 2106 | + "c": exp.DataType.build("int"), |
| 2107 | + "a": exp.DataType.build("int"), |
| 2108 | + } |
| 2109 | + |
| 2110 | + adapter.columns = columns # type: ignore |
| 2111 | + |
| 2112 | + # Create a mock for the temp_table context manager |
| 2113 | + temp_table_name_captured = None |
| 2114 | + |
| 2115 | + @contextlib.contextmanager |
| 2116 | + def mock_temp_table(query_or_df, name="diff", **kwargs): |
| 2117 | + nonlocal temp_table_name_captured |
| 2118 | + temp_table_name_captured = exp.to_table(name) |
| 2119 | + # Return a table that temp_table would normally return |
| 2120 | + yield exp.table_("__temp_diff_12345", db=temp_table_name_captured.db) |
| 2121 | + |
| 2122 | + adapter.temp_table = mock_temp_table # type: ignore |
| 2123 | + adapter.insert_append = lambda *args, **kwargs: None # type: ignore |
| 2124 | + |
| 2125 | + evaluator = SnapshotEvaluator(adapter) |
| 2126 | + |
| 2127 | + # Call the append method which will trigger _get_target_and_source_columns |
| 2128 | + evaluator.evaluate( |
| 2129 | + snapshot, |
| 2130 | + start="2020-01-01", |
| 2131 | + end="2020-01-02", |
| 2132 | + execution_time="2020-01-02", |
| 2133 | + snapshots={}, |
| 2134 | + ) |
| 2135 | + |
| 2136 | + # Verify that temp_table was called with a name that includes the schema |
| 2137 | + assert temp_table_name_captured is not None |
| 2138 | + assert temp_table_name_captured.name == "diff" |
| 2139 | + assert temp_table_name_captured.db == model.physical_schema |
| 2140 | + assert str(temp_table_name_captured.db) == "sqlmesh__test_schema" |
| 2141 | + |
| 2142 | + |
2080 | 2143 | def test_forward_only_snapshot_for_added_model(mocker: MockerFixture, adapter_mock, make_snapshot): |
2081 | 2144 | adapter_mock.SUPPORTS_CLONING = False |
2082 | 2145 | evaluator = SnapshotEvaluator(adapter_mock) |
|
0 commit comments