Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IF NOT EXISTS to register storage unit statement #23066

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void assertParseRQL() {

@Test
public void assertParseRDL() {
assertParse(MetricIds.PARSE_DIST_SQL_RDL, new RegisterStorageUnitStatement(Collections.emptyList()));
assertParse(MetricIds.PARSE_DIST_SQL_RDL, new RegisterStorageUnitStatement(false, Collections.emptyList()));
}

@Test
Expand Down
4 changes: 4 additions & 0 deletions distsql/parser/src/main/antlr4/imports/Keyword.g4
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,7 @@ CENTER
LIKE
: L I K E
;

NOT
: N O T
;
6 changes: 5 additions & 1 deletion distsql/parser/src/main/antlr4/imports/RDLStatement.g4
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ grammar RDLStatement;
import BaseRule;

registerStorageUnit
: REGISTER STORAGE UNIT storageUnitDefinition (COMMA_ storageUnitDefinition)*
: REGISTER STORAGE UNIT ifNotExists? storageUnitDefinition (COMMA_ storageUnitDefinition)*
;

alterStorageUnit
Expand Down Expand Up @@ -78,3 +78,7 @@ ignoreSingleTables
ifExists
: IF EXISTS
;

ifNotExists
: IF NOT EXISTS
;
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public final class KernelDistSQLStatementVisitor extends KernelDistSQLStatementB

@Override
public ASTNode visitRegisterStorageUnit(final RegisterStorageUnitContext ctx) {
return new RegisterStorageUnitStatement(ctx.storageUnitDefinition().stream().map(each -> (DataSourceSegment) visit(each)).collect(Collectors.toList()));
return new RegisterStorageUnitStatement(null != ctx.ifNotExists(), ctx.storageUnitDefinition().stream().map(each -> (DataSourceSegment) visit(each)).collect(Collectors.toList()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@
@Getter
public final class RegisterStorageUnitStatement extends StorageUnitDefinitionStatement {

private final boolean ifNotExists;

private final Collection<DataSourceSegment> storageUnits;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@

package org.apache.shardingsphere.transaction.utils;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.LinkedList;
import org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterStorageUnitStatement;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
Expand All @@ -31,6 +27,11 @@
import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
import org.junit.Test;

import java.util.LinkedList;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public final class AutoCommitUtilsTest {

@Test
Expand All @@ -49,6 +50,6 @@ public void assertNeedOpenTransactionForDDLOrDMLStatement() {

@Test
public void assertNeedOpenTransactionForOtherStatement() {
assertFalse(AutoCommitUtils.needOpenTransaction(new RegisterStorageUnitStatement(new LinkedList<>())));
assertFalse(AutoCommitUtils.needOpenTransaction(new RegisterStorageUnitStatement(false, new LinkedList<>())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.distsql.handler.exception.resource.DuplicateResourceException;
import org.apache.shardingsphere.distsql.handler.exception.resource.InvalidResourcesException;
import org.apache.shardingsphere.distsql.handler.validate.DataSourcePropertiesValidateHandler;
import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
import org.apache.shardingsphere.distsql.parser.segment.converter.ResourceSegmentsConverter;
import org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterStorageUnitStatement;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
import org.apache.shardingsphere.distsql.handler.exception.resource.DuplicateResourceException;
import org.apache.shardingsphere.distsql.handler.exception.resource.InvalidResourcesException;
import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.util.exception.external.server.ShardingSphereServerException;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
Expand All @@ -42,8 +42,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
Expand All @@ -66,6 +68,18 @@ public RegisterStorageUnitBackendHandler(final RegisterStorageUnitStatement sqlS
public ResponseHeader execute(final String databaseName, final RegisterStorageUnitStatement sqlStatement) {
checkSQLStatement(databaseName, sqlStatement);
Map<String, DataSourceProperties> dataSourcePropsMap = ResourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits());
if (sqlStatement.isIfNotExists()) {
Set<String> currentStorageUnits = ProxyContext.getInstance().getContextManager().getDataSourceMap(databaseName).keySet();
Iterator<String> iterator = dataSourcePropsMap.keySet().iterator();
while (iterator.hasNext()) {
if (currentStorageUnits.contains(iterator.next())) {
iterator.remove();
}
}
}
if (dataSourcePropsMap.isEmpty()) {
return new UpdateResponseHeader(sqlStatement);
}
validateHandler.validate(dataSourcePropsMap);
try {
ProxyContext.getInstance().getContextManager().addResources(databaseName, dataSourcePropsMap);
Expand All @@ -79,8 +93,10 @@ public ResponseHeader execute(final String databaseName, final RegisterStorageUn
@Override
public void checkSQLStatement(final String databaseName, final RegisterStorageUnitStatement sqlStatement) {
Collection<String> dataSourceNames = new ArrayList<>(sqlStatement.getStorageUnits().size());
checkDuplicatedDataSourceNames(databaseName, dataSourceNames, sqlStatement);
checkDuplicatedDataSourceNameWithReadwriteSplittingRule(databaseName, dataSourceNames);
if (!sqlStatement.isIfNotExists()) {
checkDuplicatedDataSourceNames(databaseName, dataSourceNames, sqlStatement);
checkDuplicatedDataSourceNameWithReadwriteSplittingRule(databaseName, dataSourceNames);
}
}

private void checkDuplicatedDataSourceNames(final String databaseName, final Collection<String> dataSourceNames, final RegisterStorageUnitStatement sqlStatement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,25 @@ public void assertExecuteWithDuplicateStorageUnitNamesWithReadwriteSplittingRule
registerStorageUnitBackendHandler.execute("test_db", createRegisterStorageUnitStatement());
}

@Test
public void assertCheckStatementWithIfNotExists() {
RegisterStorageUnitStatement registerStorageUnitStatementWithIfNotExists = new RegisterStorageUnitStatement(true, Collections.singleton(
new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "db_1", "root", "", new Properties())));
registerStorageUnitBackendHandler.checkSQLStatement("test_db", registerStorageUnitStatementWithIfNotExists);
}

private ReadwriteSplittingRuleConfiguration createReadwriteSplittingRuleConfiguration(final String ruleName) {
return new ReadwriteSplittingRuleConfiguration(Collections.singleton(new ReadwriteSplittingDataSourceRuleConfiguration(ruleName, null, null, null)), Collections.emptyMap());
}

private RegisterStorageUnitStatement createRegisterStorageUnitStatement() {
return new RegisterStorageUnitStatement(Collections.singleton(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())));
return new RegisterStorageUnitStatement(false, Collections.singleton(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())));
}

private RegisterStorageUnitStatement createRegisterStorageUnitStatementWithDuplicateStorageUnitNames() {
Collection<DataSourceSegment> result = new LinkedList<>();
result.add(new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "ds_0", "root", "", new Properties()));
result.add(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties()));
return new RegisterStorageUnitStatement(result);
return new RegisterStorageUnitStatement(false, result);
}
}