Skip to content

Commit 546d342

Browse files
authored
feature: add antlr for mysql sqlparser (apache#2933)
1 parent fa3791e commit 546d342

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+108252
-1
lines changed

all/pom.xml

+10
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@
214214
<artifactId>seata-sqlparser-core</artifactId>
215215
<version>${project.version}</version>
216216
</dependency>
217+
<dependency>
218+
<groupId>io.seata</groupId>
219+
<artifactId>seata-sqlparser-antlr</artifactId>
220+
<version>${project.version}</version>
221+
</dependency>
217222
<dependency>
218223
<groupId>io.seata</groupId>
219224
<artifactId>seata-sqlparser-druid</artifactId>
@@ -353,6 +358,10 @@
353358
<groupId>io.netty</groupId>
354359
<artifactId>netty-all</artifactId>
355360
</dependency>
361+
<dependency>
362+
<groupId>org.antlr</groupId>
363+
<artifactId>antlr4</artifactId>
364+
</dependency>
356365
<dependency>
357366
<groupId>com.alibaba</groupId>
358367
<artifactId>fastjson</artifactId>
@@ -669,6 +678,7 @@
669678
<include>io.seata:seata-rm</include>
670679
<include>io.seata:seata-rm-datasource</include>
671680
<include>io.seata:seata-sqlparser-core</include>
681+
<include>io.seata:seata-sqlparser-antlr</include>
672682
<include>io.seata:seata-sqlparser-druid</include>
673683
<include>io.seata:seata-sofa-rpc</include>
674684
<include>io.seata:seata-spring</include>

bom/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<sofa.registry.version>5.2.0</sofa.registry.version>
9898
<httpclient.version>4.5.8</httpclient.version>
9999
<httpcore.version>4.4.11</httpcore.version>
100+
<antlr4.version>4.8</antlr4.version>
100101
<druid.version>1.1.23</druid.version>
101102
<caffeine.version>2.7.0</caffeine.version>
102103
<oracle.client.version>10.2.0.3.0</oracle.client.version>
@@ -149,6 +150,11 @@
149150
<artifactId>fastjson</artifactId>
150151
<version>${fastjson.version}</version>
151152
</dependency>
153+
<dependency>
154+
<groupId>org.antlr</groupId>
155+
<artifactId>antlr4</artifactId>
156+
<version>${antlr4.version}</version>
157+
</dependency>
152158
<dependency>
153159
<groupId>com.alibaba</groupId>
154160
<artifactId>druid</artifactId>

codecov.yml

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ ignore:
1717
- ".style/.*"
1818
- "*.md"
1919
- "rm-datasource/src/test/java/io/seata/rm/datasource/mock"
20+
- "sqlparser/seata-sqlparser-antlr/src/main/java/io/seata/sqlparser/antlr/mysql/antlr/.*"
21+
- "sqlparser/seata-sqlparser-antlr/src/main/java/io/seata/sqlparser/antlr/mysql/parser/.*"
2022
comment:
2123
layout: "reach,diff,flags,tree"
2224
behavior: default

pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@
320320
</includes>
321321
<excludes>
322322
<exclude>**/generated/**</exclude>
323+
<exclude>**/antlr/mysql/parser/*.*</exclude>
324+
<exclude>**/antlr/mysql/antlr/*.*</exclude>
325+
<exclude>**/antlr/mysql/stream/ANTLRNoCaseStringStream.java</exclude>
323326
</excludes>
324327
<strictCheck>true</strictCheck>
325328
<mapping>
@@ -416,6 +419,9 @@
416419
</rulesets>
417420
<excludes>
418421
<exclude>**/generated/*.java</exclude>
422+
<exclude>**/antlr/mysql/parser/*.*</exclude>
423+
<exclude>**/antlr/mysql/antlr/*.*</exclude>
424+
<exclude>**/antlr/mysql/stream/ANTLRNoCaseStringStream.java</exclude>
419425
</excludes>
420426
</configuration>
421427
<executions>

sqlparser/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
<modules>
3131
<module>seata-sqlparser-core</module>
32+
<module>seata-sqlparser-antlr</module>
3233
<module>seata-sqlparser-druid</module>
3334
</modules>
3435
</project>
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 1999-2019 Seata.io Group.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<parent>
20+
<groupId>io.seata</groupId>
21+
<artifactId>seata-sqlparser</artifactId>
22+
<version>${revision}</version>
23+
</parent>
24+
<modelVersion>4.0.0</modelVersion>
25+
<artifactId>seata-sqlparser-antlr</artifactId>
26+
<name>seata-sqlparser-antlr ${project.version}</name>
27+
<dependencies>
28+
<dependency>
29+
<groupId>${project.groupId}</groupId>
30+
<artifactId>seata-sqlparser-core</artifactId>
31+
<version>${project.version}</version>
32+
</dependency>
33+
34+
<dependency>
35+
<groupId>org.antlr</groupId>
36+
<artifactId>antlr4</artifactId>
37+
</dependency>
38+
</dependencies>
39+
40+
<build>
41+
<plugins>
42+
<plugin>
43+
<groupId>org.apache.maven.plugins</groupId>
44+
<artifactId>maven-checkstyle-plugin</artifactId>
45+
<configuration>
46+
<skip>true</skip>
47+
</configuration>
48+
</plugin>
49+
</plugins>
50+
</build>
51+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 1999-2019 Seata.io Group.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.seata.sqlparser.antlr;
17+
18+
import io.seata.common.loader.LoadLevel;
19+
import io.seata.sqlparser.SQLParsingException;
20+
import io.seata.sqlparser.SQLRecognizer;
21+
import io.seata.sqlparser.SQLRecognizerFactory;
22+
import io.seata.sqlparser.SqlParserType;
23+
24+
import java.lang.reflect.Constructor;
25+
import java.util.List;
26+
27+
/**
28+
* @author zhihou
29+
*/
30+
@LoadLevel(name = SqlParserType.SQL_PARSER_TYPE_ANTLR)
31+
public class AntlrDelegatingSQLRecognizerFactory implements SQLRecognizerFactory {
32+
33+
private volatile SQLRecognizerFactory recognizerFactoryImpl;
34+
35+
public AntlrDelegatingSQLRecognizerFactory() {
36+
setClassLoader();
37+
}
38+
39+
/**
40+
* Only for unit test
41+
*
42+
*/
43+
void setClassLoader() {
44+
try {
45+
Class<?> recognizerFactoryImplClass = ClassLoader.getSystemClassLoader().loadClass("io.seata.sqlparser.antlr.mysql.AntlrMySQLRecognizerFactory");
46+
Constructor<?> implConstructor = recognizerFactoryImplClass.getDeclaredConstructor();
47+
implConstructor.setAccessible(true);
48+
try {
49+
recognizerFactoryImpl = (SQLRecognizerFactory) implConstructor.newInstance();
50+
} finally {
51+
implConstructor.setAccessible(false);
52+
}
53+
} catch (Exception e) {
54+
throw new SQLParsingException(e);
55+
}
56+
}
57+
58+
@Override
59+
public List<SQLRecognizer> create(String sql, String dbType) {
60+
return recognizerFactoryImpl.create(sql, dbType);
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 1999-2019 Seata.io Group.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.seata.sqlparser.antlr;
17+
18+
import io.seata.sqlparser.SQLRecognizer;
19+
20+
/**
21+
* The interface SQLOperateRecognizerHolder
22+
*
23+
* @author zhihou
24+
*/
25+
public interface SQLOperateRecognizerHolder {
26+
27+
/**
28+
* Get delete recognizer
29+
*
30+
* @param sql the sql
31+
* @return the delete recognizer
32+
*/
33+
SQLRecognizer getDeleteRecognizer(String sql);
34+
35+
/**
36+
* Get insert recognizer
37+
*
38+
* @param sql the sql
39+
* @return the insert recognizer
40+
*/
41+
SQLRecognizer getInsertRecognizer(String sql);
42+
43+
/**
44+
* Get update recognizer
45+
*
46+
* @param sql the sql
47+
* @return the update recognizer
48+
*/
49+
SQLRecognizer getUpdateRecognizer(String sql);
50+
51+
/**
52+
* Get SelectForUpdate recognizer
53+
*
54+
* @param sql the sql
55+
* @return the SelectForUpdate recognizer
56+
*/
57+
SQLRecognizer getSelectForUpdateRecognizer(String sql);
58+
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 1999-2019 Seata.io Group.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.seata.sqlparser.antlr;
17+
18+
import io.seata.common.loader.EnhancedServiceLoader;
19+
import io.seata.common.util.CollectionUtils;
20+
21+
import java.util.Map;
22+
import java.util.concurrent.ConcurrentHashMap;
23+
24+
/**
25+
* The SQLOperateRecognizerHolderFactory
26+
*
27+
* @author: zhi hou
28+
*/
29+
public class SQLOperateRecognizerHolderFactory {
30+
31+
private static final Map<String, SQLOperateRecognizerHolder> RECOGNIZER_HOLDER_MAP = new ConcurrentHashMap<>();
32+
33+
34+
/**
35+
* get SQLOperateRecognizer by db type
36+
*
37+
* @param dbType the db type
38+
* @return the SQLOperateRecognizer
39+
*/
40+
public static SQLOperateRecognizerHolder getSQLRecognizerHolder(String dbType) {
41+
return CollectionUtils.computeIfAbsent(RECOGNIZER_HOLDER_MAP, dbType, key -> EnhancedServiceLoader.load(SQLOperateRecognizerHolder.class, dbType, SQLOperateRecognizerHolderFactory.class.getClassLoader()));
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 1999-2019 Seata.io Group.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.seata.sqlparser.antlr.mysql;
17+
18+
import io.seata.sqlparser.ParametersHolder;
19+
import io.seata.sqlparser.SQLDeleteRecognizer;
20+
import io.seata.sqlparser.SQLType;
21+
import io.seata.sqlparser.antlr.mysql.listener.DeleteSpecificationSqlListener;
22+
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
23+
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
24+
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
25+
import org.antlr.v4.runtime.CommonTokenStream;
26+
import org.antlr.v4.runtime.tree.ParseTreeWalker;
27+
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
31+
/**
32+
* AntlrMySQLDeleteRecognizer
33+
*
34+
* @author zhihou
35+
*/
36+
public class AntlrMySQLDeleteRecognizer implements SQLDeleteRecognizer {
37+
38+
private MySqlContext sqlContext;
39+
40+
public AntlrMySQLDeleteRecognizer(String sql) {
41+
MySqlLexer mySqlLexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
42+
CommonTokenStream commonTokenStream = new CommonTokenStream(mySqlLexer);
43+
MySqlParser parser2 = new MySqlParser(commonTokenStream);
44+
MySqlParser.RootContext root = parser2.root();
45+
ParseTreeWalker walker2 = new ParseTreeWalker();
46+
sqlContext = new MySqlContext();
47+
sqlContext.setOriginalSQL(sql);
48+
walker2.walk(new DeleteSpecificationSqlListener(sqlContext), root);
49+
}
50+
51+
52+
@Override
53+
public String getWhereCondition(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
54+
return sqlContext.getWhereCondition();
55+
}
56+
57+
@Override
58+
public String getWhereCondition() {
59+
return sqlContext.getWhereCondition();
60+
}
61+
62+
@Override
63+
public SQLType getSQLType() {
64+
return SQLType.DELETE;
65+
}
66+
67+
@Override
68+
public String getTableAlias() {
69+
return sqlContext.tableAlias;
70+
}
71+
72+
@Override
73+
public String getTableName() {
74+
return sqlContext.tableName;
75+
}
76+
77+
@Override
78+
public String getOriginalSQL() {
79+
80+
return sqlContext.getOriginalSQL();
81+
}
82+
}

0 commit comments

Comments
 (0)