diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLParameter.java b/src/main/java/com/alibaba/druid/sql/ast/SQLParameter.java index d18be27146..d2a597d6f4 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLParameter.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLParameter.java @@ -21,16 +21,17 @@ import java.util.ArrayList; import java.util.List; public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDataType { - - private SQLName name; - private SQLDataType dataType; - private SQLExpr defaultValue; - private ParameterType paramType; - private boolean noCopy = false; - private boolean constant = false; - - private SQLName cursorName; + private SQLName name; + private SQLDataType dataType; + private SQLExpr defaultValue; + private ParameterType paramType; + private boolean noCopy = false; + private boolean constant = false; + private SQLName cursorName; private final List cursorParameters = new ArrayList(); + private boolean order; + private boolean map; + private boolean member; public SQLExpr getDefaultValue() { return defaultValue; @@ -135,6 +136,8 @@ public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDa x.paramType = paramType; x.noCopy = noCopy; x.constant = constant; + x.order = order; + x.map = map; if (cursorName != null) { x.setCursorName(cursorName.clone()); } @@ -145,4 +148,28 @@ public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDa } return x; } + + public boolean isOrder() { + return order; + } + + public void setOrder(boolean order) { + this.order = order; + } + + public boolean isMap() { + return map; + } + + public void setMap(boolean map) { + this.map = map; + } + + public boolean isMember() { + return member; + } + + public void setMember(boolean member) { + this.member = member; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSynonymStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSynonymStatement.java new file mode 100644 index 0000000000..9fe0d15724 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSynonymStatement.java @@ -0,0 +1,103 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +import java.util.ArrayList; +import java.util.List; + +public class SQLDropSynonymStatement extends SQLStatementImpl implements SQLDropStatement { + + private SQLName name; + private boolean ifExists; + private boolean isPublic; + private boolean force; + + public SQLDropSynonymStatement() { + + } + + public SQLDropSynonymStatement(String dbType) { + super (dbType); + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + } + visitor.endVisit(this); + } + + @Override + public List getChildren() { + List children = new ArrayList(); + if (name != null) { + children.add(name); + } + return children; + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public boolean isIfExists() { + return ifExists; + } + + public void setIfExists(boolean ifExists) { + this.ifExists = ifExists; + } + + public String getSchema() { + SQLName name = getName(); + if (name == null) { + return null; + } + + if (name instanceof SQLPropertyExpr) { + return ((SQLPropertyExpr) name).getOwnernName(); + } + + return null; + } + + public boolean isPublic() { + return isPublic; + } + + public void setPublic(boolean aPublic) { + isPublic = aPublic; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTypeStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTypeStatement.java index 82f9d2ff4a..3db2413ed3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTypeStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTypeStatement.java @@ -15,6 +15,8 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLParameter; import com.alibaba.druid.sql.ast.statement.SQLCreateStatement; @@ -26,20 +28,37 @@ import java.util.ArrayList; import java.util.List; public class OracleCreateTypeStatement extends OracleStatementImpl implements SQLCreateStatement { - private boolean orReplace; - private SQLName name; - private boolean force; - private SQLName oid; - private boolean body; + private boolean orReplace; + private SQLName name; + private SQLName authId; + private boolean force; + private SQLName oid; + private boolean body; + private boolean object; + private boolean paren; + private Boolean isFinal; + private Boolean instantiable; + + private SQLName under; private List parameters = new ArrayList(); + private SQLDataType tableOf; + + private SQLExpr varraySizeLimit; + private SQLDataType varrayDataType; + @Override public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, name); + acceptChild(visitor, authId); acceptChild(visitor, oid); + acceptChild(visitor, under); acceptChild(visitor, parameters); + acceptChild(visitor, tableOf); + acceptChild(visitor, varraySizeLimit); + acceptChild(visitor, varrayDataType); } visitor.endVisit(this); } @@ -75,11 +94,22 @@ public class OracleCreateTypeStatement extends OracleStatementImpl implements SQ return oid; } - public void setOid(SQLName oid) { - if (oid != null) { - oid.setParent(this); + public void setOid(SQLName x) { + if (x != null) { + x.setParent(this); } - this.oid = oid; + this.oid = x; + } + + public SQLName getAuthId() { + return authId; + } + + public void setAuthId(SQLName x) { + if (x != null) { + x.setParent(this); + } + this.authId = x; } public List getParameters() { @@ -93,4 +123,80 @@ public class OracleCreateTypeStatement extends OracleStatementImpl implements SQ public void setBody(boolean body) { this.body = body; } + + public Boolean getFinal() { + return isFinal; + } + + public void setFinal(boolean aFinal) { + isFinal = aFinal; + } + + public Boolean getInstantiable() { + return instantiable; + } + + public void setInstantiable(boolean instantiable) { + this.instantiable = instantiable; + } + + public SQLDataType getTableOf() { + return tableOf; + } + + public void setTableOf(SQLDataType x) { + if (x != null) { + x.setParent(this); + } + this.tableOf = x; + } + + public SQLExpr getVarraySizeLimit() { + return varraySizeLimit; + } + + public void setVarraySizeLimit(SQLExpr x) { + if (x != null) { + x.setParent(this); + } + this.varraySizeLimit = x; + } + + public SQLDataType getVarrayDataType() { + return varrayDataType; + } + + public void setVarrayDataType(SQLDataType x) { + if (x != null) { + x.setParent(this); + } + this.varrayDataType = x; + } + + public SQLName getUnder() { + return under; + } + + public void setUnder(SQLName x) { + if (x != null) { + x.setParent(this); + } + this.under = x; + } + + public boolean isObject() { + return object; + } + + public void setObject(boolean object) { + this.object = object; + } + + public boolean isParen() { + return paren; + } + + public void setParen(boolean paren) { + this.paren = paren; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleProcedureDataType.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleProcedureDataType.java new file mode 100644 index 0000000000..9349a5e115 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleProcedureDataType.java @@ -0,0 +1,68 @@ +/* + * 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.oracle.parser; + +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDataTypeImpl; +import com.alibaba.druid.sql.ast.SQLParameter; +import com.alibaba.druid.sql.ast.SQLStatement; + +import java.util.ArrayList; +import java.util.List; + +public class OracleProcedureDataType extends SQLDataTypeImpl { + private boolean isStatic = false; + private final List parameters = new ArrayList(); + + private SQLStatement block; + + public boolean isStatic() { + return isStatic; + } + + public void setStatic(boolean aStatic) { + isStatic = aStatic; + } + + public List getParameters() { + return parameters; + } + + public OracleProcedureDataType clone() { + OracleProcedureDataType x = new OracleProcedureDataType(); + cloneTo(x); + + x.isStatic = isStatic; + for (SQLParameter parameter : parameters) { + SQLParameter p2 = parameter.clone(); + p2.setParent(x); + x.parameters.add(p2); + } + + return x; + } + + public SQLStatement getBlock() { + return block; + } + + public void setBlock(SQLStatement block) { + if (block != null) { + block.setParent(this); + } + this.block = block; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 4d92d93058..bb233ce44e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -512,6 +512,7 @@ public class OracleStatementParser extends SQLStatementParser { } if (lexer.token() == Token.DROP) { + Lexer.SavePoint savePoint = lexer.mark(); lexer.nextToken(); if (lexer.token() == Token.TABLE) { @@ -587,6 +588,15 @@ public class OracleStatementParser extends SQLStatementParser { continue; } + if (lexer.identifierEquals(FnvHash.Constants.SYNONYM)) { + lexer.reset(savePoint); + + SQLStatement stmt = parseDropSynonym(); + stmt.setParent(parent); + statementList.add(stmt); + continue; + } + throw new ParserException("TODO : " + lexer.info()); } @@ -679,6 +689,30 @@ public class OracleStatementParser extends SQLStatementParser { } } + public SQLStatement parseDropSynonym() { + if (lexer.token() == Token.DROP) { + lexer.nextToken(); + } + SQLDropSynonymStatement stmt = new SQLDropSynonymStatement(); + stmt.setDbType(dbType); + + if (lexer.identifierEquals(FnvHash.Constants.PUBLIC)) { + lexer.nextToken(); + stmt.setPublic(true); + } + + acceptIdentifier("SYNONYM"); + + stmt.setName(this.exprParser.name()); + + if (lexer.identifierEquals(FnvHash.Constants.FORCE)) { + lexer.nextToken(); + stmt.setForce(true); + } + + return stmt; + } + public SQLStatement parsePipeRow() { OraclePipeRowStatement stmt = new OraclePipeRowStatement(); acceptIdentifier("PIPE"); @@ -862,10 +896,10 @@ public class OracleStatementParser extends SQLStatementParser { stmt.setDeterministic(true); } - if (lexer.identifierEquals("AUTHID")) { + if (lexer.identifierEquals(FnvHash.Constants.AUTHID)) { lexer.nextToken(); String strVal = lexer.stringVal(); - if (lexer.identifierEquals("CURRENT_USER")) { + if (lexer.identifierEquals(FnvHash.Constants.CURRENT_USER)) { lexer.nextToken(); } else { acceptIdentifier("DEFINER"); @@ -1753,6 +1787,18 @@ public class OracleStatementParser extends SQLStatementParser { SQLParameter parameter = new SQLParameter(); parameter.setParent(parent); + if (parent instanceof OracleCreateTypeStatement) { + if (lexer.identifierEquals(FnvHash.Constants.MAP)) { + lexer.nextToken(); + parameter.setMap(true); + } else if (lexer.token() == Token.ORDER) { + lexer.nextToken(); + parameter.setOrder(true); + } + + // acceptIdentifier("MEMBER"); + } + SQLName name; SQLDataType dataType = null; if (lexer.token() == Token.CURSOR) { @@ -1777,7 +1823,7 @@ public class OracleStatementParser extends SQLStatementParser { || lexer.token() == Token.END || lexer.token() == Token.TABLE) { break; - } else if (lexer.identifierEquals("TYPE")) { + } else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) { lexer.nextToken(); name = this.exprParser.name(); accept(Token.IS); @@ -1832,7 +1878,12 @@ public class OracleStatementParser extends SQLStatementParser { throw new ParserException("TODO : " + lexer.info()); } } else { - name = this.exprParser.name(); + if (lexer.token() == Token.KEY) { + name = new SQLIdentifierExpr(lexer.stringVal()); + lexer.nextToken(); + } else { + name = this.exprParser.name(); + } if (lexer.token() == Token.IN) { lexer.nextToken(); @@ -1870,6 +1921,9 @@ public class OracleStatementParser extends SQLStatementParser { if ((name.nameHashCode64() == FnvHash.Constants.MEMBER || name.nameHashCode64() == FnvHash.Constants.STATIC) && lexer.token() == Token.FUNCTION) { + if (name.nameHashCode64() == FnvHash.Constants.MEMBER) { + parameter.setMember(true); + } OracleFunctionDataType functionDataType = new OracleFunctionDataType(); functionDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC); lexer.nextToken(); @@ -1890,6 +1944,31 @@ public class OracleStatementParser extends SQLStatementParser { SQLStatement block = this.parseBlock(); functionDataType.setBlock(block); } + } else if ((name.nameHashCode64() == FnvHash.Constants.MEMBER + || name.nameHashCode64() == FnvHash.Constants.STATIC) + && lexer.token() == Token.PROCEDURE) { + if (name.nameHashCode64() == FnvHash.Constants.MEMBER) { + parameter.setMember(true); + } + OracleProcedureDataType procedureDataType = new OracleProcedureDataType(); + procedureDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC); + lexer.nextToken(); + procedureDataType.setName(lexer.stringVal()); + accept(Token.IDENTIFIER); + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + this.parserParameters(procedureDataType.getParameters(), procedureDataType); + accept(Token.RPAREN); + } + + dataType = procedureDataType; + name = null; + + if (lexer.token() == Token.IS) { + lexer.nextToken(); + SQLStatement block = this.parseBlock(); + procedureDataType.setBlock(block); + } } else { dataType = this.exprParser.parseDataType(false); } @@ -2661,20 +2740,49 @@ public class OracleStatementParser extends SQLStatementParser { SQLName name = this.exprParser.name(); stmt.setName(name); + if (lexer.identifierEquals(FnvHash.Constants.UNDER)) { + lexer.nextToken(); + SQLName under = this.exprParser.name(); + stmt.setUnder(under); + } + + if (lexer.identifierEquals(FnvHash.Constants.AUTHID)) { + lexer.nextToken(); + SQLName authId = this.exprParser.name(); + stmt.setAuthId(authId); + } + if (lexer.token() == Token.AS || lexer.token() == Token.IS) { lexer.nextToken(); } if (lexer.identifierEquals("OBJECT")) { lexer.nextToken(); + stmt.setObject(true); } if (lexer.identifierEquals(FnvHash.Constants.STATIC)) { this.parserParameters(stmt.getParameters(), stmt); + } else if (lexer.token() == Token.TABLE) { + lexer.nextToken(); + accept(Token.OF); + SQLDataType dataType = this.exprParser.parseDataType(); + stmt.setTableOf(dataType); + } else if (lexer.identifierEquals(FnvHash.Constants.VARRAY)) { + lexer.nextToken(); + accept(Token.LPAREN); + SQLExpr sizeLimit = this.exprParser.primary(); + stmt.setVarraySizeLimit(sizeLimit); + accept(Token.RPAREN); + + accept(Token.OF); + SQLDataType dataType = this.exprParser.parseDataType(); + stmt.setVarrayDataType(dataType); } else { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); this.parserParameters(stmt.getParameters(), stmt); + stmt.setParen(true); accept(Token.RPAREN); } else { this.parserParameters(stmt.getParameters(), stmt); @@ -2684,6 +2792,27 @@ public class OracleStatementParser extends SQLStatementParser { } } + for (;;) { + if (lexer.token() == Token.NOT) { + lexer.nextToken(); + if (lexer.identifierEquals(FnvHash.Constants.FINAL)) { + lexer.nextToken(); + stmt.setFinal(false); + } else { + acceptIdentifier("INSTANTIABLE"); + stmt.setInstantiable(false); + } + } else if (lexer.identifierEquals(FnvHash.Constants.FINAL)) { + lexer.nextToken(); + stmt.setFinal(true); + } else if (lexer.identifierEquals(FnvHash.Constants.INSTANTIABLE)) { + lexer.nextToken(); + stmt.setInstantiable(true); + } else { + break; + } + } + if (lexer.token() == Token.SEMI) { lexer.nextToken(); stmt.setAfterSemi(true); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index 949603a9ec..5ac6091bfd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -55,6 +55,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement. import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.CheckOption; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.ReadOnly; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.util.JdbcConstants; @@ -1302,7 +1304,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } } if (!(x.getParent() instanceof SQLCreateProcedureStatement - || x.getParent() instanceof SQLCreateFunctionStatement) + || x.getParent() instanceof SQLCreateFunctionStatement + || x.getParent() instanceof OracleFunctionDataType + || x.getParent() instanceof OracleProcedureDataType) ) { print0(ucase ? "DECLARE" : "declare"); println(); @@ -3311,20 +3315,101 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print0(ucase ? "CREATE TYPE " : "create type "); } + if (x.isBody()) { + print0(ucase ? "BODY " : "body "); + } + x.getName().accept(this); + SQLName under = x.getUnder(); + if (under != null) { + print0(ucase ? " UNDER " : " under "); + under.accept(this); + } + + SQLName authId = x.getAuthId(); + if (authId != null) { + print0(ucase ? " AUTHID " : " authid "); + authId.accept(this); + } + if (x.isForce()) { print0(ucase ? "FORCE " : "force "); } - print0(" AS OBJECT ("); - indentCount++; - println(); - printlnAndAccept(x.getParameters(), ", "); + List parameters = x.getParameters(); + SQLDataType tableOf = x.getTableOf(); + + if (x.isObject()) { + print0(" AS OBJECT"); + } + + if (parameters.size() > 0) { + if (x.isParen()) { + print(" ("); + } else { + print0(ucase ? " IS" : " is"); + } + indentCount++; + println(); + + for (int i = 0; i < parameters.size(); ++i) { + SQLParameter param = parameters.get(i); + param.accept(this); + + SQLDataType dataType = param.getDataType(); + + if (i < parameters.size() - 1) { + if (dataType instanceof OracleFunctionDataType + && ((OracleFunctionDataType) dataType).getBlock() != null) { + // skip + println(); + } else if (dataType instanceof OracleProcedureDataType + && ((OracleProcedureDataType) dataType).getBlock() != null) { + // skip + println(); + } else { + println(", "); + } + } + } + + indentCount--; + println(); + + if (x.isParen()) { + print0(")"); + } else { + print0("END"); + } + } else if (tableOf != null) { + print0(ucase ? " AS TABLE OF " : " as table of "); + tableOf.accept(this); + } else if (x.getVarraySizeLimit() != null) { + print0(ucase ? " VARRAY (" : " varray ("); + x.getVarraySizeLimit().accept(this); + print0(ucase ? ") OF " : ") of "); + x.getVarrayDataType().accept(this); + } + + Boolean isFinal = x.getFinal(); + if (isFinal != null) { + if (isFinal.booleanValue()) { + print0(ucase ? " FINAL" : " final"); + } else { + print0(ucase ? " NOT FINAL" : " not final"); + } + } + + Boolean instantiable = x.getInstantiable(); + if (instantiable != null) { + if (instantiable.booleanValue()) { + print0(ucase ? " INSTANTIABLE" : " instantiable"); + } else { + print0(ucase ? " NOT INSTANTIABLE" : " not instantiable"); + } + } - indentCount--; - println(); - print0(")"); return false; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java index ba8b36e65c..69d368f488 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java @@ -23,6 +23,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; import com.alibaba.druid.sql.dialect.oracle.ast.clause.*; import com.alibaba.druid.sql.dialect.oracle.ast.expr.*; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.*; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; @@ -2000,20 +2002,101 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor print0(ucase ? "CREATE TYPE " : "create type "); } + if (x.isBody()) { + print0(ucase ? "BODY " : "body "); + } + x.getName().accept(this); + SQLName under = x.getUnder(); + if (under != null) { + print0(ucase ? " UNDER " : " under "); + under.accept(this); + } + + SQLName authId = x.getAuthId(); + if (authId != null) { + print0(ucase ? " AUTHID " : " authid "); + authId.accept(this); + } + if (x.isForce()) { print0(ucase ? "FORCE " : "force "); } - print0(" AS OBJECT ("); - indentCount++; - println(); - printlnAndAccept(x.getParameters(), ", "); + List parameters = x.getParameters(); + SQLDataType tableOf = x.getTableOf(); + + if (x.isObject()) { + print0(" AS OBJECT"); + } + + if (parameters.size() > 0) { + if (x.isParen()) { + print(" ("); + } else { + print0(ucase ? " IS" : " is"); + } + indentCount++; + println(); + + for (int i = 0; i < parameters.size(); ++i) { + SQLParameter param = parameters.get(i); + param.accept(this); + + SQLDataType dataType = param.getDataType(); + + if (i < parameters.size() - 1) { + if (dataType instanceof OracleFunctionDataType + && ((OracleFunctionDataType) dataType).getBlock() != null) { + // skip + println(); + } else if (dataType instanceof OracleProcedureDataType + && ((OracleProcedureDataType) dataType).getBlock() != null) { + // skip + println(); + } else { + println(", "); + } + } + } + + indentCount--; + println(); + + if (x.isParen()) { + print0(")"); + } else { + print0("END"); + } + } else if (tableOf != null) { + print0(ucase ? " AS TABLE OF " : " as table of "); + tableOf.accept(this); + } else if (x.getVarraySizeLimit() != null) { + print0(ucase ? " VARRAY (" : " varray ("); + x.getVarraySizeLimit().accept(this); + print0(ucase ? ") OF " : ") of "); + x.getVarrayDataType().accept(this); + } + + Boolean isFinal = x.getFinal(); + if (isFinal != null) { + if (isFinal.booleanValue()) { + print0(ucase ? " FINAL" : " final"); + } else { + print0(ucase ? " NOT FINAL" : " not final"); + } + } + + Boolean instantiable = x.getInstantiable(); + if (instantiable != null) { + if (instantiable.booleanValue()) { + print0(ucase ? " INSTANTIABLE" : " instantiable"); + } else { + print0(ucase ? " NOT INSTANTIABLE" : " not instantiable"); + } + } - indentCount--; - println(); - print0(")"); return false; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index d83f847596..ac2f1c5860 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -193,13 +193,13 @@ public class Keywords { } } - public Token getKeyword(long hash) { - int index = Arrays.binarySearch(hashArray, hash); - if (index < 0) { - return null; - } - return tokens[index]; +public Token getKeyword(long hash) { + int index = Arrays.binarySearch(hashArray, hash); + if (index < 0) { + return null; } + return tokens[index]; +} public Token getKeyword(String key) { long k = Utils.fnv_64_lower(key); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index fd1e88203c..eee19f2108 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -2031,6 +2031,11 @@ public class SQLStatementParser extends SQLParser { return parseCreateSynonym(); } + if (lexer.identifierEquals(FnvHash.Constants.SYNONYM)) { + lexer.reset(markBp, markChar, Token.CREATE); + return parseCreateSynonym(); + } + // lexer.reset(mark_bp, mark_ch, Token.CREATE); throw new ParserException("TODO " + lexer.info()); } else if (token == Token.DATABASE) { @@ -2469,14 +2474,14 @@ public class SQLStatementParser extends SQLParser { lexer.nextToken(); } - if (lexer.identifierEquals("DEFINER")) { + if (lexer.identifierEquals(FnvHash.Constants.DEFINER)) { lexer.nextToken(); accept(Token.EQ); SQLName definer = (SQLName) ((MySqlExprParser) this.exprParser).userName(); createView.setDefiner(definer); } - if (lexer.identifierEquals("SQL")) { + if (lexer.identifierEquals(FnvHash.Constants.SQL)) { lexer.nextToken(); acceptIdentifier("SECURITY"); String sqlSecurity = lexer.stringVal(); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 4188be8be2..15b0bafc9c 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -43,6 +43,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatemen import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; import oracle.sql.SQLUtil; @@ -3057,6 +3058,27 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } + @Override + public boolean visit(SQLDropSynonymStatement x) { + if (x.isPublic()) { + print0(ucase ? "DROP PUBLIC SYNONYM " : "drop public synonym "); + } else { + print0(ucase ? "DROP SYNONYM " : "drop synonym "); + } + + if (x.isIfExists()) { + print0(ucase ? "IF EXISTS " : "if exists "); + } + + x.getName().accept(this); + + if (x.isForce()) { + print0(ucase ? " FORCE" : " force"); + } + + return false; + } + @Override public boolean visit(SQLSavePointStatement x) { print0(ucase ? "SAVEPOINT" : "savepoint"); @@ -4445,6 +4467,35 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet SQLStatement block = x.getBlock(); if (block != null) { + println(); + print0(ucase ? "IS" : "is"); + println(); + block.accept(this); + } + + return false; + } + + public boolean visit(OracleProcedureDataType x) { + if (x.isStatic()) { + print0(ucase ? "STATIC " : "static "); + } + + print0(ucase ? "PROCEDURE " : "procedure "); + + print0(x.getName()); + + if (x.getParameters().size() > 0) { + print(" ("); + printAndAccept(x.getParameters(), ", "); + print(")"); + } + + SQLStatement block = x.getBlock(); + if (block != null) { + println(); + print0(ucase ? "IS" : "is"); + println(); block.accept(this); } @@ -4465,14 +4516,30 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet this.indentCount--; } else { + if (x.isMap()) { + print0(ucase ? "MAP MEMBER " : "map member "); + } else if (x.isOrder()) { + print0(ucase ? "ORDER MEMBER " : "order member "); + } else if (x.isMember()) { + print0(ucase ? "MEMBER " : "member "); + } SQLDataType dataType = x.getDataType(); - if (JdbcConstants.ORACLE.equals(dbType)) { + if (JdbcConstants.ORACLE.equals(dbType) + || dataType instanceof OracleFunctionDataType + || dataType instanceof OracleProcedureDataType) { if (dataType instanceof OracleFunctionDataType) { OracleFunctionDataType functionDataType = (OracleFunctionDataType) dataType; visit(functionDataType); return false; } + + if (dataType instanceof OracleProcedureDataType) { + OracleProcedureDataType procedureDataType = (OracleProcedureDataType) dataType; + visit(procedureDataType); + return false; + } + String dataTypeName = dataType.getName(); boolean printType = (dataTypeName.startsWith("TABLE OF") && x.getDefaultValue() == null) || dataTypeName.equalsIgnoreCase("REF CURSOR") diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index 63cb0db0c6..15f27b144c 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -790,4 +790,7 @@ public interface SQLASTVisitor { boolean visit(SQLDropServerStatement x); void endVisit(SQLDropServerStatement x); + + boolean visit(SQLDropSynonymStatement x); + void endVisit(SQLDropSynonymStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 71b7792f3f..cd86827c11 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -1836,6 +1836,16 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { } + @Override + public boolean visit(SQLDropSynonymStatement x) { + return true; + } + + @Override + public void endVisit(SQLDropSynonymStatement x) { + + } + public final boolean isEnabled(VisitorFeature feature) { return VisitorFeature.isEnabled(this.features, feature); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index a6fe34e132..7c19375536 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -2391,6 +2391,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLAlterFunctionStatement x) { return false; } + public boolean visit(SQLDropSynonymStatement x) { + return false; + } public boolean visit(SQLAlterTypeStatement x) { return false; diff --git a/src/main/java/com/alibaba/druid/util/FnvHash.java b/src/main/java/com/alibaba/druid/util/FnvHash.java index 9415beb9e1..c5afa8f93d 100644 --- a/src/main/java/com/alibaba/druid/util/FnvHash.java +++ b/src/main/java/com/alibaba/druid/util/FnvHash.java @@ -514,16 +514,23 @@ public final class FnvHash { long OWNER = fnv1a_64_lower("OWNER"); long PORT = fnv1a_64_lower("PORT"); long PUBLIC = fnv1a_64_lower("PUBLIC"); + long SYNONYM = fnv1a_64_lower("SYNONYM"); long MATERIALIZED = fnv1a_64_lower("MATERIALIZED"); long BITMAP = fnv1a_64_lower("BITMAP"); long PACKAGE = fnv1a_64_lower("PACKAGE"); long TRUNC = fnv1a_64_lower("TRUNC"); long SYSTIMESTAMP = fnv1a_64_lower("SYSTIMESTAMP"); long TYPE = fnv1a_64_lower("TYPE"); + long MAP = fnv1a_64_lower("MAP"); long ONLY = fnv1a_64_lower("ONLY"); long MEMBER = fnv1a_64_lower("MEMBER"); long STATIC = fnv1a_64_lower("STATIC"); + long FINAL = fnv1a_64_lower("FINAL"); + long INSTANTIABLE = fnv1a_64_lower("INSTANTIABLE"); long UNSUPPORTED = fnv1a_64_lower("UNSUPPORTED"); + long VARRAY = fnv1a_64_lower("VARRAY"); + long AUTHID = fnv1a_64_lower("AUTHID"); + long UNDER = fnv1a_64_lower("UNDER"); long USERENV = fnv1a_64_lower("USERENV"); long NUMTODSINTERVAL = fnv1a_64_lower("NUMTODSINTERVAL"); diff --git a/src/main/java/com/alibaba/druid/util/Utils.java b/src/main/java/com/alibaba/druid/util/Utils.java index fbc55f500d..a775daa7ab 100644 --- a/src/main/java/com/alibaba/druid/util/Utils.java +++ b/src/main/java/com/alibaba/druid/util/Utils.java @@ -237,59 +237,59 @@ public class Utils { * * @author Viliam Holub */ - public static long murmurhash2_64(final byte[] data, int length, int seed) { - final long m = 0xc6a4a7935bd1e995L; - final int r = 47; +public static long murmurhash2_64(final byte[] data, int length, int seed) { + final long m = 0xc6a4a7935bd1e995L; + final int r = 47; - long h = (seed & 0xffffffffl) ^ (length * m); + long h = (seed & 0xffffffffl) ^ (length * m); - int length8 = length / 8; + int length8 = length / 8; - for (int i = 0; i < length8; i++) { - final int i8 = i * 8; - long k = ((long) data[i8 + 0] & 0xff) // - + (((long) data[i8 + 1] & 0xff) << 8) // - + (((long) data[i8 + 2] & 0xff) << 16)// - + (((long) data[i8 + 3] & 0xff) << 24) // - + (((long) data[i8 + 4] & 0xff) << 32)// - + (((long) data[i8 + 5] & 0xff) << 40)// - + (((long) data[i8 + 6] & 0xff) << 48) // - + (((long) data[i8 + 7] & 0xff) << 56); + for (int i = 0; i < length8; i++) { + final int i8 = i * 8; + long k = ((long) data[i8 + 0] & 0xff) // + + (((long) data[i8 + 1] & 0xff) << 8) // + + (((long) data[i8 + 2] & 0xff) << 16)// + + (((long) data[i8 + 3] & 0xff) << 24) // + + (((long) data[i8 + 4] & 0xff) << 32)// + + (((long) data[i8 + 5] & 0xff) << 40)// + + (((long) data[i8 + 6] & 0xff) << 48) // + + (((long) data[i8 + 7] & 0xff) << 56); - k *= m; - k ^= k >>> r; - k *= m; + k *= m; + k ^= k >>> r; + k *= m; - h ^= k; - h *= m; - } - - switch (length % 8) { - case 7: - h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48; - case 6: - h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40; - case 5: - h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32; - case 4: - h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24; - case 3: - h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16; - case 2: - h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8; - case 1: - h ^= (long) (data[length & ~7] & 0xff); - h *= m; - } - ; - - h ^= h >>> r; + h ^= k; h *= m; - h ^= h >>> r; - - return h; } + switch (length % 8) { + case 7: + h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48; + case 6: + h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40; + case 5: + h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32; + case 4: + h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24; + case 3: + h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16; + case 2: + h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8; + case 1: + h ^= (long) (data[length & ~7] & 0xff); + h *= m; + } + ; + + h ^= h >>> r; + h *= m; + h ^= h >>> r; + + return h; +} + public static byte[] md5Bytes(String text) { MessageDigest msgDigest = null; diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue2049.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue2049.java new file mode 100644 index 0000000000..6bd547447c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue2049.java @@ -0,0 +1,32 @@ +package com.alibaba.druid.bvt.bug; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.spi.OracleWallProvider; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 12/07/2017. + */ +public class Issue2049 extends TestCase { + public void test_0() throws Exception { + String sql = "select * from emp a,dmp b;"; + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); + + SQLSelectStatement stmt = (SQLSelectStatement) stmtList.get(0); + SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock(); + SQLJoinTableSource joinTableSource = (SQLJoinTableSource) queryBlock.getFrom(); + + assertEquals("a", joinTableSource.getLeft().getAlias()); + assertEquals("b", joinTableSource.getRight().getAlias()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_0.java new file mode 100644 index 0000000000..e95c6d17c5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_0.java @@ -0,0 +1,62 @@ +/* + * 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.bvt.sql.oracle.create; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateSynonymTest_0 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE PUBLIC SYNONYM emp_table \n" + + " FOR hr.employees@remote.us.oracle.com;"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ORACLE); + stmt.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()); + + assertEquals("CREATE PUBLIC SYNONYM emp_table FOR hr.employees@remote.us.oracle.com;" + , SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + assertEquals(0, visitor.getTables().size()); + +// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t1"))); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("xwarehouses", "sales_rep_id"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_1.java new file mode 100644 index 0000000000..2f8375496f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_1.java @@ -0,0 +1,61 @@ +/* + * 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.bvt.sql.oracle.create; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateSynonymTest_1 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE SYNONYM offices \n" + + " FOR hr.locations;"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ORACLE); + stmt.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()); + + assertEquals("CREATE SYNONYM offices FOR hr.locations;" + , SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + assertEquals(0, visitor.getTables().size()); + +// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t1"))); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("xwarehouses", "sales_rep_id"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_2.java new file mode 100644 index 0000000000..4e48bf4f81 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateSynonymTest_2.java @@ -0,0 +1,60 @@ +/* + * 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.bvt.sql.oracle.create; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateSynonymTest_2 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE OR REPLACE SYNONYM CSCLIENT.ECC_CUST_AREA_INFO FOR ECC_CUST.ECC_CUST_AREA_INFO"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ORACLE); + stmt.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()); + + assertEquals("CREATE OR REPLACE SYNONYM CSCLIENT.ECC_CUST_AREA_INFO FOR ECC_CUST.ECC_CUST_AREA_INFO" + , SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + assertEquals(0, visitor.getTables().size()); + +// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t1"))); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("xwarehouses", "sales_rep_id"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest1.java index a4f9acd001..b3d3f33836 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest1.java @@ -58,23 +58,27 @@ public class OracleCreateTypeTest1 extends OracleTest { { String text = SQLUtils.toOracleString(stmt); - assertEquals("CREATE OR REPLACE TYPE \"STRCAT_TYPE\" AS OBJECT (\n" + - "\tSTATIC FUNCTION ODCIAggregateInitialize (cs_ctx IN OUT strcat_type) RETURN numberBEGIN\n" + + assertEquals("CREATE OR REPLACE TYPE BODY \"STRCAT_TYPE\" IS\n" + + "\tSTATIC FUNCTION ODCIAggregateInitialize (cs_ctx IN OUT strcat_type) RETURN number\n" + + "\tIS\n" + + "\tBEGIN\n" + "\t\tcs_ctx := strcat_type(NULL);\n" + "\t\tRETURN ODCIConst.Success;\n" + "\tEND;\n" + - ")", text); + "END", text); } { String text = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); - assertEquals("create or replace type \"STRCAT_TYPE\" AS OBJECT (\n" + - "\tstatic function ODCIAggregateInitialize (cs_ctx in out strcat_type) return numberbegin\n" + + assertEquals("create or replace type body \"STRCAT_TYPE\" is\n" + + "\tstatic function ODCIAggregateInitialize (cs_ctx in out strcat_type) return number\n" + + "\tis\n" + + "\tbegin\n" + "\t\tcs_ctx := strcat_type(null);\n" + "\t\treturn ODCIConst.Success;\n" + "\tend;\n" + - ")", text); + "END", text); } // assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest10.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest10.java new file mode 100644 index 0000000000..6a4b73ee90 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest10.java @@ -0,0 +1,127 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest10 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE type body connstrBycomma is\n" + + " static function ODCIAggregateInitialize(sctx IN OUT connstrBycomma)\t\n" + + " return number is\n" + + " begin\n" + + " sctx := connstrBycomma('',',');\n" + + " return ODCIConst.Success;\n" + + " end;\n" + + " member function ODCIAggregateIterate(self IN OUT connstrBycomma, value IN VARCHAR2) return number is\n" + + " begin\n" + + " if self.currentstr is null then\n" + + " self.currentstr := value;\n" + + " else\n" + + " self.currentstr := self.currentstr ||currentseprator || value;\n" + + " end if;\n" + + " return ODCIConst.Success;\n" + + " end;\n" + + " member function ODCIAggregateTerminate(self IN connstrBycomma, returnValue OUT VARCHAR2, flags IN number) return number is\n" + + " begin\n" + + " returnValue := self.currentstr;\n" + + " return ODCIConst.Success;\n" + + " end;\n" + + " member function ODCIAggregateMerge(self IN OUT connstrBycomma, ctx2 IN connstrBycomma) return number is\n" + + " begin\n" + + " if ctx2.currentstr is null then\n" + + " self.currentstr := self.currentstr;\n" + + " elsif self.currentstr is null then\n" + + " self.currentstr := ctx2.currentstr;\n" + + " else\n" + + " self.currentstr := self.currentstr || currentseprator || ctx2.currentstr;\n" + + " end if;\n" + + " return ODCIConst.Success;\n" + + " end;\n" + + " end;"; + + System.out.println(sql); + + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE BODY connstrBycomma IS\n" + + "\tSTATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT connstrBycomma) RETURN number\n" + + "\tIS\n" + + "\tBEGIN\n" + + "\t\tsctx := connstrBycomma(NULL, ',');\n" + + "\t\tRETURN ODCIConst.Success;\n" + + "\tEND;\n" + + "\tMEMBER FUNCTION ODCIAggregateIterate (self IN OUT connstrBycomma, value IN VARCHAR2) RETURN number\n" + + "\tIS\n" + + "\tBEGIN\n" + + "\t\tIF self.currentstr IS NULL THEN\n" + + "\t\t\tself.currentstr := value;\n" + + "\t\tELSE\n" + + "\t\t\tself.currentstr := self.currentstr || currentseprator || value;\n" + + "\t\tEND IF;\n" + + "\t\tRETURN ODCIConst.Success;\n" + + "\tEND;\n" + + "\tMEMBER FUNCTION ODCIAggregateTerminate (self IN connstrBycomma, returnValue OUT VARCHAR2, flags IN number) RETURN number\n" + + "\tIS\n" + + "\tBEGIN\n" + + "\t\treturnValue := self.currentstr;\n" + + "\t\tRETURN ODCIConst.Success;\n" + + "\tEND;\n" + + "\tMEMBER FUNCTION ODCIAggregateMerge (self IN OUT connstrBycomma, ctx2 IN connstrBycomma) RETURN number\n" + + "\tIS\n" + + "\tBEGIN\n" + + "\t\tIF ctx2.currentstr IS NULL THEN\n" + + "\t\t\tself.currentstr := self.currentstr;\n" + + "\t\tELSE IF self.currentstr IS NULL THEN\n" + + "\t\t\tself.currentstr := ctx2.currentstr;\n" + + "\t\tELSE\n" + + "\t\t\tself.currentstr := self.currentstr || currentseprator || ctx2.currentstr;\n" + + "\t\tEND IF;\n" + + "\t\tRETURN ODCIConst.Success;\n" + + "\tEND;\n" + + "END",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest11.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest11.java new file mode 100644 index 0000000000..c23380ddd0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest11.java @@ -0,0 +1,105 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest11 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE TYPE BODY rational\n" + + " IS\n" + + " MAP MEMBER FUNCTION rat_to_real RETURN REAL IS\n" + + " BEGIN\n" + + " RETURN numerator/denominator;\n" + + " END;\n" + + "\n" + + " MEMBER PROCEDURE normalize IS\n" + + " gcd NUMBER := integer_operations.greatest_common_divisor\n" + + " (numerator, denominator);\n" + + " BEGIN\n" + + " numerator := numerator/gcd;\n" + + " denominator := denominator/gcd;\n" + + " END;\n" + + "\n" + + " MEMBER FUNCTION plus(x rational) RETURN rational IS\n" + + " r rational := rational_operations.make_rational\n" + + " (numerator*x.denominator +\n" + + " x.numerator*denominator,\n" + + " denominator*x.denominator);\n" + + " BEGIN\n" + + " RETURN r;\n" + + " END;\n" + + "\n" + + " END;"; + + System.out.println(sql); + + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE TYPE BODY rational IS\n" + + "\tMAP MEMBER FUNCTION rat_to_real () RETURN REAL\n" + + "\tIS\n" + + "\tBEGIN\n" + + "\t\tRETURN numerator / denominator;\n" + + "\tEND;\n" + + "\tMEMBER PROCEDURE normalize\n" + + "\tIS\n" + + "\tgcd NUMBER := integer_operations.greatest_common_divisor(numerator, denominator);\n" + + "\tBEGIN\n" + + "\t\tnumerator := numerator / gcd;\n" + + "\t\tdenominator := denominator / gcd;\n" + + "\tEND;\n" + + "\tMEMBER FUNCTION plus (x rational) RETURN rational\n" + + "\tIS\n" + + "\tr rational := rational_operations.make_rational(numerator * x.denominator + x.numerator * denominator, denominator * x.denominator);\n" + + "\tBEGIN\n" + + "\t\tRETURN r;\n" + + "\tEND;\n" + + "END;",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + + SQLUtils.toPGString(stmt); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest3.java index 87cddc1087..3d0fe3e51c 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest3.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest3.java @@ -57,7 +57,7 @@ public class OracleCreateTypeTest3 extends OracleTest { assertEquals("CREATE TYPE data_typ1 AS OBJECT (\n" + "\tyear NUMBER, \n" + - "\tFUNCTION prod (invent NUMBER) RETURN NUMBER\n" + + "\tMEMBER FUNCTION prod (invent NUMBER) RETURN NUMBER\n" + ");", text); } @@ -66,7 +66,7 @@ public class OracleCreateTypeTest3 extends OracleTest { assertEquals("create type data_typ1 AS OBJECT (\n" + "\tyear NUMBER, \n" + - "\tfunction prod (invent NUMBER) return NUMBER\n" + + "\tmember function prod (invent NUMBER) return NUMBER\n" + ");", text); } // assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); diff --git a/src/test/java/com/alibaba/druid/not_support/sql/oracle/OracleCreateTypeTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest4.java similarity index 83% rename from src/test/java/com/alibaba/druid/not_support/sql/oracle/OracleCreateTypeTest4.java rename to src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest4.java index b377a74fd9..7d24433ea6 100644 --- a/src/test/java/com/alibaba/druid/not_support/sql/oracle/OracleCreateTypeTest4.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest4.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.druid.not_support.sql.oracle; +package com.alibaba.druid.bvt.sql.oracle.create; import com.alibaba.druid.sql.OracleTest; import com.alibaba.druid.sql.SQLUtils; @@ -53,19 +53,13 @@ public class OracleCreateTypeTest4 extends OracleTest { { String text = SQLUtils.toOracleString(stmt); - assertEquals("CREATE TYPE data_typ1 AS OBJECT (\n" + - "\tyear NUMBER, \n" + - "\tFUNCTION prod (invent NUMBER) RETURN NUMBER\n" + - ");", text); + assertEquals("CREATE OR REPLACE TYPE cms_contract_config_obj_TABLE AS TABLE OF ECC_CPR.cms_contract_config_obj", text); } { String text = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); - assertEquals("create type data_typ1 AS OBJECT (\n" + - "\tyear NUMBER, \n" + - "\tfunction prod (invent NUMBER) return NUMBER\n" + - ");", text); + assertEquals("create or replace type cms_contract_config_obj_TABLE as table of ECC_CPR.cms_contract_config_obj", text); } // assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest5.java new file mode 100644 index 0000000000..d409bb0e7f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest5.java @@ -0,0 +1,76 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest5 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE TYPE T_PMINFO_LOAN_OBJECT \n" + + "is object(\n" + + " prj_id number(10), --椤圭洰 Id\n" + + " prj_code varchar2(200), --椤圭洰 缂栧彿\n" + + " prj_name varchar2(200), --椤圭洰 鍚嶇О\n" + + " forecast_our_money number, --棰勮\uE178鎴戝徃閲戦\uE582\n" + + " cust_id number(10), --瀹㈡埛 Id\n" + + " cust_name varchar2(256), --瀹㈡埛 鍚嶇О\n" + + " carriert_type varchar2(20), --杩愯惀鍟嗙被鍨�\n" + + " dept_id number(10) --閮ㄩ棬\n" + + ") not final instantiable;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE T_PMINFO_LOAN_OBJECT AS OBJECT (\n" + + "\tprj_id number(10), \n" + + "\tprj_code varchar2(200), \n" + + "\tprj_name varchar2(200), \n" + + "\tforecast_our_money number, \n" + + "\tcust_id number(10), \n" + + "\tcust_name varchar2(256), \n" + + "\tcarriert_type varchar2(20), \n" + + "\tdept_id number(10)\n" + + ") NOT FINAL INSTANTIABLE;",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest6.java new file mode 100644 index 0000000000..d59d0cc720 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest6.java @@ -0,0 +1,58 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest6 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE TYPE \"VARRAY_DEPT_TYPE\"\n" + + " AS varray(7000) OF NUMBER(10) "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE \"VARRAY_DEPT_TYPE\" VARRAY (7000) OF NUMBER(10)",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest7.java new file mode 100644 index 0000000000..6ad7b42321 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest7.java @@ -0,0 +1,63 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest7 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE TYPE histogram_entry_type AUTHID CURRENT_USER AS OBJECT\n" + + " (count NUMBER\n" + + " ,value NUMBER(5)\n" + + " )"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE histogram_entry_type AUTHID CURRENT_USER AS OBJECT (\n" + + "\tcount NUMBER, \n" + + "\tvalue NUMBER(5)\n" + + ")",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest8.java new file mode 100644 index 0000000000..b6619c6995 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest8.java @@ -0,0 +1,164 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest8 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE TYPE dmbanimp AUTHID CURRENT_USER AS OBJECT (\n" + + " key RAW(4),\n" + + " shared_ctx RAW(8),\n" + + " STATIC FUNCTION ODCITablePrepare (\n" + + " sctx IN OUT dmbanimp,\n" + + " tf_info SYS.ODCITabFuncInfo,\n" + + " qkn_ptr IN RAW,\n" + + " heap_ptr IN RAW,\n" + + " query_sequence IN CLOB,\n" + + " seqdb_cursor SYS_REFCURSOR,\n" + + " subsequence_from IN PLS_INTEGER DEFAULT 1,\n" + + " subsequence_to IN PLS_INTEGER DEFAULT -1,\n" + + " filter_low_complexity IN PLS_INTEGER DEFAULT 0,\n" + + " mask_lower_case IN PLS_INTEGER DEFAULT 0,\n" + + " expect_value IN NUMBER DEFAULT 10,\n" + + " open_gap_cost IN PLS_INTEGER DEFAULT 5,\n" + + " extend_gap_cost IN PLS_INTEGER DEFAULT 2,\n" + + " mismatch_cost IN PLS_INTEGER DEFAULT -3,\n" + + " match_reward IN PLS_INTEGER DEFAULT 1,\n" + + " word_size IN PLS_INTEGER DEFAULT 11,\n" + + " xdropoff IN PLS_INTEGER DEFAULT 30,\n" + + " final_x_dropoff IN PLS_INTEGER DEFAULT 50\n" + + " ) RETURN PLS_INTEGER,\n" + + " STATIC FUNCTION ODCITableStart (\n" + + " sctx IN OUT dmbanimp,\n" + + " rws_ptr IN RAW,\n" + + " query_sequence IN CLOB,\n" + + " seqdb_cursor SYS_REFCURSOR,\n" + + " subsequence_from IN PLS_INTEGER DEFAULT 1,\n" + + " subsequence_to IN PLS_INTEGER DEFAULT -1,\n" + + " filter_low_complexity IN PLS_INTEGER DEFAULT 0,\n" + + " mask_lower_case IN PLS_INTEGER DEFAULT 0,\n" + + " expect_value IN NUMBER DEFAULT 10,\n" + + " open_gap_cost IN PLS_INTEGER DEFAULT 5,\n" + + " extend_gap_cost IN PLS_INTEGER DEFAULT 2,\n" + + " mismatch_cost IN PLS_INTEGER DEFAULT -3,\n" + + " match_reward IN PLS_INTEGER DEFAULT 1,\n" + + " word_size IN PLS_INTEGER DEFAULT 11,\n" + + " xdropoff IN PLS_INTEGER DEFAULT 30,\n" + + " final_x_dropoff IN PLS_INTEGER DEFAULT 50\n" + + " ) RETURN NUMBER,\n" + + " MEMBER FUNCTION ODCITableFetch (\n" + + " self IN OUT dmbanimp,\n" + + " nrows IN NUMBER,\n" + + " outset OUT dmbaos\n" + + " ) RETURN NUMBER,\n" + + " MEMBER FUNCTION ODCITableClose (\n" + + " self IN dmbanimp\n" + + " ) RETURN NUMBER,\n" + + " STATIC FUNCTION dmbanPrepareStub (\n" + + " sctx IN OUT dmbanimp,\n" + + " tf_info SYS.ODCITabFuncInfo,\n" + + " qkn_ptr IN RAW,\n" + + " heap_ptr IN RAW,\n" + + " query_sequence IN CLOB,\n" + + " seqdb_cursor SYS_REFCURSOR,\n" + + " subsequence_from IN PLS_INTEGER,\n" + + " subsequence_to IN PLS_INTEGER,\n" + + " filter_low_complexity IN PLS_INTEGER,\n" + + " mask_lower_case IN PLS_INTEGER,\n" + + " expect_value IN NUMBER,\n" + + " open_gap_cost IN PLS_INTEGER,\n" + + " extend_gap_cost IN PLS_INTEGER,\n" + + " mismatch_cost IN PLS_INTEGER,\n" + + " match_reward IN PLS_INTEGER,\n" + + " word_size IN PLS_INTEGER,\n" + + " xdropoff IN PLS_INTEGER,\n" + + " final_x_dropoff IN PLS_INTEGER\n" + + " ) RETURN PLS_INTEGER,\n" + + " STATIC FUNCTION dmbanStartStub (\n" + + " sctx IN OUT dmbanimp,\n" + + " rws_ptr IN RAW,\n" + + " query_sequence IN CLOB,\n" + + " seqdb_cursor SYS_REFCURSOR,\n" + + " subsequence_from IN PLS_INTEGER,\n" + + " subsequence_to IN PLS_INTEGER,\n" + + " filter_low_complexity IN PLS_INTEGER,\n" + + " mask_lower_case IN PLS_INTEGER,\n" + + " expect_value IN NUMBER,\n" + + " open_gap_cost IN PLS_INTEGER,\n" + + " extend_gap_cost IN PLS_INTEGER,\n" + + " mismatch_cost IN PLS_INTEGER,\n" + + " match_reward IN PLS_INTEGER,\n" + + " word_size IN PLS_INTEGER,\n" + + " xdropoff IN PLS_INTEGER,\n" + + " final_x_dropoff IN PLS_INTEGER\n" + + " ) RETURN NUMBER,\n" + + " MEMBER FUNCTION dmbanFetchStub (\n" + + " self IN OUT dmbanimp,\n" + + " nrows IN NUMBER,\n" + + " outset OUT dmbaos\n" + + " ) RETURN NUMBER,\n" + + " MEMBER FUNCTION dmbanCloseStub (\n" + + " self IN dmbanimp\n" + + " ) RETURN NUMBER\n" + + ");"; + + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE dmbanimp AUTHID CURRENT_USER AS OBJECT (\n" + + "\tkey RAW(4), \n" + + "\tshared_ctx RAW(8), \n" + + "\tSTATIC FUNCTION ODCITablePrepare (sctx IN OUT dmbanimp, tf_info SYS.ODCITabFuncInfo, qkn_ptr IN RAW, heap_ptr IN RAW, query_sequence IN CLOB, seqdb_cursor SYS_REFCURSOR, subsequence_from IN PLS_INTEGER := 1, subsequence_to IN PLS_INTEGER := -1, filter_low_complexity IN PLS_INTEGER := 0, mask_lower_case IN PLS_INTEGER := 0, expect_value IN NUMBER := 10, open_gap_cost IN PLS_INTEGER := 5, extend_gap_cost IN PLS_INTEGER := 2, mismatch_cost IN PLS_INTEGER := -3, match_reward IN PLS_INTEGER := 1, word_size IN PLS_INTEGER := 11, xdropoff IN PLS_INTEGER := 30, final_x_dropoff IN PLS_INTEGER := 50) RETURN PLS_INTEGER, \n" + + "\tSTATIC FUNCTION ODCITableStart (sctx IN OUT dmbanimp, rws_ptr IN RAW, query_sequence IN CLOB, seqdb_cursor SYS_REFCURSOR, subsequence_from IN PLS_INTEGER := 1, subsequence_to IN PLS_INTEGER := -1, filter_low_complexity IN PLS_INTEGER := 0, mask_lower_case IN PLS_INTEGER := 0, expect_value IN NUMBER := 10, open_gap_cost IN PLS_INTEGER := 5, extend_gap_cost IN PLS_INTEGER := 2, mismatch_cost IN PLS_INTEGER := -3, match_reward IN PLS_INTEGER := 1, word_size IN PLS_INTEGER := 11, xdropoff IN PLS_INTEGER := 30, final_x_dropoff IN PLS_INTEGER := 50) RETURN NUMBER, \n" + + "\tMEMBER FUNCTION ODCITableFetch (self IN OUT dmbanimp, nrows IN NUMBER, outset OUT dmbaos) RETURN NUMBER, \n" + + "\tMEMBER FUNCTION ODCITableClose (self IN dmbanimp) RETURN NUMBER, \n" + + "\tSTATIC FUNCTION dmbanPrepareStub (sctx IN OUT dmbanimp, tf_info SYS.ODCITabFuncInfo, qkn_ptr IN RAW, heap_ptr IN RAW, query_sequence IN CLOB, seqdb_cursor SYS_REFCURSOR, subsequence_from IN PLS_INTEGER, subsequence_to IN PLS_INTEGER, filter_low_complexity IN PLS_INTEGER, mask_lower_case IN PLS_INTEGER, expect_value IN NUMBER, open_gap_cost IN PLS_INTEGER, extend_gap_cost IN PLS_INTEGER, mismatch_cost IN PLS_INTEGER, match_reward IN PLS_INTEGER, word_size IN PLS_INTEGER, xdropoff IN PLS_INTEGER, final_x_dropoff IN PLS_INTEGER) RETURN PLS_INTEGER, \n" + + "\tSTATIC FUNCTION dmbanStartStub (sctx IN OUT dmbanimp, rws_ptr IN RAW, query_sequence IN CLOB, seqdb_cursor SYS_REFCURSOR, subsequence_from IN PLS_INTEGER, subsequence_to IN PLS_INTEGER, filter_low_complexity IN PLS_INTEGER, mask_lower_case IN PLS_INTEGER, expect_value IN NUMBER, open_gap_cost IN PLS_INTEGER, extend_gap_cost IN PLS_INTEGER, mismatch_cost IN PLS_INTEGER, match_reward IN PLS_INTEGER, word_size IN PLS_INTEGER, xdropoff IN PLS_INTEGER, final_x_dropoff IN PLS_INTEGER) RETURN NUMBER, \n" + + "\tMEMBER FUNCTION dmbanFetchStub (self IN OUT dmbanimp, nrows IN NUMBER, outset OUT dmbaos) RETURN NUMBER, \n" + + "\tMEMBER FUNCTION dmbanCloseStub (self IN dmbanimp) RETURN NUMBER\n" + + ");",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest9.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest9.java new file mode 100644 index 0000000000..0766159421 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTypeTest9.java @@ -0,0 +1,81 @@ +/* + * 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.bvt.sql.oracle.create; + +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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTypeTest9 extends OracleTest { + + public void test_types() throws Exception { + String sql = "CREATE OR REPLACE TYPE \"T_EVA_PM_INFO_OBJECT\" \n" + + "under ecc_pm.t_pminfo_loan_object(\n" + + " marster_dept_id number,\n" + + " marster_dept_name varchar2(500), --鎵�灞炲姙浜嬪\uE629\n" + + " area_id number,\n" + + " area_name varchar2(500), --鎵�灞炲浗瀹舵垨鍦板尯\n" + + " cust2_id2 number(10), --鏈�缁堝\uE179鎴� Id\n" + + " cust2_name2 varchar2(256), --鏈�缁堝\uE179鎴� 鍚嶇О\n" + + " finalUsage2 varchar2(256), --鏈�缁堢敤閫�\n" + + " sanctionedParty12 varchar2(256), --椤圭洰瀹㈡埛鍙楀埗瑁佷富浣�\n" + + " sanctionedParty22 varchar2(256) --鏈�缁堝\uE179鎴峰彈鍒惰\uE5C6涓讳綋\n" + + " );"; + + System.out.println(sql); + + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("CREATE OR REPLACE TYPE \"T_EVA_PM_INFO_OBJECT\" UNDER ecc_pm.t_pminfo_loan_object (\n" + + "\tmarster_dept_id number, \n" + + "\tmarster_dept_name varchar2(500), \n" + + "\tarea_id number, \n" + + "\tarea_name varchar2(500), \n" + + "\tcust2_id2 number(10), \n" + + "\tcust2_name2 varchar2(256), \n" + + "\tfinalUsage2 varchar2(256), \n" + + "\tsanctionedParty12 varchar2(256), \n" + + "\tsanctionedParty22 varchar2(256)\n" + + ");",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.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()); + + assertEquals(0, visitor.getTables().size()); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleDropSynonymTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleDropSynonymTest_0.java new file mode 100644 index 0000000000..a6e389d419 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleDropSynonymTest_0.java @@ -0,0 +1,60 @@ +/* + * 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.bvt.sql.oracle.create; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleDropSynonymTest_0 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "DROP PUBLIC SYNONYM customers;"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ORACLE); + stmt.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()); + + assertEquals("DROP PUBLIC SYNONYM customers;" + , SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + assertEquals(0, visitor.getTables().size()); + +// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t1"))); + + assertEquals(0, visitor.getColumns().size()); + +// assertTrue(visitor.getColumns().contains(new TableStat.Column("xwarehouses", "sales_rep_id"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +}