Files
db/schema/dialect/duckdb
what 21b80bdea4 feat: 完善扫描器、exec 及 schema 相关功能
- exec/scanner: 用 *interface{} 替换 **json.RawMessage 扫描目标,兼容 DuckDB 返回 map[string]interface{} 的场景;新增 toJSONRawMessage 转换函数
- exec/scanner: ScanVal 支持结构体指针,通过 JSON 中间层转换(DuckDB STRUCT 列)
- exec/scanner: 将 *sql.RawBytes 和 *[]byte 的处理从 ScanValContext 移入 scanner.ScanVal
- exec/query_executor: 简化 ScanValContext,移除私有 scan 方法
- exec: 补充 scanner 级别 ScanVal 测试用例
- internal/util/reflect: 重写 SafeSetVarValue,修复非指针 src 及 nil 指针字段的 panic
- internal/util/column_map: 恢复非匿名带标签结构体字段的展开逻辑
- schema: 新增 vector 列类型支持
- engine: 补充 DuckDB 相关配置
- dialect/sqlite3/vtab: 完善虚拟表适配器
- 各方言测试改用 sqlmock 虚拟连接
2026-05-20 17:52:28 +08:00
..

DuckDB Schema Dialect

DuckDB schema dialect 为 DuckDB 数据库提供了 DDL (Data Definition Language) 操作支持。

功能特性

  • 创建表 (CREATE TABLE)
  • 添加列 (ALTER TABLE ADD COLUMN)
  • 修改列 (ALTER TABLE ALTER COLUMN)
  • 删除列 (ALTER TABLE DROP COLUMN)
  • 删除表 (DROP TABLE)
  • 重命名表 (ALTER TABLE RENAME TO)
  • 表注释 (COMMENT ON TABLE)
  • 列注释 (通过 Comment 属性)
  • 自增主键 (SERIAL/BIGSERIAL)
  • 查询表是否存在
  • 获取表的列列表

支持的数据类型

Schema 类型 DuckDB 类型 说明
char CHAR(n) 固定长度字符
string VARCHAR(n) 可变长度字符串
text TEXT 长文本
integer INTEGER 整数
bigInteger BIGINT 大整数
smallInteger SMALLINT 小整数
tinyInteger TINYINT 微整数
decimal DECIMAL(m,d) 定点数
boolean BOOLEAN 布尔值
json JSON JSON 数据
binary BLOB 二进制数据
datetime TIMESTAMP 日期时间
timestamp TIMESTAMP 时间戳
date DATE 日期
time TIME 时间
uuid UUID UUID

使用示例

package main

import (
    "git.fsdpf.net/go/db/engine"
    "git.fsdpf.net/go/db/schema"

    _ "git.fsdpf.net/go/db/dialect/duckdb"
    _ "git.fsdpf.net/go/db/schema/dialect/duckdb"
    _ "github.com/marcboeker/go-duckdb"
)

func main() {
    // 创建数据库连接
    db := engine.Open(map[string]engine.DBConfig{
        "duckdb": engine.NewDBConfig("duckdb",
            engine.WithDuckDBFile("mydb.duckdb"), // 或者 "" 表示内存数据库
        ),
    }).Connection("duckdb")

    // 获取 schema 实现
    s := schema.GetSchemaDialect(db)

    // 创建表
    bp := schema.NewBlueprint("users")
    bp.Create()

    bp.BigIncrements("id").AutoIncrement().Comment("用户ID")
    bp.String("name", 50).Comment("用户名")
    bp.String("email", 100).Comment("邮箱")
    bp.Integer("age").Nullable().Comment("年龄")
    bp.Boolean("active").Default("1").Comment("是否激活")
    bp.Timestamp("created_at").UseCurrent().Comment("创建时间")
    bp.Timestamp("updated_at").UseCurrent().Comment("更新时间")

    // 编译并执行
    sqls := s.CompileCreate(bp)
    for _, sql := range sqls {
        db.Exec(sql)
    }

    // 添加新列
    bp2 := schema.NewBlueprint("users")
    bp2.String("phone", 20).Nullable().Comment("电话")

    sqls = s.CompileAdd(bp2)
    for _, sql := range sqls {
        db.Exec(sql)
    }
}

DuckDB 特性说明

自增主键

DuckDB 使用 SERIAL 类型系列实现自增:

  • SERIAL - 对应 INTEGER 自增
  • BIGSERIAL - 对应 BIGINT 自增
  • SMALLSERIAL - 对应 SMALLINT 自增
bp.BigIncrements("id").AutoIncrement()
// 生成: "id" BIGSERIAL NOT NULL PRIMARY KEY

列修改

DuckDB 的 ALTER COLUMN 操作需要分别执行:

bp.String("name", 100).Change("username")
// 生成多条 SQL:
// 1. ALTER TABLE "users" RENAME COLUMN "name" TO "username"
// 2. ALTER TABLE "users" ALTER COLUMN "username" TYPE VARCHAR(100)
// 3. ALTER TABLE "users" ALTER COLUMN "username" SET NOT NULL

表注释和列注释

DuckDB 使用标准 SQL 的 COMMENT ON 语法:

bp := schema.NewBlueprint("users")
bp.Comment = "用户表"
// 生成: COMMENT ON TABLE "users" IS '用户表'

列注释暂时不支持单独的 COMMENT ON COLUMN 语句。

标识符引用

DuckDB 使用双引号引用标识符 (PostgreSQL 风格):

CREATE TABLE "users" (
    "id" BIGSERIAL NOT NULL PRIMARY KEY,
    "name" VARCHAR(50) NOT NULL
)

测试

运行测试:

# 运行所有测试
go test ./schema/dialect/duckdb/...

# 运行示例测试
go test -v ./schema/dialect/duckdb/... -run Example

# 运行特定测试
go test -v ./schema/dialect/duckdb/... -run TestCompileCreate

注意事项

  1. DuckDB 是分析型数据库,主要用于 OLAP 场景
  2. 内存数据库性能优异,适合测试和临时数据处理
  3. 支持 PostgreSQL 兼容的大部分语法
  4. 不支持所有的 MySQL 特性 (如 UNSIGNED、AUTO_INCREMENT 等)

相关链接