This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 51e91cc add sql hint for write route only. (#13905)
51e91cc is described below
commit 51e91cc91b5e350502e0c7e2642100146f0f1edc
Author: tuichenchuxin <[email protected]>
AuthorDate: Fri Dec 3 16:58:20 2021 +0800
add sql hint for write route only. (#13905)
* add sql hint for write route only.
* add sql hint for write route only.
* add support for sql hint write route only
* add support for sql hint write route only
* add support for sql hint write route only
* add support for write route only
---
.../route/ReadwriteSplittingSQLRouter.java | 4 +-
.../impl/ReadwriteSplittingDataSourceRouter.java | 17 ++--
.../route/ReadwriteSplittingSQLRouterTest.java | 19 ++++-
.../statement/CommonSQLStatementContext.java | 17 +++-
.../infra/hint/SQLHintExtractor.java | 94 ++++++++++++++++++++++
.../infra/hint/SQLHintProperties.java | 32 ++++++++
.../infra/hint/SQLHintPropertiesKey.java | 46 +++++++++++
.../infra/hint}/SQLHintExtractorTest.java | 17 ++--
.../sql/common/extractor/SQLHintExtractor.java | 70 ----------------
9 files changed, 230 insertions(+), 86 deletions(-)
diff --git
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java
index 6bc0c4c..72e4436 100644
---
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java
+++
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java
@@ -43,7 +43,7 @@ public final class ReadwriteSplittingSQLRouter implements
SQLRouter<ReadwriteSpl
@Override
public RouteContext createRouteContext(final LogicSQL logicSQL, final
ShardingSphereMetaData metaData, final ReadwriteSplittingRule rule, final
ConfigurationProperties props) {
RouteContext result = new RouteContext();
- String dataSourceName = new
ReadwriteSplittingDataSourceRouter(rule.getSingleDataSourceRule()).route(logicSQL.getSqlStatementContext().getSqlStatement());
+ String dataSourceName = new
ReadwriteSplittingDataSourceRouter(rule.getSingleDataSourceRule()).route(logicSQL.getSqlStatementContext());
result.getRouteUnits().add(new RouteUnit(new
RouteMapper(DefaultSchema.LOGIC_NAME, dataSourceName),
Collections.emptyList()));
return result;
}
@@ -58,7 +58,7 @@ public final class ReadwriteSplittingSQLRouter implements
SQLRouter<ReadwriteSpl
Optional<ReadwriteSplittingDataSourceRule> dataSourceRule =
rule.findDataSourceRule(dataSourceName);
if (dataSourceRule.isPresent() &&
dataSourceRule.get().getName().equalsIgnoreCase(each.getDataSourceMapper().getActualName()))
{
toBeRemoved.add(each);
- String actualDataSourceName = new
ReadwriteSplittingDataSourceRouter(dataSourceRule.get()).route(logicSQL.getSqlStatementContext().getSqlStatement());
+ String actualDataSourceName = new
ReadwriteSplittingDataSourceRouter(dataSourceRule.get()).route(logicSQL.getSqlStatementContext());
toBeAdded.add(new RouteUnit(new
RouteMapper(each.getDataSourceMapper().getLogicName(), actualDataSourceName),
each.getTableMappers()));
}
}
diff --git
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
index 7110ac9..b371123 100644
---
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
+++
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
@@ -21,6 +21,8 @@ import com.google.common.base.Strings;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.infra.aware.DataSourceNameAware;
import org.apache.shardingsphere.infra.aware.DataSourceNameAwareFactory;
+import
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.hint.HintManager;
import org.apache.shardingsphere.transaction.TransactionHolder;
import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
@@ -43,11 +45,11 @@ public final class ReadwriteSplittingDataSourceRouter {
/**
* Route.
*
- * @param sqlStatement SQL statement
+ * @param sqlStatementContext SQL statement context
* @return data source name
*/
- public String route(final SQLStatement sqlStatement) {
- if (isPrimaryRoute(sqlStatement)) {
+ public String route(final SQLStatementContext<?> sqlStatementContext) {
+ if (isPrimaryRoute(sqlStatementContext)) {
String autoAwareDataSourceName = rule.getAutoAwareDataSourceName();
if (Strings.isNullOrEmpty(autoAwareDataSourceName)) {
return rule.getWriteDataSourceName();
@@ -69,8 +71,13 @@ public final class ReadwriteSplittingDataSourceRouter {
return rule.getLoadBalancer().getDataSource(rule.getName(),
rule.getWriteDataSourceName(), rule.getReadDataSourceNames());
}
- private boolean isPrimaryRoute(final SQLStatement sqlStatement) {
- return containsLockSegment(sqlStatement) || !(sqlStatement instanceof
SelectStatement) || HintManager.isWriteRouteOnly() ||
TransactionHolder.isTransaction();
+ private boolean isPrimaryRoute(final SQLStatementContext<?>
sqlStatementContext) {
+ SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
+ return containsLockSegment(sqlStatement) || !(sqlStatement instanceof
SelectStatement) || isHintWriteRouteOnly(sqlStatementContext) ||
TransactionHolder.isTransaction();
+ }
+
+ private boolean isHintWriteRouteOnly(final SQLStatementContext<?>
sqlStatementContext) {
+ return HintManager.isWriteRouteOnly() || (sqlStatementContext
instanceof CommonSQLStatementContext && ((CommonSQLStatementContext<?>)
sqlStatementContext).isHintWriteRouteOnly());
}
private boolean containsLockSegment(final SQLStatement sqlStatement) {
diff --git
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
index b0621ee..43c0931 100644
---
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
+++
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
@@ -18,7 +18,9 @@
package org.apache.shardingsphere.readwritesplitting.route;
import org.apache.shardingsphere.infra.binder.LogicSQL;
+import
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
import
org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.resource.ShardingSphereResource;
@@ -36,6 +38,7 @@ import
org.apache.shardingsphere.spi.ordered.OrderedSPIRegistry;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.LockSegment;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
+import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLInsertStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
import org.junit.Before;
@@ -69,7 +72,7 @@ public final class ReadwriteSplittingSQLRouterTest {
private ReadwriteSplittingRule rule;
@Mock
- private SQLStatementContext<SQLStatement> sqlStatementContext;
+ private CommonSQLStatementContext<SQLStatement> sqlStatementContext;
private ReadwriteSplittingSQLRouter sqlRouter;
@@ -192,6 +195,20 @@ public final class ReadwriteSplittingSQLRouterTest {
assertThat(routedDataSourceNames.next(), is(READ_DATASOURCE));
}
+ @Test
+ public void assertSqlHintRouteWriteOnly() {
+ SelectStatement statement = mock(SelectStatement.class);
+ CommonSQLStatementContext<SelectStatement> sqlStatementContext =
mock(SelectStatementContext.class);
+ when(sqlStatementContext.getSqlStatement()).thenReturn(statement);
+ when(sqlStatementContext.isHintWriteRouteOnly()).thenReturn(true);
+ LogicSQL logicSQL = new LogicSQL(sqlStatementContext, "",
Collections.emptyList());
+ ShardingSphereRuleMetaData ruleMetaData = new
ShardingSphereRuleMetaData(Collections.emptyList(),
Collections.singleton(rule));
+ ShardingSphereMetaData metaData = new
ShardingSphereMetaData("logic_schema", mock(ShardingSphereResource.class,
RETURNS_DEEP_STUBS), ruleMetaData, mock(ShardingSphereSchema.class));
+ RouteContext actual = sqlRouter.createRouteContext(logicSQL, metaData,
rule, new ConfigurationProperties(new Properties()));
+ Iterator<String> routedDataSourceNames =
actual.getActualDataSourceNames().iterator();
+ assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE));
+ }
+
private RouteContext mockRouteContext() {
RouteContext result = new RouteContext();
RouteUnit routeUnit = new RouteUnit(new RouteMapper(DATASOURCE_NAME,
DATASOURCE_NAME), Collections.singletonList(new RouteMapper("table",
"table_0")));
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
index 30ae5ac..1d2d0e0 100644
---
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
@@ -21,8 +21,7 @@ import lombok.Getter;
import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;
-import
org.apache.shardingsphere.sql.parser.sql.common.extractor.SQLHintExtractor;
-import
org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
+import org.apache.shardingsphere.infra.hint.SQLHintExtractor;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.MySQLStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.opengauss.OpenGaussStatement;
@@ -48,10 +47,13 @@ public class CommonSQLStatementContext<T extends
SQLStatement> implements SQLSta
private final DatabaseType databaseType;
+ private final SQLHintExtractor sqlHintExtractor;
+
public CommonSQLStatementContext(final T sqlStatement) {
this.sqlStatement = sqlStatement;
tablesContext = new TablesContext(Collections.emptyList());
databaseType = getDatabaseType(sqlStatement);
+ sqlHintExtractor = new SQLHintExtractor(sqlStatement);
}
private DatabaseType getDatabaseType(final SQLStatement sqlStatement) {
@@ -82,6 +84,15 @@ public class CommonSQLStatementContext<T extends
SQLStatement> implements SQLSta
* @return dataSource name
*/
public Optional<String> findHintDataSourceName() {
- return SQLHintExtractor.findHintDataSourceName((AbstractSQLStatement)
sqlStatement);
+ return sqlHintExtractor.findHintDataSourceName();
+ }
+
+ /**
+ * Judge whether is hint routed to write data source or not.
+ *
+ * @return whether is hint routed to write data source or not
+ */
+ public boolean isHintWriteRouteOnly() {
+ return sqlHintExtractor.isHintWriteRouteOnly();
}
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
new file mode 100644
index 0000000..05f1406
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
@@ -0,0 +1,94 @@
+/*
+ * 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.hint;
+
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+
+import java.util.Optional;
+import java.util.Properties;
+
+/**
+ * SQL hint extractor.
+ */
+public final class SQLHintExtractor {
+
+ private static final String SQL_COMMENT_SUFFIX = "*/";
+
+ private static final String SQL_HINT_TOKEN = "shardingsphere hint:";
+
+ private static final String SQL_HINT_SPLIT = "=";
+
+ private final SQLHintProperties sqlHintProperties;
+
+ public SQLHintExtractor(final SQLStatement sqlStatement) {
+ sqlHintProperties = sqlStatement instanceof AbstractSQLStatement ?
extract((AbstractSQLStatement) sqlStatement) : new SQLHintProperties(new
Properties());
+ }
+
+ /**
+ * Extract from statement.
+ *
+ * @param statement statement
+ * @return sql hint properties
+ */
+ public SQLHintProperties extract(final AbstractSQLStatement statement) {
+ Properties properties = new Properties();
+ for (CommentSegment each : statement.getCommentSegments()) {
+ appendHintProperties(each.getText(), properties);
+ }
+ return new SQLHintProperties(properties);
+ }
+
+ private void appendHintProperties(final String comment, final Properties
properties) {
+ int startIndex = comment.toLowerCase().indexOf(SQL_HINT_TOKEN);
+ if (startIndex < 0) {
+ return;
+ }
+ startIndex = startIndex + SQL_HINT_TOKEN.length();
+ int endIndex = comment.endsWith(SQL_COMMENT_SUFFIX) ?
comment.indexOf(SQL_COMMENT_SUFFIX) : comment.length();
+ String[] hintValue = comment.substring(startIndex,
endIndex).trim().split(SQL_HINT_SPLIT);
+ if (2 == hintValue.length && hintValue[0].trim().length() > 0 &&
hintValue[1].trim().length() > 0) {
+ if
(SQLHintPropertiesKey.DATASOURCE_NAME_KEY.getKey().equalsIgnoreCase(hintValue[0].trim()))
{
+
properties.setProperty(SQLHintPropertiesKey.DATASOURCE_NAME_KEY.getKey(),
hintValue[1].trim());
+ }
+ if
(SQLHintPropertiesKey.WRITE_ROUTE_ONLY_KEY.getKey().equalsIgnoreCase(hintValue[0].trim()))
{
+
properties.setProperty(SQLHintPropertiesKey.WRITE_ROUTE_ONLY_KEY.getKey(),
hintValue[1].trim());
+ }
+ }
+ }
+
+ /**
+ * Find hint data source name.
+ *
+ * @return data source name
+ */
+ public Optional<String> findHintDataSourceName() {
+ String result =
sqlHintProperties.getValue(SQLHintPropertiesKey.DATASOURCE_NAME_KEY);
+ return result.isEmpty() ? Optional.empty() : Optional.of(result);
+ }
+
+ /**
+ * Judge whether is hint routed to write data source or not.
+ *
+ * @return whether is hint routed to write data source or not
+ */
+ public boolean isHintWriteRouteOnly() {
+ return
sqlHintProperties.getValue(SQLHintPropertiesKey.WRITE_ROUTE_ONLY_KEY);
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintProperties.java
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintProperties.java
new file mode 100644
index 0000000..fb2dac0
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintProperties.java
@@ -0,0 +1,32 @@
+/*
+ * 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.hint;
+
+import org.apache.shardingsphere.infra.properties.TypedProperties;
+
+import java.util.Properties;
+
+/**
+ * SQL Hint properties.
+ */
+public final class SQLHintProperties extends
TypedProperties<SQLHintPropertiesKey> {
+
+ public SQLHintProperties(final Properties props) {
+ super(SQLHintPropertiesKey.class, props);
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
new file mode 100644
index 0000000..3b3fe25
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
@@ -0,0 +1,46 @@
+/*
+ * 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.hint;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.properties.TypedPropertyKey;
+
+/**
+ * Typed property key of SQL Hint.
+ */
+@Getter
+@RequiredArgsConstructor
+public enum SQLHintPropertiesKey implements TypedPropertyKey {
+
+ /**
+ * Hint data source name.
+ */
+ DATASOURCE_NAME_KEY("dataSourceName", "", String.class),
+
+ /**
+ * Whether hint route write data source or not.
+ */
+ WRITE_ROUTE_ONLY_KEY("writeRouteOnly", String.valueOf(Boolean.FALSE),
boolean.class);
+
+ private final String key;
+
+ private final String defaultValue;
+
+ private final Class<?> type;
+}
diff --git
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractorTest.java
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
similarity index 72%
rename from
shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractorTest.java
rename to
shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
index 3c9fb35..b1ec3a3 100644
---
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractorTest.java
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.sql.parser.sql.common.extractor;
+package org.apache.shardingsphere.infra.hint;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
@@ -36,24 +36,31 @@ public final class SQLHintExtractorTest {
@Test
public void assertFindHintDataSourceNameExist() {
AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
-
when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new
CommentSegment("/* sql hint: datasourceName=ds_1 */", 0, 0)));
- Optional<String> dataSourceName =
SQLHintExtractor.findHintDataSourceName(statement);
+
when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new
CommentSegment("/* ShardingSphere hint: dataSourceName=ds_1 */", 0, 0)));
+ Optional<String> dataSourceName = new
SQLHintExtractor(statement).findHintDataSourceName();
assertTrue(dataSourceName.isPresent());
assertThat(dataSourceName.get(), is("ds_1"));
}
@Test
+ public void assertSQLHintWriteRouteOnly() {
+ AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
+
when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new
CommentSegment("/* ShardingSphere hint: writeRouteOnly=true */", 0, 0)));
+ assertTrue(new SQLHintExtractor(statement).isHintWriteRouteOnly());
+ }
+
+ @Test
public void assertFindHintDataSourceNameNotExist() {
AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new
CommentSegment("/* no hint */", 0, 0)));
- Optional<String> dataSourceName =
SQLHintExtractor.findHintDataSourceName(statement);
+ Optional<String> dataSourceName = new
SQLHintExtractor(statement).findHintDataSourceName();
assertFalse(dataSourceName.isPresent());
}
@Test
public void assertFindHintDataSourceNameNotExistWithoutComment() {
AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
- Optional<String> dataSourceName =
SQLHintExtractor.findHintDataSourceName(statement);
+ Optional<String> dataSourceName = new
SQLHintExtractor(statement).findHintDataSourceName();
assertFalse(dataSourceName.isPresent());
}
}
diff --git
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractor.java
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractor.java
deleted file mode 100644
index 7388cb3..0000000
---
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/SQLHintExtractor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.sql.parser.sql.common.extractor;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
-
-import java.util.Optional;
-
-/**
- * SQL hint extractor.
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class SQLHintExtractor {
-
- private static final String SQL_COMMENT_SUFFIX = "*/";
-
- private static final String SQL_HINT_TOKEN = "sql hint:";
-
- private static final String SQL_HINT_SPLIT = "=";
-
- private static final String SQL_HINT_DATASOURCE_NAME_KEY =
"datasourcename";
-
- /**
- * Find hint data source name.
- *
- * @param statement statement
- * @return data source name
- */
- public static Optional<String> findHintDataSourceName(final
AbstractSQLStatement statement) {
- for (CommentSegment each : statement.getCommentSegments()) {
- Optional<String> result =
findDataSourceNameFromComment(each.getText());
- if (result.isPresent()) {
- return result;
- }
- }
- return Optional.empty();
- }
-
- private static Optional<String> findDataSourceNameFromComment(final String
comment) {
- int startIndex = comment.toLowerCase().indexOf(SQL_HINT_TOKEN);
- if (startIndex < 0) {
- return Optional.empty();
- }
- startIndex = startIndex + SQL_HINT_TOKEN.length();
- int endIndex = comment.endsWith(SQL_COMMENT_SUFFIX) ?
comment.indexOf(SQL_COMMENT_SUFFIX) : comment.length();
- String[] hintValue = comment.substring(startIndex,
endIndex).trim().split(SQL_HINT_SPLIT);
- if (2 == hintValue.length &&
SQL_HINT_DATASOURCE_NAME_KEY.equalsIgnoreCase(hintValue[0].trim()) &&
hintValue[1].trim().length() > 0) {
- return Optional.of(hintValue[1].trim());
- }
- return Optional.empty();
- }
-}