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 86c83c78f49 Fix the error in parsing the MySQL query with index hints. 
(#31643)
86c83c78f49 is described below

commit 86c83c78f49afb8f3cd918513bdc5de9774d17c7
Author: HAibiiin <[email protected]>
AuthorDate: Tue Jun 11 11:33:24 2024 +0800

    Fix the error in parsing the MySQL query with index hints. (#31643)
---
 .../src/main/antlr4/imports/mysql/DMLStatement.g4  | 13 ++++-
 .../statement/type/MySQLDMLStatementVisitor.java   | 10 ++--
 .../parser/src/main/resources/case/dml/select.xml  | 56 ++++++++++++++++++++++
 .../main/resources/sql/supported/dml/select.xml    |  3 ++
 4 files changed, 76 insertions(+), 6 deletions(-)

diff --git 
a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4 
b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
index 3eb5388f6ca..fae20c6ebe0 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
@@ -300,11 +300,20 @@ partitionNames
     ;
 
 indexHintList
-    : indexHint (COMMA_ indexHint)*
+    : indexHint (indexHint)*
     ;
 
 indexHint
-    : (USE | IGNORE | FORCE) (INDEX | KEY) (FOR (JOIN | ORDER BY | GROUP BY))? 
LP_ indexName (COMMA_ indexName)* RP_
+    : USE (INDEX | KEY) indexHintClause LP_ (indexNameList)? RP_
+    | (IGNORE | FORCE) (INDEX | KEY) indexHintClause LP_ indexNameList RP_
+    ;
+
+indexHintClause
+    : (FOR (JOIN | ORDER BY | GROUP BY))?
+    ;
+
+indexNameList
+    : indexName (COMMA_ indexName)*
     ;
 
 joinedTable
diff --git 
a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDMLStatementVisitor.java
 
b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDMLStatementVisitor.java
index dffa3a770f0..b8e2466280d 100644
--- 
a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDMLStatementVisitor.java
+++ 
b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDMLStatementVisitor.java
@@ -105,7 +105,9 @@ public final class MySQLDMLStatementVisitor extends 
MySQLStatementVisitor implem
     @Override
     public ASTNode visitIndexHint(final IndexHintContext ctx) {
         Collection<String> indexNames = new LinkedList<>();
-        ctx.indexName().forEach(each -> indexNames.add(each.getText()));
+        if (null != ctx.indexNameList()) {
+            ctx.indexNameList().indexName().forEach(each -> 
indexNames.add(each.getText()));
+        }
         String useType;
         if (null != ctx.USE()) {
             useType = ctx.USE().getText();
@@ -116,11 +118,11 @@ public final class MySQLDMLStatementVisitor extends 
MySQLStatementVisitor implem
         }
         IndexHintSegment result = new 
IndexHintSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 
indexNames, useType,
                 null == ctx.INDEX() ? ctx.KEY().getText() : 
ctx.INDEX().getText(), getOriginalText(ctx));
-        if (null != ctx.FOR()) {
+        if (null != ctx.indexHintClause().FOR()) {
             String hintScope;
-            if (null != ctx.JOIN()) {
+            if (null != ctx.indexHintClause().JOIN()) {
                 hintScope = "JOIN";
-            } else if (null != ctx.ORDER()) {
+            } else if (null != ctx.indexHintClause().ORDER()) {
                 hintScope = "ORDER BY";
             } else {
                 hintScope = "GROUP BY";
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml 
b/test/it/parser/src/main/resources/case/dml/select.xml
index ada265f45ef..355d31ac6d2 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -9419,4 +9419,60 @@
             <simple-table name="pg_index" start-index="66" stop-index="73"/>
         </from>
     </select>
+
+    <select sql-case-id="select_with_index_hints1">
+        <projections start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7" />
+        </projections>
+        <from>
+            <simple-table name="t1" start-index="14" stop-index="15">
+                <index-hint origin-text="USE INDEX (i1)" start-index="17" 
stop-index="30">
+                    <hint-index-name name="i1" start-index="28" 
stop-index="29"/>
+                </index-hint>
+                <index-hint origin-text="IGNORE INDEX (i2)" start-index="32" 
stop-index="48">
+                    <hint-index-name name="i2" start-index="46" 
stop-index="47"/>
+                </index-hint>
+                <index-hint origin-text="USE INDEX (i2)" start-index="50" 
stop-index="63">
+                    <hint-index-name name="i2" start-index="61" 
stop-index="62"/>
+                </index-hint>
+            </simple-table>
+        </from>
+    </select>
+
+    <select sql-case-id="select_with_index_hints2">
+        <projections start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7" />
+        </projections>
+        <from>
+            <simple-table name="t1" start-index="14" stop-index="15">
+                <index-hint origin-text="USE INDEX ()" start-index="17" 
stop-index="28"/>
+                <index-hint origin-text="IGNORE INDEX (i2)" start-index="30" 
stop-index="46">
+                    <hint-index-name name="i2" start-index="44" 
stop-index="45"/>
+                </index-hint>
+                <index-hint origin-text="USE INDEX (i1)" start-index="48" 
stop-index="61">
+                    <hint-index-name name="i1" start-index="59" 
stop-index="60"/>
+                </index-hint>
+                <index-hint origin-text="USE INDEX (i2)" start-index="63" 
stop-index="66">
+                    <hint-index-name name="i2" start-index="74" 
stop-index="75"/>
+                </index-hint>
+            </simple-table>
+        </from>
+    </select>
+
+    <select sql-case-id="select_with_index_hints3">
+        <projections start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7" />
+        </projections>
+        <from>
+            <simple-table name="t1" start-index="14" stop-index="15">
+                <index-hint origin-text="USE INDEX (i1,i2)" start-index="17" 
stop-index="33">
+                    <hint-index-name name="i1" start-index="28" 
stop-index="29"/>
+                    <hint-index-name name="i2" start-index="31" 
stop-index="32"/>
+                </index-hint>
+                <index-hint origin-text="IGNORE INDEX (i2)" start-index="35" 
stop-index="51">
+                    <hint-index-name name="i2" start-index="49" 
stop-index="50"/>
+                </index-hint>
+            </simple-table>
+        </from>
+    </select>
 </sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 4cd3faf83ec..90bf6299c35 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -277,4 +277,7 @@
     <sql-case id="select_hour_from_table" value="select hour from table1" 
db-types="SQLServer"/>
     <sql-case id="select_minute_from_table" value="select minute from table1" 
db-types="SQLServer"/>
     <sql-case id="select_with_collation_keyword" value="SELECT pg_get_expr  AS 
CONSTRAINT ,indcollation AS COLLATION FROM pg_index" db-types="PostgreSQL"/>
+    <sql-case id="select_with_index_hints1" value="SELECT * FROM t1 USE INDEX 
(i1) IGNORE INDEX (i2) USE INDEX (i2);" db-types="MySQL"/>
+    <sql-case id="select_with_index_hints2" value="SELECT * FROM t1 USE INDEX 
() IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2);" db-types="MySQL"/>
+    <sql-case id="select_with_index_hints3" value="SELECT * FROM t1 USE INDEX 
(i1,i2) IGNORE INDEX (i2);" db-types="MySQL"/>
 </sql-cases>

Reply via email to