Skip to content

feat(clickhouse): add ClickHouse driver with multi-database navigation#501

Open
anglinb wants to merge 1 commit intoouterbase:developfrom
anglinb:feat/clickhouse-driver
Open

feat(clickhouse): add ClickHouse driver with multi-database navigation#501
anglinb wants to merge 1 commit intoouterbase:developfrom
anglinb:feat/clickhouse-driver

Conversation

@anglinb
Copy link
Copy Markdown

@anglinb anglinb commented Apr 21, 2026

Summary

Adds first-class ClickHouse support to Outerbase Studio. Works in the browser, Cloudflare Workers, and Edge runtime via native fetch — no @clickhouse/client dependency added.

  • Driver core (src/drivers/clickhouse/): ClickHouseLikeDriver extends CommonSQLImplement; ClickHouseHttpQueryable talks to /?default_format=JSONCompact&database=X with Basic auth; type mapping peels Nullable(...) / LowCardinality(...) wrappers; flags reflect ClickHouse reality (no triggers, no INSERT RETURNING, no rowid, ALTER TABLE ... UPDATE/DELETE for mutations).
  • Multi-database sidebar: schemas() queries system.databases / system.tables / system.columns so every DB the user can see shows up grouped by database. Double-click switches current DB — the driver intercepts USE <db> and flips ?database=X on the HTTP queryable (ClickHouse HTTP is stateless, so the USE alone wouldn't persist), which means subsequent unqualified queries like SELECT * FROM events resolve against the selected DB.
  • Wiring: SupportedDialect / SupportedDriver extended; ConnectionTemplateDictionary, createLocalDriver, createOuterbaseDatabaseDriver, the workspace base page, standard-extension, resource-card utils, and new-resource-list all updated. Added a small shim in query-tab.tsx that maps "clickhouse" → "mysql" for @outerbase/sdk-transform tokenization (close syntactic match: backticks + --//* */ comments).

Test plan

  • npx tsc --noEmit — clean
  • npm run lint — clean
  • Manual smoke test against local ClickHouse (docker run -p 8123:8123 -e CLICKHOUSE_PASSWORD=... clickhouse/clickhouse-server):
    • Create local ClickHouse connection via the new-resource picker
    • Sidebar shows all non-system databases (analytics, default, logs) with their tables
    • CREATE TABLE ... ENGINE = MergeTree() ORDER BY id succeeds
    • INSERT + SELECT round-trip through the HTTP driver (types inferred correctly: UInt64 → numeric, String → text)
    • Double-click a DB in the sidebar → green dot moves → SELECT * FROM <unqualified_table> works against the newly selected DB
    • Trigger/view UI affordances correctly hidden (flags off)

Known follow-ups

  • Placeholder icon (5 bars SVG) instead of the real ClickHouse brand mark
  • ALTER TABLE ... UPDATE/DELETE is async in ClickHouse — UI doesn't currently poll system.mutations
  • Materialized views exist but aren't surfaced through DatabaseViewSchema yet

🤖 Generated with Claude Code

Adds first-class ClickHouse support to the Studio via a native-fetch HTTP
queryable so it works in the browser / Cloudflare Workers / Edge runtime
without pulling in @clickhouse/client.

Driver core (src/drivers/clickhouse/):
- ClickHouseLikeDriver extends CommonSQLImplement, uses backtick-quoted
  identifiers, maps ClickHouse types (Nullable/LowCardinality wrappers
  peeled, Array/Map/Tuple/JSON -> text)
- schemas() queries system.databases/tables/columns and groups tables by
  database so every DB the user has access to shows up in the sidebar
- updateTableData() emits INSERT, ALTER TABLE...UPDATE WHERE, and
  ALTER TABLE...DELETE WHERE (ClickHouse has no row-level UPDATE/DELETE)
- Flags reflect ClickHouse reality: no triggers, no INSERT RETURNING,
  no rowid, but supportUseStatement so the UI offers DB switching
- ClickHouseHttpQueryable POSTs to /?default_format=JSONCompact&database=X
  with Basic auth and parses meta[]/data[] into headers/rows plus query
  statistics

Multi-database sidebar switching:
- Double-click on a DB emits `USE <name>` (existing sidebar behavior for
  drivers with supportUseStatement)
- ClickHouse HTTP is stateless, so the driver intercepts USE, calls
  setDatabase() on the HTTP queryable, and returns a synthetic success.
  Subsequent unqualified queries (e.g. `SELECT * FROM events`) resolve
  against the selected database via the ?database=X URL param.

Registration points:
- SupportedDialect / SupportedDriver extended with "clickhouse"
- ConnectionTemplateDictionary, createLocalDriver, createOuterbaseDatabaseDriver,
  workspace baseId page, standard-extension, resource-card utils, and
  new-resource-list all updated
- query-tab's tokenization path gets a shim that maps "clickhouse" -> "mysql"
  since @outerbase/sdk-transform's SupportedDialect doesn't yet include it
  (ClickHouse shares MySQL's backtick + comment syntax, close enough for
  tokenization)

Known follow-ups: placeholder icon (not the real ClickHouse brand SVG),
async mutation caveat for ALTER TABLE...UPDATE/DELETE, and materialized
views aren't surfaced.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant