|
18 | 18 | from collections.abc import Generator |
19 | 19 | from pathlib import Path |
20 | 20 | from typing import cast |
| 21 | +from unittest.mock import patch |
21 | 22 |
|
22 | 23 | import pytest |
23 | 24 | from sqlalchemy import Engine, create_engine, inspect, text |
@@ -395,21 +396,27 @@ def test_commit_table_ignores_view_rows(warehouse: Path) -> None: |
395 | 396 | ) |
396 | 397 | catalog.create_namespace("ns") |
397 | 398 | schema = Schema(NestedField(1, "id", StringType(), required=True)) |
398 | | - tbl = catalog.create_table(("ns", "a_view"), schema=schema) |
| 399 | + tbl = catalog.create_table(("ns", "a_table"), schema=schema) |
399 | 400 |
|
400 | | - # Tamper the table row into a VIEW (simulating external writer) |
| 401 | + tx = tbl.transaction() |
| 402 | + tx.set_properties({"key": "val"}) |
| 403 | + updates = tuple(tx._updates) |
| 404 | + requirements = tuple(tx._requirements) |
| 405 | + |
| 406 | + # Tamper the table row into a VIEW (simulating concurrent change to VIEW after load_table) |
401 | 407 | with catalog.engine.connect() as conn: |
402 | | - conn.execute(text("UPDATE iceberg_tables SET iceberg_type = 'VIEW' WHERE table_name = 'a_view'")) |
| 408 | + conn.execute(text("UPDATE iceberg_tables SET iceberg_type = 'VIEW' WHERE table_name = 'a_table'")) |
403 | 409 | conn.commit() |
404 | 410 |
|
405 | | - # Attempting to commit table updates must fail and not modify the VIEW row |
406 | | - with pytest.raises(CommitFailedException): |
407 | | - with tbl.update_schema() as update: |
408 | | - update.add_column("new_col", StringType()) |
| 411 | + # When load_table returns the pre-loaded table, commit_table must fail in the SQL UPDATE |
| 412 | + # due to type_filter and not overwrite the VIEW row. |
| 413 | + with patch.object(catalog, "load_table", return_value=tbl): |
| 414 | + with pytest.raises(CommitFailedException, match="Table has been updated by another process: ns.a_table"): |
| 415 | + catalog.commit_table(tbl, requirements=requirements, updates=updates) |
409 | 416 |
|
410 | 417 | # The view row must remain untouched with iceberg_type == 'VIEW' |
411 | 418 | with catalog.engine.connect() as conn: |
412 | | - row = conn.execute(text("SELECT iceberg_type FROM iceberg_tables WHERE table_name = 'a_view'")).fetchone() |
| 419 | + row = conn.execute(text("SELECT iceberg_type FROM iceberg_tables WHERE table_name = 'a_table'")).fetchone() |
413 | 420 | assert row is not None |
414 | 421 | assert row[0] == "VIEW" |
415 | 422 |
|
|
0 commit comments