大数据批处理流处理数据工程【免费下载链接】beamApache Beam is a unified programming model for Batch and Streaming data processing.项目地址https://gitcode.com/gh_mirrors/beam4/beam点击查看免费下载本篇技术指南基于 string-functions.md 文档系统讲解 Apache Beam ZetaSQL 方言中全部内置字符串函数CHAR_LENGTH、CHARACTER_LENGTH、CONCAT、ENDS_WITH、LTRIM、REPLACE、REVERSE、RTRIM、STARTS_WITH、SUBSTR、TRIM的调用语法、返回类型、边界语义与完整示例并结合仓库源码BuiltinStringFunctions等揭示每个函数底层的 Java 实现与测试验证帮助你在 Beam SQL 管道中准确、高效地处理字符串数据。Beam ZetaSQL 中的字符串函数定位与背景Apache Beam 在sdks/java/extensions/sql中提供了 SQL 扩展其中 Beam ZetaSQL 是 Beam SQL 支持的一种方言其语言风格与 BigQuery 的 SQL 框架Google ZetaSQL相近。正如 ZetaSQL 概览 所述这种方言尤其适用于「写入或读取 BigQuery 表」的管道场景。本页文档所覆盖的字符串函数正是该方言中针对STRING数据类型的全部内置字符串操作。需要特别留意的是ZetaSQL 支持已在Beam 2.68.0 及更新版本中移除详见 Apache Beam 官方 issue #34423官方建议改用默认的 Calcite SQL 方言。因此本文内容适用于使用 ZetaSQL 方言的 Beam 2.68.0 之前的版本如果你使用的是新版本 Beam请在 Calcite SQL 文档 中查找对应的字符串函数如CHAR_LENGTH、TRIM、SUBSTRING等见下文源码章节的对照说明。STRING 数据的通用语义在使用任何字符串函数之前需要先理解 Beam ZetaSQL 对STRING数据的两条基础约定原文如此属文档明确规定的语义STRING值必须是格式良好的 UTF-8well-formed UTF-8。也就是说传入的字符串需要是合法的 UTF-8 编码序列这直接影响CHAR_LENGTH、REVERSE等按字符而非字节操作的函数结果。所有字符串比较都是逐字节byte-by-byte进行的不考虑 Unicode 规范等价canonical equivalence。例如由不同码位组合但「视觉上等价」的字符串如组合字符 vs 预组合字符会被视为不同ENDS_WITH、STARTS_WITH等比较函数遵循这一语义。这两条约定意味着如果你的数据源混入了非法 UTF-8 字节或带有 Unicode 组合字符字符串函数的返回结果可能与你直觉预期不一致在管道中应先用数据清洗或编解码步骤处理。函数速览表Operator syntaxDescriptionCHAR_LENGTH(value)Returns the length of the string in charactersCHARACTER_LENGTH(value)Synonym for CHAR_LENGTHCONCAT(value1[, ...])Concatenates up to five values into a single resultENDS_WITH(value1, value2)Returns TRUE if the second value is a suffix of the firstLTRIM(value1[, value2])Identical to TRIM, but only removes leading characters.REPLACE(original_value, from_value, to_value)Replaces all occurrences offrom_valuewithto_valueinoriginal_valueREVERSE(value)Returns the reverse of the input stringRTRIM(value1[, value2])Identical to TRIM, but only removes trailing charactersSTARTS_WITH(value1, value2)Returns TRUE if the second value is a prefix of the first.SUBSTR(value, position[, length])Returns a substring of the supplied valueTRIM(value1[, value2])Removes all leading and trailing characters that matchvalue2CHAR_LENGTHCHAR_LENGTH(value)DescriptionReturns the length of the STRING in characters.Return typeINT64ExamplesTable example: ---------------- | characters | ---------------- | абвгд | ---------------- SELECT characters, CHAR_LENGTH(characters) AS char_length_example FROM example; --------------------------------- | characters | char_length_example | --------------------------------- | абвгд | 5 | ---------------------------------从示例可见CHAR_LENGTH计算的是字符数而非字节数字符串абвгд由 5 个西里尔字母组成每个字符在 UTF-8 中占 2 字节结果仍返回5。该函数在仓库的测试中被验证为等价于 Calcite 标准操作符表中的CHAR_LENGTH/CHARACTER_LENGTH见 BeamSqlDslSqlStdOperatorsTest.java 中的断言CHAR_LENGTH(hello) 5。CHARACTER_LENGTHCHARACTER_LENGTH(value)DescriptionSynonym for CHAR_LENGTH.Return typeINT64ExamplesTable example: ---------------- | characters | ---------------- | абвгд | ---------------- SELECT characters, CHARACTER_LENGTH(characters) AS char_length_example FROM example; --------------------------------- | characters | char_length_example | --------------------------------- | абвгд | 5 | ---------------------------------CHARACTER_LENGTH是CHAR_LENGTH的完全同义词二者返回类型均为INT64使用哪个名称均可。CONCATCONCAT(value1[, ...])DescriptionConcatenates up to five values into a single result. 即最多可将5 个值拼接为一个结果这是本方言对参数个数的明确限制。Return typeSTRINGExamplesTable Employees: ------------------------ | first_name | last_name | ------------------------ | John | Doe | | Jane | Smith | | Joe | Jackson | ------------------------ SELECT CONCAT(first_name, , last_name) AS full_name FROM Employees; --------------------- | full_name | --------------------- | John Doe | | Jane Smith | | Joe Jackson | ---------------------CONCAT常与字符串字面量混用如中间的 空格分隔符是拼接姓名字段、组装日志文本时的常用函数。注意其在 ZetaSQL 方言中最多支持 5 个参数若需要拼接更多片段可嵌套调用或使用管道中的其他拼接手段。ENDS_WITHENDS_WITH(value1, value2)DescriptionTakes two values. Returns TRUE if the second value is a suffix of the first.Return typeBOOLExamplesTable items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT ENDS_WITH(item, e) as example FROM items; --------- | example | --------- | True | | False | | True | ---------源码佐证ENDS_WITH在仓库中的实现位于 BuiltinStringFunctions.java底层直接委托给 Java 的String.endsWith(str2)并通过Strict注解声明为严格函数任一参数为 NULL 时返回 NULL。测试用例见 BeamSqlUdfExpressionTest.java其中验证了以下关键行为ENDS_WITH(string1, g1)→trueENDS_WITH(string2, g1)→falseENDS_WITH(, )→true两个空字符串互为后缀ENDS_WITH(中文, 文)→true对多字节 UTF-8 字符按字符边界正确判定而非按字节ENDS_WITH(中文, 中)→falseSTARTS_WITHSTARTS_WITH(value1, value2)DescriptionTakes two values. Returns TRUE if the second value is a prefix of the first.Return typeBOOLExamplesSELECT STARTS_WITH(item, b) as example FROM ( SELECT foo as item UNION ALL SELECT bar as item UNION ALL SELECT baz as item) AS items; --------- | example | --------- | False | | True | | True | ---------源码佐证与ENDS_WITH对称STARTS_WITH的实现位于 BuiltinStringFunctions.java底层为String.startsWith(str2)。测试见 BeamSqlUdfExpressionTest.javaSTARTS_WITH(string1, stri)→trueSTARTS_WITH(string2, str1)→falseSTARTS_WITH(, )→trueSTARTS_WITH(中文, 文)→falseSTARTS_WITH(中文, 中)→true两个函数均按「逐字节比较」的 ZetaSQL 通用语义执行但底层 Java 实现仍能正确处理多字节 UTF-8 字符的边界判定适合用于过滤以某前缀/后缀开头的记录、识别文件扩展名或 URL 路径等场景。TRIMTRIM(value1[, value2])DescriptionRemoves all leading and trailing characters that matchvalue2. Ifvalue2is not specified, all leading and trailing whitespace characters (as defined by the Unicode standard) are removed.Ifvalue2contains more than one character, the function removes all leading or trailing characters contained invalue2. 也就是说当value2是多字符集合时TRIM会从两端逐一移除「属于该集合」的任意字符而不是把value2当作一个整体子串来匹配。Return typeSTRINGExamplesTable items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT CONCAT(#, TRIM(item), #) as example FROM items; ---------- | example | ---------- | #apple# | | #banana# | | #orange# | ---------- Table items: ---------------- | item | ---------------- | ***apple*** | | ***banana*** | | ***orange*** | ---------------- SELECT TRIM(item, *) as example FROM items; --------- | example | --------- | apple | | banana | | orange | --------- Table items: ---------------- | item | ---------------- | xxxapplexxx | | yyybananayyy | | zzzorangezzz | | xyzpearxyz | ---------------- SELECT TRIM(item, xyz) as example FROM items; --------- | example | --------- | apple | | banana | | orange | | pear | ---------第三个示例最能体现多字符集合语义TRIM(item, xyz)会把字符串两端的x、y、z三个字符任意组合全部移除因此xyzpearxyz被修剪为pear注意pear中部的r不在修剪集合内得以保留。源码佐证与方言差异在 Beam 的 Calcite 标准操作符测试 BeamSqlDslSqlStdOperatorsTest.java 中TRIM还被验证支持标准 SQL 的TRIM(LEADING/TRAILING/BOTH ... FROM ...)语法TRIM( hello )→helloTRIM(LEADING eh FROM hehe__hehe)→__heheTRIM(TRAILING eh FROM hehe__hehe)→hehe__TRIM(BOTH eh FROM hehe__hehe)→__TRIM(BOTH FROM hello )→helloZetaSQL 方言的TRIM(value1[, value2])形式与上述FROM语法在语义上可互相换算不带value2等价于TRIM(BOTH FROM ...)的空白清理带value2等价于按字符集合做BOTH修剪。LTRIMLTRIM(value1[, value2])DescriptionIdentical to TRIM, but only removes leading characters. 即仅移除**开头左侧**的匹配字符未指定value2时默认移除开头空白。Return typeSTRINGExamplesTable items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT CONCAT(#, LTRIM(item), #) as example FROM items; ------------- | example | ------------- | #apple # | | #banana # | | #orange # | ------------- Table items: ---------------- | item | ---------------- | ***apple*** | | ***banana*** | | ***orange*** | ---------------- SELECT LTRIM(item, *) as example FROM items; ----------- | example | ----------- | apple*** | | banana*** | | orange*** | ----------- Table items: ---------------- | item | ---------------- | xxxapplexxx | | yyybananayyy | | zzzorangezzz | | xyzpearzyz | ---------------- SELECT LTRIM(item, xyz) as example FROM items; ----------- | example | ----------- | applexxx | | bananayyy | | orangezzz | | pearxyz | -----------第一个示例中用CONCAT(#, LTRIM(item), #)包裹结果可以直观看到前导空格被清除但尾部空格保留#apple #中#与apple之间已无空格而apple与右侧#之间仍有空格。第三个示例再次印证了「字符集合」语义LTRIM(item, xyz)只移除左侧的x/y/z右侧的xxx、yyy、zzz、xyz原样保留。RTRIMRTRIM(value1[, value2])DescriptionIdentical to TRIM, but only removes trailing characters. 即仅移除**末尾右侧**的匹配字符未指定value2时默认移除末尾空白。Return typeSTRINGExamplesTable items: ---------------- | item | ---------------- | ***apple*** | | ***banana*** | | ***orange*** | ---------------- SELECT RTRIM(item, *) as example FROM items; ----------- | example | ----------- | ***apple | | ***banana | | ***orange | ----------- Table items: ---------------- | item | ---------------- | applexxx | | bananayyy | | orangezzz | | pearxyz | ---------------- SELECT RTRIM(item, xyz) as example FROM items; --------- | example | --------- | apple | | banana | | orange | | pear | ---------RTRIM与LTRIM方向互补第一个示例中RTRIM(item, *)只去掉右侧的***左侧保留第二个示例中RTRIM(item, xyz)将右侧的xxx/yyy/zzz/xyz全部移除恰好与上文LTRIM(item, xyz)形成镜像对照。三者TRIM/LTRIM/RTRIM对value2的解析规则完全一致不指定时按 Unicode 标准移除空白指定时按字符集合逐端移除。REPLACEREPLACE(original_value, from_value, to_value)DescriptionReplaces all occurrences offrom_valuewithto_valueinoriginal_value. Iffrom_valueis empty, no replacement is made. 即替换是全局的所有出现位置都会替换特别地当from_value为空字符串时不进行任何替换。Return typeSTRINGExamples-------------------- | dessert | -------------------- | apple pie | | blackberry pie | | cherry pie | -------------------- SELECT REPLACE (dessert, pie, cobbler) as example FROM desserts; -------------------- | example | -------------------- | apple cobbler | | blackberry cobbler | | cherry cobbler | --------------------实战提示REPLACE适合做词法级别的数据规范化例如把旧标签替换为新标签、把\n换行符替换为分隔符等。要注意from_value与to_value均为字符串字面量时的引号使用示例中使用双引号以及空串不替换的边界行为——这与某些编程语言中「空串插入到每个字符之间」的行为不同是本方言的明确差异点。REVERSEREVERSE(value)DescriptionReturns the reverse of the input STRING.Return typeSTRINGExamplesWITH example AS ( SELECT foo AS sample_string UNION ALL SELECT абвгд AS sample_string ) SELECT sample_string, REVERSE(sample_string) AS reverse_string FROM example; ------------------------------- | sample_string | reverse_string | ------------------------------- | foo | oof | | абвгд | дгвба | -------------------------------源码佐证REVERSE在 BuiltinStringFunctions.java 中有两个重载版本——STRING版本通过new StringBuilder(str).reverse()实现按 UTF-16 字符单元反转对 BMP 内字符安全BYTES版本则通过字节数组反转实现。测试 BeamSqlUdfExpressionTest.java 覆盖了多种输入REVERSE()→REVERSE(foo)→oofREVERSE(中文)→文中双字节汉字正确反转REVERSE(абвгд)→дгвба西里尔字母正确反转与文档示例完全一致SUBSTRSUBSTR(value, position[, length])DescriptionReturns a substring of the supplied value. Thepositionargument is an integer specifying the starting position of the substring, with position 1 indicating the first character or byte. Thelengthargument is the maximum number of characters for STRING arguments.如果position为负数函数从value的末尾开始计数其中-1表示最后一个字符。如果position超出了字符串左端position 0 或position-LENGTH(value)函数会从 position 1 开始即自动钳制到字符串开头。如果length超过value的实际长度则返回少于length个字符即返回到字符串末尾为止。如果length小于 0函数返回错误。Return typeSTRINGExamplesTable items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT SUBSTR(item, 2) as example FROM items; --------- | example | --------- | pple | | anana | | range | --------- Table items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT SUBSTR(item, 2, 2) as example FROM items; --------- | example | --------- | pp | | an | | ra | --------- Table items: ---------------- | item | ---------------- | apple | | banana | | orange | ---------------- SELECT SUBSTR(item, -2) as example FROM items; --------- | example | --------- | le | | na | | ge | ---------三个示例分别演示了三种典型用法SUBSTR(item, 2)从第 2 个字符截取到末尾apple→ppleSUBSTR(item, 2, 2)从第 2 个字符开始取 2 个字符apple→ppSUBSTR(item, -2)从末尾倒数第 2 个字符截取到末尾apple→le。边界语义汇总结合文档原文条件行为position 1从第一个字符开始position为负从末尾倒数计数-1指最后一个字符position 0或position -LENGTH(value)自动从position 1开始length超过字符串长度返回少于length个字符截到末尾length 0返回错误方言对照ZetaSQL 的SUBSTR(value, position[, length])与 Calcite 标准语法SUBSTRING(value FROM position [FOR length])语义一致。仓库测试 BeamSqlDslSqlStdOperatorsTest.java 验证了SUBSTRING(hello FROM 2)→ello、SUBSTRING(hello FROM 2 FOR 100)→ellolength 超过时截到末尾等行为与本文档的边界规则互相印证。源码级实现从 SQL 函数到 Java UDF通过查看仓库源码可以更深入地理解这些字符串函数的落地方式。Beam SQL 中的自定义字符串函数集中在 BuiltinStringFunctions.javaorg.apache.beam.sdk.extensions.sql.impl.udf包该类通过AutoService(BeamBuiltinFunctionProvider.class)注册为 Beam 内置函数提供者其实现特征包括UDF注解声明函数每个方法通过UDF(funcName ..., parameterArray {...}, returnType ...)声明 SQL 函数名、参数类型与返回类型。例如ENDS_WITH、STARTS_WITH均声明parameterArray {TypeName.STRING}、returnType TypeName.STRING第 36-51 行Strict严格语义标注了Strict的函数在任一参数为 NULL 时直接返回 NULL避免空指针异常这解释了REVERSE(CAST(NULL as VARCHAR(0)))在测试中返回 NULL 的行为重载支持LENGTH、REVERSE都同时提供STRING与BYTES两个重载第 53-89 行按输入类型自动分派同源函数同一文件还实现了LPAD/RPAD含多字节BYTES版本的手工字节填充第 113-252 行以及FROM_HEX/TO_HEX这些属于本页未展开但同属 Beam 内置字符串能力集的函数。而CHAR_LENGTH、CHARACTER_LENGTH、TRIM、SUBSTRINGSUBSTR的对应形式与CONCAT||拼接则主要由 Calcite 的SqlStdOperatorTable标准操作符提供相关断言可见 BeamSqlDslSqlStdOperatorsTest.java。此外BeamSqlCastTest.java 中还能看到CHAR_LENGTH(TRIM(f_string))与SUBSTRING(TRIM(f_string) FROM 1 FOR 4)组合使用的实战模式——这正是字符串函数在日期格式解析类 SQL 中的典型嵌套用法。使用注意事项与实战要点综合文档语义与仓库测试使用这些字符串函数时建议留意以下几点编码前提所有STRING必须是格式良好的 UTF-8对字节级场景可改用BYTES重载如LENGTH、REVERSE均支持BYTES输入。比较语义字符串比较逐字节进行忽略 Unicode 规范等价做大小写不敏感匹配时需自行预处理本方言字符串函数集不含LOWER/UPPER需要时可结合 Beam 的其他内置函数或 UDF 扩展。空值传播ENDS_WITH、STARTS_WITH、REVERSE等Strict函数在参数为 NULL 时返回 NULL而STARTS_WITH(, )、ENDS_WITH(, )均返回 TRUE空字符串与空字符串互为前后缀。TRIM家族的多字符集合语义TRIM(value1, value2)的value2是「待移除字符集合」不是整体子串——TRIM(item, xyz)会移除两端任意出现的x/y/z。这与部分数据库将第二个参数当作整串匹配的实现不同迁移 SQL 时需特别核对。SUBSTR的位置边界position从 1 开始计数负数从末尾倒数position 0或过小时自动钳制为 1length 0会报错而非返回空串务必在应用层校验参数。REPLACE的空串行为from_value为空时不做任何替换不要期望其产生「插入」效果。CONCAT的参数上限最多 5 个值超出时可嵌套调用。版本限制ZetaSQL 方言在 Beam 2.68.0 起已移除若需在新版本中使用字符串函数请迁移至默认 Calcite 方言并对照 BeamSqlDslSqlStdOperatorsTest.java 中验证过的CHAR_LENGTH、TRIM(... FROM ...)、SUBSTRING(... FROM ... FOR ...)等标准语法。总而言之Beam ZetaSQL 的字符串函数集虽精简但覆盖了长度统计、拼接、前后缀判断、修剪、替换、反转与截取等核心字符串处理需求且每个函数都有明确的边界语义与 Java 实现对应。理解「字符 vs 字节」「字符集合 vs 子串」「严格空值传播」这三组关键区别就能在 Beam SQL 管道中写出行为可预期、可测试的字符串处理逻辑。赞分享大数据批处理流处理数据工程【免费下载链接】beamApache Beam is a unified programming model for Batch and Streaming data processing.项目地址https://gitcode.com/gh_mirrors/beam4/beam点击查看免费下载相关推荐StarRocks replace() 字符串替换函数完全指南语法、语义与源码实现剖析StarRocks replace 字符串替换函数完全指南语法、语义与源码实现剖析 replace 是 StarRocks 提供的字符串替换函数用于把字符串数据库OLAP数据仓库大数据湖仓一体数据分析Apache Beam ZetaSQL 方言完全指南语法、数据类型、函数与迁移路径Apache Beam ZetaSQL 方言完全指南语法、数据类型、函数与迁移路径 Apache Beam 的 SQL 模块在 Calcite 默认方言之外大数据批处理流处理数据工程StarRocks substring/substr 字符串截取函数完全指南语法、边界语义与源码实现剖析StarRocks substring/substr 字符串截取函数完全指南语法、边界语义与源码实现剖析 substring别名 substr是 Star数据库OLAP数据仓库大数据湖仓一体数据分析上一篇ANE 路线图展望Apple Neural Engine 训练框架从研究代码到社区维护的演进路径下一篇5个关键突破OpenArm开源机械臂重塑AI机器人教育平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考