diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md index 239a753ec74c42..97fc19a4f6a053 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md @@ -126,15 +126,13 @@ CREATE DATABASE demo_ds_2; ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -256,15 +254,13 @@ CREATE DATABASE demo_ds_2; ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -376,15 +372,13 @@ CREATE DATABASE demo_ds_2; ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -443,25 +437,108 @@ HiveServer2 并不能保证每一条 `insert` 相关的 DML SQL 都能成功执 ShardingSphere JDBC DataSource 尚不支持执行 HiveServer2 的 `set`,`create table`,`truncate table` 和 `drop table` 语句。 用户应考虑为 ShardingSphere 提交包含单元测试的 PR。 +以 `set` 为代表的 SQL 语句很容易在 HiveServer2 Client 级别被动态配置。 +即便 ShardingSphere JDBC 不支持在虚拟 DataSource 上执行 HiveServer2 的 `set` 语句, +用户也可以通过 `initFile` 的 Hive Session 参数来直接为真实 DataSource 执行一系列 SQL。 +引入讨论,可能的 ShardingSphere 配置文件如下, + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql +``` + +`/tmp/init.sql` 的可能内容如下, + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +set metastore.compactor.initiator.on=true; +set metastore.compactor.cleaner.on=true; +set metastore.compactor.worker.threads=1; + +set hive.support.concurrency=true; +set hive.exec.dynamic.partition.mode=nonstrict; +set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; +``` + +受 https://issues.apache.org/jira/browse/HIVE-28317 影响,`initFile` 参数仅可使用绝对路径。 +但 ShardingSphere JDBC Driver 存在 `placeholder-type` 参数来动态定义 YAML 属性。 +进一步讨论,可能的 ShardingSphere 配置文件如下, + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds0.jdbc-url::} + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds1.jdbc-url::} + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds2.jdbc-url::} +``` + +此时使用 ShardingSphere JDBC Driver 时可以通过拼接字符串的手段传入业务项目的 classpath 上的文件的绝对路径。 + +```java +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import javax.sql.DataSource; +import java.nio.file.Paths; +public class ExampleUtils { + public DataSource createDataSource() { + HikariConfig config = new HikariConfig(); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:demo.yaml?placeholder-type=system_props"); + try { + assert null == System.getProperty("fixture.hive.ds0.jdbc-url"); + assert null == System.getProperty("fixture.hive.ds1.jdbc-url"); + assert null == System.getProperty("fixture.hive.ds2.jdbc-url"); + String absolutePath = Paths.get("src/test/resources/init.sql").toAbsolutePath().toString(); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_0;initFile=" + absolutePath); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_1;initFile=" + absolutePath); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_2;initFile=" + absolutePath); + return new HikariDataSource(config); + } finally { + System.clearProperty("fixture.hive.ds0.jdbc-url"); + System.clearProperty("fixture.hive.ds1.jdbc-url"); + System.clearProperty("fixture.hive.ds2.jdbc-url"); + } + } +} +``` + ### 在 ShardingSphere 数据源上使用 DML SQL 语句的前提条件 为了能够使用 `delete` 等 DML SQL 语句,当连接到 HiveServer2 时,用户应当考虑在 ShardingSphere JDBC 中仅使用支持 ACID 的表。 `apache/hive` 提供了多种事务解决方案。 -第1种选择是使用 ACID 表,可能的建表流程如下。 -由于其过时的基于目录的表格式,用户可能不得不在 DML 语句执行前后进行等待,以让 HiveServer2 完成低效的 DML 操作。 +第1种选择是使用 ACID 表,可能的建表流程如下。ACID 表使用过时的基于目录的表格式。 ```sql -- noinspection SqlNoDataSourceInspectionForFile set metastore.compactor.initiator.on=true; set metastore.compactor.cleaner.on=true; -set metastore.compactor.worker.threads=5; +set metastore.compactor.worker.threads=1; set hive.support.concurrency=true; set hive.exec.dynamic.partition.mode=nonstrict; set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; -CREATE TABLE IF NOT EXISTS t_order +create table IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, @@ -477,26 +554,28 @@ CREATE TABLE IF NOT EXISTS t_order ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); ``` -Iceberg 表格式支持的 Hive type 相对较少,设置`iceberg.mr.schema.auto.conversion`为`true`有助于缓解这一问题。 +Iceberg 表格式支持的 Hive type 相对较少,为 HiveServer2 执行 SQL `set iceberg.mr.schema.auto.conversion=true;`有助于缓解这一问题。 +SQL `set iceberg.mr.schema.auto.conversion=true;` 存在 https://issues.apache.org/jira/browse/HIVE-26507 涉及的弊端。 ### 事务限制 HiveServer2 不支持 ShardingSphere 集成级别的本地事务,XA 事务或 Seata 的 AT 模式事务, 更多讨论位于 https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions 。 +这与 https://iceberg.apache.org/docs/1.7.0/hive/#table-rollback 为 HiveServer2 提供的 `Table rollback` 功能无关, +仅与 `org.apache.hive.jdbc.HiveConnection` 未实现 `java.sql.Connection#rollback()` 有关。 + ### DBeaver Community 版本限制 当用户使用 DBeaver Community 连接至 HiveServer2 时,需确保 DBeaver Community 版本大于或等于 `24.2.5`。 diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md index 91967f757f8b11..3cbcff19cb1aaa 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md @@ -129,15 +129,13 @@ Use the `jdbcUrl` of `jdbc:hive2://localhost:10000/demo_ds_0`, ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -260,15 +258,13 @@ to connect to HiveServer2 and execute the following SQL, ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -381,15 +377,13 @@ to connect to HiveServer2 and execute the following SQL, ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); @@ -450,27 +444,111 @@ ShardingSphere JDBC DataSource does not yet support executing HiveServer2's `set and `drop table` statements. Users should consider submitting a PR containing unit tests for ShardingSphere. +SQL statements represented by `set` can be easily configured dynamically at the HiveServer2 Client level. +Even though ShardingSphere JDBC does not support executing HiveServer2's `set` statement on a virtual DataSource, +users can directly execute a series of SQLs for the real DataSource through the Hive Session parameter of `initFile`. +For discussion, the possible ShardingSphere configuration files are as follows, + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: jdbc:hive2://localhost:10000/demo_ds_0;initFile=/tmp/init.sql +``` + +The possible contents of `/tmp/init.sql` are as follows, + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +set metastore.compactor.initiator.on=true; +set metastore.compactor.cleaner.on=true; +set metastore.compactor.worker.threads=1; + +set hive.support.concurrency=true; +set hive.exec.dynamic.partition.mode=nonstrict; +set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; +``` + +Affected by https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter can only use absolute paths. +However, ShardingSphere JDBC Driver has a `placeholder-type` parameter to dynamically define YAML properties. +Further discussion, possible ShardingSphere configuration files are as follows, + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds0.jdbc-url::} + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds1.jdbc-url::} + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.hive.ds2.jdbc-url::} +``` + +When using ShardingSphere JDBC Driver, +user can pass in the absolute path of the file on the classpath of the business project by concatenating strings. + +```java +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import javax.sql.DataSource; +import java.nio.file.Paths; +public class ExampleUtils { + public DataSource createDataSource() { + HikariConfig config = new HikariConfig(); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:demo.yaml?placeholder-type=system_props"); + try { + assert null == System.getProperty("fixture.hive.ds0.jdbc-url"); + assert null == System.getProperty("fixture.hive.ds1.jdbc-url"); + assert null == System.getProperty("fixture.hive.ds2.jdbc-url"); + String absolutePath = Paths.get("src/test/resources/init.sql").toAbsolutePath().toString(); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_0;initFile=" + absolutePath); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_1;initFile=" + absolutePath); + System.setProperty("fixture.hive.ds0.jdbc-url", "jdbc:hive2://localhost:10000/demo_ds_2;initFile=" + absolutePath); + return new HikariDataSource(config); + } finally { + System.clearProperty("fixture.hive.ds0.jdbc-url"); + System.clearProperty("fixture.hive.ds1.jdbc-url"); + System.clearProperty("fixture.hive.ds2.jdbc-url"); + } + } +} +``` + ### Prerequisites for using DML SQL statements on ShardingSphere data sources In order to be able to use DML SQL statements such as `delete`, users should consider using only ACID-supported tables in ShardingSphere JDBC when connecting to HiveServer2. `apache/hive` provides multiple transaction solutions. -The first option is to use ACID tables, and the possible table creation process is as follows. -Due to its outdated catalog-based table format, -users may have to wait before and after the execution of DML statements to allow HiveServer2 to complete inefficient DML operations. +The first option is to use ACID tables. The possible table creation process is as follows. +ACID tables use the outdated directory-based table format. ```sql -- noinspection SqlNoDataSourceInspectionForFile set metastore.compactor.initiator.on=true; set metastore.compactor.cleaner.on=true; -set metastore.compactor.worker.threads=5; +set metastore.compactor.worker.threads=1; set hive.support.concurrency=true; set hive.exec.dynamic.partition.mode=nonstrict; set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; -CREATE TABLE IF NOT EXISTS t_order +create table IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, @@ -486,27 +564,29 @@ Refer to https://blog.cloudera.com/from-hive-tables-to-iceberg-tables-hassle-fre ```sql -- noinspection SqlNoDataSourceInspectionForFile -set iceberg.mr.schema.auto.conversion=true; - CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); ``` -The Iceberg table format supports relatively few Hive types. -Setting `iceberg.mr.schema.auto.conversion` to `true` can help alleviate this problem. +Iceberg table format supports relatively few Hive types. +Executing SQL `set iceberg.mr.schema.auto.conversion=true;` for HiveServer2 can help alleviate this problem. +SQL `set iceberg.mr.schema.auto.conversion=true;` has the drawbacks mentioned in https://issues.apache.org/jira/browse/HIVE-26507 . ### Transaction Limitations HiveServer2 does not support local transactions at the ShardingSphere integration level, XA transactions, or Seata's AT mode transactions. For more discussion, please visit https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions. +This has nothing to do with the `Table rollback` feature provided by https://iceberg.apache.org/docs/1.7.0/hive/#table-rollback for HiveServer2, +but only with `org.apache.hive.jdbc.HiveConnection` not implementing `java.sql.Connection#rollback()`. + ### DBeaver Community Version Limitations When users use DBeaver Community to connect to HiveServer2, they need to ensure that the DBeaver Community version is greater than or equal to `24.2.5`. diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.cn.md index ddf276a03bc9ba..4dfe1068fee6fc 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.cn.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.cn.md @@ -308,7 +308,7 @@ public class DemoService { } ``` -此时在微服务实例 `a-service` 和 `b-service` 均需要添加自定义的 `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` 实现。 +此时在微服务实例 `a-service` 需要添加自定义的 `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` 实现。 ```java import org.apache.seata.integration.http.TransactionPropagationInterceptor; @@ -356,7 +356,7 @@ public class DemoService { } ``` -此时在微服务实例 `a-service` 和 `b-service` 均需要添加自定义的 `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` 实现。 +此时在微服务实例 `a-service` 需要添加自定义的 `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` 实现。 ```java import org.apache.seata.integration.http.JakartaTransactionPropagationInterceptor; @@ -380,7 +380,8 @@ public class CustomWebMvcConfigurer implements WebMvcConfigurer { 用户需要考虑更改把 XID 通过服务调用传递到微服务实例 `a-service` 使用的 HTTP Header,或使用 RPC 框架把 XID 通过服务调用传递到微服务实例 `a-service`。 参考 https://github.com/apache/incubator-seata/tree/v2.1.0/integration 。 -4. 微服务实例 `a-service` 和 `b-service` 均为 Quarkus,Micronaut Framework 和 Helidon 等微服务。此情况下无法使用 Spring WebMVC HandlerInterceptor。 +4. 微服务实例 `a-service` 和 `b-service` 均为 Quarkus,Micronaut Framework 和 Helidon 等微服务。 +此情况下无法使用 Spring WebMVC HandlerInterceptor。 可参考如下 Spring Boot 3 的自定义 WebMvcConfigurer 实现,来实现 Filter。 ```java @@ -393,7 +394,6 @@ import org.springframework.lang.NonNull; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - @Configuration public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override @@ -408,7 +408,6 @@ public class CustomWebMvcConfigurer implements WebMvcConfigurer { } return true; } - @Override public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) { if (RootContext.inGlobalTransaction()) { diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.en.md index 37b7f9410bc0a0..79fbf300d9f1b8 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.en.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.en.md @@ -327,7 +327,7 @@ public class DemoService { } ``` -At this time, custom `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` implementations need to be added to the microservice instances `a-service` and `b-service`. +At this time, a custom `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` implementation needs to be added to the microservice instance `a-service`. ```java import org.apache.seata.integration.http.TransactionPropagationInterceptor; @@ -376,7 +376,8 @@ public class DemoService { } ``` -At this time, custom `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` implementations need to be added to the microservice instances `a-service` and `b-service`. +At this time, +a custom `org.springframework.web.servlet.config.annotation.WebMvcConfigurer` implementation needs to be added to the microservice instance `a-service`. ```java import org.apache.seata.integration.http.JakartaTransactionPropagationInterceptor; @@ -403,8 +404,8 @@ The user needs to consider changing the HTTP Header used to pass XID to the micr or use the RPC framework to pass XID to the microservice instance `a-service` through service calls. Refer to https://github.com/apache/incubator-seata/tree/v2.1.0/integration . -4. The microservice instances `a-service` and `b-service` are both microservices such as Quarkus, Micronaut Framework and Helidon. -In this case, Spring WebMVC HandlerInterceptor cannot be used. +4. The microservice instances `a-service` and `b-service` are both microservices such as Quarkus, +Micronaut Framework and Helidon. In this case, Spring WebMVC HandlerInterceptor cannot be used. You can refer to the following Spring Boot 3 custom WebMvcConfigurer implementation to implement Filter. ```java @@ -417,7 +418,6 @@ import org.springframework.lang.NonNull; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - @Configuration public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override @@ -432,7 +432,6 @@ public class CustomWebMvcConfigurer implements WebMvcConfigurer { } return true; } - @Override public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) { if (RootContext.inGlobalTransaction()) { 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 c09eb7197a5b93..a6d7095620daf7 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 @@ -16,7 +16,7 @@ "name":"[Lcom.github.dockerjava.api.model.VolumesFrom;" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007ff897cab858"}, + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f547fcab290"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, { @@ -75,6 +75,10 @@ "condition":{"typeReachable":"org.apache.shardingsphere.mode.repository.standalone.jdbc.JDBCRepository"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.proxy.backend.connector.jdbc.datasource.JDBCBackendDataSource"}, + "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" +}, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.frontend.postgresql.command.query.extended.Portal"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" @@ -881,7 +885,7 @@ "name":"org.apache.shardingsphere.broadcast.metadata.nodepath.BroadcastRuleNodePathProvider" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "name":"org.apache.shardingsphere.broadcast.route.BroadcastSQLRouter" }, { @@ -1101,11 +1105,6 @@ "condition":{"typeReachable":"org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader"}, "name":"org.apache.shardingsphere.encrypt.checker.config.EncryptRuleConfigurationChecker" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, - "name":"org.apache.shardingsphere.encrypt.checker.sql.EncryptSupportedSQLCheckersBuilder", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.backend.connector.StandardDatabaseConnector"}, "name":"org.apache.shardingsphere.encrypt.checker.sql.EncryptSupportedSQLCheckersBuilder", @@ -1630,10 +1629,6 @@ "condition":{"typeReachable":"org.apache.shardingsphere.infra.parser.cache.SQLStatementCacheBuilder"}, "name":"org.apache.shardingsphere.infra.parser.cache.SQLStatementCacheLoader" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, - "name":"org.apache.shardingsphere.infra.route.engine.dialect.MySQLSQLRouteExecutorDecider" -}, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.url.core.ShardingSphereURLLoadEngine"}, "name":"org.apache.shardingsphere.infra.url.absolutepath.AbsolutePathURLLoader" @@ -2074,7 +2069,7 @@ "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007ff897b26e30"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007f547fb27268"}, "name":"org.apache.shardingsphere.mode.manager.cluster.event.subscriber.dispatch.MetaDataChangedSubscriber" }, { @@ -2446,7 +2441,7 @@ "name":"org.apache.shardingsphere.readwritesplitting.metadata.nodepath.ReadwriteSplittingRuleNodePathProvider" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "name":"org.apache.shardingsphere.readwritesplitting.route.ReadwriteSplittingSQLRouter" }, { @@ -2585,7 +2580,7 @@ "name":"org.apache.shardingsphere.shadow.metadata.nodepath.ShadowRuleNodePathProvider" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "name":"org.apache.shardingsphere.shadow.route.ShadowSQLRouter" }, { @@ -2875,7 +2870,7 @@ "name":"org.apache.shardingsphere.sharding.rewrite.context.ShardingSQLRewriteContextDecorator" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "name":"org.apache.shardingsphere.sharding.route.engine.ShardingSQLRouter" }, { @@ -3094,7 +3089,7 @@ "name":"org.apache.shardingsphere.single.metadata.reviser.SingleMetaDataReviseEntry" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "name":"org.apache.shardingsphere.single.route.SingleSQLRouter" }, { @@ -3333,11 +3328,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.clickhouse.dml.ClickHouseInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.clickhouse.dml.ClickHouseSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.clickhouse.dml.ClickHouseSelectStatement", @@ -3348,11 +3338,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.hive.dml.HiveInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.hive.dml.HiveSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandlerFactory"}, "name":"org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLDeleteStatement", @@ -3368,11 +3353,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement", @@ -3388,11 +3368,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.opengauss.dml.OpenGaussInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.opengauss.dml.OpenGaussSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.opengauss.dml.OpenGaussSelectStatement", @@ -3413,11 +3388,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.postgresql.dml.PostgreSQLInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.postgresql.dml.PostgreSQLSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.postgresql.dml.PostgreSQLSelectStatement", @@ -3433,11 +3403,6 @@ "name":"org.apache.shardingsphere.sql.parser.statement.sqlserver.dml.SQLServerInsertStatement", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, - "name":"org.apache.shardingsphere.sql.parser.statement.sqlserver.dml.SQLServerSelectStatement", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.sqlserver.dml.SQLServerSelectStatement", 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 941a363ba7a0ec..c42c1ecf3f6d58 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 @@ -79,7 +79,7 @@ "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager"}, "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007ff897b369d0"}, + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f547fb36cb8"}, "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource"}, @@ -259,7 +259,7 @@ "condition":{"typeReachable":"org.apache.shardingsphere.infra.rewrite.SQLRewriteEntry"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.infra.rewrite.context.SQLRewriteContextDecorator\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.type.PartialSQLRouteExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.infra.route.engine.SQLRouteEngine"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.infra.route.SQLRouter\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.frontend.mysql.command.query.text.query.MySQLComQueryPacketExecutor"}, @@ -1964,10 +1964,13 @@ "pattern":"\\Qtest-native/yaml/jdbc/databases/clickhouse.yaml\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.url.classpath.ClassPathURLLoader"}, - "pattern":"\\Qtest-native/yaml/jdbc/databases/hive/simple.yaml\\E" + "pattern":"\\Qtest-native/yaml/jdbc/databases/hive/acid.yaml\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.url.classpath.ClassPathURLLoader"}, - "pattern":"\\Qtest-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml\\E" + "pattern":"\\Qtest-native/yaml/jdbc/databases/hive/iceberg.yaml\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.infra.url.classpath.ClassPathURLLoader"}, + "pattern":"\\Qtest-native/yaml/jdbc/databases/hive/zsd.yaml\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.url.classpath.ClassPathURLLoader"}, "pattern":"\\Qtest-native/yaml/jdbc/databases/mysql.yaml\\E" diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json index 4597bf4a5967cb..9bb9fe20748d39 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json @@ -332,6 +332,11 @@ "name":"org.apache.shardingsphere.infra.yaml.data.pojo.YamlShardingSphereRowData", "allPublicMethods": true }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, + "name":"org.apache.shardingsphere.sql.parser.statement.hive.dml.HiveSelectStatement", + "methods":[{"name":"","parameterTypes":[] }] +}, { "condition":{"typeReachable":"sun.security.provider.SecureRandom"}, "name":"sun.security.provider.SecureRandom", diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/AcidTableTest.java similarity index 95% rename from test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java rename to test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/AcidTableTest.java index 72e0e781489b6b..2afb1dadab52a0 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/AcidTableTest.java @@ -45,7 +45,7 @@ @SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"}) @EnabledInNativeImage @Testcontainers -class HiveSimpleTest { +class AcidTableTest { @SuppressWarnings("resource") @Container @@ -53,10 +53,10 @@ class HiveSimpleTest { .withEnv("SERVICE_NAME", "hiveserver2") .withExposedPorts(10000); - private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.simple."; + private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.acid."; // Due to https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter of HiveServer2 JDBC Driver must be an absolute path. - private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().toString(); + private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive-acid.sql").toAbsolutePath().toString(); private String jdbcUrlPrefix; @@ -101,7 +101,7 @@ private DataSource createDataSource() throws SQLException { } HikariConfig config = new HikariConfig(); config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); - config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/hive/simple.yaml?placeholder-type=system_props"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/hive/acid.yaml?placeholder-type=system_props"); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0" + ";initFile=" + ABSOLUTE_PATH); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1" + ";initFile=" + ABSOLUTE_PATH); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2" + ";initFile=" + ABSOLUTE_PATH); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/IcebergTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/IcebergTest.java new file mode 100644 index 00000000000000..c63851367dfa35 --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/IcebergTest.java @@ -0,0 +1,110 @@ +/* + * 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.hive; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.shardingsphere.test.natived.commons.TestShardingService; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledInNativeImage; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import javax.sql.DataSource; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.Duration; +import java.util.Properties; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"}) +@EnabledInNativeImage +@Testcontainers +class IcebergTest { + + @SuppressWarnings("resource") + @Container + public static final GenericContainer CONTAINER = new GenericContainer<>("apache/hive:4.0.1") + .withEnv("SERVICE_NAME", "hiveserver2") + .withExposedPorts(10000); + + private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.iceberg."; + + // Due to https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter of HiveServer2 JDBC Driver must be an absolute path. + private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive-iceberg.sql").toAbsolutePath().toString(); + + private String jdbcUrlPrefix; + + @BeforeAll + static void beforeAll() { + assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue())); + assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url"), is(nullValue())); + assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"), is(nullValue())); + } + + @AfterAll + static void afterAll() { + System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"); + System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url"); + System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"); + } + + @Test + void assertShardingInLocalTransactions() throws SQLException { + jdbcUrlPrefix = "jdbc:hive2://localhost:" + CONTAINER.getMappedPort(10000) + "/"; + DataSource dataSource = createDataSource(); + TestShardingService testShardingService = new TestShardingService(dataSource); + testShardingService.processSuccessInHive(); + } + + private Connection openConnection() throws SQLException { + Properties props = new Properties(); + return DriverManager.getConnection(jdbcUrlPrefix, props); + } + + private DataSource createDataSource() throws SQLException { + Awaitility.await().atMost(Duration.ofMinutes(1L)).ignoreExceptions().until(() -> { + openConnection().close(); + return true; + }); + try ( + Connection connection = openConnection(); + Statement statement = connection.createStatement()) { + statement.executeUpdate("CREATE DATABASE demo_ds_0"); + statement.executeUpdate("CREATE DATABASE demo_ds_1"); + statement.executeUpdate("CREATE DATABASE demo_ds_2"); + } + HikariConfig config = new HikariConfig(); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/hive/iceberg.yaml?placeholder-type=system_props"); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0" + ";initFile=" + ABSOLUTE_PATH); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1" + ";initFile=" + ABSOLUTE_PATH); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2" + ";initFile=" + ABSOLUTE_PATH); + return new HikariDataSource(config); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/ZookeeperServiceDiscoveryTest.java similarity index 94% rename from test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java rename to test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/ZookeeperServiceDiscoveryTest.java index 5c6a9e7c35da7e..ee9effbbc38ae2 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/ZookeeperServiceDiscoveryTest.java @@ -52,7 +52,7 @@ @SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection", "resource", "deprecation"}) @EnabledInNativeImage @Testcontainers -class HiveZookeeperServiceDiscoveryTest { +class ZookeeperServiceDiscoveryTest { private static final int RANDOM_PORT_FIRST = InstanceSpec.getRandomPort(); @@ -81,10 +81,10 @@ class HiveZookeeperServiceDiscoveryTest { .withFixedExposedPort(RANDOM_PORT_FIRST, RANDOM_PORT_FIRST) .dependsOn(ZOOKEEPER_CONTAINER); - private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.zookeeper.sde."; + private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.zsd."; // Due to https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter of HiveServer2 JDBC Driver must be an absolute path. - private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().toString(); + private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive-iceberg.sql").toAbsolutePath().toString(); private final String jdbcUrlSuffix = ";serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2"; @@ -108,7 +108,7 @@ static void afterAll() { /** * TODO Same problem {@link InstanceSpec#getRandomPort()} as {@code HIVE_SERVER2_1_CONTAINER}. * - * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws SQLException SQL exception. */ @Test void assertShardingInLocalTransactions() throws SQLException { @@ -143,7 +143,7 @@ private DataSource createDataSource() throws SQLException { extracted(HIVE_SERVER2_1_CONTAINER.getMappedPort(RANDOM_PORT_FIRST)); HikariConfig config = new HikariConfig(); config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); - config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml?placeholder-type=system_props"); + config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/hive/zsd.yaml?placeholder-type=system_props"); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0" + ";initFile=" + ABSOLUTE_PATH + jdbcUrlSuffix); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1" + ";initFile=" + ABSOLUTE_PATH + jdbcUrlSuffix); System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2" + ";initFile=" + ABSOLUTE_PATH + jdbcUrlSuffix); @@ -159,7 +159,7 @@ private void extracted(final int hiveServer2Port) throws SQLException { client.start(); List children = client.getChildren().forPath("/hiveserver2"); assertThat(children.size(), is(1)); - return children.get(0).contains(":" + hiveServer2Port + ";version="); + return children.get(0).startsWith("serverUri=0.0.0.0:" + hiveServer2Port + ";version=4.0.1;sequence="); } }); Awaitility.await().atMost(Duration.ofMinutes(1L)).ignoreExceptions().until(() -> { diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/transactions/base/SeataTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/transactions/base/SeataTest.java index 2e20ef8bf55a7e..d30d320ec7ef9a 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/transactions/base/SeataTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/transactions/base/SeataTest.java @@ -55,6 +55,8 @@ class SeataTest { private static final String SERVICE_DEFAULT_GROUP_LIST_KEY = "service.default.grouplist"; + private static DataSource logicDataSource; + private TestShardingService testShardingService; @BeforeAll @@ -62,28 +64,28 @@ static void beforeAll() { assertThat(System.getProperty(SERVICE_DEFAULT_GROUP_LIST_KEY), is(nullValue())); } - @AfterAll - static void afterAll() { - ContainerDatabaseDriver.killContainers(); - System.clearProperty(SERVICE_DEFAULT_GROUP_LIST_KEY); - } - /** * TODO Need to investigate why {@link org.apache.shardingsphere.transaction.base.seata.at.SeataATShardingSphereTransactionManager#close()} is not called. * The manual call {@link org.apache.shardingsphere.mode.manager.ContextManager#close()} is not intuitive. * * @throws SQLException SQL exception */ + @AfterAll + static void afterAll() throws SQLException { + try (Connection connection = logicDataSource.getConnection()) { + connection.unwrap(ShardingSphereConnection.class).getContextManager().close(); + } + ContainerDatabaseDriver.killContainers(); + System.clearProperty(SERVICE_DEFAULT_GROUP_LIST_KEY); + } + @Test void assertShardingInSeataTransactions() throws SQLException { - DataSource dataSource = createDataSource(CONTAINER.getMappedPort(8091)); - testShardingService = new TestShardingService(dataSource); + logicDataSource = createDataSource(CONTAINER.getMappedPort(8091)); + testShardingService = new TestShardingService(logicDataSource); initEnvironment(); testShardingService.processSuccess(); testShardingService.cleanEnvironment(); - try (Connection connection = dataSource.getConnection()) { - connection.unwrap(ShardingSphereConnection.class).getContextManager().close(); - } } private void initEnvironment() throws SQLException { diff --git a/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/reflect-config.json b/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/reflect-config.json index 72477d6117fe4f..795f8a42034967 100644 --- a/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/reflect-config.json +++ b/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/reflect-config.json @@ -146,16 +146,16 @@ "allDeclaredFields": true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.HiveZookeeperServiceDiscoveryTest"}, - "name":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.HiveZookeeperServiceDiscoveryTest", + "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.ZookeeperServiceDiscoveryTest"}, + "name":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.ZookeeperServiceDiscoveryTest", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.HiveSimpleTest"}, - "name":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.HiveSimpleTest", + "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.IcebergTest"}, + "name":"org.apache.shardingsphere.test.natived.jdbc.databases.hive.IcebergTest", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, diff --git a/test/native/src/test/resources/test-native/sql/test-native-databases-hive-acid.sql b/test/native/src/test/resources/test-native/sql/test-native-databases-hive-acid.sql new file mode 100644 index 00000000000000..e451f6a5f69bd6 --- /dev/null +++ b/test/native/src/test/resources/test-native/sql/test-native-databases-hive-acid.sql @@ -0,0 +1,55 @@ +-- +-- 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. +-- + +-- TODO `shardingsphere-parser-sql-hive` module does not support `set`, `create table`, `truncate table` and `drop table` statements yet, +-- we always need to execute the following Hive Session-level SQL in the current `javax.sql.DataSource`. +-- Hive does not support `AUTO_INCREMENT`, refer to HIVE-6905 . +set metastore.compactor.initiator.on=true; +set metastore.compactor.cleaner.on=true; +set metastore.compactor.worker.threads=1; + +set hive.support.concurrency=true; +set hive.exec.dynamic.partition.mode=nonstrict; +set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; + +create table IF NOT EXISTS t_order ( + order_id BIGINT NOT NULL, + order_type INT, + user_id INT NOT NULL, + address_id BIGINT NOT NULL, + status VARCHAR(50), + PRIMARY KEY (order_id) disable novalidate +) CLUSTERED BY (order_id) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional' = 'true'); + +create table IF NOT EXISTS t_order_item ( + order_item_id BIGINT NOT NULL, + order_id BIGINT NOT NULL, + user_id INT NOT NULL, + phone VARCHAR(50), + status VARCHAR(50), + PRIMARY KEY (order_item_id) disable novalidate +) CLUSTERED BY (order_item_id) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional' = 'true'); + +create table IF NOT EXISTS t_address ( + address_id BIGINT NOT NULL, + address_name VARCHAR(100) NOT NULL, + PRIMARY KEY (address_id) disable novalidate +) CLUSTERED BY (address_id) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional' = 'true'); + +TRUNCATE TABLE t_order; +TRUNCATE TABLE t_order_item; +TRUNCATE TABLE t_address; diff --git a/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql b/test/native/src/test/resources/test-native/sql/test-native-databases-hive-iceberg.sql similarity index 78% rename from test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql rename to test/native/src/test/resources/test-native/sql/test-native-databases-hive-iceberg.sql index 82f8d0dacfb006..1313cea9384509 100644 --- a/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql +++ b/test/native/src/test/resources/test-native/sql/test-native-databases-hive-iceberg.sql @@ -15,37 +15,31 @@ -- limitations under the License. -- --- TODO `shardingsphere-parser-sql-hive` module does not support `create table`, `truncate table` and `drop table` statements yet, +-- TODO `shardingsphere-parser-sql-hive` module does not support `set`, `create table`, `truncate table` and `drop table` statements yet, -- we always need to execute the following Hive Session-level SQL in the current `javax.sql.DataSource`. -- Hive does not support `AUTO_INCREMENT`, refer to HIVE-6905 . --- Fixes `Unsupported Hive type VARCHAR, use string instead or enable automatic type conversion, set 'iceberg.mr.schema.auto.conversion' to true` -set iceberg.mr.schema.auto.conversion=true; - -CREATE TABLE IF NOT EXISTS t_order -( +CREATE TABLE IF NOT EXISTS t_order ( order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, - status VARCHAR(50), + status string, PRIMARY KEY (order_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); -CREATE TABLE IF NOT EXISTS t_order_item -( +CREATE TABLE IF NOT EXISTS t_order_item ( order_item_id BIGINT NOT NULL, order_id BIGINT NOT NULL, user_id INT NOT NULL, - phone VARCHAR(50), - status VARCHAR(50), + phone string, + status string, PRIMARY KEY (order_item_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); -CREATE TABLE IF NOT EXISTS t_address -( +CREATE TABLE IF NOT EXISTS t_address ( address_id BIGINT NOT NULL, - address_name VARCHAR(100) NOT NULL, + address_name string NOT NULL, PRIMARY KEY (address_id) disable novalidate ) STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2'); diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/acid.yaml similarity index 89% rename from test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml rename to test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/acid.yaml index 2a5ff41f4312f6..d39a2439f2b61f 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/acid.yaml @@ -19,15 +19,15 @@ dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.simple.ds0.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.acid.ds0.jdbc-url::} ds_1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.simple.ds1.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.acid.ds1.jdbc-url::} ds_2: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.simple.ds2.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.acid.ds2.jdbc-url::} rules: - !SHARDING diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/iceberg.yaml similarity index 89% rename from test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml rename to test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/iceberg.yaml index 11adae6a432f29..caf90413fe766e 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/iceberg.yaml @@ -19,15 +19,15 @@ dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.zookeeper.sde.ds0.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.iceberg.ds0.jdbc-url::} ds_1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.zookeeper.sde.ds1.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.iceberg.ds1.jdbc-url::} ds_2: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: org.apache.hive.jdbc.HiveDriver - jdbcUrl: $${fixture.test-native.yaml.database.hive.zookeeper.sde.ds2.jdbc-url::} + jdbcUrl: $${fixture.test-native.yaml.database.hive.iceberg.ds2.jdbc-url::} rules: - !SHARDING diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zsd.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zsd.yaml new file mode 100644 index 00000000000000..3b4f27783ff7a3 --- /dev/null +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zsd.yaml @@ -0,0 +1,64 @@ +# +# 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. +# + +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.test-native.yaml.database.hive.zsd.ds0.jdbc-url::} + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.test-native.yaml.database.hive.zsd.ds1.jdbc-url::} + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: org.apache.hive.jdbc.HiveDriver + jdbcUrl: $${fixture.test-native.yaml.database.hive.zsd.ds2.jdbc-url::} + +rules: +- !SHARDING + tables: + t_order: + actualDataNodes: ds_0.t_order, ds_1.t_order, ds_2.t_order + keyGenerateStrategy: + column: order_id + keyGeneratorName: snowflake + t_order_item: + actualDataNodes: ds_0.t_order_item, ds_1.t_order_item, ds_2.t_order_item + 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.commons.algorithm.ClassBasedInlineShardingAlgorithmFixture + keyGenerators: + snowflake: + type: SNOWFLAKE + auditors: + sharding_key_required_auditor: + type: DML_SHARDING_CONDITIONS + +- !BROADCAST + tables: + - t_address