从 #5769 的实测中带出(该单只做条件层拒收闸;维护者在 #5769 正文点名同轮该看 remote-transport.ts:462,但实测发现它不是单面问题,单独修 remote 会制造一条 local/remote 叉,故按「明确说明不做及理由」拆出本单)。
事实一:同一条件,两处裸 Error
packages/drivers/driver-turso/src/remote-transport.ts:462
throw new Error("Unsupported aggregate function: " + funcRaw)
packages/drivers/driver-sql/src/sql-driver.ts:6753(mapAggregateFunc,由 SqlDriver.aggregate:3103 调用)
throw new Error("Unsupported aggregate function: " + func)
两处都不带 code / status。在 origin/main(5c94f833c)上实测 remote 面:
aggregate({ aggregations: [{ function: 'median' }] })
→ THREW code=undefined status=undefined msg="Unsupported aggregate function: median"
mapDataError 读 error.code / error.status 组装信封,两者皆无 → 落默认分支 →
只剩一个 error 字段装消息文本、没有 code,并按 500 一类记日志,而这本是 400 类
的调用方错误。这正是 #1116/#1117 给过滤器拒收补信封的同一个缺口,只是换了个入口。
只修 remote 会把事情变坏:remote 变成 INVALID_QUERY/400,local(SqlDriver,
Turso local 继承)仍是裸 Error —— 一个条件、两种线上身份、取决于 url,正是
#5769 花整单去关的那类叉,方向反过来而已。所以这单的落点是两面同改。
事实二:三个 spec 已声明的聚合函数没有任何 SQL 后端编译
packages/spec/src/data/query.zod.ts:108 AggregationFunction 声明 8 个:
'count', 'sum', 'avg', 'min', 'max', 'count_distinct', 'array_agg', 'string_agg'
SqlDriver.mapAggregateFunc 与 RemoteTransport.aggregate 各自只编译前 5 个,
后 3 个落同一句 Unsupported aggregate function。driver-mongodb
(mongodb-aggregation.ts:139/144/147)和 driver-memory
(memory-analytics.ts:866,count_distinct)则实现了其中若干 —— 即声明 ≠ 实现,
且各后端实现的子集还不一样(Prime Directive #10)。
于是 :462 这一句今天同时承担两种性质不同的条件:
- 协议根本没声明的函数名(
median)—— 调用方写错了,INVALID_QUERY / 400 一类;
- 协议声明了、这个后端编不出的函数(
count_distinct / array_agg / string_agg)
—— 不是调用方的错,是能力缺口。
driver-memory 的 filter-refusal.ts 已经为过滤器算子画过这条线(#5345:
unknownFieldOperatorError 之于「协议没有这个算子」,对比「协议有、这个面降不下去」),
把两者合并成一句会告诉一个写 count_distinct 的看板作者说他打错字了。
建议落点(需要一次裁定,故不夹带在 #5769 里)
复现
// remote
const t = new RemoteTransport(); t.setClient(client);
await t.aggregate('deal', { aggregations: [{ function: 'median' }] });
// local
await new TursoDriver({ url: ':memory:' }).aggregate('deal', { aggregations: [{ function: 'count_distinct', field: 'stage', alias: 'n' }] });
两者都抛 Unsupported aggregate function: …,code / status 均为 undefined。
从 #5769 的实测中带出(该单只做条件层拒收闸;维护者在 #5769 正文点名同轮该看
remote-transport.ts:462,但实测发现它不是单面问题,单独修 remote 会制造一条 local/remote 叉,故按「明确说明不做及理由」拆出本单)。事实一:同一条件,两处裸
Errorpackages/drivers/driver-turso/src/remote-transport.ts:462throw new Error("Unsupported aggregate function: " + funcRaw)packages/drivers/driver-sql/src/sql-driver.ts:6753(mapAggregateFunc,由SqlDriver.aggregate:3103调用)throw new Error("Unsupported aggregate function: " + func)两处都不带
code/status。在origin/main(5c94f833c)上实测 remote 面:mapDataError读error.code/error.status组装信封,两者皆无 → 落默认分支 →只剩一个
error字段装消息文本、没有code,并按 500 一类记日志,而这本是 400 类的调用方错误。这正是 #1116/#1117 给过滤器拒收补信封的同一个缺口,只是换了个入口。
只修 remote 会把事情变坏:remote 变成
INVALID_QUERY/400,local(SqlDriver,Turso local 继承)仍是裸
Error—— 一个条件、两种线上身份、取决于url,正是#5769 花整单去关的那类叉,方向反过来而已。所以这单的落点是两面同改。
事实二:三个 spec 已声明的聚合函数没有任何 SQL 后端编译
packages/spec/src/data/query.zod.ts:108AggregationFunction声明 8 个:SqlDriver.mapAggregateFunc与RemoteTransport.aggregate各自只编译前 5 个,后 3 个落同一句
Unsupported aggregate function。driver-mongodb(
mongodb-aggregation.ts:139/144/147)和driver-memory(
memory-analytics.ts:866,count_distinct)则实现了其中若干 —— 即声明 ≠ 实现,且各后端实现的子集还不一样(Prime Directive #10)。
于是
:462这一句今天同时承担两种性质不同的条件:median)—— 调用方写错了,INVALID_QUERY/ 400 一类;count_distinct/array_agg/string_agg)—— 不是调用方的错,是能力缺口。
driver-memory的filter-refusal.ts已经为过滤器算子画过这条线(#5345:unknownFieldOperatorError之于「协议没有这个算子」,对比「协议有、这个面降不下去」),把两者合并成一句会告诉一个写
count_distinct的看板作者说他打错字了。建议落点(需要一次裁定,故不夹带在 #5769 里)
{ field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240 的规矩),并加拒收表用例把
code/status钉住;NOT_IMPLEMENTED一类的能力缺口码,还是先按INVALID_QUERY统一、把三个未实现的声明按 ADR-0049 enforce-or-remove 单独处理。这条裁定会同时影响
driver-sql/driver-sqlite-wasm/driver-turso(两面)四个后端,所以值得单开。
复现
两者都抛
Unsupported aggregate function: …,code/status均为undefined。