StarRocks strright 函数详解:从右侧提取子串的用法、别名与 UTF-8 底层实现
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
strright是 StarRocks 字符串函数族中用于从字符串右侧截取指定长度子串的函数,其语义与right完全等价,可视为right的别名。本文基于 strright 官方文档,结合 FE 函数注册与 BE 向量化执行源码,完整讲解语法、示例、边界行为、UTF-8 字符计数规则及其底层实现原理,帮助你写出精确、可预期的字符串截取 SQL。
函数概述与别名关系
strright(str, len)的作用是:从字符串str的最右侧开始,按指定长度len提取子串。长度单位是UTF-8 字符(character),而非字节(byte),因此对中文等多字节字符同样安全。
该函数同时注册为right,两者完全等价:
- FE 端在 FunctionSet.java 中分别定义了
RIGHT = "right"与STRRIGHT = "strright"两个函数名,指向同一套内置函数实现; - 你可以根据团队 SQL 风格任意选择
strright(...)或right(...),执行结果完全一致。
官方文档明确注明:"This function is also named as right",对应文档见 right.md。
语法与参数说明
VARCHAR strright(VARCHAR str, INT len)| 参数 | 类型 | 说明 |
|---|---|---|
str | VARCHAR | 源字符串,即被截取的对象 |
len | INT | 从右侧开始提取的字符个数(UTF-8 字符为单位) |
| 返回值 | VARCHAR | 截取得到的子串 |
行为要点:
- 当
len小于等于字符串长度时,返回最右侧的len个字符; - 当
len大于字符串长度时,返回整个原字符串(越界不报错,也不会返回 NULL)。
示例演示
官方文档给出了如下示例:
MySQL > select strright("Hello starrocks",9); +--------------------------------+ | strright('Hello starrocks', 9) | +--------------------------------+ | starrocks | +--------------------------------+"Hello starrocks"共 15 个字符,取最右侧 9 个字符,即得到starrocks。
结合参数行为,还可以验证以下边界场景:
-- len 大于字符串长度,返回整个字符串 SELECT strright('starrocks', 100); -- starrocks -- len 为 0,返回空字符串 SELECT strright('starrocks', 0); -- (empty) -- 多字节 UTF-8 字符按字符计数,而非按字节 SELECT strright('StarRocks 数据库', 3); -- 数据库(3 个中文字符) -- 与 right 完全等价 SELECT strright('StarRocks', 5), right('StarRocks', 5); -- Rocks | Rocks底层实现与边界语义
BE 端向量化实现
在 BE 端,strright/right的实现位于 string_functions.cpp:
// right // right(s, n) equals to substr(s, -n, n) except the case len(s) < n under which // right(s, n) return the entire s. StatusOr<ColumnPtr> StringFunctions::right(FunctionContext* context, const Columns& columns) { ... if (state != nullptr && state->is_const) { return right_const(state, columns); } else { return right_not_const(context, columns); } }源码注释明确了其与substr的关系:right(s, n)等价于substr(s, -n, n),唯一的例外是当len(s) < n时,right(s, n)返回整个s(而substr在越界时可能返回空串)。这一语义由模板参数allow_out_of_left_bound控制:
- 对
right函数,allow_out_of_left_bound恒为true,即允许越过左边界、直接返回完整字符串; - 对
substr/left函数,该参数恒为false。
相关核心逻辑见 string_functions.cpp 的ascii_substr_per_slice与 utf8_substr_from_right_per_slice:当负偏移(即从右往左数)导致from_pos < 0时,allow_out_of_left_bound为true则直接输出整个字符串,否则输出空串。
常量折叠优化(const optimization)
执行引擎对right/strright做了专门的常量优化。当两列在 Fragment 局部范围内均为非空常量时,会走left_or_right_prepare预计算路径:
Status StringFunctions::left_or_right_prepare(FunctionContext* context, FunctionContext::FunctionStateScope scope) { ... state->is_const = true; int len = ColumnHelper::get_const_value<TYPE_INT>(len_column); // right_const ignores state->pos, just use state->len state->pos = 1; state->len = len; ... }见 string_functions.cpp。由于strright('xxx', 9)这类 SQL 中两个参数往往都是字面量,该优化可将截取结果在 prepare 阶段直接计算出来,显著降低执行期开销。
ASCII 与 UTF-8 双路径
BE 实现按字符串内容自动分派两条路径:
- ASCII 快速路径:若字符串为纯 ASCII,可直接通过指针算术
from_pos + s->size定位起点,无需逐字符扫描(见 ascii_substr_per_slice); - UTF-8 慢速路径:若包含多字节字符,则从右向左扫描 UTF-8 字符边界,确保按“字符”而非“字节”截取(见 utf8_right_not_const)。对不超过 32 字节的短串,还会使用栈上
small_index缓存每个 UTF-8 字符的字节偏移以加速定位。
这也解释了文档中“The unit for length: utf-8 character”的底层原因:长度的单位始终是字符个数,中英文混排时不会出现半个字符的截断。
使用建议与注意事项
- 别名互换:
strright与right完全等价,新旧代码风格切换无任何兼容风险; - 越界安全:
len大于字符串长度时返回原串,不会报错;len = 0返回空串,可安全用于清洗场景; - 字符单位:涉及中文、Emoji 等多字节字符时,务必理解长度单位是字符而非字节,与
substr的负偏移语义一致; - NULL 处理:任一参数为 NULL 时结果返回 NULL(由
RETURN_IF_COLUMNS_ONLY_NULL等空值短路机制统一处理); - 相关函数:与
left(从左侧截取,见 left.md)、substr/substring、length/char_length等函数组合使用,可完成各类字符串处理需求。
小结
strright是 StarRocks 提供的一个语义简洁、实现高效的右侧子串截取函数,与right互为别名。从 FE 的 FunctionSet.java 注册到 BE 的 StringFunctions::right 向量化执行,再到 ASCII/UTF-8 双路径与常量折叠优化,整条链路保证了该函数在多字节场景下的正确性与高性能。需要从字符串右侧提取固定数量字符时,直接使用strright(str, len)即可。
keyword
STRRIGHT, RIGHT, 字符串函数, 右侧截取, UTF-8, StarRocks
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考