查询语言
具有明确语义的
类型化 SQL 子集。
查询语言为有限的原生子集,包含解析器、名义类型检查、三值逻辑以及受 WAL 保护的 DML。它不是完整的 SQL 方言。
| 类别 | 当前支持 | 当前不支持 |
|---|---|---|
| SELECT | 限定 / 非限定列、通配投影、LIMIT | 任意表达式投影、别名输出、DISTINCT |
| FROM / JOIN | AS 与简写别名、链式 INNER JOIN … ON、自连接 | 外连接、USING、连接重排、hash / merge join |
| 谓词 | AND / OR / NOT、比较、IS NULL、括号 | IN / BETWEEN / LIKE、子查询 |
| DML | 显式列清单的单行 INSERT、UPDATE、DELETE、可选 WHERE | 默认值、RETURNING、UPSERT、多表写 |
| ORDER BY | 多源列键、ASC / DESC、NULLS FIRST / LAST | 别名、序号、任意排序表达式 |
| 聚合 | COUNT(*) / COUNT / SUM / MIN / MAX、源列 GROUP BY | HAVING、DISTINCT 聚合、分组表达式、ROLLUP |
名义类型
Schema 列同时保留物理表示与可选的名义语义类型。HIR 在比较中要求名义兼容,因此上下文 NULL 类型也不能让 UserId = TeamId 合法。自连接通过查询局部的 RelationBindingId 区分同一 TableId 的两次出现。
physical: UINT64 semantic: UserId UserId ≠ TeamId even when both are u64
NULL 是数据库值
数据库 NULL 是显式的 ScalarValue::Null。Rust Option 留给缺席的子句或元数据。比较遇到 NULL 得到 UNKNOWN;IS NULL / IS NOT NULL 才是显式测试。AND / OR / NOT 使用 SQL 三值逻辑。WHERE 与 JOIN 的 ON 只保留 TRUE,FALSE 与 UNKNOWN 都被拒绝。
Bool(true) → TRUE Bool(false) → FALSE NULL → UNKNOWN NULL = NULL → UNKNOWN NULL IS NULL → TRUE
JOIN
别名会隐藏底层表名。限定列经由暴露的关系名解析;非限定列仅在恰好一个可见关系提供该名时被接受。每个 ON 能看见完整左子树与当前右关系,但不能看见更后的连接。执行时 nested-loop 按确定性的左主、右次顺序保留重复。
SELECT e.name, m.name
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.active IS NOT NULL
ORDER BY e.name ASC NULLS LAST
LIMIT 20DML
类型化 DML 使用与堆写入相同的编译器、事务、整页 WAL、回滚与恢复路径。Database::execute 返回查询行或显式 AffectedRows(u64);query 拒绝变更语句。省略的可空 INSERT 列赋值为 NULL;省略的非空列将被拒绝。UPDATE 基于原始行求值全部右侧,因此 SET a = b, b = a 会交换两列。
INSERT INTO users (id, name) VALUES (1, 'Ada');
UPDATE users SET name = 'Ada Lovelace' WHERE id = 1;
DELETE FROM users WHERE name IS NULL;排序与聚合
普通计划是 Scan/Join → Filter → Sort → Project → Limit。聚合计划是 Scan/Join → Filter → Aggregate → Limit。键在投影之前、对着完整 FROM / JOIN 作用域解析,所以查询可以按它不返回的列排序。
COUNT(*) 计行;COUNT(column) 忽略 NULL。数值 SUM 使用受检算术,并剥去名义含义。MIN / MAX 保留输入 SemanticType。分组键上的 NULL 共享一组,这与表达式里 NULL = NULL 仍为 UNKNOWN 不同。带 GROUP BY 的查询当前拒绝 ORDER BY。
SELECT team_id, COUNT(*), SUM(score), MAX(score)
FROM scores
GROUP BY team_id索引与 ANALYZE
create_index 在事务性回填后注册非唯一单列索引。随后的堆与 SQL DML 会维护已注册索引。符合条件的等值与 IS NULL 谓词可选择点查 IndexScan;经过分析的双侧 Int64/UInt64 边界可选择范围 IndexScan。ANALYZE 为显式操作,DML 不会自动维护统计。不提供 SQL 索引 DDL。
create_index(table, column)
→ transactional backfill
→ register in IndexCatalog
→ DML maintains the index
→ ANALYZE writes a cost snapshot
→ planner may choose IndexScan多表写入仍未支持
核心用 create_tables / open_tables 组合多张未改动的单表堆文件。JOIN 没有改页、WAL、恢复或事务格式。跨表写事务仍不受支持。