From 3d37706016fdfa2cfdbbfb7e83f16ee5e8042f0a Mon Sep 17 00:00:00 2001 From: linghengqian Date: Thu, 30 May 2024 16:43:01 +0800 Subject: [PATCH] Add GraalVM Reachability Metadata and corresponding nativeTest for ClickHouse integration over http --- .../ClickHouseConnectionPropertiesParser.java | 45 ++++++++ .../database/ClickHouseDatabaseMetaData.java | 43 ++++++++ .../type/ClickHouseDatabaseType.java | 8 -- ....core.connector.ConnectionPropertiesParser | 18 ++++ ....metadata.database.DialectDatabaseMetaData | 18 ++++ .../type/TcClickHouseDatabaseType.java | 9 +- .../reflect-config.json | 101 +++++++++++------- .../resource-config.json | 7 +- pom.xml | 8 ++ test/native/pom.xml | 17 +++ .../jdbc/commons/TestShardingService.java | 75 ++++++++++++- .../repository/OrderItemRepository.java | 74 ++++++++++++- .../commons/repository/OrderRepository.java | 75 ++++++++++++- .../testcontainers/ClickHouseProvider.java | 47 ++++++++ .../jdbc/databases/ClickHouseTest.java | 65 +++++++++++ ...s.containers.JdbcDatabaseContainerProvider | 18 ++++ .../sql/test-native-databases-clickhouse.sql | 32 ++++++ .../yaml/databases/clickhouse.yaml | 73 +++++++++++++ 18 files changed, 671 insertions(+), 62 deletions(-) create mode 100644 infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/connector/ClickHouseConnectionPropertiesParser.java create mode 100644 infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/metadata/database/ClickHouseDatabaseMetaData.java create mode 100644 infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser create mode 100644 infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData create mode 100644 test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/testcontainers/ClickHouseProvider.java create mode 100644 test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java create mode 100644 test/native/src/test/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider create mode 100644 test/native/src/test/resources/test-native/sql/test-native-databases-clickhouse.sql create mode 100644 test/native/src/test/resources/test-native/yaml/databases/clickhouse.yaml diff --git a/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/connector/ClickHouseConnectionPropertiesParser.java b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/connector/ClickHouseConnectionPropertiesParser.java new file mode 100644 index 00000000000000..07e6055cfcd97f --- /dev/null +++ b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/connector/ClickHouseConnectionPropertiesParser.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.shardingsphere.infra.database.clickhouse.connector; + +import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties; +import org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser; +import org.apache.shardingsphere.infra.database.core.connector.StandardConnectionProperties; +import org.apache.shardingsphere.infra.database.core.connector.url.JdbcUrl; +import org.apache.shardingsphere.infra.database.core.connector.url.StandardJdbcUrlParser; + +import java.util.Properties; + +/** + * Connection properties parser of ClickHouse. + */ +public final class ClickHouseConnectionPropertiesParser implements ConnectionPropertiesParser { + + private static final int DEFAULT_PORT = 8123; + + @Override + public ConnectionProperties parse(final String url, final String username, final String catalog) { + JdbcUrl jdbcUrl = new StandardJdbcUrlParser().parse(url); + return new StandardConnectionProperties(jdbcUrl.getHostname(), jdbcUrl.getPort(DEFAULT_PORT), jdbcUrl.getDatabase(), null, jdbcUrl.getQueryProperties(), new Properties()); + } + + @Override + public String getDatabaseType() { + return "ClickHouse"; + } +} diff --git a/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/metadata/database/ClickHouseDatabaseMetaData.java b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/metadata/database/ClickHouseDatabaseMetaData.java new file mode 100644 index 00000000000000..3c2281d1124c9d --- /dev/null +++ b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/metadata/database/ClickHouseDatabaseMetaData.java @@ -0,0 +1,43 @@ +/* + * 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.shardingsphere.infra.database.clickhouse.metadata.database; + +import org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; + +/** + * Database meta data of ClickHouse. + */ +public final class ClickHouseDatabaseMetaData implements DialectDatabaseMetaData { + + @Override + public QuoteCharacter getQuoteCharacter() { + return QuoteCharacter.QUOTE; + } + + @Override + public NullsOrderType getDefaultNullsOrderType() { + return NullsOrderType.FIRST; + } + + @Override + public String getDatabaseType() { + return "ClickHouse"; + } +} diff --git a/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/type/ClickHouseDatabaseType.java b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/type/ClickHouseDatabaseType.java index c03b7b18bb2dd1..53510ae33e87bc 100644 --- a/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/type/ClickHouseDatabaseType.java +++ b/infra/database/type/clickhouse/src/main/java/org/apache/shardingsphere/infra/database/clickhouse/type/ClickHouseDatabaseType.java @@ -18,15 +18,12 @@ package org.apache.shardingsphere.infra.database.clickhouse.type; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; -import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import java.util.Arrays; import java.util.Collection; -import java.util.Optional; /** * Database type of ClickHouse. - * ClickHouse currently uses MySQL dialect parsing. */ public final class ClickHouseDatabaseType implements DatabaseType { @@ -35,11 +32,6 @@ public Collection getJdbcUrlPrefixes() { return Arrays.asList("jdbc:ch:", "jdbc:clickhouse:"); } - @Override - public Optional getTrunkDatabaseType() { - return Optional.of(TypedSPILoader.getService(DatabaseType.class, "MySQL")); - } - @Override public String getType() { return "ClickHouse"; diff --git a/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser b/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser new file mode 100644 index 00000000000000..90df56bb2cebf6 --- /dev/null +++ b/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.database.clickhouse.connector.ClickHouseConnectionPropertiesParser diff --git a/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData b/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData new file mode 100644 index 00000000000000..4f96c02d334888 --- /dev/null +++ b/infra/database/type/clickhouse/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.database.clickhouse.metadata.database.ClickHouseDatabaseMetaData diff --git a/infra/database/type/testcontainers/src/main/java/org/apache/shardingsphere/infra/database/testcontainers/type/TcClickHouseDatabaseType.java b/infra/database/type/testcontainers/src/main/java/org/apache/shardingsphere/infra/database/testcontainers/type/TcClickHouseDatabaseType.java index 2e6c8735efb7e8..0f96b8da177064 100644 --- a/infra/database/type/testcontainers/src/main/java/org/apache/shardingsphere/infra/database/testcontainers/type/TcClickHouseDatabaseType.java +++ b/infra/database/type/testcontainers/src/main/java/org/apache/shardingsphere/infra/database/testcontainers/type/TcClickHouseDatabaseType.java @@ -20,8 +20,8 @@ import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Optional; /** @@ -29,9 +29,14 @@ */ public final class TcClickHouseDatabaseType implements TestcontainersDatabaseType { + /** + * TODO See the JavaDoc for `org.apache.shardingsphere.test.natived.jdbc.commons.testcontainers.ClickHouseProvider`. + * + * @return prefixes of JDBC URL + */ @Override public Collection getJdbcUrlPrefixes() { - return Collections.singleton("jdbc:tc:clickhouse:"); + return Arrays.asList("jdbc:tc:clickhouse:", "jdbc:tc:shardingsphere0clickhouse:"); } @Override diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json index 49cc77934df2c5..012a109a810d71 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json @@ -84,7 +84,7 @@ "name":"org.apache.shardingsphere.broadcast.yaml.config.YamlBroadcastRuleConfiguration" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.rule.DatabaseRulePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.DatabaseRulePersistService"}, "name":"org.apache.shardingsphere.broadcast.yaml.config.YamlBroadcastRuleConfiguration", "allDeclaredFields":true }, @@ -284,7 +284,7 @@ "methods":[{"name":"","parameterTypes":[] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }, {"name":"setType","parameterTypes":["java.lang.String"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.rule.DatabaseRulePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.DatabaseRulePersistService"}, "name":"org.apache.shardingsphere.infra.algorithm.core.yaml.YamlAlgorithmConfiguration", "allDeclaredFields":true, "methods":[{"name":"getProps","parameterTypes":[] }, {"name":"getType","parameterTypes":[] }] @@ -528,26 +528,26 @@ "name":"org.apache.shardingsphere.infra.instance.metadata.proxy.ProxyInstanceMetaDataBuilder" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.ComputeNodePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.persist.ComputeNodePersistService"}, "name":"org.apache.shardingsphere.infra.instance.yaml.YamlComputeNodeData", "allDeclaredFields":true, "queryAllPublicMethods":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"getAttribute","parameterTypes":[] }, {"name":"getVersion","parameterTypes":[] }, {"name":"setAttribute","parameterTypes":["java.lang.String"] }, {"name":"setVersion","parameterTypes":["java.lang.String"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.ComputeNodePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.persist.ComputeNodePersistService"}, "name":"org.apache.shardingsphere.infra.instance.yaml.YamlComputeNodeDataBeanInfo" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.ComputeNodePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.persist.ComputeNodePersistService"}, "name":"org.apache.shardingsphere.infra.instance.yaml.YamlComputeNodeDataCustomizer" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContexts"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory"}, "name":"org.apache.shardingsphere.infra.metadata.statistics.builder.dialect.MySQLShardingSphereStatisticsBuilder" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContexts"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory"}, "name":"org.apache.shardingsphere.infra.metadata.statistics.builder.dialect.PostgreSQLShardingSphereStatisticsBuilder" }, { @@ -572,7 +572,7 @@ "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.subsciber.EventSubscriberRegistry$$Lambda/0x00007f12133825d0"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.subsciber.EventSubscriberRegistry$$Lambda/0x00007f9703382e30"}, "name":"org.apache.shardingsphere.infra.util.eventbus.EventSubscriber" }, { @@ -591,7 +591,7 @@ "queryAllPublicMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.ComputeNodePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.persist.ComputeNodePersistService"}, "name":"org.apache.shardingsphere.infra.util.yaml.YamlConfiguration", "queryAllPublicMethods":true }, @@ -896,20 +896,10 @@ "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceWatcherFactory"}, "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.data.ShardingSphereDataChangedWatcher" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.ClusterContextManagerBuilder"}, - "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.subscriber.ShardingSphereSchemaDataRegistrySubscriber", - "queryAllDeclaredMethods":true -}, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceWatcherFactory"}, "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.watcher.MetaDataChangedWatcher" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.ClusterContextManagerBuilder"}, - "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.process.subscriber.ClusterProcessSubscriber", - "queryAllDeclaredMethods":true -}, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceWatcherFactory"}, "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.status.cluster.watcher.ClusterStateChangedWatcher" @@ -940,19 +930,9 @@ "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.subscriber.CacheEvictedSubscriber", "methods":[{"name":"onGovernanceEvent","parameterTypes":["org.apache.shardingsphere.infra.rule.event.GovernanceEvent"] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.infra.util.eventbus.EventBusContext"}, - "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.subscriber.ResourceMetaDataChangedSubscriber", - "methods":[{"name":"renew","parameterTypes":["org.apache.shardingsphere.mode.event.schema.table.CreateOrAlterTableEvent"] }, {"name":"renew","parameterTypes":["org.apache.shardingsphere.mode.event.schema.table.DropTableEvent"] }] -}, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.infra.util.eventbus.EventBusContext"}, - "name":"org.apache.shardingsphere.mode.manager.cluster.coordinator.subscriber.StateChangedSubscriber", - "methods":[{"name":"renew","parameterTypes":["org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.status.cluster.event.ClusterStateEvent"] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.PersistServiceFacade"}, - "name":"org.apache.shardingsphere.mode.manager.cluster.service.ClusterMetaDataManagerPersistServiceBuilder", + "name":"org.apache.shardingsphere.mode.manager.cluster.service.ClusterPersistServiceBuilder", "methods":[{"name":"","parameterTypes":[] }] }, { @@ -965,7 +945,7 @@ }, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.service.PersistServiceFacade"}, - "name":"org.apache.shardingsphere.mode.manager.standalone.service.StandaloneMetaDataManagerPersistServiceBuilder", + "name":"org.apache.shardingsphere.mode.manager.standalone.service.StandalonePersistServiceBuilder", "methods":[{"name":"","parameterTypes":[] }] }, { @@ -973,9 +953,56 @@ "name":"org.apache.shardingsphere.mode.manager.standalone.yaml.StandaloneYamlPersistRepositoryConfigurationSwapper" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.ClusterContextManagerBuilder"}, - "name":"org.apache.shardingsphere.mode.process.ProcessSubscriber", - "queryAllDeclaredMethods":true + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.index.AlterIndexStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.index.CreateIndexStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.index.DropIndexStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.schema.AlterSchemaStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.schema.CreateSchemaStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.schema.DropSchemaStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.table.AlterTableStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.table.CreateTableStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.table.DropTableStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.table.RenameTableStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.view.AlterViewStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.view.CreateViewStatementSchemaRefresher" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "name":"org.apache.shardingsphere.mode.metadata.refresher.type.view.DropViewStatementSchemaRefresher" }, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.ClusterContextManagerBuilder"}, @@ -1398,7 +1425,7 @@ "name":"org.apache.shardingsphere.sharding.yaml.config.YamlShardingRuleConfiguration" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.rule.DatabaseRulePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.DatabaseRulePersistService"}, "name":"org.apache.shardingsphere.sharding.yaml.config.YamlShardingRuleConfiguration", "allDeclaredFields":true }, @@ -1418,7 +1445,7 @@ "methods":[{"name":"","parameterTypes":[] }, {"name":"setActualDataNodes","parameterTypes":["java.lang.String"] }, {"name":"setKeyGenerateStrategy","parameterTypes":["org.apache.shardingsphere.sharding.yaml.config.strategy.keygen.YamlKeyGenerateStrategyConfiguration"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.rule.DatabaseRulePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.DatabaseRulePersistService"}, "name":"org.apache.shardingsphere.sharding.yaml.config.rule.YamlTableRuleConfiguration", "allDeclaredFields":true, "methods":[{"name":"getActualDataNodes","parameterTypes":[] }, {"name":"getAuditStrategy","parameterTypes":[] }, {"name":"getDatabaseStrategy","parameterTypes":[] }, {"name":"getKeyGenerateStrategy","parameterTypes":[] }, {"name":"getLogicTable","parameterTypes":[] }, {"name":"getTableStrategy","parameterTypes":[] }] @@ -1459,7 +1486,7 @@ "methods":[{"name":"","parameterTypes":[] }, {"name":"setStandard","parameterTypes":["org.apache.shardingsphere.sharding.yaml.config.strategy.sharding.YamlStandardShardingStrategyConfiguration"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.rule.DatabaseRulePersistService"}, + "condition":{"typeReachable":"org.apache.shardingsphere.metadata.persist.service.config.database.DatabaseRulePersistService"}, "name":"org.apache.shardingsphere.sharding.yaml.config.strategy.sharding.YamlShardingStrategyConfiguration", "allDeclaredFields":true, "methods":[{"name":"getComplex","parameterTypes":[] }, {"name":"getHint","parameterTypes":[] }, {"name":"getNone","parameterTypes":[] }, {"name":"getStandard","parameterTypes":[] }] diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json index db067f61bfa95c..e7af6778ebc36e 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json @@ -208,7 +208,7 @@ "condition":{"typeReachable":"org.apache.shardingsphere.infra.metadata.database.schema.reviser.schema.SchemaMetaDataReviseEngine"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContexts"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.infra.metadata.statistics.builder.ShardingSphereStatisticsBuilder\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.rewrite.SQLRewriteEntry"}, @@ -249,6 +249,9 @@ }, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.manager.listener.ContextManagerLifecycleListener\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefreshEngine"}, + "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.metadata.refresher.MetaDataRefresher\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.ClusterContextManagerBuilder"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.repository.cluster.ClusterPersistRepository\\E" @@ -260,7 +263,7 @@ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.repository.standalone.StandalonePersistRepository\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.standalone.StandaloneContextManagerBuilder"}, - "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.service.MetaDataManagerPersistServiceBuilder\\E" + "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.service.persist.PersistServiceBuilder\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.mode.spi.RuleNodePathProvider\\E" diff --git a/pom.xml b/pom.xml index 9f74d4c8f6b48e..d539451795a734 100644 --- a/pom.xml +++ b/pom.xml @@ -125,6 +125,7 @@ 2.2.224 3.1.0-og 2.4.2 + 0.6.0-patch5 4.0.3 @@ -471,6 +472,13 @@ ${h2.version} test + + com.clickhouse + clickhouse-jdbc + ${clickhouse-jdbc.version} + http + test + com.zaxxer diff --git a/test/native/pom.xml b/test/native/pom.xml index 93e036a0c110a1..1266875230cdda 100644 --- a/test/native/pom.xml +++ b/test/native/pom.xml @@ -117,6 +117,12 @@ using Seata Client under GraalVM Native Image requires using the version release + + org.apache.shardingsphere + shardingsphere-parser-sql-clickhouse + ${project.version} + test + org.awaitility @@ -143,6 +149,12 @@ using Seata Client under GraalVM Native Image requires using the version release mssql-jdbc test + + com.clickhouse + clickhouse-jdbc + http + test + org.testcontainers postgresql @@ -153,6 +165,11 @@ using Seata Client under GraalVM Native Image requires using the version release mssqlserver test + + org.testcontainers + clickhouse + test + org.apache.curator curator-test diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/TestShardingService.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/TestShardingService.java index c9ca62e18d7cd6..9424d678c1a7ce 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/TestShardingService.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/TestShardingService.java @@ -36,6 +36,7 @@ import java.util.stream.LongStream; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; @Getter @@ -55,7 +56,7 @@ public TestShardingService(final DataSource dataSource) { /** * Process success. - * + * * @throws SQLException An exception that provides information on a database access error or other errors. */ public void processSuccess() throws SQLException { @@ -85,9 +86,47 @@ public void processSuccess() throws SQLException { orderItemRepository.assertRollbackWithTransactions(); } + /** + * Process success in ClickHouse. + * TODO Need to fix `shardingsphere-parser-sql-clickhouse` module to use the following function in the last position. + * // CHECKSTYLE:OFF + *
+     * deleteData(orderIds);
+     * assertThat(orderRepository.selectAll(), equalTo(Collections.emptyList()));
+     * assertThat(orderItemRepository.selectAll(), equalTo(Collections.emptyList()));
+     * assertThat(addressRepository.selectAll(), equalTo(Collections.emptyList()));
+     * orderItemRepository.assertRollbackWithTransactions();
+     * 
+ * // CHECKSTYLE:ON + * + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public void processSuccessInClickHouse() throws SQLException { + Collection orderIds = insertDataInClickHouse(); + assertThat(orderIds, notNullValue()); + Collection orders = orderRepository.selectAll(); + assertThat(orders.stream().map(Order::getOrderType).collect(Collectors.toList()), + equalTo(Arrays.asList(1, 1, 1, 1, 1, 0, 0, 0, 0, 0))); + assertThat(orders.stream().map(Order::getUserId).collect(Collectors.toList()), + equalTo(new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9, 2, 4, 6, 8, 10)))); + assertThat(orders.stream().map(Order::getAddressId).collect(Collectors.toList()), + equalTo(new ArrayList<>(Arrays.asList(1L, 3L, 5L, 7L, 9L, 2L, 4L, 6L, 8L, 10L)))); + assertThat(orders.stream().map(Order::getStatus).collect(Collectors.toList()), + equalTo(IntStream.range(1, 11).mapToObj(i -> "INSERT_TEST").collect(Collectors.toList()))); + Collection orderItems = orderItemRepository.selectAll(); + assertThat(orderItems.stream().map(OrderItem::getUserId).collect(Collectors.toList()), + equalTo(new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9, 2, 4, 6, 8, 10)))); + assertThat(orderItems.stream().map(OrderItem::getPhone).collect(Collectors.toList()), + equalTo(IntStream.range(1, 11).mapToObj(i -> "13800000001").collect(Collectors.toList()))); + assertThat(orderItems.stream().map(OrderItem::getStatus).collect(Collectors.toList()), + equalTo(IntStream.range(1, 11).mapToObj(i -> "INSERT_TEST").collect(Collectors.toList()))); + assertThat(addressRepository.selectAll(), + equalTo(LongStream.range(1L, 11L).mapToObj(each -> new Address(each, "address_test_" + each)).collect(Collectors.toList()))); + } + /** * Insert data. - * + * * @return orderId of the insert statement. * @throws SQLException An exception that provides information on a database access error or other errors. */ @@ -113,9 +152,37 @@ public Collection insertData() throws SQLException { return result; } + /** + * Insert data in ClickHouse. + * + * @return orderId of the insert statement. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public Collection insertDataInClickHouse() throws SQLException { + Collection result = new ArrayList<>(10); + for (int i = 1; i <= 10; i++) { + Order order = new Order(); + order.setUserId(i); + order.setOrderType(i % 2); + order.setAddressId(i); + order.setStatus("INSERT_TEST"); + orderRepository.insertWithoutAutoGeneratedKey(order); + OrderItem orderItem = new OrderItem(); + orderItem.setOrderId(order.getOrderId()); + orderItem.setUserId(i); + orderItem.setPhone("13800000001"); + orderItem.setStatus("INSERT_TEST"); + orderItemRepository.insertWithoutAutoGeneratedKey(orderItem); + Address address = new Address((long) i, "address_test_" + i); + addressRepository.insert(address); + result.add(order.getOrderId()); + } + return result; + } + /** * Delete data. - * + * * @param orderIds orderId of the insert statement. * @throws SQLException An exception that provides information on a database access error or other errors. */ @@ -130,7 +197,7 @@ public void deleteData(final Collection orderIds) throws SQLException { /** * Clean environment. - * + * * @throws SQLException An exception that provides information on a database access error or other errors. */ public void cleanEnvironment() throws SQLException { diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderItemRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderItemRepository.java index f708decf509663..0f678c7c653c4b 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderItemRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderItemRepository.java @@ -42,11 +42,17 @@ public OrderItemRepository(final DataSource dataSource) { /** * create table if not exists in MySQL. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsInMySQL() throws SQLException { - String sql = "CREATE TABLE IF NOT EXISTS t_order_item " - + "(order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, phone VARCHAR(50), status VARCHAR(50), PRIMARY KEY (order_item_id))"; + String sql = "CREATE TABLE IF NOT EXISTS t_order_item \n" + + "(order_item_id BIGINT NOT NULL AUTO_INCREMENT,\n" + + "order_id BIGINT NOT NULL,\n" + + "user_id INT NOT NULL,\n" + + "phone VARCHAR(50),\n" + + "status VARCHAR(50),\n" + + "PRIMARY KEY (order_item_id));"; try ( Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { @@ -56,6 +62,7 @@ public void createTableIfNotExistsInMySQL() throws SQLException { /** * create table if not exists in Postgres. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsInPostgres() throws SQLException { @@ -76,6 +83,7 @@ public void createTableIfNotExistsInPostgres() throws SQLException { /** * create table in MS SQL Server. `order_item_id` is not set to `IDENTITY(1,1)` to simplify the unit test. * This also ignored the default schema of the `dbo`. + * * @throws SQLException SQL exception */ public void createTableInSQLServer() throws SQLException { @@ -94,8 +102,31 @@ public void createTableInSQLServer() throws SQLException { } } + /** + * create table if not exists in ClickHouse. + * + * @throws SQLException SQL exception + */ + public void createTableIfNotExistsInClickHouse() throws SQLException { + String sql = "create table IF NOT EXISTS t_order_item( \n" + + "order_item_id Int64 NOT NULL DEFAULT rand(), \n" + + "order_id Int64 NOT NULL, \n" + + "user_id Int32 NOT NULL, \n" + + "phone String,\n" + + "status String\n" + + ") engine = MergeTree \n" + + "primary key (order_item_id)\n" + + "order by(order_item_id); "; + try ( + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + } + } + /** * drop table. + * * @throws SQLException SQL exception */ public void dropTable() throws SQLException { @@ -109,6 +140,7 @@ public void dropTable() throws SQLException { /** * truncate table. + * * @throws SQLException SQL exception */ public void truncateTable() throws SQLException { @@ -122,6 +154,7 @@ public void truncateTable() throws SQLException { /** * create shadow table if not exists. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsShadow() throws SQLException { @@ -137,6 +170,7 @@ public void createTableIfNotExistsShadow() throws SQLException { /** * drop shadow table. + * * @throws SQLException SQL exception */ public void dropTableShadow() throws SQLException { @@ -150,6 +184,7 @@ public void dropTableShadow() throws SQLException { /** * truncate shadow table. + * * @throws SQLException SQL exception */ public void truncateTableShadow() throws SQLException { @@ -162,16 +197,32 @@ public void truncateTableShadow() throws SQLException { } /** - * insert something to table. + * insert OrderItem to table. + * * @param orderItem orderItem * @return orderItemId of the insert statement - * @throws SQLException SQL exception + * @throws SQLException SQL Exception */ public Long insert(final OrderItem orderItem) throws SQLException { + return insert(orderItem, Statement.RETURN_GENERATED_KEYS); + } + + /** + * insert OrderItem to table. + * + * @param orderItem orderItem + * @param autoGeneratedKeys a flag indicating whether auto-generated keys + * should be returned; one of + * {@code Statement.RETURN_GENERATED_KEYS} or + * {@code Statement.NO_GENERATED_KEYS} + * @return orderItemId of the insert statement + * @throws SQLException SQL exception + */ + public Long insert(final OrderItem orderItem, final int autoGeneratedKeys) throws SQLException { String sql = "INSERT INTO t_order_item (order_id, user_id, phone, status) VALUES (?, ?, ?, ?)"; try ( Connection connection = dataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + PreparedStatement preparedStatement = connection.prepareStatement(sql, autoGeneratedKeys)) { preparedStatement.setLong(1, orderItem.getOrderId()); preparedStatement.setInt(2, orderItem.getUserId()); preparedStatement.setString(3, orderItem.getPhone()); @@ -186,8 +237,20 @@ public Long insert(final OrderItem orderItem) throws SQLException { return orderItem.getOrderItemId(); } + /** + * insert OrderItem to table without auto generated key. Databases like ClickHouse do not support returning auto generated keys after executing SQL, + * see ClickHouse/ClickHouse#56228 . + * + * @param orderItem orderItem + * @throws SQLException SQL Exception + */ + public void insertWithoutAutoGeneratedKey(final OrderItem orderItem) throws SQLException { + insert(orderItem, Statement.NO_GENERATED_KEYS); + } + /** * delete by orderItemId. + * * @param orderItemId orderItemId * @throws SQLException SQL exception */ @@ -203,6 +266,7 @@ public void delete(final Long orderItemId) throws SQLException { /** * select all. + * * @return list of OrderItem * @throws SQLException SQL exception */ diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderRepository.java index 099ff83753780f..a2c9649fcff0ad 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/repository/OrderRepository.java @@ -39,11 +39,17 @@ public OrderRepository(final DataSource dataSource) { /** * create table if not exists in MySQL. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsInMySQL() throws SQLException { - String sql = "CREATE TABLE IF NOT EXISTS t_order " - + "(order_id BIGINT NOT NULL AUTO_INCREMENT, order_type INT(11), user_id INT NOT NULL, address_id BIGINT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id))"; + String sql = "CREATE TABLE IF NOT EXISTS t_order\n" + + "(order_id BIGINT NOT NULL AUTO_INCREMENT,\n" + + "order_type INT(11),\n" + + "user_id INT NOT NULL,\n" + + "address_id BIGINT NOT NULL,\n" + + "status VARCHAR(50),\n" + + "PRIMARY KEY (order_id));"; try ( Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { @@ -53,6 +59,7 @@ public void createTableIfNotExistsInMySQL() throws SQLException { /** * create table if not exists in Postgres. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsInPostgres() throws SQLException { @@ -73,12 +80,13 @@ public void createTableIfNotExistsInPostgres() throws SQLException { /** * create table in MS SQL Server. `order_item_id` is not set to `IDENTITY(1,1)` to simplify the unit test. * This also ignored the default schema of the `dbo`. + * * @throws SQLException SQL exception */ public void createTableInSQLServer() throws SQLException { String sql = "CREATE TABLE [t_order] (\n" + " order_id bigint NOT NULL,\n" - + " order_type int NOT NULL,\n" + + " order_type int,\n" + " user_id int NOT NULL,\n" + " address_id bigint NOT NULL,\n" + " status varchar(50),\n" @@ -91,9 +99,32 @@ public void createTableInSQLServer() throws SQLException { } } + /** + * create table in ClickHouse. + * + * @throws SQLException SQL exception + */ + public void createTableIfNotExistsInClickHouse() throws SQLException { + String sql = "create table IF NOT EXISTS t_order( \n" + + "order_id Int64 NOT NULL DEFAULT rand(), \n" + + "order_type Int32, \n" + + "user_id Int32 NOT NULL, \n" + + "address_id Int64 NOT NULL,\n" + + "status String\n" + + ") engine = MergeTree \n" + + "primary key (order_id)\n" + + "order by(order_id); "; + try ( + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + } + } + /** * drop table. * TODO There is a bug in this function in shadow's unit test and requires additional fixes. + * * @throws SQLException SQL exception */ public void dropTable() throws SQLException { @@ -107,6 +138,7 @@ public void dropTable() throws SQLException { /** * truncate table. + * * @throws SQLException SQL exception */ public void truncateTable() throws SQLException { @@ -120,6 +152,7 @@ public void truncateTable() throws SQLException { /** * create shadow table if not exists. + * * @throws SQLException SQL exception */ public void createTableIfNotExistsShadow() throws SQLException { @@ -136,6 +169,7 @@ public void createTableIfNotExistsShadow() throws SQLException { /** * drop shadow table. + * * @throws SQLException SQL exception */ public void dropTableShadow() throws SQLException { @@ -149,6 +183,7 @@ public void dropTableShadow() throws SQLException { /** * truncate shadow table. + * * @throws SQLException SQL exception */ public void truncateTableShadow() throws SQLException { @@ -162,6 +197,7 @@ public void truncateTableShadow() throws SQLException { /** * select Order from shadow table. + * * @return list of Order * @throws SQLException SQL exception */ @@ -172,6 +208,7 @@ public List selectShadowOrder() throws SQLException { /** * delete Order from shadow table. + * * @param orderId orderId * @throws SQLException SQL Exception */ @@ -187,15 +224,31 @@ public void deleteShadow(final Long orderId) throws SQLException { /** * insert Order to table. + * * @param order order * @return orderId of the insert statement * @throws SQLException SQL Exception */ public Long insert(final Order order) throws SQLException { + return insert(order, Statement.RETURN_GENERATED_KEYS); + } + + /** + * insert Order to table. + * + * @param order order + * @param autoGeneratedKeys a flag indicating whether auto-generated keys + * should be returned; one of + * {@code Statement.RETURN_GENERATED_KEYS} or + * {@code Statement.NO_GENERATED_KEYS} + * @return orderId of the insert statement + * @throws SQLException SQL Exception + */ + public Long insert(final Order order, final int autoGeneratedKeys) throws SQLException { String sql = "INSERT INTO t_order (user_id, order_type, address_id, status) VALUES (?, ?, ?, ?)"; try ( Connection connection = dataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + PreparedStatement preparedStatement = connection.prepareStatement(sql, autoGeneratedKeys)) { preparedStatement.setInt(1, order.getUserId()); preparedStatement.setInt(2, order.getOrderType()); preparedStatement.setLong(3, order.getAddressId()); @@ -210,8 +263,20 @@ public Long insert(final Order order) throws SQLException { return order.getOrderId(); } + /** + * insert Order to table without auto generated key. Databases like ClickHouse do not support returning auto generated keys after executing SQL, + * see ClickHouse/ClickHouse#56228 . + * + * @param order order + * @throws SQLException SQL Exception + */ + public void insertWithoutAutoGeneratedKey(final Order order) throws SQLException { + insert(order, Statement.NO_GENERATED_KEYS); + } + /** * delete by orderId. + * * @param orderId orderId * @throws SQLException SQL exception */ @@ -227,6 +292,7 @@ public void delete(final Long orderId) throws SQLException { /** * select all. + * * @return list of Order * @throws SQLException SQL exception */ @@ -236,6 +302,7 @@ public List selectAll() throws SQLException { /** * get Orders by SQL. + * * @param sql SQL * @return list of Order * @throws SQLException SQL exception diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/testcontainers/ClickHouseProvider.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/testcontainers/ClickHouseProvider.java new file mode 100644 index 00000000000000..5660e845d5d01f --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/commons/testcontainers/ClickHouseProvider.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.shardingsphere.test.natived.jdbc.commons.testcontainers; + +import org.testcontainers.clickhouse.ClickHouseContainer; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.JdbcDatabaseContainerProvider; +import org.testcontainers.utility.DockerImageName; + +/** + * TODO {@link org.testcontainers.containers.ClickHouseProvider} uses outdated Docker Image of `yandex/clickhouse-server`, + * which should be fixed on the testcontainers-java side. + */ +public final class ClickHouseProvider extends JdbcDatabaseContainerProvider { + + /** + * The reason for using `0` as the separator is that the URL_MATCHING_PATTERN of the {@link org.testcontainers.jdbc.ConnectionUrl.Patterns} + * sets {@code "(?[a-z0-9]+)"} for the `databaseType` part. + * + * @param databaseType {@link String} + * @return true when provider can handle this database type, else false. + */ + @Override + public boolean supports(final String databaseType) { + return "shardingsphere0clickhouse".equals(databaseType); + } + + @Override + public JdbcDatabaseContainer newInstance(final String tag) { + return new ClickHouseContainer(DockerImageName.parse("clickhouse/clickhouse-server").withTag(tag)); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java new file mode 100644 index 00000000000000..0c526f833d94df --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java @@ -0,0 +1,65 @@ +/* + * 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.shardingsphere.test.natived.jdbc.databases; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.shardingsphere.test.natived.jdbc.commons.TestShardingService; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledInNativeImage; + +import javax.sql.DataSource; +import java.sql.SQLException; + +class ClickHouseTest { + + private TestShardingService testShardingService; + + /** + * TODO Need to fix `shardingsphere-parser-sql-clickhouse` module to use `testShardingService.cleanEnvironment()` + * after `testShardingService.processSuccessInClickHouse()`. + * + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + @EnabledInNativeImage + @Test + void assertShardingInLocalTransactions() throws SQLException { + HikariConfig config = new HikariConfig(); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/databases/clickhouse.yaml"); + DataSource dataSource = new HikariDataSource(config); + testShardingService = new TestShardingService(dataSource); + testShardingService.processSuccessInClickHouse(); + } + + /** + * TODO Need to fix `shardingsphere-parser-sql-clickhouse` module to use `initEnvironment()` + * before `testShardingService.processSuccess()`. + * + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + @SuppressWarnings("unused") + private void initEnvironment() throws SQLException { + testShardingService.getOrderRepository().createTableIfNotExistsInClickHouse(); + testShardingService.getOrderItemRepository().createTableIfNotExistsInClickHouse(); + testShardingService.getAddressRepository().createTableIfNotExists(); + testShardingService.getOrderRepository().truncateTable(); + testShardingService.getOrderItemRepository().truncateTable(); + testShardingService.getAddressRepository().truncateTable(); + } +} diff --git a/test/native/src/test/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider b/test/native/src/test/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider new file mode 100644 index 00000000000000..a4a4667b0e4f5e --- /dev/null +++ b/test/native/src/test/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.test.natived.jdbc.commons.testcontainers.ClickHouseProvider diff --git a/test/native/src/test/resources/test-native/sql/test-native-databases-clickhouse.sql b/test/native/src/test/resources/test-native/sql/test-native-databases-clickhouse.sql new file mode 100644 index 00000000000000..3b6bfb335073f4 --- /dev/null +++ b/test/native/src/test/resources/test-native/sql/test-native-databases-clickhouse.sql @@ -0,0 +1,32 @@ +create table IF NOT EXISTS t_order +( + order_id Int64 NOT NULL DEFAULT rand(), + order_type Int32, + user_id Int32 NOT NULL, + address_id Int64 NOT NULL, + status String +) engine = MergeTree + primary key (order_id) + order by (order_id); + +create table IF NOT EXISTS t_order_item +( + order_item_id Int64 NOT NULL DEFAULT rand(), + order_id Int64 NOT NULL, + user_id Int32 NOT NULL, + phone String, + status String +) engine = MergeTree + primary key (order_item_id) + order by (order_item_id); + +CREATE TABLE IF NOT EXISTS t_address +( + address_id BIGINT NOT NULL, + address_name VARCHAR(100) NOT NULL, + PRIMARY KEY (address_id) +); + +TRUNCATE TABLE t_order; +TRUNCATE TABLE t_order_item; +TRUNCATE TABLE t_address; diff --git a/test/native/src/test/resources/test-native/yaml/databases/clickhouse.yaml b/test/native/src/test/resources/test-native/yaml/databases/clickhouse.yaml new file mode 100644 index 00000000000000..a6989339adacb7 --- /dev/null +++ b/test/native/src/test/resources/test-native/yaml/databases/clickhouse.yaml @@ -0,0 +1,73 @@ +# +# 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. +# + +mode: + type: Standalone + repository: + type: JDBC + +# TODO See the JavaDoc for `org.apache.shardingsphere.test.natived.jdbc.commons.testcontainers.ClickHouseProvider`. +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver + jdbcUrl: jdbc:tc:shardingsphere0clickhouse:24.4.1.2088://test-native-databases-clickhouse/demo_ds_0?TC_INITSCRIPT=test-native/sql/test-native-databases-clickhouse.sql + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver + jdbcUrl: jdbc:tc:shardingsphere0clickhouse:24.4.1.2088://test-native-databases-clickhouse/demo_ds_1?TC_INITSCRIPT=test-native/sql/test-native-databases-clickhouse.sql + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver + jdbcUrl: jdbc:tc:shardingsphere0clickhouse:24.4.1.2088://test-native-databases-clickhouse/demo_ds_2?TC_INITSCRIPT=test-native/sql/test-native-databases-clickhouse.sql + +rules: + - !SHARDING + tables: + t_order: + actualDataNodes: + keyGenerateStrategy: + column: order_id + keyGeneratorName: snowflake + t_order_item: + actualDataNodes: + keyGenerateStrategy: + column: order_item_id + keyGeneratorName: snowflake + defaultDatabaseStrategy: + standard: + shardingColumn: user_id + shardingAlgorithmName: inline + shardingAlgorithms: + inline: + type: CLASS_BASED + props: + strategy: STANDARD + algorithmClassName: org.apache.shardingsphere.test.natived.jdbc.commons.algorithm.ClassBasedInlineShardingAlgorithmFixture + keyGenerators: + snowflake: + type: SNOWFLAKE + auditors: + sharding_key_required_auditor: + type: DML_SHARDING_CONDITIONS + + - !BROADCAST + tables: + - t_address + +props: + sql-show: false