Skip to content

Commit 4dfcc44

Browse files
authored
feat(query): Support bitmap_to_array function (#18927)
1 parent 154664d commit 4dfcc44

5 files changed

Lines changed: 77 additions & 3 deletions

File tree

src/query/functions/src/scalars/bitmap.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,31 @@ pub fn register(registry: &mut FunctionRegistry) {
192192
}),
193193
);
194194

195+
registry.register_passthrough_nullable_1_arg::<BitmapType, ArrayType<NumberType<u64>>, _, _>(
196+
"bitmap_to_array",
197+
|_, _| FunctionDomain::MayThrow,
198+
vectorize_with_builder_1_arg::<BitmapType, ArrayType<NumberType<u64>>>(
199+
|b, builder, ctx| {
200+
if let Some(validity) = &ctx.validity {
201+
if !validity.get_bit(builder.len()) {
202+
builder.commit_row();
203+
return;
204+
}
205+
}
206+
match deserialize_bitmap(b) {
207+
Ok(rb) => {
208+
let ids = rb.into_iter().collect::<Vec<_>>();
209+
builder.push(ids.into());
210+
}
211+
Err(e) => {
212+
ctx.set_error(builder.len(), e.to_string());
213+
builder.commit_row();
214+
}
215+
}
216+
},
217+
),
218+
);
219+
195220
registry.register_passthrough_nullable_2_arg::<BitmapType, UInt64Type, BooleanType, _, _>(
196221
"bitmap_contains",
197222
|_, _, _| FunctionDomain::Full,

src/query/functions/tests/it/scalars/bitmap.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ fn test_bitmap() {
3737
test_bitmap_subset_limit(file);
3838
test_bitmap_subset_in_range(file);
3939
test_bitmap_op(file);
40+
test_bitmap_to_array(file);
4041
}
4142

4243
fn test_build_bitmap(file: &mut impl Write) {
@@ -140,3 +141,11 @@ fn test_bitmap_op(file: &mut impl Write) {
140141
&[],
141142
);
142143
}
144+
145+
fn test_bitmap_to_array(file: &mut impl Write) {
146+
run_ast(file, "bitmap_to_array(build_bitmap([1,4,5]))", &[]);
147+
run_ast(file, "bitmap_to_array(build_bitmap([a, b]))", &[
148+
("a", UInt16Type::from_data(vec![1u16, 2, 3])),
149+
("b", UInt16Type::from_data(vec![1u16, 5, 6])),
150+
]);
151+
}

src/query/functions/tests/it/scalars/testdata/bitmap.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,35 @@ output domain : Undefined
209209
output : '3'
210210

211211

212+
ast : bitmap_to_array(build_bitmap([1,4,5]))
213+
raw expr : bitmap_to_array(build_bitmap(array(1, 4, 5)))
214+
checked expr : bitmap_to_array<Bitmap>(build_bitmap<Array(UInt8 NULL)>(CAST<Array(UInt8)>(array<T0=UInt8><T0, T0, T0>(1_u8, 4_u8, 5_u8) AS Array(UInt8 NULL))))
215+
optimized expr : [1, 4, 5]
216+
output type : Array(UInt64)
217+
output domain : [{1..=5}]
218+
output : [1, 4, 5]
219+
220+
221+
ast : bitmap_to_array(build_bitmap([a, b]))
222+
raw expr : bitmap_to_array(build_bitmap(array(a::UInt16, b::UInt16)))
223+
checked expr : bitmap_to_array<Bitmap>(build_bitmap<Array(UInt16 NULL)>(CAST<Array(UInt16)>(array<T0=UInt16><T0, T0>(a, b) AS Array(UInt16 NULL))))
224+
evaluation:
225+
+--------+---------+---------+---------------+
226+
| | a | b | Output |
227+
+--------+---------+---------+---------------+
228+
| Type | UInt16 | UInt16 | Array(UInt64) |
229+
| Domain | {1..=3} | {1..=6} | Unknown |
230+
| Row 0 | 1 | 1 | [1] |
231+
| Row 1 | 2 | 5 | [2, 5] |
232+
| Row 2 | 3 | 6 | [3, 6] |
233+
+--------+---------+---------+---------------+
234+
evaluation (internal):
235+
+--------+------------------------------------------------------------------------+
236+
| Column | Data |
237+
+--------+------------------------------------------------------------------------+
238+
| a | UInt16([1, 2, 3]) |
239+
| b | UInt16([1, 5, 6]) |
240+
| Output | ArrayColumn { values: UInt64([1, 2, 5, 3, 6]), offsets: [0, 1, 3, 5] } |
241+
+--------+------------------------------------------------------------------------+
242+
243+

src/query/functions/tests/it/scalars/testdata/function_list.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,8 @@ Functions overloads:
920920
1 bitmap_subset_in_range(Bitmap NULL, UInt64 NULL, UInt64 NULL) :: Bitmap NULL
921921
0 bitmap_subset_limit(Bitmap, UInt64, UInt64) :: Bitmap
922922
1 bitmap_subset_limit(Bitmap NULL, UInt64 NULL, UInt64 NULL) :: Bitmap NULL
923+
0 bitmap_to_array(Bitmap) :: Array(UInt64)
924+
1 bitmap_to_array(Bitmap NULL) :: Array(UInt64) NULL
923925
0 bitmap_xor(Bitmap, Bitmap) :: Bitmap
924926
1 bitmap_xor(Bitmap NULL, Bitmap NULL) :: Bitmap NULL
925927
0 blake3(String) :: String

tests/sqllogictests/suites/query/functions/02_0064_function_bitmap.test

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SELECT to_string(to_bitmap(1024))
88
----
99
1024
1010

11-
query II
11+
query TII
1212
SELECT build_bitmap([1,4,5])::String, bitmap_count(build_bitmap([1,2,5])), bitmap_count(build_bitmap([1, 66, 69, 70]))
1313
----
1414
1,4,5 3 4
@@ -72,12 +72,18 @@ SELECT sub_bitmap(build_bitmap([1, 2, 3, 4, 5]), 1, 3)::String;
7272
----
7373
2,3,4
7474

75-
query II
75+
query T
7676
SELECT bitmap_subset_limit(build_bitmap([3,5,7]), 4, 2)::String;
7777
----
7878
5,7
7979

80-
query TT
80+
query T
8181
SELECT bitmap_subset_in_range(build_bitmap([5,7,9]), 6, 9)::String;
8282
----
8383
7
84+
85+
query T
86+
SELECT bitmap_to_array(build_bitmap([1, 2, 3, 100, 10000]));
87+
----
88+
[1,2,3,100,10000]
89+

0 commit comments

Comments
 (0)