Skip to content

Commit 316b3e2

Browse files
committed
fix(db2): _truncate_table — use DELETE FROM instead of TRUNCATE IMMEDIATE
TRUNCATE TABLE ... IMMEDIATE cannot run inside an open unit of work (SQL0428N). ibm_db_dbi forces AUTOCOMMIT_OFF on all connections, which means _prepare_helper() inside execute() implicitly opens a unit of work before the statement runs — making the IMMEDIATE constraint impossible to satisfy in practice. DELETE FROM has no such restriction and is rollback-safe, matching the established pattern in trino.py and risingwave.py.
1 parent 275f99c commit 316b3e2

1 file changed

Lines changed: 7 additions & 13 deletions

File tree

  • sqlmesh/core/engine_adapter

sqlmesh/core/engine_adapter/db2.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -733,19 +733,13 @@ def _create_table_like(
733733
)
734734

735735
def _truncate_table(self, table_name: TableName) -> None:
736-
# Db2's TRUNCATE TABLE ... IMMEDIATE commits instantly and cannot be
737-
# rolled back (SQL0428N if inside an open transaction). When a
738-
# transaction is already active, use DELETE which participates in the
739-
# transaction normally and can be rolled back. When no transaction is
740-
# active, use TRUNCATE TABLE ... IMMEDIATE — the IMMEDIATE keyword is
741-
# mandatory in Db2 syntax (SQL0104N without it).
742-
if self._connection_pool.is_transaction_active:
743-
self.execute(exp.Delete(this=exp.to_table(table_name)))
744-
else:
745-
table = exp.to_table(table_name)
746-
self.execute(
747-
f"TRUNCATE TABLE {table.sql(dialect=self.dialect, identify=True)} IMMEDIATE"
748-
)
736+
# Db2's TRUNCATE TABLE ... IMMEDIATE requires being the first statement
737+
# in a unit of work (SQL0428N). ibm_db_dbi forces AUTOCOMMIT_OFF on all
738+
# connections, so _prepare_helper() inside execute() implicitly opens a
739+
# unit of work before TRUNCATE runs — making it impossible to satisfy
740+
# that constraint. DELETE FROM has no such restriction and is
741+
# rollback-safe, matching the pattern used by trino.py and risingwave.py.
742+
self.execute(exp.Delete(this=exp.to_table(table_name)))
749743

750744
def _convert_df_datetime(self, df: DF, columns_to_types: t.Dict[str, exp.DataType]) -> None:
751745
"""

0 commit comments

Comments
 (0)