Skip to content

Commit 6db15d2

Browse files
joeymartwumpz
authored andcommitted
Introduce support for mysql index hints (fixing issue #374) (#429)
* Introduce support for mysql index hints (fixing issue #374) * Fix checkstyle errors -Converted indent tabs to spaces -Added missing {} on single-line if statement
1 parent f11133c commit 6db15d2

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2017 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.expression;
23+
24+
import java.util.List;
25+
26+
public class MySQLIndexHint {
27+
28+
private final String action;
29+
private final String indexQualifier;
30+
private final List<String> indexNames;
31+
32+
public MySQLIndexHint(String action, String indexQualifier, List<String> indexNames) {
33+
this.action = action;
34+
this.indexQualifier = indexQualifier;
35+
this.indexNames = indexNames;
36+
}
37+
38+
@Override
39+
public String toString() {
40+
// use|ignore|force key|index (index1,...,indexN)
41+
StringBuilder buffer = new StringBuilder();
42+
buffer.append(" ").append(action).append(" ").append(indexQualifier).append(" (");
43+
for (int i = 0; i < indexNames.size(); i++) {
44+
if (i > 0) {
45+
buffer.append(",");
46+
}
47+
buffer.append(indexNames.get(i));
48+
}
49+
buffer.append(")");
50+
return buffer.toString();
51+
}
52+
}

src/main/java/net/sf/jsqlparser/schema/Table.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class Table extends ASTNodeAccessImpl implements FromItem, MultiPartName
3636

3737
private Alias alias;
3838
private Pivot pivot;
39+
private MySQLIndexHint hint;
3940

4041
public Table() {
4142
}
@@ -133,10 +134,19 @@ public void setPivot(Pivot pivot) {
133134
this.pivot = pivot;
134135
}
135136

137+
public MySQLIndexHint getIndexHint() {
138+
return hint;
139+
}
140+
141+
public void setHint(MySQLIndexHint hint) {
142+
this.hint = hint;
143+
}
144+
136145
@Override
137146
public String toString() {
138147
return getFullyQualifiedName()
139148
+ ((pivot != null) ? " " + pivot : "")
140-
+ ((alias != null) ? alias.toString() : "");
149+
+ ((alias != null) ? alias.toString() : "")
150+
+ ((hint != null) ? hint.toString() : "");
141151
}
142152
}

src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ public void visit(Table tableName) {
232232
if (alias != null) {
233233
buffer.append(alias);
234234
}
235+
MySQLIndexHint indexHint = tableName.getIndexHint();
236+
if (indexHint != null) {
237+
buffer.append(indexHint);
238+
}
235239
}
236240

237241
@Override

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
263263
| <K_NOVALIDATE : "NOVALIDATE">
264264
| <K_ENABLE : "ENABLE">
265265
| <K_DISABLE : "DISABLE">
266+
| <K_USE : "USE">
267+
| <K_FORCE : "FORCE">
266268
}
267269

268270
TOKEN : /* Stuff */
@@ -1077,6 +1079,38 @@ Alias Alias():
10771079
{ return new Alias(name,useAs); }
10781080
}
10791081

1082+
MySQLIndexHint MySQLIndexHint():
1083+
{
1084+
Token actionToken = null;
1085+
Token indexToken = null;
1086+
String indexName = null;
1087+
List<String> indexNameList = new ArrayList<String>();
1088+
}
1089+
{
1090+
(actionToken = <K_USE>
1091+
| actionToken = <K_IGNORE>
1092+
| actionToken = <K_FORCE> )
1093+
(indexToken = <K_INDEX>
1094+
| indexToken = <K_KEY>)
1095+
"("
1096+
indexName = Identifier() { indexNameList.add(indexName); }
1097+
("," indexName= Identifier() { indexNameList.add(indexName); })*
1098+
")"
1099+
{
1100+
return new MySQLIndexHint(actionToken.image, indexToken.image, indexNameList);
1101+
}
1102+
}
1103+
1104+
String Identifier():
1105+
{
1106+
Token tk = null;
1107+
}
1108+
{
1109+
(tk=<S_IDENTIFIER>
1110+
| tk=<S_QUOTED_IDENTIFIER>)
1111+
{ return tk.image; }
1112+
}
1113+
10801114
FunctionItem FunctionItem():
10811115
{
10821116
Alias alias = null;
@@ -1224,6 +1258,7 @@ FromItem FromItem():
12241258
FromItem fromItem = null;
12251259
Pivot pivot = null;
12261260
Alias alias = null;
1261+
MySQLIndexHint indexHint = null;
12271262
}
12281263
{
12291264
(
@@ -1251,6 +1286,13 @@ FromItem FromItem():
12511286
)
12521287
[(LOOKAHEAD(2) pivot=PivotXml()|pivot=Pivot()) { fromItem.setPivot(pivot); } ]
12531288
[ alias=Alias() { fromItem.setAlias(alias); } ]
1289+
[
1290+
LOOKAHEAD(2)
1291+
indexHint=MySQLIndexHint() {
1292+
if (fromItem instanceof Table)
1293+
((Table) fromItem).setHint(indexHint);
1294+
}
1295+
]
12541296
)
12551297
)
12561298
{

src/test/java/net/sf/jsqlparser/test/select/SelectTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,4 +2578,22 @@ public void testForUpdateWaitWithTimeout() throws JSQLParserException {
25782578
// public void testSubSelectFailsIssue394_2() throws JSQLParserException {
25792579
// assertSqlCanBeParsedAndDeparsed("select * from all");
25802580
// }
2581+
2582+
public void testMysqlIndexHints() throws JSQLParserException {
2583+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 USE INDEX (index1)");
2584+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 IGNORE INDEX (index1)");
2585+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 FORCE INDEX (index1)");
2586+
}
2587+
2588+
public void testMysqlIndexHintsWithJoins() throws JSQLParserException {
2589+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM table0 t0 INNER JOIN table1 t1 USE INDEX (index1)");
2590+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM table0 t0 INNER JOIN table1 t1 IGNORE INDEX (index1)");
2591+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM table0 t0 INNER JOIN table1 t1 FORCE INDEX (index1)");
2592+
}
2593+
2594+
public void testMysqlMultipleIndexHints() throws JSQLParserException {
2595+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 USE INDEX (index1,index2)");
2596+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 IGNORE INDEX (index1,index2)");
2597+
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 FORCE INDEX (index1,index2)");
2598+
}
25812599
}

0 commit comments

Comments
 (0)