Ignore corrupted statistics when altering partition
If the statistics are corrupted, it doesn't make much sense to restore
them on rollback.
@@ -57,6 +57,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
+import static com.facebook.presto.hive.HiveErrorCode.HIVE_CORRUPTED_COLUMN_STATISTICS;
import static com.facebook.presto.hive.HiveErrorCode.HIVE_FILESYSTEM_ERROR;
import static com.facebook.presto.hive.HiveErrorCode.HIVE_METASTORE_ERROR;
import static com.facebook.presto.hive.HiveErrorCode.HIVE_PATH_ALREADY_EXISTS;
@@ -1083,13 +1084,7 @@ public class SemiTransactionalHiveMetastore
format("The partition that this transaction modified was deleted in another transaction. %s %s", partition.getTableName(), partition.getValues()));
}
String partitionName = getPartitionName(partition.getDatabaseName(), partition.getTableName(), partition.getValues());
- PartitionStatistics oldPartitionStatistics = delegate.getPartitionStatistics(partition.getDatabaseName(), partition.getTableName(), ImmutableSet.of(partitionName))
- .get(partitionName);
- if (oldPartitionStatistics == null) {
- throw new PrestoException(
- TRANSACTION_CONFLICT,
- format("The partition that this transaction modified was deleted in another transaction. %s %s", partition.getTableName(), partition.getValues()));
- }
+ PartitionStatistics oldPartitionStatistics = getExistingPartitionStatistics(partition, partitionName);
String oldPartitionLocation = oldPartition.get().getStorage().getLocation();
Path oldPartitionPath = new Path(oldPartitionLocation);
@@ -1135,6 +1130,32 @@ public class SemiTransactionalHiveMetastore
new PartitionWithStatistics(oldPartition.get(), partitionName, oldPartitionStatistics)));
}
+ private PartitionStatistics getExistingPartitionStatistics(Partition partition, String partitionName)
+ {
+ try {
+ PartitionStatistics statistics = delegate.getPartitionStatistics(partition.getDatabaseName(), partition.getTableName(), ImmutableSet.of(partitionName))
+ .get(partitionName);
+ if (statistics == null) {
+ throw new PrestoException(
+ TRANSACTION_CONFLICT,
+ format("The partition that this transaction modified was deleted in another transaction. %s %s", partition.getTableName(), partition.getValues()));
+ }
+ return statistics;
+ }
+ catch (PrestoException e) {
+ if (e.getErrorCode().equals(HIVE_CORRUPTED_COLUMN_STATISTICS.toErrorCode())) {
+ log.warn(
+ e,
+ "Corrupted statistics found when altering partition. Table: %s.%s. Partition: %s",
+ partition.getDatabaseName(),
+ partition.getTableName(),
+ partition.getValues());
+ return PartitionStatistics.empty();
+ }
+ throw e;
+ }
+ }
+
private void prepareAddPartition(HdfsContext context, PartitionAndMore partitionAndMore)
{
deleteOnly = false;
