mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser for sqlserver, support for xml clause
This commit is contained in:
@@ -15,8 +15,82 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.sqlserver.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SQLServerSelect extends SQLSelect {
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLServerSelect extends SQLSelect implements SQLServerObject {
|
||||
|
||||
private boolean forBrowse;
|
||||
private List<String> forXmlOptions = new ArrayList<String>(4);
|
||||
|
||||
public boolean isForBrowse() {
|
||||
return forBrowse;
|
||||
}
|
||||
|
||||
public void setForBrowse(boolean forBrowse) {
|
||||
this.forBrowse = forBrowse;
|
||||
}
|
||||
|
||||
public List<String> getForXmlOptions() {
|
||||
return forXmlOptions;
|
||||
}
|
||||
|
||||
public void setForXmlOptions(List<String> forXmlOptions) {
|
||||
this.forXmlOptions = forXmlOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((SQLServerASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(SQLServerASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.query);
|
||||
acceptChild(visitor, this.orderBy);
|
||||
acceptChild(visitor, this.hints);
|
||||
}
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (forBrowse ? 1231 : 1237);
|
||||
result = prime * result + ((forXmlOptions == null) ? 0 : forXmlOptions.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SQLServerSelect other = (SQLServerSelect) obj;
|
||||
if (forBrowse != other.forBrowse) {
|
||||
return false;
|
||||
}
|
||||
if (forXmlOptions == null) {
|
||||
if (other.forXmlOptions != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!forXmlOptions.equals(other.forXmlOptions)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+52
-11
@@ -25,6 +25,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
@@ -39,9 +40,9 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
super(exprParser);
|
||||
}
|
||||
|
||||
public SQLSelect select() {
|
||||
public SQLSelect select() {
|
||||
SQLServerSelect select = new SQLServerSelect();
|
||||
|
||||
|
||||
withSubquery(select);
|
||||
|
||||
select.setQuery(query());
|
||||
@@ -51,10 +52,50 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
select.setOrderBy(parseOrderBy());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.FOR) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (identifierEquals("BROWSE")) {
|
||||
lexer.nextToken();
|
||||
select.setForBrowse(true);
|
||||
} else if (identifierEquals("XML")) {
|
||||
lexer.nextToken();
|
||||
|
||||
for (;;) {
|
||||
if (identifierEquals("AUTO") //
|
||||
|| identifierEquals("TYPE") //
|
||||
|| identifierEquals("XMLSCHEMA") //
|
||||
) {
|
||||
select.getForXmlOptions().add(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("ELEMENTS")) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("XSINIL")) {
|
||||
lexer.nextToken();
|
||||
select.getForXmlOptions().add("ELEMENTS XSINIL");
|
||||
} else {
|
||||
select.getForXmlOptions().add("ELEMENTS");
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new ParserException("syntax error, not support option : " + lexer.token());
|
||||
}
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
public SQLSelectQuery query() {
|
||||
public SQLSelectQuery query() {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -68,7 +109,7 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
if (lexer.token() == Token.COMMENT) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -88,10 +129,10 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
|
||||
parseSelectList(queryBlock);
|
||||
}
|
||||
|
||||
|
||||
if (lexer.token() == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
SQLTableSource into = this.parseTableSource();
|
||||
queryBlock.setInto((SQLExprTableSource) into);
|
||||
}
|
||||
@@ -104,16 +145,16 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
|
||||
return queryRest(queryBlock);
|
||||
}
|
||||
|
||||
|
||||
protected SQLServerExprParser createExprParser() {
|
||||
return new SQLServerExprParser(lexer);
|
||||
}
|
||||
|
||||
|
||||
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
|
||||
|
||||
for (;;) {
|
||||
SQLExpr expr = this.expr();
|
||||
SQLExprHint hint = new SQLExprHint(expr);
|
||||
@@ -126,10 +167,10 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
|
||||
return super.parseTableSourceRest(tableSource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
|
||||
@@ -97,5 +98,9 @@ public interface SQLServerASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(SQLServerBlockStatement x);
|
||||
|
||||
void endVisit(SQLServerBlockStatement x);
|
||||
|
||||
boolean visit(SQLServerSelect x);
|
||||
|
||||
void endVisit(SQLServerSelect x);
|
||||
|
||||
}
|
||||
|
||||
+11
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
|
||||
@@ -193,5 +194,15 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements
|
||||
public void endVisit(SQLServerBlockStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLServerSelect x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLServerSelect x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+42
@@ -22,10 +22,12 @@ import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
|
||||
@@ -553,4 +555,44 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
|
||||
public void endVisit(SQLServerBlockStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void printGrantOn(SQLGrantStatement x) {
|
||||
if (x.getOn() != null) {
|
||||
print(" ON ");
|
||||
|
||||
if (x.getObjectType() != null) {
|
||||
print(x.getObjectType().name());
|
||||
print("::");
|
||||
}
|
||||
|
||||
x.getOn().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLServerSelect x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLServerSelect x) {
|
||||
super.visit(x);
|
||||
if (x.isForBrowse()) {
|
||||
println();
|
||||
print("FOR BROWSE");
|
||||
}
|
||||
|
||||
if (x.getForXmlOptions().size() > 0) {
|
||||
println();
|
||||
print("FOR XML ");
|
||||
for (int i = 0; i < x.getForXmlOptions().size(); ++i) {
|
||||
if (i != 0) {
|
||||
print(", ");
|
||||
print(x.getForXmlOptions().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -25,6 +25,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
|
||||
@@ -230,4 +231,14 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLServerSelect x) {
|
||||
return super.visit(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLServerSelect x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user