This is an automated email from the ASF dual-hosted git repository.
jshao 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 f1a40a7dbb [#9754] feat(clickhouse): Add schema operations for
ClickHouse catalog (#9761)
f1a40a7dbb is described below
commit f1a40a7dbb67b9b328a4f78f580cc88170e29c12
Author: Qi Yu <[email protected]>
AuthorDate: Sat Jan 31 02:45:57 2026 +0800
[#9754] feat(clickhouse): Add schema operations for ClickHouse catalog
(#9761)
### What changes were proposed in this pull request?
This PR adds support for schema operations.
### Why are the changes needed?
It's a need from the user community.
Fix: #9754
### Does this PR introduce _any_ user-facing change?
N/A
### How was this patch tested?
UTs
---
.github/workflows/build.yml | 1 +
.../catalog/clickhouse/ClickHouseCatalog.java | 11 ++++
.../clickhouse/ClickHouseCatalogCapability.java | 61 +++++++++++++------
...va => ClickHouseCatalogPropertiesMetadata.java} | 21 ++++++-
.../catalog/clickhouse/ClickHouseConfig.java | 57 ++++++++++++++++++
...logCapability.java => ClickHouseConstants.java} | 10 +++-
.../ClickHouseSchemaPropertiesMetadata.java | 57 ++++++++++++++++++
.../converter/ClickHouseExceptionConverter.java | 30 +++++++++-
.../operations/ClickHouseDatabaseOperations.java | 65 +++++++++++++++++++-
.../TestClickHouseCatalogPropertiesMeta.java} | 19 ++++--
.../TestClickHouseSchemaPropertiesMetadata.java | 45 ++++++++++++++
.../TestClickHouseDatabaseOperations.java | 69 ++++++++++++++++++++++
12 files changed, 414 insertions(+), 32 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c3408c0824..0032e7ac7e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -25,6 +25,7 @@ jobs:
source_changes:
- '.github/**'
- 'catalogs/**'
+ - 'catalogs-contrib/**'
- 'clients/**'
- 'conf/**'
- 'dev/**'
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalog.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalog.java
index 8d547c2aa0..03d9650d58 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalog.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalog.java
@@ -29,6 +29,7 @@ import
org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
import org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter;
import org.apache.gravitino.catalog.jdbc.operation.JdbcDatabaseOperations;
import org.apache.gravitino.catalog.jdbc.operation.JdbcTableOperations;
+import org.apache.gravitino.connector.PropertiesMetadata;
import org.apache.gravitino.connector.capability.Capability;
public class ClickHouseCatalog extends JdbcCatalog {
@@ -67,4 +68,14 @@ public class ClickHouseCatalog extends JdbcCatalog {
public Capability newCapability() {
return new ClickHouseCatalogCapability();
}
+
+ @Override
+ public PropertiesMetadata catalogPropertiesMetadata() throws
UnsupportedOperationException {
+ return new ClickHouseCatalogPropertiesMetadata();
+ }
+
+ @Override
+ public PropertiesMetadata schemaPropertiesMetadata() throws
UnsupportedOperationException {
+ return new ClickHouseSchemaPropertiesMetadata();
+ }
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
index 8ce7478945..ad0030b7b6 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
@@ -1,26 +1,51 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.gravitino.catalog.clickhouse;
-import org.apache.gravitino.catalog.jdbc.JdbcCatalogCapability;
+import org.apache.gravitino.connector.capability.Capability;
+import org.apache.gravitino.connector.capability.CapabilityResult;
+
+public class ClickHouseCatalogCapability implements Capability {
+ /**
+ * Regular expression explanation: ^[\w\p{L}-$/=]{1,64}$
+ *
+ * <p>^ - Start of the string
+ *
+ * <p>[\w\p{L}-$/=]{1,64} - Consist of 1 to 64 characters of letters (both
cases), digits,
+ * underscores, any kind of letter from any language, hyphens, dollar signs,
slashes or equal
+ * signs
+ *
+ * <p>\w - matches [a-zA-Z0-9_]
+ *
+ * <p>\p{L} - matches any kind of letter from any language
+ *
+ * <p>$ - End of the string
+ */
+ public static final String CLICKHOUSE_NAME_PATTERN =
"^[\\w\\p{L}-$/=]{1,64}$";
-public class ClickHouseCatalogCapability extends JdbcCatalogCapability {
- // No additional capabilities for ClickHouse at this time
+ @Override
+ public CapabilityResult specificationOnName(Scope scope, String name) {
+ // TODO(yuqi): Validate the name against reserved words
+ if (!name.matches(CLICKHOUSE_NAME_PATTERN)) {
+ return CapabilityResult.unsupported(
+ String.format("The %s name '%s' is illegal.", scope, name));
+ }
+ return CapabilityResult.SUPPORTED;
+ }
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogPropertiesMetadata.java
similarity index 53%
copy from
catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
copy to
catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogPropertiesMetadata.java
index 8ce7478945..43a3079ff6 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogPropertiesMetadata.java
@@ -19,8 +19,23 @@
package org.apache.gravitino.catalog.clickhouse;
-import org.apache.gravitino.catalog.jdbc.JdbcCatalogCapability;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.apache.gravitino.catalog.jdbc.JdbcCatalogPropertiesMetadata;
+import org.apache.gravitino.connector.PropertyEntry;
-public class ClickHouseCatalogCapability extends JdbcCatalogCapability {
- // No additional capabilities for ClickHouse at this time
+public class ClickHouseCatalogPropertiesMetadata extends
JdbcCatalogPropertiesMetadata {
+
+ private static final Map<String, PropertyEntry<?>> PROPERTIES_METADATA =
ImmutableMap.of();
+
+ @Override
+ protected Map<String, PropertyEntry<?>> specificPropertyEntries() {
+ Map<String, PropertyEntry<?>> superMap = super.specificPropertyEntries();
+ ImmutableMap<String, PropertyEntry<?>> result =
+ new ImmutableMap.Builder<String, PropertyEntry<?>>()
+ .putAll(superMap)
+ .putAll(PROPERTIES_METADATA)
+ .build();
+ return result;
+ }
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConfig.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConfig.java
new file mode 100644
index 0000000000..83e99fc0ca
--- /dev/null
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConfig.java
@@ -0,0 +1,57 @@
+/*
+ * 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.gravitino.catalog.clickhouse;
+
+import static
org.apache.gravitino.catalog.clickhouse.ClickHouseConstants.CLUSTER_NAME;
+import static
org.apache.gravitino.catalog.clickhouse.ClickHouseConstants.CLUSTER_SHARDING_KEY;
+import static
org.apache.gravitino.catalog.clickhouse.ClickHouseConstants.ON_CLUSTER;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.gravitino.config.ConfigBuilder;
+import org.apache.gravitino.config.ConfigConstants;
+import org.apache.gravitino.config.ConfigEntry;
+
+public class ClickHouseConfig {
+
+ public static final boolean DEFAULT_CK_ON_CLUSTER = false;
+
+ // Constants part
+ public static final ConfigEntry<String> CK_CLUSTER_NAME =
+ new ConfigBuilder(CLUSTER_NAME)
+ .doc("Cluster name for ClickHouse distributed tables")
+ .version(ConfigConstants.VERSION_1_2_0)
+ .stringConf()
+ .checkValue(StringUtils::isNotEmpty, "Cluster name cannot be empty")
+ .create();
+
+ public static final ConfigEntry<Boolean> CK_ON_CLUSTER =
+ new ConfigBuilder(ON_CLUSTER)
+ .doc("Whether to use 'ON CLUSTER' clause when creating tables in
ClickHouse")
+ .version(ConfigConstants.VERSION_1_2_0)
+ .booleanConf()
+ .createWithDefault(DEFAULT_CK_ON_CLUSTER);
+
+ public static final ConfigEntry<String> CK_CLUSTER_SHARDING_KEY =
+ new ConfigBuilder(CLUSTER_SHARDING_KEY)
+ .doc("Sharding key for ClickHouse distributed tables")
+ .version(ConfigConstants.VERSION_1_2_0)
+ .stringConf()
+ .create();
+}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConstants.java
similarity index 70%
copy from
catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
copy to
catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConstants.java
index 8ce7478945..fab6db164b 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseConstants.java
@@ -19,8 +19,12 @@
package org.apache.gravitino.catalog.clickhouse;
-import org.apache.gravitino.catalog.jdbc.JdbcCatalogCapability;
+public class ClickHouseConstants {
-public class ClickHouseCatalogCapability extends JdbcCatalogCapability {
- // No additional capabilities for ClickHouse at this time
+ // Name of the clickhouse cluster
+ public static final String CLUSTER_NAME = "cluster-name";
+ // Whether to use 'ON CLUSTER' clause when creating tables
+ public static final String ON_CLUSTER = "on-cluster";
+ // Sharding key for the clickhouse cluster
+ public static final String CLUSTER_SHARDING_KEY = "cluster-sharding-key";
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseSchemaPropertiesMetadata.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseSchemaPropertiesMetadata.java
new file mode 100644
index 0000000000..3ef74118b5
--- /dev/null
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseSchemaPropertiesMetadata.java
@@ -0,0 +1,57 @@
+/*
+ * 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.gravitino.catalog.clickhouse;
+
+import static
org.apache.gravitino.connector.PropertyEntry.booleanPropertyEntry;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+import org.apache.gravitino.catalog.jdbc.JdbcSchemaPropertiesMetadata;
+import org.apache.gravitino.connector.PropertyEntry;
+
+public class ClickHouseSchemaPropertiesMetadata extends
JdbcSchemaPropertiesMetadata {
+ private static final Map<String, PropertyEntry<?>> PROPERTIES_METADATA;
+
+ static {
+ List<PropertyEntry<?>> propertyEntries =
+ ImmutableList.of(
+ booleanPropertyEntry(
+ ClickHouseConfig.CK_ON_CLUSTER.getKey(),
+ ClickHouseConfig.CK_ON_CLUSTER.getDoc(),
+ false /* required */,
+ false /* immutable */,
+ false /* defaultValue */,
+ false /* hidden */,
+ false /* reserved */));
+ PROPERTIES_METADATA = Maps.uniqueIndex(propertyEntries,
PropertyEntry::getName);
+ }
+
+ @Override
+ public Map<String, PropertyEntry<?>> propertyEntries() {
+ Map<String, PropertyEntry<?>> stringPropertyEntryMap =
super.propertyEntries();
+ return new ImmutableMap.Builder<String, PropertyEntry<?>>()
+ .putAll(stringPropertyEntryMap)
+ .putAll(PROPERTIES_METADATA)
+ .build();
+ }
+}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseExceptionConverter.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseExceptionConverter.java
index 5da5170dd9..c78ab9cb1c 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseExceptionConverter.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseExceptionConverter.java
@@ -18,8 +18,36 @@
*/
package org.apache.gravitino.catalog.clickhouse.converter;
+import java.sql.SQLException;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.apache.gravitino.exceptions.GravitinoRuntimeException;
+import org.apache.gravitino.exceptions.NoSuchSchemaException;
+import org.apache.gravitino.exceptions.NoSuchTableException;
+import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
+import org.apache.gravitino.exceptions.TableAlreadyExistsException;
public class ClickHouseExceptionConverter extends JdbcExceptionConverter {
- // Implement ClickHouse specific exception conversions if needed
+ static final int ERROR_CODE_UNKNOWN_DATABASE = 81;
+ static final int ERROR_CODE_DATABASE_ALREADY_EXISTS = 82;
+
+ static final int ERROR_CODE_TABLE_ALREADY_EXISTS = 57;
+ static final int ERROR_CODE_TABLE_IS_DROPPED = 218;
+
+ @SuppressWarnings("FormatStringAnnotation")
+ @Override
+ public GravitinoRuntimeException toGravitinoException(SQLException
sqlException) {
+ int errorCode = sqlException.getErrorCode();
+ switch (errorCode) {
+ case ERROR_CODE_DATABASE_ALREADY_EXISTS:
+ return new SchemaAlreadyExistsException(sqlException,
sqlException.getMessage());
+ case ERROR_CODE_TABLE_ALREADY_EXISTS:
+ return new TableAlreadyExistsException(sqlException,
sqlException.getMessage());
+ case ERROR_CODE_UNKNOWN_DATABASE:
+ return new NoSuchSchemaException(sqlException,
sqlException.getMessage());
+ case ERROR_CODE_TABLE_IS_DROPPED:
+ return new NoSuchTableException(sqlException,
sqlException.getMessage());
+ default:
+ return new GravitinoRuntimeException(sqlException,
sqlException.getMessage());
+ }
+ }
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/operations/ClickHouseDatabaseOperations.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/operations/ClickHouseDatabaseOperations.java
index bc0569bea7..a3902ba1f6 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/operations/ClickHouseDatabaseOperations.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/operations/ClickHouseDatabaseOperations.java
@@ -18,19 +18,78 @@
*/
package org.apache.gravitino.catalog.clickhouse.operations;
-import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.gravitino.StringIdentifier;
import org.apache.gravitino.catalog.jdbc.operation.JdbcDatabaseOperations;
public class ClickHouseDatabaseOperations extends JdbcDatabaseOperations {
+ private static final Set<String> CLICK_HOUSE_SYSTEM_DATABASES =
+ ImmutableSet.of("information_schema", "default", "system",
"INFORMATION_SCHEMA");
+
+ // TODO: handle ClickHouse cluster properly when creating/dropping
databases/tables
+ // use https://github.com/apache/gravitino/issues/9820 to track it.
+
@Override
protected boolean supportSchemaComment() {
- return false;
+ return true;
}
@Override
protected Set<String> createSysDatabaseNameSet() {
- return Sets.newHashSet();
+ return CLICK_HOUSE_SYSTEM_DATABASES;
+ }
+
+ @Override
+ public List<String> listDatabases() {
+ List<String> databaseNames = new ArrayList<>();
+ try (final Connection connection = getConnection()) {
+ // It is possible that other catalogs have been deleted,
+ // causing the following statement to error,
+ // so here we manually set a system catalog
+ connection.setCatalog(createSysDatabaseNameSet().iterator().next());
+ try (Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery("SHOW DATABASES")) {
+ while (resultSet.next()) {
+ String databaseName = resultSet.getString(1);
+ if (!isSystemDatabase(databaseName)) {
+ databaseNames.add(databaseName);
+ }
+ }
+ }
+ return databaseNames;
+ } catch (final SQLException se) {
+ throw this.exceptionMapper.toGravitinoException(se);
+ }
+ }
+
+ @Override
+ protected String generateCreateDatabaseSql(
+ String databaseName, String comment, Map<String, String> properties) {
+
+ String originComment = StringIdentifier.removeIdFromComment(comment);
+ if (!supportSchemaComment() && StringUtils.isNotEmpty(originComment)) {
+ throw new UnsupportedOperationException(
+ "Doesn't support setting schema comment: " + originComment);
+ }
+
+ StringBuilder createDatabaseSql =
+ new StringBuilder(String.format("CREATE DATABASE `%s`", databaseName));
+
+ if (StringUtils.isNotEmpty(originComment)) {
+ createDatabaseSql.append(String.format(" COMMENT '%s'", originComment));
+ }
+
+ LOG.info("Generated create database:{} sql: {}", databaseName,
createDatabaseSql);
+ return createDatabaseSql.toString();
}
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseCatalogPropertiesMeta.java
similarity index 55%
copy from
catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
copy to
catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseCatalogPropertiesMeta.java
index 8ce7478945..6e18407ba1 100644
---
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/ClickHouseCatalogCapability.java
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseCatalogPropertiesMeta.java
@@ -16,11 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.gravitino.catalog.clickhouse;
-import org.apache.gravitino.catalog.jdbc.JdbcCatalogCapability;
+import java.util.Map;
+import org.apache.gravitino.catalog.jdbc.config.JdbcConfig;
+import org.apache.gravitino.connector.PropertyEntry;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestClickHouseCatalogPropertiesMeta {
-public class ClickHouseCatalogCapability extends JdbcCatalogCapability {
- // No additional capabilities for ClickHouse at this time
+ @Test
+ void testSpecificPropertyEntriesIncludeClickHouseSettings() {
+ ClickHouseCatalogPropertiesMetadata meta = new
ClickHouseCatalogPropertiesMetadata();
+ Map<String, PropertyEntry<?>> entries = meta.specificPropertyEntries();
+ // Should still include base JDBC properties
+ Assertions.assertTrue(entries.containsKey(JdbcConfig.JDBC_URL.getKey()));
+ Assertions.assertTrue(entries.containsKey(JdbcConfig.USERNAME.getKey()));
+ }
}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseSchemaPropertiesMetadata.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseSchemaPropertiesMetadata.java
new file mode 100644
index 0000000000..f50cb4de9d
--- /dev/null
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/TestClickHouseSchemaPropertiesMetadata.java
@@ -0,0 +1,45 @@
+/*
+ * 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.gravitino.catalog.clickhouse;
+
+import java.util.Map;
+import org.apache.gravitino.StringIdentifier;
+import org.apache.gravitino.connector.PropertyEntry;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestClickHouseSchemaPropertiesMetadata {
+
+ @Test
+ void testSchemaPropertyEntriesIncludeClusterToggle() {
+ ClickHouseSchemaPropertiesMetadata metadata = new
ClickHouseSchemaPropertiesMetadata();
+ Map<String, PropertyEntry<?>> entries = metadata.propertyEntries();
+
+ Assertions.assertTrue(
+ entries.containsKey(ClickHouseConfig.CK_ON_CLUSTER.getKey()), "on
cluster missing");
+ PropertyEntry<?> onCluster =
entries.get(ClickHouseConfig.CK_ON_CLUSTER.getKey());
+ Assertions.assertEquals(Boolean.FALSE, onCluster.getDefaultValue());
+ Assertions.assertFalse(onCluster.isRequired());
+ Assertions.assertFalse(onCluster.isImmutable());
+ Assertions.assertFalse(onCluster.isHidden());
+
+ // Reserved ID property should still exist
+ Assertions.assertTrue(entries.containsKey(StringIdentifier.ID_KEY));
+ }
+}
diff --git
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseDatabaseOperations.java
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseDatabaseOperations.java
new file mode 100644
index 0000000000..b4ee51d703
--- /dev/null
+++
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseDatabaseOperations.java
@@ -0,0 +1,69 @@
+/*
+ * 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.gravitino.catalog.clickhouse.operations;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.gravitino.catalog.clickhouse.ClickHouseConfig;
+import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestClickHouseDatabaseOperations {
+
+ private static class TestableClickHouseDatabaseOperations extends
ClickHouseDatabaseOperations {
+ String buildCreateSql(String databaseName, String comment, Map<String,
String> properties) {
+ return generateCreateDatabaseSql(databaseName, comment, properties);
+ }
+
+ String buildDropSql(String databaseName, boolean cascade) {
+ return generateDropDatabaseSql(databaseName, cascade);
+ }
+ }
+
+ private TestableClickHouseDatabaseOperations newOps(Map<String, String>
conf) {
+ TestableClickHouseDatabaseOperations ops = new
TestableClickHouseDatabaseOperations();
+ ops.initialize(null, new JdbcExceptionConverter(), conf);
+ return ops;
+ }
+
+ @Test
+ void testGenerateCreateDatabaseSqlWithoutCluster() {
+ Map<String, String> conf = new HashMap<>();
+ String sql = newOps(conf).buildCreateSql("db_name", null,
Collections.emptyMap());
+ Assertions.assertEquals("CREATE DATABASE `db_name`", sql);
+ }
+
+ @Test
+ void testGenerateCreateDatabaseSqlWithClusterNameButDisabled() {
+ Map<String, String> conf = new HashMap<>();
+ conf.put(ClickHouseConfig.CK_CLUSTER_NAME.getKey(), "ck_cluster");
+
+ String sql = newOps(conf).buildCreateSql("db_name", "comment",
Collections.emptyMap());
+ Assertions.assertEquals("CREATE DATABASE `db_name` COMMENT 'comment'",
sql);
+ }
+
+ @Test
+ void testGenerateDropDatabaseSqlWithoutCluster() {
+ Map<String, String> conf = new HashMap<>();
+ String sql = newOps(conf).buildDropSql("db_name", true);
+ Assertions.assertEquals("DROP DATABASE `db_name`", sql);
+ }
+}