资讯动态

Daft SQL 标识符(Identifiers)大小写语义全解析:三种 Identifier Mode 的语法、配置与源码实现

发布时间:2026/9/18 3:59:47 来源:尧图企业网站定制
Daft SQL 标识符Identifiers大小写语义全解析三种 Identifier Mode 的语法、配置与源码实现【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/DaftDaft 的 SQL 标识符默认区分大小写但内置了insensitive不敏感、sensitive敏感与normalize归一化三种解析模式可通过SessionOptions在创建会话时配置。本指南以 docs/sql/identifiers.md 为主线结合 daft/session.py、src/daft-session/src/options.rs、src/daft-catalog/src/bindings.rs 与 src/daft-sql/src/planner.rs 等源码系统讲解 Daft 中标识符的书写语法、三种模式的行为差异、与主流引擎的兼容性对比以及底层查找与归一化的实现原理帮助你在跨目录、跨系统场景下正确选择标识符大小写策略。Daft SQL 标识符的基本概念在 Daft 中标识符Identifier用于引用 SQL 语句中的各类对象——附加目录attached catalogs、附加表attached tables、列columns等。Daft 的标识符解析遵循以下核心原则标识符默认区分大小写case-sensitive。解析行为受会话Session级配置的Identifier Mode控制可切换为大小写不敏感或大小写归一化模式。无论何种模式标识符本身都会被保留原始大小写case-preserved模式只影响“匹配”的方式即用户写下的大小写与已注册名称如何对应。这一设计在 src/daft-session/src/options.rs 中有直接对应IdentifierMode枚举的三个变体Insensitive、Sensitive默认、Normalize其文档注释明确说明Insensitive对ident AS alias中的ident做大小写不敏感查找绑定到保留大小写的aliasSensitive对ident做大小写敏感查找绑定到保留大小写的alias默认值标有#[default]Normalize对ident做大小写敏感查找但绑定到小写化的alias。这些模式在解析附加目录、附加表以及通过会话解析的列时统一生效是理解 Daft SQL 大小写行为的总入口。一个重要的前提警告!!! warning 注意诸如 Iceberg、Unity 等目录Catalog拥有**互不兼容的解析规则**Daft 无法保证所有目录实现之间的一致性。这意味着标识符大小写语义无法跨目录完全统一。官方建议在不同系统间协作时为命名空间和表统一使用小写名称并搭配identifier_mode normalize可以获得最一致的体验。标识符的书写语法Daft 支持三种标识符书写形式规则与 SQL 标准一致普通标识符regular identifier——不加引号abc带引号的定界标识符delimited identifier——使用双引号abc限定标识符qualified identifier——用点号连接多个部分abc.xyz混合限定标识符——各段可以分别选择是否加引号a.b.c含特殊字符的定界标识符——双引号内可以容纳 emoji、空格、保留字等SELECT FROM 标识符规则标识符可以是不加引号的普通标识符也可以是双引号包裹的定界标识符。当文本是关键字keyword或包含特殊字符时必须使用双引号包裹。普通标识符必须以字母字符或下划线_开头字母字符按 Unicode 派生核心属性判定。普通标识符只能包含字母数字、$与_字符。从源码角度看定界标识符只接受双引号。在 src/daft-sql/src/planner.rs 的normalize函数中SQL parser 解析出的每个ObjectNamePart会按其quote_style分派Some()双引号定界标识符原样保留ident.value.clone()不经过归一化None普通标识符送入会话的normalizer处理Some(c)其他引号风格如反引号、单引号直接抛出unsupported_sql_err提示 “Daft only supports delimited identifiers with double-quotes”。也就是说Daft 目前只支持双引号作为定界符SELECT \col或SELECT col 这类写法会报错。三种 Identifier Mode 的行为与兼容性Daft 提供三种标识符模式各自的行为与主流引擎兼容性总结如下模式行为兼容性insensitive所有标识符按大小写不敏感匹配名称保留原始大小写duckdb、spark、unitysensitive所有标识符按大小写敏感匹配名称保留原始大小写python、icebergnormalize不加引号的普通标识符归一化为小写双引号定界标识符保留原始大小写trino、postgres、datafusion三种模式的底层差异可以直接映射到 src/daft-session/src/session.rs 的normalizer()实现Insensitive与Sensitive模式normalizer返回恒等函数str::to_string即不修改任何大小写Normalize模式normalizer返回str::to_lowercase即把普通标识符统一小写化。模式的底层实现Bindings 的双重映射大小写匹配的核心数据结构是 src/daft-catalog/src/bindings.rs 中的BindingsT它维护了两套映射bindings: HashMapString, T以原始大小写保存的绑定lvalue即对象被注册时的名称aliases: HashMapString, HashSetString以小写化别名name.to_lowercase()即alias()函数为键指向所有匹配该别名的原始名称。查找rvalue即用户写下的标识符时依据LookupMode分派见 bindings.rsLookupMode::Insensitive通过小写别名集合查找到所有候选绑定并全部返回LookupMode::Sensitive直接在bindings中按精确大小写查找。而LookupMode与IdentifierMode的映射关系定义在 options.rsmatch self.identifier_mode { IdentifierMode::Insensitive LookupMode::Insensitive, IdentifierMode::Sensitive LookupMode::Sensitive, IdentifierMode::Normalize LookupMode::Sensitive, // 归一化在 SQL 规划阶段完成 }注意Normalize模式的查找本身仍是大小写敏感的小写归一化发生在 SQL 规划阶段——即 planner.rs 的normalize()先把普通标识符转成小写再以这个已小写的名字去执行敏感查找。正因为如此normalize模式下双引号定界标识符会被跳过归一化见上文从而实现“普通标识符小写化、定界标识符保留大小写”的混合语义。查找结果唯一性歧义处理由于insensitive模式可能命中多个大小写不同的绑定src/daft-session/src/session.rs 中对目录、Provider、表的查找都做了统一处理命中 0 个返回None未找到命中 1 个直接返回该对象命中多个抛出ambiguous_identifier_err!歧义错误。例如同一命名空间下同时注册了Orders与orders两张表在insensitive模式下查询orders会因命中两个候选而报歧义错误。一个值得注意的例外是函数名get_function与get_aggregate_function见 session.rs始终使用LookupMode::Insensitive查找注释明确说明 “Functions always use case-insensitive lookup (SQL convention)”即 SQL 函数名大小写不敏感是 Daft 的固定约定不受 Identifier Mode 影响。配置方式与当前默认值标识符模式在会话Session级别配置当前版本默认使用case-sensitive大小写敏感模式。!!! note 未来配置用于配置标识符模式的 Python API 计划在后续版本提供目前统一使用默认的大小写敏感模式。也就是说当前仓库代码options.rs 中Sensitive带有#[default]属性中会话创建时Options派生Defaultidentifier_mode即为SensitiveSessionOptions中可配置标识符模式的能力已经为未来版本预留src/daft-session/src/options.rs 顶部还有 “TODO make env variables” 的注释暗示未来可能通过环境变量开放配置。如果你需要了解 Daft SQL 会话与目录的完整用法可以参考 会话与目录指南Session类的 Python 接口定义在 daft/session.py。多系统协作的实践建议结合三种模式的语义与兼容性官方给出了跨系统协作的最佳实践首选normalize模式当需要同时对接 Trino、PostgreSQL、DataFusion 等“小写归一化”生态或者需要保证多系统行为一致时identifier_mode normalize是最稳妥的选择命名空间与表统一小写在跨多个系统的场景下为命名空间namespace和表table统一使用全小写名称能获得最一致的体验按生态选模式如果主要对接 DuckDB / Spark / Unity Cataloginsensitive更贴近其行为如果主要使用 Python 数据类库或 Iceberg默认的sensitive与其语义一致注意目录差异Iceberg、Unity 等目录有自己的解析规则与 Daft 会话级模式无法保证完全一致因此“模式只是起点目录实现才是最终裁决者”。同时可以留意因为insensitive模式下大小写不同的重名对象会触发歧义错误在开启该模式前应检查是否已存在仅大小写区分的同名对象。总结Daft 的标识符体系围绕“大小写保留 模式化匹配”设计sensitive默认做精确匹配insensitive借助小写别名做不敏感匹配normalize在 SQL 规划阶段把普通标识符统一小写、同时尊重双引号定界标识符。从 bindings.rs 的双映射结构到 options.rs 的模式默认值再到 planner.rs 的归一化分派这套机制贯穿了 Daft SQL 从解析到绑定的完整链路。理解三种模式的差异与适用生态是你在多目录、多引擎场景下写出行为可预期的 SQL 的关键一步。【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/Daft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价