查询语言

具有明确语义的
类型化 SQL 子集。

查询语言为有限的原生子集,包含解析器、名义类型检查、三值逻辑以及受 WAL 保护的 DML。它不是完整的 SQL 方言。

类别当前支持当前不支持
SELECT限定 / 非限定列、通配投影、LIMIT任意表达式投影、别名输出、DISTINCT
FROM / JOINAS 与简写别名、链式 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 BYHAVING、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 20

DML

类型化 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、恢复或事务格式。跨表写事务仍不受支持。