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

fanng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 2b8687a2f [#3920] feat(catalog-lakehouse-paimon): Support jdbc backend 
for Paimon Catalog (#5087)
2b8687a2f is described below

commit 2b8687a2fcec48863efcb99a0ef5478a0fd9ae3f
Author: cai can <[email protected]>
AuthorDate: Sun Oct 13 23:21:48 2024 -0700

    [#3920] feat(catalog-lakehouse-paimon): Support jdbc backend for Paimon 
Catalog (#5087)
    
    ### What changes were proposed in this pull request?
    
    Support jdbc backend for Paimon Catalog
    
    ### Why are the changes needed?
    
    Fix: https://github.com/apache/gravitino/issues/3920
    
    ### Does this PR introduce _any_ user-facing change?
    yes, updated the related doc.
    
    ### How was this patch tested?
    new UT and IT.
    
    ---------
    
    Co-authored-by: caican <[email protected]>
---
 catalogs/catalog-lakehouse-paimon/build.gradle.kts |  2 +
 .../lakehouse/paimon/PaimonCatalogBackend.java     |  3 +-
 .../paimon/PaimonCatalogPropertiesMetadata.java    | 30 ++++++++++++++-
 .../catalog/lakehouse/paimon/PaimonConfig.java     | 16 ++++++++
 .../integration/test/CatalogPaimonBaseIT.java      | 44 ++++++++++++++--------
 .../test/CatalogPaimonFileSystemIT.java            | 25 ++++++++++++
 ...nFileSystemIT.java => CatalogPaimonJdbcIT.java} | 12 +++++-
 .../lakehouse/paimon/utils/TestCatalogUtils.java   |  9 ++++-
 docs/lakehouse-paimon-catalog.md                   | 19 ++++++++--
 9 files changed, 135 insertions(+), 25 deletions(-)

diff --git a/catalogs/catalog-lakehouse-paimon/build.gradle.kts 
b/catalogs/catalog-lakehouse-paimon/build.gradle.kts
index 8fee91745..16a3382cf 100644
--- a/catalogs/catalog-lakehouse-paimon/build.gradle.kts
+++ b/catalogs/catalog-lakehouse-paimon/build.gradle.kts
@@ -122,6 +122,7 @@ dependencies {
   testImplementation(libs.junit.jupiter.api)
   testImplementation(libs.mysql.driver)
   testImplementation(libs.postgresql.driver)
+  testImplementation(libs.h2db)
   testImplementation(libs.bundles.log4j)
   testImplementation(libs.junit.jupiter.params)
   testImplementation(libs.paimon.oss)
@@ -129,6 +130,7 @@ dependencies {
   testImplementation(libs.paimon.spark)
   testImplementation(libs.testcontainers)
   testImplementation(libs.testcontainers.localstack)
+  testImplementation(libs.testcontainers.mysql)
 
   testRuntimeOnly(libs.junit.jupiter.engine)
 }
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogBackend.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogBackend.java
index 32effe452..355a79f58 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogBackend.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogBackend.java
@@ -20,5 +20,6 @@ package org.apache.gravitino.catalog.lakehouse.paimon;
 
 /** The type of Apache Paimon catalog backend. */
 public enum PaimonCatalogBackend {
-  FILESYSTEM
+  FILESYSTEM,
+  JDBC
 }
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogPropertiesMetadata.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogPropertiesMetadata.java
index 0c6a87c02..78a7eb1eb 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogPropertiesMetadata.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogPropertiesMetadata.java
@@ -49,6 +49,10 @@ public class PaimonCatalogPropertiesMetadata extends 
BaseCatalogPropertiesMetada
   public static final String PAIMON_METASTORE = "metastore";
   public static final String WAREHOUSE = "warehouse";
   public static final String URI = "uri";
+  public static final String GRAVITINO_JDBC_USER = "jdbc-user";
+  public static final String PAIMON_JDBC_USER = "jdbc.user";
+  public static final String GRAVITINO_JDBC_PASSWORD = "jdbc-password";
+  public static final String PAIMON_JDBC_PASSWORD = "jdbc.password";
 
   // S3 properties needed by Paimon
   public static final String S3_ENDPOINT = "s3.endpoint";
@@ -56,7 +60,17 @@ public class PaimonCatalogPropertiesMetadata extends 
BaseCatalogPropertiesMetada
   public static final String S3_SECRET_KEY = "s3.secret-key";
 
   public static final Map<String, String> GRAVITINO_CONFIG_TO_PAIMON =
-      ImmutableMap.of(GRAVITINO_CATALOG_BACKEND, PAIMON_METASTORE, WAREHOUSE, 
WAREHOUSE, URI, URI);
+      ImmutableMap.of(
+          GRAVITINO_CATALOG_BACKEND,
+          PAIMON_METASTORE,
+          WAREHOUSE,
+          WAREHOUSE,
+          URI,
+          URI,
+          GRAVITINO_JDBC_USER,
+          PAIMON_JDBC_USER,
+          GRAVITINO_JDBC_PASSWORD,
+          PAIMON_JDBC_PASSWORD);
   private static final Map<String, PropertyEntry<?>> PROPERTIES_METADATA;
   public static final Map<String, String> KERBEROS_CONFIGURATION =
       ImmutableMap.of(
@@ -105,7 +119,19 @@ public class PaimonCatalogPropertiesMetadata extends 
BaseCatalogPropertiesMetada
                 "Paimon catalog uri config",
                 false /* immutable */,
                 null /* defaultValue */,
-                false /* hidden */));
+                false /* hidden */),
+            stringOptionalPropertyEntry(
+                GRAVITINO_JDBC_USER,
+                "Gravitino Paimon catalog jdbc user",
+                false /* immutable */,
+                null /* defaultValue */,
+                true /* hidden */),
+            stringOptionalPropertyEntry(
+                GRAVITINO_JDBC_PASSWORD,
+                "Gravitino Paimon catalog jdbc password",
+                false /* immutable */,
+                null /* defaultValue */,
+                true /* hidden */));
     HashMap<String, PropertyEntry<?>> result = Maps.newHashMap();
     result.putAll(Maps.uniqueIndex(propertyEntries, PropertyEntry::getName));
     result.putAll(KerberosConfig.KERBEROS_PROPERTY_ENTRIES);
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConfig.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConfig.java
index 71b6292d1..97adfeb51 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConfig.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConfig.java
@@ -50,6 +50,22 @@ public class PaimonConfig extends Config {
           .stringConf()
           .create();
 
+  public static final ConfigEntry<String> CATALOG_JDBC_USER =
+      new ConfigBuilder(PaimonCatalogPropertiesMetadata.GRAVITINO_JDBC_USER)
+          .doc("Paimon catalog jdbc user")
+          .version(ConfigConstants.VERSION_0_7_0)
+          .stringConf()
+          .checkValue(StringUtils::isNotBlank, 
ConfigConstants.NOT_BLANK_ERROR_MSG)
+          .create();
+
+  public static final ConfigEntry<String> CATALOG_JDBC_PASSWORD =
+      new 
ConfigBuilder(PaimonCatalogPropertiesMetadata.GRAVITINO_JDBC_PASSWORD)
+          .doc("Paimon catalog jdbc password")
+          .version(ConfigConstants.VERSION_0_7_0)
+          .stringConf()
+          .checkValue(StringUtils::isNotBlank, 
ConfigConstants.NOT_BLANK_ERROR_MSG)
+          .create();
+
   public PaimonConfig() {
     super(false);
   }
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
index b5ac224d9..5cb04e6a3 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
@@ -51,8 +51,10 @@ import org.apache.gravitino.exceptions.NoSuchSchemaException;
 import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
 import org.apache.gravitino.exceptions.TableAlreadyExistsException;
 import org.apache.gravitino.integration.test.container.ContainerSuite;
+import org.apache.gravitino.integration.test.container.MySQLContainer;
 import org.apache.gravitino.integration.test.util.AbstractIT;
 import org.apache.gravitino.integration.test.util.GravitinoITUtils;
+import org.apache.gravitino.integration.test.util.TestDatabaseName;
 import org.apache.gravitino.rel.Column;
 import org.apache.gravitino.rel.Table;
 import org.apache.gravitino.rel.TableCatalog;
@@ -87,12 +89,23 @@ import org.junit.platform.commons.util.StringUtils;
 public abstract class CatalogPaimonBaseIT extends AbstractIT {
 
   protected static final ContainerSuite containerSuite = 
ContainerSuite.getInstance();
+  protected static final TestDatabaseName TEST_DB_NAME =
+      TestDatabaseName.PG_TEST_ICEBERG_CATALOG_MULTIPLE_JDBC_LOAD;
+  protected static MySQLContainer mySQLContainer;
   protected String WAREHOUSE;
   protected String TYPE;
+  protected String URI;
+  protected String jdbcUser;
+  protected String jdbcPassword;
+  protected Catalog catalog;
+  protected org.apache.paimon.catalog.Catalog paimonCatalog;
+  protected String metalakeName = 
GravitinoITUtils.genRandomName("paimon_it_metalake");
+  protected String catalogName = 
GravitinoITUtils.genRandomName("paimon_it_catalog");
+  protected String schemaName = 
GravitinoITUtils.genRandomName("paimon_it_schema");
+  protected static final String schema_comment = "schema_comment";
 
   private static final String provider = "lakehouse-paimon";
   private static final String catalog_comment = "catalog_comment";
-  private static final String schema_comment = "schema_comment";
   private static final String table_comment = "table_comment";
   private static final String PAIMON_COL_NAME1 = "paimon_col_name1";
   private static final String PAIMON_COL_NAME2 = "paimon_col_name2";
@@ -100,15 +113,9 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
   private static final String PAIMON_COL_NAME4 = "paimon_col_name4";
   private static final String PAIMON_COL_NAME5 = "paimon_col_name5";
   private static final String alertTableName = "alert_table_name";
-  private String metalakeName = 
GravitinoITUtils.genRandomName("paimon_it_metalake");
-  private String catalogName = 
GravitinoITUtils.genRandomName("paimon_it_catalog");
-  private String schemaName = 
GravitinoITUtils.genRandomName("paimon_it_schema");
-  private String tableName = GravitinoITUtils.genRandomName("paimon_it_table");
   private static String INSERT_BATCH_WITHOUT_PARTITION_TEMPLATE = "INSERT INTO 
paimon.%s VALUES %s";
   private static final String SELECT_ALL_TEMPLATE = "SELECT * FROM paimon.%s";
   private GravitinoMetalake metalake;
-  private Catalog catalog;
-  private org.apache.paimon.catalog.Catalog paimonCatalog;
   protected SparkSession spark;
   private Map<String, String> catalogProperties;
 
@@ -163,9 +170,7 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
 
     // load schema check.
     Schema schema = schemas.loadSchema(schemaIdent.name());
-    // database properties is empty for Paimon FilesystemCatalog.
-    Assertions.assertTrue(schema.properties().isEmpty());
-    
Assertions.assertTrue(paimonCatalog.loadDatabaseProperties(schemaIdent.name()).isEmpty());
+    Assertions.assertEquals(testSchemaName, schema.name());
 
     Map<String, String> emptyMap = Collections.emptyMap();
     Assertions.assertThrows(
@@ -202,6 +207,7 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
 
   @Test
   void testCreateTableWithNullComment() {
+    String tableName = 
GravitinoITUtils.genRandomName("paimon_table_with_null_comment");
     Column[] columns = createColumns();
     NameIdentifier tableIdentifier = NameIdentifier.of(schemaName, tableName);
 
@@ -217,6 +223,8 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
   @Test
   void testCreateAndLoadPaimonTable()
       throws org.apache.paimon.catalog.Catalog.TableNotExistException {
+    String tableName = 
GravitinoITUtils.genRandomName("create_and_load_paimon_table");
+
     // Create table from Gravitino API
     Column[] columns = createColumns();
 
@@ -301,6 +309,8 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
   @Test
   void testCreateAndLoadPaimonPartitionedTable()
       throws org.apache.paimon.catalog.Catalog.TableNotExistException {
+    String tableName = 
GravitinoITUtils.genRandomName("create_and_load_paimon_partitioned_table");
+
     // Create table from Gravitino API
     Column[] columns = createColumns();
 
@@ -390,6 +400,8 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
   @Test
   void testCreateAndLoadPaimonPrimaryKeyTable()
       throws org.apache.paimon.catalog.Catalog.TableNotExistException {
+    String tableName = 
GravitinoITUtils.genRandomName("create_and_load_paimon_primary_key_table");
+
     // Create table from Gravitino API
     Column[] columns = createColumns();
     ArrayList<Column> newColumns = new ArrayList<>(Arrays.asList(columns));
@@ -615,6 +627,8 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
 
   @Test
   public void testAlterPaimonTable() {
+    String tableName = GravitinoITUtils.genRandomName("alter_paimon_table");
+
     Column[] columns = createColumns();
     catalog
         .asTableCatalog()
@@ -716,7 +730,7 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
 
     Column[] newColumns = new Column[] {col1, col2, col3};
     NameIdentifier tableIdentifier =
-        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("PaimonAlterTableIT"));
+        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("new_alter_paimon_table"));
     catalog
         .asTableCatalog()
         .createTable(
@@ -857,9 +871,9 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
   }
 
   private void clearTableAndSchema() {
-    if (catalog.asSchemas().schemaExists(schemaName)) {
-      catalog.asSchemas().dropSchema(schemaName, true);
-    }
+    SupportsSchemas supportsSchema = catalog.asSchemas();
+    Arrays.stream(supportsSchema.listSchemas())
+        .forEach(schema -> supportsSchema.dropSchema(schema, true));
   }
 
   private void createMetalake() {
@@ -903,10 +917,8 @@ public abstract class CatalogPaimonBaseIT extends 
AbstractIT {
     prop.put("key2", "val2");
 
     Schema createdSchema = catalog.asSchemas().createSchema(ident.name(), 
schema_comment, prop);
-    // database properties is empty for Paimon FilesystemCatalog.
     Schema loadSchema = catalog.asSchemas().loadSchema(ident.name());
     Assertions.assertEquals(createdSchema.name(), loadSchema.name());
-    Assertions.assertTrue(loadSchema.properties().isEmpty());
   }
 
   private Column[] createColumns() {
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
index c4717b43e..5c7c67acc 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
@@ -20,9 +20,16 @@ package 
org.apache.gravitino.catalog.lakehouse.paimon.integration.test;
 
 import com.google.common.collect.Maps;
 import java.util.Map;
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.Schema;
+import org.apache.gravitino.SupportsSchemas;
 import 
org.apache.gravitino.catalog.lakehouse.paimon.PaimonCatalogPropertiesMetadata;
 import org.apache.gravitino.integration.test.container.HiveContainer;
+import org.apache.gravitino.integration.test.util.GravitinoITUtils;
+import org.apache.paimon.catalog.Catalog;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
 
 @Tag("gravitino-docker-test")
@@ -48,4 +55,22 @@ public class CatalogPaimonFileSystemIT extends 
CatalogPaimonBaseIT {
 
     return catalogProperties;
   }
+
+  @Test
+  void testPaimonSchemaProperties() throws Catalog.DatabaseNotExistException {
+    SupportsSchemas schemas = catalog.asSchemas();
+
+    // create schema.
+    String testSchemaName = GravitinoITUtils.genRandomName("test_schema_1");
+    NameIdentifier schemaIdent = NameIdentifier.of(metalakeName, catalogName, 
testSchemaName);
+    Map<String, String> schemaProperties = Maps.newHashMap();
+    schemaProperties.put("key1", "val1");
+    schemaProperties.put("key2", "val2");
+    schemas.createSchema(schemaIdent.name(), schema_comment, schemaProperties);
+
+    // load schema check, database properties is empty for Paimon 
FilesystemCatalog.
+    Schema schema = schemas.loadSchema(schemaIdent.name());
+    Assertions.assertTrue(schema.properties().isEmpty());
+    
Assertions.assertTrue(paimonCatalog.loadDatabaseProperties(schemaIdent.name()).isEmpty());
+  }
 }
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
similarity index 76%
copy from 
catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
copy to 
catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
index c4717b43e..d252b901d 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonFileSystemIT.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
@@ -27,24 +27,32 @@ import org.junit.jupiter.api.TestInstance;
 
 @Tag("gravitino-docker-test")
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class CatalogPaimonFileSystemIT extends CatalogPaimonBaseIT {
+public class CatalogPaimonJdbcIT extends CatalogPaimonBaseIT {
 
   @Override
   protected Map<String, String> initPaimonCatalogProperties() {
+    containerSuite.startMySQLContainer(TEST_DB_NAME);
+    mySQLContainer = containerSuite.getMySQLContainer();
 
     Map<String, String> catalogProperties = Maps.newHashMap();
     catalogProperties.put("key1", "val1");
     catalogProperties.put("key2", "val2");
 
-    TYPE = "filesystem";
+    TYPE = "jdbc";
     WAREHOUSE =
         String.format(
             "hdfs://%s:%d/user/hive/warehouse-catalog-paimon/",
             containerSuite.getHiveContainer().getContainerIpAddress(),
             HiveContainer.HDFS_DEFAULTFS_PORT);
+    URI = mySQLContainer.getJdbcUrl(TEST_DB_NAME);
+    jdbcUser = mySQLContainer.getUsername();
+    jdbcPassword = mySQLContainer.getPassword();
 
     
catalogProperties.put(PaimonCatalogPropertiesMetadata.GRAVITINO_CATALOG_BACKEND,
 TYPE);
     catalogProperties.put(PaimonCatalogPropertiesMetadata.WAREHOUSE, 
WAREHOUSE);
+    catalogProperties.put(PaimonCatalogPropertiesMetadata.URI, URI);
+    catalogProperties.put(PaimonCatalogPropertiesMetadata.GRAVITINO_JDBC_USER, 
jdbcUser);
+    
catalogProperties.put(PaimonCatalogPropertiesMetadata.GRAVITINO_JDBC_PASSWORD, 
jdbcPassword);
 
     return catalogProperties;
   }
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/TestCatalogUtils.java
 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/TestCatalogUtils.java
index 8072c1654..e8fe66551 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/TestCatalogUtils.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/TestCatalogUtils.java
@@ -32,6 +32,7 @@ import 
org.apache.gravitino.catalog.lakehouse.paimon.PaimonConfig;
 import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.FileSystemCatalog;
 import org.apache.paimon.factories.FactoryException;
+import org.apache.paimon.jdbc.JdbcCatalog;
 import org.junit.jupiter.api.Test;
 
 /** Tests for {@link 
org.apache.gravitino.catalog.lakehouse.paimon.utils.CatalogUtils}. */
@@ -41,6 +42,8 @@ public class TestCatalogUtils {
   void testLoadCatalogBackend() throws Exception {
     // Test load FileSystemCatalog for filesystem metastore.
     assertCatalog(PaimonCatalogBackend.FILESYSTEM.name(), 
FileSystemCatalog.class);
+    // Test load JdbcCatalog for jdbc metastore.
+    assertCatalog(PaimonCatalogBackend.JDBC.name(), JdbcCatalog.class);
     // Test load catalog exception for other metastore.
     assertThrowsExactly(FactoryException.class, () -> assertCatalog("other", 
catalog -> {}));
   }
@@ -63,7 +66,11 @@ public class TestCatalogUtils {
                             System.getProperty("java.io.tmpdir"),
                             "paimon_catalog_warehouse"),
                         PaimonConfig.CATALOG_URI.getKey(),
-                        "uri")))
+                        "jdbc:h2:mem:testdb",
+                        PaimonConfig.CATALOG_JDBC_USER.getKey(),
+                        "user",
+                        PaimonConfig.CATALOG_JDBC_PASSWORD.getKey(),
+                        "password")))
             .getCatalog()) {
       consumer.accept(catalog);
     }
diff --git a/docs/lakehouse-paimon-catalog.md b/docs/lakehouse-paimon-catalog.md
index 2a8226668..4c336f3d3 100644
--- a/docs/lakehouse-paimon-catalog.md
+++ b/docs/lakehouse-paimon-catalog.md
@@ -22,17 +22,17 @@ Builds with Apache Paimon `0.8.0`.
 
 ### Catalog capabilities
 
-- Works as a catalog proxy, supporting `FilesystemCatalog`.
+- Works as a catalog proxy, supporting `FilesystemCatalog` and `JdbcCatalog`.
 - Supports DDL operations for Paimon schemas and tables.
 
-- Doesn't support `JdbcCatalog` and `HiveCatalog` catalog backend now.
+- Doesn't support `HiveCatalog` catalog backend now.
 - Doesn't support alterSchema.
 
 ### Catalog properties
 
 | Property name                                      | Description             
                                                                                
                                                                                
                    | Default value          | Required                         
                               | Since Version     |
 
|----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-----------------------------------------------------------------|-------------------|
-| `catalog-backend`                                  | Catalog backend of 
Gravitino Paimon catalog. Only supports `filesystem` now.                       
                                                                                
                         | (none)                 | Yes                         
                                    | 0.6.0-incubating  |
+| `catalog-backend`                                  | Catalog backend of 
Gravitino Paimon catalog. Supports `filesystem` and `jdbc` now.                 
                                                                                
                         | (none)                 | Yes                         
                                    | 0.6.0-incubating  |
 | `uri`                                              | The URI configuration 
of the Paimon catalog. `thrift://127.0.0.1:9083` or 
`jdbc:postgresql://127.0.0.1:5432/db_name` or 
`jdbc:mysql://127.0.0.1:3306/metastore_db`. It is optional for 
`FilesystemCatalog`. | (none)                 | required if the value of 
`catalog-backend` is not `filesystem`. | 0.6.0-incubating  |
 | `warehouse`                                        | Warehouse directory of 
catalog. `file:///user/hive/warehouse-paimon/` for local fs, 
`hdfs://namespace/hdfs/path` for HDFS , `s3://{bucket-name}/path/` for S3 or 
`oss://{bucket-name}/path` for Aliyun OSS  | (none)                 | Yes       
                                                      | 0.6.0-incubating  |
 | `authentication.type`                              | The type of 
authentication for Paimon catalog backend, currently Gravitino only supports 
`Kerberos` and `simple`.                                                        
                                   | `simple`               | No                
                                              | 0.6.0-incubating  |
@@ -54,6 +54,19 @@ If you want to use the `oss` or `s3` warehouse, you need to 
place related jars i
 
 Any properties not defined by Gravitino with `gravitino.bypass.` prefix will 
pass to Paimon catalog properties and HDFS configuration. For example, if 
specify `gravitino.bypass.table.type`, `table.type` will pass to Paimon catalog 
properties.
 
+#### JDBC backend
+
+If you are using JDBC backend, you must specify the properties like 
`jdbc-user` and `jdbc-password`.
+
+| Property name   | Description                                                
                                                                                
                                                                 | Default 
value          | Required                                                       
 | Since Version      |
+|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-----------------------------------------------------------------|--------------------|
+| `jdbc-user`     | Jdbc user of Gravitino Paimon catalog for `jdbc` backend.  
                                                                                
                                                                 | (none)       
          | required if the value of `catalog-backend` is `jdbc`.           | 
0.7.0-incubating   |
+| `jdbc-password` | Jdbc password of Gravitino Paimon catalog for `jdbc` 
backend.                                                                        
                                                                       | (none) 
                | required if the value of `catalog-backend` is `jdbc`.         
  | 0.7.0-incubating   |
+
+:::caution
+You must download the corresponding JDBC driver and place it to the 
`catalogs/lakehouse-paimon/libs` directory If you are using JDBC backend.
+:::
+
 ### Catalog operations
 
 Please refer to [Manage Relational Metadata Using 
Gravitino](./manage-relational-metadata-using-gravitino.md#catalog-operations) 
for more details.

Reply via email to