查询与表达式完整参考
Pipeline 结构
from tasks
let threshold = 5
let urgent = (priority: int) -> priority >= threshold
filter archived == false
filter urgent priority
derive label = match state {
Pending => "pending"
Running {worker, ..} => worker
Done {result} => result
Failed {message, ..} => message
}
sort {-priority, id}
select {id, title, state, priority, label}
take 20stage 严格按源码顺序:filter 改变 row 集合;derive 扩充当前 schema;select 改变后续可见字段;union/intersect/except 组合同形结果;aggregate 归约结果;window 追加排名;sort 定义 total order;take/page 限制结果。Planner 只跳过前置 let,不越过其他 stage 重新排序。
表达式
支持字段/嵌套路径、binding、参数、typed literal、constructor、算术、比较、bool operator、Option helper、contains、length、any/all 与非递归局部函数。
filter {
priority >= $minimum
&& contains tags "release"
&& is_some assignee
&& all attempts (x -> x >= 0)
}混用 &&/|| 必须用括号明确分组。箭头闭包写 x -> expression 或 (x: Type) -> expression,不使用会与 pipeline | 冲突的竖线闭包。Int 算术 checked;float 每个中间结果必须有限;除零、溢出、NaN/Infinity 返回 E_ARITH。一个 pipeline/DML target 最多求值 100,000 个 list predicate element。
Match
filter match state {
Running {attempt, ..} => attempt >= 2
Failed {retryable: true, ..} => true
_ => false
}Pattern 可递归解构 sum、option、record、tuple 和 list。Binder 在扫描前检查穷尽性、不可达分支和积类型相关性;最多 100,000 analysis steps。_ 是 catch-all,.. 忽略 record 剩余字段。
derive x = match source {...} 构造任意目标 typed value。Mutation 的 set field = match source 使用同一 IR;顶层 current => current 可保留完整旧值。
Select 与 derive
derive {
subtotal = price + tax
has_owner = is_some owner
}
select {
id
display = title
total = subtotal + shipping
}字段顺序即响应列顺序。重复或未知字段即使空表也失败。Computed select 仍经过完整静态类型检查。
Sort 与 take
from tasks
sort {-priority, created_at, id}
take 11..21包含末端的等价写法:
from tasks
sort {-priority, created_at, id}
take 11..=20只限制行数时写 take 20。
全部 typed value 共享 total order:sum 先 variant ID 再 payload,record 按 field ID,None < Some,list 做短前缀优先的词典序比较。相同 sort keys 的行无稳定顺序保证;需要稳定结果时以主键收尾。
take N 接受非负整数。范围使用一基 Rust 语义:11..21 是半开区间,11..=20 包含末端;两者都跳过前 10 行并最多取 10 行。
Aggregate
from tasks
group {owner, state} {
aggregate {
count = count
total = sum estimate
min_priority = min priority
max_priority = max priority
}
}
filter count > 0
sort {-count, owner}未分组 aggregate 与 group ... { aggregate {...} } 支持 count、count_distinct、avg、sum、min 和 max。count 与 count_distinct 空输入为 0,sum 使用输入数值类型的零,avg/min/max 返回 Option<T>。avg int 的具体输出是 Option<float>;float/duration avg 保留命名类型。decimal avg 返回 E_TYPE。Group key 与 count_distinct 输入可为完整 ADT,未 sort 时不承诺组顺序。
限制:最多 256 aggregate 输出、100,000 groups、1,000,000 accumulator cells、64 MiB 估算 group state、250,000 working rows、100,000 result rows。count_distinct 的 typed 去重键计入 group state。超限返回 E_LIMIT。
基础排名窗口
from tasks
window {
partition state
sort {-priority, created_at}
position = row_number
placing = rank
dense = dense_rank
}
filter position <= 3
sort {state, position}partition 可省略;sort 必须存在。row_number 返回分区内 1..N,rank 对并列 typed sort tuple 留出名次空缺,dense_rank 不留空缺。并列 row_number 由进入 stage 的稳定顺序区分;需要跨恢复稳定时,把主键追加到 window sort。
partition 支持完整 ADT equality,sort 支持完整 typed total order。window 保留输入基数与原输出顺序,仅追加不覆盖已有字段的 int 列;后续可继续 filter/select/sort/take。空输入仍保留结果 schema。每个 window 最多 256 个输出,并计入 250,000 working rows 与 64 MiB working state。page、frame、lag/lead、窗口 aggregate 与用户定义窗口函数尚不支持。
有界 lookup
from orders
filter tenant == $tenant
sort id
page 100
lookup lines from order_lines on order_id == id take 100
select {id, customer, lines}目标 key 必须是主键、单列 index 或 composite index 第一项,并与 driver key 同型。每个 driver 的 take 为 1..=1000 的硬上限;读到 take + 1 即返回 E_RELATION_LIMIT。一个 lookup 最多接收 10,000 driver rows。无匹配结果为 []。
Page 后只允许 lookup 与 select。多个 lookup 可顺序组合,但不遍历前一层 list 内部。Lookup 不支持 mutation target,也没有目标侧自定义 sort。
有界相关 exists 与 not exists
from tasks
filter exists {
from task_items
filter task_id == outer.id
filter state != Done
}内层只允许 filter,且至少有一个 target.path == outer.path 的同型等值条件。目标路径必须是主键或 index 首项。一个 stage 最多接受 10,000 driver rows,目标查询在首个 residual match 处停止。使用 filter not exists { ... } 保留没有匹配行的 driver。explain.plan.exists 返回 negated、目标表、相关路径、实际索引和上限,但不执行 row。首版不支持嵌套 exists、mutation target 或其他内层 stage。
类型化集合运算
from active_tasks
select {state, tags}
union {
from archived_tasks
filter state != Done
select {state, tags}
}
sort stateunion、intersect 和 except 用花括号明确右侧 pipeline。两侧在集合 stage 处必须具有完全相同的字段名、顺序和类型;命名 ADT 使用 stable type ID,结构相似但名字不同的类型不兼容,也不做隐式数值提升。
三种运算都按完整 typed row 去重,包括嵌套 enum payload、record、tuple、Option 和 list:
union先保留左侧首次出现的行,再保留右侧尚未出现的行。intersect按左侧首次出现顺序保留同时存在于右侧的行。except按左侧首次出现顺序保留右侧不存在的行。
集合 stage 的首次出现顺序不替代业务排序;需要明确最终顺序时在其后写 sort。首版不支持嵌套集合运算,任一侧都不能使用 cursor page。可先在两侧 filter/take,合并后再 sort/take。
左右 materialized rows、encoded bytes 和 membership 状态合并计入 working-state 上限,并响应 deadline/cancel。explain.plan.set_operations 返回 operator、右侧表和访问计划,不读取数据行;explain analyze 合并两侧无业务值的执行计数。
Keyset page
from jobs
filter archived == false
sort {-priority, id}
page 100 after "u1.payload.mac"limit 1..=1000,最多 16 sort keys。最终顺序必须由主键收尾,或由 equality-fixed prefix + 完整 unique-index suffix 证明唯一。Cursor 最多 8192 bytes,payload 最多 6144 bytes;HMAC 绑定 database identity、schema、canonical query、typed params、direction、limit、sequence 和 boundary tuple。
成功 mutation 推进 sequence 并使旧 cursor 返回 E_CURSOR_STALE;失败/回滚、read 和 idempotent replay 不推进。Restore 轮换 database/cursor identity。
Explain 与运行画像
explain 返回 access kind、索引 lookup、当前 candidate 数、源码 stage 顺序、lookup/exists/set-operation 子计划和结果 schema,不执行 row。explain analyze 执行普通查询路径但不返回业务值,增加 prepare/plan/execute 耗时、returned/examined/decoded rows、index entry、redb cache、batch 和 working-memory peak。
通用资源边界
查询源码 1 MiB / 100,000 tokens / 64 层;working rows 250,000;结果 100,000 rows;服务 response 16 MiB;默认服务 deadline 25 秒。排序、group、match、局部函数和集合 predicate 还有各自预算。应通过 indexed filter、较小 page/batch 和更早 projection 控制工作量,而不是依赖提高无界上限。