Skip to content

Commit

Permalink
Fix table exist exception when execute preview create table statement…
Browse files Browse the repository at this point in the history
… with exist table (#33171)

* Fix table exist exception when execute preview create table statement with exist table

* Update release note

* refactor SingleStandardRouteEngine
  • Loading branch information
strongduanmu authored Oct 9, 2024
1 parent ba86f62 commit ec1e1f6
Show file tree
Hide file tree
Showing 50 changed files with 233 additions and 161 deletions.
2 changes: 2 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
1. Sharding: Fix alter view exception when config sharding rule and binding table rule - [#32696](https://github.com/apache/shardingsphere/issues/32696)
1. Shadow: Use hintValueContext to replace extract sql hint from sql statement for solving shadow sql hint bug - [#33063](https://github.com/apache/shardingsphere/pull/33063)
1. Shadow: Make Shadow feature available again in GraalVM Native Image - [#33080](https://github.com/apache/shardingsphere/pull/33080)
1. DistSQL & Kernel: Fix table exist exception when execute preview create table statement with exist table - [#33171](https://github.com/apache/shardingsphere/pull/33171)


### Change Log

Expand Down
29 changes: 20 additions & 9 deletions docs/document/content/user-manual/common-config/sql-hint.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ ShardingSphere 的 SQL Hint 语法格式如下:

ShardingSphere SQL Hint 中可以定义如下的属性,为了兼容低版本 SQL Hint 语法,也可以使用别名中定义的属性:

| *名称* | *别名* | *数据类型* | *说明* | *默认值* |
|-----------------------------|-----------------------|------------|---------------------------------------|-------|
| SHARDING_DATABASE_VALUE (?) | shardingDatabaseValue | Comparable | 数据分片分库值,和 Hint 分片策略配合使用 | - |
| SHARDING_TABLE_VALUE (?) | shardingTableValue | Comparable | 数据分片分表值,和 Hint 分片策略配合使用 | - |
| WRITE_ROUTE_ONLY (?) | writeRouteOnly | boolean | 读写分离强制路由到主库执行 | false |
| DATA_SOURCE_NAME (?) | dataSourceName | String | 数据源透传,将 SQL 直接路由到指定数据源 | - |
| SKIP_SQL_REWRITE (?) | skipSQLRewrite | boolean | 跳过 SQL 改写阶段 | false |
| DISABLE_AUDIT_NAMES (?) | disableAuditNames | String | 禁用指定 SQL 审计算法 | - |
| SHADOW (?) | shadow | boolean | 影子库强制路由到影子库数据源执行,和影子库 SQL_HINT 算法配合使用 | false |
| *名称* | *别名* | *数据类型* | *说明* | *默认值* |
|------------------------------------|------------------------|------------|---------------------------------------|-------|
| SHARDING_DATABASE_VALUE (?) | shardingDatabaseValue | Comparable | 数据分片分库值,和 Hint 分片策略配合使用 | - |
| SHARDING_TABLE_VALUE (?) | shardingTableValue | Comparable | 数据分片分表值,和 Hint 分片策略配合使用 | - |
| WRITE_ROUTE_ONLY (?) | writeRouteOnly | boolean | 读写分离强制路由到主库执行 | false |
| DATA_SOURCE_NAME (?) | dataSourceName | String | 数据源透传,将 SQL 直接路由到指定数据源 | - |
| SKIP_SQL_REWRITE (?) | skipSQLRewrite | boolean | 跳过 SQL 改写阶段 | false |
| SKIP_METADATA_VALIDATE (?) | skipMetadataValidate | boolean | 跳过 SQL 执行元数据校验 | false |
| DISABLE_AUDIT_NAMES (?) | disableAuditNames | String | 禁用指定 SQL 审计算法 | - |
| SHADOW (?) | shadow | boolean | 影子库强制路由到影子库数据源执行,和影子库 SQL_HINT 算法配合使用 | false |


## SQL Hint
Expand Down Expand Up @@ -82,6 +83,16 @@ ShardingSphere SQL Hint 中可以定义如下的属性,为了兼容低版本 S
/* SHARDINGSPHERE_HINT: SKIP_SQL_REWRITE=true */ SELECT * FROM t_order;
```

### 跳过 SQL 执行元数据校验

跳过 SQL 执行元数据校验 SQL Hint 功能可选属性为 `SKIP_METADATA_VALIDATE``true` 表示跳过当前 SQL 执行的元数据校验。

跳过 SQL 执行元数据校验 SQL Hint 功能的使用示例:

```sql
/* SHARDINGSPHERE_HINT: SKIP_METADATA_VALIDATE=true */ SELECT * FROM t_order;
```

### 禁用 SQL 审计

禁用 SQL 审计 SQL Hint 功能可选属性为 `DISABLE_AUDIT_NAMES`,需要指定需要禁用的 SQL 审计算法名称,多个 SQL 审计算法需要使用逗号分隔。
Expand Down
29 changes: 20 additions & 9 deletions docs/document/content/user-manual/common-config/sql-hint.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ If you use the MySQL client to connect, you need to add the `-c` option to retai

The following attributes can be defined in ShardingSphere SQL Hint. In order to be compatible with the lower version SQL Hint syntax, the attributes defined in the alias can also be used:

| *Name* | *Alias* | *Data Type* | *Description* | *Default Value* |
|-----------------------------|-----------------------|-------------|---------------------------------------------------------------------------|-----------------|
| SHARDING_DATABASE_VALUE (?) | shardingDatabaseValue | Comparable | Database sharding value, used when config Hint sharding strategy | - |
| SHARDING_TABLE_VALUE (?) | shardingTableValue | Comparable | Table sharding value, used when config Hint sharding strategy | - |
| WRITE_ROUTE_ONLY (?) | writeRouteOnly | boolean | Route to the write datasource when use readwrite-splitting | false |
| DATA_SOURCE_NAME (?) | dataSourceName | String | Data source pass through, route SQL directly to the specified data source | - |
| SKIP_SQL_REWRITE (?) | skipSQLRewrite | boolean | Skip the SQL rewrite phase | false |
| DISABLE_AUDIT_NAMES (?) | disableAuditNames | String | Disable the specified SQL audit algorithm | - |
| SHADOW (?) | shadow | boolean | Route to the shadow datasource when use shadow | false |
| *Name* | *Alias* | *Data Type* | *Description* | *Default Value* |
|-------------------------------|-----------------------|-------------|------------------------------------------------------------------------|-----------------|
| SHARDING_DATABASE_VALUE (?) | shardingDatabaseValue | Comparable | Database sharding value, used when config Hint sharding strategy | - |
| SHARDING_TABLE_VALUE (?) | shardingTableValue | Comparable | Table sharding value, used when config Hint sharding strategy | - |
| WRITE_ROUTE_ONLY (?) | writeRouteOnly | boolean | Route to the write datasource when use readwrite-splitting | false |
| DATA_SOURCE_NAME (?) | dataSourceName | String | Data source pass through, route SQL directly to the specified data source | - |
| SKIP_SQL_REWRITE (?) | skipSQLRewrite | boolean | Skip the SQL rewrite phase | false |
| SKIP_METADATA_VALIDATE (?) | skipMetadataValidate | boolean | Skip the SQL metadata validate | false |
| DISABLE_AUDIT_NAMES (?) | disableAuditNames | String | Disable the specified SQL audit algorithm | - |
| SHADOW (?) | shadow | boolean | Route to the shadow datasource when use shadow | false |


## SQL Hint
Expand Down Expand Up @@ -82,6 +83,16 @@ An example of skipping SQL rewrite SQL Hint:
/* SHARDINGSPHERE_HINT: SKIP_SQL_REWRITE=true */ SELECT * FROM t_order;
```

### SKIP METADATA VALIDATE

The optional attribute of skip SQL metadata validate SQL Hint is `SKIP_METADATA_VALIDATE`, and `true` means skipping the current SQL metadata validate.

An example of skipping SQL metadata validate SQL Hint:

```sql
/* SHARDINGSPHERE_HINT: SKIP_METADATA_VALIDATE=true */ SELECT * FROM t_order;
```

### DISABLE SQL AUDIT

The optional attribute of disable SQL audit is `DISABLE_AUDIT_NAMES`, you need to specify names of SQL audit algorithm that needs to be disabled, and multiple SQL audit algorithms need to be separated by commas.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private RouteContext createRouteContext0(final QueryContext queryContext, final
SQLStatement sqlStatement = queryContext.getSqlStatementContext().getSqlStatement();
ShardingConditions shardingConditions = createShardingConditions(queryContext, globalRuleMetaData, database, rule);
Optional<ShardingStatementValidator> validator = ShardingStatementValidatorFactory.newInstance(sqlStatement, shardingConditions);
validator.ifPresent(optional -> optional.preValidate(rule, queryContext.getSqlStatementContext(), queryContext.getParameters(), database, props));
validator.ifPresent(optional -> optional.preValidate(rule, queryContext.getSqlStatementContext(), queryContext.getHintValueContext(), queryContext.getParameters(), database, props));
if (sqlStatement instanceof DMLStatement && shardingConditions.isNeedMerge()) {
shardingConditions.merge();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ public interface ShardingStatementValidator {
*
* @param shardingRule sharding rule
* @param sqlStatementContext SQL statement context
* @param hintValueContext hint value context
* @param params SQL parameters
* @param database database
* @param props props
*/
void preValidate(ShardingRule shardingRule, SQLStatementContext sqlStatementContext, List<Object> params, ShardingSphereDatabase database, ConfigurationProperties props);
void preValidate(ShardingRule shardingRule, SQLStatementContext sqlStatementContext, HintValueContext hintValueContext, List<Object> params, ShardingSphereDatabase database,
ConfigurationProperties props);

/**
* Validate whether sharding operation is supported after route.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
public final class ShardingAlterIndexStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
AlterIndexStatement alterIndexStatement = (AlterIndexStatement) sqlStatementContext.getSqlStatement();
Optional<IndexSegment> index = alterIndexStatement.getIndex();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
public final class ShardingAlterTableStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
AlterTableStatementContext alterTableStatementContext = (AlterTableStatementContext) sqlStatementContext;
Collection<String> tableNames = alterTableStatementContext.getTablesContext().getSimpleTables().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
public final class ShardingAlterViewStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
AlterViewStatement alterViewStatement = (AlterViewStatement) sqlStatementContext.getSqlStatement();
Optional<SelectStatement> selectStatement = alterViewStatement.getSelectStatement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.sharding.route.engine.validator.ddl.ShardingDDLStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.statement.core.util.TableExtractor;
import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.RoutineBodySegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateFunctionStatement;
import org.apache.shardingsphere.sql.parser.statement.core.util.TableExtractor;

import java.util.Collection;
import java.util.List;
Expand All @@ -41,7 +41,7 @@
public final class ShardingCreateFunctionStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
CreateFunctionStatement createFunctionStatement = (CreateFunctionStatement) sqlStatementContext.getSqlStatement();
Optional<RoutineBodySegment> routineBodySegment = createFunctionStatement.getRoutineBody();
Expand All @@ -51,11 +51,13 @@ public void preValidate(final ShardingRule shardingRule, final SQLStatementConte
TableExtractor extractor = new TableExtractor();
Collection<SimpleTableSegment> existTables = extractor.extractExistTableFromRoutineBody(routineBodySegment.get());
validateShardingTable(shardingRule, "CREATE FUNCTION", existTables);
String defaultSchemaName = new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName());
ShardingSphereSchema schema = createFunctionStatement.getFunctionName().flatMap(optional -> optional.getOwner()
.map(owner -> database.getSchema(owner.getIdentifier().getValue()))).orElseGet(() -> database.getSchema(defaultSchemaName));
validateTableExist(schema, existTables);
validateTableNotExist(schema, extractor.extractNotExistTableFromRoutineBody(routineBodySegment.get()));
if (!hintValueContext.isSkipMetadataValidate()) {
String defaultSchemaName = new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName());
ShardingSphereSchema schema = createFunctionStatement.getFunctionName().flatMap(optional -> optional.getOwner()
.map(owner -> database.getSchema(owner.getIdentifier().getValue()))).orElseGet(() -> database.getSchema(defaultSchemaName));
validateTableExist(schema, existTables);
validateTableNotExist(schema, extractor.extractNotExistTableFromRoutineBody(routineBodySegment.get()));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
public final class ShardingCreateIndexStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
CreateIndexStatementContext createIndexStatementContext = (CreateIndexStatementContext) sqlStatementContext;
CreateIndexStatement createIndexStatement = createIndexStatementContext.getSqlStatement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.sharding.route.engine.validator.ddl.ShardingDDLStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.statement.core.util.TableExtractor;
import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.RoutineBodySegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateProcedureStatement;
import org.apache.shardingsphere.sql.parser.statement.core.util.TableExtractor;

import java.util.Collection;
import java.util.List;
Expand All @@ -41,22 +41,24 @@
public final class ShardingCreateProcedureStatementValidator extends ShardingDDLStatementValidator {

@Override
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext, final HintValueContext hintValueContext,
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
CreateProcedureStatement createProcedureStatement = (CreateProcedureStatement) sqlStatementContext.getSqlStatement();
Optional<RoutineBodySegment> routineBodySegment = createProcedureStatement.getRoutineBody();
if (!routineBodySegment.isPresent()) {
return;
}
TableExtractor extractor = new TableExtractor();
String defaultSchemaName = new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName());
ShardingSphereSchema schema = createProcedureStatement.getProcedureName().flatMap(optional -> optional.getOwner()
.map(owner -> database.getSchema(owner.getIdentifier().getValue()))).orElseGet(() -> database.getSchema(defaultSchemaName));
Collection<SimpleTableSegment> existTables = extractor.extractExistTableFromRoutineBody(routineBodySegment.get());
validateShardingTable(shardingRule, "CREATE PROCEDURE", existTables);
validateTableExist(schema, existTables);
Collection<SimpleTableSegment> notExistTables = extractor.extractNotExistTableFromRoutineBody(routineBodySegment.get());
validateTableNotExist(schema, notExistTables);
if (!hintValueContext.isSkipMetadataValidate()) {
String defaultSchemaName = new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName());
ShardingSphereSchema schema = createProcedureStatement.getProcedureName().flatMap(optional -> optional.getOwner()
.map(owner -> database.getSchema(owner.getIdentifier().getValue()))).orElseGet(() -> database.getSchema(defaultSchemaName));
validateTableExist(schema, existTables);
Collection<SimpleTableSegment> notExistTables = extractor.extractNotExistTableFromRoutineBody(routineBodySegment.get());
validateTableNotExist(schema, notExistTables);
}
}

@Override
Expand Down
Loading

0 comments on commit ec1e1f6

Please sign in to comment.