原文地址:https://github.com/tursodatabase/turso/issues/4637
一、总体情况
Turso 仅支持 基本 CTE(仅限于 SELECT 语句),且存在多项关键限制。相比 SQLite,其 CTE 支持尚不完整。
二、支持与不支持的功能对比
✅ 已支持的功能(基本 SELECT CTE):
- 单个 CTE、多个 CTE、CTE 间相互引用
- 包含
ORDER BY、LIMIT、GROUP BY、DISTINCT - 包含
CASE、COALESCE、EXISTS、IN、LEFT JOIN等复杂表达式 - 包含聚合函数、数学运算、字符串函数、
VALUES子句等 - 可在子查询或嵌套查询中使用
❌ 不支持或存在问题的功能:
-
CTE 无法被多次引用(关键缺陷)
- 同一 CTE 不能在查询中引用超过一次(如自连接、多次出现在子查询中)。
-
CTE 内不支持复合查询(BUG)
UNION、INTERSECT、EXCEPT、UNION ALL在 CTE 内部会被错误拒绝。
-
CTE 不能与 DML 语句结合使用
- 不支持
WITH ... INSERT、WITH ... UPDATE、WITH ... DELETE。
- 不支持
-
不支持显式列名定义
WITH t(a, b) AS (...)语法不被支持。
-
不支持递归 CTE
WITH RECURSIVE语法不被支持。
-
CTE 不能遮盖同名表
- SQLite 允许 CTE 遮盖同名表,但 Turso 会直接拒绝。
-
不支持
MATERIALIZED提示NOT MATERIALIZED可被接受(但被忽略),MATERIALIZED则被拒绝。
三、关键问题示例
sql
-- 1. CTE 无法多次引用(失败)
WITH t AS (SELECT 1 AS x) SELECT * FROM t, t AS t2;
-- 错误:no such table: t
-- 2. CTE 内不能使用 UNION(失败)
WITH t AS (SELECT 1 UNION SELECT 2) SELECT * FROM t;
-- 错误:Only SELECT queries are currently supported in CTEs
-- 3. 不能与 INSERT 等同使用(失败)
WITH t AS (SELECT 1 AS x) INSERT INTO table SELECT * FROM t;
-- 错误:WITH clause is not supported
四、修复优先级建议
- 关键:CTE 多次引用问题(影响多数常用场景)。
- 高 :CTE 内支持复合查询(
UNION等)。 - 中:支持 CTE 与 DML 结合、显式列名定义。
- 低 :CTE 遮盖表名、
MATERIALIZED提示。 - 未来:递归 CTE(明确标记为尚未支持)。
五、其他说明
- 报告指出 SQLite 本身也不支持
WITH ... INSERT ... RETURNING语法,因此 Turso 在此方面无需立即为兼容性实现该功能。 - 存在一个关于递归 CTE 的未合并 PR,但目前非优先事项。
总结
Turso 的 CTE 支持目前处于 基础可用但限制明显 的阶段,适用于简单的查询分解和重用,但无法应对需要多次引用同一 CTE、使用复合查询或与数据修改操作结合的复杂场景。开发团队已识别关键问题并设置了修复优先级。