jingshanglu commented on a change in pull request #9239:
URL: https://github.com/apache/shardingsphere/pull/9239#discussion_r567545921



##########
File path: 
shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/hint/AbstractHintSegment.java
##########
@@ -0,0 +1,35 @@
+/*
+ * 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.segment.dml.hint;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+
+/**
+ * AbstractHintSegment.
+ */
+@RequiredArgsConstructor
+@Getter
+public abstract class AbstractHintSegment implements SQLSegment {
+
+    private final int startIndex;
+
+    private final int stopIndex;
+

Review comment:
       Delete the empty line.

##########
File path: 
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
##########
@@ -237,6 +237,31 @@ withClause
     : WITH RECURSIVE? cteClause (COMMA_ cteClause)*
     ;
 
+hintComment
+    : SLASH_ ASTERISK_ NOT_ (databaseHintComment| shardingHintComment) 
ASTERISK_ SLASH_
+    ;
+
+databaseHintComment
+    : DATABASESHARDING LP_ identifier RP_
+    ;
+
+shardingHintComment
+    : shardingDatabaseHintComment? shardingTableHintComment?
+    | shardingTableHintComment? shardingDatabaseHintComment?
+    ;

Review comment:
       @jackyLqq There is a conflict between the two branches.

##########
File path: 
shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-route/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/hint/ShardingHintRoutingEngine.java
##########
@@ -0,0 +1,129 @@
+/*
+ * 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.sharding.route.engine.type.hint;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import 
org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
+import org.apache.shardingsphere.infra.datanode.DataNode;
+import org.apache.shardingsphere.infra.route.context.RouteContext;
+import org.apache.shardingsphere.infra.route.context.RouteMapper;
+import org.apache.shardingsphere.infra.route.context.RouteUnit;
+import 
org.apache.shardingsphere.sharding.api.config.strategy.sharding.ShardingStrategyConfiguration;
+import 
org.apache.shardingsphere.sharding.route.engine.condition.generator.ConditionValue;
+import 
org.apache.shardingsphere.sharding.route.engine.condition.value.ListShardingConditionValue;
+import 
org.apache.shardingsphere.sharding.route.engine.type.ShardingRouteEngine;
+import org.apache.shardingsphere.sharding.route.strategy.ShardingStrategy;
+import 
org.apache.shardingsphere.sharding.route.strategy.ShardingStrategyFactory;
+import 
org.apache.shardingsphere.sharding.route.strategy.type.none.NoneShardingStrategy;
+import org.apache.shardingsphere.sharding.rule.ShardingRule;
+import org.apache.shardingsphere.sharding.rule.TableRule;
+import org.apache.shardingsphere.sharding.spi.ShardingAlgorithm;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.hint.ShardingHintValueSegment;
+
+/**
+ * ShardingSqlHintRoutingEngine.
+ */
+
+@RequiredArgsConstructor
+public class ShardingHintRoutingEngine implements ShardingRouteEngine {
+
+    private final String logicTableName;
+
+    private final ConfigurationProperties properties;
+
+    private final SelectStatementContext selectStatementContext;
+
+    @Override
+    public void route(final RouteContext routeContext, final ShardingRule 
shardingRule) {
+        Collection<DataNode> dataNodes = getDataNodes(shardingRule, 
shardingRule.getTableRule(logicTableName), selectStatementContext);
+        for (DataNode each : dataNodes) {
+            routeContext.getRouteUnits().add(
+                    new RouteUnit(new RouteMapper(each.getDataSourceName(), 
each.getDataSourceName()), Collections.singletonList(new 
RouteMapper(logicTableName, each.getTableName()))));
+        }
+
+    }
+
+    private Collection<DataNode> route(final TableRule tableRule, final 
ShardingStrategy databaseShardingStrategy, final ShardingHintValueSegment 
shardingDatabaseHintValueSegment,
+                                       final ShardingStrategy 
tableShardingStrategy, final ShardingHintValueSegment 
shardingTableHintValueSegment) {
+        Collection<String> routedDataSources = 
routeDataSourcesByHint(tableRule, databaseShardingStrategy, 
shardingDatabaseHintValueSegment);
+        Collection<DataNode> result = new LinkedList<>();
+        for (String each : routedDataSources) {
+            result.addAll(routeTablesByHint(tableRule, each, 
tableShardingStrategy, shardingTableHintValueSegment));
+        }
+        return result;
+    }
+
+    private Collection<DataNode> getDataNodes(final ShardingRule shardingRule, 
final TableRule tableRule, final SelectStatementContext selectStatementContext) 
{
+        ShardingStrategy databaseShardingStrategy = 
createShardingStrategy(shardingRule.getDatabaseShardingStrategyConfiguration(tableRule),
 shardingRule.getShardingAlgorithms());
+        ShardingStrategy tableShardingStrategy = 
createShardingStrategy(shardingRule.getTableShardingStrategyConfiguration(tableRule),
 shardingRule.getShardingAlgorithms());
+        return route(tableRule, databaseShardingStrategy, 
selectStatementContext.getHintContext().getShardingHintSegment().getShardingDatabaseHintValueSegment(),
+                tableShardingStrategy, 
selectStatementContext.getHintContext().getShardingHintSegment().getShardingTableHintValueSegment());
+    }
+
+    private Collection<String> routeDataSourcesByHint(final TableRule 
tableRule, final ShardingStrategy databaseShardingStrategy, final 
ShardingHintValueSegment shardingDatabaseHintValueSegment) {
+        Collection<String> datasourceNames = 
tableRule.getActualDatasourceNames();
+        if (shardingDatabaseHintValueSegment != null) {
+            List<ExpressionSegment> databaseHintValueSegmentValues = 
shardingDatabaseHintValueSegment.getValues();
+            ListShardingConditionValue<Comparable<?>> listShardingValue = 
getListShardingValueFromHint(databaseHintValueSegmentValues, 
databaseShardingStrategy);
+            datasourceNames = new 
LinkedHashSet<>(databaseShardingStrategy.doSharding(datasourceNames, 
Collections.singletonList(listShardingValue), properties));
+        } 
+        Preconditions.checkState(!datasourceNames.isEmpty(), "no database 
route info");
+        
Preconditions.checkState(tableRule.getActualDatasourceNames().containsAll(datasourceNames),
+                "Some routed data sources do not belong to configured data 
sources. routed data sources: `%s`, configured data sources: `%s`", 
datasourceNames, tableRule.getActualDatasourceNames());
+        return datasourceNames;
+    }
+
+    private ListShardingConditionValue<Comparable<?>> 
getListShardingValueFromHint(final List<ExpressionSegment> 
databaseHintValueSegmentValues, final ShardingStrategy shardingStrategy) {
+        Collection<Comparable<?>> shardingConditionValues = new 
LinkedHashSet<>();
+        for (ExpressionSegment expressionSegment : 
databaseHintValueSegmentValues) {
+            new ConditionValue(expressionSegment, 
Collections.emptyList()).getValue().ifPresent(shardingConditionValues::add);
+        }
+        return new 
ListShardingConditionValue<>(shardingStrategy.getShardingColumns().iterator().next(),
 logicTableName, shardingConditionValues);
+    }
+
+    private Collection<? extends DataNode> routeTablesByHint(final TableRule 
tableRule, final String routedDataSource,
+                                                             final 
ShardingStrategy tableShardingStrategy, final ShardingHintValueSegment 
shardingTableHintValueSegment) {
+        Collection<String> availableTargetTables = 
tableRule.getActualTableNames(routedDataSource);
+        if (shardingTableHintValueSegment != null) {
+            ListShardingConditionValue<Comparable<?>> listShardingValue = 
getListShardingValueFromHint(shardingTableHintValueSegment.getValues(), 
tableShardingStrategy);
+            availableTargetTables = 
tableShardingStrategy.doSharding(availableTargetTables, 
Collections.singletonList(listShardingValue), properties);
+        }
+        Collection<DataNode> result = new LinkedList<>();
+        for (String each : availableTargetTables) {
+            result.add(new DataNode(routedDataSource, each));
+        }
+        return result;
+    }
+
+    private ShardingStrategy createShardingStrategy(final 
ShardingStrategyConfiguration shardingStrategyConfig, final Map<String, 
ShardingAlgorithm> shardingAlgorithms) {
+        return null == shardingStrategyConfig ? new NoneShardingStrategy()
+                : ShardingStrategyFactory.newInstance(shardingStrategyConfig, 
shardingAlgorithms.get(shardingStrategyConfig.getShardingAlgorithmName()));
+    }
+

Review comment:
       Plz delete the empty line.

##########
File path: 
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatTest.java
##########
@@ -117,7 +117,7 @@
                 + "FROM t_order\n"
                 + "WHERE \n"
                 + "\torder_id = 1;"});
-        testUnits.add(new String[]{"only_comment", "/* c_zz_xdba_test_4 login 
*/", ""});
+        // testUnits.add(new String[]{"only_comment", "/* c_zz_xdba_test_4 
login */", ""});

Review comment:
       why delete the case?

##########
File path: 
shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/hint/HintContextEngineTest.java
##########
@@ -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.
+ */
+
+package org.apache.shardingsphere.infra.binder.segment.select.hint;
+
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.hint.DataBaseHintSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.hint.HintSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.hint.ShardingHintSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.hint.ShardingHintValueSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * HintContextEngineTest.
+ */
+public final class HintContextEngineTest {
+
+    @Test
+    public void testCreateHintContextForCommonSql() {
+        HintContext hintContext = new 
HintContextEngine().createHintContext(new MySQLSelectStatement());
+        Assert.assertEquals(HintType.NONE, hintContext.getHintType());
+    }
+
+    @Test
+    public void testCreateHintContextForDataBaseHint() {
+        MySQLSelectStatement mySQLSelectStatement = new MySQLSelectStatement();
+        mySQLSelectStatement.setHint(new HintSegment(0, 52, new 
DataBaseHintSegment(3, 50, new IdentifierValue("ds_0"))));
+        HintContext hintContext = new 
HintContextEngine().createHintContext(mySQLSelectStatement);
+        Assert.assertEquals(HintType.DATABASE_HINT, hintContext.getHintType());
+    }
+
+    @Test
+    public void testCreateHintContextForShardingValueHint() {
+        ShardingHintValueSegment shardingDatabaseHintValueSegment = new 
ShardingHintValueSegment(10, 50);
+        shardingDatabaseHintValueSegment.getValues().add(new 
LiteralExpressionSegment(20, 40, 1));
+        ShardingHintValueSegment shardingTableHintValueSegment = new 
ShardingHintValueSegment(50, 90);
+        shardingTableHintValueSegment.getValues().add(new 
LiteralExpressionSegment(60, 80, 1));
+        ShardingHintSegment shardingHintSegment = new ShardingHintSegment(10, 
90);
+        
shardingHintSegment.setShardingDatabaseHintValueSegment(shardingDatabaseHintValueSegment);
+        
shardingHintSegment.setShardingTableHintValueSegment(shardingTableHintValueSegment);
+        MySQLSelectStatement mySQLSelectStatement = new MySQLSelectStatement();
+        mySQLSelectStatement.setHint(new HintSegment(0, 100, 
shardingHintSegment));
+        HintContext hintContext = new 
HintContextEngine().createHintContext(mySQLSelectStatement);
+        Assert.assertEquals(HintType.SHARDING_HINT, hintContext.getHintType());
+    }
+    

Review comment:
       Plz delete the empty line.

##########
File path: 
shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-comment.xml
##########
@@ -17,6 +17,6 @@
   -->
 
 <sql-cases>
-    <sql-case id="select_with_block_comment" value="SELECT * /* this is 
&#x000D;&#x000A; block comment */ FROM /* this is another &#x000A; block 
comment */ t_order where status='1'" db-types="MySQL" />
+   <!-- <sql-case id="select_with_block_comment" value="SELECT * /* this is 
&#x000D;&#x000A; block comment */ FROM /* this is another &#x000A; block 
comment */ t_order where status='1'" db-types="MySQL" />-->

Review comment:
       We should not delete exist test case.

##########
File path: 
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/Keyword.g4
##########
@@ -115,3 +115,15 @@ INNODB
 REDO_LOG
     : 'REDO_LOG'
     ;
+
+DATABASESHARDING
+    : D A T A B A S E S H A R D I N G
+    ;
+
+SHARDINGDATABASEVALUE
+    : S H A R D I N G D A T A B A S E V A L U E
+    ;
+
+SHARDINGTABLEVALUE
+    : S H A R D I N G T A B L E V A L U E
+    ;

Review comment:
       A blank line is required at the end of the file.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to