Skip to Content
We are live but in Staging 🎉

DDL

Data-definition statements through Execute. K3 supports CREATE TABLE, CREATE TABLE AS SELECT (CTAS), ALTER TABLE ADD COLUMN, and DROP TABLE. DROP COLUMN and RENAME COLUMN are parsed but refused — see Refusals. For the RPC contract and full enum reference, see the Execute hub.

CREATE TABLE

Inline column-level or table-level PRIMARY KEYs both flow into the planner — subsequent writes get keyed routing for free.

CREATE TABLE events ( id BIGINT NOT NULL, user_id VARCHAR NOT NULL, occurred_at TIMESTAMP NOT NULL, event_type VARCHAR NOT NULL, payload JSON, PRIMARY KEY (id, user_id) ) PARTITIONED BY (event_type);

Inline-PK form:

CREATE TABLE users ( id BIGINT PRIMARY KEY, email VARCHAR NOT NULL, tier VARCHAR DEFAULT 'free' );

Response:

{ "ddl": { "op": "create_table", "targetTable": "events", "version": "0" } }

CREATE TABLE AS SELECT (CTAS)

Type inference rules: int-shaped JSON numbers → long, fractional → double, strings → string, bools → boolean. For typed migrations, declare columns explicitly via CreateTable instead.

-- Derive a click summary CREATE TABLE click_summary AS SELECT user_id, COUNT(*) AS n, MAX(occurred_at) AS last_click FROM events WHERE event_type = 'click' GROUP BY user_id;

K3’s dispatcher flow under the hood:

  1. Run the SELECT through Query — materialize rows.
  2. Infer schema from result columns (or use explicit columns if the plan has them).
  3. Create the target table.
  4. Insert the materialized rows.

Response: op: "create_table_as_select".

For structured CTAS (separate inputs for source / SQL / target / partitioning / mode), use Materialize — same underlying dispatcher, different wire shape.

ALTER TABLE ADD COLUMN

Supports multiple ADD COLUMNs in one ALTER.

ALTER TABLE events ADD COLUMN session_id VARCHAR; ALTER TABLE events ADD COLUMN device VARCHAR;

Multi-column variant:

-- Single statement with multiple ADDs (one Execute call each — multi-statement bodies are refused) ALTER TABLE events ADD COLUMN session_id VARCHAR, ADD COLUMN device VARCHAR;

Response: op: "alter_table". Existing rows get NULL for the new columns (nullable by default).

DROP COLUMN and RENAME COLUMN are parsed but refused — not implemented. For drops / renames, recreate via CTAS.

DROP TABLE [IF EXISTS]

DROP TABLE events; DROP TABLE IF EXISTS events;

Response: op: "drop_table". Permanently removes the Delta directory + sidecar.

Pipeline-generated tables (source = TABLE_SOURCE_PIPELINE_GENERATED): DROP TABLE does not cascade to the bound pipeline / auto-generated rule. Clean those up separately via the Pipelines API.

See also