This example demonstrates DDL (Data Definition Language) support in an Airport Flight server, enabling schema and table management via SQL statements like CREATE SCHEMA, DROP SCHEMA, CREATE TABLE, ALTER TABLE, etc.
- Schema Management: CREATE SCHEMA, DROP SCHEMA
- Table Management: CREATE TABLE, DROP TABLE, RENAME TABLE
- Column Operations: ADD COLUMN, DROP COLUMN, RENAME COLUMN
- CREATE TABLE AS SELECT: Copy data from one table to another
- Go 1.25+
- DuckDB 1.4+ (for client testing)
- Airport extension for DuckDB
Start the DDL-enabled Flight server:
go run main.goThe server will start on localhost:50051 and output:
Airport DDL server listening on :50051
Example catalog structure:
- Schema: data
- Table: sample (id INTEGER, name VARCHAR)
Test with DuckDB CLI:
ATTACH '' AS demo (TYPE airport, LOCATION 'grpc://localhost:50051');
Start DuckDB and connect to the server:
duckdb-- Install and load Airport extension
INSTALL airport FROM community;
LOAD airport;
-- Connect to the DDL server
ATTACH '' AS demo (TYPE airport, LOCATION 'grpc://localhost:50051');
-- View existing schema and table
SELECT * FROM demo.data.sample;-- Create a new schema
CREATE SCHEMA demo.analytics;
-- Drop a schema (must be empty)
DROP SCHEMA demo.analytics;
-- Create schema if not exists
CREATE SCHEMA IF NOT EXISTS demo.reports;-- Create a new table
CREATE TABLE demo.data.users (
id INTEGER,
name VARCHAR,
email VARCHAR
);
-- View the table structure
DESCRIBE demo.data.users;
-- Drop a table
DROP TABLE demo.data.users;
-- Drop table if exists
DROP TABLE IF EXISTS demo.data.users;-- Create a table to alter
CREATE TABLE demo.data.products (
id INTEGER,
name VARCHAR
);
-- Add a new column
ALTER TABLE demo.data.products ADD COLUMN price DOUBLE;
-- Rename a column
ALTER TABLE demo.data.products RENAME COLUMN name TO product_name;
-- Drop a column
ALTER TABLE demo.data.products DROP COLUMN price;
-- View changes
DESCRIBE demo.data.products;-- Create source table
CREATE TABLE demo.data.source (id INTEGER, value VARCHAR);
-- Insert data (requires InsertableTable implementation)
INSERT INTO demo.data.source VALUES (1, 'one'), (2, 'two');
-- Create table from query
CREATE TABLE demo.data.backup AS SELECT * FROM demo.data.source;
-- Verify data was copied
SELECT * FROM demo.data.backup;This example implements three interfaces from the catalog package:
type DynamicCatalog interface {
Catalog
CreateSchema(ctx context.Context, name string, opts CreateSchemaOptions) (Schema, error)
DropSchema(ctx context.Context, name string, opts DropSchemaOptions) error
}type DynamicSchema interface {
Schema
CreateTable(ctx context.Context, name string, schema *arrow.Schema, opts CreateTableOptions) (Table, error)
DropTable(ctx context.Context, name string, opts DropTableOptions) error
RenameTable(ctx context.Context, oldName, newName string, opts RenameTableOptions) error
}type DynamicTable interface {
Table
AddColumn(ctx context.Context, columnSchema *arrow.Schema, opts AddColumnOptions) error
RemoveColumn(ctx context.Context, name string, opts RemoveColumnOptions) error
RenameColumn(ctx context.Context, oldName, newName string, opts RenameColumnOptions) error
// ... additional methods for constraints and struct fields
}The server returns appropriate errors for common DDL failures:
catalog.ErrAlreadyExists- When creating a schema/table/column that already existscatalog.ErrNotFound- When dropping/altering a non-existent objectcatalog.ErrSchemaNotEmpty- When dropping a schema that contains tables
- Try the dml example for INSERT/UPDATE/DELETE operations
- Try the basic example for simple read-only tables
- Read the main README for more advanced usage