improved sql parser.

This commit is contained in:
wenshao
2017-06-15 09:50:49 +08:00
parent 4be1b561de
commit 0528af3207
20 changed files with 296 additions and 172 deletions
@@ -19,6 +19,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLKeep;
@@ -115,6 +116,10 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
this.ignoreNulls = ignoreNulls;
}
public String toString() {
return SQLUtils.toSQLString(this);
}
@Override
protected void accept0(SQLASTVisitor visitor) {
@@ -1,3 +1,18 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLHint;
import com.alibaba.druid.sql.ast.SQLObject;
@@ -31,4 +32,7 @@ public interface SQLTableSource extends SQLObject {
SQLTableSource clone();
String computeAlias();
SQLExpr getFlashback();
void setFlashback(SQLExpr flashback);
}
@@ -72,10 +72,13 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
}
public MySqlCreateTableStatement parseCrateTable(boolean acceptCreate) {
MySqlCreateTableStatement stmt = new MySqlCreateTableStatement();
if (acceptCreate) {
if (lexer.hasComment() && lexer.isKeepComments()) {
stmt.addBeforeComment(lexer.readAndResetComments());
}
accept(Token.CREATE);
}
MySqlCreateTableStatement stmt = new MySqlCreateTableStatement();
if (identifierEquals("TEMPORARY")) {
lexer.nextToken();
@@ -71,8 +71,7 @@ public class MySqlLexer extends Lexer {
}
public MySqlLexer(String input){
super(input);
super.keywods = DEFAULT_MYSQL_KEYWORDS;
this(input, true, true);
}
public MySqlLexer(String input, boolean skipComment, boolean keepComments){
@@ -407,7 +406,7 @@ public class MySqlLexer extends Lexer {
bufPos++;
}
stringVal = subString(mark, bufPos + 1);
stringVal = subString(mark, bufPos);
token = Token.LINE_COMMENT;
commentCount++;
if (keepComments) {
@@ -471,6 +471,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
public boolean visit(MySqlCreateTableStatement x) {
if (isPrettyFormat() && x.hasBeforeComment()) {
printlnComments(x.getBeforeCommentsDirect());
}
print0(ucase ? "CREATE " : "create ");
@@ -23,8 +23,4 @@ public interface OracleSelectTableSource extends SQLTableSource {
OracleSelectPivotBase getPivot();
void setPivot(OracleSelectPivotBase pivot);
SQLExpr getFlashback();
void setFlashback(SQLExpr flashback);
}
@@ -27,11 +27,11 @@ import com.alibaba.druid.util.JdbcConstants;
public class SQLCreateTableParser extends SQLDDLParser {
public SQLCreateTableParser(String sql){
public SQLCreateTableParser(String sql) {
super(sql);
}
public SQLCreateTableParser(SQLExprParser exprParser){
public SQLCreateTableParser(SQLExprParser exprParser) {
super(exprParser);
}
@@ -40,22 +40,26 @@ public class SQLCreateTableParser extends SQLDDLParser {
if (lexer.isKeepComments() && lexer.hasComment()) {
comments = lexer.readAndResetComments();
}
SQLCreateTableStatement stmt = parseCrateTable(true);
if (comments != null) {
stmt.addBeforeComment(comments);
}
return stmt;
}
public SQLCreateTableStatement parseCrateTable(boolean acceptCreate) {
SQLCreateTableStatement createTable = newCreateStatement();
if (acceptCreate) {
if (lexer.hasComment() && lexer.isKeepComments()) {
createTable.addBeforeComment(lexer.readAndResetComments());
}
accept(Token.CREATE);
}
SQLCreateTableStatement createTable = newCreateStatement();
if (identifierEquals("GLOBAL")) {
lexer.nextToken();
@@ -82,21 +86,21 @@ public class SQLCreateTableParser extends SQLDDLParser {
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (;;) {
for (; ; ) {
Token token = lexer.token();
if (token == Token.IDENTIFIER
&& lexer.stringVal().equalsIgnoreCase("SUPPLEMENTAL")
&& JdbcConstants.ORACLE.equals(dbType)) {
this.parseCreateTableSupplementalLogingProps(createTable);
} else if (token == Token.IDENTIFIER //
|| token == Token.LITERAL_ALIAS) {
|| token == Token.LITERAL_ALIAS) {
SQLColumnDefinition column = this.exprParser.parseColumn();
createTable.getTableElementList().add(column);
} else if (token == Token.PRIMARY //
|| token == Token.UNIQUE //
|| token == Token.CHECK //
|| token == Token.CONSTRAINT
|| token == Token.FOREIGN) {
|| token == Token.UNIQUE //
|| token == Token.CHECK //
|| token == Token.CONSTRAINT
|| token == Token.FOREIGN) {
SQLConstraint constraint = this.exprParser.parseConstaint();
constraint.setParent(createTable);
createTable.getTableElementList().add((SQLTableElement) constraint);
@@ -149,5 +153,4 @@ public class SQLCreateTableParser extends SQLDDLParser {
protected SQLCreateTableStatement newCreateStatement() {
return new SQLCreateTableStatement(getDbType());
}
}
}
@@ -3856,23 +3856,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
printPartitionsCountAndSubPartitions(x);
List<SQLPartition> partitions = x.getPartitions();
int partitionsSize = partitions.size();
if (partitionsSize > 0) {
println();
incrementIndent();
print('(');
for (int i = 0; i < partitionsSize; ++i) {
println();
partitions.get(i).accept(this);
if (i != partitionsSize - 1) {
print0(", ");
}
}
decrementIndent();
println();
print(')');
}
printSQLPartitions(x.getPartitions());
return false;
}
@@ -3894,9 +3878,29 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
printPartitionsCountAndSubPartitions(x);
printSQLPartitions(x.getPartitions());
return false;
}
private void printSQLPartitions(List<SQLPartition> partitions) {
int partitionsSize = partitions.size();
if (partitionsSize > 0) {
print0(" (");
incrementIndent();
for (int i = 0; i < partitionsSize; ++i) {
println();
partitions.get(i).accept(this);
if (i != partitionsSize - 1) {
print0(", ");
}
}
decrementIndent();
println();
print(')');
}
}
protected void printPartitionsCountAndSubPartitions(SQLPartitionBy x) {
if (x.getPartitionsCount() != null) {