Merge pull request #248 from wenshao/master

增强SQL Parser
This commit is contained in:
温高铁
2013-01-12 00:04:30 -08:00
33 changed files with 1343 additions and 87 deletions
@@ -18,7 +18,6 @@ package com.alibaba.druid.sql.ast;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLDataTypeImpl extends SQLObjectImpl implements SQLDataType {
@@ -16,11 +16,12 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlUnionQuery extends SQLUnionQuery implements MySqlStatement {
public class MySqlUnionQuery extends SQLUnionQuery implements MySqlObject {
private static final long serialVersionUID = 1L;
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
@@ -199,27 +200,7 @@ public class MySqlStatementParser extends SQLStatementParser {
stmt.setTableSource(tableSource);
}
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
if (lexer.token() == Token.EQ) {
lexer.nextToken();
} else {
accept(Token.COLONEQ);
}
item.setValue(this.exprParser.expr());
stmt.getItems().add(item);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
parseUpdateSet(stmt);
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
@@ -2361,4 +2342,35 @@ public class MySqlStatementParser extends SQLStatementParser {
return stmt;
}
protected void parseUpdateSet(SQLUpdateStatement update) {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems());
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
item.setValue(this.exprParser.expr());
update.getItems().add(item);
if (lexer.token() != Token.COMMA) {
break;
}
lexer.nextToken();
}
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 1999-2011 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.oracle.ast;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleDataTypeIntervalDay extends SQLDataTypeImpl implements OracleSQLObject {
private static final long serialVersionUID = 1L;
private boolean toSecond = false;
protected final List<SQLExpr> fractionalSeconds = new ArrayList<SQLExpr>();
public OracleDataTypeIntervalDay(){
this.setName("INTERVAL DAY");
}
@Override
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getArguments());
}
visitor.endVisit(this);
}
public boolean isToSecond() {
return toSecond;
}
public void setToSecond(boolean toSecond) {
this.toSecond = toSecond;
}
public List<SQLExpr> getFractionalSeconds() {
return fractionalSeconds;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 1999-2011 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.oracle.ast;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleDataTypeIntervalYear extends SQLDataTypeImpl implements OracleSQLObject {
private static final long serialVersionUID = 1L;
public OracleDataTypeIntervalYear(){
this.setName("INTERVAL YEAR");
}
@Override
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getArguments());
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 1999-2011 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.oracle.ast;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleDataTypeTimestamp extends SQLDataTypeImpl implements OracleSQLObject {
private static final long serialVersionUID = 1L;
private boolean withTimeZone = false;
private boolean withLocalTimeZone = false;
public OracleDataTypeTimestamp() {
this.setName("TIMESTAMP");
}
@Override
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getArguments());
}
visitor.endVisit(this);
}
public boolean isWithTimeZone() {
return withTimeZone;
}
public void setWithTimeZone(boolean withTimeZone) {
this.withTimeZone = withTimeZone;
}
public boolean isWithLocalTimeZone() {
return withLocalTimeZone;
}
public void setWithLocalTimeZone(boolean withLocalTimeZone) {
this.withLocalTimeZone = withLocalTimeZone;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 1999-2011 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.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
public class OracleDropSequenceStatement extends OracleStatementImpl implements OracleDDLStatement {
private static final long serialVersionUID = 1L;
private SQLName name;
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
this.name = name;
}
}
@@ -37,6 +37,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
@@ -75,6 +78,7 @@ public class OracleExprParser extends SQLExprParser {
public boolean allowStringAdditive = false;
/**
@@ -117,9 +121,73 @@ public class OracleExprParser extends SQLExprParser {
return null;
}
if (lexer.token() == Token.INTERVAL) {
lexer.nextToken();
if (identifierEquals("YEAR")) {
lexer.nextToken();
OracleDataTypeIntervalYear interval = new OracleDataTypeIntervalYear();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
interval.getArguments().add(this.expr());
accept(Token.RPAREN);
}
accept(Token.TO);
acceptIdentifier("MONTH");
return interval;
} else {
acceptIdentifier("DAY");
OracleDataTypeIntervalDay interval = new OracleDataTypeIntervalDay();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
interval.getArguments().add(this.expr());
accept(Token.RPAREN);
}
accept(Token.TO);
acceptIdentifier("SECOND");
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
interval.getFractionalSeconds().add(this.expr());
accept(Token.RPAREN);
}
return interval;
}
}
SQLName typeExpr = name();
String typeName = typeExpr.toString();
if ("TIMESTAMP".equalsIgnoreCase(typeName)) {
OracleDataTypeTimestamp timestamp = new OracleDataTypeTimestamp();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
timestamp.getArguments().add(this.expr());
accept(Token.RPAREN);
}
if (lexer.token() == Token.WITH) {
lexer.nextToken();
if (identifierEquals("LOCAL")) {
lexer.nextToken();
timestamp.setWithLocalTimeZone(true);
} else {
timestamp.setWithTimeZone(true);
}
acceptIdentifier("TIME");
acceptIdentifier("ZONE");
}
return timestamp;
}
if (isCharType(typeName)) {
SQLCharactorDataType charType = new SQLCharactorDataType(typeName);
@@ -72,6 +72,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatem
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropDatabaseLinkStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement;
@@ -444,6 +445,18 @@ public class OracleStatementParser extends SQLStatementParser {
continue;
}
}
if (identifierEquals("SEQUENCE")) {
lexer.nextToken();
SQLName name = this.exprParser.name();
OracleDropSequenceStatement stmt = new OracleDropSequenceStatement();
stmt.setName(name);
statementList.add(stmt);
continue;
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
@@ -55,7 +55,7 @@ public class OracleUpdateParser extends SQLStatementParser {
}
}
parseSet(update);
parseUpdateSet(update);
parseWhere(update);
@@ -117,30 +117,4 @@ public class OracleUpdateParser extends SQLStatementParser {
}
}
private void parseSet(OracleUpdateStatement update) {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems());
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
accept(Token.EQ);
item.setValue(this.exprParser.expr());
update.getItems().add(item);
if (lexer.token() != Token.COMMA) {
break;
}
lexer.nextToken();
}
}
}
@@ -16,6 +16,9 @@
package com.alibaba.druid.sql.dialect.oracle.visitor;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
@@ -77,6 +80,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStateme
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropDatabaseLinkStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement;
@@ -611,4 +615,20 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleDropDatabaseLinkStatement x);
void endVisit(OracleDropDatabaseLinkStatement x);
boolean visit(OracleDataTypeTimestamp x);
void endVisit(OracleDataTypeTimestamp x);
boolean visit(OracleDataTypeIntervalYear x);
void endVisit(OracleDataTypeIntervalYear x);
boolean visit(OracleDataTypeIntervalDay x);
void endVisit(OracleDataTypeIntervalDay x);
boolean visit(OracleDropSequenceStatement x);
void endVisit(OracleDropSequenceStatement x);
}
@@ -16,6 +16,9 @@
package com.alibaba.druid.sql.dialect.oracle.visitor;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
@@ -85,6 +88,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStateme
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropDatabaseLinkStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement;
@@ -1393,4 +1397,44 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
}
@Override
public boolean visit(OracleDataTypeTimestamp x) {
return true;
}
@Override
public void endVisit(OracleDataTypeTimestamp x) {
}
@Override
public boolean visit(OracleDataTypeIntervalYear x) {
return true;
}
@Override
public void endVisit(OracleDataTypeIntervalYear x) {
}
@Override
public boolean visit(OracleDataTypeIntervalDay x) {
return true;
}
@Override
public void endVisit(OracleDataTypeIntervalDay x) {
}
@Override
public boolean visit(OracleDropSequenceStatement x) {
return true;
}
@Override
public void endVisit(OracleDropSequenceStatement x) {
}
}
@@ -38,6 +38,9 @@ import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
@@ -114,6 +117,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStateme
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropDatabaseLinkStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement;
@@ -3107,4 +3111,83 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
return false;
}
@Override
public boolean visit(OracleDataTypeTimestamp x) {
print(x.getName());
if (x.getArguments().size() > 0) {
print("(");
x.getArguments().get(0).accept(this);
print(")");
}
if (x.isWithTimeZone()) {
print(" WITH TIME ZONE");
} else if (x.isWithLocalTimeZone()) {
print(" WITH LOCAL TIME ZONE");
}
return false;
}
@Override
public void endVisit(OracleDataTypeTimestamp x) {
}
@Override
public boolean visit(OracleDataTypeIntervalYear x) {
print(x.getName());
if (x.getArguments().size() > 0) {
print("(");
x.getArguments().get(0).accept(this);
print(")");
}
print(" TO MONTH");
return false;
}
@Override
public void endVisit(OracleDataTypeIntervalYear x) {
}
@Override
public boolean visit(OracleDataTypeIntervalDay x) {
print(x.getName());
if (x.getArguments().size() > 0) {
print("(");
x.getArguments().get(0).accept(this);
print(")");
}
print(" TO SECOND");
if (x.getFractionalSeconds().size() > 0) {
print("(");
x.getFractionalSeconds().get(0).accept(this);
print(")");
}
return false;
}
@Override
public void endVisit(OracleDataTypeIntervalDay x) {
}
@Override
public boolean visit(OracleDropSequenceStatement x) {
print("DROP SEQUENCE ");
x.getName().accept(this);
return false;
}
@Override
public void endVisit(OracleDropSequenceStatement x) {
}
}
@@ -37,6 +37,9 @@ import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
@@ -106,6 +109,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStateme
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropDatabaseLinkStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDropSequenceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement;
@@ -1822,4 +1826,44 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(OracleDropDatabaseLinkStatement x) {
}
@Override
public boolean visit(OracleDataTypeTimestamp x) {
return false;
}
@Override
public void endVisit(OracleDataTypeTimestamp x) {
}
@Override
public boolean visit(OracleDataTypeIntervalYear x) {
return false;
}
@Override
public void endVisit(OracleDataTypeIntervalYear x) {
}
@Override
public boolean visit(OracleDataTypeIntervalDay x) {
return false;
}
@Override
public void endVisit(OracleDataTypeIntervalDay x) {
}
@Override
public boolean visit(OracleDropSequenceStatement x) {
return false;
}
@Override
public void endVisit(OracleDropSequenceStatement x) {
}
}
@@ -60,23 +60,7 @@ public class PGSQLStatementParser extends SQLStatementParser {
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
udpateStatement.setTableSource(tableSource);
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
accept(Token.EQ);
item.setValue(this.exprParser.expr());
udpateStatement.getItems().add(item);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
parseUpdateSet(udpateStatement);
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
@@ -17,6 +17,6 @@ package com.alibaba.druid.sql.dialect.sqlserver.ast;
import com.alibaba.druid.sql.ast.SQLStatement;
public interface SQLServerStatement extends SQLStatement {
public interface SQLServerStatement extends SQLStatement, SQLServerObject {
}
@@ -0,0 +1,55 @@
/*
* Copyright 1999-2011 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.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLServerUpdateStatement extends SQLUpdateStatement implements SQLServerStatement {
private static final long serialVersionUID = 1L;
private SQLTableSource from;
public SQLTableSource getFrom() {
return from;
}
public void setFrom(SQLTableSource from) {
this.from = from;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
this.accept0((SQLServerASTVisitor) visitor);
}
@Override
public void accept0(SQLServerASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, tableSource);
acceptChild(visitor, items);
acceptChild(visitor, from);
acceptChild(visitor, where);
}
visitor.endVisit(this);
}
}
@@ -15,11 +15,14 @@
*/
package com.alibaba.druid.sql.dialect.sqlserver.parser;
import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.druid.sql.parser.Keywords;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.NotAllowCommentException;
import com.alibaba.druid.sql.parser.Token;
public class SQLServerLexer extends Lexer {
@@ -48,4 +51,95 @@ public class SQLServerLexer extends Lexer {
super(input);
super.keywods = DEFAULT_SQL_SERVER_KEYWORDS;
}
public void scanComment() {
if (ch != '/' && ch != '-') {
throw new IllegalStateException();
}
mark = pos;
bufPos = 0;
scanChar();
// /*+ */
if (ch == '*') {
scanChar();
bufPos++;
while (ch == ' ') {
scanChar();
bufPos++;
}
boolean isHint = false;
int startHintSp = bufPos + 1;
if (ch == '!') {
isHint = true;
scanChar();
bufPos++;
}
for (;;) {
if (ch == '*' && charAt(pos + 1) == '/') {
bufPos += 2;
scanChar();
scanChar();
break;
}
scanChar();
bufPos++;
}
if (isHint) {
stringVal = subString(mark + startHintSp, (bufPos - startHintSp) - 1);
token = Token.HINT;
} else {
stringVal = subString(mark, bufPos);
token = Token.MULTI_LINE_COMMENT;
}
if (token != Token.HINT && !isAllowComment()) {
throw new NotAllowCommentException();
}
return;
}
if (!isAllowComment()) {
throw new NotAllowCommentException();
}
if (ch == '/' || ch == '-') {
scanChar();
bufPos++;
for (;;) {
if (ch == '\r') {
if (charAt(pos + 1) == '\n') {
bufPos += 2;
scanChar();
break;
}
bufPos++;
break;
} else if (ch == EOI) {
break;
}
if (ch == '\n') {
scanChar();
bufPos++;
break;
}
scanChar();
bufPos++;
}
stringVal = subString(mark + 1, bufPos);
token = Token.LINE_COMMENT;
return;
}
}
}
@@ -37,6 +37,8 @@ public class SQLServerSelectParser extends SQLSelectParser {
public SQLSelect select() {
SQLServerSelect select = new SQLServerSelect();
withSubquery(select);
select.setQuery(query());
select.setOrderBy(parseOrderBy());
@@ -15,12 +15,18 @@
*/
package com.alibaba.druid.sql.dialect.sqlserver.parser;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
@@ -40,6 +46,16 @@ public class SQLServerStatementParser extends SQLStatementParser {
super(new SQLServerExprParser(lexer));
}
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
if (lexer.token() == Token.WITH) {
SQLStatement stmt = parseSelect();
statementList.add(stmt);
return true;
}
return false;
}
public SQLStatement parseInsert() {
SQLServerInsertStatement insertStatement = new SQLServerInsertStatement();
@@ -100,4 +116,34 @@ public class SQLServerStatementParser extends SQLStatementParser {
insertStatement.setQuery(queryExpr.getSubQuery());
}
}
protected SQLServerUpdateStatement createUpdateStatement() {
return new SQLServerUpdateStatement();
}
public SQLUpdateStatement parseUpdateStatement() {
SQLServerUpdateStatement udpateStatement = createUpdateStatement();
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
udpateStatement.setTableSource(tableSource);
}
parseUpdateSet(udpateStatement);
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLTableSource from = this.exprParser.createSelectParser().parseTableSource();
udpateStatement.setFrom(from);
}
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
udpateStatement.setWhere(this.exprParser.expr());
}
return udpateStatement;
}
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.Top;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public interface SQLServerASTVisitor extends SQLASTVisitor {
@@ -38,4 +39,8 @@ public interface SQLServerASTVisitor extends SQLASTVisitor {
boolean visit(SQLServerInsertStatement x);
void endVisit(SQLServerInsertStatement x);
boolean visit(SQLServerUpdateStatement x);
void endVisit(SQLServerUpdateStatement x);
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.Top;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements SQLServerASTVisitor {
@@ -63,4 +64,14 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements
}
@Override
public boolean visit(SQLServerUpdateStatement x) {
return true;
}
@Override
public void endVisit(SQLServerUpdateStatement x) {
}
}
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.Top;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLServerASTVisitor {
@@ -144,4 +145,40 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
}
@Override
public boolean visit(SQLServerUpdateStatement x) {
print("UPDATE ");
x.getTableSource().accept(this);
println();
print("SET ");
for (int i = 0, size = x.getItems().size(); i < size; ++i) {
if (i != 0) {
print(", ");
}
x.getItems().get(i).accept(this);
}
if (x.getFrom() != null) {
println();
print("FROM ");
x.getFrom().setParent(x);
x.getFrom().accept(this);
}
if (x.getWhere() != null) {
println();
print("WHERE ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
return false;
}
@Override
public void endVisit(SQLServerUpdateStatement x) {
}
}
@@ -15,13 +15,17 @@
*/
package com.alibaba.druid.sql.dialect.sqlserver.visitor;
import java.util.Map;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.Top;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcUtils;
@@ -73,5 +77,30 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL
this.endVisit((SQLInsertStatement) x);
}
@Override
public boolean visit(SQLServerUpdateStatement x) {
setAliasMap();
String ident = x.getTableName().toString();
setCurrentTable(ident);
TableStat stat = getTableStat(ident);
stat.incrementUpdateCount();
Map<String, String> aliasMap = getAliasMap();
aliasMap.put(ident, ident);
accept(x.getItems());
accept(x.getFrom());
accept(x.getWhere());
return false;
}
@Override
public void endVisit(SQLServerUpdateStatement x) {
}
}
@@ -21,6 +21,7 @@ import java.util.List;
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.SQLListExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
@@ -38,6 +39,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLReleaseSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
@@ -80,7 +82,7 @@ public class SQLStatementParser extends SQLParser {
continue;
}
if (lexer.token() == (Token.SELECT)) {
if (lexer.token() == Token.SELECT) {
statementList.add(parseSelect());
continue;
}
@@ -545,7 +547,9 @@ public class SQLStatementParser extends SQLParser {
}
public SQLSelectStatement parseSelect() {
return new SQLSelectStatement(createSQLSelectParser().select());
SQLSelectParser selectParser = createSQLSelectParser();
SQLSelect select = selectParser.select();
return new SQLSelectStatement(select);
}
public SQLSelectParser createSQLSelectParser() {
@@ -562,23 +566,7 @@ public class SQLStatementParser extends SQLParser {
udpateStatement.setTableSource(tableSource);
}
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
accept(Token.EQ);
item.setValue(this.exprParser.expr());
udpateStatement.getItems().add(item);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
parseUpdateSet(udpateStatement);
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
@@ -587,6 +575,33 @@ public class SQLStatementParser extends SQLParser {
return udpateStatement;
}
protected void parseUpdateSet(SQLUpdateStatement update) {
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprParser.exprList(list.getItems());
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.exprParser.primary());
}
accept(Token.EQ);
item.setValue(this.exprParser.expr());
update.getItems().add(item);
if (lexer.token() != Token.COMMA) {
break;
}
lexer.nextToken();
}
}
protected SQLUpdateStatement createUpdateStatement() {
return new SQLUpdateStatement();
@@ -46,6 +46,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
@@ -222,6 +223,13 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
return true;
}
@Override
public boolean visit(MySqlUnionQuery x) {
WallVisitorUtils.checkUnion(this, x);
return true;
}
@Override
public String toSQL(SQLObject obj) {
@@ -0,0 +1,52 @@
/*
* Copyright 1999-2011 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.bvt.filter.wall;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.wall.WallUtils;
/**
* SQLServerWallTest
*
* @author RaymondXiu
* @version 1.0, 2012-3-18
* @see
*/
public class MySqlWallTest1 extends TestCase {
/**
* @param name
*/
public MySqlWallTest1(String name){
super(name);
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void test_stuff() throws Exception {
Assert.assertTrue(WallUtils.isValidateMySql(//
"select count(*) from (select DATE_FORMAT(staydate,'%m月') as month,sum(a) as addnum,sum(q) as quitnum from (select staydate,1 as a,0 as q from add_person union all select quitdate,0 as a,1 as q from quit_person) t where (DATE_FORMAT(staydate,'%Y')= ? ) group by DATE_FORMAT(staydate,'%Y-%m'))"));
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 1999-2011 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.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
public class OracleCreateTableTest15 extends OracleTest {
public void test_types() throws Exception {
String sql = //
"create table T (" + //
"F1 TIMESTAMP," + //
"F2 TIMESTAMP(9), " + //
"F3 TIMESTAMP WITH TIME ZONE," + //
"F4 TIMESTAMP(9) WITH TIME ZONE, " + //
"F5 TIMESTAMP WITH TIME ZONE," + //
"F6 TIMESTAMP(9) WITH TIME ZONE" + //
") ";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statement = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
Assert.assertEquals("CREATE TABLE T (" + //
"\n\tF1 TIMESTAMP," + //
"\n\tF2 TIMESTAMP(9)," + //
"\n\tF3 TIMESTAMP WITH TIME ZONE," + //
"\n\tF4 TIMESTAMP(9) WITH TIME ZONE," + //
"\n\tF5 TIMESTAMP WITH TIME ZONE," + //
"\n\tF6 TIMESTAMP(9) WITH TIME ZONE" + //
"\n)", SQLUtils.toSQLString(statement, JdbcConstants.ORACLE));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statement.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
System.out.println("coditions : " + visitor.getConditions());
System.out.println("relationships : " + visitor.getRelationships());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(6, visitor.getColumns().size());
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F1")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F2")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F3")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F4")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F5")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F6")));
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 1999-2011 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.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
public class OracleCreateTableTest16 extends OracleTest {
public void test_types() throws Exception {
String sql = //
"create table T (" + //
"F1 INTERVAL YEAR TO MONTH," + //
"F2 INTERVAL YEAR (3) TO MONTH," + //
"F3 INTERVAL DAY TO SECOND," + //
"F4 INTERVAL DAY (3) TO SECOND," + //
"F5 INTERVAL DAY TO SECOND (9)," + //
"F6 INTERVAL DAY (3) TO SECOND (9)" + //
") ";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statement = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
Assert.assertEquals("CREATE TABLE T (" + //
"\n\tF1 INTERVAL YEAR TO MONTH," + //
"\n\tF2 INTERVAL YEAR(3) TO MONTH," + //
"\n\tF3 INTERVAL DAY TO SECOND," + //
"\n\tF4 INTERVAL DAY(3) TO SECOND," + //
"\n\tF5 INTERVAL DAY TO SECOND(9)," + //
"\n\tF6 INTERVAL DAY(3) TO SECOND(9)" + //
"\n)", SQLUtils.toSQLString(statement, JdbcConstants.ORACLE));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statement.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
System.out.println("coditions : " + visitor.getConditions());
System.out.println("relationships : " + visitor.getRelationships());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(6, visitor.getColumns().size());
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F1")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F2")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F3")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F4")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F5")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("T", "F6")));
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 1999-2011 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.bvt.sql.oracle;
import java.util.List;
import junit.framework.Assert;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
public class OracleDropSequenceTest extends OracleTest {
public void test_types() throws Exception {
String sql = //
"DROP SEQUENCE oe.customers_seq";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statement = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
Assert.assertEquals("DROP SEQUENCE oe.customers_seq", SQLUtils.toSQLString(statement, JdbcConstants.ORACLE));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statement.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
System.out.println("coditions : " + visitor.getConditions());
System.out.println("relationships : " + visitor.getRelationships());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(0, visitor.getTables().size());
Assert.assertEquals(0, visitor.getColumns().size());
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 1999-2011 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.bvt.sql.sqlserver;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
import com.alibaba.druid.sql.test.TestUtils;
public class SQLServerSelectTest6 extends TestCase {
public void test_isEmpty() throws Exception {
String sql = "WITH DirReps(ManagerID, DirectReports) AS " + //
"(" + //
" SELECT ManagerID, COUNT(*) " + //
" FROM HumanResources.Employee AS e" + //
" WHERE ManagerID IS NOT NULL" + //
" GROUP BY ManagerID" + //
")" + //
"SELECT ManagerID, DirectReports " + //
"FROM DirReps " + //
"ORDER BY ManagerID;";
String expect = "WITH" +
"\n\tDirReps (ManagerID, DirectReports)" +
"\n\tAS" +
"\n\t(" +
"\n\t\tSELECT ManagerID, COUNT(*)" +
"\n\t\tFROM HumanResources.Employee e" +
"\n\t\tWHERE ManagerID IS NOT NULL" +
"\n\t\tGROUP BY ManagerID" +
"\n\t)" +
"\nSELECT ManagerID, DirectReports" +
"\nFROM DirReps" +
"\nORDER BY ManagerID";
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
String text = TestUtils.outputSqlServer(stmt);
Assert.assertEquals(expect, text);
System.out.println(text);
}
}
@@ -0,0 +1,109 @@
/*
* Copyright 1999-2011 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.bvt.sql.sqlserver;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
import com.alibaba.druid.sql.test.TestUtils;
public class SQLServerSelectTest7 extends TestCase {
public void test_isEmpty() throws Exception {
String sql = "with menu_view as(" +
"\n select t.*,1 level from sec_portal_menu t where t.parent_id = ?" +
"\n union all" +
"\n select t.*,level + 1 from sec_portal_menu t , menu_view x where t.parent_id = x.menu_id" +
"\n )" +
"\n select t.menu_id \"id\"," +
"\n t.menu_name \"name\"," +
"\n t.parent_id \"pId\"," +
"\n case t.level when 1 then 'true' else 'false' end \"open\"," +
"\n t.link_type \"linkType\"" +
"\n from menu_view t" +
"\n where 1=1" +
"\n and t.deleted = 0" +
"\n --菜单权限控制" +
"\n AND t.link_type in ('simple','link')" +
"\n AND (" +
"\n EXISTS (" +
"\n select p.entity_code from sec_role_auth p where p.entity_code = t.menu_id" +
"\n and p.entity_type = 'menu'" +
"\n and p.role_id in (" +
"\n select r.role_code from sec_role_member rm ,sec_role r where rm.entity_type = 'user'" +
"\n and entity_code = ? --用户ID" +
"\n and r.role_id = rm.role_id" +
"\n and r.enabled = 1" +
"\n and r.deleted = 0" +
"\n )" +
"\n )" +
"\n or '1'= ? --超级管理员账户id" +
"\n or t.need_control = 0" +
"\n )" +
"\n AND (" +
"\n t.enabled = 1 or '1'= ? --超级管理员账户id" +
"\n or t.need_control = 0" +
"\n )" +
"\n order by t.sort_order";
String expect = "WITH" +
"\n\tmenu_view" +
"\n\tAS" +
"\n\t(" +
"\n\t\tSELECT t.*, 1 AS level" +
"\n\t\tFROM sec_portal_menu t" +
"\n\t\tWHERE t.parent_id = ?" +
"\n\t\tUNION ALL" +
"\n\t\tSELECT t.*, level + 1" +
"\n\t\tFROM sec_portal_menu t, menu_view x" +
"\n\t\tWHERE t.parent_id = x.menu_id" +
"\n\t)" +
"\nSELECT t.menu_id AS \"id\", t.menu_name AS \"name\", t.parent_id AS \"pId\", CASE t.level WHEN 1 THEN 'true' ELSE 'false' END AS \"open\", t.link_type AS \"linkType\"" +
"\nFROM menu_view t" +
"\nWHERE 1 = 1" +
"\n\tAND t.deleted = 0" +
"\n\tAND t.link_type IN ('simple', 'link')" +
"\n\tAND (EXISTS (SELECT p.entity_code" +
"\n\t\t\tFROM sec_role_auth p" +
"\n\t\t\tWHERE p.entity_code = t.menu_id" +
"\n\t\t\t\tAND p.entity_type = 'menu'" +
"\n\t\t\t\tAND p.role_id IN (SELECT r.role_code" +
"\n\t\t\t\t\tFROM sec_role_member rm, sec_role r" +
"\n\t\t\t\t\tWHERE rm.entity_type = 'user'" +
"\n\t\t\t\t\t\tAND entity_code = ?" +
"\n\t\t\t\t\t\tAND r.role_id = rm.role_id" +
"\n\t\t\t\t\t\tAND r.enabled = 1" +
"\n\t\t\t\t\t\tAND r.deleted = 0))" +
"\n\t\tOR '1' = ?" +
"\n\t\tOR t.need_control = 0)" +
"\n\tAND (t.enabled = 1" +
"\n\t\tOR '1' = ?" +
"\n\t\tOR t.need_control = 0)" +
"\nORDER BY t.sort_order";
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
String text = TestUtils.outputSqlServer(stmt);
Assert.assertEquals(expect, text);
System.out.println(text);
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 1999-2011 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.bvt.sql.sqlserver;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
import com.alibaba.druid.sql.test.TestUtils;
public class SQLServerUpdateTest extends TestCase {
public void test_isEmpty() throws Exception {
String sql = "update reg_student_charge_item " + //
"set FAmountReceived = b.amount " + //
"from reg_student_charge_item a" + //
" ,(" + //
" select a.FId, " + //
" case when sum(b.FChargeAmount) is null then 0 " + //
" else sum(b.FChargeAmount)" + //
" end as amount " + //
" from reg_student_charge_item a " + //
" left join reg_student_charge_daybook b on a.FId = b.FChargeItemId" + //
" where a.FId=? group by a.FId" + //
" ) b " + //
"where a.FId = b.FId and a.FId = ?";
String expect = "UPDATE reg_student_charge_item" +
"\nSET FAmountReceived = b.amount" +
"\nFROM reg_student_charge_item a, (SELECT a.FId, CASE WHEN SUM(b.FChargeAmount) IS NULL THEN 0 ELSE SUM(b.FChargeAmount) END AS amount" +
"\n\t\tFROM reg_student_charge_item a" +
"\n\t\t\tLEFT JOIN reg_student_charge_daybook b ON a.FId = b.FChargeItemId" +
"\n\t\tWHERE a.FId = ? GROUP BY a.FId" +
"\n\t\t) b" +
"\nWHERE a.FId = b.FId" +
"\nAND a.FId = ?";
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
String text = TestUtils.outputSqlServer(stmt);
Assert.assertEquals(expect, text);
System.out.println(text);
}
}