refactor sql parser.

This commit is contained in:
wenshao
2017-09-18 11:25:40 +08:00
parent 3c98a1eee5
commit 8343ca08c4
29 changed files with 201 additions and 499 deletions
@@ -46,12 +46,11 @@ import com.alibaba.druid.proxy.jdbc.JdbcParameter.TYPE;
* @author wenshao [szujobs@hotmail.com]
*/
public class PreparedStatementProxyImpl extends StatementProxyImpl implements PreparedStatementProxy {
private PreparedStatement statement;
protected final String sql;
private JdbcParameter[] parameters;
private int parametersSize = 0;
private Map<Integer, JdbcParameter> paramMap = null;
private PreparedStatement statement;
protected final String sql;
private JdbcParameter[] parameters;
private int parametersSize;
private Map<Integer, JdbcParameter> paramMap;
public PreparedStatementProxyImpl(ConnectionProxy connection, PreparedStatement statement, String sql, long id){
super(connection, statement, id);
@@ -34,23 +34,17 @@ import com.alibaba.druid.stat.JdbcSqlStat;
*/
public class StatementProxyImpl extends WrapperProxyImpl implements StatementProxy {
private final ConnectionProxy connection;
protected Statement statement;
protected String lastExecuteSql;
protected long lastExecuteStartNano;
protected long lastExecuteTimeNano;
protected JdbcSqlStat sqlStat;
protected boolean firstResultSet;
protected ArrayList<String> batchSqlList;
protected StatementExecuteType lastExecuteType;
protected Integer updateCount = null;
private FilterChainImpl filterChain = null;
private final ConnectionProxy connection;
protected Statement statement;
protected String lastExecuteSql;
protected long lastExecuteStartNano;
protected long lastExecuteTimeNano;
protected JdbcSqlStat sqlStat;
protected boolean firstResultSet;
protected ArrayList<String> batchSqlList;
protected StatementExecuteType lastExecuteType;
protected Integer updateCount;
private FilterChainImpl filterChain;
public StatementProxyImpl(ConnectionProxy connection, Statement statement, long id){
super(statement, id);
@@ -56,5 +56,6 @@ public interface SQLDataType extends SQLObject {
String BIGINT = "BIGINT";
String TEXT = "TEXT";
String BYTEA = "BYTEA";
String BOOLEAN = "BOOLEAN";
}
}
@@ -16,13 +16,14 @@
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public final class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLiteralExpr, SQLValuableExpr {
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("boolean");
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLDataTypeImpl(SQLDataType.Constants.BOOLEAN);
private boolean value;
@@ -91,4 +92,8 @@ public final class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLit
public SQLBooleanExpr clone() {
return new SQLBooleanExpr(value);
}
public static enum Type {
ON_OFF
}
}
@@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSetStatement extends SQLStatementImpl {
private Option option;
private List<SQLAssignItem> items = new ArrayList<SQLAssignItem>();
@@ -72,6 +73,20 @@ public class SQLSetStatement extends SQLStatementImpl {
this.hints = hints;
}
public Option getOption() {
return option;
}
public void setOption(Option option) {
this.option = option;
}
public void set(SQLExpr target, SQLExpr value) {
SQLAssignItem assignItem = new SQLAssignItem(target, value);
assignItem.setParent(this);
this.items.add(assignItem);
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -110,4 +125,11 @@ public class SQLSetStatement extends SQLStatementImpl {
}
return x;
}
public static enum Option {
IDENTITY_INSERT,
PASSWORD, // mysql
SESSION,
LOCAL
}
}
@@ -1,55 +0,0 @@
/*
* 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.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlSetCharSetStatement extends MySqlStatementImpl {
private boolean isDefault = false;
private String charSet;
private String collate;
public void accept0(MySqlASTVisitor visitor) {
// visitor.visit(this);
// visitor.endVisit(this);
}
public String getCharSet() {
return charSet;
}
public void setCharSet(String charSet) {
this.charSet = charSet;
}
public String getCollate() {
return collate;
}
public void setCollate(String collate) {
this.collate = collate;
}
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}
}
@@ -1,55 +0,0 @@
/*
* 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.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlSetNamesStatement extends MySqlStatementImpl {
private boolean isDefault = false;
private String charSet;
private String collate;
public void accept0(MySqlASTVisitor visitor) {
// visitor.visit(this);
// visitor.endVisit(this);
}
public String getCharSet() {
return charSet;
}
public void setCharSet(String charSet) {
this.charSet = charSet;
}
public String getCollate() {
return collate;
}
public void setCollate(String collate) {
this.collate = collate;
}
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}
}
@@ -1,58 +0,0 @@
/*
* 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.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlSetPasswordStatement extends MySqlStatementImpl {
private SQLName user;
private SQLExpr password;
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, user);
acceptChild(visitor, password);
}
visitor.endVisit(this);
}
public SQLName getUser() {
return user;
}
public void setUser(SQLName user) {
if (user != null) {
user.setParent(this);
}
this.user = user;
}
public SQLExpr getPassword() {
return password;
}
public void setPassword(SQLExpr password) {
if (password != null) {
password.setParent(this);
}
this.password = password;
}
}
@@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement
import com.alibaba.druid.sql.parser.*;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.JdbcConstants;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import java.util.ArrayList;
import java.util.List;
@@ -2289,18 +2290,23 @@ public class MySqlStatementParser extends SQLStatementParser {
public SQLStatement parseSet() {
accept(Token.SET);
if (lexer.identifierEquals("PASSWORD")) {
if (lexer.identifierEquals(FnvHash.Constants.PASSWORD)) {
lexer.nextToken();
MySqlSetPasswordStatement stmt = new MySqlSetPasswordStatement();
SQLSetStatement stmt = new SQLSetStatement();
stmt.setDbType(dbType);
stmt.setOption(SQLSetStatement.Option.PASSWORD);
SQLExpr user = null;
if (lexer.token() == Token.FOR) {
lexer.nextToken();
stmt.setUser(this.exprParser.name());
user = this.exprParser.name();
}
accept(Token.EQ);
stmt.setPassword(this.exprParser.expr());
SQLExpr password = this.exprParser.expr();
stmt.set(user, password);
return stmt;
}
@@ -403,10 +403,6 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(MySqlOptimizeStatement x);
boolean visit(MySqlSetPasswordStatement x);
void endVisit(MySqlSetPasswordStatement x);
boolean visit(MySqlHintStatement x);
void endVisit(MySqlHintStatement x);
@@ -959,16 +959,6 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
}
@Override
public boolean visit(MySqlSetPasswordStatement x) {
return true;
}
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
@Override
public boolean visit(MySqlHintStatement x) {
return true;
@@ -2956,28 +2956,31 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public boolean visit(MySqlSetPasswordStatement x) {
print0(ucase ? "SET PASSWORD " : "set password ");
if (x.getUser() != null) {
print0(ucase ? "FOR " : "for ");
x.getUser().accept(this);
public boolean visit(SQLSetStatement x) {
boolean printSet = x.getAttribute("parser.set") == Boolean.TRUE || !JdbcConstants.ORACLE.equals(dbType);
if (printSet) {
print0(ucase ? "SET " : "set ");
}
SQLSetStatement.Option option = x.getOption();
if (option != null) {
print(option.name());
print(' ');
}
print0("= ");
if (x.getPassword() != null) {
x.getPassword().accept(this);
if (option == SQLSetStatement.Option.PASSWORD) {
print0("FOR ");
}
printAndAccept(x.getItems(), ", ");
if (x.getHints() != null && x.getHints().size() > 0) {
print(' ');
printAndAccept(x.getHints(), " ");
}
return false;
}
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
@Override
public boolean visit(MySqlHintStatement x) {
List<SQLCommentHint> hints = x.getHints();
@@ -1095,16 +1095,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
}
@Override
public boolean visit(MySqlSetPasswordStatement x) {
return false;
}
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
@Override
public boolean visit(MySqlHintStatement x) {
return true;
@@ -1,52 +0,0 @@
/*
* 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.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
public class PGSetStatement extends SQLSetStatement implements PGSQLStatement {
public final String range;
public final String param;
public final List<SQLExpr> values;
// SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }
// SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }
public PGSetStatement(String range, String param, List<SQLExpr> values) {
super(JdbcConstants.POSTGRESQL);
this.range = range;
this.param = param;
this.values = values;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof PGASTVisitor) {
accept0((PGASTVisitor) visitor);
}
}
@Override
public void accept0(PGASTVisitor visitor) {
visitor.visit(this);
visitor.endVisit(this);
}
}
@@ -18,10 +18,7 @@ package com.alibaba.druid.sql.dialect.postgresql.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
@@ -327,58 +324,73 @@ public class PGSQLStatementParser extends SQLStatementParser {
lexer.nextToken();
return stmt;
}
private SQLStatement handleTimeZoneSet(String range) {
// ZONE
lexer.nextToken();
// VALUE
lexer.nextToken();
String value = lexer.stringVal();
List<SQLExpr> exprs = new ArrayList<SQLExpr>();
if (lexer.token() == Token.IDENTIFIER) {
exprs.add(new SQLIdentifierExpr(value.toUpperCase()));
} else {
exprs.add(new SQLCharExpr(value));
}
lexer.nextToken();
return new PGSetStatement(range, TIME_ZONE, exprs);
}
@Override
public SQLStatement parseSet() {
accept(Token.SET);
Token token = lexer.token();
String range = "";
SQLSetStatement.Option option = null;
if (token == Token.SESSION) {
lexer.nextToken();
range = Token.SESSION.name();
option = SQLSetStatement.Option.SESSION;
} else if (token == Token.IDENTIFIER && LOCAL.equalsIgnoreCase(lexer.stringVal())) {
range = LOCAL;
option = SQLSetStatement.Option.LOCAL;
lexer.nextToken();
}
String parameter = lexer.stringVal();
SQLExpr paramExpr;
List<SQLExpr> values = new ArrayList<SQLExpr>();
if (TIME.equalsIgnoreCase(parameter)) {
// SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }
return handleTimeZoneSet(range);
lexer.nextToken();
acceptIdentifier("ZONE");
paramExpr = new SQLIdentifierExpr("TIME ZONE");
String value = lexer.stringVal();
if (lexer.token() == Token.IDENTIFIER) {
values.add(new SQLIdentifierExpr(value.toUpperCase()));
} else {
values.add(new SQLCharExpr(value));
}
lexer.nextToken();
// return new PGSetStatement(range, TIME_ZONE, exprs);
} else {
paramExpr = new SQLIdentifierExpr(parameter);
lexer.nextToken();
while (!lexer.isEOF()) {
lexer.nextToken();
if (lexer.token() == Token.LITERAL_CHARS) {
values.add(new SQLCharExpr(lexer.stringVal()));
} else if (lexer.token() == Token.LITERAL_INT) {
values.add(new SQLIdentifierExpr(lexer.numberString()));
} else {
values.add(new SQLIdentifierExpr(lexer.stringVal()));
}
// skip comma
lexer.nextToken();
}
}
// TO | =
lexer.nextToken();
// value | 'value' | DEFAULT
List<SQLExpr> values = new ArrayList<SQLExpr>();
while (!lexer.isEOF()) {
lexer.nextToken();
if (lexer.token() == Token.LITERAL_CHARS) {
values.add(new SQLCharExpr(lexer.stringVal()));
} else if (lexer.token() == Token.LITERAL_INT) {
values.add(new SQLIdentifierExpr(lexer.numberString()));
} else {
values.add(new SQLIdentifierExpr(lexer.stringVal()));
SQLExpr valueExpr;
if (values.size() == 1) {
valueExpr = values.get(0);
} else {
SQLListExpr listExpr = new SQLListExpr();
for (SQLExpr value : values) {
listExpr.addItem(value);
}
// skip comma
lexer.nextToken();
valueExpr = listExpr;
}
return new PGSetStatement(range, parameter, values);
SQLSetStatement stmt = new SQLSetStatement(paramExpr, valueExpr, dbType);
stmt.setOption(option);
return stmt;
}
@@ -113,8 +113,4 @@ public interface PGASTVisitor extends SQLASTVisitor {
boolean visit(PGStartTransactionStatement x);
void endVisit(PGSetStatement x);
boolean visit(PGSetStatement x);
}
@@ -268,14 +268,4 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi
return true;
}
@Override
public void endVisit(PGSetStatement x) {
}
@Override
public boolean visit(PGSetStatement x) {
return true;
}
}
@@ -20,6 +20,8 @@ import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLBinaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr;
@@ -39,6 +41,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.Wind
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.StringUtils;
import java.util.List;
@@ -606,33 +609,41 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
}
@Override
public void endVisit(PGSetStatement x) {
}
@Override
public boolean visit(PGSetStatement x) {
public boolean visit(SQLSetStatement x) {
print0(ucase ? "SET " : "set ");
if (!StringUtils.isEmpty(x.range)) {
print0(x.range);
print0(" ");
SQLSetStatement.Option option = x.getOption();
if (option != null) {
print(option.name());
print(' ');
}
if (PGSQLStatementParser.TIME_ZONE.equalsIgnoreCase(x.param)) {
print0(PGSQLStatementParser.TIME_ZONE);
print0(" ");
x.values.get(0).accept(this);
return false;
}
print0(x.param);
print0(" ");
print0(Token.TO.name());
print0(" ");
for (int i = 0; i < x.values.size(); i++) {
List<SQLAssignItem> items = x.getItems();
for (int i = 0; i < items.size(); i++) {
if (i != 0) {
print0(", ");
}
x.values.get(i).accept(this);
SQLAssignItem item = x.getItems().get(i);
SQLExpr target = item.getTarget();
target.accept(this);
if (target instanceof SQLIdentifierExpr && ((SQLIdentifierExpr) target).getName().equalsIgnoreCase("TIME ZONE")) {
print(' ');
} else {
print0(" TO ");
}
SQLExpr value = item.getValue();
if (value instanceof SQLListExpr) {
SQLListExpr listExpr = (SQLListExpr) value;
printAndAccept(listExpr.getItems(), ", ");
} else {
value.accept(this);
}
}
return false;
}
}
@@ -351,13 +351,4 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
return false;
}
@Override
public void endVisit(PGSetStatement x) {
}
@Override
public boolean visit(PGSetStatement x) {
return false;
}
}
@@ -1,76 +0,0 @@
/*
* 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.dialect.sqlserver.ast.stmt;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatementImpl;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
public class SQLServerSetStatement extends SQLServerStatementImpl implements SQLServerStatement {
private Option option;
private SQLAssignItem item = new SQLAssignItem();
public SQLServerSetStatement(){
}
public SQLServerSetStatement(SQLExpr target, SQLExpr value){
this.item = new SQLAssignItem(target, value);
}
public SQLAssignItem getItem() {
return item;
}
public void setItem(SQLAssignItem item) {
if (item != null) {
item.setParent(this);
}
this.item = item;
}
public void output(StringBuffer buf) {
buf.append("SET ");
item.output(buf);
}
public Option getOption() {
return option;
}
public void setOption(Option option) {
this.option = option;
}
@Override
public void accept0(SQLServerASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.item);
}
visitor.endVisit(this);
}
public void set(SQLExpr target, SQLExpr value) {
SQLAssignItem assignItem = new SQLAssignItem(target, value);
setItem(assignItem);
}
public static enum Option {
IDENTITY_INSERT
}
}
@@ -33,7 +33,6 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
@@ -405,18 +404,19 @@ public class SQLServerStatementParser extends SQLStatementParser {
if (lexer.identifierEquals(FnvHash.Constants.STATISTICS)) {
lexer.nextToken();
SQLServerSetStatement stmt = new SQLServerSetStatement();
SQLSetStatement stmt = new SQLSetStatement();
if (lexer.identifierEquals("IO") || lexer.identifierEquals("XML") || lexer.identifierEquals("PROFILE")
|| lexer.identifierEquals("TIME")) {
stmt.getItem().setTarget(new SQLIdentifierExpr("STATISTICS " + lexer.stringVal().toUpperCase()));
SQLExpr target = new SQLIdentifierExpr("STATISTICS " + lexer.stringVal().toUpperCase());
lexer.nextToken();
if (lexer.token() == Token.ON) {
stmt.getItem().setValue(new SQLIdentifierExpr("ON"));
stmt.set(target, new SQLIdentifierExpr("ON"));
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.OFF)) {
stmt.getItem().setValue(new SQLIdentifierExpr("OFF"));
stmt.set(target, new SQLIdentifierExpr("OFF"));
lexer.nextToken();
}
}
@@ -424,8 +424,8 @@ public class SQLServerStatementParser extends SQLStatementParser {
}
if (lexer.identifierEquals(FnvHash.Constants.IDENTITY_INSERT)) {
SQLServerSetStatement stmt = new SQLServerSetStatement();
stmt.setOption(SQLServerSetStatement.Option.IDENTITY_INSERT);
SQLSetStatement stmt = new SQLSetStatement();
stmt.setOption(SQLSetStatement.Option.IDENTITY_INSERT);
lexer.nextToken();
SQLName table = this.exprParser.name();
@@ -447,17 +447,17 @@ public class SQLServerStatementParser extends SQLStatementParser {
parseAssignItems(stmt.getItems(), stmt);
return stmt;
} else {
SQLServerSetStatement stmt = new SQLServerSetStatement();
stmt.getItem().setTarget(this.exprParser.expr());
SQLSetStatement stmt = new SQLSetStatement();
SQLExpr target = this.exprParser.expr();
if (lexer.token() == Token.ON) {
stmt.getItem().setValue(new SQLIdentifierExpr("ON"));
stmt.set(target, new SQLIdentifierExpr("ON"));
lexer.nextToken();
} else if (lexer.identifierEquals("OFF")) {
stmt.getItem().setValue(new SQLIdentifierExpr("OFF"));
stmt.set(target, new SQLIdentifierExpr("OFF"));
lexer.nextToken();
} else {
stmt.getItem().setValue(this.exprParser.expr());
stmt.set(target, this.exprParser.expr());
}
return stmt;
}
@@ -23,7 +23,6 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
@@ -58,11 +57,7 @@ public interface SQLServerASTVisitor extends SQLASTVisitor {
boolean visit(SQLServerSetTransactionIsolationLevelStatement x);
void endVisit(SQLServerSetTransactionIsolationLevelStatement x);
boolean visit(SQLServerSetStatement x);
void endVisit(SQLServerSetStatement x);
boolean visit(SQLServerOutput x);
void endVisit(SQLServerOutput x);
@@ -23,7 +23,6 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
@@ -101,16 +100,6 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements
}
@Override
public boolean visit(SQLServerSetStatement x) {
return true;
}
@Override
public void endVisit(SQLServerSetStatement x) {
}
@Override
public boolean visit(SQLServerOutput x) {
return true;
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.sqlserver.visitor;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
@@ -25,13 +26,15 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLServerASTVisitor {
public SQLServerOutputVisitor(Appendable appender){
@@ -348,27 +351,38 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
}
@Override
public boolean visit(SQLServerSetStatement x) {
public boolean visit(SQLSetStatement x) {
print0(ucase ? "SET " : "set ");
SQLServerSetStatement.Option option = x.getOption();
SQLSetStatement.Option option = x.getOption();
if (option != null) {
print(option.name());
print(' ');
}
SQLAssignItem item = x.getItem();
item.getTarget().accept(this);
print(' ');
item.getValue().accept(this);
List<SQLAssignItem> items = x.getItems();
for (int i = 0; i < items.size(); i++) {
if (i != 0) {
print0(", ");
}
SQLAssignItem item = x.getItems().get(i);
item.getTarget().accept(this);
SQLExpr value = item.getValue();
if (value instanceof SQLIdentifierExpr
&& (((SQLIdentifierExpr) value).nameHashCode64() == FnvHash.Constants.ON
|| ((SQLIdentifierExpr) value).nameHashCode64() == FnvHash.Constants.OFF)) {
print(' ');
} else {
print0(" = ");
}
value.accept(this);
}
return false;
}
@Override
public void endVisit(SQLServerSetStatement x) {
}
@Override
public boolean visit(SQLServerOutput x) {
print0(ucase ? "OUTPUT " : "output ");
@@ -27,7 +27,6 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
@@ -119,16 +118,6 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL
}
@Override
public boolean visit(SQLServerSetStatement x) {
return false;
}
@Override
public void endVisit(SQLServerSetStatement x) {
}
@Override
public boolean visit(SQLServerOutput x) {
return false;
@@ -2615,6 +2615,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
if (printSet) {
print0(ucase ? "SET " : "set ");
}
SQLSetStatement.Option option = x.getOption();
if (option != null) {
print(option.name());
print(' ');
}
printAndAccept(x.getItems(), ", ");
if (x.getHints() != null && x.getHints().size() > 0) {
@@ -495,5 +495,6 @@ public final class FnvHash {
long TRANSACTION = fnv1a_64_lower("TRANSACTION");
long OFF = fnv1a_64_lower("OFF");
long IDENTITY_INSERT = fnv1a_64_lower("IDENTITY_INSERT");
long PASSWORD = fnv1a_64_lower("PASSWORD");
}
}
@@ -35,7 +35,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGShowStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
@@ -2507,8 +2506,7 @@ public class WallVisitorUtils {
allow = config.isDropTableAllow();
denyMessage = "drop table not allow";
errorCode = ErrorCode.DROP_TABLE_NOT_ALLOW;
} else if (x instanceof SQLSetStatement //
|| x instanceof SQLServerSetStatement) {
} else if (x instanceof SQLSetStatement) {
allow = config.isSetAllow();
denyMessage = "set not allow";
errorCode = ErrorCode.SET_NOT_ALLOW;
@@ -16,11 +16,11 @@
package com.alibaba.druid.bvt.sql.postgresql;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
public class PGSetTest3 extends PGTest {
public void testSet() throws Exception {
Class<?> type = PGSetStatement.class;
Class<?> type = SQLSetStatement.class;
String sql = "SET TIME ZONE 'Europe/Rome';";
String expectedSql = "SET TIME ZONE 'Europe/Rome';";