Skip to content

Commit 919c890

Browse files
singchafacebook-github-bot
authored andcommitted
feat: Add decimal support in histogram aggregate (facebookincubator#12811)
Summary: Pull Request resolved: facebookincubator#12811 Add long decimal support in histogram aggregate. Short decimal is handled through BIGINT Reviewed By: kgpai Differential Revision: D71860678 fbshipit-source-id: 1c8b32fba1b282196573500f42f32e2abf9a2328
1 parent ef9c7f3 commit 919c890

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

velox/functions/prestosql/aggregates/HistogramAggregate.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,11 @@ void registerHistogramAggregate(
624624
case TypeKind::ROW:
625625
return std::make_unique<HistogramAggregate<ComplexType>>(
626626
resultType);
627+
case TypeKind::HUGEINT:
628+
if (inputType->isLongDecimal()) {
629+
return std::make_unique<HistogramAggregate<int128_t>>(resultType);
630+
}
631+
[[fallthrough]];
627632
case TypeKind::UNKNOWN:
628633
return std::make_unique<HistogramAggregate<int8_t>>(resultType);
629634
default:

velox/functions/prestosql/aggregates/tests/HistogramTest.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ namespace facebook::velox::aggregate::test {
2828

2929
namespace {
3030

31+
constexpr int64_t kLongMax = std::numeric_limits<int64_t>::max();
32+
constexpr int64_t kLongMin = std::numeric_limits<int64_t>::min();
33+
constexpr int128_t kHugeMax = std::numeric_limits<int128_t>::max();
34+
constexpr int128_t kHugeMin = std::numeric_limits<int128_t>::min();
35+
3136
class HistogramTest : public AggregationTestBase {
3237
protected:
3338
void SetUp() override {
@@ -234,6 +239,136 @@ TEST_F(HistogramTest, groupByTimestampWithTimezones) {
234239
testHistogram("histogram(c1)", {"c0"}, keys, vector, expected);
235240
}
236241

242+
TEST_F(HistogramTest, groupByLongDecimal) {
243+
auto type = DECIMAL(30, 2);
244+
245+
auto vector = makeFlatVector<int128_t>({1000, 1001, 1002, 1003, 1000}, type);
246+
auto keys = makeFlatVector<int16_t>(5, [](auto row) { return row % 2; });
247+
auto expected = makeRowVector(
248+
{makeFlatVector<int16_t>({0, 1}),
249+
makeMapVector<int128_t, int64_t>(
250+
{{{{1000}, 2}, {{1002}, 1}}, {{{1001}, 1}, {{1003}, 1}}},
251+
MAP(type, BIGINT()))});
252+
253+
testHistogram("histogram(c1)", {"c0"}, keys, vector, expected);
254+
255+
// with commonly used precision & scale
256+
auto type1 = DECIMAL(38, 0);
257+
auto vector1 = makeFlatVector<int128_t>({1000, 1001, 1002, 1003, 1000}, type);
258+
auto keys1 = makeFlatVector<int16_t>(5, [](auto row) { return row % 2; });
259+
auto expected1 = makeRowVector(
260+
{makeFlatVector<int16_t>({0, 1}),
261+
makeMapVector<int128_t, int64_t>(
262+
{{{{1000}, 2}, {{1002}, 1}}, {{{1001}, 1}, {{1003}, 1}}},
263+
MAP(type, BIGINT()))});
264+
265+
testHistogram("histogram(c1)", {"c0"}, keys1, vector1, expected1);
266+
}
267+
268+
TEST_F(HistogramTest, groupByShortDecimal) {
269+
auto type = DECIMAL(5, 2);
270+
271+
auto vector = makeFlatVector<int64_t>({1000, 1001, 1002, 1003, 1000}, type);
272+
auto keys = makeFlatVector<int16_t>(5, [](auto row) { return row % 2; });
273+
auto expected = makeRowVector(
274+
{makeFlatVector<int16_t>({0, 1}),
275+
makeMapVector<int64_t, int64_t>(
276+
{{{{1000}, 2}, {{1002}, 1}}, {{{1001}, 1}, {{1003}, 1}}},
277+
MAP(type, BIGINT()))});
278+
279+
testHistogram("histogram(c1)", {"c0"}, keys, vector, expected);
280+
}
281+
282+
TEST_F(HistogramTest, globalLongDecimal) {
283+
auto type = DECIMAL(30, 2);
284+
285+
auto vector = makeFlatVector<int128_t>(
286+
{10023, kHugeMax, 20035, 10023, kHugeMin, 40033, kHugeMin}, type);
287+
auto expected = makeRowVector({makeMapVector<int128_t, int64_t>(
288+
{{{{kHugeMin}, 2},
289+
{{10023}, 2},
290+
{{20035}, 1},
291+
{{40033}, 1},
292+
{{kHugeMax}, 1}}},
293+
MAP(type, BIGINT()))});
294+
295+
testHistogram("histogram(c1)", {}, vector, vector, expected);
296+
297+
// with nullable vectors
298+
auto vectorWithNulls = makeNullableFlatVector<int128_t>(
299+
{10023,
300+
kHugeMax,
301+
std::nullopt,
302+
std::nullopt,
303+
20035,
304+
10023,
305+
kHugeMin,
306+
40033,
307+
std::nullopt,
308+
kHugeMin},
309+
type);
310+
auto expectedResultWithNullInputs =
311+
makeRowVector({makeMapVector<int128_t, int64_t>(
312+
{{{{kHugeMin}, 2},
313+
{{10023}, 2},
314+
{{20035}, 1},
315+
{{40033}, 1},
316+
{{kHugeMax}, 1}}},
317+
MAP(type, BIGINT()))});
318+
319+
testHistogram(
320+
"histogram(c1)",
321+
{},
322+
vectorWithNulls,
323+
vectorWithNulls,
324+
expectedResultWithNullInputs);
325+
}
326+
327+
TEST_F(HistogramTest, gllobalShortDecimal) {
328+
auto type = DECIMAL(5, 2);
329+
330+
auto vector = makeFlatVector<int64_t>(
331+
{10023, kLongMax, 20035, 10023, kLongMin, 40033, kLongMin}, type);
332+
auto expected = makeRowVector({makeMapVector<int64_t, int64_t>(
333+
{{{{kLongMin}, 2},
334+
{{10023}, 2},
335+
{{20035}, 1},
336+
{{40033}, 1},
337+
{{kLongMax}, 1}}},
338+
MAP(type, BIGINT()))});
339+
340+
testHistogram("histogram(c1)", {}, vector, vector, expected);
341+
342+
// with nullable vectors
343+
auto vectorWithNulls = makeNullableFlatVector<int64_t>(
344+
{10023,
345+
kLongMax,
346+
std::nullopt,
347+
std::nullopt,
348+
20035,
349+
10023,
350+
kLongMin,
351+
40033,
352+
std::nullopt,
353+
kLongMin},
354+
type);
355+
auto expectedResultWithNullInputs =
356+
makeRowVector({makeMapVector<int64_t, int64_t>(
357+
{{{{kLongMin}, 2},
358+
{{10023}, 2},
359+
{{20035}, 1},
360+
{{40033}, 1},
361+
{{kLongMax}, 1}}},
362+
MAP(type, BIGINT()))});
363+
364+
testHistogram(
365+
"histogram(c1)",
366+
{},
367+
vectorWithNulls,
368+
vectorWithNulls,
369+
expectedResultWithNullInputs);
370+
}
371+
237372
TEST_F(HistogramTest, globalInteger) {
238373
vector_size_t num = 29;
239374
auto vector = makeFlatVector<int32_t>(

0 commit comments

Comments
 (0)