| 204 | } |
| 205 | |
| 206 | static Status GetTimestampMetadata(const ::arrow::TimestampType& type, |
| 207 | const WriterProperties& properties, |
| 208 | const ArrowWriterProperties& arrow_properties, |
| 209 | ParquetType::type* physical_type, |
| 210 | std::shared_ptr<const LogicalType>* logical_type) { |
| 211 | const bool coerce = arrow_properties.coerce_timestamps_enabled(); |
| 212 | const auto target_unit = |
| 213 | coerce ? arrow_properties.coerce_timestamps_unit() : type.unit(); |
| 214 | const auto version = properties.version(); |
| 215 | |
| 216 | // The user is explicitly asking for Impala int96 encoding, there is no |
| 217 | // logical type. |
| 218 | if (arrow_properties.support_deprecated_int96_timestamps()) { |
| 219 | *physical_type = ParquetType::INT96; |
| 220 | return Status::OK(); |
| 221 | } |
| 222 | |
| 223 | *physical_type = ParquetType::INT64; |
| 224 | *logical_type = TimestampLogicalTypeFromArrowTimestamp(type, target_unit); |
| 225 | |
| 226 | // The user is explicitly asking for timestamp data to be converted to the |
| 227 | // specified units (target_unit). |
| 228 | if (coerce) { |
| 229 | if (version == ::parquet::ParquetVersion::PARQUET_1_0 || |
| 230 | version == ::parquet::ParquetVersion::PARQUET_2_4) { |
| 231 | switch (target_unit) { |
| 232 | case ::arrow::TimeUnit::MILLI: |
| 233 | case ::arrow::TimeUnit::MICRO: |
| 234 | break; |
| 235 | case ::arrow::TimeUnit::NANO: |
| 236 | case ::arrow::TimeUnit::SECOND: |
| 237 | return Status::NotImplemented("For Parquet version ", |
| 238 | ::parquet::ParquetVersionToString(version), |
| 239 | ", can only coerce Arrow timestamps to " |
| 240 | "milliseconds or microseconds"); |
| 241 | } |
| 242 | } else { |
| 243 | switch (target_unit) { |
| 244 | case ::arrow::TimeUnit::MILLI: |
| 245 | case ::arrow::TimeUnit::MICRO: |
| 246 | case ::arrow::TimeUnit::NANO: |
| 247 | break; |
| 248 | case ::arrow::TimeUnit::SECOND: |
| 249 | return Status::NotImplemented("For Parquet version ", |
| 250 | ::parquet::ParquetVersionToString(version), |
| 251 | ", can only coerce Arrow timestamps to " |
| 252 | "milliseconds, microseconds, or nanoseconds"); |
| 253 | } |
| 254 | } |
| 255 | return Status::OK(); |
| 256 | } |
| 257 | |
| 258 | // The user implicitly wants timestamp data to retain its original time units, |
| 259 | // however the ConvertedType field used to indicate logical types for Parquet |
| 260 | // version <= 2.4 fields does not allow for nanosecond time units and so nanoseconds |
| 261 | // must be coerced to microseconds. |
| 262 | if ((version == ::parquet::ParquetVersion::PARQUET_1_0 || |
| 263 | version == ::parquet::ParquetVersion::PARQUET_2_4) && |
no test coverage detected