Skip to content

Commit ca66f64

Browse files
test(bigquery): unchanged clustering key is not altered when a column is added
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 34e52ef commit ca66f64

1 file changed

Lines changed: 54 additions & 1 deletion

File tree

‎tests/core/engine_adapter/test_bigquery.py‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
import sqlmesh.core.dialect as d
1414
from sqlmesh.core.engine_adapter import BigQueryEngineAdapter
1515
from sqlmesh.core.engine_adapter.bigquery import select_partitions_expr
16-
from sqlmesh.core.engine_adapter.mixins import TableAlterDropClusterKeyOperation
16+
from sqlmesh.core.engine_adapter.mixins import (
17+
TableAlterClusterByOperation,
18+
TableAlterDropClusterKeyOperation,
19+
)
1720
from sqlmesh.core.engine_adapter.shared import DataObject, DataObjectType
1821
from sqlmesh.core.schema_diff import TableAlterDropColumnOperation
1922
from sqlmesh.core.node import IntervalUnit
@@ -1487,3 +1490,53 @@ def test_bigquery_no_column_change_clustering_drop_only(
14871490

14881491
assert len(operations) == 1
14891492
assert isinstance(operations[0], TableAlterDropClusterKeyOperation)
1493+
1494+
1495+
def test_unchanged_clustering_key_is_not_altered_when_column_added(
1496+
adapter: BigQueryEngineAdapter, mocker: MockerFixture
1497+
):
1498+
# Adding a column to a clustered table must not emit a clustering change when the key
1499+
# itself is unchanged. BigQuery applies a new key by rewriting the clustered columns.
1500+
current_columns = {"c1": exp.DataType.build("INT64", dialect="bigquery")}
1501+
target_columns = {
1502+
**current_columns,
1503+
"c2": exp.DataType.build("INT64", dialect="bigquery"),
1504+
}
1505+
1506+
def columns(table_name: str, include_pseudo_columns: bool = False) -> t.Dict[str, exp.DataType]:
1507+
if exp.to_table(table_name).name == "current_table":
1508+
return current_columns
1509+
return target_columns
1510+
1511+
mocker.patch.object(adapter, "columns", side_effect=columns)
1512+
1513+
def get_data_objects(
1514+
schema_name: exp.Table,
1515+
object_names: t.Optional[t.Set[str]] = None,
1516+
safe_to_cache: bool = False,
1517+
) -> t.List[DataObject]:
1518+
assert object_names is not None
1519+
return [
1520+
DataObject(
1521+
schema=schema_name.db,
1522+
name=next(iter(object_names)),
1523+
type=DataObjectType.TABLE,
1524+
clustering_key="(c1)",
1525+
)
1526+
]
1527+
1528+
mocker.patch.object(adapter, "get_data_objects", side_effect=get_data_objects)
1529+
# Let a wrongly emitted clustering change surface as the column-rewrite UPDATE.
1530+
mocker.patch.object(adapter, "_get_table", return_value=mocker.Mock())
1531+
mocker.patch.object(adapter, "_db_call")
1532+
1533+
operations = adapter.get_alter_operations(
1534+
"test_schema.current_table", "test_schema.target_table"
1535+
)
1536+
assert not any(isinstance(operation, TableAlterClusterByOperation) for operation in operations)
1537+
1538+
adapter.alter_table(operations)
1539+
1540+
assert _to_sql_calls(adapter) == [
1541+
"ALTER TABLE `test_schema`.`current_table` ADD COLUMN `c2` INT64"
1542+
]

0 commit comments

Comments
 (0)