Data Manipulation Language: reads, writes, updates, deletes, merges. SQE adds Iceberg time-travel clauses on SELECT, an Iceberg-aware MERGE INTO, and a SET WRITE_BRANCH shortcut for routing writes to a named branch.
Read a specific snapshot (snapshot id, branch name, or tag name).
SELECT ... FROM t FOR SYSTEM_TIME AS OF timestamp
datafusion-builtin (sqlparser native)
Read snapshot active at the given timestamp.
SELECT ... FROM t FOR INCREMENTAL BETWEEN SNAPSHOT s1 AND SNAPSHOT s2
sqe-sql/time_travel.rs
SQE-specific. Returns rows added between two snapshots; useful for CDC-style processing.
-- By snapshot id
SELECT * FROM events FOR VERSION AS OF 8472810294;
-- By branch
SELECT * FROM events FOR VERSION AS OF 'dev_2026_05';
-- By tag
SELECT * FROM events FOR VERSION AS OF 'release_2026_q2';
-- By timestamp
SELECT * FROM events FOR SYSTEM_TIME AS OF TIMESTAMP '2026-04-01 00:00:00';
-- Incremental between two snapshots
SELECT * FROM events
FOR INCREMENTAL BETWEEN SNAPSHOT 1234 AND SNAPSHOT 5678;
MERGE INTO t USING s ON cond WHEN MATCHED THEN UPDATE SET ... WHEN NOT MATCHED THEN INSERT (...) VALUES (...)
sqlparser-rs + sqe-coordinator
CoW or MoR. Multiple WHEN MATCHED branches with extra predicates allowed.
MERGE INTO t USING s ON cond WHEN MATCHED THEN DELETE
sqlparser-rs + sqe-coordinator
Delete matched rows.
MERGE INTO t USING s ON cond WHEN MATCHED AND pred THEN UPDATE SET ... WHEN MATCHED THEN DELETE
sqlparser-rs + sqe-coordinator
Conditional MATCHED branches.
MERGE INTO orders t
USING staging.order_updates s
ON t.id = s.id
WHEN MATCHED AND s.status = 'cancelled' THEN DELETE
WHEN MATCHED THEN UPDATE SET status = s.status, updated_at = s.updated_at
WHEN NOT MATCHED THEN INSERT (id, status, created_at) VALUES (s.id, s.status, s.created_at);
COPY (SELECT ...) TO 'path' (FORMAT csv|json|parquet)
datafusion-builtin
Write query result to a file.
-
yes
-
yes
COPY t TO 'path' (FORMAT parquet)
datafusion-builtin
Write whole table.
-
yes
-
yes
COPY (SELECT ...) TO 'path' (FORMAT parquet, PARTITION_BY 'col1, col2')
datafusion-builtin
Hive-style partitioned output.
-
yes
-
yes
COPY (SELECT * FROM events WHERE occurred_at >= DATE '2026-05-01')
TO '/tmp/may_events.parquet'
(FORMAT parquet);
COPY events TO 's3://export/events.csv'
(FORMAT csv, COMPRESSION gzip, HEADER true);
Iceberg branches let you isolate writes from the production snapshot. SQE exposes branch routing as a session variable.
Statement
Notes
SET WRITE_BRANCH = 'name'
Subsequent INSERT / UPDATE / DELETE / MERGE writes go to the named branch.
SET WRITE_BRANCH = DEFAULT
Reset to the default (main) branch.
SET WRITE_BRANCH = NULL
Same as DEFAULT.
ALTER TABLE events CREATE BRANCH staging;
SET WRITE_BRANCH = 'staging';
INSERT INTO events SELECT * FROM new_data;
-- ^ writes to the 'staging' branch only
SELECT count(*) FROM events FOR VERSION AS OF 'staging';
-- ^ reads from staging branch
SET WRITE_BRANCH = DEFAULT;