diff --git a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakePageSourceProvider.java b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakePageSourceProvider.java index e85543cfe41a..490d16341f65 100644 --- a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakePageSourceProvider.java +++ b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakePageSourceProvider.java @@ -181,9 +181,7 @@ private static TupleDomain getParquetTupleDomain(TupleDomain { String baseType = columnHandle.getType().getTypeSignature().getBase(); // skip looking up predicates for complex types as Parquet only stores stats for primitives - if (!baseType.equals(StandardTypes.MAP) && !baseType.equals(StandardTypes.ARRAY) && !baseType.equals(StandardTypes.ROW) && - // TODO: Remove the next line once timestamp predicate pushdown works in Parquet reader (https://github.com/trinodb/trino/issues/12007) - !baseType.equals(StandardTypes.TIMESTAMP_WITH_TIME_ZONE)) { + if (!baseType.equals(StandardTypes.MAP) && !baseType.equals(StandardTypes.ARRAY) && !baseType.equals(StandardTypes.ROW)) { HiveColumnHandle hiveColumnHandle = columnHandle.toHiveColumnHandle(); predicate.put(hiveColumnHandle, domain); } diff --git a/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/BaseDeltaLakeMinioConnectorTest.java b/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/BaseDeltaLakeMinioConnectorTest.java index 34a2b0bcbe44..d6169850219d 100644 --- a/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/BaseDeltaLakeMinioConnectorTest.java +++ b/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/BaseDeltaLakeMinioConnectorTest.java @@ -15,14 +15,18 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import io.trino.execution.QueryInfo; import io.trino.plugin.deltalake.util.DockerizedMinioDataLake; import io.trino.testing.BaseConnectorTest; +import io.trino.testing.DistributedQueryRunner; import io.trino.testing.MaterializedResult; import io.trino.testing.QueryRunner; +import io.trino.testing.ResultWithQueryId; import io.trino.testing.TestingConnectorBehavior; import io.trino.testing.sql.TestTable; import io.trino.tpch.TpchTable; import org.testng.SkipException; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Optional; @@ -265,6 +269,50 @@ public void testCharVarcharComparison() .hasStackTraceContaining("Unsupported type: char(3)"); } + @Test(dataProvider = "timestampValues") + public void testTimestampPredicatePushdown(String value) + { + String tableName = "test_parquet_timestamp_predicate_pushdown_" + randomTableSuffix(); + + assertUpdate("DROP TABLE IF EXISTS " + tableName); + assertUpdate("CREATE TABLE " + tableName + " (t TIMESTAMP WITH TIME ZONE)"); + assertUpdate("INSERT INTO " + tableName + " VALUES (TIMESTAMP '" + value + "')", 1); + + DistributedQueryRunner queryRunner = (DistributedQueryRunner) getQueryRunner(); + ResultWithQueryId queryResult = queryRunner.executeWithQueryId( + getSession(), + "SELECT * FROM " + tableName + " WHERE t < TIMESTAMP '" + value + "'"); + assertEquals(getQueryInfo(queryRunner, queryResult).getQueryStats().getProcessedInputDataSize().toBytes(), 0); + + queryResult = queryRunner.executeWithQueryId( + getSession(), + "SELECT * FROM " + tableName + " WHERE t > TIMESTAMP '" + value + "'"); + assertEquals(getQueryInfo(queryRunner, queryResult).getQueryStats().getProcessedInputDataSize().toBytes(), 0); + + assertQueryStats( + getSession(), + "SELECT * FROM " + tableName + " WHERE t = TIMESTAMP '" + value + "'", + queryStats -> assertThat(queryStats.getProcessedInputDataSize().toBytes()).isGreaterThan(0), + results -> {}); + } + + @DataProvider + public Object[][] timestampValues() + { + return new Object[][] { + {"1965-10-31 01:00:08.123 UTC"}, + {"1965-10-31 01:00:08.999 UTC"}, + {"1970-01-01 01:13:42.000 America/Bahia_Banderas"}, // There is a gap in JVM zone + {"1970-01-01 00:00:00.000 Asia/Kathmandu"}, + {"2018-10-28 01:33:17.456 Europe/Vilnius"}, + {"9999-12-31 23:59:59.999 UTC"}}; + } + + private QueryInfo getQueryInfo(DistributedQueryRunner queryRunner, ResultWithQueryId queryResult) + { + return queryRunner.getCoordinator().getQueryManager().getFullQueryInfo(queryResult.getQueryId()); + } + @Override protected String createSchemaSql(String schemaName) {