有界编译与结构证据
输入超过 4,194,304 个 UTF-16 单元、131,072 个非 End 词法 token、8,192 层括号分组或 65,536 个 AST 节点时,编译会拒绝。迭代式 AST 遍历与有界渲染在六种提供程序上保持参数顺序及无法证明安全即拒绝的原则,不保证任意深度的 SQL 都能通过。
资源上限包含每阶段 8,000,000 工作单元、每次编译 32,000,000 工作单元、每阶段 30 秒、每次编译 90 秒,以及每阶段累计 536,870,912 字节托管内存分配。这些是编译预算,不是数据库查询超时或进程内存上限;超限会返回带类型的资源诊断。
可选的不可变 schema snapshot 解析表名、列名及可证明的类型族,包含有序 CTE/派生查询投影,并将摘要绑定到计划指纹。这是有限范围的证明,并非完整数据库类型检查器。带 schema 证据的 DML 需要实时 freshness verifier;证据缺失或结构已变化时拒绝执行。默认不采集快照;AddHsSqlAgentNativeDmlSchemaFreshness() 提供需显式启用的原生支持。
hs-sql-agent 不会把 AI 生成的 SQL 直接当作可信命令执行。SQL 在真正执行前会经过解析、验证、功能支持检查、访问策略检查以及面向目标数据库的编译。
查询执行路径
查询大致按照以下顺序处理:
- 验证 MCP 密钥,并应用该密钥限定的数据库、表、工具和运行时权限范围。
- 把受支持的 SQL 解析为结构化定义 / AST。
- 验证语句以及输入 SQL 的语义是否处于支持范围内。
- 检查目标数据库是否能够安全表达保持这些语义所需的功能。
- 为已配置的数据库编译并生成对应 SQL。
- 在配置的运行时限制内执行 SQL。
SQL 编译器明确区分输入语义验证和目标数据库功能支持检查两个阶段。不支持的语法,或者无法确认能够安全保持相同语义的功能,会被直接拒绝,而不是静默替换为一个表面相似的结构。
为什么采用“失败即拒绝”(fail-closed)?
跨数据库 SQL 中有大量“看起来相同,实际含义不同”的结构,例如 NULL 行为、类型规则、运算符语义、分页、标识符、函数以及 DML 行为。
对于面向 AI 的执行入口,“尽力改写”很危险,因为 SQL 即使仍然语法正确,也可能已经改变原意。因此 hs-sql-agent 更愿意明确拒绝,也不会在后台偷偷降低语义保证。
按数据库生成 SQL
MCP 的公开接口是统一的,但最终 SQL 会针对不同数据库分别生成。目前支持的数据库包括:
- PostgreSQL
- MySQL
- SQL Server
- Oracle
- SQLite
- Firebird
支持范围是有意限定的。某个数据库出现在支持列表中,并不意味着该数据库提供的所有 SQL 语法都可以使用。只有当某项功能的语义能够被内部表示并验证时,编译器才会把它加入支持范围。