StarRocks bitmap_empty 函数详解:构造空 Bitmap 并填充 BITMAP 列默认值
【免费下载链接】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
bitmap_empty()是 StarRocks 中用于构造空 Bitmap 的系统函数,典型应用场景是在 INSERT 或 Stream Load 导入数据时,为 BITMAP 类型的列填充默认值,避免因源数据缺失或类型不匹配导致导入失败。阅读本文后,你将掌握bitmap_empty()的语法、导入场景下的实际用法,并能结合 StarRocks BE 源码理解其“常量空列”的底层实现语义。
函数定位:返回一个空 Bitmap
bitmap_empty()返回一个不包含任何元素的空 Bitmap 对象。它本身不参与复杂的数据计算,主要价值体现在导入阶段为 BITMAP 列提供合法默认值。当源数据中没有对应位图数据、或希望初始化为“空集合”语义时,可以通过该函数直接填充,其官方定义为 "Returns an empty bitmap"(官方文档)。
典型场景:Stream Load 导入时填充 BITMAP 列默认值
在 StarRocks 中,BITMAP 类型的列无法直接接收普通的文本值,必须通过to_bitmap、bitmap_from_string等函数转换,或通过bitmap_empty()填充空值。bitmap_empty()最常见的用法就是配合 Stream Load 的columns参数,为没有位图数据的字段补默认值:
cat data | curl --location-trusted -u user:passwd -T - \ -H "columns: dt,page,v1,v2=bitmap_empty()" \ http://host:8410/api/test/testDb/_stream_load这条命令的作用是:通过管道把data文件内容通过curl -T -以 Stream Load 方式导入test.testDb表,columns参数将源数据的字段依次映射为dt、page、v1,而第四个字段v2(BITMAP 类型)没有对应的源数据列,直接由bitmap_empty()生成空位图作为默认值写入。这样即使源数据每行只有 3 个字段,也能完整写入 4 列的表结构。
同理,该函数也可以直接用在 INSERT 语句的 VALUES 或INSERT INTO ... SELECT中,作为 BITMAP 列的值表达式。
语法与参数说明
BITMAP BITMAP_EMPTY()- 返回值类型:
BITMAP,一个不含任何成员的空位图。 - 参数:无。该函数不接收任何输入参数,属于零元函数(nullary function),因此每一行的计算结果都相同。
从函数注册表看(gensrc/script/functions.py),StarRocks 以函数 ID90040注册了该函数,签名信息为BITMAP返回类型、空参数列表,底层实现绑定到 BE 的BitmapFunctions::bitmap_empty:
[90040, 'bitmap_empty', False, False, 'BITMAP', [], 'BitmapFunctions::bitmap_empty'],同时 FE 侧在 FunctionSet.java 中以常量BITMAP_EMPTY = "bitmap_empty"登记函数名,供 SQL 解析与函数解析器调用。
底层实现:生成一个常量空列
深入 BE 源码(bitmap_functions.cpp)可以看到,bitmap_empty()的实现非常精简:
StatusOr<ColumnPtr> BitmapFunctions::bitmap_empty(FunctionContext* context, const starrocks::Columns& columns) { BitmapValue bitmap; return ColumnHelper::create_const_column<TYPE_OBJECT>(&bitmap, 1); }关键点有两处:
- 构造
BitmapValue空对象:BitmapValue是 StarRocks 位图的底层数据结构(定义于 bitmap_value.h),此处直接以默认构造方式得到一个不含任何元素的空位图。 - 包装为常量列:通过
ColumnHelper::create_const_column<TYPE_OBJECT>(&bitmap, 1)将其封装为大小为 1 的常量列(const column)。常量列在向量化执行引擎中代表整列共享同一个值,无需为每行重复存储,这也是为什么bitmap_empty()在任意行数下都只有一份真实数据、内存开销极低。
需要说明的是,这里返回的是“结构上为空”的位图:其存储表示中不包含任何已加入的成员,序列化后的字节数极小。因此它天然适合作为导入默认值——不会引入多余的数据膨胀。
使用示例:与 bitmap_count 组合验证空集
bitmap_empty()常与bitmap_count()(统计位图基数,注册于 functions.py)搭配验证其“空集”语义。官方示例:
MySQL > select bitmap_count(bitmap_empty()); +------------------------------+ | bitmap_count(bitmap_empty()) | +------------------------------+ | 0 | +------------------------------+空位图的基数(cardinality)为 0,因此bitmap_count(bitmap_empty())恒等于 0。这一点在 BE 的bitmap_count实现中也有印证(bitmap_functions.cpp):它遍历输入列并调用viewer.value(row)->cardinality()获取每个位图的基数,空位图自然返回 0。若 BITMAP 列本身为 NULL,则bitmap_count按 0 处理。
测试验证:BE 单元测试覆盖
StarRocks 在 be/test/exprs/bitmap_functions_test.cpp 中为该函数编写了专项单测bitmapEmptyTest:
TEST_F(VecBitmapFunctionsTest, bitmapEmptyTest) { { Columns c; auto column = BitmapFunctions::bitmap_empty(ctx, c).value(); ASSERT_TRUE(column->is_constant()); auto* bitmap = ColumnHelper::get_const_value<TYPE_OBJECT>(column); ASSERT_EQ(1, bitmap->get_size_in_bytes()); } }该测试断言了两个核心事实:
- 结果为常量列:
column->is_constant()为真,验证了“常量空列”的实现语义; - 序列化大小极小:空位图序列化后仅占
1字节(存储层为区分空与非空位图预留的标记字节),进一步佐证其作为默认值不会带来存储开销。
与相关 Bitmap 函数的配合使用
bitmap_empty()属于 StarRocks Bitmap 函数族(完整索引见 bitmap-functions.mdx),理解它与邻近函数的差异有助于正确选型:
| 函数 | 返回值 | 用途与差异 |
|---|---|---|
bitmap_empty() | 空 BITMAP | 构造空集,多用于导入默认值填充 |
to_bitmap(expr) | BITMAP | 将整数/字符串转换为位图,可参考 to_bitmap 文档 |
bitmap_from_string(str) | BITMAP | 从逗号分隔字符串构造位图,参考 bitmap_from_string 文档 |
bitmap_count(bitmap) | BIGINT | 统计位图基数,参考 bitmap_count 文档 |
base64_to_bitmap(str) | BITMAP | 从 Base64 编码反序列化位图,参考 base64_to_bitmap 文档 |
实践中的典型搭配是:bitmap_empty()负责“兜底空集”,bitmap_count()负责“检验空集”,to_bitmap()/bitmap_from_string()/base64_to_bitmap()负责“从业务数据构造真实位图”。
使用前提与注意事项
- 适用场景:主要用于 INSERT / Stream Load 导入阶段为 BITMAP 列填充默认值,避免因缺少位图数据而导致导入失败;也可在查询中用于构造空集参与集合运算。
- 空集语义:
bitmap_empty()返回的是合法的空位图对象,而非 SQLNULL。若业务希望将列写为 NULL,则应使用NULL字面量而不是本函数;二者的区别可通过bitmap_count(NULL)与bitmap_count(bitmap_empty())的行为差异来观察。 - 平台与版本:该函数注册于 FE 函数表(FunctionSet.java)并由 BE 向量化执行引擎统一实现,在支持 BITMAP 类型的数据模型(如明细表、聚合表的
BITMAP_UNION聚合列)中均可使用。 - 无参数约束:该函数不接受参数,也不依赖行上下文,属于纯常量函数,可直接出现在 VALUES 列表、
columns映射或 SELECT 投影中。
小结
bitmap_empty()虽然只是一个小函数,却是 StarRocks BITMAP 类型导入链路上不可或缺的“默认值填充器”。通过 Stream Load 的columns映射或 INSERT 语句即可零成本地为 BITMAP 列兜底;其 BE 实现(bitmap_functions.cpp)以常量列方式返回空BitmapValue,配合单测(bitmap_functions_test.cpp)保证了极低的存储开销与确定的空集语义,是理解 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),仅供参考