Atlas now merges multiple ALTER TABLE operations on the same table into a single statement, improving atomicity and removing redundant SETTINGS alter_sync in non-cluster mode.
When you change multiple columns, indexes, or table attributes in a single schema apply, Atlas previously generated a separate ALTER TABLE statement for each one. If one of them failed mid-way, the table could end up in a partially-migrated state that required manual cleanup.
Starting with this release, Atlas merges all compatible operations into a single ALTER TABLE statement. ClickHouse executes all clauses as one mutation: either everything applies or nothing does.
Before and After: Mixed Operations
Suppose you add a column, change a column type, and recreate an index in the same schema apply. Previously this produced four round-trips to ClickHouse:
-- 4 separate statements (before)ALTER TABLE `orders` ADD COLUMN `discount` Decimal(5, 2) DEFAULT 0.00;ALTER TABLE `orders` MODIFY COLUMN `total` Decimal(12, 2) DEFAULT 0.00;ALTER TABLE `orders` DROP INDEX `idx_status`;ALTER TABLE `orders` ADD INDEX `idx_status` (`status`) TYPE set(100);
Atlas now produces a single statement that applies all changes at once:
-- 1 merged statement (after)ALTER TABLE `orders`ADD COLUMN `discount` Decimal(5, 2) DEFAULT 0.00,MODIFY COLUMN `total` Decimal(12, 2) DEFAULT 0.00,DROP INDEX `idx_status`,ADD INDEX `idx_status` (`status`) TYPE set(100);
Before and After: Column Attributes
Adding a compression codec, setting a TTL, updating a column comment, and changing a default on the same table are also combined into one statement:
-- 4 separate statements (before)ALTER TABLE `users` MODIFY COLUMN `email` String CODEC(ZSTD(3));ALTER TABLE `users` MODIFY COLUMN `email` String TTL created_at + toIntervalDay(365);ALTER TABLE `users` COMMENT COLUMN `email` 'user primary email, PII';ALTER TABLE `users` MODIFY COLUMN `updated_at` DateTime64(3) DEFAULT now64();
-- 1 merged statement (after)ALTER TABLE `users`MODIFY COLUMN `email` String CODEC(ZSTD(3)),MODIFY COLUMN `email` String TTL created_at + toIntervalDay(365),COMMENT COLUMN `email` 'user primary email, PII',MODIFY COLUMN `updated_at` DateTime64(3) DEFAULT now64();
Cluster Mode
In cluster mode, Atlas appends SETTINGS alter_sync = 2 once at the end of the merged statement so the coordinator waits for all replicas before returning.
In non-cluster (single-node) mode, the previously emitted SETTINGS alter_sync = 1 is dropped entirely because 1 is already the ClickHouse default. This makes generated migrations shorter and easier to read.
-- Cluster mode: alter_sync is appended once at the endALTER TABLE `events` ON CLUSTER `{cluster}`ADD COLUMN `region` LowCardinality(String) DEFAULT 'us-east-1',DROP INDEX `idx_session`,ADD INDEX `idx_session` (`session_id`) TYPE bloom_filter(0.01)SETTINGS alter_sync = 2;
What is Not Merged
A few operations cannot be combined with others and will still get their own statement:
- MODIFY SETTING and RESET SETTING (ClickHouse requires these to be standalone)
- Column recreations where the column must be dropped and re-added because the type change cannot be done in place
After adding an index or projection, Atlas still emits a separate MATERIALIZE INDEX / MATERIALIZE PROJECTION statement to back-fill existing data. This cannot be part of the same ALTER TABLE because ClickHouse requires the index/projection to exist before materializing it.