Skip to content

Commit

Permalink
antlr4分析DML
Browse files Browse the repository at this point in the history
  • Loading branch information
Kurok1 committed May 24, 2023
1 parent 2f42a18 commit 9eaf55d
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.acme</groupId>
<artifactId>distributed-configuration-project</artifactId>
<artifactId>distributed-config-project</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.acme</groupId>
<artifactId>distributed-configuration-project</artifactId>
<artifactId>distributed-config-project</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
Expand Down
1 change: 1 addition & 0 deletions stage-2/src/middleware-projects/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<module>distributed-transaction-project</module>
<module>rpc-project</module>
<module>distributed-config-project</module>
<module>sql-analysis</module>
</modules>

<dependencyManagement>
Expand Down
58 changes: 58 additions & 0 deletions stage-2/src/middleware-projects/sql-analysis/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme</groupId>
<artifactId>middleware-projects</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>sql-analysis</artifactId>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.12.0</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.12.0</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
<configuration>
<listener>true</listener>
<visitor>true</visitor>
<outputDirectory>src/main/java/com/acme/sql/antlr4</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
grammar SqlAnalysis;

@header {
package com.acme.sql.antlr4;
}

sqlDML
: insert EOF
| update EOF
| delete EOF
;

INSERT: [Ii][Nn][Ss][Ee][Rr][Tt];
INTO: [Ii][Nn][Tt][Oo];
VALUES: [Vv][Aa][Ll][Uu][Ee][Ss];
UPDATE : [Uu][Pp][Dd][Aa][Tt][Ee];
SET: [Ss][Ee][Tt];
WHERE : [Ww][Hh][Ee][Rr][Ee];
DELETE: [Dd][Ee][Ll][Ee][Tt][Ee];
FROM : [Ff][Rr][Oo][Mm];
AND: [Aa][Nn][Dd];
OR: [Oo][Rr];
NOT:[Nn][Oo][Tt];
IS: [Ii][Ss];
IN: [Ii][Nn];
LIKE: [Ll][Ii][Kk][Ee];
BETWEEN: [Bb][Ee][Tt][Ww][Ee][Ee][Nn];
ESCAPE: [Ee][Ss][Cc][Aa][Pp][Ee];

PLUS: '+';
MINUS: '-';
LR_BRACKET: '(';
RR_BRACKET: ')';
EQ: '=';
COMMA: ',';
SEMI: ';';
BACKTICK: '`';
comparison_operator
: '<' | '=' | '>' | '<=' | '>=' | '<>'
;
WS: [ \t\r\n] -> skip;
ID_LITERAL: [a-zA-Z_$0-9\u0080-\uFFFF]*?[a-zA-Z_$\u0080-\uFFFF]+?[a-zA-Z_$0-9\u0080-\uFFFF]*;



schema_name: any_word;
correlation_name: any_word;
table_name: (schema_name DOT)? any_word
| BACKTICK table_name BACKTICK;
column_name
: ( ( table_name | correlation_name) DOT )? any_word
| BACKTICK column_name BACKTICK
;
simple_column_name_list:
simple_column_name (COMMA simple_column_name )*;
simple_column_name: any_word | BACKTICK any_word BACKTICK;
any_word: ID_LITERAL;
values_expression: value (COMMA value )*;
value: expression;
expression
:primitive_expression
|expression comparison_operator expression;
primitive_expression
:literal
| any_word
|
;
where_clause: WHERE boolean_expression;
boolean_expression
: expression AND expression
| expression OR expression
| NOT expression
| expression comparison_operator expression
| expression IS NOT? NULL_
| character_expression NOT? LIKE character_expression ( ESCAPE string )?
| expression NOT? BETWEEN expression AND expression
| expression NOT? IN '(' expression (COMMA expression )* ')'
;
character_expression
: string
;
literal
: string // string, date, time, timestamp
| sign? DECIMAL_LITERAL
| sign? (REAL_LITERAL | FLOAT_LITERAL)
| TRUE | FALSE
| NULL_
;
sign
: PLUS
| MINUS
;
string
: STRING_LITERAL
;

STRING_LITERAL: DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING;

DECIMAL_LITERAL: DEC_DIGIT+;
FLOAT_LITERAL: DEC_DOT_DEC;
REAL_LITERAL: (DECIMAL_LITERAL | DEC_DOT_DEC) ('E' [+-]? DEC_DIGIT+);
NULL_: 'NULL';
TRUE: 'TRUE' | 'true';
FALSE: 'FALSE' | 'false';

fragment DQUOTA_STRING: '"' ( '\\'. | '""' | ~('"'| '\\') )* '"';
fragment SQUOTA_STRING: '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'';
fragment BQUOTA_STRING: '`' ( '\\'. | '``' | ~('`'|'\\'))* '`';
fragment DEC_DIGIT: [0-9];
fragment DEC_DOT_DEC: (DEC_DIGIT+ '.' DEC_DIGIT+ | DEC_DIGIT+ '.' | '.' DEC_DIGIT+);


insert: INSERT INTO
table_name LR_BRACKET simple_column_name_list RR_BRACKET
VALUES LR_BRACKET values_expression RR_BRACKET SEMI?;
update: UPDATE table_name SET column_name EQ value ( COMMA column_name EQ value )* where_clause? SEMI?;
delete: DELETE FROM table_name where_clause? SEMI?;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.acme.sql;

/**
* @author <a href="mailto:maimengzzz@gmail.com">韩超</a>
* @since 1.0.0
*/
public class DmlMetaData {

private String tableName;

private String type;

public String getTableName() {
return tableName;
}

public void setTableName(String tableName) {
this.tableName = tableName;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.acme.sql;

import com.acme.sql.antlr4.SqlAnalysisBaseVisitor;
import com.acme.sql.antlr4.SqlAnalysisParser;

/**
* @author <a href="mailto:maimengzzz@gmail.com">韩超</a>
* @since 1.0.0
*/
public class MySqlAnalysisVisitor extends SqlAnalysisBaseVisitor<DmlMetaData> {

private DmlMetaData sqlMetaData = new DmlMetaData();

@Override
public DmlMetaData visitTable_name(SqlAnalysisParser.Table_nameContext ctx) {
sqlMetaData.setTableName(ctx.getText());
return super.visitTable_name(ctx);
}

@Override
public DmlMetaData visitInsert(SqlAnalysisParser.InsertContext ctx) {
sqlMetaData.setType("insert");
return super.visitInsert(ctx);
}

@Override
public DmlMetaData visitUpdate(SqlAnalysisParser.UpdateContext ctx) {
sqlMetaData.setType("update");
return super.visitUpdate(ctx);
}

@Override
public DmlMetaData visitDelete(SqlAnalysisParser.DeleteContext ctx) {
sqlMetaData.setType("delete");
return super.visitDelete(ctx);
}

@Override
protected DmlMetaData defaultResult() {
return this.sqlMetaData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.acme.sql;

import com.acme.sql.antlr4.SqlAnalysisLexer;
import com.acme.sql.antlr4.SqlAnalysisParser;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class MySqlAnalysisVisitorTest {

@Test
public void testInsert() {
String sql = "INSERT INTO `test`(id, name, age) VALUES(1, '张三', 18);";
DmlMetaData accept = getSqlMetaData(sql);
assertEquals("insert", accept.getType());
assertEquals("`test`", accept.getTableName());
}


private static DmlMetaData getSqlMetaData(String sql) {
var baseSqlLexer = new SqlAnalysisLexer(CharStreams.fromString(sql));
CommonTokenStream tokens = new CommonTokenStream(baseSqlLexer);
var parser = new SqlAnalysisParser(tokens);
ParseTree tree = parser.sqlDML();

return tree.accept(new MySqlAnalysisVisitor());
}


}

0 comments on commit 9eaf55d

Please sign in to comment.