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

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


The following commit(s) were added to refs/heads/main by this push:
     new 7b9064c  [Presto] Support table scan options for time-travel (#50)
7b9064c is described below

commit 7b9064c28374e13e5cd2343c2111ed46217a2246
Author: xiangyu0xf <[email protected]>
AuthorDate: Sun Jan 19 14:40:53 2025 +0800

    [Presto] Support table scan options for time-travel (#50)
---
 .../org/apache/paimon/presto/TestPrestoITCase.java | 27 +++++++++
 .../org/apache/paimon/presto/PrestoMetadata.java   | 18 ++++--
 .../apache/paimon/presto/PrestoPropertyUtils.java  | 66 ++++++++++++++++++++++
 .../paimon/presto/PrestoPropertyUtilsTest.java     | 58 +++++++++++++++++++
 .../org/apache/paimon/presto/TestPrestoITCase.java | 27 +++++++++
 5 files changed, 190 insertions(+), 6 deletions(-)

diff --git 
a/paimon-presto-0.236/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
 
b/paimon-presto-0.236/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
index d57d9db..edbe701 100644
--- 
a/paimon-presto-0.236/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
+++ 
b/paimon-presto-0.236/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
@@ -229,6 +229,33 @@ public class TestPrestoITCase {
                 .isEqualTo("[[1, 1], [3, 2]]");
     }
 
+    @Test
+    public void testFilterWithTimeTravelAndTableOptions() throws Exception {
+        // Time travel table t2 to first commit.
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t2.1"))
+                .isEqualTo("[[1, 1], [3, 2]]");
+
+        // Invalid time travel table options
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t1.1"))
+                .isEqualTo("[[1, 1], [3, 2], [5, 3]]");
+
+        // Time travel table t2 to first commit by table options
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t1.1|default.t2.1"))
+                .isEqualTo("[[1, 1], [3, 2]]");
+    }
+
     @Test
     public void testGroupByWithCast() throws Exception {
         assertThat(
diff --git 
a/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoMetadata.java
 
b/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoMetadata.java
index b1a3aeb..14d9ca9 100644
--- 
a/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoMetadata.java
+++ 
b/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoMetadata.java
@@ -140,13 +140,19 @@ public class PrestoMetadata implements ConnectorMetadata {
         try {
             Table table = catalog.getTable(tablePath);
             if (!StringUtils.isBlank(scanVersion)) {
+                String tableScanVersion =
+                        PrestoPropertyUtils.getScanVersion(scanVersion, 
tablePath);
                 table =
-                        table.copy(
-                                new HashMap<String, String>() {
-                                    {
-                                        put(CoreOptions.SCAN_VERSION.key(), 
scanVersion);
-                                    }
-                                });
+                        StringUtils.isBlank(tableScanVersion)
+                                ? table
+                                : table.copy(
+                                        new HashMap<String, String>() {
+                                            {
+                                                put(
+                                                        
CoreOptions.SCAN_VERSION.key(),
+                                                        tableScanVersion);
+                                            }
+                                        });
             }
             serializedTable = InstantiationUtil.serializeObject(table);
         } catch (Catalog.TableNotExistException e) {
diff --git 
a/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoPropertyUtils.java
 
b/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoPropertyUtils.java
new file mode 100644
index 0000000..8b04228
--- /dev/null
+++ 
b/paimon-presto-common/src/main/java/org/apache/paimon/presto/PrestoPropertyUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.presto;
+
+import org.apache.paimon.catalog.Identifier;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/** Utils for PrestoProperties. */
+public class PrestoPropertyUtils {
+
+    private static final String TABLE_SCAN_OPTIONS_TEMPLATE = 
"(%s|\\*)\\.(%s|\\*)\\.(.+)";
+    private static final String TABLE_SCAN_OPTIONS_SPLITTER = "\\|";
+
+    /**
+     * The scan version can be passed using two kind of formats: 1, global 
option format
+     * ${scanVersion}; 2, table option format
+     * 
"${dbName}.${tableName}.${scanVersion1}|${dbName}.${tableName}.${scanVersion2}",
 The
+     * dbName/tableName can be *, which means matching all the specific parts.
+     */
+    public static String getScanVersion(String scanVersion, Identifier 
identifier) {
+        if (isGlobalScanOption(scanVersion)) {
+            // return scan version directly for global option format
+            return scanVersion.trim();
+        }
+
+        String[] tableScanOptions = 
scanVersion.trim().split(TABLE_SCAN_OPTIONS_SPLITTER);
+        String tableScanVersion = "";
+
+        for (String tableScanOption : tableScanOptions) {
+            String tableOptionsTemplate =
+                    String.format(
+                            TABLE_SCAN_OPTIONS_TEMPLATE,
+                            identifier.getDatabaseName(),
+                            identifier.getObjectName());
+            Pattern tableOptionsPattern = 
Pattern.compile(tableOptionsTemplate);
+            Matcher matcher = 
tableOptionsPattern.matcher(tableScanOption.trim());
+            if (matcher.find()) {
+                return matcher.group(3).trim();
+            }
+        }
+
+        return tableScanVersion;
+    }
+
+    public static boolean isGlobalScanOption(String scanVersion) {
+        return !scanVersion.contains(".");
+    }
+}
diff --git 
a/paimon-presto-common/src/test/java/org/apache/paimon/presto/PrestoPropertyUtilsTest.java
 
b/paimon-presto-common/src/test/java/org/apache/paimon/presto/PrestoPropertyUtilsTest.java
new file mode 100644
index 0000000..ad6cc90
--- /dev/null
+++ 
b/paimon-presto-common/src/test/java/org/apache/paimon/presto/PrestoPropertyUtilsTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.presto;
+
+import org.apache.paimon.catalog.Identifier;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/** Test for {@link PrestoPlugin}. */
+public class PrestoPropertyUtilsTest {
+
+    @Test
+    public void testScanVersion() {
+        Identifier t1 = new Identifier("db", "t1");
+        String scanVersion1 = "version1";
+        String scanVersion2 = "*.*.version2";
+        String scanVersion3 = "*.t1.version3";
+        String scanVersion4 = "db.t1.version4";
+        String scanVersion5 = "db.t2.version5";
+        String scanVersion6 = "db.t2.version5|db.t1.version6";
+
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion1, 
t1)).isEqualTo("version1");
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion2, 
t1)).isEqualTo("version2");
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion3, 
t1)).isEqualTo("version3");
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion4, 
t1)).isEqualTo("version4");
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion5, 
t1)).isEmpty();
+        assertThat(PrestoPropertyUtils.getScanVersion(scanVersion6, 
t1)).isEqualTo("version6");
+    }
+
+    @Test
+    public void testGlobalScanOption() {
+        String scanVersion1 = "version1";
+        String scanVersion2 = "*.*.version2";
+        String scanVersion3 = "*.*.version2|db.tb.version3";
+
+        
assertThat(PrestoPropertyUtils.isGlobalScanOption(scanVersion1)).isTrue();
+        
assertThat(PrestoPropertyUtils.isGlobalScanOption(scanVersion2)).isFalse();
+        
assertThat(PrestoPropertyUtils.isGlobalScanOption(scanVersion3)).isFalse();
+    }
+}
diff --git 
a/paimon-presto-common/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
 
b/paimon-presto-common/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
index 8643fc3..e2e8fab 100644
--- 
a/paimon-presto-common/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
+++ 
b/paimon-presto-common/src/test/java/org/apache/paimon/presto/TestPrestoITCase.java
@@ -370,6 +370,33 @@ public class TestPrestoITCase {
                 .isEqualTo("[[1, 1], [3, 2]]");
     }
 
+    @Test
+    public void testFilterWithTimeTravelAndTableOptions() throws Exception {
+        // Time travel table t2 to first commit.
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t2.1"))
+                .isEqualTo("[[1, 1], [3, 2]]");
+
+        // Invalid time travel table options
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t1.1"))
+                .isEqualTo("[[1, 1], [3, 2], [5, 3]]");
+
+        // Time travel table t2 to first commit by table options
+        assertThat(
+                        sql(
+                                "SELECT a, aCa FROM paimon.default.t2 WHERE a 
< 7",
+                                PrestoSessionProperties.SCAN_VERSION,
+                                "default.t1.1|default.t2.1"))
+                .isEqualTo("[[1, 1], [3, 2]]");
+    }
+
     @Test
     public void testGroupByWithCast() throws Exception {
         assertThat(

Reply via email to