Skip to content

Commit c566aaa

Browse files
committed
fix: avoid stale PostgreSQL catalog cleanup
1 parent 6d7e3e2 commit c566aaa

2 files changed

Lines changed: 40 additions & 9 deletions

File tree

‎src/openstatspec/sql/wide.py‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,11 @@ def _compensate_catalog_initialization(
15501550
))
15511551

15521552

1553+
def _requires_compensating_catalog_cleanup(profile_name: str) -> bool:
1554+
"""Only PostgreSQL rolls back catalog DDL without stale compensation."""
1555+
return profile_name != "postgresql"
1556+
1557+
15531558
def _catalog_residual_inventory(
15541559
engine: Any, *, before_tables: set[str],
15551560
before_columns: Mapping[str, set[str]],
@@ -1709,14 +1714,18 @@ def initialize_wide_catalog(
17091714
pre_dolt_state, post_dolt_state, phase="catalog initialization",
17101715
)
17111716
except Exception as install_error:
1712-
try:
1713-
with connection.begin():
1714-
_compensate_catalog_initialization(
1715-
connection, metadata=metadata, before_tables=before_tables,
1716-
before_columns=before_columns, normative=normative,
1717-
legacy=legacy,
1718-
)
1719-
except Exception as cleanup_error:
1717+
cleanup_error = None
1718+
if _requires_compensating_catalog_cleanup(profile.name):
1719+
try:
1720+
with connection.begin():
1721+
_compensate_catalog_initialization(
1722+
connection, metadata=metadata, before_tables=before_tables,
1723+
before_columns=before_columns, normative=normative,
1724+
legacy=legacy,
1725+
)
1726+
except Exception as error:
1727+
cleanup_error = error
1728+
if cleanup_error is not None:
17201729
inventory = _catalog_residual_inventory(
17211730
engine, before_tables=before_tables, before_columns=before_columns,
17221731
)

‎tests/test_catalog_lifecycle.py‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import openstatspec
88
import openstatspec.sql.wide as wide
99
from openstatspec.core import UnsupportedOperationError
10-
from openstatspec.sql.profiles import MYSQL, TargetCapabilityExceededError, preflight
10+
from openstatspec.sql.profiles import (
11+
MYSQL, POSTGRESQL, TargetCapabilityExceededError, preflight,
12+
)
1113
from openstatspec.sql.wide import (
1214
ImportRecoveryError,
1315
_bounded_batches,
@@ -514,3 +516,23 @@ def invalidate(self):
514516
"commit",
515517
]
516518

519+
def test_postgresql_initializer_relies_on_transaction_rollback(tmp_path, monkeypatch):
520+
path = tmp_path / "postgresql-rollback.sqlite"
521+
522+
def fail_migration(*_args, **_kwargs):
523+
raise RuntimeError("injected catalog migration failure")
524+
525+
def compensation_must_not_run(*_args, **_kwargs):
526+
raise AssertionError("PostgreSQL must not use stale DDL compensation")
527+
528+
monkeypatch.setattr(
529+
wide, "effective_profile", lambda _url, **_kwargs: (POSTGRESQL, {}),
530+
)
531+
monkeypatch.setattr(wide, "_migrate_catalog_columns", fail_migration)
532+
monkeypatch.setattr(
533+
wide, "_compensate_catalog_initialization", compensation_must_not_run,
534+
)
535+
536+
with pytest.raises(RuntimeError, match="injected catalog migration failure"):
537+
openstatspec.initialize_catalog(database_url=f"sqlite:///{path}")
538+

0 commit comments

Comments
 (0)