Skip to content

Commit

Permalink
Add to_hex for int32
Browse files Browse the repository at this point in the history
  • Loading branch information
jvictorhuguenin authored and anthonylouisbsb committed Jul 15, 2021
1 parent 8a2f2d6 commit 47dd546
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 10 deletions.
5 changes: 4 additions & 1 deletion cpp/src/gandiva/function_registry_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,10 @@ std::vector<NativeFunction> GetStringFunctionRegistry() {
"to_hex_binary", NativeFunction::kNeedsContext),

NativeFunction("to_hex", {"hex"}, DataTypeVector{int64()}, utf8(),
kResultNullIfNull, "to_hex_big_int", NativeFunction::kNeedsContext),
kResultNullIfNull, "to_hex_int64", NativeFunction::kNeedsContext),

NativeFunction("to_hex", {"hex"}, DataTypeVector{int32()}, utf8(),
kResultNullIfNull, "to_hex_int32", NativeFunction::kNeedsContext),

NativeFunction("from_hex", {"unhex"}, DataTypeVector{utf8()}, binary(),
kResultNullIfNull, "from_hex_utf8", NativeFunction::kNeedsContext),
Expand Down
18 changes: 17 additions & 1 deletion cpp/src/gandiva/precompiled/string_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,7 @@ const char* to_hex_binary(int64_t context, const char* text, int32_t text_len,
}

FORCE_INLINE
const char* to_hex_big_int(int64_t context, int64_t data, int32_t* out_len) {
const char* to_hex_int64(int64_t context, int64_t data, int32_t* out_len) {
const int64_t hex_long_max_size = 2 * sizeof(int64_t);
auto ret =
reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, hex_long_max_size));
Expand All @@ -2155,6 +2155,22 @@ const char* to_hex_big_int(int64_t context, int64_t data, int32_t* out_len) {
return ret;
}

FORCE_INLINE
const char* to_hex_int32(int64_t context, int32_t data, int32_t* out_len) {
const int32_t max_size = 2 * sizeof(int32_t);
auto ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, max_size));

if (ret == nullptr) {
gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
*out_len = 0;
return "";
}
snprintf(ret, max_size + 1, "%" PRIX32, data);

*out_len = static_cast<int32_t>(strlen(ret));
return ret;
}

FORCE_INLINE
const char* from_hex_utf8(int64_t context, const char* text, int32_t text_len,
int32_t* out_len) {
Expand Down
69 changes: 62 additions & 7 deletions cpp/src/gandiva/precompiled/string_ops_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1754,54 +1754,109 @@ TEST(TestStringOps, TestToHex) {
EXPECT_EQ(output, "090A090A090A090A0A0A092061206C657474405D6572");
}

TEST(TestStringOps, TestToHexNumerical) {
TEST(TestStringOps, TestToHexInt64) {
gandiva::ExecutionContext ctx;
uint64_t ctx_ptr = reinterpret_cast<int64_t>(&ctx);
int32_t out_len = 0;
const char* out_str;

int64_t max_data = INT64_MAX;
out_str = to_hex_big_int(ctx_ptr, max_data, &out_len);
out_str = to_hex_int64(ctx_ptr, max_data, &out_len);
std::string output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 16);
EXPECT_EQ(output, "7FFFFFFFFFFFFFFF");
ctx.Reset();

int64_t min_data = INT64_MIN;
out_str = to_hex_big_int(ctx_ptr, min_data, &out_len);
out_str = to_hex_int64(ctx_ptr, min_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 16);
EXPECT_EQ(output, "8000000000000000");
ctx.Reset();

int64_t zero_data = 0;
out_str = to_hex_big_int(ctx_ptr, zero_data, &out_len);
out_str = to_hex_int64(ctx_ptr, zero_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
EXPECT_EQ(output, "0");
ctx.Reset();

int64_t minus_zero_data = -0;
out_str = to_hex_big_int(ctx_ptr, minus_zero_data, &out_len);
out_str = to_hex_int64(ctx_ptr, minus_zero_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
EXPECT_EQ(output, "0");
ctx.Reset();

int64_t minus_one_data = -1;
out_str = to_hex_big_int(ctx_ptr, minus_one_data, &out_len);
out_str = to_hex_int64(ctx_ptr, minus_one_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 16);
EXPECT_EQ(output, "FFFFFFFFFFFFFFFF");
ctx.Reset();

int64_t one_data = 1;
out_str = to_hex_big_int(ctx_ptr, one_data, &out_len);
out_str = to_hex_int64(ctx_ptr, one_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
EXPECT_EQ(output, "1");
ctx.Reset();
}

TEST(TestStringOps, TestToHexInt32) {
gandiva::ExecutionContext ctx;
uint64_t ctx_ptr = reinterpret_cast<int64_t>(&ctx);
int32_t out_len = 0;
const char* out_str;

int32_t max_data = INT32_MAX;
out_str = to_hex_int32(ctx_ptr, max_data, &out_len);
std::string output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 8);
EXPECT_EQ(output, "7FFFFFFF");
ctx.Reset();

int32_t min_data = INT32_MIN;
out_str = to_hex_int32(ctx_ptr, min_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 8);
EXPECT_EQ(output, "80000000");
ctx.Reset();

int32_t zero_data = 0;
out_str = to_hex_int32(ctx_ptr, zero_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
EXPECT_EQ(output, "0");
ctx.Reset();

int32_t minus_zero_data = -0;
out_str = to_hex_int32(ctx_ptr, minus_zero_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
EXPECT_EQ(output, "0");
ctx.Reset();

int32_t minus_one_data = -1;
out_str = to_hex_int32(ctx_ptr, minus_one_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 8);
EXPECT_EQ(output, "FFFFFFFF");
ctx.Reset();

int32_t one_data = 1;
out_str = to_hex_int32(ctx_ptr, one_data, &out_len);
output = std::string(out_str, out_len);
EXPECT_FALSE(ctx.has_error());
EXPECT_EQ(out_len, 1);
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/gandiva/precompiled/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,9 @@ const char* binary_string(gdv_int64 context, const char* text, gdv_int32 text_le
const char* to_hex_binary(int64_t context, const char* text, int32_t text_len,
int32_t* out_len);

const char* to_hex_big_int(int64_t context, int64_t data, int32_t* out_len);
const char* to_hex_int64(int64_t context, int64_t data, int32_t* out_len);

const char* to_hex_int32(int64_t context, int32_t data, int32_t* out_len);

const char* from_hex_utf8(int64_t context, const char* text, int32_t text_len,
int32_t* out_len);
Expand Down

0 comments on commit 47dd546

Please sign in to comment.