improve sqlparser

This commit is contained in:
Yako
2014-11-10 21:22:33 +08:00
parent 776f9a8e34
commit 92ebbdee2f
4 changed files with 112 additions and 5 deletions
@@ -48,7 +48,9 @@ public class MySqlLoadDataInFileStatement extends MySqlStatementImpl {
private SQLExpr ignoreLinesNumber;
private final List<SQLExpr> setList = new ArrayList<SQLExpr>();
private List<SQLExpr> setList = new ArrayList<SQLExpr>();
private List<SQLExpr> columns = new ArrayList<SQLExpr>();
public boolean isLowPriority() {
return lowPriority;
@@ -188,4 +190,19 @@ public class MySqlLoadDataInFileStatement extends MySqlStatementImpl {
}
visitor.endVisit(this);
}
public List<SQLExpr> getColumns() {
return columns;
}
public void setColumns(List<SQLExpr> columns) {
this.columns = columns;
}
public void setSetList(List<SQLExpr> setList) {
this.setList = setList;
}
}
@@ -1787,19 +1787,61 @@ public class MySqlStatementParser extends SQLStatementParser {
}
if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) {
throw new ParserException("TODO");
lexer.nextToken();
if (identifierEquals("TERMINATED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsTerminatedBy((SQLLiteralExpr) this.exprParser.expr());
}
if (identifierEquals("OPTIONALLY")) {
stmt.setColumnsEnclosedOptionally(true);
lexer.nextToken();
}
if (identifierEquals("ENCLOSED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsEnclosedBy((SQLLiteralExpr) this.exprParser.expr());
}
if (identifierEquals("ESCAPED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsEscaped((SQLLiteralExpr) this.exprParser.expr());
}
}
if (identifierEquals("LINES")) {
throw new ParserException("TODO");
lexer.nextToken();
if (identifierEquals("STARTING")) {
lexer.nextToken();
accept(Token.BY);
stmt.setLinesStartingBy((SQLLiteralExpr) this.exprParser.expr());
}
if (identifierEquals("TERMINATED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setLinesTerminatedBy((SQLLiteralExpr) this.exprParser.expr());
}
}
if (identifierEquals(IGNORE)) {
throw new ParserException("TODO");
lexer.nextToken();
stmt.setIgnoreLinesNumber((SQLLiteralExpr) this.exprParser.expr());
acceptIdentifier("LINES");
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
this.exprParser.exprList(stmt.getColumns(), stmt);
accept(Token.RPAREN);
}
if (lexer.token() == Token.SET) {
throw new ParserException("TODO");
lexer.nextToken();
this.exprParser.exprList(stmt.getSetList(), stmt);
}
return stmt;
@@ -1037,7 +1037,19 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
x.getLinesTerminatedBy().accept(this);
}
}
if(x.getIgnoreLinesNumber() != null) {
print(" IGNORE ");
x.getIgnoreLinesNumber().accept(this);
print(" LINES");
}
if (x.getColumns().size() != 0) {
print(" (");
printAndAccept(x.getColumns(), ", ");
print(")");
}
if (x.getSetList().size() != 0) {
print(" SET ");
printAndAccept(x.getSetList(), ", ");
@@ -38,6 +38,42 @@ public class LoadDataInFileSyntaxTest extends TestCase {
Assert.assertEquals("LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;", text);
}
public void test_1() throws Exception {
String sql = "LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test FIELDS TERMINATED BY ',' LINES STARTING BY 'xxx';";
SQLStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> stmtList = parser.parseStatementList();
String text = output(stmtList);
Assert.assertEquals("LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test COLUMNS TERMINATED BY ',' LINES STARTING BY 'xxx';",
text);
}
public void test_2() throws Exception {
String sql = "LOAD DATA INFILE '/home/Order.txt' INTO TABLE Orders (Order_Number, Order_Date, Customer_ID);";
SQLStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> stmtList = parser.parseStatementList();
String text = output(stmtList);
Assert.assertEquals("LOAD DATA INFILE '/home/Order.txt' INTO TABLE Orders (Order_Number, Order_Date, Customer_ID);",
text);
}
public void test_3() throws Exception {
String sql = "LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;";
SQLStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> stmtList = parser.parseStatementList();
String text = output(stmtList);
Assert.assertEquals("LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name COLUMNS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;",
text);
}
private String output(List<SQLStatement> stmtList) {
StringBuilder out = new StringBuilder();