Skip to content

refactor(datagrid): restore reloadVersion external-only semantic + invalidate schema cache#1289

Merged
datlechin merged 2 commits into
mainfrom
refactor/reload-version-and-schema-cache
May 16, 2026
Merged

refactor(datagrid): restore reloadVersion external-only semantic + invalidate schema cache#1289
datlechin merged 2 commits into
mainfrom
refactor/reload-version-and-schema-cache

Conversation

@datlechin
Copy link
Copy Markdown
Member

Summary

Two follow-ups from PR #1288 (fix #1281). Independent of #1288 — lands cleanly before or after.

reloadVersion was overloaded → cell-edit perf regression after #1288

ChangeManaging.reloadVersion was originally a signal for "external data identity reloaded; column widths may need recalc". Two grid delegates explicitly document this and route cell-edit visual updates through their own reloadAllVisibleRows() path (StructureGridDelegate.swift:316-319, CreateTableGridDelegate.swift:20-24). The architects clearly knew the snapshot wouldn't catch cell-content updates.

Over time, 26+ bump sites accumulated — most on internal mutations (cell edit, add row, undo, redo). They were no-ops because nothing observed the counter. When PR #1288 wired the counter into DataGridUpdateSnapshot to fix the external-refresh bug, those internal bumps started cascading into full tableView.reloadData() calls on top of the precise reloads already issued by CellCommit. On Data tab, Tab-through editing a wide table now stacks one full reload per cell.

This PR restores the original semantic by removing 22 bumps from internal mutation paths:

  • StructureChangeManager.swift: keeps bumps at loadSchema (line 107) and discardChanges (line 513). Removes 13 bumps from add/edit/delete/undo of column, index, FK.
  • DataChangeManager.swift: keeps bumps at clearChanges (82), configureForTable (107), discardChanges (470). Removes 9 bumps from recordCellChange, recordRowDeletion, recordRowInsertion, undo handlers.

Targeted reload paths already cover every removed site:

  • Cell edits → DataGridView+CellCommit.swift:46-59 (precise reloadData(forRowIndexes:columnIndexes:))
  • Soft deletes (row stays in array with deleted marker) → StructureGridDelegate.dataGridDeleteRowsreloadAllVisibleRows() (already documented at line 169-172)
  • Undo/redo → dataGridUndo/dataGridRedoreloadAllVisibleRows()
  • Add/remove from working arrays → SwiftUI @Observable re-eval → snapshot rowDisplayCount changes → existing structureChanged path → full reload

Autocomplete shows stale columns after external rename

SQLSchemaProvider.columnCache (LRU keyed by lowercase table name) is only invalidated on database switch via MainContentCoordinator.reconcilePostSchemaLoad(). Nothing clears it on Refresh, so after external ALTER TABLE RENAME COLUMN + ⌘R, query-editor autocomplete keeps suggesting the old column name.

Fix:

  • New SQLSchemaProvider.clearColumnCache() actor method (cancels eager load, clears cache + access order, restarts eager load if a driver is cached).
  • SchemaProviderRegistry subscribes to AppCommands.shared.refreshData in init(). On signal, routes through invalidateColumnCache(for connectionId: UUID?). Scoped to one connection if signal carries an ID; otherwise invalidates every loaded provider. Matches the existing refreshData convention used by ImportDialog (scoped) vs toolbar refresh (broad).

Test plan

  • Bug Structure Tab Does Not Refresh After DDL Changes in ClickHouse #1281 still fixed after both PRs land. External ALTER TABLE RENAME COLUMN a TO b → ⌘R on Structure tab → Columns sub-tab shows b immediately.
  • Data tab perf restored. Open a wide table (10+ cols, 1000+ rows). Tab through editing 10 cells. Should feel instant. Compare to a build with PR fix(structure): refresh picks up external schema changes (#1281) #1288 alone — perceptible improvement.
  • Structure cell edit still works. Edit column name in Structure → Columns grid → Tab away → cell shows new name.
  • Undo still re-renders. Edit cell, ⌘Z → cell reverts visibly.
  • Soft delete tint paints. Select a row in Structure → Columns → Delete → row gets strikethrough/red tint immediately.
  • Add row. New Column button → empty row appears, gets focus.
  • Discard changes. Edit 3 cells in Data tab → click Discard → all three revert visibly.
  • Autocomplete fix. Open query editor, type SELECT * FROM test_refresh WHERE, trigger autocomplete on column prefix → sees current name. Externally rename column → ⌘R → trigger autocomplete on same prefix → sees new name.
  • Scoped invalidation. Open two connections. Import to connection A (sends scoped refreshData). Connection B's autocomplete cache stays warm.

@datlechin datlechin merged commit c1b2017 into main May 16, 2026
2 checks passed
@datlechin datlechin deleted the refactor/reload-version-and-schema-cache branch May 16, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structure Tab Does Not Refresh After DDL Changes in ClickHouse

1 participant