Skip to content

feat(api): first-class multi-statement DDL/migration application (provision a tenant without direct ClickHouse access) #361

Description

@EricAndrechek

Summary

There's no reliable first-class way to apply a multi-statement DDL migration file (a set of CREATE TABLE / CREATE MATERIALIZED VIEW / seed statements) through the WaveHouse API. For a hosted tenant whose operator only has the WaveHouse API (no direct clickhouse-client), this blocks schema provisioning.

Context

Per #158, all non-insert mutations (incl. DDL) are correctly routed through POST /v1/query under an admin/service role — good. But /v1/query forwards the body to ClickHouse's HTTP interface, which rejects multi-statement bodies unless the upstream CH has multi-query enabled:

POST /v1/query   body: "CREATE TABLE a (...) ENGINE=...; CREATE TABLE b (...) ENGINE=...;"
→ Code: 62 ... Multi-statements are not allowed

The comment in internal/api/query.go already acknowledges this ("multi-statement input works when the upstream ClickHouse has multi-query enabled") — but that's a CH-side setting the tenant operator may not control, and it isn't surfaced in the provisioning path. Real migration files are multi-statement and contain ; inside comments/strings, so a naive client split is also unsafe.

Impact

To provision a tenant's schema today you need direct clickhouse-client --multiquery access, or you split every migration file into individual statements yourself. A managed "WaveHouse Cloud" tenant with only API access has no clean path to apply its schema.

Suggested

One or more of:

  • A dedicated POST /v1/admin/migrate (or a flag on /v1/query) that accepts a multi-statement body/file and executes statements sequentially, server-side, with a comment/string-aware splitter (skipping comment-only trailing chunks) and a per-statement result — friendly to idempotent IF NOT EXISTS DDL.
  • Or, at minimum, document the required CH-side multi-query setting + the recommended provisioning path explicitly.

Found provisioning a WaveHouse-backed tenant for the SCC 2026 tracker pilot against a self-hosted WaveHouse (local emulation of WaveHouse Cloud). Worked around it with a comment/string-aware statement splitter in our tenant apply.sh — happy to contribute it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/apiHTTP handlers, routing, middlewareenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions