This is an automated email from the ASF dual-hosted git repository.

lzljs3620320 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-paimon-trino.git


The following commit(s) were added to refs/heads/main by this push:
     new e397528  Support trino time travel query statement (#43)
e397528 is described below

commit e397528bc928d391bc92f51944bfdd468b3c9d91
Author: shidayang <[email protected]>
AuthorDate: Thu Dec 7 16:22:17 2023 +0800

    Support trino time travel query statement (#43)
---
 .../apache/paimon/trino/TestTrino358ITCase.java    |  4 ++
 .../org/apache/paimon/trino/TrinoMetadata.java     | 69 ++++++++++++++++++++++
 .../apache/paimon/trino/TestTrino368ITCase.java    |  6 +-
 .../org/apache/paimon/trino/TrinoMetadata.java     | 69 ++++++++++++++++++++++
 .../apache/paimon/trino/TestTrino369ITCase.java    |  6 +-
 .../org/apache/paimon/trino/TrinoMetadata.java     | 68 +++++++++++++++++++++
 .../apache/paimon/trino/TestTrino370ITCase.java    |  6 +-
 .../apache/paimon/trino/TestTrino388ITCase.java    |  6 +-
 .../apache/paimon/trino/TestTrino393ITCase.java    |  6 +-
 .../apache/paimon/trino/TestTrino422ITCase.java    |  7 ++-
 .../org/apache/paimon/trino/TrinoMetadata.java     | 58 ++++++++++++++++++
 .../org/apache/paimon/trino/TrinoMetadataBase.java | 12 +++-
 .../org/apache/paimon/trino/TestTrinoITCase.java   | 42 ++++++++++++-
 13 files changed, 349 insertions(+), 10 deletions(-)

diff --git 
a/paimon-trino-358/src/test/java/org/apache/paimon/trino/TestTrino358ITCase.java
 
b/paimon-trino-358/src/test/java/org/apache/paimon/trino/TestTrino358ITCase.java
index fe87b21..98bd9fc 100644
--- 
a/paimon-trino-358/src/test/java/org/apache/paimon/trino/TestTrino358ITCase.java
+++ 
b/paimon-trino-358/src/test/java/org/apache/paimon/trino/TestTrino358ITCase.java
@@ -23,6 +23,10 @@ import org.testng.annotations.Test;
 /** {@link TestTrinoITCase} for Trino 358. */
 public class TestTrino358ITCase extends TestTrinoITCase {
 
+    public TestTrino358ITCase() {
+        super(358);
+    }
+
     @Override
     @Test
     public void testSetTableProperties() {
diff --git 
a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoMetadata.java 
b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
index 2f60a53..1e31625 100644
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
@@ -18,6 +18,7 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.CoreOptions;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.CatalogContext;
 import org.apache.paimon.catalog.CatalogFactory;
@@ -26,14 +27,25 @@ import org.apache.paimon.options.Options;
 import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.security.SecurityContext;
 
+import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ConnectorMetadata;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTableHandle;
+import io.trino.spi.connector.ConnectorTableVersion;
+import io.trino.spi.connector.PointerType;
+import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.TimestampWithTimeZoneType;
+import io.trino.spi.type.Type;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
+import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
+import static io.trino.spi.type.DateTimeEncoding.unpackMillisUtc;
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toMap;
 
@@ -57,6 +69,63 @@ public class TrinoMetadata extends TrinoMetadataBase {
         return false;
     }
 
+    @Override
+    public ConnectorTableHandle getTableHandle(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            Optional<ConnectorTableVersion> startVersion,
+            Optional<ConnectorTableVersion> endVersion) {
+        if (startVersion.isPresent()) {
+            throw new TrinoException(
+                    NOT_SUPPORTED, "Read paimon table with start version is 
not supported");
+        }
+
+        Map<String, String> dynamicOptions = new HashMap<>();
+        if (endVersion.isPresent()) {
+            ConnectorTableVersion version = endVersion.get();
+            Type versionType = version.getVersionType();
+            switch (version.getPointerType()) {
+                case TEMPORAL:
+                    {
+                        if (!(versionType instanceof 
TimestampWithTimeZoneType)) {
+                            throw new TrinoException(
+                                    NOT_SUPPORTED,
+                                    "Unsupported type for table version: "
+                                            + versionType.getDisplayName());
+                        }
+                        TimestampWithTimeZoneType timeZonedVersionType =
+                                (TimestampWithTimeZoneType) versionType;
+                        long epochMillis =
+                                timeZonedVersionType.isShort()
+                                        ? unpackMillisUtc((long) 
version.getVersion())
+                                        : ((LongTimestampWithTimeZone) 
version.getVersion())
+                                                .getEpochMillis();
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_TIMESTAMP_MILLIS.key(),
+                                String.valueOf(epochMillis));
+                        break;
+                    }
+                case TARGET_ID:
+                    {
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_SNAPSHOT_ID.key(),
+                                version.getVersion().toString());
+                        break;
+                    }
+            }
+        }
+        return getTableHandle(tableName, dynamicOptions);
+    }
+
+    @Override
+    public boolean isSupportedVersionType(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            PointerType pointerType,
+            Type versioning) {
+        return true;
+    }
+
     @Override
     public void setTableProperties(
             ConnectorSession session,
diff --git 
a/paimon-trino-368/src/test/java/org/apache/paimon/trino/TestTrino368ITCase.java
 
b/paimon-trino-368/src/test/java/org/apache/paimon/trino/TestTrino368ITCase.java
index 6063600..e2badeb 100644
--- 
a/paimon-trino-368/src/test/java/org/apache/paimon/trino/TestTrino368ITCase.java
+++ 
b/paimon-trino-368/src/test/java/org/apache/paimon/trino/TestTrino368ITCase.java
@@ -19,4 +19,8 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 368. */
-public class TestTrino368ITCase extends TestTrinoITCase {}
+public class TestTrino368ITCase extends TestTrinoITCase {
+    public TestTrino368ITCase() {
+        super(368);
+    }
+}
diff --git 
a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoMetadata.java 
b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
index c998eb0..1caf53f 100644
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
@@ -18,6 +18,7 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.CoreOptions;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.CatalogContext;
 import org.apache.paimon.catalog.CatalogFactory;
@@ -26,14 +27,25 @@ import org.apache.paimon.options.Options;
 import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.security.SecurityContext;
 
+import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ConnectorMetadata;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTableHandle;
+import io.trino.spi.connector.ConnectorTableVersion;
+import io.trino.spi.connector.PointerType;
+import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.TimestampWithTimeZoneType;
+import io.trino.spi.type.Type;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
+import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
+import static io.trino.spi.type.DateTimeEncoding.unpackMillisUtc;
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toMap;
 
@@ -52,6 +64,63 @@ public class TrinoMetadata extends TrinoMetadataBase {
         this.catalog = 
CatalogFactory.createCatalog(CatalogContext.create(catalogOptions));
     }
 
+    @Override
+    public ConnectorTableHandle getTableHandle(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            Optional<ConnectorTableVersion> startVersion,
+            Optional<ConnectorTableVersion> endVersion) {
+        if (startVersion.isPresent()) {
+            throw new TrinoException(
+                    NOT_SUPPORTED, "Read paimon table with start version is 
not supported");
+        }
+
+        Map<String, String> dynamicOptions = new HashMap<>();
+        if (endVersion.isPresent()) {
+            ConnectorTableVersion version = endVersion.get();
+            Type versionType = version.getVersionType();
+            switch (version.getPointerType()) {
+                case TEMPORAL:
+                    {
+                        if (!(versionType instanceof 
TimestampWithTimeZoneType)) {
+                            throw new TrinoException(
+                                    NOT_SUPPORTED,
+                                    "Unsupported type for table version: "
+                                            + versionType.getDisplayName());
+                        }
+                        TimestampWithTimeZoneType timeZonedVersionType =
+                                (TimestampWithTimeZoneType) versionType;
+                        long epochMillis =
+                                timeZonedVersionType.isShort()
+                                        ? unpackMillisUtc((long) 
version.getVersion())
+                                        : ((LongTimestampWithTimeZone) 
version.getVersion())
+                                                .getEpochMillis();
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_TIMESTAMP_MILLIS.key(),
+                                String.valueOf(epochMillis));
+                        break;
+                    }
+                case TARGET_ID:
+                    {
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_SNAPSHOT_ID.key(),
+                                version.getVersion().toString());
+                        break;
+                    }
+            }
+        }
+        return getTableHandle(tableName, dynamicOptions);
+    }
+
+    @Override
+    public boolean isSupportedVersionType(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            PointerType pointerType,
+            Type versioning) {
+        return true;
+    }
+
     @Override
     public void setTableProperties(
             ConnectorSession session,
diff --git 
a/paimon-trino-369/src/test/java/org/apache/paimon/trino/TestTrino369ITCase.java
 
b/paimon-trino-369/src/test/java/org/apache/paimon/trino/TestTrino369ITCase.java
index 31652d0..7ec111c 100644
--- 
a/paimon-trino-369/src/test/java/org/apache/paimon/trino/TestTrino369ITCase.java
+++ 
b/paimon-trino-369/src/test/java/org/apache/paimon/trino/TestTrino369ITCase.java
@@ -19,4 +19,8 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 369. */
-public class TestTrino369ITCase extends TestTrinoITCase {}
+public class TestTrino369ITCase extends TestTrinoITCase {
+    public TestTrino369ITCase() {
+        super(369);
+    }
+}
diff --git 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java 
b/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
similarity index 50%
copy from 
paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
copy to 
paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
index 9d080ef..9a33668 100644
--- 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ b/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
@@ -18,6 +18,7 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.CoreOptions;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.CatalogContext;
 import org.apache.paimon.catalog.CatalogFactory;
@@ -26,15 +27,25 @@ import org.apache.paimon.options.Options;
 import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.security.SecurityContext;
 
+import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ConnectorMetadata;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTableHandle;
+import io.trino.spi.connector.ConnectorTableVersion;
+import io.trino.spi.connector.PointerType;
+import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.TimestampWithTimeZoneType;
+import io.trino.spi.type.Type;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
+import static io.trino.spi.type.DateTimeEncoding.unpackMillisUtc;
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toMap;
 
@@ -53,6 +64,63 @@ public class TrinoMetadata extends TrinoMetadataBase {
         this.catalog = 
CatalogFactory.createCatalog(CatalogContext.create(catalogOptions));
     }
 
+    @Override
+    public ConnectorTableHandle getTableHandle(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            Optional<ConnectorTableVersion> startVersion,
+            Optional<ConnectorTableVersion> endVersion) {
+        if (startVersion.isPresent()) {
+            throw new TrinoException(
+                    NOT_SUPPORTED, "Read paimon table with start version is 
not supported");
+        }
+
+        Map<String, String> dynamicOptions = new HashMap<>();
+        if (endVersion.isPresent()) {
+            ConnectorTableVersion version = endVersion.get();
+            Type versionType = version.getVersionType();
+            switch (version.getPointerType()) {
+                case TEMPORAL:
+                    {
+                        if (!(versionType instanceof 
TimestampWithTimeZoneType)) {
+                            throw new TrinoException(
+                                    NOT_SUPPORTED,
+                                    "Unsupported type for table version: "
+                                            + versionType.getDisplayName());
+                        }
+                        TimestampWithTimeZoneType timeZonedVersionType =
+                                (TimestampWithTimeZoneType) versionType;
+                        long epochMillis =
+                                timeZonedVersionType.isShort()
+                                        ? unpackMillisUtc((long) 
version.getVersion())
+                                        : ((LongTimestampWithTimeZone) 
version.getVersion())
+                                                .getEpochMillis();
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_TIMESTAMP_MILLIS.key(),
+                                String.valueOf(epochMillis));
+                        break;
+                    }
+                case TARGET_ID:
+                    {
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_SNAPSHOT_ID.key(),
+                                version.getVersion().toString());
+                        break;
+                    }
+            }
+        }
+        return getTableHandle(tableName, dynamicOptions);
+    }
+
+    @Override
+    public boolean isSupportedVersionType(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            PointerType pointerType,
+            Type versioning) {
+        return true;
+    }
+
     @Override
     public void setTableProperties(
             ConnectorSession session,
diff --git 
a/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
 
b/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
index 98e8c40..d7fd631 100644
--- 
a/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
+++ 
b/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
@@ -19,4 +19,8 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 370. */
-public class TestTrino370ITCase extends TestTrinoITCase {}
+public class TestTrino370ITCase extends TestTrinoITCase {
+    public TestTrino370ITCase() {
+        super(370);
+    }
+}
diff --git 
a/paimon-trino-388/src/test/java/org/apache/paimon/trino/TestTrino388ITCase.java
 
b/paimon-trino-388/src/test/java/org/apache/paimon/trino/TestTrino388ITCase.java
index 95c10d0..decefcf 100644
--- 
a/paimon-trino-388/src/test/java/org/apache/paimon/trino/TestTrino388ITCase.java
+++ 
b/paimon-trino-388/src/test/java/org/apache/paimon/trino/TestTrino388ITCase.java
@@ -19,4 +19,8 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 388. */
-public class TestTrino388ITCase extends TestTrinoITCase {}
+public class TestTrino388ITCase extends TestTrinoITCase {
+    public TestTrino388ITCase() {
+        super(388);
+    }
+}
diff --git 
a/paimon-trino-393/src/test/java/org/apache/paimon/trino/TestTrino393ITCase.java
 
b/paimon-trino-393/src/test/java/org/apache/paimon/trino/TestTrino393ITCase.java
index beaaede..0a240f0 100644
--- 
a/paimon-trino-393/src/test/java/org/apache/paimon/trino/TestTrino393ITCase.java
+++ 
b/paimon-trino-393/src/test/java/org/apache/paimon/trino/TestTrino393ITCase.java
@@ -19,4 +19,8 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 393. */
-public class TestTrino393ITCase extends TestTrinoITCase {}
+public class TestTrino393ITCase extends TestTrinoITCase {
+    public TestTrino393ITCase() {
+        super(393);
+    }
+}
diff --git 
a/paimon-trino-422/src/test/java/org/apache/paimon/trino/TestTrino422ITCase.java
 
b/paimon-trino-422/src/test/java/org/apache/paimon/trino/TestTrino422ITCase.java
index 4341754..dbf3119 100644
--- 
a/paimon-trino-422/src/test/java/org/apache/paimon/trino/TestTrino422ITCase.java
+++ 
b/paimon-trino-422/src/test/java/org/apache/paimon/trino/TestTrino422ITCase.java
@@ -19,4 +19,9 @@
 package org.apache.paimon.trino;
 
 /** {@link TestTrinoITCase} for Trino 422. */
-public class TestTrino422ITCase extends TestTrinoITCase {}
+public class TestTrino422ITCase extends TestTrinoITCase {
+
+    public TestTrino422ITCase() {
+        super(422);
+    }
+}
diff --git 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java 
b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
index 9d080ef..8bf7d90 100644
--- 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ 
b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
@@ -18,6 +18,7 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.CoreOptions;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.CatalogContext;
 import org.apache.paimon.catalog.CatalogFactory;
@@ -26,15 +27,24 @@ import org.apache.paimon.options.Options;
 import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.security.SecurityContext;
 
+import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ConnectorMetadata;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTableHandle;
+import io.trino.spi.connector.ConnectorTableVersion;
+import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.TimestampWithTimeZoneType;
+import io.trino.spi.type.Type;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
+import static io.trino.spi.type.DateTimeEncoding.unpackMillisUtc;
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toMap;
 
@@ -53,6 +63,54 @@ public class TrinoMetadata extends TrinoMetadataBase {
         this.catalog = 
CatalogFactory.createCatalog(CatalogContext.create(catalogOptions));
     }
 
+    @Override
+    public ConnectorTableHandle getTableHandle(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            Optional<ConnectorTableVersion> startVersion,
+            Optional<ConnectorTableVersion> endVersion) {
+        if (startVersion.isPresent()) {
+            throw new TrinoException(
+                    NOT_SUPPORTED, "Read paimon table with start version is 
not supported");
+        }
+
+        Map<String, String> dynamicOptions = new HashMap<>();
+        if (endVersion.isPresent()) {
+            ConnectorTableVersion version = endVersion.get();
+            Type versionType = version.getVersionType();
+            switch (version.getPointerType()) {
+                case TEMPORAL:
+                    {
+                        if (!(versionType instanceof 
TimestampWithTimeZoneType)) {
+                            throw new TrinoException(
+                                    NOT_SUPPORTED,
+                                    "Unsupported type for table version: "
+                                            + versionType.getDisplayName());
+                        }
+                        TimestampWithTimeZoneType timeZonedVersionType =
+                                (TimestampWithTimeZoneType) versionType;
+                        long epochMillis =
+                                timeZonedVersionType.isShort()
+                                        ? unpackMillisUtc((long) 
version.getVersion())
+                                        : ((LongTimestampWithTimeZone) 
version.getVersion())
+                                                .getEpochMillis();
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_TIMESTAMP_MILLIS.key(),
+                                String.valueOf(epochMillis));
+                        break;
+                    }
+                case TARGET_ID:
+                    {
+                        dynamicOptions.put(
+                                CoreOptions.SCAN_SNAPSHOT_ID.key(),
+                                version.getVersion().toString());
+                        break;
+                    }
+            }
+        }
+        return getTableHandle(tableName, dynamicOptions);
+    }
+
     @Override
     public void setTableProperties(
             ConnectorSession session,
diff --git 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataBase.java
 
b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataBase.java
index 154db64..e4482a8 100644
--- 
a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataBase.java
+++ 
b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataBase.java
@@ -26,6 +26,7 @@ import org.apache.paimon.options.Options;
 import org.apache.paimon.schema.Schema;
 import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.security.SecurityContext;
+import org.apache.paimon.table.Table;
 import org.apache.paimon.utils.InstantiationUtil;
 import org.apache.paimon.utils.StringUtils;
 
@@ -125,7 +126,7 @@ public abstract class TrinoMetadataBase implements 
ConnectorMetadata {
 
     @Override
     public TrinoTableHandle getTableHandle(ConnectorSession session, 
SchemaTableName tableName) {
-        return getTableHandle(tableName);
+        return getTableHandle(tableName, null);
     }
 
     @Override
@@ -134,11 +135,16 @@ public abstract class TrinoMetadataBase implements 
ConnectorMetadata {
         return new ConnectorTableProperties();
     }
 
-    public TrinoTableHandle getTableHandle(SchemaTableName tableName) {
+    public TrinoTableHandle getTableHandle(
+            SchemaTableName tableName, Map<String, String> dynamicOptions) {
         Identifier tablePath = new Identifier(tableName.getSchemaName(), 
tableName.getTableName());
         byte[] serializedTable;
         try {
-            serializedTable = 
InstantiationUtil.serializeObject(catalog.getTable(tablePath));
+            Table table = catalog.getTable(tablePath);
+            if (dynamicOptions != null && !dynamicOptions.isEmpty()) {
+                table = table.copy(dynamicOptions);
+            }
+            serializedTable = InstantiationUtil.serializeObject(table);
         } catch (Catalog.TableNotExistException e) {
             return null;
         } catch (IOException e) {
diff --git 
a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoITCase.java
 
b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoITCase.java
index 4fa7b3d..25b2d60 100644
--- 
a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoITCase.java
+++ 
b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoITCase.java
@@ -49,6 +49,8 @@ import io.trino.testing.QueryRunner;
 import org.testng.annotations.Test;
 
 import java.nio.file.Files;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -59,6 +61,7 @@ import java.util.UUID;
 
 import static io.airlift.testing.Closeables.closeAllSuppress;
 import static io.trino.testing.TestingSession.testSessionBuilder;
+import static java.time.ZoneOffset.UTC;
 import static org.apache.paimon.data.BinaryString.fromString;
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -68,6 +71,14 @@ public abstract class TestTrinoITCase extends 
AbstractTestQueryFramework {
     private static final String CATALOG = "paimon";
     private static final String DB = "default";
 
+    protected long t2FirstCommitTimestamp;
+
+    private int trinoVersion;
+
+    public TestTrinoITCase(int trinoVersion) {
+        this.trinoVersion = trinoVersion;
+    }
+
     @Override
     protected QueryRunner createQueryRunner() throws Exception {
         String warehouse =
@@ -87,6 +98,7 @@ public abstract class TestTrinoITCase extends 
AbstractTestQueryFramework {
         testHelper2.write(GenericRow.of(1, 2L, fromString("1"), 
fromString("1")));
         testHelper2.write(GenericRow.of(3, 4L, fromString("2"), 
fromString("2")));
         testHelper2.commit();
+        t2FirstCommitTimestamp = System.currentTimeMillis();
         testHelper2.write(GenericRow.of(5, 6L, fromString("3"), 
fromString("3")));
         testHelper2.write(GenericRow.of(7, 8L, fromString("4"), 
fromString("4")));
         testHelper2.commit();
@@ -479,8 +491,36 @@ public abstract class TestTrinoITCase extends 
AbstractTestQueryFramework {
                 .isEqualTo("[[2023-09-12T07:54:48.002Z[UTC]]]");
     }
 
-    private String sql(String sql) {
+    @Test
+    public void testTimeTravel() {
+        if (trinoVersion < 368) {
+            return;
+        }
+        assertThat(sql("SELECT * FROM paimon.default.t2 FOR VERSION AS OF 1"))
+                .isEqualTo("[[1, 2, 1, 1], [3, 4, 2, 2]]");
+        assertThat(sql("SELECT * FROM paimon.default.t2 FOR VERSION AS OF 2"))
+                .isEqualTo("[[1, 2, 1, 1], [3, 4, 2, 2], [5, 6, 3, 3], [7, 8, 
4, 4]]");
+
+        assertThat(
+                        sql(
+                                "SELECT * FROM paimon.default.t2 FOR TIMESTAMP 
AS OF TIMESTAMP "
+                                        + 
timestampLiteral(t2FirstCommitTimestamp, 6)))
+                .isEqualTo("[[1, 2, 1, 1], [3, 4, 2, 2]]");
+        assertThat(
+                        sql(
+                                "SELECT * FROM paimon.default.t2 FOR TIMESTAMP 
AS OF TIMESTAMP "
+                                        + 
timestampLiteral(System.currentTimeMillis(), 6)))
+                .isEqualTo("[[1, 2, 1, 1], [3, 4, 2, 2], [5, 6, 3, 3], [7, 8, 
4, 4]]");
+    }
+
+    protected String sql(String sql) {
         MaterializedResult result = getQueryRunner().execute(sql);
         return result.getMaterializedRows().toString();
     }
+
+    protected static String timestampLiteral(long epochMilliSeconds, int 
precision) {
+        return DateTimeFormatter.ofPattern(
+                        "''yyyy-MM-dd HH:mm:ss." + "S".repeat(precision) + " 
VV''")
+                .format(Instant.ofEpochMilli(epochMilliSeconds).atZone(UTC));
+    }
 }

Reply via email to