forked from apache/parquet-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PARQUET-251: Binary column statistics error when reuse byte[] among rows
Author: asingh <asingh@cloudera.com> Author: Alex Levenson <alexlevenson@twitter.com> Author: Ashish Singh <asingh@cloudera.com> Closes apache#197 from SinghAsDev/PARQUET-251 and squashes the following commits: 68e0eae [asingh] Remove deprecated constructors from private classes 67e4e5f [asingh] Add removed public methods in Binary and deprecate them 0e71728 [asingh] Add comment for BinaryStatistics.setMinMaxFromBytes fbe873f [Ashish Singh] Merge pull request apache#4 from isnotinvain/PR-197-3 9826ee6 [Alex Levenson] Some minor cleanup 7570035 [asingh] Remove test for stats getting ingnored for version 160 when type is int64 af43d28 [Alex Levenson] Address PR feedback 89ab4ee [Alex Levenson] put the headers in the right location 2838cc9 [Alex Levenson] Split out version checks to separate files, add some tests 5af9142 [Alex Levenson] Generalize tests, make Binary.fromString reused=false e00d9b7 [asingh] Rename isReused => isBackingBytesReused d2ad939 [asingh] Rebase over latest trunk 857141a [asingh] Remove redundant junit dependency 32b88ed [asingh] Remove semver from hadoop-common 7a0e99e [asingh] Revert to fromConstantByteArray for ByteString c820ec9 [asingh] Add unit tests for Binary and to check if stats are ignored for version 160 9bbd1e5 [asingh] Improve version parsing 84a1d8b [asingh] Remove ignoring stats on write side and ignore it on read side 903f8e3 [asingh] Address some review comments. * Ignore stats for writer's version < 1.8.0 * Refactor shoudlIgnoreStatistics method a bit * Assume implementations other than parquet-mr were writing binary statistics correctly * Add toParquetStatistics method's original method signature to maintain backwards compatibility and mark it as deprecated 64c2617 [asingh] Revert changes for ignoring stats at RowGroupFilter level e861b18 [asingh] Ignore max min stats while reading 3a8cb8d [asingh] Fix typo 8e12618 [asingh] Fix usage of fromConstant versions of Binary constructors 860adf7 [asingh] Rename unmodified to constant and isReused instead of isUnmodifiable 0d127a7 [asingh] Add unmodfied and Reused versions for creating a Binary. Add copy() to Binary. b4e2950 [asingh] Skip filtering based on stats when file was written with version older than 1.6.1 6fcee8c [asingh] Add getBytesUnsafe() to Binary that returns backing byte[] if possible, else returns result of getBytes() 30b07dd [asingh] PARQUET-251: Binary column statistics error when reuse byte[] among rows
- Loading branch information
1 parent
e6ee42e
commit e3b9502
Showing
42 changed files
with
1,044 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
parquet-column/src/main/java/org/apache/parquet/CorruptStatistics.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package org.apache.parquet; | ||
|
||
import org.apache.parquet.SemanticVersion.SemanticVersionParseException; | ||
import org.apache.parquet.VersionParser.ParsedVersion; | ||
import org.apache.parquet.VersionParser.VersionParseException; | ||
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName; | ||
|
||
/** | ||
* There was a bug (PARQUET-251) that caused the statistics metadata | ||
* for binary columns to be corrupted in the write path. | ||
* | ||
* This class is used to detect whether a file was written with this bug, | ||
* and thus it's statistics should be ignored / not trusted. | ||
*/ | ||
public class CorruptStatistics { | ||
private static final Log LOG = Log.getLog(CorruptStatistics.class); | ||
|
||
// the version in which the bug described by jira: PARQUET-251 was fixed | ||
// the bug involved writing invalid binary statistics, so stats written prior to this | ||
// fix must be ignored / assumed invalid | ||
private static final SemanticVersion PARQUET_251_FIXED_VERSION = new SemanticVersion(1, 8, 0); | ||
|
||
/** | ||
* Decides if the statistics from a file created by createdBy (the created_by field from parquet format) | ||
* should be ignored because they are potentially corrupt. | ||
*/ | ||
public static boolean shouldIgnoreStatistics(String createdBy, PrimitiveTypeName columnType) { | ||
|
||
if (columnType != PrimitiveTypeName.BINARY && columnType != PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY) { | ||
// the bug only applies to binary columns | ||
return false; | ||
} | ||
|
||
if (Strings.isNullOrEmpty(createdBy)) { | ||
// created_by is not populated, which could have been caused by | ||
// parquet-mr during the same time as PARQUET-251, see PARQUET-297 | ||
LOG.info("Ignoring statistics because created_by is null or empty! See PARQUET-251 and PARQUET-297"); | ||
return true; | ||
} | ||
|
||
try { | ||
ParsedVersion version = VersionParser.parse(createdBy); | ||
|
||
if (!"parquet-mr".equals(version.application)) { | ||
// assume other applications don't have this bug | ||
return false; | ||
} | ||
|
||
if (Strings.isNullOrEmpty(version.semver)) { | ||
LOG.warn("Ignoring statistics because created_by did not contain a semver (see PARQUET-251): " + createdBy); | ||
return true; | ||
} | ||
|
||
SemanticVersion semver = SemanticVersion.parse(version.semver); | ||
|
||
if (semver.compareTo(PARQUET_251_FIXED_VERSION) < 0) { | ||
LOG.info("Ignoring statistics because this file was created prior to " | ||
+ PARQUET_251_FIXED_VERSION | ||
+ ", see PARQUET-251" ); | ||
return true; | ||
} | ||
|
||
// this file was created after the fix | ||
return false; | ||
} catch (RuntimeException e) { | ||
// couldn't parse the created_by field, log what went wrong, don't trust the stats, | ||
// but don't make this fatal. | ||
warnParseError(createdBy, e); | ||
return true; | ||
} catch (SemanticVersionParseException e) { | ||
// couldn't parse the created_by field, log what went wrong, don't trust the stats, | ||
// but don't make this fatal. | ||
warnParseError(createdBy, e); | ||
return true; | ||
} catch (VersionParseException e) { | ||
// couldn't parse the created_by field, log what went wrong, don't trust the stats, | ||
// but don't make this fatal. | ||
warnParseError(createdBy, e); | ||
return true; | ||
} | ||
} | ||
|
||
private static void warnParseError(String createdBy, Throwable e) { | ||
LOG.warn("Ignoring statistics because created_by could not be parsed (see PARQUET-251): " + createdBy, e); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.