diff --git a/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedSmokeTestBase.java b/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedSmokeTestBase.java index 1cdc8a6596a19..894daf2efed84 100644 --- a/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedSmokeTestBase.java +++ b/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedSmokeTestBase.java @@ -33,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import static com.facebook.presto.common.type.TimeZoneKey.UTC_KEY; import static com.facebook.presto.common.type.VarcharType.VARCHAR; import static com.facebook.presto.iceberg.IcebergQueryRunner.ICEBERG_CATALOG; import static com.facebook.presto.iceberg.IcebergQueryRunner.TEST_CATALOG_DIRECTORY; @@ -946,4 +947,28 @@ public void testMergeOnReadDisabled() cleanupTableWithMergeOnRead(tableName); } } + + @Test + public void testTableStatisticsTimestamp() + { + Session session = Session.builder(getSession()) + .setTimeZoneKey(UTC_KEY) + .build(); + String tableName = "test_table_statistics_timestamp"; + assertUpdate(session, format("CREATE TABLE %s (col TIMESTAMP)", tableName)); + + assertQuery(session, "SHOW STATS FOR " + tableName, + "VALUES " + + " ('col', null, null, null, NULL, NULL, NULL), " + + " (NULL, NULL, NULL, NULL, 0e0, NULL, NULL)"); + + assertUpdate(session, "INSERT INTO " + tableName + " VALUES TIMESTAMP '2021-01-02 09:04:05.321'", 1); + assertUpdate(session, "INSERT INTO " + tableName + " VALUES TIMESTAMP '2022-12-22 10:07:08.456'", 1); + + assertQuery(session, "SHOW STATS FOR " + tableName, + "VALUES " + + " ('col', 113.0, NULL, 0.0, NULL, '2021-01-02 09:04:05.321', '2022-12-22 10:07:08.456'), " + + " (NULL, NULL, NULL, NULL, 2e0, NULL, NULL)"); + dropTable(session, tableName); + } } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java index 5e910cdd5d32b..a303f0946f28d 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java @@ -21,6 +21,7 @@ import com.facebook.presto.common.type.IntegerType; import com.facebook.presto.common.type.RealType; import com.facebook.presto.common.type.SmallintType; +import com.facebook.presto.common.type.SqlTimestamp; import com.facebook.presto.common.type.TinyintType; import com.facebook.presto.common.type.Type; import com.facebook.presto.metadata.Metadata; @@ -74,8 +75,10 @@ import java.util.Set; import static com.facebook.presto.common.type.DateType.DATE; +import static com.facebook.presto.common.type.SqlTimestamp.MICROSECONDS_PER_MILLISECOND; import static com.facebook.presto.common.type.StandardTypes.DOUBLE; import static com.facebook.presto.common.type.StandardTypes.VARCHAR; +import static com.facebook.presto.common.type.TimestampType.TIMESTAMP; import static com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName; import static com.facebook.presto.sql.QueryUtil.aliased; import static com.facebook.presto.sql.QueryUtil.selectAll; @@ -88,6 +91,7 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap; import static java.lang.Math.round; import static java.util.Objects.requireNonNull; +import static java.util.concurrent.TimeUnit.MILLISECONDS; public class ShowStatsRewrite implements StatementRewrite.Rewrite @@ -336,12 +340,12 @@ private static Expression createEstimateRepresentation(Estimate estimate) return new DoubleLiteral(Double.toString(estimate.getValue())); } - private static Expression toStringLiteral(Type type, Optional optionalValue) + private Expression toStringLiteral(Type type, Optional optionalValue) { return optionalValue.map(value -> toStringLiteral(type, value)).orElse(NULL_VARCHAR); } - private static Expression toStringLiteral(Type type, double value) + private Expression toStringLiteral(Type type, double value) { if (type.equals(BigintType.BIGINT) || type.equals(IntegerType.INTEGER) || type.equals(SmallintType.SMALLINT) || type.equals(TinyintType.TINYINT)) { return new StringLiteral(Long.toString(round(value))); @@ -355,6 +359,9 @@ private static Expression toStringLiteral(Type type, double value) if (type.equals(DATE)) { return new StringLiteral(LocalDate.ofEpochDay(round(value)).toString()); } + if (type.equals(TIMESTAMP)) { + return new StringLiteral(new SqlTimestamp(round(value) / MICROSECONDS_PER_MILLISECOND, session.getSqlFunctionProperties().getTimeZoneKey(), MILLISECONDS).toString()); + } throw new IllegalArgumentException("Unexpected type: " + type); } }