- 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 虚拟连接
86 lines
3.1 KiB
Go
86 lines
3.1 KiB
Go
//go:build sqlite_vtable || vtable
|
|
|
|
package vtab
|
|
|
|
import "git.fsdpf.net/go/db/exp"
|
|
|
|
// FilterValue 是一个 WHERE 约束值,包含实际值和操作符类型。
|
|
// 用于 BestIndex/Filter 阶段向上层传递结构化的过滤条件。
|
|
type FilterValue struct {
|
|
Value any
|
|
Op exp.BooleanOperation
|
|
}
|
|
|
|
// Module 是虚拟表工厂,每个数据库连接各调用一次。
|
|
type Module interface {
|
|
// Create 在 CREATE VIRTUAL TABLE 时调用。
|
|
// args 是 CREATE VIRTUAL TABLE 语句括号内的参数列表(已去除引号):
|
|
// args[0] = 模块名, args[1] = 数据库名, args[2] = 表名, args[3..] = 用户参数
|
|
// declare 必须被调用以声明表结构,例如:
|
|
// declare("CREATE TABLE t(id INTEGER, name TEXT)")
|
|
Create(args []string, declare func(schema string) error) (Table, error)
|
|
|
|
// Connect 在重新连接到已有虚拟表时调用(通常与 Create 实现相同)。
|
|
Connect(args []string, declare func(schema string) error) (Table, error)
|
|
}
|
|
|
|
// Table 是虚拟表实例(只读),每个连接持有一个。
|
|
// 若需要写操作,同时实现 WritableTable 接口即可,框架会自动识别。
|
|
type Table interface {
|
|
// BestIndex 告知 SQLite 本表能处理哪些 WHERE 约束。
|
|
// 返回的 IndexOutput.Used 长度必须与传入的 constraints 长度一致。
|
|
// 简单实现:返回 Used 全为 false,让 SQLite 做全表扫描后自行过滤。
|
|
BestIndex(constraints []ConstraintInfo, orderBy []OrderByInfo) (*IndexOutput, error)
|
|
|
|
// Open 为每次查询创建一个游标实例。
|
|
Open() (Cursor, error)
|
|
|
|
// Disconnect 在连接关闭时调用,用于释放连接级资源。
|
|
Disconnect() error
|
|
|
|
// Destroy 在 DROP TABLE 时调用,用于清理持久化资源。
|
|
Destroy() error
|
|
}
|
|
|
|
// WritableTable 在 Table 基础上增加写操作支持。
|
|
// 只需让 Table 实现同时满足该接口,框架会自动启用写操作。
|
|
type WritableTable interface {
|
|
Table
|
|
|
|
// Insert 插入一行,values 顺序与 DeclareVTab 中列的顺序一致。
|
|
// 返回新行的 rowid(若表有整型主键,应返回主键值)。
|
|
Insert(values []any) (rowid int64, err error)
|
|
|
|
// Update 更新 rowid 对应的行,values 同 Insert。
|
|
Update(rowid any, values []any) error
|
|
|
|
// Delete 删除 rowid 对应的行。
|
|
Delete(rowid any) error
|
|
}
|
|
|
|
// Cursor 是行迭代器,每次查询(SELECT)创建一个独立实例。
|
|
type Cursor interface {
|
|
// Filter 开始或重置扫描。
|
|
// idxNum 来自 BestIndex 返回的 IndexOutput.IdxNum,可用于区分查询计划。
|
|
// constraints 是 BestIndex 中 Used=true 的约束,适配层已自动绑定值(ConstraintInfo.Value),
|
|
// 无需手动编解码 idxStr。
|
|
Filter(idxNum int, constraints []ConstraintInfo) error
|
|
|
|
// Next 移动到下一行。
|
|
Next() error
|
|
|
|
// EOF 返回 true 表示已无更多行。
|
|
EOF() bool
|
|
|
|
// Column 返回第 col 列的值。nil 表示 SQL NULL。
|
|
// 支持的类型:int/int32/int64、float32/float64、bool、string、[]byte。
|
|
// 其他类型会被 fmt.Sprint 转为字符串。
|
|
Column(col int) (any, error)
|
|
|
|
// Rowid 返回当前行的 rowid。
|
|
Rowid() (int64, error)
|
|
|
|
// Close 释放游标资源。
|
|
Close() error
|
|
}
|