๐Ÿ”„ Change Proposal: atomic-ctas

๐Ÿ“… Created: 2026-04-13 ๐Ÿ“‹ Schema: spec-driven ๐Ÿ› Fixes: #195 BREAKING SQL output change

๐ŸŽฏ Problem

The exasol__create_table_as macro emits two separate SQL statements:

  1. CREATE OR REPLACE TABLE ... WITH NO DATA โ€” auto-commits an empty table
  2. INSERT INTO ... โ€” populates the table

If the dbt process crashes between steps 1 and 2 (signal, network drop, OOM), the target table is left permanently empty. Downstream models silently produce zero-row results.

โœ… Solution

Replace the two-step pattern with a single atomic CREATE OR REPLACE TABLE ... AS <sql> statement. The table either has the new data or the previous version is preserved unchanged.

๐Ÿ“ฆ Capabilities

NEW atomic-ctas

Guarantees create_table_as is atomic โ€” populated with data or previous version preserved

MODIFIED relation-management

get_replace_table_sql now produces single atomic CTAS via delegation

โš–๏ธ Key Design Decisions

D1: Single atomic CTAS (non-contract)
CREATE OR REPLACE TABLE t AS <sql> DISTRIBUTE BY ... PARTITION BY ... โ€” one statement, inline distribution. If SELECT fails, existing table is preserved.
D2: CTAS + ALTER CONSTRAINT (contract path)
Exasol cannot combine column defs with AS subquery. Solution: atomic CTAS first, then ALTER TABLE ADD CONSTRAINT โ€” safe because data is guaranteed present.
D3: PK via ALTER TABLE (not inline)
Primary keys applied after data load via ALTER TABLE ADD CONSTRAINT ... PRIMARY KEY (...). Actually safer โ€” PK validated against real data.
D4: Macro restructuring
add_constraints split into inline clauses (DISTRIBUTE/PARTITION) and post-creation ALTERs (PK). |SEPARATEMEPLEASE| splitter retained only for ALTER statements.

โš ๏ธ Risks & Trade-offs

Multi-node cluster reshuffling
Contract + distribute_by_config: ALTERs post-CTAS could trigger reshuffling. Mitigated: DISTRIBUTE BY is inline in CTAS even for contract path โ€” only PK needs ALTER.
NOT NULL timing change
NOT NULL now applied after data load via ALTER TABLE MODIFY COLUMN ... NOT NULL. If data has NULLs, ALTER fails. Actually correct behavior โ€” old pattern never validated against data.
Test fixture updates needed
exasol_expected_sql in constraint test fixtures hardcodes old pattern. Test-only change.
SQL output change BREAKING
Users/tools parsing emitted SQL will see different pattern. This is a bugfix โ€” new pattern is strictly safer.

๐Ÿ’ฅ Impact

Macros

  • adapters.sql โ€” exasol__create_table_as
  • create_table_helpers.sql โ€” add_constraints, partition_by_conf, distribute_by_conf

Materializations

  • table.sql, incremental.sql, snapshot.sql
  • All call create_table_as โ€” fix applies transparently

Tests

  • constraints/fixtures.py โ€” expected SQL update
  • Contract enforcement, table, incremental, snapshot tests

No Changes To

  • Public API / dependencies
  • connections.py splitter mechanism
  • View materializations

๐Ÿ“‹ Tasks (5 groups, 14 items)

1. Restructure create_table_helpers.sql macros
โ˜ 1.1 Refactor partition_by_conf โ€” inline CTAS clause (no trailing semicolon)
โ˜ 1.2 Refactor distribute_by_conf โ€” inline CTAS clause
โ˜ 1.3 Refactor add_constraints โ€” post-creation ALTERs only (remove PARTITION/DISTRIBUTE)
2. Rewrite exasol__create_table_as macro
โ˜ 2.1 Non-contract path: single atomic CTAS + inline DISTRIBUTE/PARTITION + post ALTERs
โ˜ 2.2 Contract-enforced path: atomic CTAS + ALTER for NOT NULL, PK, FK
โ˜ 2.3 Remove all WITH NO DATA and INSERT INTO patterns
โ˜ 2.4 Remove temporary parameter handling distinction
3. Update contract test fixtures
โ˜ 3.1 Update exasol_expected_sql to match new pattern
โ˜ 3.2 Verify contract enforcement tests pass
4. Run existing test suites
โ˜ 4.1 Unit tests
โ˜ 4.2 Contract enforcement functional tests
โ˜ 4.3 Table materialization tests
โ˜ 4.4 Incremental materialization tests
โ˜ 4.5 Snapshot materialization tests
5. Add atomicity verification test
โ˜ 5.1 Test that rendered SQL has single CTAS (no WITH NO DATA + INSERT)

๐Ÿ“„ Specs Summary

New Spec: atomic-ctas (6 requirements, 11 scenarios)

Modified Spec: relation-management (1 scenario changed)


Generated from openspec/changes/atomic-ctas/ ยท dbt-exasol ยท 2026-04-13