ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

DataFusion SQL 运算符与字面量完全指南:从算术、比较到正则与 E 风格字符串

DataFusion SQL 运算符与字面量完全指南:从算术、比较到正则与 E 风格字符串 大数据数据分析后端【免费下载链接】datafusionApache DataFusion SQL Query Engine项目地址https://gitcode.com/gh_mirrors/datafu/datafusion点击查看免费下载本文基于 Apache DataFusion 官方用户文档docs/source/user-guide/sql/operators.md系统整理覆盖 DataFusion SQL 引擎支持的全部算术运算符、比较运算符含 NULL 安全的三值比较、逻辑与位运算符、数组包含运算符、字符串拼接以及 SQL 字面量的转义规则转义与E风格字符串。读完本文你可以直接写出可运行的 DataFusion SQL 表达式并能对照仓库源码理解每个运算符从 SQL 词法解析到物理执行的完整落地路径。一、运算符在 DataFusion 中的实现链路在逐个讲解运算符之前先说明一个背景DataFusion 中所有二元运算符都收敛到同一个核心抽象——Operator枚举定义在 operator.rs。SQL 层解析器把词法层识别的BinaryOperator来自 sqlparser-rs逐一映射到该枚举映射逻辑集中在 binary_op.rs 的parse_sql_binary_op方法中match op { BinaryOperator::Gt Ok(Operator::Gt), BinaryOperator::Plus Ok(Operator::Plus), BinaryOperator::PGRegexMatch Ok(Operator::RegexMatch), BinaryOperator::PGLikeMatch Ok(Operator::LikeMatch), BinaryOperator::Spaceship Ok(Operator::IsNotDistinctFrom), ... }可以看到PostgreSQL 风格的运算符~、~~、等在词法层被标记为PG*前缀的BinaryOperator再映射为 DataFusion 内部的Operator变体而spaceship直接映射为Operator::IsNotDistinctFrom说明它在引擎内部就是IS NOT DISTINCT FROM的别名。映射之后build_binary_expr会构造Expr::BinaryExpr见 binary_op.rs物理计划阶段则由各物理表达式模块如 binary.rs调用 Arrow 的计算内核真正执行。此外Operator枚举还实现了negate方法operator.rs为优化器改写NOT下的比较表达式提供依据例如Eq - NotEq、IsDistinctFrom - IsNotDistinctFrom、LikeMatch - NotLikeMatch。下面按文档的分组逐项讲解。二、算术运算符Numerical OperatorsDataFusion 支持五个算术运算符均以Int64字面量参与运算时默认返回整数结果。2.1加法 SELECT 1 2; --------------------- || Int64(1) Int64(2) | --------------------- || 3 | ---------------------2.2-减法 SELECT 4 - 3; --------------------- || Int64(4) - Int64(3) | --------------------- || 1 | ---------------------2.3*乘法 SELECT 2 * 3; --------------------- || Int64(2) * Int64(3) | --------------------- || 6 | ---------------------2.4/除法整数除法向零截断integer division truncates toward zero SELECT 8 / 4; --------------------- || Int64(8) / Int64(4) | --------------------- || 2 | ---------------------2.5%取模 SELECT 7 % 3; --------------------- || Int64(7) % Int64(3) | --------------------- || 1 | ---------------------从源码结构看这些运算符在 operator.rs 中分别对应Operator::Plus / Minus / Multiply / Divide / Modulo且negate()对它们统一返回None算术运算符不可直接取反。一个值得注意的边界Operator枚举中虽然定义了IntegerDivide对应 MySQL 的DIV或 DuckDB 的//见 binary_op.rs 对DuckIntegerDivide与MyIntegerDivide的解析但其文档注释明确标注 Not implemented in DataFusion yet即当前仓库中该运算符仅完成词法解析尚未具备完整的执行实现。使用整数除法语义时应以实际的/行为向零截断为准。三、比较运算符Comparison Operators3.1 基本比较六个基本比较运算符、!、、、、的行为符合标准 SQL 语义 SELECT 1 1; -- true SELECT 1 ! 2; -- true SELECT 3 4; -- true SELECT 3 3; -- true SELECT 6 5; -- true SELECT 5 5; -- true它们在源码中对应Operator::Eq / NotEq / Lt / LtEq / Gt / GtEq且都支持negate()取反例如Lt取反为GtEq优化器可以据此把NOT (a b)归一化为a b。3.2三值比较NULL 安全是 NULL 安全的三值比较运算符是IS NOT DISTINCT FROM的别名当两个操作数相等、或者两者都是 NULL 时返回true否则返回false。 SELECT NULL NULL; -- true SELECT 1 NULL; -- false SELECT 1 2; -- false SELECT 1 1; -- true其内部直接复用IsNotDistinctFrom运算符列名显示为IS NOT DISTINCT FROM SELECT NULL NULL; -------------------------------- || NULL IS NOT DISTINCT FROM NULL | -------------------------------- || true | --------------------------------仓库中的 expr.slt 还覆盖了一个列比较用例验证与显式等价写法的一致性select column1 column2 from (VALUES (1, 1), (2, 3), (NULL, NULL)) as t;该测试同时断言了等价表达式((column1 column2) OR (column1 IS NULL AND column2 IS NULL))与column1 column2的结果一致。3.3IS DISTINCT FROM与IS NOT DISTINCT FROM这两个运算符的意义在于保证比较结果一定是true或false而不会是 SQL 三值逻辑中的 UNKNOWN空集 SELECT 0 IS DISTINCT FROM NULL; -------------------------------- || Int64(0) IS DISTINCT FROM NULL | -------------------------------- || true | -------------------------------- SELECT NULL IS NOT DISTINCT FROM NULL; -------------------------------- || NULL IS NOT DISTINCT FROM NULL | -------------------------------- || true | --------------------------------在实现层Operator::IsDistinctFrom与Operator::IsNotDistinctFrom的文档注释operator.rs指明它们最终执行时分别调用arrow::compute::kernels::cmp::distinct与arrow::compute::kernels::cmp::not_distinct这两个 Arrow 计算内核即直接复用 Arrow Rust 的向量化比较实现而非自行标量循环。3.4 PostgreSQL 风格正则匹配~、~*、!~、!~* SELECT datafusion ~ ^datafusion(-cli)*; || Utf8(datafusion) ~ Utf8(^datafusion(-cli)*) | || true | SELECT datafusion ~* ^DATAFUSION(-cli)*; || Utf8(datafusion) ~* Utf8(^DATAFUSION(-cli)*) | || true | SELECT datafusion !~ ^DATAFUSION(-cli)*; || Utf8(datafusion) !~ Utf8(^DATAFUSION(-cli)*) | || true | SELECT datafusion !~* ^DATAFUSION(-cli); || Utf8(datafusion) !~* Utf8(^DATAFUSION(-cli)) | || true |语义规则~区分大小写的正则匹配~*不区分大小写的正则匹配!~区分大小写的正则不匹配!~*不区分大小写的正则不匹配。映射链路上这四个符号在词法层分别对应PGRegexMatch / PGRegexIMatch / PGRegexNotMatch / PGRegexNotIMatch见 binary_op.rs并一一映射到Operator::RegexMatch / RegexIMatch / RegexNotMatch / RegexNotIMatch。四者两两互为negate()的取反对因此NOT (a ~ b)可被优化器直接改写为a !~ b。仓库中 regexp_match.slt 与 regexp_like.slt 提供了这些正则运算符更系统的行为测试。3.5 PostgreSQL 风格 LIKE 匹配~~、~~*、!~~、!~~* SELECT datafusion ~~ dat_f%n; || Utf8(datafusion) ~~ Utf8(dat_f%n) | || true | SELECT datafusion ~~* Dat_F%n; || Utf8(datafusion) ~~* Utf8(Dat_F%n) | || true | SELECT datafusion !~~ Dat_F%n; || Utf8(datafusion) !~~ Utf8(Dat_F%n) | || true | SELECT datafusion !~~* Dat%F_n; || Utf8(datafusion) !~~* Utf8(Dat%F_n) | || true |即~~是区分大小写的 LIKE 匹配~~*是忽略大小写的 LIKE 匹配!~~、!~~*为对应的不匹配。它们分别映射到Operator::LikeMatch / ILikeMatch / NotLikeMatch / NotILikeMatchbinary_op.rs。四、逻辑运算符Logical Operators SELECT true AND true; --------------------------------- || Boolean(true) AND Boolean(true) | --------------------------------- || true | --------------------------------- SELECT false OR true; --------------------------------- || Boolean(false) OR Boolean(true) | --------------------------------- || true | ---------------------------------AND对应Operator::AndOR对应Operator::Or执行时遵循 SQL 三值逻辑。五、位运算符Bitwise OperatorsDataFusion 支持五个位运算符 SELECT 5 3; -- 位与结果 1 SELECT 5 | 3; -- 位或结果 7 SELECT 5 # 3; -- 位异或结果 6 SELECT 5 3; -- 右移结果 0 SELECT 5 3; -- 左移结果 40要点#是 PostgreSQL 风格的位异或写法文档特别指出它与^等价可互换从源码看^BinaryOperator::BitwiseXor、#BinaryOperator::PGBitwiseXor以及标准 SQL 的XOR关键字BinaryOperator::Xor三者都被解析为同一个Operator::BitwiseXorbinary_op.rs因此在 DataFusion 中^不是逻辑异或而是位异或移位运算要求右操作数为非负整数对应Operator::BitwiseShiftRight / BitwiseShiftLeft。六、其他运算符Other Operators6.1||字符串拼接 SELECT Hello, || DataFusion!; ---------------------------------------- || Utf8(Hello, ) || Utf8(DataFusion!) | ---------------------------------------- || Hello, DataFusion! | ----------------------------------------对应Operator::StringConcat。6.2数组包含 与数组被包含 SELECT make_array(1,2,3) make_array(1,3); || make_array(Int64(1),Int64(2),Int64(3)) make_array(Int64(1),Int64(3)) | || true | SELECT make_array(1,3) make_array(1,2,3); || make_array(Int64(1),Int64(3)) make_array(Int64(1),Int64(2),Int64(3)) | || true |a ba 包含 ba ba 被 b 包含。Operator枚举的注释operator.rs明确说明这两个运算符目前仅支持与列表list/数组类型一起使用AtArrow与ArrowAt的文档示例正是select [1,2,3] [1,3]与select [1,3] [1,2,3]。顺带说明实现边界同一枚举中还声明了-Arrow、-LongArrow、#HashArrow、#HashLongArrow、AtAt、?、?、?|、#-、?等 JSON 相关运算符但注释均标注 Not implemented in DataFusion yet当前版本不可用。七、SQL 字面量Literals与转义规则7.1 基本字面量字符串字面量使用单引号包裹例如字符串foo bar写作foo barselect foo;7.2 转义默认不支持 C 风格转义序列与许多编程语言不同SQL 字面量默认不支持\n这类 C 风格转义序列串内的所有字符都按字面意义处理要转义单引号使用双单引号 select its escaped; ---------------------- || Utf8(its escaped) | ---------------------- || its escaped | ----------------------字符串foo\nbar的含义是反斜杠加字母 n而不是换行符 select foo\nbar; ------------------ || Utf8(foo\nbar) | ------------------ || foo\nbar | ------------------7.3E风格字符串使用转义字符要表达换行、制表符等控制字符需要使用 PostgreSQL 风格的E...字符串此时\n、\t等转义序列才会生效 select Efoo\nbar; ----------------- || Utf8(foo bar) | ----------------- || foo bar | -----------------仓库测试 expr.slt 中同样验证了转义字符串select Efoo\t\tbar;制表符的行为。八、小结运算符对照与实现索引分组运算符内部 Operator 变体状态算术 - * / %Plus / Minus / Multiply / Divide / Modulo完整支持比较 ! Eq / NotEq / Lt / LtEq / Gt / GtEq完整支持比较IsNotDistinctFrom即IS NOT DISTINCT FROM别名完整支持比较IS [NOT] DISTINCT FROMIsDistinctFrom / IsNotDistinctFrom完整支持底层调用 Arrowcmp内核比较~ ~* !~ !~*RegexMatch / RegexIMatch / RegexNotMatch / RegexNotIMatch完整支持比较~~ ~~* !~~ !~~*LikeMatch / ILikeMatch / NotLikeMatch / NotILikeMatch完整支持逻辑AND ORAnd / Or完整支持位 | # ^ BitwiseAnd / BitwiseOr / BitwiseXor / BitwiseShiftRight / BitwiseShiftLeft完整支持其他\|\|StringConcat完整支持其他 AtArrow / ArrowAt仅支持列表类型完整支持其他DIV、//、-、-、#、?等IntegerDivide / Arrow / LongArrow / HashArrow等已解析未实现Not implemented深入阅读建议的仓库入口运算符抽象定义与negate取反逻辑datafusion/expr-common/src/operator.rsSQL 词法运算符到内部Operator的映射datafusion/sql/src/expr/binary_op.rs二元表达式的物理执行如加法走add_wrappingdatafusion/physical-expr/src/expressions/binary.rs、E...字符串等行为的回归测试datafusion/sqllogictest/test_files/expr.slt 与 regexp_match.slt。适用前提本文所有运算符行为与源码引用均基于当前仓库Apache DataFusion 主分支的实际实现文档中标注未实现的运算符在后续版本可能发生变化使用前建议先查看最新的Operator枚举注释与datafusion/sqllogictest/test_files/下的对应测试用例。赞分享大数据数据分析后端【免费下载链接】datafusionApache DataFusion SQL Query Engine项目地址https://gitcode.com/gh_mirrors/datafu/datafusion点击查看免费下载相关推荐TDesign Vue Next与Vue 3组合式API完美结合10个实用技巧TDesign Vue Next与Vue 3组合式API完美结合10个实用技巧 TDesign Vue Next是腾讯设计体系推出的Vue 3.x UI组件库前端UI组件桌面应用Polars SQL 操作符完全指南布尔逻辑、比较、数值、位运算、字符串、正则与索引访问Polars SQL 操作符完全指南布尔逻辑、比较、数值、位运算、字符串、正则与索引访问 Polars 不仅提供了惯用的 Python 表达式 API还内置音视频桌面应用后端如何用洛雪音乐助手桌面版构建你的终极免费音乐播放器如何用洛雪音乐助手桌面版构建你的终极免费音乐播放器 洛雪音乐助手桌面版是一款基于现代Web技术栈构建的跨平台音乐播放软件它为音乐爱好者提供了完全免费、开源且功开发工具上一篇如何通过hoverboard-firmware-hack-FOC实现无线遥控PWM/PPM信号接收配置终极指南 下一篇Pydantic AI 流式处理让加载转圈消失的选型实操创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表