| 121 | } |
| 122 | |
| 123 | std::string FormatDecimalValue(Type::type parquet_type, ::std::string_view val, |
| 124 | const std::shared_ptr<const LogicalType>& logical_type) { |
| 125 | ARROW_DCHECK(logical_type != nullptr && logical_type->is_decimal()); |
| 126 | |
| 127 | const auto& decimal_type = |
| 128 | ::arrow::internal::checked_cast<const DecimalLogicalType&>(*logical_type); |
| 129 | const int32_t scale = decimal_type.scale(); |
| 130 | |
| 131 | std::stringstream result; |
| 132 | switch (parquet_type) { |
| 133 | case Type::INT32: { |
| 134 | int32_t int_value{}; |
| 135 | std::memcpy(&int_value, val.data(), std::min(sizeof(int32_t), val.size())); |
| 136 | ::arrow::Decimal128 decimal_value(int_value); |
| 137 | result << decimal_value.ToString(scale); |
| 138 | break; |
| 139 | } |
| 140 | case Type::INT64: { |
| 141 | int64_t long_value{}; |
| 142 | std::memcpy(&long_value, val.data(), std::min(sizeof(int64_t), val.size())); |
| 143 | ::arrow::Decimal128 decimal_value(long_value); |
| 144 | result << decimal_value.ToString(scale); |
| 145 | break; |
| 146 | } |
| 147 | case Type::FIXED_LEN_BYTE_ARRAY: |
| 148 | case Type::BYTE_ARRAY: { |
| 149 | auto decimal_result = ::arrow::Decimal256::FromBigEndian( |
| 150 | reinterpret_cast<const uint8_t*>(val.data()), static_cast<int32_t>(val.size())); |
| 151 | if (!decimal_result.ok()) { |
| 152 | throw ParquetException("Failed to parse decimal value: ", |
| 153 | decimal_result.status().message()); |
| 154 | } |
| 155 | result << decimal_result.ValueUnsafe().ToString(scale); |
| 156 | break; |
| 157 | } |
| 158 | default: |
| 159 | throw ParquetException("Unsupported decimal type: ", TypeToString(parquet_type)); |
| 160 | } |
| 161 | |
| 162 | return result.str(); |
| 163 | } |
| 164 | |
| 165 | std::string FormatNonUTF8Value(::std::string_view val) { |
| 166 | if (val.empty()) { |
no test coverage detected