Repository navigation
ClickHouse: Import as Update and Insert or Update fail on the first matched row #3765
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't workingplatform-macosAbout the macOS appAbout the macOS app
Description
What happened?
Left open by #3743 ("Not in this PR"). Importing rows into a ClickHouse table as Update or Insert or Update stops at the first row whose key is already in the table. ClickHouse refuses the plain UPDATE ... SET the import sends, and the import shows the server's syntax error.
What the code does today:
- The sheet offers every mode for every engine (
apple/TablePro/Views/Import/RowImportSheet.swift:329). The only engine check is whether the engine has a SQL dialect (apple/TablePro/Core/Plugins/ImportDataSinkAdapter.swift:75). - Match on offers ClickHouse's primary key, since the plugin flags those columns as primary key (
apple/Plugins/ClickHouseDriverPlugin/ClickHousePluginDriver+Schema.swift:97,:157). - Per run of rows, one
SELECT <pos>, COUNT(*) ... UNION ALLcounts the matches (apple/TablePro/Core/ChangeTracking/SQLStatementGenerator.swift:277). A count of 1 sendsUPDATE <table> SET <mapped> WHERE <key>(SQLStatementGenerator.swift:293, sent atImportDataSinkAdapter.swift:424). - ClickHouse changes rows with
ALTER TABLE ... UPDATE, a mutation. The plugin already writes that form for grid edits (apple/Plugins/ClickHouseDriverPlugin/ClickHousePlugin.swift:467). - Lightweight
UPDATE ... SETworks only on a MergeTree-family table with theenable_block_number_columnandenable_block_offset_columntable settings (ClickHouse docs, UPDATE statement). Any other table, or a server without lightweight updates, refuses it. - Data Compare sync writes the same
UPDATE ... SET(apple/TablePro/Core/Compare/DataSyncScriptBuilder.swift:151), and ClickHouse declares.dataCompare(ClickHousePlugin.swift:211).
Steps to reproduce
- On a ClickHouse connection, create
CREATE TABLE t (id UInt32, name String) ENGINE = MergeTree ORDER BY idand insert(1, 'a'). - Import a CSV with the header
id,nameand the row1,bintot. - Set Import as to Update, Match on to the primary key, and import.
Expected behavior
One of these, not the server's error:
- Hide the modes. Update and Insert or Update are not offered for an engine that cannot run a keyed
UPDATE. The engine says so through a new capability inapple/Plugins/TableProPluginKit/PluginCapabilities.swift(the last bit used is 18). Data Compare sync reads the same capability before it writes an UPDATE script for that target. A new bit is a PluginKit ABI change (.claude/rules/plugin-system.md, ABI). - Write ClickHouse's own form. The plugin builds the keyed update as
ALTER TABLE ... UPDATE ... WHERE <key>. A mutation applies in the background unless asked to wait, so the import must wait for it before the next count. The iOS app already addsSETTINGS mutations_sync = 1to its ClickHouse row writes (apple/TableProMobile/TableProMobile/Platform/IOSDriverFactory.swift:190).
Done when: on ClickHouse, Update and Insert or Update either are not offered or update the matched rows, and a test covers that choice for import and for Data Compare sync.
Database type
ClickHouse
TablePro version
Not released. #3743 merged to main on 2026-10-21, after 0.83.0-beta.1.
Platform
macOS
OS version & hardware
No response
Screenshots / Logs
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingplatform-macosAbout the macOS appAbout the macOS app
Activity