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