|
32 | 32 | #include "parquet/file/reader.h" |
33 | 33 | #include "parquet/file/writer.h" |
34 | 34 | #include "parquet/schema.h" |
| 35 | +#include "parquet/thrift.h" |
35 | 36 | #include "parquet/types.h" |
36 | 37 | #include "parquet/util/memory.h" |
37 | 38 |
|
@@ -167,6 +168,7 @@ class TestRowGroupStatistics : public PrimitiveTypedTest<TestType> { |
167 | 168 | auto file_reader = ParquetFileReader::Open(source); |
168 | 169 | auto rg_reader = file_reader->RowGroup(0); |
169 | 170 | auto column_chunk = rg_reader->metadata()->ColumnChunk(0); |
| 171 | + if (!column_chunk->is_stats_set()) return; |
170 | 172 | std::shared_ptr<RowGroupStatistics> stats = column_chunk->statistics(); |
171 | 173 | // check values after serialization + deserialization |
172 | 174 | ASSERT_EQ(null_count, stats->null_count()); |
@@ -308,5 +310,49 @@ TYPED_TEST(TestNumericRowGroupStatistics, Merge) { |
308 | 310 | this->TestMerge(); |
309 | 311 | } |
310 | 312 |
|
| 313 | +TEST(CorruptStatistics, Basics) { |
| 314 | + ApplicationVersion version("parquet-mr version 1.8.0"); |
| 315 | + SchemaDescriptor schema; |
| 316 | + schema::NodePtr node; |
| 317 | + std::vector<schema::NodePtr> fields; |
| 318 | + // Test Physical Types |
| 319 | + fields.push_back(schema::PrimitiveNode::Make( |
| 320 | + "col1", Repetition::OPTIONAL, Type::INT32, LogicalType::NONE)); |
| 321 | + fields.push_back(schema::PrimitiveNode::Make( |
| 322 | + "col2", Repetition::OPTIONAL, Type::BYTE_ARRAY, LogicalType::NONE)); |
| 323 | + // Test Logical Types |
| 324 | + fields.push_back(schema::PrimitiveNode::Make( |
| 325 | + "col3", Repetition::OPTIONAL, Type::INT32, LogicalType::DATE)); |
| 326 | + fields.push_back(schema::PrimitiveNode::Make( |
| 327 | + "col4", Repetition::OPTIONAL, Type::INT32, LogicalType::UINT_32)); |
| 328 | + fields.push_back(schema::PrimitiveNode::Make("col5", Repetition::OPTIONAL, |
| 329 | + Type::FIXED_LEN_BYTE_ARRAY, LogicalType::INTERVAL, 12)); |
| 330 | + fields.push_back(schema::PrimitiveNode::Make( |
| 331 | + "col6", Repetition::OPTIONAL, Type::BYTE_ARRAY, LogicalType::UTF8)); |
| 332 | + node = schema::GroupNode::Make("schema", Repetition::REQUIRED, fields); |
| 333 | + schema.Init(node); |
| 334 | + |
| 335 | + format::ColumnChunk col_chunk; |
| 336 | + col_chunk.meta_data.__isset.statistics = true; |
| 337 | + auto column_chunk1 = ColumnChunkMetaData::Make( |
| 338 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(0), &version); |
| 339 | + ASSERT_TRUE(column_chunk1->is_stats_set()); |
| 340 | + auto column_chunk2 = ColumnChunkMetaData::Make( |
| 341 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(1), &version); |
| 342 | + ASSERT_FALSE(column_chunk2->is_stats_set()); |
| 343 | + auto column_chunk3 = ColumnChunkMetaData::Make( |
| 344 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(2), &version); |
| 345 | + ASSERT_TRUE(column_chunk3->is_stats_set()); |
| 346 | + auto column_chunk4 = ColumnChunkMetaData::Make( |
| 347 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(3), &version); |
| 348 | + ASSERT_FALSE(column_chunk4->is_stats_set()); |
| 349 | + auto column_chunk5 = ColumnChunkMetaData::Make( |
| 350 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(4), &version); |
| 351 | + ASSERT_FALSE(column_chunk5->is_stats_set()); |
| 352 | + auto column_chunk6 = ColumnChunkMetaData::Make( |
| 353 | + reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(5), &version); |
| 354 | + ASSERT_FALSE(column_chunk6->is_stats_set()); |
| 355 | +} |
| 356 | + |
311 | 357 | } // namespace test |
312 | 358 | } // namespace parquet |
0 commit comments