From 32a43cc549984d163c77e686cecc0f58b7465031 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 3 Aug 2013 20:52:07 +0800 Subject: [PATCH] improve sql parser --- .../sql/ast/statement/SQLConstaintImpl.java | 9 ++ .../mysql/parser/MySqlCreateTableParser.java | 6 +- .../dialect/oracle/ast/stmt/OracleCheck.java | 87 +++++++++++++++++++ .../oracle/ast/stmt/OracleConstraint.java | 16 ++++ .../oracle/ast/stmt/OracleForeignKey.java | 29 ++++--- .../oracle/ast/stmt/OraclePrimaryKey.java | 18 ++++ .../dialect/oracle/ast/stmt/OracleUnique.java | 19 ++-- .../oracle/parser/OracleExprParser.java | 38 +++++++- .../dialect/oracle/parser/OracleLexer.java | 1 + .../oracle/visitor/OracleASTVisitor.java | 5 ++ .../visitor/OracleASTVisitorAdapter.java | 11 +++ .../oracle/visitor/OracleOutputVisitor.java | 57 +++++++----- .../visitor/OracleSchemaStatVisitor.java | 12 +++ .../sql/parser/SQLCreateTableParser.java | 1 + .../druid/sql/parser/SQLExprParser.java | 56 +++++++++++- .../alibaba/druid/sql/parser/SQLParser.java | 5 ++ .../com/alibaba/druid/sql/parser/Token.java | 1 + .../sql/visitor/SQLASTOutputVisitor.java | 43 +++++++-- .../sql/visitor/SQLASTVisitorAdapter.java | 6 +- .../sql/oracle/OracleAlterTableTest19.java | 2 +- .../sql/oracle/OracleCreateTableTest22.java | 2 +- .../sql/oracle/OracleCreateTableTest23.java | 3 +- .../sql/oracle/OracleCreateTableTest24.java | 3 +- .../sql/oracle/OracleCreateTableTest28.java | 78 +++++++++++++++++ .../sql/oracle/OracleCreateTableTest29.java | 78 +++++++++++++++++ .../sql/oracle/OracleCreateTableTest30.java | 84 ++++++++++++++++++ .../sql/oracle/OracleCreateTableTest31.java | 68 +++++++++++++++ .../sql/oracle/OracleCreateTableTest32.java | 64 ++++++++++++++ .../sql/oracle/OracleCreateTableTest33.java | 66 ++++++++++++++ 29 files changed, 811 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCheck.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest28.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest29.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest30.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest31.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest32.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest33.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLConstaintImpl.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLConstaintImpl.java index 8101565ea4..2fa9566599 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLConstaintImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLConstaintImpl.java @@ -21,6 +21,7 @@ import com.alibaba.druid.sql.ast.SQLObjectImpl; public abstract class SQLConstaintImpl extends SQLObjectImpl implements SQLConstaint { private SQLName name; + private Boolean enable; public SQLConstaintImpl(){ @@ -34,4 +35,12 @@ public abstract class SQLConstaintImpl extends SQLObjectImpl implements SQLConst this.name = name; } + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index b86f285973..7338d30e64 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -140,11 +140,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { fk.setParent(stmt); stmt.getTableElementList().add(fk); } else if (lexer.token() == Token.CHECK) { - lexer.nextToken(); - SQLCheck check = new SQLCheck(); - accept(Token.LPAREN); - check.setExpr(this.exprParser.expr()); - accept(Token.RPAREN); + SQLCheck check = this.exprParser.parseCheck(); stmt.getTableElementList().add(check); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCheck.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCheck.java new file mode 100644 index 0000000000..1187dbc445 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCheck.java @@ -0,0 +1,87 @@ +/* + * 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.ast.statement.SQLCheck; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class OracleCheck extends SQLCheck implements OracleConstraint, OracleSQLObject { + + private OracleUsingIndexClause using; + private SQLName exceptionsInto; + private Initially initially; + private Boolean deferrable; + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof OracleASTVisitor) { + accept0((OracleASTVisitor) visitor); + return; + } + + super.accept(visitor); + } + + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, this.getName()); + acceptChild(visitor, this.getExpr()); + + acceptChild(visitor, using); + acceptChild(visitor, exceptionsInto); + } + visitor.endVisit(this); + } + + public Boolean getDeferrable() { + return deferrable; + } + + public void setDeferrable(Boolean deferrable) { + this.deferrable = deferrable; + } + + public Initially getInitially() { + return initially; + } + + public void setInitially(Initially initially) { + this.initially = initially; + } + + public SQLName getExceptionsInto() { + return exceptionsInto; + } + + public void setExceptionsInto(SQLName exceptionsInto) { + this.exceptionsInto = exceptionsInto; + } + + public OracleUsingIndexClause getUsing() { + return using; + } + + public void setUsing(OracleUsingIndexClause using) { + if (using != null) { + using.setParent(this); + } + this.using = using; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleConstraint.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleConstraint.java index ec75d3a896..129d73818a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleConstraint.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleConstraint.java @@ -26,7 +26,23 @@ public interface OracleConstraint extends OracleSQLObject, SQLConstaint, SQLTabl void setExceptionsInto(SQLName exceptionsInto); + Boolean getDeferrable(); + + void setDeferrable(Boolean enable); + Boolean getEnable(); void setEnable(Boolean enable); + + Initially getInitially(); + + void setInitially(Initially value); + + OracleUsingIndexClause getUsing(); + + void setUsing(OracleUsingIndexClause using); + + public static enum Initially { + DEFERRED, IMMEDIATE + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleForeignKey.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleForeignKey.java index ffbc1572df..f3add1a8a0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleForeignKey.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleForeignKey.java @@ -25,7 +25,8 @@ public class OracleForeignKey extends SQLForeignKeyImpl implements OracleConstra private OracleUsingIndexClause using; private SQLName exceptionsInto; - private Boolean enable; + private Initially initially; + private Boolean deferrable; @Override protected void accept0(SQLASTVisitor visitor) { @@ -43,13 +44,29 @@ public class OracleForeignKey extends SQLForeignKeyImpl implements OracleConstra acceptChild(visitor, this.getReferencedTableName()); acceptChild(visitor, this.getReferencingColumns()); acceptChild(visitor, this.getReferencedColumns()); - + acceptChild(visitor, using); acceptChild(visitor, exceptionsInto); } visitor.endVisit(this); } + public Boolean getDeferrable() { + return deferrable; + } + + public void setDeferrable(Boolean deferrable) { + this.deferrable = deferrable; + } + + public Initially getInitially() { + return initially; + } + + public void setInitially(Initially initially) { + this.initially = initially; + } + public SQLName getExceptionsInto() { return exceptionsInto; } @@ -69,12 +86,4 @@ public class OracleForeignKey extends SQLForeignKeyImpl implements OracleConstra this.using = using; } - public Boolean getEnable() { - return enable; - } - - public void setEnable(Boolean enable) { - this.enable = enable; - } - } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePrimaryKey.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePrimaryKey.java index 7beb97a140..554fb6156d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePrimaryKey.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePrimaryKey.java @@ -33,6 +33,8 @@ public class OraclePrimaryKey extends OracleSQLObjectImpl implements OracleConst private OracleUsingIndexClause using; private SQLName exceptionsInto; private Boolean enable; + private Initially initially; + private Boolean deferrable; @Override public void accept0(OracleASTVisitor visitor) { @@ -45,6 +47,14 @@ public class OraclePrimaryKey extends OracleSQLObjectImpl implements OracleConst visitor.endVisit(this); } + public Boolean getDeferrable() { + return deferrable; + } + + public void setDeferrable(Boolean deferrable) { + this.deferrable = deferrable; + } + public SQLName getName() { return name; } @@ -85,4 +95,12 @@ public class OraclePrimaryKey extends OracleSQLObjectImpl implements OracleConst this.enable = enable; } + public Initially getInitially() { + return initially; + } + + public void setInitially(Initially initially) { + this.initially = initially; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUnique.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUnique.java index e0ed69dc0a..d599b1ff46 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUnique.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUnique.java @@ -25,7 +25,8 @@ public class OracleUnique extends SQLUnique implements OracleConstraint, OracleS private OracleUsingIndexClause using; private SQLName exceptionsInto; - private Boolean enable; + private Initially initially; + private Boolean deferrable; @Override protected void accept0(SQLASTVisitor visitor) { @@ -47,6 +48,14 @@ public class OracleUnique extends SQLUnique implements OracleConstraint, OracleS visitor.endVisit(this); } + public Boolean getDeferrable() { + return deferrable; + } + + public void setDeferrable(Boolean deferrable) { + this.deferrable = deferrable; + } + public SQLName getExceptionsInto() { return exceptionsInto; } @@ -66,12 +75,12 @@ public class OracleUnique extends SQLUnique implements OracleConstraint, OracleS this.using = using; } - public Boolean getEnable() { - return enable; + public Initially getInitially() { + return initially; } - public void setEnable(Boolean enable) { - this.enable = enable; + public void setInitially(Initially initially) { + this.initially = initially; } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index d88dea63ef..da227ef71b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -36,9 +36,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; 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.SQLCheck; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint; -import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl; import com.alibaba.druid.sql.ast.statement.SQLUnique; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay; import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear; @@ -67,7 +67,9 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleRangeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSizeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCheck; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraint; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraint.Initially; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForeignKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; @@ -1273,6 +1275,36 @@ public class OracleExprParser extends SQLExprParser { continue; } + if (lexer.token() == Token.INITIALLY) { + lexer.nextToken(); + + if (lexer.token() == Token.IMMEDIATE) { + lexer.nextToken(); + constraint.setInitially(Initially.IMMEDIATE); + } else { + accept(Token.DEFERRED); + constraint.setInitially(Initially.DEFERRED); + } + + continue; + } + + if (lexer.token() == Token.NOT) { + lexer.nextToken(); + if (identifierEquals("DEFERRABLE")) { + lexer.nextToken(); + constraint.setDeferrable(false); + continue; + } + throw new ParserException("TODO " + lexer.token()); + } + + if (identifierEquals("DEFERRABLE")) { + lexer.nextToken(); + constraint.setDeferrable(true); + continue; + } + break; } @@ -1282,4 +1314,8 @@ public class OracleExprParser extends SQLExprParser { protected SQLForeignKeyConstraint createForeignKey() { return new OracleForeignKey(); } + + protected SQLCheck createCheck() { + return new OracleCheck(); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java index a74c2eddc9..2b8dc098a3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java @@ -108,6 +108,7 @@ public class OracleLexer extends Lexer { map.put("NOCOMPRESS", Token.NOCOMPRESS); map.put("KEEP_DUPLICATES", Token.KEEP_DUPLICATES); map.put("EXCEPTIONS", Token.EXCEPTIONS); + map.put("INITIALLY", Token.INITIALLY); DEFAULT_ORACLE_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java index d4dff6413e..40c5f3fa4c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java @@ -71,6 +71,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTablespaceStatem import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTriggerStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterViewStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCheck; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateDatabaseDbLinkStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; @@ -616,4 +617,8 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(OracleForeignKey x); void endVisit(OracleForeignKey x); + + boolean visit(OracleCheck x); + + void endVisit(OracleCheck x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java index 830a217f63..9466fd3407 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitorAdapter.java @@ -79,6 +79,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTablespaceStatem import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTriggerStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterViewStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCheck; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateDatabaseDbLinkStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; @@ -1396,5 +1397,15 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora public void endVisit(OracleForeignKey x) { } + + @Override + public boolean visit(OracleCheck x) { + return true; + } + + @Override + public void endVisit(OracleCheck x) { + + } } 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 bfd09b57a0..2f4bffcc6b 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 @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem; import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType; +import com.alibaba.druid.sql.ast.statement.SQLCheck; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl; @@ -109,7 +110,9 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTablespaceStatem import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTriggerStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterViewStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCheck; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraint; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateDatabaseDbLinkStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; @@ -2339,6 +2342,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS printAndAccept(x.getColumns(), ", "); print(")"); + printConstraintState(x); + + return false; + } + + protected void printConstraintState(OracleConstraint x) { if (x.getUsing() != null) { println(); x.getUsing().accept(this); @@ -2357,8 +2366,19 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print(" DIABLE"); } } - - return false; + + if (x.getInitially() != null) { + print(" INITIALLY "); + print(x.getInitially().name()); + } + + if (x.getDeferrable() != null) { + if(x.getDeferrable().booleanValue()) { + print(" DEFERRABLE"); + } else { + print(" NOT DEFERRABLE"); + } + } } @Override @@ -3349,15 +3369,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OracleUnique x) { visit((SQLUnique) x); - if (x.getUsing() != null) { - println(); - x.getUsing().accept(this); - } - if (x.getExceptionsInto() != null) { - println(); - print("EXCEPTIONS INTO "); - x.getExceptionsInto().accept(this); - } + printConstraintState(x); return false; } @@ -3370,15 +3382,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OracleForeignKey x) { visit((SQLForeignKeyImpl) x); - if (x.getUsing() != null) { - println(); - x.getUsing().accept(this); - } - if (x.getExceptionsInto() != null) { - println(); - print("EXCEPTIONS INTO "); - x.getExceptionsInto().accept(this); - } + printConstraintState(x); return false; } @@ -3386,4 +3390,17 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(OracleForeignKey x) { } + + @Override + public boolean visit(OracleCheck x) { + visit((SQLCheck) x); + + printConstraintState(x); + return false; + } + + @Override + public void endVisit(OracleCheck x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java index 3eccaa6b05..ab82b718f0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java @@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.statement.SQLCheck; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; @@ -103,6 +104,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTablespaceStatem import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTriggerStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterViewStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCheck; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateDatabaseDbLinkStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; @@ -1818,4 +1820,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public void endVisit(OracleForeignKey x) { } + + @Override + public boolean visit(OracleCheck x) { + return visit((SQLCheck) x); + } + + @Override + public void endVisit(OracleCheck x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java index f2857f9b78..eb7347c771 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java @@ -75,6 +75,7 @@ public class SQLCreateTableParser extends SQLDDLParser { createTable.getTableElementList().add(column); } else if (lexer.token == Token.PRIMARY // || lexer.token == Token.UNIQUE // + || lexer.token == Token.CHECK // || lexer.token == Token.CONSTRAINT) { OracleConstraint constraint = ((OracleExprParser) this.exprParser).parseConstaint(); constraint.setParent(createTable); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 704b763f9f..e7c89b6a13 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -62,6 +62,7 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.NotNullConstraint; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType; +import com.alibaba.druid.sql.ast.statement.SQLCheck; import com.alibaba.druid.sql.ast.statement.SQLColumnCheck; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLColumnPrimaryKey; @@ -241,6 +242,7 @@ public class SQLExprParser extends SQLParser { case COMPUTE: case ENABLE: case DISABLE: + case INITIALLY: sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); lexer.nextToken(); break; @@ -1347,18 +1349,51 @@ public class SQLExprParser extends SQLParser { column.getConstaints().add(ref); return parseColumnRest(column); } + + if (lexer.token() == Token.NOT) { + lexer.nextToken(); + accept(Token.NULL); + NotNullConstraint notNull = new NotNullConstraint(); + notNull.setName(name); + column.getConstaints().add(notNull); + return parseColumnRest(column); + } + + if (lexer.token == Token.CHECK) { + SQLColumnCheck check = parseColumnCheck(); + check.setName(name); + check.setParent(column); + column.getConstaints().add(check); + return parseColumnRest(column); + } + + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } if (lexer.token == Token.CHECK) { - lexer.nextToken(); - SQLExpr expr = this.expr(); - column.getConstaints().add(new SQLColumnCheck(expr)); + SQLColumnCheck check = parseColumnCheck(); + column.getConstaints().add(check); return parseColumnRest(column); } return column; } + protected SQLColumnCheck parseColumnCheck() { + lexer.nextToken(); + SQLExpr expr = this.expr(); + SQLColumnCheck check = new SQLColumnCheck(expr); + + if (lexer.token() == Token.DISABLE) { + lexer.nextToken(); + check.setEnable(false); + } else if (lexer.token() == Token.ENABLE) { + lexer.nextToken(); + check.setEnable(true); + } + return check; + } + public SQLPrimaryKey parsePrimaryKey() { accept(Token.PRIMARY); accept(Token.KEY); @@ -1430,6 +1465,8 @@ public class SQLExprParser extends SQLParser { constraint = parseUnique(); } else if (lexer.token() == Token.FOREIGN) { constraint = parseForeignKey(); + } else if (lexer.token() == Token.CHECK) { + constraint = parseCheck(); } else { throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } @@ -1438,6 +1475,19 @@ public class SQLExprParser extends SQLParser { return constraint; } + + public SQLCheck parseCheck() { + accept(Token.CHECK); + SQLCheck check = createCheck(); + accept(Token.LPAREN); + check.setExpr(this.expr()); + accept(Token.RPAREN); + return check; + } + + protected SQLCheck createCheck() { + return new SQLCheck(); + } public SQLForeignKeyConstraint parseForeignKey() { accept(Token.FOREIGN); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index f79294bb6f..91a45c9708 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -93,6 +93,11 @@ public class SQLParser { case NOCOMPRESS: case KEEP_DUPLICATES: case EXCEPTIONS: + case INITIALLY: + case END: + case COMMENT: + case ENABLE: + case DISABLE: alias = lexer.stringVal(); lexer.nextToken(); return alias; diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 467efbb4fb..f907019680 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -171,6 +171,7 @@ public enum Token { PCTFREE("PCTFREE"), INITRANS("INITRANS"), MAXTRANS("MAXTRANS"), + INITIALLY("INITIALLY"), ENABLE("ENABLE"), DISABLE("DISABLE"), SEGMENT("SEGMENT"), 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 40c9922398..5f127f707c 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -818,16 +818,20 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab } for (SQLColumnConstraint item : x.getConstaints()) { - boolean newLine = item instanceof SQLForeignKeyConstraint || item instanceof SQLPrimaryKey || item instanceof SQLColumnReference; + boolean newLine = item instanceof SQLForeignKeyConstraint // + || item instanceof SQLPrimaryKey // + || item instanceof SQLColumnCheck // + || item instanceof SQLColumnCheck // + || item.getName() != null; if (newLine) { incrementIndent(); println(); } else { print(' '); } - + item.accept(this); - + if (newLine) { decrementIndent(); } @@ -986,6 +990,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab } public boolean visit(NotNullConstraint x) { + if (x.getName() != null) { + print("CONSTRAINT "); + x.getName().accept(this); + print(' '); + } print("NOT NULL"); return false; } @@ -1365,27 +1374,43 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab @Override public boolean visit(SQLColumnPrimaryKey x) { if (x.getName() != null) { - print(" CONSTRAINT "); + print("CONSTRAINT "); x.getName().accept(this); + print(' '); } - print(" PRIMARY KEY"); + print("PRIMARY KEY"); return false; } @Override public boolean visit(SQLColumnUniqueKey x) { if (x.getName() != null) { - print(" CONSTRAINT "); + print("CONSTRAINT "); x.getName().accept(this); + print(' '); } - print(" UNIQUE"); + print("UNIQUE"); return false; } @Override public boolean visit(SQLColumnCheck x) { - print("CHECK "); + if (x.getName() != null) { + print("CONSTRAINT "); + x.getName().accept(this); + print(' '); + } + print("CHECK ("); x.getExpr().accept(this); + print(')'); + + if (x.getEnable() != null) { + if (x.getEnable().booleanValue()) { + print(" ENABLE"); + } else { + print(" DISABLE"); + } + } return false; } @@ -1440,7 +1465,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab print(' '); } print("CHECK ("); + incrementIndent(); x.getExpr().accept(this); + decrementIndent(); print(')'); return false; } 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 b7af435223..74a5bc26b4 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -17,6 +17,7 @@ package com.alibaba.druid.sql.visitor; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLOver; @@ -870,7 +871,10 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { @Override public boolean visit(SQLUnique x) { - return true; + for (SQLExpr column : x.getColumns()) { + column.accept(this); + } + return false; } @Override diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest19.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest19.java index ca2e90a571..17a713ed75 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest19.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest19.java @@ -61,7 +61,7 @@ public class OracleAlterTableTest19 extends OracleTest { Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("warehouses"))); - Assert.assertEquals(4, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getColumns().size()); // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("PRODUCT_IDS_ZZJ_TBD0209", // "discount_amount"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest22.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest22.java index f437f1edf8..09fb727704 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest22.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest22.java @@ -74,7 +74,7 @@ public class OracleCreateTableTest22 extends OracleTest { Assert.assertEquals(1, visitor.getTables().size()); - Assert.assertEquals(7, visitor.getColumns().size()); + Assert.assertEquals(6, visitor.getColumns().size()); Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("promotions_var2", "promo_id"))); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest23.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest23.java index ddc51e4138..5e84633013 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest23.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest23.java @@ -49,7 +49,8 @@ public class OracleCreateTableTest23 extends OracleTest { Assert.assertEquals(1, statementList.size()); Assert.assertEquals("CREATE TABLE promotions_var1 (" // - + "\n\tpromo_id NUMBER(6) CONSTRAINT promo_id_u UNIQUE," // + + "\n\tpromo_id NUMBER(6)" // + + "\n\t\tCONSTRAINT promo_id_u UNIQUE," // + "\n\tpromo_name VARCHAR2(20)," // + "\n\tpromo_category VARCHAR2(15)," // + "\n\tpromo_cost NUMBER(10, 2)," // diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest24.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest24.java index 451168fed9..78c643cd84 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest24.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest24.java @@ -48,7 +48,8 @@ public class OracleCreateTableTest24 extends OracleTest { Assert.assertEquals(1, statementList.size()); Assert.assertEquals("CREATE TABLE locations_demo (" // - + "\n\tlocation_id NUMBER(4) CONSTRAINT loc_id_pk PRIMARY KEY," // + + "\n\tlocation_id NUMBER(4)"// + + "\n\t\tCONSTRAINT loc_id_pk PRIMARY KEY," // + "\n\tstreet_address VARCHAR2(40)," // + "\n\tpostal_code VARCHAR2(12)," // + "\n\tcity VARCHAR2(30)," // diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest28.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest28.java new file mode 100644 index 0000000000..08c22ff115 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest28.java @@ -0,0 +1,78 @@ +/* + * 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 org.junit.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 OracleCreateTableTest28 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE divisions " // + + " (div_no NUMBER CONSTRAINT check_divno" // + + " CHECK (div_no BETWEEN 10 AND 99) " // + + " DISABLE, " // + + " div_name VARCHAR2(9) CONSTRAINT check_divname" // + + " CHECK (div_name = UPPER(div_name)) " // + + " DISABLE, " // + + " office VARCHAR2(10) CONSTRAINT check_office" // + + " CHECK (office IN ('DALLAS','BOSTON'," // + + " 'PARIS','TOKYO')) " // + + " DISABLE); "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE divisions (" // + + "\n\tdiv_no NUMBER" // + + "\n\t\tCONSTRAINT check_divno CHECK (div_no BETWEEN 10 AND 99) DISABLE," // + + "\n\tdiv_name VARCHAR2(9)" // + + "\n\t\tCONSTRAINT check_divname CHECK (div_name = UPPER(div_name)) DISABLE," // + + "\n\toffice VARCHAR2(10)" // + + "\n\t\tCONSTRAINT check_office CHECK (office IN ('DALLAS', 'BOSTON', 'PARIS', 'TOKYO')) DISABLE" // + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("divisions", "div_no"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest29.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest29.java new file mode 100644 index 0000000000..9030c7813b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest29.java @@ -0,0 +1,78 @@ +/* + * 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 org.junit.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 OracleCreateTableTest29 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE dept_20" // + + " (employee_id NUMBER(4) PRIMARY KEY, "// + + " last_name VARCHAR2(10), "// + + " job_id VARCHAR2(9), "// + + " manager_id NUMBER(4), "// + + " salary NUMBER(7,2), "// + + " commission_pct NUMBER(7,2), "// + + " department_id NUMBER(2),"// + + " CONSTRAINT check_sal CHECK (salary * commission_pct <= 5000));"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE dept_20 (" // + + "\n\temployee_id NUMBER(4) PRIMARY KEY," // + + "\n\tlast_name VARCHAR2(10)," // + + "\n\tjob_id VARCHAR2(9)," // + + "\n\tmanager_id NUMBER(4)," // + + "\n\tsalary NUMBER(7, 2)," // + + "\n\tcommission_pct NUMBER(7, 2)," // + + "\n\tdepartment_id NUMBER(2)," // + + "\n\tCONSTRAINT check_sal CHECK (salary * commission_pct <= 5000)" // + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(8, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("dept_20", "employee_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest30.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest30.java new file mode 100644 index 0000000000..d98ee6d051 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest30.java @@ -0,0 +1,84 @@ +/* + * 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 org.junit.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 OracleCreateTableTest30 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE order_detail " // + + " (CONSTRAINT pk_od PRIMARY KEY (order_id, part_no), " // + + " order_id NUMBER " // + + " CONSTRAINT fk_oid " // + + " REFERENCES oe.orders(order_id), " // + + " part_no NUMBER " // + + " CONSTRAINT fk_pno " // + + " REFERENCES oe.product_information(product_id), " // + + " quantity NUMBER " // + + " CONSTRAINT nn_qty NOT NULL " // + + " CONSTRAINT check_qty CHECK (quantity > 0), " // + + " cost NUMBER " // + + " CONSTRAINT check_cost CHECK (cost > 0) ); "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE order_detail (" // + + "\n\tCONSTRAINT pk_od PRIMARY KEY (order_id, part_no)," // + + "\n\torder_id NUMBER" // + + "\n\t\tCONSTRAINT fk_oid REFERENCES oe.orders (order_id)," // + + "\n\tpart_no NUMBER" // + + "\n\t\tCONSTRAINT fk_pno REFERENCES oe.product_information (product_id)," // + + "\n\tquantity NUMBER" // + + "\n\t\tCONSTRAINT nn_qty NOT NULL" // + + "\n\t\tCONSTRAINT check_qty CHECK (quantity > 0)," // + + "\n\tcost NUMBER" // + + "\n\t\tCONSTRAINT check_cost CHECK (cost > 0)" // + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(4, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("order_detail", "order_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest31.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest31.java new file mode 100644 index 0000000000..03c7184c88 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest31.java @@ -0,0 +1,68 @@ +/* + * 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 org.junit.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 OracleCreateTableTest31 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE students (name person_name, age INTEGER," // + + " CHECK (name.first_name IS NOT NULL AND " // + + " name.last_name IS NOT NULL));"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE students (" + + "\n\tname person_name," + + "\n\tage INTEGER," + + "\n\tCHECK (name.first_name IS NOT NULL" + + "\n\t\tAND name.last_name IS NOT NULL)" + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(4, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("students", "name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest32.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest32.java new file mode 100644 index 0000000000..ae5f29747d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest32.java @@ -0,0 +1,64 @@ +/* + * 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 org.junit.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 OracleCreateTableTest32 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE games (scores NUMBER CHECK (scores >= 0));"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE games (" // + + "\n\tscores NUMBER" // + + "\n\t\tCHECK (scores >= 0)" // + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(1, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("games", "scores"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest33.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest33.java new file mode 100644 index 0000000000..f50d43e4c0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest33.java @@ -0,0 +1,66 @@ +/* + * 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 org.junit.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 OracleCreateTableTest33 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE games" // + + " (scores NUMBER, CONSTRAINT unq_num UNIQUE (scores)" // + + " INITIALLY DEFERRED DEFERRABLE);"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TABLE games (" // + + "\n\tscores NUMBER," // + + "\n\tCONSTRAINT unq_num UNIQUE (scores) INITIALLY DEFERRED DEFERRABLE" // + + "\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()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertEquals(1, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("games", "scores"))); + } +}