diff --git a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java index c6f457e32c0c4..acadf5b544cac 100644 --- a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java +++ b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java @@ -14,6 +14,9 @@ package com.facebook.presto.hive.metastore.thrift; import com.facebook.presto.common.predicate.Domain; +import com.facebook.presto.common.type.ArrayType; +import com.facebook.presto.common.type.MapType; +import com.facebook.presto.common.type.RowType; import com.facebook.presto.common.type.Type; import com.facebook.presto.hive.HiveBasicStatistics; import com.facebook.presto.hive.HiveType; @@ -27,7 +30,6 @@ import com.facebook.presto.hive.metastore.HiveColumnStatistics; import com.facebook.presto.hive.metastore.HivePrivilegeInfo; import com.facebook.presto.hive.metastore.MetastoreContext; -import com.facebook.presto.hive.metastore.MetastoreUtil; import com.facebook.presto.hive.metastore.PartitionStatistics; import com.facebook.presto.hive.metastore.PartitionWithStatistics; import com.facebook.presto.spi.PrestoException; @@ -78,6 +80,13 @@ import java.util.function.Function; import java.util.stream.Collectors; +import static com.facebook.presto.common.type.BooleanType.BOOLEAN; +import static com.facebook.presto.common.type.Chars.isCharType; +import static com.facebook.presto.common.type.DateType.DATE; +import static com.facebook.presto.common.type.TimestampType.TIMESTAMP; +import static com.facebook.presto.common.type.TypeUtils.isNumericType; +import static com.facebook.presto.common.type.VarbinaryType.VARBINARY; +import static com.facebook.presto.common.type.Varchars.isVarcharType; import static com.facebook.presto.hive.HiveBasicStatistics.createEmptyStatistics; import static com.facebook.presto.hive.HiveErrorCode.HIVE_METASTORE_ERROR; import static com.facebook.presto.hive.metastore.HivePrivilegeInfo.HivePrivilege; @@ -96,6 +105,13 @@ import static com.facebook.presto.spi.StandardErrorCode.ALREADY_EXISTS; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; import static com.facebook.presto.spi.security.PrincipalType.USER; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.MAX_VALUE; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.MAX_VALUE_SIZE_IN_BYTES; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.MIN_VALUE; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.NUMBER_OF_DISTINCT_VALUES; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.NUMBER_OF_NON_NULL_VALUES; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.NUMBER_OF_TRUE_VALUES; +import static com.facebook.presto.spi.statistics.ColumnStatisticType.TOTAL_SIZE_IN_BYTES; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Throwables.throwIfUnchecked; import static com.google.common.collect.ImmutableList.toImmutableList; @@ -109,7 +125,6 @@ import static org.apache.hadoop.hive.common.FileUtils.makePartName; import static org.apache.hadoop.hive.metastore.api.HiveObjectType.TABLE; import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.HIVE_FILTER_FIELD_PARAMS; -import static org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category.PRIMITIVE; @ThreadSafe public class ThriftHiveMetastore @@ -257,7 +272,23 @@ public Optional getTable(MetastoreContext metastoreContext, String databa @Override public Set getSupportedColumnStatistics(MetastoreContext metastoreContext, Type type) { - return MetastoreUtil.getSupportedColumnStatistics(type); + if (type.equals(BOOLEAN)) { + return ImmutableSet.of(NUMBER_OF_NON_NULL_VALUES, NUMBER_OF_TRUE_VALUES); + } + if (isNumericType(type) || type.equals(DATE) || type.equals(TIMESTAMP)) { + return ImmutableSet.of(MIN_VALUE, MAX_VALUE, NUMBER_OF_DISTINCT_VALUES, NUMBER_OF_NON_NULL_VALUES); + } + if (isVarcharType(type) || isCharType(type)) { + return ImmutableSet.of(NUMBER_OF_NON_NULL_VALUES, NUMBER_OF_DISTINCT_VALUES, TOTAL_SIZE_IN_BYTES, MAX_VALUE_SIZE_IN_BYTES); + } + if (type.equals(VARBINARY)) { + return ImmutableSet.of(NUMBER_OF_NON_NULL_VALUES, TOTAL_SIZE_IN_BYTES, MAX_VALUE_SIZE_IN_BYTES); + } + if (type instanceof ArrayType || type instanceof RowType || type instanceof MapType) { + return ImmutableSet.of(); + } + // Throwing here to make sure this method is updated when a new type is added in Hive connector + throw new IllegalArgumentException("Unsupported type: " + type); } @Override @@ -409,7 +440,6 @@ public synchronized void updateTableStatistics(MetastoreContext metastoreContext com.facebook.presto.hive.metastore.Table table = fromMetastoreApiTable(modifiedTable, metastoreContext.getColumnConverter()); OptionalLong rowCount = basicStatistics.getRowCount(); List metastoreColumnStatistics = updatedStatistics.getColumnStatistics().entrySet().stream() - .filter(entry -> table.getColumn(entry.getKey()).get().getType().getTypeInfo().getCategory() == PRIMITIVE) .map(entry -> createMetastoreColumnStatistics(entry.getKey(), table.getColumn(entry.getKey()).get().getType(), entry.getValue(), rowCount)) .collect(toImmutableList()); if (!metastoreColumnStatistics.isEmpty()) { diff --git a/presto-product-tests/src/main/java/com/facebook/presto/tests/hive/TestHiveTableStatistics.java b/presto-product-tests/src/main/java/com/facebook/presto/tests/hive/TestHiveTableStatistics.java index b9668e646d7c8..7562179670e7d 100644 --- a/presto-product-tests/src/main/java/com/facebook/presto/tests/hive/TestHiveTableStatistics.java +++ b/presto-product-tests/src/main/java/com/facebook/presto/tests/hive/TestHiveTableStatistics.java @@ -699,6 +699,29 @@ public void testAnalyzeForTableWithNonPrimitiveTypes() row(null, null, null, null, 1.0, null, null)); } + @Test + public void testAnalyzeForPartitionedTableWithNonPrimitiveTypes() + { + String tableName = "test_analyze_partitioned_table_complex_types"; + String showStatsTable = "SHOW STATS FOR " + tableName; + + query("DROP TABLE IF EXISTS " + tableName); + query("CREATE TABLE " + tableName + + "(c_row row(c1 int, c2 int), c_char char, c_int int, c_part char) " + + "WITH (partitioned_by = ARRAY['c_part'])"); + query("INSERT INTO " + tableName + " VALUES (row(1,2), 'a', 3, '1')"); + query("INSERT INTO " + tableName + " VALUES (row(4,5), 'b', 5, '2')"); + query("INSERT INTO " + tableName + " VALUES (row(6,7), 'c', 5, '2')"); + + assertThat(query("ANALYZE " + tableName)).containsExactly(row(3)); + assertThat(query(showStatsTable)).containsOnly( + row("c_row", null, null, null, null, null, null), + row("c_char", 3.0, 2.0, 0.0, null, null, null), + row("c_int", null, 1.0, 0.0, null, "3", "5"), + row("c_part", 3.0, 2.0, 0.0, null, null, null), + row(null, null, null, null, 3.0, null, null)); + } + @Test @Requires(NationPartitionedByBigintTable.class) public void testAnalyzeForTablePartitionedByBigint()