Skip to content
Open
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
74 changes: 73 additions & 1 deletion src/iceberg/arrow_row_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
* under the License.
*/

#include <utility>
#include <map>
#include <span>
#include <vector>

#include <nanoarrow/nanoarrow.h>

Expand Down Expand Up @@ -109,12 +111,49 @@ Status AppendInt(ArrowArray* array, int64_t value) {
return {};
}

Status AppendUInt(ArrowArray* array, uint64_t value) {
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayAppendUInt(array, value));
return {};
}

Status AppendDouble(ArrowArray* array, double value) {
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayAppendDouble(array, value));
return {};
}

Status AppendString(ArrowArray* array, std::string_view value) {
ArrowStringView view(value.data(), static_cast<int64_t>(value.size()));
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayAppendString(array, view));
return {};
}

Status AppendBytes(ArrowArray* array, std::span<const uint8_t> value) {
ArrowBufferViewData data;
data.as_char = reinterpret_cast<const char*>(value.data());
ArrowBufferView view(data, static_cast<int64_t>(value.size()));
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayAppendBytes(array, view));
return {};
}

Status AppendIntList(ArrowArray* array, const std::vector<int32_t>& values) {
auto list_array = array->children[0];
for (const auto& value : values) {
ICEBERG_NANOARROW_RETURN_UNEXPECTED(
ArrowArrayAppendInt(list_array, static_cast<int64_t>(value)));
}
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array));
return {};
}

Status AppendIntList(ArrowArray* array, const std::vector<int64_t>& values) {
auto list_array = array->children[0];
for (const auto& value : values) {
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayAppendInt(list_array, value));
}
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array));
return {};
}

Status AppendStringMap(ArrowArray* array,
const std::unordered_map<std::string, std::string>& entries) {
// A nanoarrow map array is a list of struct<key, value>. children[0] is the
Expand All @@ -134,4 +173,37 @@ Status AppendStringMap(ArrowArray* array,
return {};
}

Status AppendIntMap(ArrowArray* array, const std::map<int32_t, int64_t>& entries) {
auto map_array = array->children[0];
if (map_array->n_children != 2) {
return InvalidArrowData("Map array must have exactly 2 children.");
}
for (const auto& [key, value] : entries) {
auto key_array = map_array->children[0];
auto value_array = map_array->children[1];
ICEBERG_RETURN_UNEXPECTED(AppendInt(key_array, static_cast<int64_t>(key)));
ICEBERG_RETURN_UNEXPECTED(AppendInt(value_array, value));
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(map_array));
}
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array));
return {};
}

Status AppendBinaryMap(ArrowArray* array,
const std::map<int32_t, std::vector<uint8_t>>& entries) {
auto map_array = array->children[0];
if (map_array->n_children != 2) {
return InvalidArrowData("Map array must have exactly 2 children.");
}
for (const auto& [key, value] : entries) {
auto key_array = map_array->children[0];
auto value_array = map_array->children[1];
ICEBERG_RETURN_UNEXPECTED(AppendInt(key_array, static_cast<int64_t>(key)));
ICEBERG_RETURN_UNEXPECTED(AppendBytes(value_array, value));
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(map_array));
}
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array));
return {};
}

} // namespace iceberg
28 changes: 28 additions & 0 deletions src/iceberg/arrow_row_builder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
/// boilerplate.

#include <cstdint>
#include <map>
#include <span>
#include <string_view>
#include <unordered_map>
#include <vector>

#include "iceberg/arrow_c_data.h"
#include "iceberg/iceberg_export.h"
Expand Down Expand Up @@ -113,14 +116,39 @@ ICEBERG_EXPORT Status AppendBoolean(ArrowArray* array, bool value);
/// Works for int32/int64/timestamp columns, which nanoarrow stores as int64.
ICEBERG_EXPORT Status AppendInt(ArrowArray* array, int64_t value);

/// \brief Append an unsigned integer value to a nanoarrow array builder.
ICEBERG_EXPORT Status AppendUInt(ArrowArray* array, uint64_t value);

/// \brief Append a double value to a nanoarrow array builder.
ICEBERG_EXPORT Status AppendDouble(ArrowArray* array, double value);

/// \brief Append a string value to a nanoarrow array builder.
ICEBERG_EXPORT Status AppendString(ArrowArray* array, std::string_view value);

/// \brief Append a binary value to a nanoarrow array builder.
ICEBERG_EXPORT Status AppendBytes(ArrowArray* array, std::span<const uint8_t> value);

/// \brief Append a list of int32 values to a nanoarrow list array builder.
ICEBERG_EXPORT Status AppendIntList(ArrowArray* array,
const std::vector<int32_t>& values);

/// \brief Append a list of int64 values to a nanoarrow list array builder.
ICEBERG_EXPORT Status AppendIntList(ArrowArray* array,
const std::vector<int64_t>& values);

/// \brief Append a map<string, string> value to a nanoarrow map array builder.
///
/// Appends one (possibly empty) map element. The iteration order of the
/// resulting entries is unspecified.
ICEBERG_EXPORT Status AppendStringMap(
ArrowArray* array, const std::unordered_map<std::string, std::string>& entries);

/// \brief Append a map<int32, int64> to a nanoarrow map array builder.
ICEBERG_EXPORT Status AppendIntMap(ArrowArray* array,
const std::map<int32_t, int64_t>& entries);

/// \brief Append a map<int32, binary> to a nanoarrow map array builder.
ICEBERG_EXPORT Status AppendBinaryMap(
ArrowArray* array, const std::map<int32_t, std::vector<uint8_t>>& entries);

} // namespace iceberg
Loading
Loading