diff --git a/cpp/src/gandiva/array_ops.cc b/cpp/src/gandiva/array_ops.cc index 64548bf09abbc..a441aabffb2c5 100644 --- a/cpp/src/gandiva/array_ops.cc +++ b/cpp/src/gandiva/array_ops.cc @@ -116,6 +116,36 @@ bool array_contains_template(const Type* entry_buf, return false; } +template +char* array_to_string_template(const Type* entry_buf, + int32_t entry_len, const int32_t* entry_validity, bool combined_row_validity, + const char* delimiter) { + bool first_element = true; + + const int32_t* entry_validityAdjusted = entry_validity - entry_len; + int64_t validityBitIndex = -entry_len; + std::string result; // Initialize the result variable as an empty string + + for (int i = 0; i < entry_len; i++) { + if (!arrow::bit_util::GetBit(reinterpret_cast(entry_validityAdjusted), validityBitIndex + i)) { + continue; + } + + if (!first_element) { + result += delimiter; + } + + Type entry_item = *(entry_buf + i); + result += std::to_string(entry_item); + + first_element = false; + } + + char* result_char = new char[result.length() + 1]; + std::strcpy(result_char, result.c_str()); + return result_char; +} + extern "C" { bool array_int32_contains_int32(int64_t context_ptr, const int32_t* entry_buf, @@ -208,6 +238,35 @@ double* array_float64_remove(int64_t context_ptr, const double* entry_buf, loop_var, validity_index_var, valid_row, out_len, valid_ptr); } + +bool array_int32_to_string(int64_t context_ptr, const int32_t* entry_buf, + int32_t entry_len, const int32_t* entry_validity, bool combined_row_validity, + int32_t contains_data, bool contains_data_valid, + const char* delimiter) { + return array_to_string_template(entry_buf, entry_len, entry_validity, + combined_row_validity, delimiter); +} + +bool array_int64_to_string(int64_t context_ptr, const int64_t* entry_buf, + int32_t entry_len, const int32_t* entry_validity, bool combined_row_validity, + const char* delimiter) { + return array_to_string_template(entry_buf, entry_len, entry_validity, + combined_row_validity, delimiter); +} + +bool array_float32_to_string(int64_t context_ptr, const float* entry_buf, + int32_t entry_len, const int32_t* entry_validity, bool combined_row_validity, + const char* delimiter) { + return array_to_string_template(entry_buf, entry_len, entry_validity, + combined_row_validity, delimiter); +} + +bool array_float64_to_string(int64_t context_ptr, const double* entry_buf, + int32_t entry_len, const int32_t* entry_validity, bool combined_row_validity, + const char* delimiter) { + return array_to_string_template(entry_buf, entry_len, entry_validity, + combined_row_validity, delimiter); +} } namespace gandiva { diff --git a/cpp/src/gandiva/function_registry_array.cc b/cpp/src/gandiva/function_registry_array.cc index 893ba6e3d2b04..b980051697501 100644 --- a/cpp/src/gandiva/function_registry_array.cc +++ b/cpp/src/gandiva/function_registry_array.cc @@ -47,6 +47,19 @@ std::vector GetArrayFunctionRegistry() { NativeFunction("array_remove", {}, DataTypeVector{list(float64()), float64()}, list(float64()), kResultNullInternal, "array_float64_remove", NativeFunction::kNeedsContext), + + NativeFunction("array_to_string", {}, DataTypeVector{list(int32()), utf8()}, + utf8(), kResultNullInternal, "array_int32_to_string", + NativeFunction::kNeedsContext), + NativeFunction("array_to_string", {}, DataTypeVector{list(int64()), utf8()}, + utf8(), kResultNullInternal, "array_int64_to_string", + NativeFunction::kNeedsContext), + NativeFunction("array_to_string", {}, DataTypeVector{list(float32()), utf8()}, + utf8(), kResultNullInternal, "array_float32_to_string", + NativeFunction::kNeedsContext), + NativeFunction("array_to_string", {}, DataTypeVector{list(float64()), utf8()}, + utf8(), kResultNullInternal, "array_float64_to_string", + NativeFunction::kNeedsContext), }; return array_fn_registry_; }