You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@paimon.apache.org by lz...@apache.org on 2024/03/14 02:59:12 UTC

(incubator-paimon-trino) branch main updated: Refactory paimon trino module, use `TrinoFileSystem` as the only file system. (#54)

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 30ce27e  Refactory paimon trino module, use `TrinoFileSystem` as the only file system. (#54)
30ce27e is described below

commit 30ce27ef1c331c18a96fc69bec3a9d635a9ba1a1
Author: YeJunHao <41...@users.noreply.github.com>
AuthorDate: Thu Mar 14 10:59:06 2024 +0800

    Refactory paimon trino module, use `TrinoFileSystem` as the only file system. (#54)
---
 .github/workflows/ci-jdk17.yml                     |   2 +-
 .github/workflows/ci.yml                           |  33 --
 .github/workflows/publish_snapshot.yml             |  68 ----
 .github/workflows/publish_snapshot_jdk17.yml       |   2 +-
 paimon-trino-358/pom.xml                           | 122 ------
 .../java/org/apache/paimon/trino/DecimalUtils.java |  32 --
 .../apache/paimon/trino/TrinoConnectorFactory.java |  31 --
 .../apache/paimon/trino/TrinoHandleResolver.java   |  48 ---
 .../org/apache/paimon/trino/TrinoMetadata.java     |  36 --
 .../org/apache/paimon/trino/TrinoPageSource.java   |  44 ---
 .../java/org/apache/paimon/trino/TrinoSplit.java   |  72 ----
 .../org/apache/paimon/trino/TrinoSplitManager.java |  40 --
 .../org/apache/paimon/trino/TrinoSplitSource.java  |  39 --
 .../apache/paimon/trino/TestTrino358ITCase.java    |  35 --
 paimon-trino-368/pom.xml                           | 123 ------
 paimon-trino-368/src/main/assembly/paimon.xml      |  31 --
 .../apache/paimon/trino/TrinoConnectorFactory.java |  31 --
 .../apache/paimon/trino/TrinoHandleResolver.java   |  48 ---
 .../org/apache/paimon/trino/TrinoMetadata.java     | 138 -------
 .../org/apache/paimon/trino/TrinoPageSource.java   |  44 ---
 .../org/apache/paimon/trino/TrinoSplitManager.java |  40 --
 .../org/apache/paimon/trino/TrinoSplitSource.java  |  39 --
 .../apache/paimon/trino/TestTrino368ITCase.java    |  26 --
 .../src/test/resources/log4j2-test.properties      |  28 --
 paimon-trino-369/pom.xml                           | 123 ------
 paimon-trino-369/src/main/assembly/paimon.xml      |  31 --
 .../apache/paimon/trino/TrinoConnectorFactory.java |  31 --
 .../apache/paimon/trino/TrinoHandleResolver.java   |  48 ---
 .../org/apache/paimon/trino/TrinoMetadata.java     | 133 -------
 .../org/apache/paimon/trino/TrinoSplitManager.java |  40 --
 .../org/apache/paimon/trino/TrinoSplitSource.java  |  39 --
 .../apache/paimon/trino/TestTrino369ITCase.java    |  26 --
 .../src/test/resources/log4j2-test.properties      |  28 --
 paimon-trino-370/pom.xml                           | 123 ------
 paimon-trino-370/src/main/assembly/paimon.xml      |  31 --
 .../org/apache/paimon/trino/TrinoMetadata.java     | 133 -------
 .../org/apache/paimon/trino/TrinoSplitManager.java |  42 --
 .../org/apache/paimon/trino/TrinoSplitSource.java  |  39 --
 .../src/test/resources/log4j2-test.properties      |  28 --
 paimon-trino-388/pom.xml                           | 122 ------
 paimon-trino-388/src/main/assembly/paimon.xml      |  31 --
 .../apache/paimon/trino/TestTrino388ITCase.java    |  26 --
 .../src/test/resources/log4j2-test.properties      |  28 --
 paimon-trino-393/src/main/assembly/paimon.xml      |  31 --
 .../apache/paimon/trino/TestTrino393ITCase.java    |  26 --
 .../src/test/resources/log4j2-test.properties      |  28 --
 paimon-trino-422/pom.xml                           |   6 +
 .../org/apache/paimon/trino/TrinoConnector.java    |  55 ---
 .../apache/paimon/trino/TrinoConnectorFactory.java |  54 ---
 .../apache/paimon/trino/TrinoMetadataFactory.java  |  62 ---
 .../org/apache/paimon/trino/TrinoPageSource.java   | 163 --------
 .../apache/paimon/trino/fileio/TrinoFileIO.java    | 166 ++++++++
 .../apache/paimon/trino/TestTrino422ITCase.java    |  27 ++
 {paimon-trino-393 => paimon-trino-427}/pom.xml     |  42 +-
 .../src/main/assembly/paimon.xml                   |   0
 .../apache/paimon/trino/TestTrino427ITCase.java    |   9 +-
 .../src/test/resources/log4j2-test.properties      |   0
 paimon-trino-common/pom.xml                        |  14 +-
 .../java/org/apache/paimon/trino/DecimalUtils.java |  11 +-
 .../org/apache/paimon/trino/DecimalUtilsBase.java  |  31 --
 .../apache/paimon/trino/DirectTrinoPageSource.java | 117 ++++++
 .../org/apache/paimon/trino/HiveHdfsModule.java    |  52 ---
 .../org/apache/paimon/trino/TrinoConnector.java    |  67 +++-
 .../apache/paimon/trino/TrinoConnectorBase.java    |  83 ----
 .../apache/paimon/trino/TrinoConnectorFactory.java |  78 +++-
 .../paimon/trino/TrinoConnectorFactoryBase.java    |  91 -----
 .../org/apache/paimon/trino/TrinoMetadata.java     | 404 ++++++++++++++++++-
 .../org/apache/paimon/trino/TrinoMetadataBase.java | 437 ---------------------
 .../apache/paimon/trino/TrinoMetadataFactory.java  |  34 +-
 .../apache/paimon/trino/TrinoOrcDataSource.java    |  58 +++
 .../org/apache/paimon/trino/TrinoPageSource.java   | 325 ++++++++++++++-
 .../apache/paimon/trino/TrinoPageSourceBase.java   | 330 ----------------
 .../paimon/trino/TrinoPageSourceProvider.java      | 276 ++++++++++++-
 .../org/apache/paimon/trino/TrinoSplitManager.java |  59 ++-
 .../apache/paimon/trino/TrinoSplitManagerBase.java |  66 ----
 .../org/apache/paimon/trino/TrinoSplitSource.java  |  37 +-
 .../apache/paimon/trino/TrinoSplitSourceBase.java  |  58 ---
 .../org/apache/paimon/trino/TrinoTableHandle.java  |  98 ++---
 .../apache/paimon/trino/catalog/TrinoCatalog.java  | 203 ++++++++++
 .../trino/fileio/PositionOutputStreamWrapper.java  |  76 ++++
 .../trino/fileio/TrinoDirectoryFileStatus.java     |  56 +++
 .../apache/paimon/trino/fileio/TrinoFileIO.java    | 170 ++++++++
 .../paimon/trino/fileio/TrinoFileIOLoader.java     |  47 +++
 .../paimon/trino/fileio/TrinoFileStatus.java       |  58 +++
 .../trino/fileio/TrinoInputStreamWrapper.java      |  62 +++
 .../apache/paimon/trino/SimpleTableTestHelper.java |   2 +-
 .../paimon/trino/TestTrinoDistributedQuery.java    |  15 +
 .../org/apache/paimon/trino/TestTrinoITCase.java   | 141 ++++++-
 .../apache/paimon/trino/TestTrinoTableHandle.java  |   5 +-
 pom.xml                                            |   7 +-
 90 files changed, 2541 insertions(+), 3950 deletions(-)

diff --git a/.github/workflows/ci-jdk17.yml b/.github/workflows/ci-jdk17.yml
index b2f36ad..3e9d15b 100644
--- a/.github/workflows/ci-jdk17.yml
+++ b/.github/workflows/ci-jdk17.yml
@@ -30,4 +30,4 @@ jobs:
           java-version: 17
       - name: Build
         run: |
-          mvn clean install -P '!toolchain' -pl paimon-trino-common,paimon-trino-393,paimon-trino-422
+          mvn clean install -P '!toolchain' -pl paimon-trino-common,paimon-trino-422,paimon-trino-427
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index fc48186..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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.
-
-name: Java 11 Build
-
-on: [push, pull_request]
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v2
-      - name: Set up JDK 11
-        uses: actions/setup-java@v1
-        with:
-          java-version: 11
-      - name: Build
-        run: |
-          mvn clean install -pl paimon-trino-common,paimon-trino-358,paimon-trino-368,paimon-trino-369,paimon-trino-370,paimon-trino-388
diff --git a/.github/workflows/publish_snapshot.yml b/.github/workflows/publish_snapshot.yml
deleted file mode 100644
index 47545c8..0000000
--- a/.github/workflows/publish_snapshot.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-name: Publish Snapshot
-
-on:
-  schedule:
-    # At the end of every day
-    - cron: '0 0 * * *'
-  workflow_dispatch:
-
-env:
-  JDK_VERSION: 11
-
-concurrency:
-  group: ps-${{ github.event.pull_request.number || github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  publish-snapshot:
-    if: github.repository == 'apache/incubator-paimon-trino'
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v2
-      # temporarily publish the jdk11 version to maven
-      # lately when jdk is deprecated, we need update it to jdk11
-      - name: Set up JDK ${{ env.JDK_VERSION }}
-        uses: actions/setup-java@v2
-        with:
-          java-version: ${{ env.JDK_VERSION }}
-          distribution: 'adopt'
-      - name: Cache local Maven repository
-        uses: actions/cache@v3
-        with:
-          path: ~/.m2/repository
-          key: snapshot-maven-${{ hashFiles('**/pom.xml') }}
-          restore-keys: |
-            snapshot-maven-
-      - name: Publish snapshot
-        env:
-          ASF_USERNAME: ${{ secrets.NEXUS_USER }}
-          ASF_PASSWORD: ${{ secrets.NEXUS_PW }}
-        run: |
-          tmp_settings="tmp-settings.xml"
-          echo "<settings><servers><server>" > $tmp_settings
-          echo "<id>apache.snapshots.https</id><username>$ASF_USERNAME</username>" >> $tmp_settings
-          echo "<password>$ASF_PASSWORD</password>" >> $tmp_settings
-          echo "</server></servers></settings>" >> $tmp_settings
-          
-          mvn --settings $tmp_settings clean deploy -Dgpg.skip -Drat.skip -DskipTests -Papache-release -pl paimon-trino-common,paimon-trino-358,paimon-trino-368,paimon-trino-369,paimon-trino-370,paimon-trino-388
-          
-          rm $tmp_settings
diff --git a/.github/workflows/publish_snapshot_jdk17.yml b/.github/workflows/publish_snapshot_jdk17.yml
index 3d73996..322e1de 100644
--- a/.github/workflows/publish_snapshot_jdk17.yml
+++ b/.github/workflows/publish_snapshot_jdk17.yml
@@ -81,6 +81,6 @@ jobs:
           echo "<password>$ASF_PASSWORD</password>" >> $tmp_settings
           echo "</server></servers></settings>" >> $tmp_settings
           
-          mvn --settings $tmp_settings clean deploy -Dgpg.skip -Drat.skip -DskipTests -Papache-release -pl paimon-trino-common,paimon-trino-393,paimon-trino-422
+          mvn --settings $tmp_settings clean deploy -Dgpg.skip -Drat.skip -DskipTests -Papache-release -pl paimon-trino-common,paimon-trino-422,paimon-trino-427
           
           rm $tmp_settings
diff --git a/paimon-trino-358/pom.xml b/paimon-trino-358/pom.xml
deleted file mode 100644
index a3d4098..0000000
--- a/paimon-trino-358/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.paimon</groupId>
-        <artifactId>paimon-trino</artifactId>
-        <version>0.8-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>paimon-trino-358</artifactId>
-    <name>Paimon : Trino : 358</name>
-
-    <properties>
-        <trino.version>358</trino.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-plugin-toolkit</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-spi</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- for testing -->
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-client</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-main</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-testing</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.5</version>
-                <configuration>
-                    <descriptors>
-                        <descriptor>src/main/assembly/paimon.xml</descriptor>
-                    </descriptors>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attached</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/DecimalUtils.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/DecimalUtils.java
deleted file mode 100644
index deb22d6..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/DecimalUtils.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.trino;
-
-import io.airlift.slice.Slice;
-import io.trino.spi.type.Decimals;
-
-import java.math.BigInteger;
-
-/** Utils for decimal. */
-public class DecimalUtils {
-
-    public static BigInteger toBigInteger(Object value) {
-        return Decimals.decodeUnscaledValue((Slice) value);
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
deleted file mode 100644
index 5a82c7b..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorFactory;
-import io.trino.spi.connector.ConnectorHandleResolver;
-
-/** Trino {@link ConnectorFactory}. */
-public class TrinoConnectorFactory extends TrinoConnectorFactoryBase {
-
-    @Override
-    public ConnectorHandleResolver getHandleResolver() {
-        return new TrinoHandleResolver();
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
deleted file mode 100644
index 78e5d8c..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorHandleResolver;
-import io.trino.spi.connector.ConnectorSplit;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-
-/** Trino {@link ConnectorHandleResolver}. */
-public class TrinoHandleResolver implements ConnectorHandleResolver {
-    @Override
-    public Class<? extends ConnectorTransactionHandle> getTransactionHandleClass() {
-        return TrinoTransactionHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorTableHandle> getTableHandleClass() {
-        return TrinoTableHandle.class;
-    }
-
-    @Override
-    public Class<? extends ColumnHandle> getColumnHandleClass() {
-        return TrinoColumnHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorSplit> getSplitClass() {
-        return TrinoSplit.class;
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoMetadata.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
deleted file mode 100644
index 3d5e04c..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.catalog.Catalog;
-
-import io.trino.spi.connector.ConnectorMetadata;
-
-/** Trino {@link ConnectorMetadata}. */
-public class TrinoMetadata extends TrinoMetadataBase {
-
-    public TrinoMetadata(Catalog catalog) {
-        super(catalog);
-    }
-
-    @Override
-    public boolean usesLegacyTableLayouts() {
-        return false;
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoPageSource.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
deleted file mode 100644
index 617c9d0..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.reader.RecordReader;
-
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorPageSource;
-
-import java.util.List;
-import java.util.OptionalLong;
-
-/** Trino {@link ConnectorPageSource}. */
-public class TrinoPageSource extends TrinoPageSourceBase {
-
-    public TrinoPageSource(
-            RecordReader<InternalRow> reader,
-            List<ColumnHandle> projectedColumns,
-            OptionalLong limit) {
-        super(reader, projectedColumns, limit);
-    }
-
-    @Override
-    public long getSystemMemoryUsage() {
-        return 0;
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplit.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplit.java
deleted file mode 100644
index 86d6410..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplit.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.table.source.Split;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import io.trino.spi.HostAddress;
-import io.trino.spi.connector.ConnectorSplit;
-
-import java.util.Collections;
-import java.util.List;
-
-/** Trino {@link ConnectorSplit}. */
-public class TrinoSplit implements ConnectorSplit {
-
-    private final String splitSerialized;
-
-    @JsonCreator
-    public TrinoSplit(
-            @JsonProperty("splitSerialized") String splitSerialized,
-            // weight is not required, it's just to align the constructor parameters with other
-            // versions.
-            @JsonProperty("weight") Double weight) {
-        this.splitSerialized = splitSerialized;
-    }
-
-    public static TrinoSplit fromSplit(Split split, Double weight) {
-        return new TrinoSplit(EncodingUtils.encodeObjectToString(split), weight);
-    }
-
-    public Split decodeSplit() {
-        return EncodingUtils.decodeStringToObject(splitSerialized);
-    }
-
-    @JsonProperty
-    public String getSplitSerialized() {
-        return splitSerialized;
-    }
-
-    @Override
-    public boolean isRemotelyAccessible() {
-        return true;
-    }
-
-    @Override
-    public List<HostAddress> getAddresses() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public Object getInfo() {
-        return Collections.emptyMap();
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
deleted file mode 100644
index 8a57210..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorSplitManager;
-import io.trino.spi.connector.ConnectorSplitSource;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.connector.DynamicFilter;
-
-/** Trino {@link ConnectorSplitManager}. */
-public class TrinoSplitManager extends TrinoSplitManagerBase {
-
-    @Override
-    public ConnectorSplitSource getSplits(
-            ConnectorTransactionHandle transaction,
-            ConnectorSession session,
-            ConnectorTableHandle table,
-            SplitSchedulingStrategy splitSchedulingStrategy,
-            DynamicFilter dynamicFilter) {
-        return getSplits(table, session);
-    }
-}
diff --git a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java b/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
deleted file mode 100644
index 0e2a86a..0000000
--- a/paimon-trino-358/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorPartitionHandle;
-import io.trino.spi.connector.ConnectorSplitSource;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-/** Trino {@link ConnectorSplitSource}. */
-public class TrinoSplitSource extends TrinoSplitSourceBase {
-
-    public TrinoSplitSource(List<TrinoSplit> splits) {
-        super(splits);
-    }
-
-    @Override
-    public CompletableFuture<ConnectorSplitBatch> getNextBatch(
-            ConnectorPartitionHandle partitionHandle, int maxSize) {
-        return innerGetNextBatch(maxSize);
-    }
-}
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
deleted file mode 100644
index 98bd9fc..0000000
--- a/paimon-trino-358/src/test/java/org/apache/paimon/trino/TestTrino358ITCase.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.trino;
-
-import org.testng.annotations.Test;
-
-/** {@link TestTrinoITCase} for Trino 358. */
-public class TestTrino358ITCase extends TestTrinoITCase {
-
-    public TestTrino358ITCase() {
-        super(358);
-    }
-
-    @Override
-    @Test
-    public void testSetTableProperties() {
-        // not supported
-    }
-}
diff --git a/paimon-trino-368/pom.xml b/paimon-trino-368/pom.xml
deleted file mode 100644
index 338fd32..0000000
--- a/paimon-trino-368/pom.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.paimon</groupId>
-        <artifactId>paimon-trino</artifactId>
-        <version>0.8-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>paimon-trino-368</artifactId>
-    <name>Paimon : Trino : 368</name>
-
-    <properties>
-        <trino.version>368</trino.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-plugin-toolkit</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-spi</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- for testing -->
-
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-client</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-main</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-testing</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.5</version>
-                <configuration>
-                    <descriptors>
-                        <descriptor>src/main/assembly/paimon.xml</descriptor>
-                    </descriptors>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attached</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/paimon-trino-368/src/main/assembly/paimon.xml b/paimon-trino-368/src/main/assembly/paimon.xml
deleted file mode 100644
index ba1bd63..0000000
--- a/paimon-trino-368/src/main/assembly/paimon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
-<assembly>
-    <id>plugin</id>
-    <formats>
-        <format>tar.gz</format>
-    </formats>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>paimon</outputDirectory>
-            <scope>runtime</scope>
-        </dependencySet>
-    </dependencySets>
-</assembly>
diff --git a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
deleted file mode 100644
index 5a82c7b..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorFactory;
-import io.trino.spi.connector.ConnectorHandleResolver;
-
-/** Trino {@link ConnectorFactory}. */
-public class TrinoConnectorFactory extends TrinoConnectorFactoryBase {
-
-    @Override
-    public ConnectorHandleResolver getHandleResolver() {
-        return new TrinoHandleResolver();
-    }
-}
diff --git a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
deleted file mode 100644
index 78e5d8c..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorHandleResolver;
-import io.trino.spi.connector.ConnectorSplit;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-
-/** Trino {@link ConnectorHandleResolver}. */
-public class TrinoHandleResolver implements ConnectorHandleResolver {
-    @Override
-    public Class<? extends ConnectorTransactionHandle> getTransactionHandleClass() {
-        return TrinoTransactionHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorTableHandle> getTableHandleClass() {
-        return TrinoTableHandle.class;
-    }
-
-    @Override
-    public Class<? extends ColumnHandle> getColumnHandleClass() {
-        return TrinoColumnHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorSplit> getSplitClass() {
-        return TrinoSplit.class;
-    }
-}
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
deleted file mode 100644
index 31fa993..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.CoreOptions;
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.Identifier;
-import org.apache.paimon.schema.SchemaChange;
-
-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;
-
-/** Trino {@link ConnectorMetadata}. */
-public class TrinoMetadata extends TrinoMetadataBase {
-
-    public TrinoMetadata(Catalog catalog) {
-        super(catalog);
-    }
-
-    @Override
-    public boolean usesLegacyTableLayouts() {
-        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,
-            ConnectorTableHandle tableHandle,
-            Map<String, Object> properties) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        List<SchemaChange> changes = new ArrayList<>();
-        Map<String, String> options =
-                properties.entrySet().stream()
-                        .collect(toMap(Map.Entry::getKey, e -> (String) e.getValue()));
-        options.forEach((key, value) -> changes.add(SchemaChange.setOption(key, value)));
-        // TODO: remove options, SET PROPERTIES x = DEFAULT
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-}
diff --git a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoPageSource.java b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
deleted file mode 100644
index 617c9d0..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.reader.RecordReader;
-
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorPageSource;
-
-import java.util.List;
-import java.util.OptionalLong;
-
-/** Trino {@link ConnectorPageSource}. */
-public class TrinoPageSource extends TrinoPageSourceBase {
-
-    public TrinoPageSource(
-            RecordReader<InternalRow> reader,
-            List<ColumnHandle> projectedColumns,
-            OptionalLong limit) {
-        super(reader, projectedColumns, limit);
-    }
-
-    @Override
-    public long getSystemMemoryUsage() {
-        return 0;
-    }
-}
diff --git a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
deleted file mode 100644
index 8a57210..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorSplitManager;
-import io.trino.spi.connector.ConnectorSplitSource;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.connector.DynamicFilter;
-
-/** Trino {@link ConnectorSplitManager}. */
-public class TrinoSplitManager extends TrinoSplitManagerBase {
-
-    @Override
-    public ConnectorSplitSource getSplits(
-            ConnectorTransactionHandle transaction,
-            ConnectorSession session,
-            ConnectorTableHandle table,
-            SplitSchedulingStrategy splitSchedulingStrategy,
-            DynamicFilter dynamicFilter) {
-        return getSplits(table, session);
-    }
-}
diff --git a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java b/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
deleted file mode 100644
index 0e2a86a..0000000
--- a/paimon-trino-368/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorPartitionHandle;
-import io.trino.spi.connector.ConnectorSplitSource;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-/** Trino {@link ConnectorSplitSource}. */
-public class TrinoSplitSource extends TrinoSplitSourceBase {
-
-    public TrinoSplitSource(List<TrinoSplit> splits) {
-        super(splits);
-    }
-
-    @Override
-    public CompletableFuture<ConnectorSplitBatch> getNextBatch(
-            ConnectorPartitionHandle partitionHandle, int maxSize) {
-        return innerGetNextBatch(maxSize);
-    }
-}
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
deleted file mode 100644
index e2badeb..0000000
--- a/paimon-trino-368/src/test/java/org/apache/paimon/trino/TestTrino368ITCase.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.trino;
-
-/** {@link TestTrinoITCase} for Trino 368. */
-public class TestTrino368ITCase extends TestTrinoITCase {
-    public TestTrino368ITCase() {
-        super(368);
-    }
-}
diff --git a/paimon-trino-368/src/test/resources/log4j2-test.properties b/paimon-trino-368/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 1b3980d..0000000
--- a/paimon-trino-368/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-# Set root logger level to OFF to not flood build logs
-# set manually to INFO for debugging purposes
-rootLogger.level = OFF
-rootLogger.appenderRef.test.ref = TestLogger
-
-appender.testlogger.name = TestLogger
-appender.testlogger.type = CONSOLE
-appender.testlogger.target = SYSTEM_ERR
-appender.testlogger.layout.type = PatternLayout
-appender.testlogger.layout.pattern = %-4r [%tid %t] %-5p %c %x - %m%n
diff --git a/paimon-trino-369/pom.xml b/paimon-trino-369/pom.xml
deleted file mode 100644
index 482c0c9..0000000
--- a/paimon-trino-369/pom.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.paimon</groupId>
-        <artifactId>paimon-trino</artifactId>
-        <version>0.8-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>paimon-trino-369</artifactId>
-    <name>Paimon : Trino : 369</name>
-
-    <properties>
-        <trino.version>369</trino.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-plugin-toolkit</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-spi</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- for testing -->
-
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-client</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-main</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-testing</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.5</version>
-                <configuration>
-                    <descriptors>
-                        <descriptor>src/main/assembly/paimon.xml</descriptor>
-                    </descriptors>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attached</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/paimon-trino-369/src/main/assembly/paimon.xml b/paimon-trino-369/src/main/assembly/paimon.xml
deleted file mode 100644
index ba1bd63..0000000
--- a/paimon-trino-369/src/main/assembly/paimon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
-<assembly>
-    <id>plugin</id>
-    <formats>
-        <format>tar.gz</format>
-    </formats>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>paimon</outputDirectory>
-            <scope>runtime</scope>
-        </dependencySet>
-    </dependencySets>
-</assembly>
diff --git a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
deleted file mode 100644
index 5a82c7b..0000000
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorFactory;
-import io.trino.spi.connector.ConnectorHandleResolver;
-
-/** Trino {@link ConnectorFactory}. */
-public class TrinoConnectorFactory extends TrinoConnectorFactoryBase {
-
-    @Override
-    public ConnectorHandleResolver getHandleResolver() {
-        return new TrinoHandleResolver();
-    }
-}
diff --git a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
deleted file mode 100644
index 78e5d8c..0000000
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoHandleResolver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorHandleResolver;
-import io.trino.spi.connector.ConnectorSplit;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-
-/** Trino {@link ConnectorHandleResolver}. */
-public class TrinoHandleResolver implements ConnectorHandleResolver {
-    @Override
-    public Class<? extends ConnectorTransactionHandle> getTransactionHandleClass() {
-        return TrinoTransactionHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorTableHandle> getTableHandleClass() {
-        return TrinoTableHandle.class;
-    }
-
-    @Override
-    public Class<? extends ColumnHandle> getColumnHandleClass() {
-        return TrinoColumnHandle.class;
-    }
-
-    @Override
-    public Class<? extends ConnectorSplit> getSplitClass() {
-        return TrinoSplit.class;
-    }
-}
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
deleted file mode 100644
index b03ae50..0000000
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.CoreOptions;
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.Identifier;
-import org.apache.paimon.schema.SchemaChange;
-
-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;
-
-/** Trino {@link ConnectorMetadata}. */
-public class TrinoMetadata extends TrinoMetadataBase {
-
-    public TrinoMetadata(Catalog catalog) {
-        super(catalog);
-    }
-
-    @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,
-            ConnectorTableHandle tableHandle,
-            Map<String, Object> properties) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        List<SchemaChange> changes = new ArrayList<>();
-        Map<String, String> options =
-                properties.entrySet().stream()
-                        .collect(toMap(Map.Entry::getKey, e -> (String) e.getValue()));
-        options.forEach((key, value) -> changes.add(SchemaChange.setOption(key, value)));
-        // TODO: remove options, SET PROPERTIES x = DEFAULT
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-}
diff --git a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
deleted file mode 100644
index 8a57210..0000000
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorSplitManager;
-import io.trino.spi.connector.ConnectorSplitSource;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.connector.DynamicFilter;
-
-/** Trino {@link ConnectorSplitManager}. */
-public class TrinoSplitManager extends TrinoSplitManagerBase {
-
-    @Override
-    public ConnectorSplitSource getSplits(
-            ConnectorTransactionHandle transaction,
-            ConnectorSession session,
-            ConnectorTableHandle table,
-            SplitSchedulingStrategy splitSchedulingStrategy,
-            DynamicFilter dynamicFilter) {
-        return getSplits(table, session);
-    }
-}
diff --git a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java b/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
deleted file mode 100644
index 0e2a86a..0000000
--- a/paimon-trino-369/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorPartitionHandle;
-import io.trino.spi.connector.ConnectorSplitSource;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-/** Trino {@link ConnectorSplitSource}. */
-public class TrinoSplitSource extends TrinoSplitSourceBase {
-
-    public TrinoSplitSource(List<TrinoSplit> splits) {
-        super(splits);
-    }
-
-    @Override
-    public CompletableFuture<ConnectorSplitBatch> getNextBatch(
-            ConnectorPartitionHandle partitionHandle, int maxSize) {
-        return innerGetNextBatch(maxSize);
-    }
-}
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
deleted file mode 100644
index 7ec111c..0000000
--- a/paimon-trino-369/src/test/java/org/apache/paimon/trino/TestTrino369ITCase.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.trino;
-
-/** {@link TestTrinoITCase} for Trino 369. */
-public class TestTrino369ITCase extends TestTrinoITCase {
-    public TestTrino369ITCase() {
-        super(369);
-    }
-}
diff --git a/paimon-trino-369/src/test/resources/log4j2-test.properties b/paimon-trino-369/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 1b3980d..0000000
--- a/paimon-trino-369/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-# Set root logger level to OFF to not flood build logs
-# set manually to INFO for debugging purposes
-rootLogger.level = OFF
-rootLogger.appenderRef.test.ref = TestLogger
-
-appender.testlogger.name = TestLogger
-appender.testlogger.type = CONSOLE
-appender.testlogger.target = SYSTEM_ERR
-appender.testlogger.layout.type = PatternLayout
-appender.testlogger.layout.pattern = %-4r [%tid %t] %-5p %c %x - %m%n
diff --git a/paimon-trino-370/pom.xml b/paimon-trino-370/pom.xml
deleted file mode 100644
index df56d2e..0000000
--- a/paimon-trino-370/pom.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.paimon</groupId>
-        <artifactId>paimon-trino</artifactId>
-        <version>0.8-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>paimon-trino-370</artifactId>
-    <name>Paimon : Trino : 370</name>
-
-    <properties>
-        <trino.version>370</trino.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-plugin-toolkit</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-spi</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- for testing -->
-
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-client</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-main</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-testing</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.5</version>
-                <configuration>
-                    <descriptors>
-                        <descriptor>src/main/assembly/paimon.xml</descriptor>
-                    </descriptors>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attached</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/paimon-trino-370/src/main/assembly/paimon.xml b/paimon-trino-370/src/main/assembly/paimon.xml
deleted file mode 100644
index ba1bd63..0000000
--- a/paimon-trino-370/src/main/assembly/paimon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
-<assembly>
-    <id>plugin</id>
-    <formats>
-        <format>tar.gz</format>
-    </formats>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>paimon</outputDirectory>
-            <scope>runtime</scope>
-        </dependencySet>
-    </dependencySets>
-</assembly>
diff --git a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java b/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
deleted file mode 100644
index 9875ae0..0000000
--- a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoMetadata.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.CoreOptions;
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.Identifier;
-import org.apache.paimon.schema.SchemaChange;
-
-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;
-
-/** Trino {@link ConnectorMetadata}. */
-public class TrinoMetadata extends TrinoMetadataBase {
-
-    public TrinoMetadata(Catalog catalog) {
-        super(catalog);
-    }
-
-    @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,
-            ConnectorTableHandle tableHandle,
-            Map<String, Optional<Object>> properties) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        List<SchemaChange> changes = new ArrayList<>();
-        Map<String, String> options =
-                properties.entrySet().stream()
-                        .collect(toMap(Map.Entry::getKey, e -> (String) e.getValue().get()));
-        options.forEach((key, value) -> changes.add(SchemaChange.setOption(key, value)));
-        // TODO: remove options, SET PROPERTIES x = DEFAULT
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-}
diff --git a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java b/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
deleted file mode 100644
index de6c091..0000000
--- a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorSplitManager;
-import io.trino.spi.connector.ConnectorSplitSource;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.connector.Constraint;
-import io.trino.spi.connector.DynamicFilter;
-
-/** Trino {@link ConnectorSplitManager}. */
-public class TrinoSplitManager extends TrinoSplitManagerBase {
-
-    @Override
-    public ConnectorSplitSource getSplits(
-            ConnectorTransactionHandle transaction,
-            ConnectorSession session,
-            ConnectorTableHandle table,
-            SplitSchedulingStrategy splitSchedulingStrategy,
-            DynamicFilter dynamicFilter,
-            Constraint constraint) {
-        return getSplits(table, session);
-    }
-}
diff --git a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java b/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
deleted file mode 100644
index 0e2a86a..0000000
--- a/paimon-trino-370/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorPartitionHandle;
-import io.trino.spi.connector.ConnectorSplitSource;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-/** Trino {@link ConnectorSplitSource}. */
-public class TrinoSplitSource extends TrinoSplitSourceBase {
-
-    public TrinoSplitSource(List<TrinoSplit> splits) {
-        super(splits);
-    }
-
-    @Override
-    public CompletableFuture<ConnectorSplitBatch> getNextBatch(
-            ConnectorPartitionHandle partitionHandle, int maxSize) {
-        return innerGetNextBatch(maxSize);
-    }
-}
diff --git a/paimon-trino-370/src/test/resources/log4j2-test.properties b/paimon-trino-370/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 1b3980d..0000000
--- a/paimon-trino-370/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-# Set root logger level to OFF to not flood build logs
-# set manually to INFO for debugging purposes
-rootLogger.level = OFF
-rootLogger.appenderRef.test.ref = TestLogger
-
-appender.testlogger.name = TestLogger
-appender.testlogger.type = CONSOLE
-appender.testlogger.target = SYSTEM_ERR
-appender.testlogger.layout.type = PatternLayout
-appender.testlogger.layout.pattern = %-4r [%tid %t] %-5p %c %x - %m%n
diff --git a/paimon-trino-388/pom.xml b/paimon-trino-388/pom.xml
deleted file mode 100644
index 120cd20..0000000
--- a/paimon-trino-388/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <artifactId>paimon-trino</artifactId>
-        <groupId>org.apache.paimon</groupId>
-        <version>0.8-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>paimon-trino-388</artifactId>
-    <name>Paimon : Trino : 388</name>
-
-    <properties>
-        <trino.version>388</trino.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-plugin-toolkit</artifactId>
-            <version>${trino.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-spi</artifactId>
-            <version>${trino.version}</version>
-        </dependency>
-
-        <!-- for testing -->
-
-        <dependency>
-            <groupId>org.apache.paimon</groupId>
-            <artifactId>paimon-trino-common</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-client</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-main</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>io.trino</groupId>
-            <artifactId>trino-testing</artifactId>
-            <version>${trino.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.5</version>
-                <configuration>
-                    <descriptors>
-                        <descriptor>src/main/assembly/paimon.xml</descriptor>
-                    </descriptors>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attached</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/paimon-trino-388/src/main/assembly/paimon.xml b/paimon-trino-388/src/main/assembly/paimon.xml
deleted file mode 100644
index ba1bd63..0000000
--- a/paimon-trino-388/src/main/assembly/paimon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
-<assembly>
-    <id>plugin</id>
-    <formats>
-        <format>tar.gz</format>
-    </formats>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>paimon</outputDirectory>
-            <scope>runtime</scope>
-        </dependencySet>
-    </dependencySets>
-</assembly>
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
deleted file mode 100644
index decefcf..0000000
--- a/paimon-trino-388/src/test/java/org/apache/paimon/trino/TestTrino388ITCase.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.trino;
-
-/** {@link TestTrinoITCase} for Trino 388. */
-public class TestTrino388ITCase extends TestTrinoITCase {
-    public TestTrino388ITCase() {
-        super(388);
-    }
-}
diff --git a/paimon-trino-388/src/test/resources/log4j2-test.properties b/paimon-trino-388/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 1b3980d..0000000
--- a/paimon-trino-388/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-# Set root logger level to OFF to not flood build logs
-# set manually to INFO for debugging purposes
-rootLogger.level = OFF
-rootLogger.appenderRef.test.ref = TestLogger
-
-appender.testlogger.name = TestLogger
-appender.testlogger.type = CONSOLE
-appender.testlogger.target = SYSTEM_ERR
-appender.testlogger.layout.type = PatternLayout
-appender.testlogger.layout.pattern = %-4r [%tid %t] %-5p %c %x - %m%n
diff --git a/paimon-trino-393/src/main/assembly/paimon.xml b/paimon-trino-393/src/main/assembly/paimon.xml
deleted file mode 100644
index ba1bd63..0000000
--- a/paimon-trino-393/src/main/assembly/paimon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
-<assembly>
-    <id>plugin</id>
-    <formats>
-        <format>tar.gz</format>
-    </formats>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>paimon</outputDirectory>
-            <scope>runtime</scope>
-        </dependencySet>
-    </dependencySets>
-</assembly>
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
deleted file mode 100644
index 0a240f0..0000000
--- a/paimon-trino-393/src/test/java/org/apache/paimon/trino/TestTrino393ITCase.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.trino;
-
-/** {@link TestTrinoITCase} for Trino 393. */
-public class TestTrino393ITCase extends TestTrinoITCase {
-    public TestTrino393ITCase() {
-        super(393);
-    }
-}
diff --git a/paimon-trino-393/src/test/resources/log4j2-test.properties b/paimon-trino-393/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 1b3980d..0000000
--- a/paimon-trino-393/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-################################################################################
-#  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.
-################################################################################
-
-# Set root logger level to OFF to not flood build logs
-# set manually to INFO for debugging purposes
-rootLogger.level = OFF
-rootLogger.appenderRef.test.ref = TestLogger
-
-appender.testlogger.name = TestLogger
-appender.testlogger.type = CONSOLE
-appender.testlogger.target = SYSTEM_ERR
-appender.testlogger.layout.type = PatternLayout
-appender.testlogger.layout.pattern = %-4r [%tid %t] %-5p %c %x - %m%n
diff --git a/paimon-trino-422/pom.xml b/paimon-trino-422/pom.xml
index f761bc7..1a7a995 100644
--- a/paimon-trino-422/pom.xml
+++ b/paimon-trino-422/pom.xml
@@ -67,6 +67,12 @@ under the License.
             <version>${trino.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>io.trino</groupId>
+            <artifactId>trino-hive</artifactId>
+            <version>${trino.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>io.airlift</groupId>
             <artifactId>bootstrap</artifactId>
diff --git a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnector.java b/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnector.java
deleted file mode 100644
index beff06a..0000000
--- a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnector.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.Connector;
-import io.trino.spi.connector.ConnectorMetadata;
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.transaction.IsolationLevel;
-
-/** Trino {@link Connector}. */
-public class TrinoConnector extends TrinoConnectorBase {
-
-    public TrinoConnector(
-            TrinoMetadataBase trinoMetadata,
-            TrinoSplitManagerBase trinoSplitManager,
-            TrinoPageSourceProvider trinoPageSourceProvider,
-            TrinoTableOptions trinoTableOptions,
-            TrinoSessionProperties trinoSessionProperties) {
-        super(
-                trinoMetadata,
-                trinoSplitManager,
-                trinoPageSourceProvider,
-                trinoTableOptions,
-                trinoSessionProperties);
-    }
-
-    @Override
-    public ConnectorTransactionHandle beginTransaction(
-            IsolationLevel isolationLevel, boolean readOnly, boolean autoCommit) {
-        return beginTransactionBase(isolationLevel, readOnly);
-    }
-
-    @Override
-    public ConnectorMetadata getMetadata(
-            ConnectorSession session, ConnectorTransactionHandle transactionHandle) {
-        return getMetadataBase(transactionHandle);
-    }
-}
diff --git a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java b/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
deleted file mode 100644
index 270c031..0000000
--- a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.trino;
-
-import com.google.inject.Module;
-import io.airlift.json.JsonModule;
-import io.opentelemetry.api.OpenTelemetry;
-import io.trino.hdfs.HdfsModule;
-import io.trino.hdfs.authentication.HdfsAuthenticationModule;
-import io.trino.plugin.hive.NodeVersion;
-import io.trino.spi.connector.ConnectorContext;
-import io.trino.spi.connector.ConnectorFactory;
-import io.trino.spi.type.TypeManager;
-
-import java.util.Map;
-
-/** Trino {@link ConnectorFactory}. */
-public class TrinoConnectorFactory extends TrinoConnectorFactoryBase {
-
-    @Override
-    protected Module[] modules(
-            String catalogName, Map<String, String> config, ConnectorContext context) {
-        return new Module[] {
-            new JsonModule(),
-            new TrinoModule(config),
-            new HdfsModule(),
-            new HdfsAuthenticationModule(),
-            binder -> {
-                binder.bind(NodeVersion.class)
-                        .toInstance(
-                                new NodeVersion(
-                                        context.getNodeManager().getCurrentNode().getVersion()));
-                binder.bind(TypeManager.class).toInstance(context.getTypeManager());
-                binder.bind(OpenTelemetry.class).toInstance(context.getOpenTelemetry());
-            }
-        };
-    }
-}
diff --git a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java b/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java
deleted file mode 100644
index 4dc6772..0000000
--- a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.CatalogContext;
-import org.apache.paimon.catalog.CatalogFactory;
-import org.apache.paimon.options.Options;
-import org.apache.paimon.security.SecurityContext;
-
-import com.google.inject.Inject;
-import io.trino.hdfs.ConfigurationUtils;
-import io.trino.hdfs.HdfsConfig;
-import io.trino.hdfs.HdfsConfigurationInitializer;
-import org.apache.hadoop.conf.Configuration;
-
-/** A factory to create {@link TrinoMetadata}. */
-public class TrinoMetadataFactory {
-
-    private final Catalog catalog;
-
-    @Inject
-    public TrinoMetadataFactory(
-            Options options,
-            HdfsConfigurationInitializer hdfsConfigurationInitializer,
-            HdfsConfig hdfsConfig) {
-        CatalogContext catalogContext;
-        if (hdfsConfig.getResourceConfigFiles().isEmpty()) {
-            catalogContext = CatalogContext.create(options);
-        } else {
-            Configuration configuration = ConfigurationUtils.getInitialConfiguration();
-            hdfsConfigurationInitializer.initializeConfiguration(configuration);
-            catalogContext = CatalogContext.create(options, configuration);
-        }
-        try {
-            SecurityContext.install(catalogContext);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        this.catalog = CatalogFactory.createCatalog(catalogContext);
-    }
-
-    public TrinoMetadata create() {
-        return new TrinoMetadata(catalog);
-    }
-}
diff --git a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoPageSource.java b/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
deleted file mode 100644
index 75eb2d5..0000000
--- a/paimon-trino-422/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.data.InternalArray;
-import org.apache.paimon.data.InternalMap;
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.reader.RecordReader;
-import org.apache.paimon.types.DataType;
-import org.apache.paimon.types.DataTypeChecks;
-import org.apache.paimon.utils.InternalRowUtils;
-
-import io.trino.spi.TrinoException;
-import io.trino.spi.block.ArrayBlockBuilder;
-import io.trino.spi.block.ArrayValueBuilder;
-import io.trino.spi.block.BlockBuilder;
-import io.trino.spi.block.MapBlockBuilder;
-import io.trino.spi.block.MapValueBuilder;
-import io.trino.spi.block.RowBlockBuilder;
-import io.trino.spi.block.RowValueBuilder;
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorPageSource;
-import io.trino.spi.metrics.Metrics;
-import io.trino.spi.type.ArrayType;
-import io.trino.spi.type.MapType;
-import io.trino.spi.type.RowType;
-import io.trino.spi.type.Type;
-
-import java.util.List;
-import java.util.OptionalLong;
-import java.util.concurrent.CompletableFuture;
-
-import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR;
-
-/** Trino {@link ConnectorPageSource}. */
-public class TrinoPageSource extends TrinoPageSourceBase {
-
-    public TrinoPageSource(
-            RecordReader<InternalRow> reader,
-            List<ColumnHandle> projectedColumns,
-            OptionalLong limit) {
-        super(reader, projectedColumns, limit);
-    }
-
-    protected void writeBlock(BlockBuilder output, Type type, DataType logicalType, Object value) {
-        if (type instanceof ArrayType) {
-            ArrayBlockBuilder arrayBlockBuilder = (ArrayBlockBuilder) output;
-            try {
-                arrayBlockBuilder.buildEntry(
-                        (ArrayValueBuilder<Throwable>)
-                                elementBuilder -> {
-                                    InternalArray arrayData = (InternalArray) value;
-                                    DataType elementType =
-                                            DataTypeChecks.getNestedTypes(logicalType).get(0);
-                                    for (int i = 0; i < arrayData.size(); i++) {
-                                        appendTo(
-                                                type.getTypeParameters().get(0),
-                                                elementType,
-                                                InternalRowUtils.get(arrayData, i, elementType),
-                                                elementBuilder);
-                                    }
-                                });
-            } catch (Throwable e) {
-                e.printStackTrace();
-            }
-            return;
-        }
-        if (type instanceof RowType) {
-            RowBlockBuilder rowBlockBuilder = (RowBlockBuilder) output;
-            try {
-                rowBlockBuilder.buildEntry(
-                        (RowValueBuilder<Throwable>)
-                                fieldBuilders -> {
-                                    InternalRow rowData = (InternalRow) value;
-                                    for (int index = 0;
-                                            index < type.getTypeParameters().size();
-                                            index++) {
-                                        Type fieldType = type.getTypeParameters().get(index);
-                                        DataType fieldLogicalType =
-                                                ((org.apache.paimon.types.RowType) logicalType)
-                                                        .getTypeAt(index);
-                                        appendTo(
-                                                fieldType,
-                                                fieldLogicalType,
-                                                InternalRowUtils.get(
-                                                        rowData, index, fieldLogicalType),
-                                                fieldBuilders.get(index));
-                                    }
-                                });
-            } catch (Throwable e) {
-                e.printStackTrace();
-            }
-            return;
-        }
-        if (type instanceof MapType) {
-            InternalMap mapData = (InternalMap) value;
-            InternalArray keyArray = mapData.keyArray();
-            InternalArray valueArray = mapData.valueArray();
-            DataType keyType = ((org.apache.paimon.types.MapType) logicalType).getKeyType();
-            DataType valueType = ((org.apache.paimon.types.MapType) logicalType).getValueType();
-            MapBlockBuilder mapBlockBuilder = (MapBlockBuilder) output;
-            try {
-                mapBlockBuilder.buildEntry(
-                        (MapValueBuilder<Throwable>)
-                                (keyBuilder, valueBuilder) -> {
-                                    for (int i = 0; i < keyArray.size(); i++) {
-                                        appendTo(
-                                                type.getTypeParameters().get(0),
-                                                keyType,
-                                                InternalRowUtils.get(keyArray, i, keyType),
-                                                keyBuilder);
-                                        appendTo(
-                                                type.getTypeParameters().get(1),
-                                                valueType,
-                                                InternalRowUtils.get(valueArray, i, valueType),
-                                                valueBuilder);
-                                    }
-                                });
-            } catch (Throwable e) {
-                e.printStackTrace();
-            }
-            return;
-        }
-        throw new TrinoException(
-                GENERIC_INTERNAL_ERROR, "Unhandled type for Block: " + type.getTypeSignature());
-    }
-
-    @Override
-    public OptionalLong getCompletedPositions() {
-        return super.getCompletedPositions();
-    }
-
-    @Override
-    public long getMemoryUsage() {
-        return 0;
-    }
-
-    @Override
-    public CompletableFuture<?> isBlocked() {
-        return super.isBlocked();
-    }
-
-    @Override
-    public Metrics getMetrics() {
-        return super.getMetrics();
-    }
-}
diff --git a/paimon-trino-422/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java b/paimon-trino-422/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java
new file mode 100644
index 0000000..94290ee
--- /dev/null
+++ b/paimon-trino-422/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java
@@ -0,0 +1,166 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.catalog.CatalogContext;
+import org.apache.paimon.fs.FileIO;
+import org.apache.paimon.fs.FileStatus;
+import org.apache.paimon.fs.Path;
+import org.apache.paimon.fs.PositionOutputStream;
+import org.apache.paimon.fs.SeekableInputStream;
+
+import io.trino.filesystem.FileEntry;
+import io.trino.filesystem.FileIterator;
+import io.trino.filesystem.Location;
+import io.trino.filesystem.TrinoFileSystem;
+import io.trino.filesystem.TrinoInputFile;
+
+import javax.annotation.Nullable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Trino file io for paimon. */
+public class TrinoFileIO implements FileIO {
+
+    private final TrinoFileSystem trinoFileSystem;
+    private final boolean objectStore;
+
+    public TrinoFileIO(TrinoFileSystem trinoFileSystem, @Nullable Path path) {
+        this.trinoFileSystem = trinoFileSystem;
+        this.objectStore = path == null || checkObjectStore(path.toUri().getScheme());
+    }
+
+    @Override
+    public boolean isObjectStore() {
+        return objectStore;
+    }
+
+    @Override
+    public void configure(CatalogContext catalogContext) {}
+
+    @Override
+    public SeekableInputStream newInputStream(Path path) throws IOException {
+        return new TrinoInputStreamWrapper(
+                trinoFileSystem.newInputFile(Location.of(path.toString())).newStream());
+    }
+
+    @Override
+    public PositionOutputStream newOutputStream(Path path, boolean b) throws IOException {
+        return new PositionOutputStreamWrapper(
+                trinoFileSystem.newOutputFile(Location.of(path.toString())).create());
+    }
+
+    @Override
+    public FileStatus getFileStatus(Path path) throws IOException {
+        return status(path);
+    }
+
+    private FileStatus status(Path path) throws IOException {
+        if (trinoFileSystem.directoryExists(Location.of(path.toString())).orElse(false)) {
+            return new TrinoDirectoryFileStatus(path);
+        } else {
+            TrinoInputFile trinoInputFile =
+                    trinoFileSystem.newInputFile(Location.of(path.toString()));
+            return new TrinoFileStatus(
+                    trinoInputFile.length(), path, trinoInputFile.lastModified().getEpochSecond());
+        }
+    }
+
+    @Override
+    public FileStatus[] listStatus(Path path) throws IOException {
+        List<FileStatus> fileStatusList = new ArrayList<>();
+        Location location = Location.of(path.toString());
+        // In version trino 422, trinoFileSystem could only search for files (directories don't
+        // count in files in trino)
+        // Therefore, this interface only return FileStatus those are file.
+        if (trinoFileSystem.directoryExists(location).orElse(false)) {
+            FileIterator fileIterator = trinoFileSystem.listFiles(location);
+            while (fileIterator.hasNext()) {
+                FileEntry fileEntry = fileIterator.next();
+                fileStatusList.add(
+                        new TrinoFileStatus(
+                                fileEntry.length(),
+                                new Path(fileEntry.location().toString()),
+                                fileEntry.lastModified().getEpochSecond()));
+            }
+        }
+        return fileStatusList.toArray(new FileStatus[0]);
+    }
+
+    @Override
+    public boolean exists(Path path) throws IOException {
+        return trinoFileSystem.directoryExists(Location.of(path.toString())).orElse(false)
+                || existFile(Location.of(path.toString()));
+    }
+
+    private boolean existFile(Location location) throws IOException {
+        try {
+            return trinoFileSystem.newInputFile(location).exists();
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean delete(Path path, boolean b) throws IOException {
+        Location location = Location.of(path.toString());
+        if (trinoFileSystem.directoryExists(location).orElse(false)) {
+            trinoFileSystem.deleteDirectory(location);
+            return true;
+        } else if (existFile(location)) {
+            trinoFileSystem.deleteFile(location);
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean mkdirs(Path path) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean rename(Path source, Path target) throws IOException {
+        Location sourceLocation = Location.of(source.toString());
+        Location targetLocation = Location.of(target.toString());
+        if (trinoFileSystem.directoryExists(sourceLocation).orElse(false)) {
+            throw new UnsupportedOperationException();
+        } else {
+            trinoFileSystem.renameFile(sourceLocation, targetLocation);
+        }
+        return true;
+    }
+
+    private static boolean checkObjectStore(String scheme) {
+        scheme = scheme.toLowerCase();
+        if (!scheme.startsWith("s3")
+                && !scheme.startsWith("emr")
+                && !scheme.startsWith("oss")
+                && !scheme.startsWith("wasb")) {
+            return scheme.startsWith("http") || scheme.startsWith("ftp");
+        } else {
+            return true;
+        }
+    }
+}
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 dbf3119..68009d7 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
@@ -24,4 +24,31 @@ public class TestTrino422ITCase extends TestTrinoITCase {
     public TestTrino422ITCase() {
         super(422);
     }
+
+    @Override
+    public void testCreateSchema() {}
+
+    @Override
+    public void testDropSchema() {}
+
+    @Override
+    public void testCreateTable() {}
+
+    @Override
+    public void testRenameTable() {}
+
+    @Override
+    public void testDropTable() {}
+
+    @Override
+    public void testAddColumn() {}
+
+    @Override
+    public void testRenameColumn() {}
+
+    @Override
+    public void testDropColumn() {}
+
+    @Override
+    public void testSetTableProperties() {}
 }
diff --git a/paimon-trino-393/pom.xml b/paimon-trino-427/pom.xml
similarity index 84%
rename from paimon-trino-393/pom.xml
rename to paimon-trino-427/pom.xml
index 3a8395a..d62e476 100644
--- a/paimon-trino-393/pom.xml
+++ b/paimon-trino-427/pom.xml
@@ -28,13 +28,15 @@ under the License.
         <version>0.8-SNAPSHOT</version>
     </parent>
 
-    <artifactId>paimon-trino-393</artifactId>
-    <name>Paimon : Trino : 393</name>
+    <artifactId>paimon-trino-427</artifactId>
+    <name>Paimon : Trino : 427</name>
 
     <properties>
         <target.java.version>17</target.java.version>
         <jdk.test.version>17</jdk.test.version>
-        <trino.version>393</trino.version>
+        <trino.version>427</trino.version>
+        <airlift.version>235</airlift.version>
+        <slice.version>2.2</slice.version>
         <maven.toolchains.plugin.version>3.1.0</maven.toolchains.plugin.version>
     </properties>
 
@@ -58,6 +60,38 @@ under the License.
             <version>${trino.version}</version>
             <scope>provided</scope>
         </dependency>
+
+        <dependency>
+            <groupId>io.trino</groupId>
+            <artifactId>trino-hdfs</artifactId>
+            <version>${trino.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.trino</groupId>
+            <artifactId>trino-hive</artifactId>
+            <version>${trino.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>bootstrap</artifactId>
+            <version>${airlift.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>configuration</artifactId>
+            <version>${airlift.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>slice</artifactId>
+            <version>${slice.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
         <!-- for testing -->
 
         <dependency>
@@ -175,4 +209,4 @@ under the License.
         </profile>
     </profiles>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/paimon-trino-358/src/main/assembly/paimon.xml b/paimon-trino-427/src/main/assembly/paimon.xml
similarity index 100%
rename from paimon-trino-358/src/main/assembly/paimon.xml
rename to paimon-trino-427/src/main/assembly/paimon.xml
diff --git a/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java b/paimon-trino-427/src/test/java/org/apache/paimon/trino/TestTrino427ITCase.java
similarity index 84%
rename from paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
rename to paimon-trino-427/src/test/java/org/apache/paimon/trino/TestTrino427ITCase.java
index d7fd631..28a979a 100644
--- a/paimon-trino-370/src/test/java/org/apache/paimon/trino/TestTrino370ITCase.java
+++ b/paimon-trino-427/src/test/java/org/apache/paimon/trino/TestTrino427ITCase.java
@@ -18,9 +18,10 @@
 
 package org.apache.paimon.trino;
 
-/** {@link TestTrinoITCase} for Trino 370. */
-public class TestTrino370ITCase extends TestTrinoITCase {
-    public TestTrino370ITCase() {
-        super(370);
+/** {@link TestTrinoITCase} for Trino 422. */
+public class TestTrino427ITCase extends TestTrinoITCase {
+
+    public TestTrino427ITCase() {
+        super(427);
     }
 }
diff --git a/paimon-trino-358/src/test/resources/log4j2-test.properties b/paimon-trino-427/src/test/resources/log4j2-test.properties
similarity index 100%
rename from paimon-trino-358/src/test/resources/log4j2-test.properties
rename to paimon-trino-427/src/test/resources/log4j2-test.properties
diff --git a/paimon-trino-common/pom.xml b/paimon-trino-common/pom.xml
index df89b20..ee5423f 100644
--- a/paimon-trino-common/pom.xml
+++ b/paimon-trino-common/pom.xml
@@ -34,9 +34,11 @@ under the License.
     <name>Paimon : Trino : Common</name>
 
     <properties>
-        <trino.version>388</trino.version>
-        <slice.version>0.42</slice.version>
-        <airlift.version>216</airlift.version>
+        <target.java.version>17</target.java.version>
+        <jdk.test.version>17</jdk.test.version>
+        <trino.version>427</trino.version>
+        <slice.version>2.2</slice.version>
+        <airlift.version>235</airlift.version>
         <hadoop.apache.version>3.2.0-18</hadoop.apache.version>
     </properties>
 
@@ -61,6 +63,12 @@ under the License.
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>io.trino</groupId>
+            <artifactId>trino-hdfs</artifactId>
+            <version>${trino.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>io.trino</groupId>
             <artifactId>trino-hive</artifactId>
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtils.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtils.java
index c4e3b73..467b03c 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtils.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtils.java
@@ -18,5 +18,14 @@
 
 package org.apache.paimon.trino;
 
+import io.trino.spi.type.Int128;
+
+import java.math.BigInteger;
+
 /** Utils for decimal. */
-public class DecimalUtils extends DecimalUtilsBase {}
+public class DecimalUtils {
+
+    public static BigInteger toBigInteger(Object value) {
+        return ((Int128) value).toBigInteger();
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtilsBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtilsBase.java
deleted file mode 100644
index a31e9ac..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/DecimalUtilsBase.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.type.Int128;
-
-import java.math.BigInteger;
-
-/** Utils for decimal. */
-public abstract class DecimalUtilsBase {
-
-    public static BigInteger toBigInteger(Object value) {
-        return ((Int128) value).toBigInteger();
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/DirectTrinoPageSource.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/DirectTrinoPageSource.java
new file mode 100644
index 0000000..1144557
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/DirectTrinoPageSource.java
@@ -0,0 +1,117 @@
+/*
+ * 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.trino;
+
+import io.trino.spi.Page;
+import io.trino.spi.connector.ConnectorPageSource;
+import io.trino.spi.metrics.Metrics;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.LinkedList;
+
+/** Trino {@link ConnectorPageSource}. */
+public class DirectTrinoPageSource implements ConnectorPageSource {
+
+    private ConnectorPageSource current;
+    private final LinkedList<ConnectorPageSource> pageSourceQueue;
+    private long completedBytes;
+
+    public DirectTrinoPageSource(LinkedList<ConnectorPageSource> pageSourceQueue) {
+        this.pageSourceQueue = pageSourceQueue;
+        this.current = pageSourceQueue.poll();
+    }
+
+    @Override
+    public long getCompletedBytes() {
+        return completedBytes;
+    }
+
+    @Override
+    public long getReadTimeNanos() {
+        return current == null ? 0 : current.getReadTimeNanos();
+    }
+
+    @Override
+    public boolean isFinished() {
+        return current == null || (current.isFinished() && pageSourceQueue.isEmpty());
+    }
+
+    @Override
+    public Page getNextPage() {
+        try {
+            if (current == null) {
+                return null;
+            }
+            Page dataPage = current.getNextPage();
+            if (dataPage == null) {
+                advance();
+                return getNextPage();
+            }
+
+            return dataPage;
+        } catch (RuntimeException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void advance() {
+        if (current == null) {
+            throw new RuntimeException("Current is null, should not invoke advance");
+        }
+        try {
+            completedBytes += current.getCompletedBytes();
+            current.close();
+        } catch (IOException e) {
+            current = null;
+            close();
+            throw new RuntimeException("error happens while advance and close old page source.");
+        }
+        current = pageSourceQueue.poll();
+    }
+
+    @Override
+    public void close() {
+        try {
+            if (current != null) {
+                current.close();
+            }
+            for (ConnectorPageSource source : pageSourceQueue) {
+                source.close();
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return current == null ? null : current.toString();
+    }
+
+    @Override
+    public long getMemoryUsage() {
+        return current == null ? 0 : current.getMemoryUsage();
+    }
+
+    @Override
+    public Metrics getMetrics() {
+        return current == null ? Metrics.EMPTY : current.getMetrics();
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/HiveHdfsModule.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/HiveHdfsModule.java
deleted file mode 100644
index 18de705..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/HiveHdfsModule.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.trino;
-
-import com.google.inject.Binder;
-import com.google.inject.Module;
-import com.google.inject.Scopes;
-import io.trino.plugin.hive.ConfigurationInitializer;
-import io.trino.plugin.hive.DynamicConfigurationProvider;
-import io.trino.plugin.hive.HdfsConfig;
-import io.trino.plugin.hive.HdfsConfiguration;
-import io.trino.plugin.hive.HdfsConfigurationInitializer;
-import io.trino.plugin.hive.HdfsEnvironment;
-import io.trino.plugin.hive.HiveHdfsConfiguration;
-
-import static com.google.inject.multibindings.Multibinder.newSetBinder;
-import static io.airlift.configuration.ConfigBinder.configBinder;
-
-/**
- * Copied from {@link io.trino.plugin.hive.HiveHdfsModule}. We removed the {@link
- * io.trino.plugin.hive.NamenodeStats}, as Trino relies on different versions of jol-core across
- * versions, leading to potential conflicts with the dependency on jol-core by NamenodeStats.
- */
-public class HiveHdfsModule implements Module {
-    @Override
-    public void configure(Binder binder) {
-        configBinder(binder).bindConfig(HdfsConfig.class);
-
-        binder.bind(HdfsConfiguration.class).to(HiveHdfsConfiguration.class).in(Scopes.SINGLETON);
-        binder.bind(HdfsEnvironment.class).in(Scopes.SINGLETON);
-
-        binder.bind(HdfsConfigurationInitializer.class).in(Scopes.SINGLETON);
-        newSetBinder(binder, ConfigurationInitializer.class);
-        newSetBinder(binder, DynamicConfigurationProvider.class);
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnector.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnector.java
index beaf55b..6bbb64a 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnector.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnector.java
@@ -19,34 +19,79 @@
 package org.apache.paimon.trino;
 
 import io.trino.spi.connector.Connector;
+import io.trino.spi.connector.ConnectorMetadata;
+import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTransactionHandle;
+import io.trino.spi.session.PropertyMetadata;
 import io.trino.spi.transaction.IsolationLevel;
 
+import java.util.List;
+
+import static io.trino.spi.transaction.IsolationLevel.READ_COMMITTED;
+import static io.trino.spi.transaction.IsolationLevel.checkConnectorSupports;
+import static java.util.Objects.requireNonNull;
+
 /** Trino {@link Connector}. */
-public class TrinoConnector extends TrinoConnectorBase {
+public class TrinoConnector implements Connector {
+    private final TrinoMetadata trinoMetadata;
+    private final TrinoSplitManager trinoSplitManager;
+    private final TrinoPageSourceProvider trinoPageSourceProvider;
+    private final List<PropertyMetadata<?>> tableProperties;
+    private final List<PropertyMetadata<?>> sessionProperties;
 
     public TrinoConnector(
-            TrinoMetadataBase trinoMetadata,
-            TrinoSplitManagerBase trinoSplitManager,
+            TrinoMetadata trinoMetadata,
+            TrinoSplitManager trinoSplitManager,
             TrinoPageSourceProvider trinoPageSourceProvider,
             TrinoTableOptions trinoTableOptions,
             TrinoSessionProperties trinoSessionProperties) {
-        super(
-                trinoMetadata,
-                trinoSplitManager,
-                trinoPageSourceProvider,
-                trinoTableOptions,
-                trinoSessionProperties);
+        this.trinoMetadata = requireNonNull(trinoMetadata, "jmxMetadata is null");
+        this.trinoSplitManager = requireNonNull(trinoSplitManager, "jmxSplitManager is null");
+        this.trinoPageSourceProvider =
+                requireNonNull(trinoPageSourceProvider, "jmxRecordSetProvider is null");
+        this.tableProperties = trinoTableOptions.getTableProperties();
+        this.sessionProperties = trinoSessionProperties.getSessionProperties();
     }
 
     @Override
     public ConnectorTransactionHandle beginTransaction(
-            IsolationLevel isolationLevel, boolean readOnly) {
+            IsolationLevel isolationLevel, boolean readOnly, boolean autoCommit) {
         return beginTransactionBase(isolationLevel, readOnly);
     }
 
     @Override
-    public TrinoMetadataBase getMetadata(ConnectorTransactionHandle transactionHandle) {
+    public ConnectorMetadata getMetadata(
+            ConnectorSession session, ConnectorTransactionHandle transactionHandle) {
         return getMetadataBase(transactionHandle);
     }
+
+    protected ConnectorTransactionHandle beginTransactionBase(
+            IsolationLevel isolationLevel, boolean readOnly) {
+        checkConnectorSupports(READ_COMMITTED, isolationLevel);
+        return TrinoTransactionHandle.INSTANCE;
+    }
+
+    protected TrinoMetadata getMetadataBase(ConnectorTransactionHandle transactionHandle) {
+        return trinoMetadata;
+    }
+
+    @Override
+    public TrinoSplitManager getSplitManager() {
+        return trinoSplitManager;
+    }
+
+    @Override
+    public TrinoPageSourceProvider getPageSourceProvider() {
+        return trinoPageSourceProvider;
+    }
+
+    @Override
+    public List<PropertyMetadata<?>> getSessionProperties() {
+        return sessionProperties;
+    }
+
+    @Override
+    public List<PropertyMetadata<?>> getTableProperties() {
+        return tableProperties;
+    }
 }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorBase.java
deleted file mode 100644
index 8f3e0b2..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorBase.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.Connector;
-import io.trino.spi.connector.ConnectorTransactionHandle;
-import io.trino.spi.session.PropertyMetadata;
-import io.trino.spi.transaction.IsolationLevel;
-
-import java.util.List;
-
-import static io.trino.spi.transaction.IsolationLevel.READ_COMMITTED;
-import static io.trino.spi.transaction.IsolationLevel.checkConnectorSupports;
-import static java.util.Objects.requireNonNull;
-
-/** Trino {@link Connector}. */
-public abstract class TrinoConnectorBase implements Connector {
-    private final TrinoMetadataBase trinoMetadata;
-    private final TrinoSplitManagerBase trinoSplitManager;
-    private final TrinoPageSourceProvider trinoPageSourceProvider;
-    private final List<PropertyMetadata<?>> tableProperties;
-    private final List<PropertyMetadata<?>> sessionProperties;
-
-    public TrinoConnectorBase(
-            TrinoMetadataBase trinoMetadata,
-            TrinoSplitManagerBase trinoSplitManager,
-            TrinoPageSourceProvider trinoPageSourceProvider,
-            TrinoTableOptions trinoTableOptions,
-            TrinoSessionProperties trinoSessionProperties) {
-        this.trinoMetadata = requireNonNull(trinoMetadata, "jmxMetadata is null");
-        this.trinoSplitManager = requireNonNull(trinoSplitManager, "jmxSplitManager is null");
-        this.trinoPageSourceProvider =
-                requireNonNull(trinoPageSourceProvider, "jmxRecordSetProvider is null");
-        this.tableProperties = trinoTableOptions.getTableProperties();
-        sessionProperties = trinoSessionProperties.getSessionProperties();
-    }
-
-    protected ConnectorTransactionHandle beginTransactionBase(
-            IsolationLevel isolationLevel, boolean readOnly) {
-        checkConnectorSupports(READ_COMMITTED, isolationLevel);
-        return TrinoTransactionHandle.INSTANCE;
-    }
-
-    protected TrinoMetadataBase getMetadataBase(ConnectorTransactionHandle transactionHandle) {
-        return trinoMetadata;
-    }
-
-    @Override
-    public TrinoSplitManagerBase getSplitManager() {
-        return trinoSplitManager;
-    }
-
-    @Override
-    public TrinoPageSourceProvider getPageSourceProvider() {
-        return trinoPageSourceProvider;
-    }
-
-    @Override
-    public List<PropertyMetadata<?>> getSessionProperties() {
-        return sessionProperties;
-    }
-
-    @Override
-    public List<PropertyMetadata<?>> getTableProperties() {
-        return tableProperties;
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
index c0af2e1..ea26016 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactory.java
@@ -18,7 +18,83 @@
 
 package org.apache.paimon.trino;
 
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import io.airlift.bootstrap.Bootstrap;
+import io.airlift.json.JsonModule;
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.trace.Tracer;
+import io.trino.filesystem.manager.FileSystemModule;
+import io.trino.hdfs.HdfsModule;
+import io.trino.hdfs.authentication.HdfsAuthenticationModule;
+import io.trino.plugin.hive.NodeVersion;
+import io.trino.plugin.hive.orc.OrcReaderConfig;
+import io.trino.spi.classloader.ThreadContextClassLoader;
+import io.trino.spi.connector.Connector;
+import io.trino.spi.connector.ConnectorContext;
 import io.trino.spi.connector.ConnectorFactory;
+import io.trino.spi.type.TypeManager;
+
+import java.util.Map;
 
 /** Trino {@link ConnectorFactory}. */
-public class TrinoConnectorFactory extends TrinoConnectorFactoryBase {}
+public class TrinoConnectorFactory implements ConnectorFactory {
+
+    @Override
+    public String getName() {
+        return "paimon";
+    }
+
+    @Override
+    public Connector create(
+            String catalogName, Map<String, String> config, ConnectorContext context) {
+
+        try (ThreadContextClassLoader ignored =
+                new ThreadContextClassLoader(TrinoConnectorFactory.class.getClassLoader())) {
+            Bootstrap app = new Bootstrap(modules(catalogName, config, context));
+
+            Injector injector =
+                    app.doNotInitializeLogging()
+                            .setRequiredConfigurationProperties(Map.of())
+                            .setOptionalConfigurationProperties(config)
+                            .initialize();
+
+            TrinoMetadata trinoMetadata = injector.getInstance(TrinoMetadataFactory.class).create();
+            TrinoSplitManager trinoSplitManager = injector.getInstance(TrinoSplitManager.class);
+            TrinoPageSourceProvider trinoPageSourceProvider =
+                    injector.getInstance(TrinoPageSourceProvider.class);
+            TrinoSessionProperties trinoSessionProperties =
+                    injector.getInstance(TrinoSessionProperties.class);
+            TrinoTableOptions trinoTableOptions = injector.getInstance(TrinoTableOptions.class);
+
+            return new TrinoConnector(
+                    trinoMetadata,
+                    trinoSplitManager,
+                    trinoPageSourceProvider,
+                    trinoTableOptions,
+                    trinoSessionProperties);
+        }
+    }
+
+    protected Module[] modules(
+            String catalogName, Map<String, String> config, ConnectorContext context) {
+        return new Module[] {
+            new JsonModule(),
+            new TrinoModule(config),
+            new HdfsModule(),
+            new HdfsAuthenticationModule(),
+            // bind the trino file system module
+            new FileSystemModule(),
+            binder -> {
+                binder.bind(NodeVersion.class)
+                        .toInstance(
+                                new NodeVersion(
+                                        context.getNodeManager().getCurrentNode().getVersion()));
+                binder.bind(TypeManager.class).toInstance(context.getTypeManager());
+                binder.bind(OpenTelemetry.class).toInstance(context.getOpenTelemetry());
+                binder.bind(Tracer.class).toInstance(context.getTracer());
+                binder.bind(OrcReaderConfig.class).toInstance(new OrcReaderConfig());
+            }
+        };
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactoryBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactoryBase.java
deleted file mode 100644
index 5338b8e..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoConnectorFactoryBase.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.trino;
-
-import com.google.inject.Injector;
-import com.google.inject.Module;
-import io.airlift.bootstrap.Bootstrap;
-import io.airlift.json.JsonModule;
-import io.trino.plugin.hive.HiveHdfsModule;
-import io.trino.plugin.hive.NodeVersion;
-import io.trino.plugin.hive.authentication.HdfsAuthenticationModule;
-import io.trino.spi.classloader.ThreadContextClassLoader;
-import io.trino.spi.connector.Connector;
-import io.trino.spi.connector.ConnectorContext;
-import io.trino.spi.connector.ConnectorFactory;
-import io.trino.spi.type.TypeManager;
-
-import java.util.Map;
-
-/** Trino {@link ConnectorFactory}. */
-public abstract class TrinoConnectorFactoryBase implements ConnectorFactory {
-
-    @Override
-    public String getName() {
-        return "paimon";
-    }
-
-    @Override
-    public Connector create(
-            String catalogName, Map<String, String> config, ConnectorContext context) {
-
-        try (ThreadContextClassLoader ignored =
-                new ThreadContextClassLoader(TrinoConnectorFactoryBase.class.getClassLoader())) {
-            Bootstrap app = new Bootstrap(modules(catalogName, config, context));
-
-            Injector injector =
-                    app.doNotInitializeLogging()
-                            .setRequiredConfigurationProperties(Map.of())
-                            .setOptionalConfigurationProperties(config)
-                            .initialize();
-
-            TrinoMetadata trinoMetadata = injector.getInstance(TrinoMetadataFactory.class).create();
-            TrinoSplitManager trinoSplitManager = injector.getInstance(TrinoSplitManager.class);
-            TrinoPageSourceProvider trinoPageSourceProvider =
-                    injector.getInstance(TrinoPageSourceProvider.class);
-            TrinoSessionProperties trinoSessionProperties =
-                    injector.getInstance(TrinoSessionProperties.class);
-            TrinoTableOptions trinoTableOptions = injector.getInstance(TrinoTableOptions.class);
-
-            return new TrinoConnector(
-                    trinoMetadata,
-                    trinoSplitManager,
-                    trinoPageSourceProvider,
-                    trinoTableOptions,
-                    trinoSessionProperties);
-        }
-    }
-
-    protected Module[] modules(
-            String catalogName, Map<String, String> config, ConnectorContext context) {
-        return new Module[] {
-            new JsonModule(),
-            new TrinoModule(config),
-            new HiveHdfsModule(),
-            new HdfsAuthenticationModule(),
-            binder -> {
-                binder.bind(NodeVersion.class)
-                        .toInstance(
-                                new NodeVersion(
-                                        context.getNodeManager().getCurrentNode().getVersion()));
-                binder.bind(TypeManager.class).toInstance(context.getTypeManager());
-            }
-        };
-    }
-}
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 8f96681..1e310f4 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
@@ -21,34 +21,107 @@ package org.apache.paimon.trino;
 import org.apache.paimon.CoreOptions;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.Identifier;
+import org.apache.paimon.schema.Schema;
 import org.apache.paimon.schema.SchemaChange;
+import org.apache.paimon.table.Table;
+import org.apache.paimon.trino.catalog.TrinoCatalog;
+import org.apache.paimon.utils.StringUtils;
 
 import io.trino.spi.TrinoException;
+import io.trino.spi.connector.Assignment;
+import io.trino.spi.connector.ColumnHandle;
+import io.trino.spi.connector.ColumnMetadata;
 import io.trino.spi.connector.ConnectorMetadata;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorTableHandle;
+import io.trino.spi.connector.ConnectorTableMetadata;
+import io.trino.spi.connector.ConnectorTableProperties;
 import io.trino.spi.connector.ConnectorTableVersion;
+import io.trino.spi.connector.Constraint;
+import io.trino.spi.connector.ConstraintApplicationResult;
+import io.trino.spi.connector.LimitApplicationResult;
+import io.trino.spi.connector.ProjectionApplicationResult;
 import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.connector.SchemaTablePrefix;
+import io.trino.spi.expression.ConnectorExpression;
+import io.trino.spi.predicate.Domain;
+import io.trino.spi.predicate.TupleDomain;
+import io.trino.spi.security.TrinoPrincipal;
 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.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.OptionalLong;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 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.Objects.requireNonNull;
+import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toMap;
+import static org.apache.paimon.utils.Preconditions.checkArgument;
 
 /** Trino {@link ConnectorMetadata}. */
-public class TrinoMetadata extends TrinoMetadataBase {
+public class TrinoMetadata implements ConnectorMetadata {
 
-    public TrinoMetadata(Catalog catalog) {
-        super(catalog);
+    protected final TrinoCatalog catalog;
+
+    public TrinoMetadata(TrinoCatalog catalog) {
+        this.catalog = catalog;
+    }
+
+    public TrinoCatalog catalog() {
+        return catalog;
+    }
+
+    @Override
+    public List<String> listSchemaNames(ConnectorSession session) {
+        catalog.initSession(session);
+        return catalog.listDatabases();
+    }
+
+    @Override
+    public void createSchema(
+            ConnectorSession session,
+            String schemaName,
+            Map<String, Object> properties,
+            TrinoPrincipal owner) {
+        checkArgument(
+                !StringUtils.isNullOrWhitespaceOnly(schemaName),
+                "schemaName cannot be null or empty");
+
+        try {
+            catalog.initSession(session);
+            catalog.createDatabase(schemaName, true);
+        } catch (Catalog.DatabaseAlreadyExistException e) {
+            throw new RuntimeException(format("database already existed: '%s'", schemaName));
+        }
+    }
+
+    @Override
+    public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) {
+        checkArgument(
+                !StringUtils.isNullOrWhitespaceOnly(schemaName),
+                "schemaName cannot be null or empty");
+        try {
+            catalog.initSession(session);
+            catalog.dropDatabase(schemaName, false, true);
+        } catch (Catalog.DatabaseNotEmptyException e) {
+            throw new RuntimeException(format("database is not empty: '%s'", schemaName));
+        } catch (Catalog.DatabaseNotExistException e) {
+            throw new RuntimeException(format("database not exists: '%s'", schemaName));
+        }
     }
 
     @Override
@@ -96,7 +169,37 @@ public class TrinoMetadata extends TrinoMetadataBase {
                     }
             }
         }
-        return getTableHandle(tableName, dynamicOptions);
+        return getTableHandle(session, tableName, dynamicOptions);
+    }
+
+    @Override
+    public TrinoTableHandle getTableHandle(ConnectorSession session, SchemaTableName tableName) {
+        return getTableHandle(session, tableName, Collections.emptyMap());
+    }
+
+    @Override
+    public ConnectorTableProperties getTableProperties(
+            ConnectorSession session, ConnectorTableHandle table) {
+        return new ConnectorTableProperties();
+    }
+
+    public TrinoTableHandle getTableHandle(
+            ConnectorSession session,
+            SchemaTableName tableName,
+            Map<String, String> dynamicOptions) {
+        catalog.initSession(session);
+        return catalog.tableExists(
+                        Identifier.create(tableName.getSchemaName(), tableName.getTableName()))
+                ? new TrinoTableHandle(
+                        tableName.getSchemaName(), tableName.getTableName(), dynamicOptions)
+                : null;
+    }
+
+    @Override
+    public ConnectorTableMetadata getTableMetadata(
+            ConnectorSession session, ConnectorTableHandle tableHandle) {
+        catalog.initSession(session);
+        return ((TrinoTableHandle) tableHandle).tableMetadata(catalog);
     }
 
     @Override
@@ -114,10 +217,303 @@ public class TrinoMetadata extends TrinoMetadataBase {
         options.forEach((key, value) -> changes.add(SchemaChange.setOption(key, value)));
         // TODO: remove options, SET PROPERTIES x = DEFAULT
         try {
+            catalog.initSession(session);
             catalog.alterTable(identifier, changes, false);
         } catch (Exception e) {
             throw new RuntimeException(
                     format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
         }
     }
+
+    @Override
+    public List<SchemaTableName> listTables(ConnectorSession session, Optional<String> schemaName) {
+        catalog.initSession(session);
+        List<SchemaTableName> tables = new ArrayList<>();
+        schemaName
+                .map(Collections::singletonList)
+                .orElseGet(catalog::listDatabases)
+                .forEach(schema -> tables.addAll(listTables(schema)));
+        return tables;
+    }
+
+    private List<SchemaTableName> listTables(String schema) {
+        try {
+            return catalog.listTables(schema).stream()
+                    .map(table -> new SchemaTableName(schema, table))
+                    .collect(toList());
+        } catch (Catalog.DatabaseNotExistException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void createTable(
+            ConnectorSession session,
+            ConnectorTableMetadata tableMetadata,
+            boolean ignoreExisting) {
+        SchemaTableName table = tableMetadata.getTable();
+        Identifier identifier = Identifier.create(table.getSchemaName(), table.getTableName());
+
+        try {
+            catalog.initSession(session);
+            catalog.createTable(identifier, prepareSchema(tableMetadata), false);
+        } catch (Catalog.DatabaseNotExistException e) {
+            throw new RuntimeException(format("database not exists: '%s'", table.getSchemaName()));
+        } catch (Catalog.TableAlreadyExistException e) {
+            throw new RuntimeException(format("table already existed: '%s'", table.getTableName()));
+        }
+    }
+
+    private Schema prepareSchema(ConnectorTableMetadata tableMetadata) {
+        Map<String, Object> properties = new HashMap<>(tableMetadata.getProperties());
+        Schema.Builder builder =
+                Schema.newBuilder()
+                        .primaryKey(TrinoTableOptions.getPrimaryKeys(properties))
+                        .partitionKeys(TrinoTableOptions.getPartitionedKeys(properties));
+
+        for (ColumnMetadata column : tableMetadata.getColumns()) {
+            builder.column(
+                    column.getName(),
+                    TrinoTypeUtils.toPaimonType(column.getType()),
+                    column.getComment());
+        }
+
+        TrinoTableOptionUtils.buildOptions(builder, properties);
+
+        return builder.build();
+    }
+
+    @Override
+    public void renameTable(
+            ConnectorSession session,
+            ConnectorTableHandle tableHandle,
+            SchemaTableName newTableName) {
+        TrinoTableHandle oldTableHandle = (TrinoTableHandle) tableHandle;
+        try {
+            catalog.initSession(session);
+            catalog.renameTable(
+                    new Identifier(oldTableHandle.getSchemaName(), oldTableHandle.getTableName()),
+                    new Identifier(newTableName.getSchemaName(), newTableName.getTableName()),
+                    false);
+        } catch (Catalog.TableNotExistException e) {
+            throw new RuntimeException(
+                    format("table not exists: '%s'", oldTableHandle.getTableName()));
+        } catch (Catalog.TableAlreadyExistException e) {
+            throw new RuntimeException(
+                    format("table already existed: '%s'", newTableName.getTableName()));
+        }
+    }
+
+    @Override
+    public void dropTable(ConnectorSession session, ConnectorTableHandle tableHandle) {
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
+        try {
+            catalog.initSession(session);
+            catalog.dropTable(
+                    new Identifier(
+                            trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName()),
+                    false);
+        } catch (Catalog.TableNotExistException e) {
+            throw new RuntimeException(
+                    format("table not exists: '%s'", trinoTableHandle.getTableName()));
+        }
+    }
+
+    @Override
+    public Map<String, ColumnHandle> getColumnHandles(
+            ConnectorSession session, ConnectorTableHandle tableHandle) {
+        TrinoTableHandle table = (TrinoTableHandle) tableHandle;
+        Map<String, ColumnHandle> handleMap = new HashMap<>();
+        for (ColumnMetadata column : table.columnMetadatas(catalog)) {
+            handleMap.put(column.getName(), table.columnHandle(catalog, column.getName()));
+        }
+        return handleMap;
+    }
+
+    @Override
+    public ColumnMetadata getColumnMetadata(
+            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle columnHandle) {
+        return ((TrinoColumnHandle) columnHandle).getColumnMetadata();
+    }
+
+    @Override
+    public Map<SchemaTableName, List<ColumnMetadata>> listTableColumns(
+            ConnectorSession session, SchemaTablePrefix prefix) {
+        requireNonNull(prefix, "prefix is null");
+        List<SchemaTableName> tableNames;
+        if (prefix.getTable().isPresent()) {
+            tableNames = Collections.singletonList(prefix.toSchemaTableName());
+        } else {
+            tableNames = listTables(session, prefix.getSchema());
+        }
+
+        return tableNames.stream()
+                .collect(
+                        toMap(
+                                Function.identity(),
+                                table -> getTableHandle(session, table).columnMetadatas(catalog)));
+    }
+
+    @Override
+    public void addColumn(
+            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnMetadata column) {
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
+        Identifier identifier =
+                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
+        List<SchemaChange> changes = new ArrayList<>();
+        changes.add(
+                SchemaChange.addColumn(
+                        column.getName(), TrinoTypeUtils.toPaimonType(column.getType())));
+        try {
+            catalog.initSession(session);
+            catalog.alterTable(identifier, changes, false);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
+        }
+    }
+
+    @Override
+    public void renameColumn(
+            ConnectorSession session,
+            ConnectorTableHandle tableHandle,
+            ColumnHandle source,
+            String target) {
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
+        Identifier identifier =
+                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
+        TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) source;
+        List<SchemaChange> changes = new ArrayList<>();
+        changes.add(SchemaChange.renameColumn(trinoColumnHandle.getColumnName(), target));
+        try {
+            catalog.initSession(session);
+            catalog.alterTable(identifier, changes, false);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
+        }
+    }
+
+    @Override
+    public void dropColumn(
+            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle column) {
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
+        Identifier identifier =
+                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
+        TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) column;
+        List<SchemaChange> changes = new ArrayList<>();
+        changes.add(SchemaChange.dropColumn(trinoColumnHandle.getColumnName()));
+        try {
+            catalog.initSession(session);
+            catalog.alterTable(identifier, changes, false);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
+        }
+    }
+
+    @Override
+    public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(
+            ConnectorSession session, ConnectorTableHandle handle, Constraint constraint) {
+        catalog.initSession(session);
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) handle;
+        TupleDomain<TrinoColumnHandle> oldFilter = trinoTableHandle.getFilter();
+        TupleDomain<TrinoColumnHandle> newFilter =
+                constraint
+                        .getSummary()
+                        .transformKeys(TrinoColumnHandle.class::cast)
+                        .intersect(oldFilter);
+        if (oldFilter.equals(newFilter)) {
+            return Optional.empty();
+        }
+
+        LinkedHashMap<TrinoColumnHandle, Domain> acceptedDomains = new LinkedHashMap<>();
+        LinkedHashMap<TrinoColumnHandle, Domain> unsupportedDomains = new LinkedHashMap<>();
+        new TrinoFilterConverter(trinoTableHandle.table(catalog).rowType())
+                .convert(newFilter, acceptedDomains, unsupportedDomains);
+
+        List<String> partitionKeys = trinoTableHandle.table(catalog).partitionKeys();
+        LinkedHashMap<TrinoColumnHandle, Domain> unenforcedDomains = new LinkedHashMap<>();
+        acceptedDomains.forEach(
+                (columnHandle, domain) -> {
+                    if (!partitionKeys.contains(columnHandle.getColumnName())) {
+                        unenforcedDomains.put(columnHandle, domain);
+                    }
+                });
+
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        TupleDomain<ColumnHandle> remain =
+                (TupleDomain)
+                        TupleDomain.withColumnDomains(unsupportedDomains)
+                                .intersect(TupleDomain.withColumnDomains(unenforcedDomains));
+
+        return Optional.of(
+                new ConstraintApplicationResult<>(trinoTableHandle.copy(newFilter), remain, false));
+    }
+
+    @Override
+    public Optional<ProjectionApplicationResult<ConnectorTableHandle>> applyProjection(
+            ConnectorSession session,
+            ConnectorTableHandle handle,
+            List<ConnectorExpression> projections,
+            Map<String, ColumnHandle> assignments) {
+        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) handle;
+        List<ColumnHandle> newColumns = new ArrayList<>(assignments.values());
+
+        if (trinoTableHandle.getProjectedColumns().isPresent()
+                && containSameElements(newColumns, trinoTableHandle.getProjectedColumns().get())) {
+            return Optional.empty();
+        }
+
+        List<Assignment> assignmentList = new ArrayList<>();
+        assignments.forEach(
+                (name, column) ->
+                        assignmentList.add(
+                                new Assignment(
+                                        name,
+                                        column,
+                                        ((TrinoColumnHandle) column).getTrinoType())));
+
+        return Optional.of(
+                new ProjectionApplicationResult<>(
+                        trinoTableHandle.copy(Optional.of(newColumns)),
+                        projections,
+                        assignmentList,
+                        false));
+    }
+
+    private static boolean containSameElements(
+            List<? extends ColumnHandle> first, List<? extends ColumnHandle> second) {
+        return new HashSet<>(first).equals(new HashSet<>(second));
+    }
+
+    @Override
+    public Optional<LimitApplicationResult<ConnectorTableHandle>> applyLimit(
+            ConnectorSession session, ConnectorTableHandle handle, long limit) {
+        TrinoTableHandle table = (TrinoTableHandle) handle;
+
+        if (table.getLimit().isPresent() && table.getLimit().getAsLong() <= limit) {
+            return Optional.empty();
+        }
+
+        if (!table.getFilter().isAll()) {
+            Table paimonTable = table.table(catalog);
+            LinkedHashMap<TrinoColumnHandle, Domain> acceptedDomains = new LinkedHashMap<>();
+            LinkedHashMap<TrinoColumnHandle, Domain> unsupportedDomains = new LinkedHashMap<>();
+            new TrinoFilterConverter(paimonTable.rowType())
+                    .convert(table.getFilter(), acceptedDomains, unsupportedDomains);
+            Set<String> acceptedFields =
+                    acceptedDomains.keySet().stream()
+                            .map(TrinoColumnHandle::getColumnName)
+                            .collect(Collectors.toSet());
+            if (unsupportedDomains.size() > 0
+                    || !paimonTable.partitionKeys().containsAll(acceptedFields)) {
+                return Optional.empty();
+            }
+        }
+
+        table = table.copy(OptionalLong.of(limit));
+
+        return Optional.of(new LimitApplicationResult<>(table, false, false));
+    }
 }
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
deleted file mode 100644
index 3899642..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataBase.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.Identifier;
-import org.apache.paimon.schema.Schema;
-import org.apache.paimon.schema.SchemaChange;
-import org.apache.paimon.table.Table;
-import org.apache.paimon.utils.InstantiationUtil;
-import org.apache.paimon.utils.StringUtils;
-
-import io.trino.spi.connector.Assignment;
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ColumnMetadata;
-import io.trino.spi.connector.ConnectorMetadata;
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorTableHandle;
-import io.trino.spi.connector.ConnectorTableMetadata;
-import io.trino.spi.connector.ConnectorTableProperties;
-import io.trino.spi.connector.Constraint;
-import io.trino.spi.connector.ConstraintApplicationResult;
-import io.trino.spi.connector.LimitApplicationResult;
-import io.trino.spi.connector.ProjectionApplicationResult;
-import io.trino.spi.connector.SchemaTableName;
-import io.trino.spi.connector.SchemaTablePrefix;
-import io.trino.spi.expression.ConnectorExpression;
-import io.trino.spi.predicate.Domain;
-import io.trino.spi.predicate.TupleDomain;
-import io.trino.spi.security.TrinoPrincipal;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.OptionalLong;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
-import static org.apache.paimon.utils.Preconditions.checkArgument;
-
-/** Trino {@link ConnectorMetadata}. */
-public abstract class TrinoMetadataBase implements ConnectorMetadata {
-
-    protected final Catalog catalog;
-
-    public TrinoMetadataBase(Catalog catalog) {
-        this.catalog = catalog;
-    }
-
-    @Override
-    public List<String> listSchemaNames(ConnectorSession session) {
-        return listSchemaNames();
-    }
-
-    private List<String> listSchemaNames() {
-        return catalog.listDatabases();
-    }
-
-    @Override
-    public void createSchema(
-            ConnectorSession session,
-            String schemaName,
-            Map<String, Object> properties,
-            TrinoPrincipal owner) {
-        checkArgument(
-                !StringUtils.isNullOrWhitespaceOnly(schemaName),
-                "schemaName cannot be null or empty");
-
-        try {
-            catalog.createDatabase(schemaName, true);
-        } catch (Catalog.DatabaseAlreadyExistException e) {
-            throw new RuntimeException(format("database already existed: '%s'", schemaName));
-        }
-    }
-
-    @Override
-    public void dropSchema(ConnectorSession session, String schemaName) {
-        checkArgument(
-                !StringUtils.isNullOrWhitespaceOnly(schemaName),
-                "schemaName cannot be null or empty");
-        try {
-            catalog.dropDatabase(schemaName, false, true);
-        } catch (Catalog.DatabaseNotEmptyException e) {
-            throw new RuntimeException(format("database is not empty: '%s'", schemaName));
-        } catch (Catalog.DatabaseNotExistException e) {
-            throw new RuntimeException(format("database not exists: '%s'", schemaName));
-        }
-    }
-
-    @Override
-    public TrinoTableHandle getTableHandle(ConnectorSession session, SchemaTableName tableName) {
-        return getTableHandle(tableName, null);
-    }
-
-    @Override
-    public ConnectorTableProperties getTableProperties(
-            ConnectorSession session, ConnectorTableHandle table) {
-        return new ConnectorTableProperties();
-    }
-
-    public TrinoTableHandle getTableHandle(
-            SchemaTableName tableName, Map<String, String> dynamicOptions) {
-        Identifier tablePath = new Identifier(tableName.getSchemaName(), tableName.getTableName());
-        byte[] serializedTable;
-        try {
-            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) {
-            throw new UncheckedIOException(e);
-        }
-
-        return new TrinoTableHandle(
-                tableName.getSchemaName(), tableName.getTableName(), serializedTable);
-    }
-
-    @Override
-    public ConnectorTableMetadata getTableMetadata(
-            ConnectorSession session, ConnectorTableHandle tableHandle) {
-        return ((TrinoTableHandle) tableHandle).tableMetadata();
-    }
-
-    @Override
-    public List<SchemaTableName> listTables(ConnectorSession session, Optional<String> schemaName) {
-        List<SchemaTableName> tables = new ArrayList<>();
-        schemaName
-                .map(Collections::singletonList)
-                .orElseGet(catalog::listDatabases)
-                .forEach(schema -> tables.addAll(listTables(schema)));
-        return tables;
-    }
-
-    private List<SchemaTableName> listTables(String schema) {
-        try {
-            return catalog.listTables(schema).stream()
-                    .map(table -> new SchemaTableName(schema, table))
-                    .collect(toList());
-        } catch (Catalog.DatabaseNotExistException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
-    public void createTable(
-            ConnectorSession session,
-            ConnectorTableMetadata tableMetadata,
-            boolean ignoreExisting) {
-        SchemaTableName table = tableMetadata.getTable();
-        Identifier identifier = Identifier.create(table.getSchemaName(), table.getTableName());
-
-        try {
-            catalog.createTable(identifier, prepareSchema(tableMetadata), false);
-        } catch (Catalog.DatabaseNotExistException e) {
-            throw new RuntimeException(format("database not exists: '%s'", table.getSchemaName()));
-        } catch (Catalog.TableAlreadyExistException e) {
-            throw new RuntimeException(format("table already existed: '%s'", table.getTableName()));
-        }
-    }
-
-    private Schema prepareSchema(ConnectorTableMetadata tableMetadata) {
-        Map<String, Object> properties = new HashMap<>(tableMetadata.getProperties());
-        Schema.Builder builder =
-                Schema.newBuilder()
-                        .primaryKey(TrinoTableOptions.getPrimaryKeys(properties))
-                        .partitionKeys(TrinoTableOptions.getPartitionedKeys(properties));
-
-        for (ColumnMetadata column : tableMetadata.getColumns()) {
-            builder.column(
-                    column.getName(),
-                    TrinoTypeUtils.toPaimonType(column.getType()),
-                    column.getComment());
-        }
-
-        TrinoTableOptionUtils.buildOptions(builder, properties);
-
-        return builder.build();
-    }
-
-    @Override
-    public void renameTable(
-            ConnectorSession session,
-            ConnectorTableHandle tableHandle,
-            SchemaTableName newTableName) {
-        TrinoTableHandle oldTableHandle = (TrinoTableHandle) tableHandle;
-        try {
-            catalog.renameTable(
-                    new Identifier(oldTableHandle.getSchemaName(), oldTableHandle.getTableName()),
-                    new Identifier(newTableName.getSchemaName(), newTableName.getTableName()),
-                    false);
-        } catch (Catalog.TableNotExistException e) {
-            throw new RuntimeException(
-                    format("table not exists: '%s'", oldTableHandle.getTableName()));
-        } catch (Catalog.TableAlreadyExistException e) {
-            throw new RuntimeException(
-                    format("table already existed: '%s'", newTableName.getTableName()));
-        }
-    }
-
-    @Override
-    public void dropTable(ConnectorSession session, ConnectorTableHandle tableHandle) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        try {
-            catalog.dropTable(
-                    new Identifier(
-                            trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName()),
-                    false);
-        } catch (Catalog.TableNotExistException e) {
-            throw new RuntimeException(
-                    format("table not exists: '%s'", trinoTableHandle.getTableName()));
-        }
-    }
-
-    @Override
-    public Map<String, ColumnHandle> getColumnHandles(
-            ConnectorSession session, ConnectorTableHandle tableHandle) {
-        TrinoTableHandle table = (TrinoTableHandle) tableHandle;
-        Map<String, ColumnHandle> handleMap = new HashMap<>();
-        for (ColumnMetadata column : table.columnMetadatas()) {
-            handleMap.put(column.getName(), table.columnHandle(column.getName()));
-        }
-        return handleMap;
-    }
-
-    @Override
-    public ColumnMetadata getColumnMetadata(
-            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle columnHandle) {
-        return ((TrinoColumnHandle) columnHandle).getColumnMetadata();
-    }
-
-    @Override
-    public Map<SchemaTableName, List<ColumnMetadata>> listTableColumns(
-            ConnectorSession session, SchemaTablePrefix prefix) {
-        requireNonNull(prefix, "prefix is null");
-        List<SchemaTableName> tableNames;
-        if (prefix.getTable().isPresent()) {
-            tableNames = Collections.singletonList(prefix.toSchemaTableName());
-        } else {
-            tableNames = listTables(session, prefix.getSchema());
-        }
-
-        return tableNames.stream()
-                .collect(
-                        toMap(
-                                Function.identity(),
-                                table -> getTableHandle(session, table).columnMetadatas()));
-    }
-
-    @Override
-    public void addColumn(
-            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnMetadata column) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        List<SchemaChange> changes = new ArrayList<>();
-        changes.add(
-                SchemaChange.addColumn(
-                        column.getName(), TrinoTypeUtils.toPaimonType(column.getType())));
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-
-    @Override
-    public void renameColumn(
-            ConnectorSession session,
-            ConnectorTableHandle tableHandle,
-            ColumnHandle source,
-            String target) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) source;
-        List<SchemaChange> changes = new ArrayList<>();
-        changes.add(SchemaChange.renameColumn(trinoColumnHandle.getColumnName(), target));
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-
-    @Override
-    public void dropColumn(
-            ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle column) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Identifier identifier =
-                new Identifier(trinoTableHandle.getSchemaName(), trinoTableHandle.getTableName());
-        TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) column;
-        List<SchemaChange> changes = new ArrayList<>();
-        changes.add(SchemaChange.dropColumn(trinoColumnHandle.getColumnName()));
-        try {
-            catalog.alterTable(identifier, changes, false);
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    format("failed to alter table: '%s'", trinoTableHandle.getTableName()), e);
-        }
-    }
-
-    @Override
-    public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(
-            ConnectorSession session, ConnectorTableHandle handle, Constraint constraint) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) handle;
-        TupleDomain<TrinoColumnHandle> oldFilter = trinoTableHandle.getFilter();
-        TupleDomain<TrinoColumnHandle> newFilter =
-                constraint
-                        .getSummary()
-                        .transformKeys(TrinoColumnHandle.class::cast)
-                        .intersect(oldFilter);
-        if (oldFilter.equals(newFilter)) {
-            return Optional.empty();
-        }
-
-        LinkedHashMap<TrinoColumnHandle, Domain> acceptedDomains = new LinkedHashMap<>();
-        LinkedHashMap<TrinoColumnHandle, Domain> unsupportedDomains = new LinkedHashMap<>();
-        new TrinoFilterConverter(trinoTableHandle.table().rowType())
-                .convert(newFilter, acceptedDomains, unsupportedDomains);
-
-        List<String> partitionKeys = trinoTableHandle.table().partitionKeys();
-        LinkedHashMap<TrinoColumnHandle, Domain> unenforcedDomains = new LinkedHashMap<>();
-        acceptedDomains.forEach(
-                (columnHandle, domain) -> {
-                    if (!partitionKeys.contains(columnHandle.getColumnName())) {
-                        unenforcedDomains.put(columnHandle, domain);
-                    }
-                });
-
-        @SuppressWarnings({"unchecked", "rawtypes"})
-        TupleDomain<ColumnHandle> remain =
-                (TupleDomain)
-                        TupleDomain.withColumnDomains(unsupportedDomains)
-                                .intersect(TupleDomain.withColumnDomains(unenforcedDomains));
-
-        return Optional.of(
-                new ConstraintApplicationResult<>(trinoTableHandle.copy(newFilter), remain, false));
-    }
-
-    @Override
-    public Optional<ProjectionApplicationResult<ConnectorTableHandle>> applyProjection(
-            ConnectorSession session,
-            ConnectorTableHandle handle,
-            List<ConnectorExpression> projections,
-            Map<String, ColumnHandle> assignments) {
-        TrinoTableHandle trinoTableHandle = (TrinoTableHandle) handle;
-        List<ColumnHandle> newColumns = new ArrayList<>(assignments.values());
-
-        if (trinoTableHandle.getProjectedColumns().isPresent()
-                && containSameElements(newColumns, trinoTableHandle.getProjectedColumns().get())) {
-            return Optional.empty();
-        }
-
-        List<Assignment> assignmentList = new ArrayList<>();
-        assignments.forEach(
-                (name, column) ->
-                        assignmentList.add(
-                                new Assignment(
-                                        name,
-                                        column,
-                                        ((TrinoColumnHandle) column).getTrinoType())));
-
-        return Optional.of(
-                new ProjectionApplicationResult<>(
-                        trinoTableHandle.copy(Optional.of(newColumns)),
-                        projections,
-                        assignmentList,
-                        false));
-    }
-
-    private static boolean containSameElements(
-            List<? extends ColumnHandle> first, List<? extends ColumnHandle> second) {
-        return new HashSet<>(first).equals(new HashSet<>(second));
-    }
-
-    @Override
-    public Optional<LimitApplicationResult<ConnectorTableHandle>> applyLimit(
-            ConnectorSession session, ConnectorTableHandle handle, long limit) {
-        TrinoTableHandle table = (TrinoTableHandle) handle;
-
-        if (table.getLimit().isPresent() && table.getLimit().getAsLong() <= limit) {
-            return Optional.empty();
-        }
-
-        if (!table.getFilter().isAll()) {
-            LinkedHashMap<TrinoColumnHandle, Domain> acceptedDomains = new LinkedHashMap<>();
-            LinkedHashMap<TrinoColumnHandle, Domain> unsupportedDomains = new LinkedHashMap<>();
-            new TrinoFilterConverter(table.table().rowType())
-                    .convert(table.getFilter(), acceptedDomains, unsupportedDomains);
-            Set<String> acceptedFields =
-                    acceptedDomains.keySet().stream()
-                            .map(TrinoColumnHandle::getColumnName)
-                            .collect(Collectors.toSet());
-            if (unsupportedDomains.size() > 0
-                    || !table.table().partitionKeys().containsAll(acceptedFields)) {
-                return Optional.empty();
-            }
-        }
-
-        table = table.copy(OptionalLong.of(limit));
-
-        return Optional.of(new LimitApplicationResult<>(table, false, false));
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java
index 4b03327..9f99954 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoMetadataFactory.java
@@ -18,42 +18,34 @@
 
 package org.apache.paimon.trino;
 
-import org.apache.paimon.catalog.Catalog;
-import org.apache.paimon.catalog.CatalogContext;
-import org.apache.paimon.catalog.CatalogFactory;
 import org.apache.paimon.options.Options;
-import org.apache.paimon.security.SecurityContext;
+import org.apache.paimon.trino.catalog.TrinoCatalog;
 
 import com.google.inject.Inject;
-import io.trino.plugin.hive.HdfsConfig;
-import io.trino.plugin.hive.HdfsConfigurationInitializer;
-import io.trino.plugin.hive.util.ConfigurationUtils;
+import io.trino.filesystem.TrinoFileSystemFactory;
+import io.trino.hdfs.ConfigurationUtils;
+import io.trino.hdfs.HdfsConfig;
+import io.trino.hdfs.HdfsConfigurationInitializer;
 import org.apache.hadoop.conf.Configuration;
 
 /** A factory to create {@link TrinoMetadata}. */
 public class TrinoMetadataFactory {
 
-    private final Catalog catalog;
+    private final TrinoCatalog catalog;
 
     @Inject
     public TrinoMetadataFactory(
             Options options,
             HdfsConfigurationInitializer hdfsConfigurationInitializer,
-            HdfsConfig hdfsConfig) {
-        CatalogContext catalogContext;
-        if (hdfsConfig.getResourceConfigFiles().isEmpty()) {
-            catalogContext = CatalogContext.create(options);
-        } else {
-            Configuration configuration = ConfigurationUtils.getInitialConfiguration();
+            HdfsConfig hdfsConfig,
+            TrinoFileSystemFactory fileSystemFactory) {
+        Configuration configuration = null;
+        if (!hdfsConfig.getResourceConfigFiles().isEmpty()) {
+            configuration = ConfigurationUtils.getInitialConfiguration();
             hdfsConfigurationInitializer.initializeConfiguration(configuration);
-            catalogContext = CatalogContext.create(options, configuration);
         }
-        try {
-            SecurityContext.install(catalogContext);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        this.catalog = CatalogFactory.createCatalog(catalogContext);
+
+        this.catalog = new TrinoCatalog(options, configuration, fileSystemFactory);
     }
 
     public TrinoMetadata create() {
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoOrcDataSource.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoOrcDataSource.java
new file mode 100644
index 0000000..250366c
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoOrcDataSource.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.trino;
+
+import io.airlift.slice.Slice;
+import io.trino.filesystem.TrinoInput;
+import io.trino.filesystem.TrinoInputFile;
+import io.trino.orc.AbstractOrcDataSource;
+import io.trino.orc.OrcDataSourceId;
+import io.trino.orc.OrcReader;
+import io.trino.orc.OrcReaderOptions;
+
+import java.io.IOException;
+
+/** Data source to construct {@link OrcReader}. */
+public class TrinoOrcDataSource extends AbstractOrcDataSource {
+
+    private final TrinoInput input;
+
+    public TrinoOrcDataSource(TrinoInputFile file, OrcReaderOptions options) throws IOException {
+        super(new OrcDataSourceId(file.location().toString()), file.length(), options);
+        this.input = file.newInput();
+    }
+
+    @Override
+    public void close() throws IOException {
+        input.close();
+    }
+
+    @Override
+    protected Slice readTailInternal(int length) throws IOException {
+        return input.readTail(length);
+    }
+
+    @Override
+    protected void readInternal(long position, byte[] buffer, int bufferOffset, int bufferLength)
+            throws IOException {
+        input.readFully(position, buffer, bufferOffset, bufferLength);
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSource.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
index 687f409..736728e 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSource.java
@@ -18,27 +18,348 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.data.BinaryString;
+import org.apache.paimon.data.Decimal;
+import org.apache.paimon.data.InternalArray;
+import org.apache.paimon.data.InternalMap;
 import org.apache.paimon.data.InternalRow;
+import org.apache.paimon.data.Timestamp;
 import org.apache.paimon.reader.RecordReader;
+import org.apache.paimon.types.DataType;
+import org.apache.paimon.types.DataTypeChecks;
+import org.apache.paimon.utils.CloseableIterator;
+import org.apache.paimon.utils.InternalRowUtils;
 
+import io.airlift.slice.Slice;
+import io.trino.spi.Page;
+import io.trino.spi.PageBuilder;
+import io.trino.spi.TrinoException;
+import io.trino.spi.block.ArrayBlockBuilder;
+import io.trino.spi.block.ArrayValueBuilder;
+import io.trino.spi.block.BlockBuilder;
+import io.trino.spi.block.MapBlockBuilder;
+import io.trino.spi.block.MapValueBuilder;
+import io.trino.spi.block.RowBlockBuilder;
+import io.trino.spi.block.RowValueBuilder;
 import io.trino.spi.connector.ColumnHandle;
 import io.trino.spi.connector.ConnectorPageSource;
+import io.trino.spi.type.ArrayType;
+import io.trino.spi.type.DecimalType;
+import io.trino.spi.type.Decimals;
+import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.MapType;
+import io.trino.spi.type.RowType;
+import io.trino.spi.type.Type;
+import io.trino.spi.type.VarbinaryType;
+import io.trino.spi.type.VarcharType;
 
+import javax.annotation.Nullable;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.OptionalLong;
 
+import static io.airlift.slice.Slices.wrappedBuffer;
+import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR;
+import static io.trino.spi.type.BigintType.BIGINT;
+import static io.trino.spi.type.DateTimeEncoding.packDateTimeWithZone;
+import static io.trino.spi.type.DateType.DATE;
+import static io.trino.spi.type.Decimals.encodeShortScaledValue;
+import static io.trino.spi.type.IntegerType.INTEGER;
+import static io.trino.spi.type.LongTimestampWithTimeZone.fromEpochMillisAndFraction;
+import static io.trino.spi.type.RealType.REAL;
+import static io.trino.spi.type.SmallintType.SMALLINT;
+import static io.trino.spi.type.TimeType.TIME_MICROS;
+import static io.trino.spi.type.TimeZoneKey.UTC_KEY;
+import static io.trino.spi.type.TimestampType.TIMESTAMP_MICROS;
+import static io.trino.spi.type.TimestampType.TIMESTAMP_MILLIS;
+import static io.trino.spi.type.TimestampType.TIMESTAMP_SECONDS;
+import static io.trino.spi.type.TimestampWithTimeZoneType.TIMESTAMP_TZ_MILLIS;
+import static io.trino.spi.type.Timestamps.MICROSECONDS_PER_MILLISECOND;
+import static io.trino.spi.type.TinyintType.TINYINT;
+import static java.lang.String.format;
+import static org.apache.paimon.utils.Preconditions.checkArgument;
+
 /** Trino {@link ConnectorPageSource}. */
-public class TrinoPageSource extends TrinoPageSourceBase {
+public class TrinoPageSource implements ConnectorPageSource {
+
+    private static final int ROWS_PER_REQUEST = 4096;
+
+    private final CloseableIterator<InternalRow> iterator;
+    private final OptionalLong limit;
+    private final PageBuilder pageBuilder;
+    private final List<Type> columnTypes;
+    private final List<DataType> logicalTypes;
+
+    private boolean isFinished = false;
+    private long numReturn = 0;
 
     public TrinoPageSource(
             RecordReader<InternalRow> reader,
             List<ColumnHandle> projectedColumns,
             OptionalLong limit) {
-        super(reader, projectedColumns, limit);
+        this.iterator = reader.toCloseableIterator();
+        this.limit = limit;
+        this.columnTypes = new ArrayList<>();
+        this.logicalTypes = new ArrayList<>();
+        for (ColumnHandle handle : projectedColumns) {
+            TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) handle;
+            columnTypes.add(trinoColumnHandle.getTrinoType());
+            logicalTypes.add(trinoColumnHandle.logicalType());
+        }
+
+        this.pageBuilder = new PageBuilder(columnTypes);
+    }
+
+    @Override
+    public long getCompletedBytes() {
+        return 0;
+    }
+
+    @Override
+    public long getReadTimeNanos() {
+        return 0;
+    }
+
+    @Override
+    public boolean isFinished() {
+        return isFinished;
+    }
+
+    @Override
+    public Page getNextPage() {
+        return ClassLoaderUtils.runWithContextClassLoader(
+                () -> {
+                    try {
+                        return nextPage();
+                    } catch (IOException e) {
+                        throw new UncheckedIOException(e);
+                    }
+                },
+                TrinoPageSource.class.getClassLoader());
     }
 
     @Override
     public long getMemoryUsage() {
         return 0;
     }
+
+    @Nullable
+    private Page nextPage() throws IOException {
+        int count = 0;
+        while (count < ROWS_PER_REQUEST && !pageBuilder.isFull()) {
+            if (limit.isPresent() && numReturn + count >= limit.getAsLong()) {
+                isFinished = true;
+                return returnPage(count);
+            }
+
+            if (!iterator.hasNext()) {
+                isFinished = true;
+                return returnPage(count);
+            }
+
+            InternalRow row = iterator.next();
+            pageBuilder.declarePosition();
+            count++;
+            for (int i = 0; i < columnTypes.size(); i++) {
+                BlockBuilder output = pageBuilder.getBlockBuilder(i);
+                appendTo(
+                        columnTypes.get(i),
+                        logicalTypes.get(i),
+                        InternalRowUtils.get(row, i, logicalTypes.get(i)),
+                        output);
+            }
+        }
+
+        return returnPage(count);
+    }
+
+    private Page returnPage(int count) {
+        if (count == 0) {
+            return null;
+        }
+        numReturn += count;
+        Page page = pageBuilder.build();
+        pageBuilder.reset();
+        return page;
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            this.iterator.close();
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    protected void appendTo(Type type, DataType logicalType, Object value, BlockBuilder output) {
+        if (value == null) {
+            output.appendNull();
+            return;
+        }
+
+        Class<?> javaType = type.getJavaType();
+        if (javaType == boolean.class) {
+            type.writeBoolean(output, (Boolean) value);
+        } else if (javaType == long.class) {
+            if (type.equals(BIGINT)
+                    || type.equals(INTEGER)
+                    || type.equals(TINYINT)
+                    || type.equals(SMALLINT)
+                    || type.equals(DATE)) {
+                type.writeLong(output, ((Number) value).longValue());
+            } else if (type.equals(REAL)) {
+                type.writeLong(output, Float.floatToIntBits((Float) value));
+            } else if (type instanceof DecimalType) {
+                DecimalType decimalType = (DecimalType) type;
+                BigDecimal decimal = ((Decimal) value).toBigDecimal();
+                type.writeLong(output, encodeShortScaledValue(decimal, decimalType.getScale()));
+            } else if (type.equals(TIMESTAMP_MILLIS) || type.equals(TIMESTAMP_SECONDS)) {
+                type.writeLong(
+                        output,
+                        ((Timestamp) value).getMillisecond() * MICROSECONDS_PER_MILLISECOND);
+            } else if (type.equals(TIMESTAMP_MICROS)) {
+                type.writeLong(output, ((Timestamp) value).toMicros());
+            } else if (type.equals(TIMESTAMP_TZ_MILLIS)) {
+                type.writeLong(
+                        output,
+                        packDateTimeWithZone(((Timestamp) value).getMillisecond(), UTC_KEY));
+            } else if (type.equals(TIME_MICROS)) {
+                type.writeLong(output, (int) value * MICROSECONDS_PER_MILLISECOND);
+            } else {
+                throw new TrinoException(
+                        GENERIC_INTERNAL_ERROR,
+                        format("Unhandled type for %s: %s", javaType.getSimpleName(), type));
+            }
+        } else if (javaType == double.class) {
+            type.writeDouble(output, ((Number) value).doubleValue());
+        } else if (type instanceof DecimalType) {
+            writeObject(output, type, value);
+        } else if (javaType == Slice.class) {
+            writeSlice(output, type, value);
+        } else if (javaType == LongTimestampWithTimeZone.class) {
+            checkArgument(type.equals(TIMESTAMP_TZ_MILLIS));
+            Timestamp timestamp = (org.apache.paimon.data.Timestamp) value;
+            type.writeObject(
+                    output, fromEpochMillisAndFraction(timestamp.getMillisecond(), 0, UTC_KEY));
+        } else if (type instanceof ArrayType
+                || type instanceof MapType
+                || type instanceof RowType) {
+            writeBlock(output, type, logicalType, value);
+        } else {
+            throw new TrinoException(
+                    GENERIC_INTERNAL_ERROR,
+                    format("Unhandled type for %s: %s", javaType.getSimpleName(), type));
+        }
+    }
+
+    private static void writeSlice(BlockBuilder output, Type type, Object value) {
+        if (type instanceof VarcharType || type instanceof io.trino.spi.type.CharType) {
+            type.writeSlice(output, wrappedBuffer(((BinaryString) value).toBytes()));
+        } else if (type instanceof VarbinaryType) {
+            type.writeSlice(output, wrappedBuffer((byte[]) value));
+        } else {
+            throw new TrinoException(
+                    GENERIC_INTERNAL_ERROR, "Unhandled type for Slice: " + type.getTypeSignature());
+        }
+    }
+
+    private static void writeObject(BlockBuilder output, Type type, Object value) {
+        if (type instanceof DecimalType) {
+            DecimalType decimalType = (DecimalType) type;
+            BigDecimal decimal = ((Decimal) value).toBigDecimal();
+            type.writeObject(output, Decimals.encodeScaledValue(decimal, decimalType.getScale()));
+        } else {
+            throw new TrinoException(
+                    GENERIC_INTERNAL_ERROR,
+                    "Unhandled type for Object: " + type.getTypeSignature());
+        }
+    }
+
+    protected void writeBlock(BlockBuilder output, Type type, DataType logicalType, Object value) {
+        if (type instanceof ArrayType) {
+            ArrayBlockBuilder arrayBlockBuilder = (ArrayBlockBuilder) output;
+            try {
+                arrayBlockBuilder.buildEntry(
+                        (ArrayValueBuilder<Throwable>)
+                                elementBuilder -> {
+                                    InternalArray arrayData = (InternalArray) value;
+                                    DataType elementType =
+                                            DataTypeChecks.getNestedTypes(logicalType).get(0);
+                                    for (int i = 0; i < arrayData.size(); i++) {
+                                        appendTo(
+                                                type.getTypeParameters().get(0),
+                                                elementType,
+                                                InternalRowUtils.get(arrayData, i, elementType),
+                                                elementBuilder);
+                                    }
+                                });
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+            return;
+        }
+        if (type instanceof RowType) {
+            RowBlockBuilder rowBlockBuilder = (RowBlockBuilder) output;
+            try {
+                rowBlockBuilder.buildEntry(
+                        (RowValueBuilder<Throwable>)
+                                fieldBuilders -> {
+                                    InternalRow rowData = (InternalRow) value;
+                                    for (int index = 0;
+                                            index < type.getTypeParameters().size();
+                                            index++) {
+                                        Type fieldType = type.getTypeParameters().get(index);
+                                        DataType fieldLogicalType =
+                                                ((org.apache.paimon.types.RowType) logicalType)
+                                                        .getTypeAt(index);
+                                        appendTo(
+                                                fieldType,
+                                                fieldLogicalType,
+                                                InternalRowUtils.get(
+                                                        rowData, index, fieldLogicalType),
+                                                fieldBuilders.get(index));
+                                    }
+                                });
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+            return;
+        }
+        if (type instanceof MapType) {
+            InternalMap mapData = (InternalMap) value;
+            InternalArray keyArray = mapData.keyArray();
+            InternalArray valueArray = mapData.valueArray();
+            DataType keyType = ((org.apache.paimon.types.MapType) logicalType).getKeyType();
+            DataType valueType = ((org.apache.paimon.types.MapType) logicalType).getValueType();
+            MapBlockBuilder mapBlockBuilder = (MapBlockBuilder) output;
+            try {
+                mapBlockBuilder.buildEntry(
+                        (MapValueBuilder<Throwable>)
+                                (keyBuilder, valueBuilder) -> {
+                                    for (int i = 0; i < keyArray.size(); i++) {
+                                        appendTo(
+                                                type.getTypeParameters().get(0),
+                                                keyType,
+                                                InternalRowUtils.get(keyArray, i, keyType),
+                                                keyBuilder);
+                                        appendTo(
+                                                type.getTypeParameters().get(1),
+                                                valueType,
+                                                InternalRowUtils.get(valueArray, i, valueType),
+                                                valueBuilder);
+                                    }
+                                });
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+            return;
+        }
+        throw new TrinoException(
+                GENERIC_INTERNAL_ERROR, "Unhandled type for Block: " + type.getTypeSignature());
+    }
 }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceBase.java
deleted file mode 100644
index 31e0da7..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceBase.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.data.BinaryString;
-import org.apache.paimon.data.Decimal;
-import org.apache.paimon.data.InternalArray;
-import org.apache.paimon.data.InternalMap;
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.data.Timestamp;
-import org.apache.paimon.reader.RecordReader;
-import org.apache.paimon.types.DataType;
-import org.apache.paimon.types.DataTypeChecks;
-import org.apache.paimon.utils.CloseableIterator;
-import org.apache.paimon.utils.InternalRowUtils;
-
-import io.airlift.slice.Slice;
-import io.trino.spi.Page;
-import io.trino.spi.PageBuilder;
-import io.trino.spi.TrinoException;
-import io.trino.spi.block.BlockBuilder;
-import io.trino.spi.connector.ColumnHandle;
-import io.trino.spi.connector.ConnectorPageSource;
-import io.trino.spi.type.ArrayType;
-import io.trino.spi.type.DecimalType;
-import io.trino.spi.type.Decimals;
-import io.trino.spi.type.LongTimestampWithTimeZone;
-import io.trino.spi.type.MapType;
-import io.trino.spi.type.RowType;
-import io.trino.spi.type.Type;
-import io.trino.spi.type.VarbinaryType;
-import io.trino.spi.type.VarcharType;
-
-import javax.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.OptionalLong;
-
-import static io.airlift.slice.Slices.wrappedBuffer;
-import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR;
-import static io.trino.spi.type.BigintType.BIGINT;
-import static io.trino.spi.type.DateTimeEncoding.packDateTimeWithZone;
-import static io.trino.spi.type.DateType.DATE;
-import static io.trino.spi.type.Decimals.encodeShortScaledValue;
-import static io.trino.spi.type.IntegerType.INTEGER;
-import static io.trino.spi.type.LongTimestampWithTimeZone.fromEpochMillisAndFraction;
-import static io.trino.spi.type.RealType.REAL;
-import static io.trino.spi.type.SmallintType.SMALLINT;
-import static io.trino.spi.type.TimeType.TIME_MICROS;
-import static io.trino.spi.type.TimeZoneKey.UTC_KEY;
-import static io.trino.spi.type.TimestampType.TIMESTAMP_MICROS;
-import static io.trino.spi.type.TimestampType.TIMESTAMP_MILLIS;
-import static io.trino.spi.type.TimestampType.TIMESTAMP_SECONDS;
-import static io.trino.spi.type.TimestampWithTimeZoneType.TIMESTAMP_TZ_MILLIS;
-import static io.trino.spi.type.Timestamps.MICROSECONDS_PER_MILLISECOND;
-import static io.trino.spi.type.TinyintType.TINYINT;
-import static java.lang.String.format;
-import static org.apache.paimon.utils.Preconditions.checkArgument;
-
-/** Trino {@link ConnectorPageSource}. */
-public abstract class TrinoPageSourceBase implements ConnectorPageSource {
-
-    private static final int ROWS_PER_REQUEST = 4096;
-
-    private final CloseableIterator<InternalRow> iterator;
-    private final OptionalLong limit;
-    private final PageBuilder pageBuilder;
-    private final List<Type> columnTypes;
-    private final List<DataType> logicalTypes;
-
-    private boolean isFinished = false;
-    private long numReturn = 0;
-
-    public TrinoPageSourceBase(
-            RecordReader<InternalRow> reader,
-            List<ColumnHandle> projectedColumns,
-            OptionalLong limit) {
-        this.iterator = reader.toCloseableIterator();
-        this.limit = limit;
-        this.columnTypes = new ArrayList<>();
-        this.logicalTypes = new ArrayList<>();
-        for (ColumnHandle handle : projectedColumns) {
-            TrinoColumnHandle trinoColumnHandle = (TrinoColumnHandle) handle;
-            columnTypes.add(trinoColumnHandle.getTrinoType());
-            logicalTypes.add(trinoColumnHandle.logicalType());
-        }
-
-        this.pageBuilder = new PageBuilder(columnTypes);
-    }
-
-    @Override
-    public long getCompletedBytes() {
-        return 0;
-    }
-
-    @Override
-    public long getReadTimeNanos() {
-        return 0;
-    }
-
-    @Override
-    public boolean isFinished() {
-        return isFinished;
-    }
-
-    @Override
-    public Page getNextPage() {
-        return ClassLoaderUtils.runWithContextClassLoader(
-                () -> {
-                    try {
-                        return nextPage();
-                    } catch (IOException e) {
-                        throw new UncheckedIOException(e);
-                    }
-                },
-                TrinoPageSourceBase.class.getClassLoader());
-    }
-
-    @Nullable
-    private Page nextPage() throws IOException {
-        int count = 0;
-        while (count < ROWS_PER_REQUEST && !pageBuilder.isFull()) {
-            if (limit.isPresent() && numReturn + count >= limit.getAsLong()) {
-                isFinished = true;
-                return returnPage(count);
-            }
-
-            if (!iterator.hasNext()) {
-                isFinished = true;
-                return returnPage(count);
-            }
-
-            InternalRow row = iterator.next();
-            pageBuilder.declarePosition();
-            count++;
-            for (int i = 0; i < columnTypes.size(); i++) {
-                BlockBuilder output = pageBuilder.getBlockBuilder(i);
-                appendTo(
-                        columnTypes.get(i),
-                        logicalTypes.get(i),
-                        InternalRowUtils.get(row, i, logicalTypes.get(i)),
-                        output);
-            }
-        }
-
-        return returnPage(count);
-    }
-
-    private Page returnPage(int count) {
-        if (count == 0) {
-            return null;
-        }
-        numReturn += count;
-        Page page = pageBuilder.build();
-        pageBuilder.reset();
-        return page;
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            this.iterator.close();
-        } catch (Exception e) {
-            throw new IOException(e);
-        }
-    }
-
-    protected void appendTo(Type type, DataType logicalType, Object value, BlockBuilder output) {
-        if (value == null) {
-            output.appendNull();
-            return;
-        }
-
-        Class<?> javaType = type.getJavaType();
-        if (javaType == boolean.class) {
-            type.writeBoolean(output, (Boolean) value);
-        } else if (javaType == long.class) {
-            if (type.equals(BIGINT)
-                    || type.equals(INTEGER)
-                    || type.equals(TINYINT)
-                    || type.equals(SMALLINT)
-                    || type.equals(DATE)) {
-                type.writeLong(output, ((Number) value).longValue());
-            } else if (type.equals(REAL)) {
-                type.writeLong(output, Float.floatToIntBits((Float) value));
-            } else if (type instanceof DecimalType) {
-                DecimalType decimalType = (DecimalType) type;
-                BigDecimal decimal = ((Decimal) value).toBigDecimal();
-                type.writeLong(output, encodeShortScaledValue(decimal, decimalType.getScale()));
-            } else if (type.equals(TIMESTAMP_MILLIS) || type.equals(TIMESTAMP_SECONDS)) {
-                type.writeLong(
-                        output,
-                        ((Timestamp) value).getMillisecond() * MICROSECONDS_PER_MILLISECOND);
-            } else if (type.equals(TIMESTAMP_MICROS)) {
-                type.writeLong(output, ((Timestamp) value).toMicros());
-            } else if (type.equals(TIMESTAMP_TZ_MILLIS)) {
-                type.writeLong(
-                        output,
-                        packDateTimeWithZone(((Timestamp) value).getMillisecond(), UTC_KEY));
-            } else if (type.equals(TIME_MICROS)) {
-                type.writeLong(output, (int) value * MICROSECONDS_PER_MILLISECOND);
-            } else {
-                throw new TrinoException(
-                        GENERIC_INTERNAL_ERROR,
-                        format("Unhandled type for %s: %s", javaType.getSimpleName(), type));
-            }
-        } else if (javaType == double.class) {
-            type.writeDouble(output, ((Number) value).doubleValue());
-        } else if (type instanceof DecimalType) {
-            writeObject(output, type, value);
-        } else if (javaType == Slice.class) {
-            writeSlice(output, type, value);
-        } else if (javaType == LongTimestampWithTimeZone.class) {
-            checkArgument(type.equals(TIMESTAMP_TZ_MILLIS));
-            Timestamp timestamp = (org.apache.paimon.data.Timestamp) value;
-            type.writeObject(
-                    output, fromEpochMillisAndFraction(timestamp.getMillisecond(), 0, UTC_KEY));
-        } else if (type instanceof ArrayType
-                || type instanceof MapType
-                || type instanceof RowType) {
-            writeBlock(output, type, logicalType, value);
-        } else {
-            throw new TrinoException(
-                    GENERIC_INTERNAL_ERROR,
-                    format("Unhandled type for %s: %s", javaType.getSimpleName(), type));
-        }
-    }
-
-    private static void writeSlice(BlockBuilder output, Type type, Object value) {
-        if (type instanceof VarcharType || type instanceof io.trino.spi.type.CharType) {
-            type.writeSlice(output, wrappedBuffer(((BinaryString) value).toBytes()));
-        } else if (type instanceof VarbinaryType) {
-            type.writeSlice(output, wrappedBuffer((byte[]) value));
-        } else {
-            throw new TrinoException(
-                    GENERIC_INTERNAL_ERROR, "Unhandled type for Slice: " + type.getTypeSignature());
-        }
-    }
-
-    private static void writeObject(BlockBuilder output, Type type, Object value) {
-        if (type instanceof DecimalType) {
-            DecimalType decimalType = (DecimalType) type;
-            BigDecimal decimal = ((Decimal) value).toBigDecimal();
-            type.writeObject(output, Decimals.encodeScaledValue(decimal, decimalType.getScale()));
-        } else {
-            throw new TrinoException(
-                    GENERIC_INTERNAL_ERROR,
-                    "Unhandled type for Object: " + type.getTypeSignature());
-        }
-    }
-
-    protected void writeBlock(BlockBuilder output, Type type, DataType logicalType, Object value) {
-        if (type instanceof ArrayType) {
-            BlockBuilder builder = output.beginBlockEntry();
-
-            InternalArray arrayData = (InternalArray) value;
-            DataType elementType = DataTypeChecks.getNestedTypes(logicalType).get(0);
-            for (int i = 0; i < arrayData.size(); i++) {
-                appendTo(
-                        type.getTypeParameters().get(0),
-                        elementType,
-                        InternalRowUtils.get(arrayData, i, elementType),
-                        builder);
-            }
-
-            output.closeEntry();
-            return;
-        }
-        if (type instanceof RowType) {
-            InternalRow rowData = (InternalRow) value;
-            BlockBuilder builder = output.beginBlockEntry();
-            for (int index = 0; index < type.getTypeParameters().size(); index++) {
-                Type fieldType = type.getTypeParameters().get(index);
-                DataType fieldLogicalType =
-                        ((org.apache.paimon.types.RowType) logicalType).getTypeAt(index);
-                appendTo(
-                        fieldType,
-                        fieldLogicalType,
-                        InternalRowUtils.get(rowData, index, fieldLogicalType),
-                        builder);
-            }
-            output.closeEntry();
-            return;
-        }
-        if (type instanceof MapType) {
-            InternalMap mapData = (InternalMap) value;
-            InternalArray keyArray = mapData.keyArray();
-            InternalArray valueArray = mapData.valueArray();
-            DataType keyType = ((org.apache.paimon.types.MapType) logicalType).getKeyType();
-            DataType valueType = ((org.apache.paimon.types.MapType) logicalType).getValueType();
-            BlockBuilder builder = output.beginBlockEntry();
-            for (int i = 0; i < keyArray.size(); i++) {
-                appendTo(
-                        type.getTypeParameters().get(0),
-                        keyType,
-                        InternalRowUtils.get(keyArray, i, keyType),
-                        builder);
-                appendTo(
-                        type.getTypeParameters().get(1),
-                        valueType,
-                        InternalRowUtils.get(valueArray, i, valueType),
-                        builder);
-            }
-            output.closeEntry();
-            return;
-        }
-        throw new TrinoException(
-                GENERIC_INTERNAL_ERROR, "Unhandled type for Block: " + type.getTypeSignature());
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceProvider.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceProvider.java
index f59078d..15fad2b 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceProvider.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoPageSourceProvider.java
@@ -18,10 +18,32 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.CoreOptions;
+import org.apache.paimon.schema.SchemaManager;
+import org.apache.paimon.table.FileStoreTable;
 import org.apache.paimon.table.Table;
+import org.apache.paimon.table.source.RawFile;
 import org.apache.paimon.table.source.ReadBuilder;
+import org.apache.paimon.table.source.Split;
+import org.apache.paimon.trino.catalog.TrinoCatalog;
+import org.apache.paimon.types.DataField;
 import org.apache.paimon.types.RowType;
 
+import com.google.inject.Inject;
+import io.airlift.units.DataSize;
+import io.trino.filesystem.Location;
+import io.trino.filesystem.TrinoFileSystem;
+import io.trino.filesystem.TrinoFileSystemFactory;
+import io.trino.filesystem.TrinoInputFile;
+import io.trino.memory.context.AggregatedMemoryContext;
+import io.trino.orc.OrcColumn;
+import io.trino.orc.OrcDataSource;
+import io.trino.orc.OrcReader;
+import io.trino.orc.OrcReaderOptions;
+import io.trino.orc.OrcRecordReader;
+import io.trino.orc.TupleDomainOrcPredicate;
+import io.trino.plugin.hive.FileFormatDataSourceStats;
+import io.trino.plugin.hive.orc.OrcPageSource;
 import io.trino.spi.connector.ColumnHandle;
 import io.trino.spi.connector.ConnectorPageSource;
 import io.trino.spi.connector.ConnectorPageSourceProvider;
@@ -30,18 +52,43 @@ import io.trino.spi.connector.ConnectorSplit;
 import io.trino.spi.connector.ConnectorTableHandle;
 import io.trino.spi.connector.ConnectorTransactionHandle;
 import io.trino.spi.connector.DynamicFilter;
+import io.trino.spi.predicate.Domain;
 import io.trino.spi.predicate.TupleDomain;
+import io.trino.spi.type.Type;
+import org.joda.time.DateTimeZone;
 
-import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.OptionalLong;
+import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
+import static io.trino.memory.context.AggregatedMemoryContext.newSimpleAggregatedMemoryContext;
+import static io.trino.orc.OrcReader.INITIAL_BATCH_SIZE;
+import static java.util.Objects.requireNonNull;
+import static org.apache.paimon.schema.SchemaEvolutionUtil.createIndexMapping;
 import static org.apache.paimon.trino.ClassLoaderUtils.runWithContextClassLoader;
 
 /** Trino {@link ConnectorPageSourceProvider}. */
 public class TrinoPageSourceProvider implements ConnectorPageSourceProvider {
 
+    private final TrinoFileSystemFactory fileSystemFactory;
+    private final TrinoCatalog trinoCatalog;
+
+    @Inject
+    public TrinoPageSourceProvider(
+            TrinoFileSystemFactory fileSystemFactory, TrinoMetadataFactory trinoMetadataFactory) {
+        this.fileSystemFactory = requireNonNull(fileSystemFactory, "fileSystemFactory is null");
+        this.trinoCatalog =
+                requireNonNull(trinoMetadataFactory, "trinoMetadataFactory is null")
+                        .create()
+                        .catalog();
+    }
+
     @Override
     public ConnectorPageSource createPageSource(
             ConnectorTransactionHandle transaction,
@@ -50,11 +97,13 @@ public class TrinoPageSourceProvider implements ConnectorPageSourceProvider {
             ConnectorTableHandle tableHandle,
             List<ColumnHandle> columns,
             DynamicFilter dynamicFilter) {
+        trinoCatalog.initSession(session);
         TrinoTableHandle trinoTableHandle = (TrinoTableHandle) tableHandle;
-        Table table = trinoTableHandle.tableWithDynamicOptions(session);
+        Table table = trinoTableHandle.tableWithDynamicOptions(trinoCatalog, session);
         return runWithContextClassLoader(
                 () ->
                         createPageSource(
+                                session,
                                 table,
                                 trinoTableHandle.getFilter(),
                                 (TrinoSplit) split,
@@ -64,32 +113,233 @@ public class TrinoPageSourceProvider implements ConnectorPageSourceProvider {
     }
 
     private ConnectorPageSource createPageSource(
+            ConnectorSession session,
             Table table,
             TupleDomain<TrinoColumnHandle> filter,
             TrinoSplit split,
             List<ColumnHandle> columns,
             OptionalLong limit) {
-        ReadBuilder read = table.newReadBuilder();
         RowType rowType = table.rowType();
         List<String> fieldNames = FieldNameUtils.fieldNames(rowType);
         List<String> projectedFields =
                 columns.stream()
                         .map(TrinoColumnHandle.class::cast)
                         .map(TrinoColumnHandle::getColumnName)
-                        .collect(Collectors.toList());
-        if (!fieldNames.equals(projectedFields)) {
-            int[] projected = projectedFields.stream().mapToInt(fieldNames::indexOf).toArray();
-            read.withProjection(projected);
+                        .toList();
+        int[] columnIndex =
+                // the column index, very important
+                projectedFields.stream().mapToInt(fieldNames::indexOf).toArray();
+
+        TrinoFileSystem fileSystem = fileSystemFactory.create(session);
+
+        try {
+            Split paimonSplit = split.decodeSplit();
+            Optional<List<RawFile>> optionalRawFiles = paimonSplit.convertToRawFiles();
+            if (checkRawFile(optionalRawFiles)) {
+                FileStoreTable fileStoreTable = (FileStoreTable) table;
+                SchemaManager schemaManager =
+                        new SchemaManager(fileStoreTable.fileIO(), fileStoreTable.location());
+                List<Type> type =
+                        columns.stream()
+                                .map(s -> ((TrinoColumnHandle) s).getTrinoType())
+                                .collect(Collectors.toList());
+                try {
+                    return new DirectTrinoPageSource(
+                            optionalRawFiles.orElseThrow().stream()
+                                    .map(
+                                            rawFile ->
+                                                    createDataPageSource(
+                                                            rawFile.format(),
+                                                            fileSystem.newInputFile(
+                                                                    Location.of(rawFile.path())),
+                                                            fileStoreTable.coreOptions(),
+                                                            // map table column index to data column
+                                                            // index, if column does not exist in
+                                                            // data columns, set it to -1
+                                                            // columns those set to -1 will generate
+                                                            // a null vector in orc page
+                                                            mapping(
+                                                                    columnIndex,
+                                                                    rowType.getFields(),
+                                                                    schemaManager
+                                                                            .schema(
+                                                                                    rawFile
+                                                                                            .schemaId())
+                                                                            .fields()),
+                                                            type,
+                                                            orderDomains(projectedFields, filter)))
+                                    .collect(
+                                            Collector.of(
+                                                    LinkedList::new,
+                                                    List::add,
+                                                    (left, right) -> {
+                                                        left.addAll(right);
+                                                        return left;
+                                                    })));
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            } else {
+                // old read way
+                ReadBuilder read = table.newReadBuilder();
+                new TrinoFilterConverter(rowType).convert(filter).ifPresent(read::withFilter);
+
+                if (!fieldNames.equals(projectedFields)) {
+                    read.withProjection(columnIndex);
+                }
+
+                return new TrinoPageSource(
+                        read.newRead().executeFilter().createReader(paimonSplit), columns, limit);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
         }
+    }
+
+    // make domains(filters) to be ordered by projected fields' order.
+    private List<Domain> orderDomains(
+            List<String> projectedFields, TupleDomain<TrinoColumnHandle> filter) {
+        Optional<Map<TrinoColumnHandle, Domain>> optionalFilter = filter.getDomains();
+        Map<String, Domain> domainMap = new HashMap<>();
+        optionalFilter.ifPresent(
+                trinoColumnHandleDomainMap ->
+                        trinoColumnHandleDomainMap.forEach(
+                                (k, v) -> domainMap.put(k.getColumnName(), v)));
 
-        new TrinoFilterConverter(rowType).convert(filter).ifPresent(read::withFilter);
+        return projectedFields.stream()
+                .map(name -> domainMap.getOrDefault(name, null))
+                .collect(Collectors.toList());
+    }
+
+    private boolean checkRawFile(Optional<List<RawFile>> optionalRawFiles) {
+        return optionalRawFiles.isPresent() && canUseTrinoPageSource(optionalRawFiles.get());
+    }
 
+    // only support orc yet.
+    // TODO: support parquet and avro
+    private boolean canUseTrinoPageSource(List<RawFile> rawFiles) {
+        for (RawFile rawFile : rawFiles) {
+            if (!rawFile.format().equals("orc")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // map the table schema columnsIndex to data schema columnsIndex
+    private int[] mapping(
+            int[] tableSchemaColumnIndex, List<DataField> tableFields, List<DataField> dataFields) {
+
+        int[] mapping = createIndexMapping(tableFields, dataFields);
+        if (mapping == null) {
+            return tableSchemaColumnIndex;
+        }
+        int[] result = new int[tableSchemaColumnIndex.length];
+
+        for (int i = 0; i < tableSchemaColumnIndex.length; i++) {
+            int po = tableSchemaColumnIndex[i];
+            result[i] = mapping[po];
+        }
+        return result;
+    }
+
+    private ConnectorPageSource createDataPageSource(
+            String format,
+            TrinoInputFile inputFile,
+            // TODO construct read option by core-options
+            CoreOptions coreOptions,
+            int[] columns,
+            List<Type> types,
+            List<Domain> domains) {
+        switch (format) {
+            case "orc":
+                {
+                    return createOrcDataPageSource(
+                            inputFile,
+                            // TODO: pass options from catalog configuration
+                            new OrcReaderOptions()
+                                    // Default tiny stripe size 8 M is too big for paimon.
+                                    // Cache stripe will cause more read (I want to read one column,
+                                    // but not the whole stripe)
+                                    .withTinyStripeThreshold(
+                                            DataSize.of(4, DataSize.Unit.KILOBYTE)),
+                            columns,
+                            types,
+                            domains);
+                }
+            case "parquet":
+                {
+                    // todo
+                    throw new RuntimeException("Unsupport file format: " + format);
+                }
+            case "avro":
+                {
+                    // todo
+                    throw new RuntimeException("Unsupport file format: " + format);
+                }
+            default:
+                {
+                    throw new RuntimeException("Unsupport file format: " + format);
+                }
+        }
+    }
+
+    private ConnectorPageSource createOrcDataPageSource(
+            TrinoInputFile inputFile,
+            OrcReaderOptions options,
+            int[] columns,
+            List<Type> types,
+            List<Domain> domains) {
         try {
-            return new TrinoPageSource(
-                    read.newRead().executeFilter().createReader(split.decodeSplit()),
-                    columns,
-                    limit);
-        } catch (IOException e) {
+            OrcDataSource orcDataSource = new TrinoOrcDataSource(inputFile, options);
+            OrcReader reader =
+                    OrcReader.createOrcReader(orcDataSource, options)
+                            .orElseThrow(() -> new RuntimeException("ORC file is zero length"));
+
+            List<OrcColumn> fileColumns = reader.getRootColumn().getNestedColumns();
+            TupleDomainOrcPredicate.TupleDomainOrcPredicateBuilder predicateBuilder =
+                    TupleDomainOrcPredicate.builder();
+            List<OrcPageSource.ColumnAdaptation> columnAdaptations = new ArrayList<>();
+            List<OrcColumn> fileReadColumns = new ArrayList<>(columns.length);
+            List<Type> fileReadTypes = new ArrayList<>(columns.length);
+
+            for (int i = 0; i < columns.length; i++) {
+                if (columns[i] >= 0) {
+                    // column exists
+                    columnAdaptations.add(
+                            OrcPageSource.ColumnAdaptation.sourceColumn(fileReadColumns.size()));
+                    fileReadColumns.add(fileColumns.get(columns[i]));
+                    fileReadTypes.add(types.get(i));
+                    if (domains.get(i) != null) {
+                        predicateBuilder.addColumn(
+                                fileColumns.get(columns[i]).getColumnId(), domains.get(i));
+                    }
+                } else {
+                    columnAdaptations.add(OrcPageSource.ColumnAdaptation.nullColumn(types.get(i)));
+                }
+            }
+
+            AggregatedMemoryContext memoryUsage = newSimpleAggregatedMemoryContext();
+            OrcRecordReader recordReader =
+                    reader.createRecordReader(
+                            fileReadColumns,
+                            fileReadTypes,
+                            predicateBuilder.build(),
+                            DateTimeZone.UTC,
+                            memoryUsage,
+                            INITIAL_BATCH_SIZE,
+                            RuntimeException::new);
+
+            return new OrcPageSource(
+                    recordReader,
+                    columnAdaptations,
+                    orcDataSource,
+                    Optional.empty(),
+                    Optional.empty(),
+                    memoryUsage,
+                    new FileFormatDataSourceStats(),
+                    reader.getCompressionKind());
+        } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
index e942641..b2b5ea0 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManager.java
@@ -18,6 +18,13 @@
 
 package org.apache.paimon.trino;
 
+import org.apache.paimon.table.Table;
+import org.apache.paimon.table.source.ReadBuilder;
+import org.apache.paimon.table.source.Split;
+import org.apache.paimon.trino.catalog.TrinoCatalog;
+
+import com.google.inject.Inject;
+import io.trino.filesystem.TrinoFileSystemFactory;
 import io.trino.spi.connector.ConnectorSession;
 import io.trino.spi.connector.ConnectorSplitManager;
 import io.trino.spi.connector.ConnectorSplitSource;
@@ -26,8 +33,26 @@ import io.trino.spi.connector.ConnectorTransactionHandle;
 import io.trino.spi.connector.Constraint;
 import io.trino.spi.connector.DynamicFilter;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+
 /** Trino {@link ConnectorSplitManager}. */
-public class TrinoSplitManager extends TrinoSplitManagerBase {
+public class TrinoSplitManager implements ConnectorSplitManager {
+
+    private final TrinoFileSystemFactory fileSystemFactory;
+    private final TrinoCatalog trinoCatalog;
+
+    @Inject
+    public TrinoSplitManager(
+            TrinoFileSystemFactory fileSystemFactory, TrinoMetadataFactory trinoMetadataFactory) {
+        this.fileSystemFactory = requireNonNull(fileSystemFactory, "fileSystemFactory is null");
+        this.trinoCatalog =
+                requireNonNull(trinoMetadataFactory, "trinoMetadataFactory is null")
+                        .create()
+                        .catalog();
+    }
 
     @Override
     public ConnectorSplitSource getSplits(
@@ -38,4 +63,36 @@ public class TrinoSplitManager extends TrinoSplitManagerBase {
             Constraint constraint) {
         return getSplits(table, session);
     }
+
+    protected ConnectorSplitSource getSplits(
+            ConnectorTableHandle connectorTableHandle, ConnectorSession session) {
+        // TODO dynamicFilter?
+        // TODO what is constraint?
+
+        TrinoTableHandle tableHandle = (TrinoTableHandle) connectorTableHandle;
+        Table table = tableHandle.tableWithDynamicOptions(trinoCatalog, session);
+        ReadBuilder readBuilder = table.newReadBuilder();
+        new TrinoFilterConverter(table.rowType())
+                .convert(tableHandle.getFilter())
+                .ifPresent(readBuilder::withFilter);
+        tableHandle.getLimit().ifPresent(limit -> readBuilder.withLimit((int) limit));
+        List<Split> splits = readBuilder.newScan().plan().splits();
+
+        long maxRowCount = splits.stream().mapToLong(Split::rowCount).max().orElse(0L);
+        double minimumSplitWeight = TrinoSessionProperties.getMinimumSplitWeight(session);
+        return new TrinoSplitSource(
+                splits.stream()
+                        .map(
+                                split ->
+                                        TrinoSplit.fromSplit(
+                                                split,
+                                                Math.min(
+                                                        Math.max(
+                                                                (double) split.rowCount()
+                                                                        / maxRowCount,
+                                                                minimumSplitWeight),
+                                                        1.0)))
+                        .collect(Collectors.toList()),
+                ((TrinoTableHandle) connectorTableHandle).getLimit());
+    }
 }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManagerBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManagerBase.java
deleted file mode 100644
index 61a26d2..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitManagerBase.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.trino;
-
-import org.apache.paimon.table.Table;
-import org.apache.paimon.table.source.ReadBuilder;
-import org.apache.paimon.table.source.Split;
-
-import io.trino.spi.connector.ConnectorSession;
-import io.trino.spi.connector.ConnectorSplitManager;
-import io.trino.spi.connector.ConnectorSplitSource;
-import io.trino.spi.connector.ConnectorTableHandle;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Trino {@link ConnectorSplitManager}. */
-public abstract class TrinoSplitManagerBase implements ConnectorSplitManager {
-
-    protected ConnectorSplitSource getSplits(
-            ConnectorTableHandle connectorTableHandle, ConnectorSession session) {
-        // TODO dynamicFilter?
-        // TODO what is constraint?
-
-        TrinoTableHandle tableHandle = (TrinoTableHandle) connectorTableHandle;
-        Table table = tableHandle.tableWithDynamicOptions(session);
-        ReadBuilder readBuilder = table.newReadBuilder();
-        new TrinoFilterConverter(table.rowType())
-                .convert(tableHandle.getFilter())
-                .ifPresent(readBuilder::withFilter);
-        tableHandle.getLimit().ifPresent(limit -> readBuilder.withLimit((int) limit));
-        List<Split> splits = readBuilder.newScan().plan().splits();
-
-        long maxRowCount = splits.stream().mapToLong(Split::rowCount).max().orElse(0L);
-        double minimumSplitWeight = TrinoSessionProperties.getMinimumSplitWeight(session);
-        return new TrinoSplitSource(
-                splits.stream()
-                        .map(
-                                split ->
-                                        TrinoSplit.fromSplit(
-                                                split,
-                                                Math.min(
-                                                        Math.max(
-                                                                (double) split.rowCount()
-                                                                        / maxRowCount,
-                                                                minimumSplitWeight),
-                                                        1.0)))
-                        .collect(Collectors.toList()));
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
index a7cee21..bd8201f 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSource.java
@@ -18,20 +18,51 @@
 
 package org.apache.paimon.trino;
 
+import io.trino.spi.connector.ConnectorSplit;
 import io.trino.spi.connector.ConnectorSplitSource;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.OptionalLong;
+import java.util.Queue;
 import java.util.concurrent.CompletableFuture;
 
 /** Trino {@link ConnectorSplitSource}. */
-public class TrinoSplitSource extends TrinoSplitSourceBase {
+public class TrinoSplitSource implements ConnectorSplitSource {
 
-    public TrinoSplitSource(List<TrinoSplit> splits) {
-        super(splits);
+    private final Queue<TrinoSplit> splits;
+    private final OptionalLong limit;
+    private long count = 0;
+
+    public TrinoSplitSource(List<TrinoSplit> splits, OptionalLong limit) {
+        this.splits = new LinkedList<>(splits);
+        this.limit = limit;
+    }
+
+    protected CompletableFuture<ConnectorSplitBatch> innerGetNextBatch(int maxSize) {
+        List<ConnectorSplit> batch = new ArrayList<>();
+        for (int i = 0; i < maxSize; i++) {
+            TrinoSplit split = splits.poll();
+            if (split == null || (limit.isPresent() && count >= limit.getAsLong())) {
+                break;
+            }
+            count += split.decodeSplit().rowCount();
+            batch.add(split);
+        }
+        return CompletableFuture.completedFuture(new ConnectorSplitBatch(batch, isFinished()));
     }
 
     @Override
     public CompletableFuture<ConnectorSplitBatch> getNextBatch(int maxSize) {
         return innerGetNextBatch(maxSize);
     }
+
+    @Override
+    public void close() {}
+
+    @Override
+    public boolean isFinished() {
+        return splits.isEmpty() || (limit.isPresent() && count >= limit.getAsLong());
+    }
 }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSourceBase.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSourceBase.java
deleted file mode 100644
index 65843d8..0000000
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoSplitSourceBase.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.trino;
-
-import io.trino.spi.connector.ConnectorSplit;
-import io.trino.spi.connector.ConnectorSplitSource;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.CompletableFuture;
-
-/** Trino {@link ConnectorSplitSource}. */
-public abstract class TrinoSplitSourceBase implements ConnectorSplitSource {
-
-    private final Queue<TrinoSplit> splits;
-
-    public TrinoSplitSourceBase(List<TrinoSplit> splits) {
-        this.splits = new LinkedList<>(splits);
-    }
-
-    protected CompletableFuture<ConnectorSplitBatch> innerGetNextBatch(int maxSize) {
-        List<ConnectorSplit> batch = new ArrayList<>();
-        for (int i = 0; i < maxSize; i++) {
-            TrinoSplit split = splits.poll();
-            if (split == null) {
-                break;
-            }
-            batch.add(split);
-        }
-        return CompletableFuture.completedFuture(new ConnectorSplitBatch(batch, isFinished()));
-    }
-
-    @Override
-    public void close() {}
-
-    @Override
-    public boolean isFinished() {
-        return splits.isEmpty();
-    }
-}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoTableHandle.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoTableHandle.java
index 1e785fd..30c03af 100644
--- a/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoTableHandle.java
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/TrinoTableHandle.java
@@ -19,8 +19,10 @@
 package org.apache.paimon.trino;
 
 import org.apache.paimon.CoreOptions;
+import org.apache.paimon.catalog.Catalog;
+import org.apache.paimon.catalog.Identifier;
 import org.apache.paimon.table.Table;
-import org.apache.paimon.utils.InstantiationUtil;
+import org.apache.paimon.trino.catalog.TrinoCatalog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -32,8 +34,6 @@ import io.trino.spi.connector.ConnectorTableMetadata;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.predicate.TupleDomain;
 
-import java.io.IOException;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -44,22 +44,23 @@ import java.util.OptionalLong;
 import java.util.stream.Collectors;
 
 /** Trino {@link ConnectorTableHandle}. */
-public final class TrinoTableHandle implements ConnectorTableHandle {
+public class TrinoTableHandle implements ConnectorTableHandle {
 
     private final String schemaName;
     private final String tableName;
-    private final byte[] serializedTable;
     private final TupleDomain<TrinoColumnHandle> filter;
     private final Optional<List<ColumnHandle>> projectedColumns;
     private final OptionalLong limit;
+    private final Map<String, String> dynamicOptions;
 
-    private Table lazyTable;
+    private transient Table table;
 
-    public TrinoTableHandle(String schemaName, String tableName, byte[] serializedTable) {
+    public TrinoTableHandle(
+            String schemaName, String tableName, Map<String, String> dynamicOptions) {
         this(
                 schemaName,
                 tableName,
-                serializedTable,
+                dynamicOptions,
                 TupleDomain.all(),
                 Optional.empty(),
                 OptionalLong.empty());
@@ -69,13 +70,13 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
     public TrinoTableHandle(
             @JsonProperty("schemaName") String schemaName,
             @JsonProperty("tableName") String tableName,
-            @JsonProperty("serializedTable") byte[] serializedTable,
+            @JsonProperty("dynamicOptions") Map<String, String> dynamicOptions,
             @JsonProperty("filter") TupleDomain<TrinoColumnHandle> filter,
             @JsonProperty("projection") Optional<List<ColumnHandle>> projectedColumns,
             @JsonProperty("limit") OptionalLong limit) {
         this.schemaName = schemaName;
         this.tableName = tableName;
-        this.serializedTable = serializedTable;
+        this.dynamicOptions = dynamicOptions;
         this.filter = filter;
         this.projectedColumns = projectedColumns;
         this.limit = limit;
@@ -92,8 +93,8 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
     }
 
     @JsonProperty
-    public byte[] getSerializedTable() {
-        return serializedTable;
+    public Map<String, String> getDynamicOptions() {
+        return dynamicOptions;
     }
 
     @JsonProperty
@@ -110,22 +111,9 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
         return limit;
     }
 
-    public TrinoTableHandle copy(TupleDomain<TrinoColumnHandle> filter) {
-        return new TrinoTableHandle(
-                schemaName, tableName, serializedTable, filter, projectedColumns, limit);
-    }
+    public Table tableWithDynamicOptions(TrinoCatalog catalog, ConnectorSession session) {
+        Table paimonTable = table(catalog);
 
-    public TrinoTableHandle copy(Optional<List<ColumnHandle>> projectedColumns) {
-        return new TrinoTableHandle(
-                schemaName, tableName, serializedTable, filter, projectedColumns, limit);
-    }
-
-    public TrinoTableHandle copy(OptionalLong limit) {
-        return new TrinoTableHandle(
-                schemaName, tableName, serializedTable, filter, projectedColumns, limit);
-    }
-
-    public Table tableWithDynamicOptions(ConnectorSession session) {
         // see TrinoConnector.getSessionProperties
         Map<String, String> dynamicOptions = new HashMap<>();
         Long scanTimestampMills = TrinoSessionProperties.getScanTimestampMillis(session);
@@ -138,32 +126,31 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
             dynamicOptions.put(CoreOptions.SCAN_SNAPSHOT_ID.key(), scanSnapshotId.toString());
         }
 
-        return dynamicOptions.size() > 0 ? table().copy(dynamicOptions) : table();
+        return dynamicOptions.size() > 0 ? paimonTable.copy(dynamicOptions) : paimonTable;
     }
 
-    public Table table() {
-        if (lazyTable == null) {
-            try {
-                lazyTable =
-                        InstantiationUtil.deserializeObject(
-                                serializedTable, this.getClass().getClassLoader());
-            } catch (IOException | ClassNotFoundException e) {
-                throw new RuntimeException(e);
-            }
+    public Table table(TrinoCatalog catalog) {
+        if (table != null) {
+            return table;
+        }
+        try {
+            table = catalog.getTable(Identifier.create(schemaName, tableName)).copy(dynamicOptions);
+        } catch (Catalog.TableNotExistException e) {
+            throw new RuntimeException(e);
         }
-        return lazyTable;
+        return table;
     }
 
-    public ConnectorTableMetadata tableMetadata() {
+    public ConnectorTableMetadata tableMetadata(TrinoCatalog catalog) {
         return new ConnectorTableMetadata(
                 SchemaTableName.schemaTableName(schemaName, tableName),
-                columnMetadatas(),
+                columnMetadatas(catalog),
                 Collections.emptyMap(),
                 Optional.empty());
     }
 
-    public List<ColumnMetadata> columnMetadatas() {
-        return table().rowType().getFields().stream()
+    public List<ColumnMetadata> columnMetadatas(TrinoCatalog catalog) {
+        return table(catalog).rowType().getFields().stream()
                 .map(
                         column ->
                                 ColumnMetadata.builder()
@@ -175,14 +162,30 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
                 .collect(Collectors.toList());
     }
 
-    public TrinoColumnHandle columnHandle(String field) {
-        List<String> fieldNames = FieldNameUtils.fieldNames(table().rowType());
+    public TrinoColumnHandle columnHandle(TrinoCatalog catalog, String field) {
+        Table paimonTable = table(catalog);
+        List<String> fieldNames = FieldNameUtils.fieldNames(paimonTable.rowType());
         int index = fieldNames.indexOf(field);
         if (index == -1) {
             throw new RuntimeException(
                     String.format("Cannot find field %s in schema %s", field, fieldNames));
         }
-        return TrinoColumnHandle.of(field, table().rowType().getTypeAt(index));
+        return TrinoColumnHandle.of(field, paimonTable.rowType().getTypeAt(index));
+    }
+
+    public TrinoTableHandle copy(TupleDomain<TrinoColumnHandle> filter) {
+        return new TrinoTableHandle(
+                schemaName, tableName, dynamicOptions, filter, projectedColumns, limit);
+    }
+
+    public TrinoTableHandle copy(Optional<List<ColumnHandle>> projectedColumns) {
+        return new TrinoTableHandle(
+                schemaName, tableName, dynamicOptions, filter, projectedColumns, limit);
+    }
+
+    public TrinoTableHandle copy(OptionalLong limit) {
+        return new TrinoTableHandle(
+                schemaName, tableName, dynamicOptions, filter, projectedColumns, limit);
     }
 
     @Override
@@ -194,7 +197,7 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
             return false;
         }
         TrinoTableHandle that = (TrinoTableHandle) o;
-        return Arrays.equals(serializedTable, that.serializedTable)
+        return Objects.equals(dynamicOptions, that.dynamicOptions)
                 && Objects.equals(schemaName, that.schemaName)
                 && Objects.equals(tableName, that.tableName)
                 && Objects.equals(filter, that.filter)
@@ -203,7 +206,6 @@ public final class TrinoTableHandle implements ConnectorTableHandle {
 
     @Override
     public int hashCode() {
-        return Objects.hash(
-                schemaName, tableName, filter, projectedColumns, Arrays.hashCode(serializedTable));
+        return Objects.hash(schemaName, tableName, filter, projectedColumns, dynamicOptions);
     }
 }
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/catalog/TrinoCatalog.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/catalog/TrinoCatalog.java
new file mode 100644
index 0000000..95f2ec5
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/catalog/TrinoCatalog.java
@@ -0,0 +1,203 @@
+/*
+ *
+ *  * 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.trino.catalog;
+
+import org.apache.paimon.catalog.Catalog;
+import org.apache.paimon.catalog.CatalogContext;
+import org.apache.paimon.catalog.CatalogFactory;
+import org.apache.paimon.catalog.CatalogLock;
+import org.apache.paimon.catalog.Identifier;
+import org.apache.paimon.metastore.MetastoreClient;
+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.trino.ClassLoaderUtils;
+import org.apache.paimon.trino.fileio.TrinoFileIOLoader;
+import org.apache.paimon.utils.IOUtils;
+
+import io.trino.filesystem.TrinoFileSystem;
+import io.trino.filesystem.TrinoFileSystemFactory;
+import io.trino.spi.connector.ConnectorSession;
+import org.apache.hadoop.conf.Configuration;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/** Trino catalog, use it after set session. */
+public class TrinoCatalog implements Catalog {
+
+    private final Map<ConnectorSession, Catalog> catalogMap = new HashMap<>();
+
+    private final Options options;
+
+    private final Configuration configuration;
+
+    private final TrinoFileSystemFactory trinoFileSystemFactory;
+
+    private Catalog current;
+
+    public TrinoCatalog(
+            Options options,
+            Configuration configuration,
+            TrinoFileSystemFactory trinoFileSystemFactory) {
+        this.options = options;
+        this.configuration = configuration;
+        this.trinoFileSystemFactory = trinoFileSystemFactory;
+    }
+
+    public void initSession(ConnectorSession connectorSession) {
+        current =
+                catalogMap.computeIfAbsent(
+                        connectorSession,
+                        session -> {
+                            TrinoFileSystem trinoFileSystem =
+                                    trinoFileSystemFactory.create(session);
+                            CatalogContext catalogContext =
+                                    CatalogContext.create(
+                                            options,
+                                            configuration,
+                                            new TrinoFileIOLoader(trinoFileSystem),
+                                            null);
+                            try {
+                                SecurityContext.install(catalogContext);
+                            } catch (Exception e) {
+                                throw new RuntimeException(e);
+                            }
+                            return ClassLoaderUtils.runWithContextClassLoader(
+                                    () -> CatalogFactory.createCatalog(catalogContext),
+                                    this.getClass().getClassLoader());
+                        });
+    }
+
+    @Override
+    public Optional<CatalogLock.LockFactory> lockFactory() {
+        return current.lockFactory();
+    }
+
+    @Override
+    public List<String> listDatabases() {
+        return current.listDatabases();
+    }
+
+    @Override
+    public boolean databaseExists(String s) {
+        return current.databaseExists(s);
+    }
+
+    @Override
+    public void createDatabase(String s, boolean b, Map<String, String> map)
+            throws DatabaseAlreadyExistException {
+        current.createDatabase(s, b, map);
+    }
+
+    @Override
+    public Map<String, String> loadDatabaseProperties(String s) throws DatabaseNotExistException {
+        return current.loadDatabaseProperties(s);
+    }
+
+    @Override
+    public void dropDatabase(String s, boolean b, boolean b1)
+            throws DatabaseNotExistException, DatabaseNotEmptyException {
+        current.dropDatabase(s, b, b1);
+    }
+
+    @Override
+    public Table getTable(Identifier identifier) throws TableNotExistException {
+        return current.getTable(identifier);
+    }
+
+    @Override
+    public List<String> listTables(String s) throws DatabaseNotExistException {
+        return current.listTables(s);
+    }
+
+    @Override
+    public void dropTable(Identifier identifier, boolean b) throws TableNotExistException {
+        current.dropTable(identifier, b);
+    }
+
+    @Override
+    public void createTable(Identifier identifier, Schema schema, boolean ignoreIfExists)
+            throws TableAlreadyExistException, DatabaseNotExistException {
+        current.createTable(identifier, schema, ignoreIfExists);
+    }
+
+    @Override
+    public void renameTable(Identifier fromTable, Identifier toTable, boolean ignoreIfExistsb)
+            throws TableNotExistException, TableAlreadyExistException {
+        current.renameTable(fromTable, toTable, ignoreIfExistsb);
+    }
+
+    @Override
+    public void alterTable(Identifier identifier, List<SchemaChange> list, boolean ignoreIfExists)
+            throws TableNotExistException, ColumnAlreadyExistException, ColumnNotExistException {
+        current.alterTable(identifier, list, ignoreIfExists);
+    }
+
+    @Override
+    public void dropPartition(Identifier identifier, Map<String, String> partitions)
+            throws TableNotExistException, PartitionNotExistException {
+        current.dropPartition(identifier, partitions);
+    }
+
+    @Override
+    public void close() {
+        catalogMap.values().forEach(IOUtils::closeQuietly);
+        catalogMap.clear();
+        current = null;
+    }
+
+    @Override
+    public Optional<CatalogLock.LockContext> lockContext() {
+        return current.lockContext();
+    }
+
+    @Override
+    public Optional<MetastoreClient.Factory> metastoreClientFactory(Identifier identifier) {
+        return current.metastoreClientFactory(identifier);
+    }
+
+    @Override
+    public void createDatabase(String name, boolean ignoreIfExists)
+            throws DatabaseAlreadyExistException {
+        current.createDatabase(name, ignoreIfExists);
+    }
+
+    @Override
+    public boolean tableExists(Identifier identifier) {
+        return current.tableExists(identifier);
+    }
+
+    @Override
+    public void alterTable(Identifier identifier, SchemaChange change, boolean ignoreIfNotExists)
+            throws TableNotExistException, ColumnAlreadyExistException, ColumnNotExistException {
+        current.alterTable(identifier, change, ignoreIfNotExists);
+    }
+
+    @Override
+    public boolean caseSensitive() {
+        return current.caseSensitive();
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/PositionOutputStreamWrapper.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/PositionOutputStreamWrapper.java
new file mode 100644
index 0000000..e342eb3
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/PositionOutputStreamWrapper.java
@@ -0,0 +1,76 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.fs.PositionOutputStream;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** Wrapper of {@link OutputStream}. */
+public class PositionOutputStreamWrapper extends PositionOutputStream {
+
+    private final OutputStream outputStream;
+
+    private long position;
+
+    public PositionOutputStreamWrapper(OutputStream outputStream) {
+        this(outputStream, 0);
+    }
+
+    public PositionOutputStreamWrapper(OutputStream outputStream, long startPosition) {
+        this.outputStream = outputStream;
+        this.position = startPosition;
+    }
+
+    @Override
+    public long getPos() {
+        return position;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        position++;
+        outputStream.write(b);
+    }
+
+    @Override
+    public void write(byte[] bytes) throws IOException {
+        position += bytes.length;
+        outputStream.write(bytes);
+    }
+
+    @Override
+    public void write(byte[] bytes, int off, int len) throws IOException {
+        position += len;
+        outputStream.write(bytes, off, len);
+    }
+
+    @Override
+    public void flush() throws IOException {
+        outputStream.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        outputStream.close();
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoDirectoryFileStatus.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoDirectoryFileStatus.java
new file mode 100644
index 0000000..b37ebe8
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoDirectoryFileStatus.java
@@ -0,0 +1,56 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.fs.FileStatus;
+import org.apache.paimon.fs.Path;
+
+/** File status for directory. */
+public class TrinoDirectoryFileStatus implements FileStatus {
+
+    private final Path path;
+
+    public TrinoDirectoryFileStatus(Path path) {
+        this.path = path;
+    }
+
+    @Override
+    public long getLen() {
+        // can't get len by trino file system
+        return -1;
+    }
+
+    @Override
+    public boolean isDir() {
+        return true;
+    }
+
+    @Override
+    public Path getPath() {
+        return path;
+    }
+
+    @Override
+    public long getModificationTime() {
+        // can't get modification time by trino file system
+        return -1;
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java
new file mode 100644
index 0000000..3a5f676
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIO.java
@@ -0,0 +1,170 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.catalog.CatalogContext;
+import org.apache.paimon.fs.FileIO;
+import org.apache.paimon.fs.FileStatus;
+import org.apache.paimon.fs.Path;
+import org.apache.paimon.fs.PositionOutputStream;
+import org.apache.paimon.fs.SeekableInputStream;
+
+import io.trino.filesystem.FileEntry;
+import io.trino.filesystem.FileIterator;
+import io.trino.filesystem.Location;
+import io.trino.filesystem.TrinoFileSystem;
+import io.trino.filesystem.TrinoInputFile;
+
+import javax.annotation.Nullable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Trino file io for paimon. */
+public class TrinoFileIO implements FileIO {
+
+    private final TrinoFileSystem trinoFileSystem;
+    private final boolean objectStore;
+
+    public TrinoFileIO(TrinoFileSystem trinoFileSystem, @Nullable Path path) {
+        this.trinoFileSystem = trinoFileSystem;
+        this.objectStore = path == null || checkObjectStore(path.toUri().getScheme());
+    }
+
+    @Override
+    public boolean isObjectStore() {
+        return objectStore;
+    }
+
+    @Override
+    public void configure(CatalogContext catalogContext) {}
+
+    @Override
+    public SeekableInputStream newInputStream(Path path) throws IOException {
+        return new TrinoInputStreamWrapper(
+                trinoFileSystem.newInputFile(Location.of(path.toString())).newStream());
+    }
+
+    @Override
+    public PositionOutputStream newOutputStream(Path path, boolean b) throws IOException {
+        return new PositionOutputStreamWrapper(
+                trinoFileSystem.newOutputFile(Location.of(path.toString())).create());
+    }
+
+    @Override
+    public FileStatus getFileStatus(Path path) throws IOException {
+        return status(path);
+    }
+
+    private FileStatus status(Path path) throws IOException {
+        if (trinoFileSystem.directoryExists(Location.of(path.toString())).orElse(false)) {
+            return new TrinoDirectoryFileStatus(path);
+        } else {
+            TrinoInputFile trinoInputFile =
+                    trinoFileSystem.newInputFile(Location.of(path.toString()));
+            return new TrinoFileStatus(
+                    trinoInputFile.length(), path, trinoInputFile.lastModified().getEpochSecond());
+        }
+    }
+
+    @Override
+    public FileStatus[] listStatus(Path path) throws IOException {
+        List<FileStatus> fileStatusList = new ArrayList<>();
+        Location location = Location.of(path.toString());
+        if (trinoFileSystem.directoryExists(location).orElse(false)) {
+            FileIterator fileIterator = trinoFileSystem.listFiles(location);
+            while (fileIterator.hasNext()) {
+                FileEntry fileEntry = fileIterator.next();
+                fileStatusList.add(
+                        new TrinoFileStatus(
+                                fileEntry.length(),
+                                new Path(fileEntry.location().toString()),
+                                fileEntry.lastModified().getEpochSecond()));
+            }
+            trinoFileSystem
+                    .listDirectories(Location.of(path.toString()))
+                    .forEach(
+                            l ->
+                                    fileStatusList.add(
+                                            new TrinoDirectoryFileStatus(new Path(l.toString()))));
+        }
+        return fileStatusList.toArray(new FileStatus[0]);
+    }
+
+    @Override
+    public boolean exists(Path path) throws IOException {
+        return trinoFileSystem.directoryExists(Location.of(path.toString())).orElse(false)
+                || existFile(Location.of(path.toString()));
+    }
+
+    private boolean existFile(Location location) throws IOException {
+        try {
+            return trinoFileSystem.newInputFile(location).exists();
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean delete(Path path, boolean b) throws IOException {
+        Location location = Location.of(path.toString());
+        if (trinoFileSystem.directoryExists(location).orElse(false)) {
+            trinoFileSystem.deleteDirectory(location);
+            return true;
+        } else if (existFile(location)) {
+            trinoFileSystem.deleteFile(location);
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean mkdirs(Path path) throws IOException {
+        trinoFileSystem.createDirectory(Location.of(path.toString()));
+        return true;
+    }
+
+    @Override
+    public boolean rename(Path source, Path target) throws IOException {
+        Location sourceLocation = Location.of(source.toString());
+        Location targetLocation = Location.of(target.toString());
+        if (trinoFileSystem.directoryExists(sourceLocation).orElse(false)) {
+            trinoFileSystem.renameDirectory(sourceLocation, targetLocation);
+        } else {
+            trinoFileSystem.renameFile(sourceLocation, targetLocation);
+        }
+        return true;
+    }
+
+    private static boolean checkObjectStore(String scheme) {
+        scheme = scheme.toLowerCase();
+        if (!scheme.startsWith("s3")
+                && !scheme.startsWith("emr")
+                && !scheme.startsWith("oss")
+                && !scheme.startsWith("wasb")) {
+            return scheme.startsWith("http") || scheme.startsWith("ftp");
+        } else {
+            return true;
+        }
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIOLoader.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIOLoader.java
new file mode 100644
index 0000000..e891cfa
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileIOLoader.java
@@ -0,0 +1,47 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.fs.FileIO;
+import org.apache.paimon.fs.FileIOLoader;
+import org.apache.paimon.fs.Path;
+
+import io.trino.filesystem.TrinoFileSystem;
+
+/** Trino file io loader for paimon. */
+public class TrinoFileIOLoader implements FileIOLoader {
+
+    private final TrinoFileSystem trinoFileSystem;
+
+    public TrinoFileIOLoader(TrinoFileSystem trinoFileSystem) {
+        this.trinoFileSystem = trinoFileSystem;
+    }
+
+    @Override
+    public String getScheme() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FileIO load(Path path) {
+        return new TrinoFileIO(trinoFileSystem, path);
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileStatus.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileStatus.java
new file mode 100644
index 0000000..a3fdacf
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoFileStatus.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.trino.fileio;
+
+import org.apache.paimon.fs.FileStatus;
+import org.apache.paimon.fs.Path;
+
+/** File status for trino file. */
+public class TrinoFileStatus implements FileStatus {
+
+    private final long len;
+    private final Path path;
+    private final long modificationTmie;
+
+    public TrinoFileStatus(long len, Path path, long modificationTmie) {
+        this.len = len;
+        this.path = path;
+        this.modificationTmie = modificationTmie;
+    }
+
+    @Override
+    public long getLen() {
+        return len;
+    }
+
+    @Override
+    public boolean isDir() {
+        return false;
+    }
+
+    @Override
+    public Path getPath() {
+        return path;
+    }
+
+    @Override
+    public long getModificationTime() {
+        return modificationTmie;
+    }
+}
diff --git a/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoInputStreamWrapper.java b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoInputStreamWrapper.java
new file mode 100644
index 0000000..c9992f7
--- /dev/null
+++ b/paimon-trino-common/src/main/java/org/apache/paimon/trino/fileio/TrinoInputStreamWrapper.java
@@ -0,0 +1,62 @@
+/*
+ *
+ *  * 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.trino.fileio;
+
+import org.apache.paimon.fs.SeekableInputStream;
+
+import io.trino.filesystem.TrinoInputStream;
+
+import java.io.IOException;
+
+/** Trino input stream wrapper for paimon. */
+public class TrinoInputStreamWrapper extends SeekableInputStream {
+
+    private final TrinoInputStream trinoInputStream;
+
+    public TrinoInputStreamWrapper(TrinoInputStream trinoInputStream) {
+        this.trinoInputStream = trinoInputStream;
+    }
+
+    @Override
+    public void seek(long l) throws IOException {
+        trinoInputStream.seek(l);
+    }
+
+    @Override
+    public long getPos() throws IOException {
+        return trinoInputStream.getPosition();
+    }
+
+    @Override
+    public int read() throws IOException {
+        return trinoInputStream.read();
+    }
+
+    @Override
+    public int read(byte[] bytes, int off, int len) throws IOException {
+        return trinoInputStream.read(bytes, off, len);
+    }
+
+    @Override
+    public void close() throws IOException {
+        trinoInputStream.close();
+    }
+}
diff --git a/paimon-trino-common/src/test/java/org/apache/paimon/trino/SimpleTableTestHelper.java b/paimon-trino-common/src/test/java/org/apache/paimon/trino/SimpleTableTestHelper.java
index 2ef7fc7..5caef5c 100644
--- a/paimon-trino-common/src/test/java/org/apache/paimon/trino/SimpleTableTestHelper.java
+++ b/paimon-trino-common/src/test/java/org/apache/paimon/trino/SimpleTableTestHelper.java
@@ -44,7 +44,7 @@ public class SimpleTableTestHelper {
                                 rowType.getFields(),
                                 Collections.emptyList(),
                                 Collections.singletonList("a"),
-                                Collections.emptyMap(),
+                                Collections.singletonMap("bucket", "1"),
                                 ""));
         FileStoreTable table = FileStoreTableFactory.create(LocalFileIO.create(), path);
         String user = "user";
diff --git a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoDistributedQuery.java b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoDistributedQuery.java
index 548065c..00d5de7 100644
--- a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoDistributedQuery.java
+++ b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoDistributedQuery.java
@@ -262,6 +262,21 @@ public class TestTrinoDistributedQuery extends AbstractDistributedEngineOnlyQuer
         throw new SkipException("TODO: test not implemented yet");
     }
 
+    @Override
+    public void testColumnNames() {
+        throw new SkipException("TODO: test not implemented yet");
+    }
+
+    @Override
+    public void testExplainAnalyzeTopLevelTimes() {
+        throw new SkipException("TODO: test not implemented yet");
+    }
+
+    @Override
+    public void testExplainDistributed() {
+        throw new SkipException("TODO: test not implemented yet");
+    }
+
     @Override
     public void testCorrelationSymbolMapping() {
         throw new SkipException("TODO: test not implemented yet");
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 d70e7ab..14cdeea 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
@@ -27,6 +27,7 @@ import org.apache.paimon.data.Timestamp;
 import org.apache.paimon.fs.Path;
 import org.apache.paimon.fs.local.LocalFileIO;
 import org.apache.paimon.schema.Schema;
+import org.apache.paimon.schema.SchemaChange;
 import org.apache.paimon.schema.SchemaManager;
 import org.apache.paimon.table.FileStoreTable;
 import org.apache.paimon.table.FileStoreTableFactory;
@@ -172,7 +173,7 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                                     rowType.getFields(),
                                     Collections.emptyList(),
                                     Collections.singletonList("i"),
-                                    new HashMap<>(),
+                                    Collections.singletonMap("bucket", "1"),
                                     ""));
             FileStoreTable table = FileStoreTableFactory.create(LocalFileIO.create(), tablePath4);
             InnerTableWrite writer = table.newWrite("user");
@@ -263,7 +264,7 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                                             "timestamp_tz",
                                             "decimal",
                                             "varbinary"),
-                                    Collections.emptyMap(),
+                                    Collections.singletonMap("bucket", "1"),
                                     ""));
             FileStoreTable table = FileStoreTableFactory.create(LocalFileIO.create(), tablePath6);
             InnerTableWrite writer = table.newWrite("user");
@@ -292,6 +293,124 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
             commit.commit(0, writer.prepareCommit(true, 0));
         }
 
+        {
+            Path tablePath7 = new Path(warehouse, "default.db/t100");
+            RowType rowType =
+                    new RowType(
+                            Arrays.asList(
+                                    new DataField(0, "boolean", DataTypes.BOOLEAN()),
+                                    new DataField(1, "tinyint", DataTypes.TINYINT()),
+                                    new DataField(2, "smallint", DataTypes.SMALLINT()),
+                                    new DataField(3, "int", DataTypes.INT()),
+                                    new DataField(4, "bigint", DataTypes.BIGINT()),
+                                    new DataField(5, "float", DataTypes.FLOAT()),
+                                    new DataField(6, "double", DataTypes.DOUBLE()),
+                                    new DataField(7, "char", DataTypes.CHAR(5)),
+                                    new DataField(8, "varchar", DataTypes.VARCHAR(100)),
+                                    new DataField(9, "date", DataTypes.DATE()),
+                                    new DataField(10, "timestamp_0", DataTypes.TIMESTAMP(3)),
+                                    new DataField(11, "timestamp_3", DataTypes.TIMESTAMP(3)),
+                                    new DataField(12, "timestamp_6", DataTypes.TIMESTAMP(6)),
+                                    new DataField(13, "decimal", DataTypes.DECIMAL(10, 5)),
+                                    new DataField(14, "varbinary", DataTypes.VARBINARY(10)),
+                                    new DataField(15, "array", DataTypes.ARRAY(DataTypes.INT())),
+                                    new DataField(
+                                            16,
+                                            "map",
+                                            DataTypes.MAP(DataTypes.INT(), DataTypes.INT())),
+                                    new DataField(
+                                            17,
+                                            "row",
+                                            DataTypes.ROW(
+                                                    DataTypes.FIELD(100, "q1", DataTypes.INT()),
+                                                    DataTypes.FIELD(101, "q2", DataTypes.INT())))));
+            new SchemaManager(LocalFileIO.create(), tablePath7)
+                    .createTable(
+                            new Schema(
+                                    rowType.getFields(),
+                                    Collections.emptyList(),
+                                    Collections.emptyList(),
+                                    Collections.singletonMap("bucket", "-1"),
+                                    ""));
+            FileStoreTable table = FileStoreTableFactory.create(LocalFileIO.create(), tablePath7);
+            InnerTableWrite writer = table.newWrite("user");
+            InnerTableCommit commit = table.newCommit("user");
+            writer.write(
+                    GenericRow.of(
+                            true,
+                            (byte) 1,
+                            (short) 1,
+                            1,
+                            1L,
+                            1.0f,
+                            1.0d,
+                            BinaryString.fromString("char1"),
+                            BinaryString.fromString("varchar1"),
+                            0,
+                            Timestamp.fromMicros(1694505288000000L),
+                            Timestamp.fromMicros(1694505288001000L),
+                            Timestamp.fromMicros(1694505288001001L),
+                            Decimal.fromUnscaledLong(10000, 10, 5),
+                            new byte[] {0x01, 0x02, 0x03},
+                            new GenericArray(new int[] {1, 1, 1}),
+                            new GenericMap(Map.of(1, 1)),
+                            GenericRow.of(1, 1)));
+            commit.commit(0, writer.prepareCommit(true, 0));
+
+            new SchemaManager(LocalFileIO.create(), tablePath7)
+                    .commitChanges(SchemaChange.dropColumn("smallint"));
+            table = FileStoreTableFactory.create(LocalFileIO.create(), tablePath7);
+            writer = table.newWrite("user");
+            commit = table.newCommit("user");
+            writer.write(
+                    GenericRow.of(
+                            true,
+                            (byte) 1,
+                            1,
+                            1L,
+                            1.0f,
+                            1.0d,
+                            BinaryString.fromString("char1"),
+                            BinaryString.fromString("varchar1"),
+                            0,
+                            Timestamp.fromMicros(1694505288000000L),
+                            Timestamp.fromMicros(1694505288001000L),
+                            Timestamp.fromMicros(1694505288001001L),
+                            Decimal.fromUnscaledLong(10000, 10, 5),
+                            new byte[] {0x01, 0x02, 0x03},
+                            new GenericArray(new int[] {1, 1, 1}),
+                            new GenericMap(Map.of(1, 1)),
+                            GenericRow.of(1, 1)));
+            commit.commit(1, writer.prepareCommit(true, 1));
+
+            new SchemaManager(LocalFileIO.create(), tablePath7)
+                    .commitChanges(SchemaChange.addColumn("smallint", DataTypes.SMALLINT()));
+            table = FileStoreTableFactory.create(LocalFileIO.create(), tablePath7);
+            writer = table.newWrite("user");
+            commit = table.newCommit("user");
+            writer.write(
+                    GenericRow.of(
+                            true,
+                            (byte) 1,
+                            1,
+                            1L,
+                            1.0f,
+                            1.0d,
+                            BinaryString.fromString("char1"),
+                            BinaryString.fromString("varchar1"),
+                            0,
+                            Timestamp.fromMicros(1694505288000000L),
+                            Timestamp.fromMicros(1694505288001000L),
+                            Timestamp.fromMicros(1694505288001001L),
+                            Decimal.fromUnscaledLong(10000, 10, 5),
+                            new byte[] {0x01, 0x02, 0x03},
+                            new GenericArray(new int[] {1, 1, 1}),
+                            new GenericMap(Map.of(1, 1)),
+                            GenericRow.of(1, 1),
+                            (short) 1));
+            commit.commit(1, writer.prepareCommit(true, 1));
+        }
+
         DistributedQueryRunner queryRunner = null;
         try {
             queryRunner =
@@ -424,7 +543,7 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                         + "changelog_producer = 'input'"
                         + ")");
         assertThat(sql("SHOW TABLES FROM paimon.default"))
-                .isEqualTo("[[empty_t], [orders], [t1], [t2], [t3], [t4], [t99]]");
+                .isEqualTo("[[empty_t], [orders], [t1], [t100], [t2], [t3], [t4], [t99]]");
         sql("DROP TABLE IF EXISTS paimon.default.orders");
     }
 
@@ -447,7 +566,7 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                         + ")");
         sql("ALTER TABLE paimon.default.t5 RENAME TO t6");
         assertThat(sql("SHOW TABLES FROM paimon.default"))
-                .isEqualTo("[[empty_t], [t1], [t2], [t3], [t4], [t6], [t99]]");
+                .isEqualTo("[[empty_t], [t1], [t100], [t2], [t3], [t4], [t6], [t99]]");
         sql("DROP TABLE IF EXISTS paimon.default.t6");
     }
 
@@ -470,7 +589,7 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                         + ")");
         sql("DROP TABLE IF EXISTS paimon.default.t5");
         assertThat(sql("SHOW TABLES FROM paimon.default"))
-                .isEqualTo("[[empty_t], [t1], [t2], [t3], [t4], [t99]]");
+                .isEqualTo("[[empty_t], [t1], [t100], [t2], [t3], [t4], [t99]]");
     }
 
     @Test
@@ -601,6 +720,18 @@ public abstract class TestTrinoITCase extends AbstractTestQueryFramework {
                 .isEqualTo("[[1, 2, 1, 1], [3, 4, 2, 2], [5, 6, 3, 3], [7, 8, 4, 4]]");
     }
 
+    @Test
+    public void testSchemaEvolution() {
+        assertThat(
+                        sql(
+                                "SELECT boolean, tinyint, smallint, int, bigint,float,double,char,varchar, date,timestamp_0, "
+                                        + "timestamp_3, timestamp_6, decimal, to_hex(varbinary), array, map, row FROM paimon.default.t100"))
+                .isEqualTo(
+                        "[[true, 1, null, 1, 1, 1.0, 1.0, char1, varchar1, 1970-01-01, 2023-09-12T07:54:48, 2023-09-12T07:54:48.001, 2023-09-12T07:54:48.001001, 0.10000, 010203, [1, 1, 1], {1=1}, [1, 1]], "
+                                + "[true, 1, null, 1, 1, 1.0, 1.0, char1, varchar1, 1970-01-01, 2023-09-12T07:54:48, 2023-09-12T07:54:48.001, 2023-09-12T07:54:48.001001, 0.10000, 010203, [1, 1, 1], {1=1}, [1, 1]], "
+                                + "[true, 1, 1, 1, 1, 1.0, 1.0, char1, varchar1, 1970-01-01, 2023-09-12T07:54:48, 2023-09-12T07:54:48.001, 2023-09-12T07:54:48.001001, 0.10000, 010203, [1, 1, 1], {1=1}, [1, 1]]]");
+    }
+
     protected String sql(String sql) {
         MaterializedResult result = getQueryRunner().execute(sql);
         return result.getMaterializedRows().toString();
diff --git a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoTableHandle.java b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoTableHandle.java
index 08986d7..a5fe539 100644
--- a/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoTableHandle.java
+++ b/paimon-trino-common/src/test/java/org/apache/paimon/trino/TestTrinoTableHandle.java
@@ -22,6 +22,7 @@ import io.airlift.json.JsonCodec;
 import io.trino.spi.predicate.TupleDomain;
 import org.junit.jupiter.api.Test;
 
+import java.util.Collections;
 import java.util.Optional;
 import java.util.OptionalLong;
 
@@ -34,12 +35,11 @@ public class TestTrinoTableHandle {
 
     @Test
     public void testPrestoTableHandle() throws Exception {
-        byte[] serializedTable = TrinoTestUtils.getSerializedTable();
         TrinoTableHandle expected =
                 new TrinoTableHandle(
                         "test",
                         "user",
-                        serializedTable,
+                        Collections.emptyMap(),
                         TupleDomain.all(),
                         Optional.empty(),
                         OptionalLong.empty());
@@ -52,7 +52,6 @@ public class TestTrinoTableHandle {
         assertThat(actual).isEqualTo(expected);
         assertThat(actual.getSchemaName()).isEqualTo(expected.getSchemaName());
         assertThat(actual.getTableName()).isEqualTo(expected.getTableName());
-        assertThat(actual.getSerializedTable()).isEqualTo(expected.getSerializedTable());
         assertThat(actual.getFilter()).isEqualTo(expected.getFilter());
         assertThat(actual.getProjectedColumns()).isEqualTo(expected.getProjectedColumns());
     }
diff --git a/pom.xml b/pom.xml
index 87677d5..982d520 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,13 +22,8 @@ under the License.
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <modules>
-        <module>paimon-trino-358</module>
-        <module>paimon-trino-368</module>
-        <module>paimon-trino-369</module>
-        <module>paimon-trino-370</module>
-        <module>paimon-trino-388</module>
-        <module>paimon-trino-393</module>
         <module>paimon-trino-422</module>
+        <module>paimon-trino-427</module>
         <module>paimon-trino-common</module>
     </modules>