| 1065 | |
| 1066 | template <typename T> |
| 1067 | void exportStrings( |
| 1068 | const FlatVector<StringView>& vec, |
| 1069 | const Selection& rows, |
| 1070 | ArrowArray& out, |
| 1071 | memory::MemoryPool* pool, |
| 1072 | BoltToArrowBridgeHolder& holder) { |
| 1073 | static_assert( |
| 1074 | std::is_same_v<T, int32_t> || std::is_same_v<T, int64_t>, |
| 1075 | "T must be either int32_t or int64_t"); |
| 1076 | out.n_buffers = 3; |
| 1077 | size_t bufSize = 0; |
| 1078 | rows.apply([&](vector_size_t i) { |
| 1079 | BOLT_CHECK_LT(i, vec.size()); |
| 1080 | if (!vec.isNullAt(i)) { |
| 1081 | bufSize += vec.valueAtFast(i).size(); |
| 1082 | } |
| 1083 | }); |
| 1084 | if constexpr (std::is_same_v<T, int32_t>) { |
| 1085 | BOLT_CHECK_LT( |
| 1086 | bufSize, |
| 1087 | std::numeric_limits<int32_t>::max(), |
| 1088 | "Cannot export VARCHAR/VARBINARY to Arrow with int32 offsets: " |
| 1089 | "rows={}, vectorSize={}, bufSize={}", |
| 1090 | rows.count(), |
| 1091 | vec.size(), |
| 1092 | bufSize); |
| 1093 | } |
| 1094 | holder.setBuffer(2, AlignedBuffer::allocate<char>(bufSize, pool)); |
| 1095 | char* rawBuffer = holder.getBufferAs<char>(2); |
| 1096 | auto offsetLen = checkedPlus<size_t>(out.length, 1); |
| 1097 | holder.setBuffer(1, AlignedBuffer::allocate<T>(offsetLen, pool)); |
| 1098 | auto* rawOffsets = holder.getBufferAs<T>(1); |
| 1099 | *rawOffsets = 0; |
| 1100 | rows.apply([&](vector_size_t i) { |
| 1101 | auto newOffset = *rawOffsets; |
| 1102 | BOLT_CHECK_LT(i, vec.size()); |
| 1103 | if (!vec.isNullAt(i)) { |
| 1104 | auto sv = vec.valueAtFast(i); |
| 1105 | memcpy(rawBuffer, sv.data(), sv.size()); |
| 1106 | rawBuffer += sv.size(); |
| 1107 | newOffset += sv.size(); |
| 1108 | } |