mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql format output
This commit is contained in:
@@ -56,6 +56,8 @@ public class Lexer {
|
||||
protected Keywords keywods = Keywords.DEFAULT_KEYWORDS;
|
||||
|
||||
protected String stringVal;
|
||||
|
||||
protected String commentVal;
|
||||
|
||||
protected boolean skipComment = true;
|
||||
|
||||
@@ -73,9 +75,24 @@ public class Lexer {
|
||||
protected boolean hasComment = false;
|
||||
|
||||
protected boolean endOfComment = false;
|
||||
|
||||
protected boolean keepComments = false;
|
||||
|
||||
public Lexer(String input){
|
||||
this(input, null);
|
||||
}
|
||||
|
||||
public Lexer(String input, CommentHandler commentHandler){
|
||||
this(input, true);
|
||||
this.commentHandler = commentHandler;
|
||||
}
|
||||
|
||||
public boolean isKeepComments() {
|
||||
return keepComments;
|
||||
}
|
||||
|
||||
public void setKeepComments(boolean keepComments) {
|
||||
this.keepComments = keepComments;
|
||||
}
|
||||
|
||||
public CommentHandler getCommentHandler() {
|
||||
@@ -270,6 +287,7 @@ public class Lexer {
|
||||
|
||||
public final void nextToken() {
|
||||
bufPos = 0;
|
||||
hasComment = false;
|
||||
|
||||
for (;;) {
|
||||
if (isWhitespace(ch)) {
|
||||
@@ -759,6 +777,8 @@ public class Lexer {
|
||||
}
|
||||
|
||||
private void scanMultiLineComment() {
|
||||
Token lastToken = this.token;
|
||||
|
||||
scanChar();
|
||||
scanChar();
|
||||
mark = pos;
|
||||
@@ -782,12 +802,25 @@ public class Lexer {
|
||||
stringVal = subString(mark, bufPos);
|
||||
token = Token.MULTI_LINE_COMMENT;
|
||||
hasComment = true;
|
||||
if (keepComments) {
|
||||
commentVal = stringVal;
|
||||
}
|
||||
|
||||
if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAllowComment() && !isSafeComment(stringVal)) {
|
||||
throw new NotAllowCommentException();
|
||||
}
|
||||
}
|
||||
|
||||
private void scanSingleLineComment() {
|
||||
Token lastToken = this.token;
|
||||
|
||||
scanChar();
|
||||
scanChar();
|
||||
mark = pos;
|
||||
mark = pos - 1;
|
||||
bufPos = 0;
|
||||
|
||||
for (;;) {
|
||||
@@ -817,6 +850,17 @@ public class Lexer {
|
||||
stringVal = subString(mark, bufPos);
|
||||
token = Token.LINE_COMMENT;
|
||||
hasComment = true;
|
||||
if (keepComments) {
|
||||
commentVal = stringVal;
|
||||
}
|
||||
|
||||
if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAllowComment() && !isSafeComment(stringVal)) {
|
||||
throw new NotAllowCommentException();
|
||||
}
|
||||
}
|
||||
|
||||
public void scanIdentifier() {
|
||||
@@ -972,6 +1016,10 @@ public class Lexer {
|
||||
public final String stringVal() {
|
||||
return stringVal;
|
||||
}
|
||||
|
||||
public final String commentVal() {
|
||||
return commentVal;
|
||||
}
|
||||
|
||||
private boolean isOperator(char ch) {
|
||||
switch (ch) {
|
||||
@@ -1080,11 +1128,10 @@ public class Lexer {
|
||||
}
|
||||
|
||||
public static interface CommentHandler {
|
||||
|
||||
boolean handle(Token lastToken, String comment);
|
||||
}
|
||||
|
||||
public boolean isHasComment() {
|
||||
public boolean hasComment() {
|
||||
return hasComment;
|
||||
}
|
||||
|
||||
|
||||
@@ -1179,6 +1179,10 @@ public class SQLExprParser extends SQLParser {
|
||||
public SQLExpr andRest(SQLExpr expr) {
|
||||
for (;;) {
|
||||
if (lexer.token() == Token.AND || lexer.token() == Token.AMPAMP) {
|
||||
if (lexer.isKeepComments() && lexer.hasComment()) {
|
||||
expr.addAfterComment(lexer.commentVal());
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = relational();
|
||||
|
||||
@@ -1682,7 +1686,12 @@ public class SQLExprParser extends SQLParser {
|
||||
item.setValue(new SQLIdentifierExpr(lexer.stringVal()));
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
item.setValue(expr());
|
||||
if (lexer.token() == Token.ALL) {
|
||||
item.setValue(new SQLIdentifierExpr(lexer.stringVal()));
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
item.setValue(expr());
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
|
||||
@@ -158,6 +158,12 @@ public class SQLSelectParser extends SQLParser {
|
||||
|
||||
return queryRest(select);
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = new SQLSelectQueryBlock();
|
||||
|
||||
if (lexer.hasComment() && lexer.isKeepComments()) {
|
||||
queryBlock.addBeforeComment(lexer.commentVal());
|
||||
}
|
||||
|
||||
accept(Token.SELECT);
|
||||
|
||||
@@ -165,8 +171,6 @@ public class SQLSelectParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = new SQLSelectQueryBlock();
|
||||
|
||||
if (lexer.token() == Token.DISTINCT) {
|
||||
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT);
|
||||
lexer.nextToken();
|
||||
@@ -234,7 +238,15 @@ public class SQLSelectParser extends SQLParser {
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
|
||||
queryBlock.setWhere(expr());
|
||||
SQLExpr where = expr();
|
||||
|
||||
if (lexer.hasComment() && lexer.isKeepComments() //
|
||||
&& lexer.token() != Token.INSERT // odps multi-insert
|
||||
) {
|
||||
where.addAfterComment(lexer.commentVal());
|
||||
}
|
||||
|
||||
queryBlock.setWhere(where);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +338,13 @@ public class SQLSelectParser extends SQLParser {
|
||||
|
||||
parseTableSourceQueryTableExpr(tableReference);
|
||||
|
||||
return parseTableSourceRest(tableReference);
|
||||
SQLTableSource tableSrc = parseTableSourceRest(tableReference);
|
||||
|
||||
if (lexer.hasComment() && lexer.isKeepComments()) {
|
||||
tableSrc.addAfterComment(lexer.commentVal());
|
||||
}
|
||||
|
||||
return tableSrc;
|
||||
}
|
||||
|
||||
private void parseTableSourceQueryTableExpr(SQLExprTableSource tableReference) {
|
||||
|
||||
@@ -88,12 +88,16 @@ import com.alibaba.druid.sql.dialect.odps.parser.OdpsSelectParser;
|
||||
|
||||
public class SQLStatementParser extends SQLParser {
|
||||
|
||||
protected SQLExprParser exprParser;
|
||||
protected SQLExprParser exprParser;
|
||||
|
||||
protected boolean parseCompleteValues = true;
|
||||
|
||||
protected int parseValuesSize = 3;
|
||||
protected boolean parseCompleteValues = true;
|
||||
|
||||
protected int parseValuesSize = 3;
|
||||
|
||||
protected List<String> comments;
|
||||
|
||||
protected CommentCallback commentCallBack = new CommentCallback();
|
||||
|
||||
public SQLStatementParser(String sql){
|
||||
this(sql, null);
|
||||
}
|
||||
@@ -101,11 +105,23 @@ public class SQLStatementParser extends SQLParser {
|
||||
public SQLStatementParser(String sql, String dbType){
|
||||
this(new SQLExprParser(sql, dbType));
|
||||
}
|
||||
|
||||
|
||||
public SQLStatementParser(SQLExprParser exprParser){
|
||||
super(exprParser.getLexer(), exprParser.getDbType());
|
||||
this.exprParser = exprParser;
|
||||
}
|
||||
|
||||
protected SQLStatementParser(Lexer lexer, String dbType){
|
||||
super(lexer, dbType);
|
||||
}
|
||||
|
||||
public boolean isKeepComments() {
|
||||
return lexer.isKeepComments();
|
||||
}
|
||||
|
||||
public void setKeepComments(boolean keepComments) {
|
||||
this.lexer.setKeepComments(keepComments);
|
||||
}
|
||||
|
||||
public SQLExprParser getExprParser() {
|
||||
return exprParser;
|
||||
@@ -122,13 +138,30 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
||||
List<String> comments = null;
|
||||
if (this.comments != null) {
|
||||
comments = this.comments;
|
||||
this.comments = null;
|
||||
}
|
||||
|
||||
int size_original = statementList.size();
|
||||
|
||||
for (;;) {
|
||||
boolean isFirstStmt = statementList.size() == size_original + 1;
|
||||
if (isFirstStmt && comments != null && lexer.isKeepComments()) {
|
||||
SQLStatement firstStmt = statementList.get(size_original);
|
||||
for (String comment : comments) {
|
||||
firstStmt.addBeforeComment(comment);
|
||||
}
|
||||
comments = null;
|
||||
}
|
||||
|
||||
if (max != -1) {
|
||||
if (statementList.size() >= max) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lexer.token() == Token.EOF) {
|
||||
return;
|
||||
}
|
||||
@@ -136,8 +169,15 @@ public class SQLStatementParser extends SQLParser {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lexer.token() == (Token.SEMI)) {
|
||||
if (lexer.token() == Token.SEMI) {
|
||||
size_original = statementList.size();
|
||||
this.comments = null;
|
||||
lexer.nextToken();
|
||||
comments = this.comments;
|
||||
if (lexer.isKeepComments()) {
|
||||
SQLStatement stmt = statementList.get(statementList.size() - 1);
|
||||
stmt.getAttributes().put("format.semi", Boolean.TRUE);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1781,4 +1821,22 @@ public class SQLStatementParser extends SQLParser {
|
||||
public void setParseValuesSize(int parseValuesSize) {
|
||||
this.parseValuesSize = parseValuesSize;
|
||||
}
|
||||
|
||||
class CommentCallback implements Lexer.CommentHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(Token lastToken, String comment) {
|
||||
addComment(comment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addComment(String comment) {
|
||||
if (comments == null) {
|
||||
comments = new ArrayList<String>();
|
||||
}
|
||||
comments.add(comment);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user