Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cpp/src/gandiva/function_holder_maker_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ FunctionHolderMakerRegistry::MakerMap FunctionHolderMakerRegistry::DefaultHolder
{"to_date", HolderMaker<ToDateHolder>},
{"random", HolderMaker<RandomGeneratorHolder>},
{"rand", HolderMaker<RandomGeneratorHolder>},
{"rand_integer", HolderMaker<RandomIntegerGeneratorHolder>},
{"regexp_replace", HolderMaker<ReplaceHolder>},
{"regexp_extract", HolderMaker<ExtractHolder>},
{"castintervalday", HolderMaker<IntervalDaysHolder>},
Expand Down
8 changes: 8 additions & 0 deletions cpp/src/gandiva/function_registry_math_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ std::vector<NativeFunction> GetMathOpsFunctionRegistry() {
"gdv_fn_random", NativeFunction::kNeedsFunctionHolder),
NativeFunction("random", {"rand"}, DataTypeVector{int32()}, float64(),
kResultNullNever, "gdv_fn_random_with_seed",
NativeFunction::kNeedsFunctionHolder),
NativeFunction("rand_integer", {}, DataTypeVector{}, int32(), kResultNullNever,
"gdv_fn_rand_integer", NativeFunction::kNeedsFunctionHolder),
NativeFunction("rand_integer", {}, DataTypeVector{int32()}, int32(),
kResultNullNever, "gdv_fn_rand_integer_with_range",
NativeFunction::kNeedsFunctionHolder),
NativeFunction("rand_integer", {}, DataTypeVector{int32(), int32()}, int32(),
kResultNullNever, "gdv_fn_rand_integer_with_min_max",
NativeFunction::kNeedsFunctionHolder)};

return math_fn_registry_;
Expand Down
39 changes: 38 additions & 1 deletion cpp/src/gandiva/gdv_function_stubs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,33 @@ double gdv_fn_random(int64_t ptr) {
return (*holder)();
}

double gdv_fn_random_with_seed(int64_t ptr, int32_t seed, bool seed_validity) {
double gdv_fn_random_with_seed(int64_t ptr, int32_t /*seed*/, bool /*seed_validity*/) {
gandiva::RandomGeneratorHolder* holder =
reinterpret_cast<gandiva::RandomGeneratorHolder*>(ptr);
return (*holder)();
}

int32_t gdv_fn_rand_integer(int64_t ptr) {
gandiva::RandomIntegerGeneratorHolder* holder =
reinterpret_cast<gandiva::RandomIntegerGeneratorHolder*>(ptr);
return (*holder)();
}

int32_t gdv_fn_rand_integer_with_range(int64_t ptr, int32_t /*range*/,
bool /*range_validity*/) {
gandiva::RandomIntegerGeneratorHolder* holder =
reinterpret_cast<gandiva::RandomIntegerGeneratorHolder*>(ptr);
return (*holder)();
}

int32_t gdv_fn_rand_integer_with_min_max(int64_t ptr, int32_t /*min*/,
bool /*min_validity*/, int32_t /*max*/,
bool /*max_validity*/) {
gandiva::RandomIntegerGeneratorHolder* holder =
reinterpret_cast<gandiva::RandomIntegerGeneratorHolder*>(ptr);
return (*holder)();
}

bool gdv_fn_in_expr_lookup_int32(int64_t ptr, int32_t value, bool in_validity) {
if (!in_validity) {
return false;
Expand Down Expand Up @@ -936,6 +957,22 @@ arrow::Status ExportedStubFunctions::AddMappings(Engine* engine) const {
engine->AddGlobalMappingForFunc("gdv_fn_random_with_seed", types->double_type(), args,
reinterpret_cast<void*>(gdv_fn_random_with_seed));

// gdv_fn_rand_integer
args = {types->i64_type()};
engine->AddGlobalMappingForFunc("gdv_fn_rand_integer", types->i32_type(), args,
reinterpret_cast<void*>(gdv_fn_rand_integer));

args = {types->i64_type(), types->i32_type(), types->i1_type()};
engine->AddGlobalMappingForFunc(
"gdv_fn_rand_integer_with_range", types->i32_type(), args,
reinterpret_cast<void*>(gdv_fn_rand_integer_with_range));

args = {types->i64_type(), types->i32_type(), types->i1_type(), types->i32_type(),
types->i1_type()};
engine->AddGlobalMappingForFunc(
"gdv_fn_rand_integer_with_min_max", types->i32_type(), args,
reinterpret_cast<void*>(gdv_fn_rand_integer_with_min_max));

// gdv_fn_dec_from_string
args = {
types->i64_type(), // context
Expand Down
61 changes: 61 additions & 0 deletions cpp/src/gandiva/gdv_function_stubs_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <limits>

#include "arrow/util/logging.h"
#include "gandiva/execution_context.h"
#include "gandiva/encrypt_utils_ecb.h"
Expand Down Expand Up @@ -353,6 +355,14 @@ TEST(TestGdvFnStubs, TestCastVARCHARFromInt64) {
out_str = gdv_fn_castVARCHAR_int64_int64(ctx_ptr, 12345, 3, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "123");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_int64_int64(ctx_ptr, 347, 0, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_int64_int64(ctx_ptr, 347, -1, &out_len);
EXPECT_THAT(ctx.get_error(), ::testing::HasSubstr("Buffer length cannot be negative"));
ctx.Reset();
}

TEST(TestGdvFnStubs, TestCastVARCHARFromMilliseconds) {
Expand Down Expand Up @@ -384,6 +394,15 @@ TEST(TestGdvFnStubs, TestCastVARCHARFromMilliseconds) {
out_str = gdv_fn_castVARCHAR_date64_int64(ctx_ptr, ts, 4, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "2008");
EXPECT_FALSE(ctx.has_error());

ts = StringToTimestamp("2021-04-23 10:20:33");
out_str = gdv_fn_castVARCHAR_date64_int64(ctx_ptr, ts, 0, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_date64_int64(ctx_ptr, ts, -1, &out_len);
EXPECT_THAT(ctx.get_error(), ::testing::HasSubstr("Buffer length cannot be negative"));
ctx.Reset();
}

TEST(TestGdvFnStubs, TestCastVARCHARFromFloat) {
Expand Down Expand Up @@ -419,6 +438,14 @@ TEST(TestGdvFnStubs, TestCastVARCHARFromFloat) {
out_str = gdv_fn_castVARCHAR_float32_int64(ctx_ptr, 1.2345f, 3, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "1.2");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_float32_int64(ctx_ptr, 1.2345f, 0, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_float32_int64(ctx_ptr, 1.2345f, -1, &out_len);
EXPECT_THAT(ctx.get_error(), ::testing::HasSubstr("Buffer length cannot be negative"));
ctx.Reset();
}

TEST(TestGdvFnStubs, TestCastVARCHARFromDouble) {
Expand Down Expand Up @@ -454,6 +481,25 @@ TEST(TestGdvFnStubs, TestCastVARCHARFromDouble) {
out_str = gdv_fn_castVARCHAR_float64_int64(ctx_ptr, 1.2345, 3, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "1.2");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_float64_int64(ctx_ptr, 1.2345, 0, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_castVARCHAR_float64_int64(ctx_ptr, 1.2345, -1, &out_len);
EXPECT_THAT(ctx.get_error(), ::testing::HasSubstr("Buffer length cannot be negative"));
ctx.Reset();

// test long repeating decimal (1/3) with large buffer
out_str = gdv_fn_castVARCHAR_float64_int64(ctx_ptr, 1.0 / 3.0, 100, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "0.3333333333333333");
EXPECT_FALSE(ctx.has_error());

// test exponential notation with large negative exponent (24 chars)
out_str =
gdv_fn_castVARCHAR_float64_int64(ctx_ptr, -1.2345678901234567e-100, 100, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "-1.2345678901234567E-100");
EXPECT_FALSE(ctx.has_error());
}

TEST(TestGdvFnStubs, TestSubstringIndex) {
Expand Down Expand Up @@ -529,6 +575,21 @@ TEST(TestGdvFnStubs, TestSubstringIndex) {
out_str = gdv_fn_substring_index(ctx_ptr, "路学\\L", 8, "\\", 1, -1, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "L");
EXPECT_FALSE(ctx.has_error());

// Large counts return full string when delimiter not found enough times
out_str = gdv_fn_substring_index(ctx_ptr, "a.b.c", 5, ".", 1, -1000, &out_len);
EXPECT_EQ(std::string(out_str, out_len), "a.b.c");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_substring_index(ctx_ptr, "a.b.c", 5, ".", 1,
std::numeric_limits<int32_t>::max(), &out_len);
EXPECT_EQ(std::string(out_str, out_len), "a.b.c");
EXPECT_FALSE(ctx.has_error());

out_str = gdv_fn_substring_index(ctx_ptr, "a.b.c", 5, ".", 1,
std::numeric_limits<int32_t>::min(), &out_len);
EXPECT_EQ(std::string(out_str, out_len), "a.b.c");
EXPECT_FALSE(ctx.has_error());
}

TEST(TestGdvFnStubs, TestUpper) {
Expand Down
Loading
Loading