From 811aa9b4b56dbf66b9947ec26ba535e306229044 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 19 Jul 2017 00:40:03 +0800 Subject: [PATCH] improved sql parser. --- .../java/com/alibaba/druid/sql/SQLUtils.java | 19 ++ .../statement/SQLCreateTableStatement.java | 165 +++++++++++++++- .../ast/stmt/OracleCreateTableStatement.java | 21 +- .../stmt/OracleSetTransactionStatement.java | 8 + .../parser/OracleCreateTableParser.java | 16 +- .../oracle/parser/OracleStatementParser.java | 17 +- .../oracle/visitor/OracleOutputVisitor.java | 21 +- .../com/alibaba/druid/sql/parser/Lexer.java | 59 +++++- .../alibaba/druid/sql/parser/SQLParser.java | 2 +- .../druid/support/calcite/DDLColumn.java | 73 +++++++ .../druid/support/calcite/DDLSchema.java | 136 +++++++++++++ .../druid/support/calcite/DDLTable.java | 184 ++++++++++++++++++ .../druid/bvt/sql/CreateCompareTest.java | 82 ++++++++ .../sql/oracle/OracleSetTransactionTest3.java | 55 ++++++ .../create/OracleCreateTableTest72.java | 82 ++++++++ .../create/OracleCreateTableTest73.java | 131 +++++++++++++ .../druid/sql/calcite/CalciteTest.java | 5 + 17 files changed, 1042 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/support/calcite/DDLColumn.java create mode 100644 src/main/java/com/alibaba/druid/support/calcite/DDLSchema.java create mode 100644 src/main/java/com/alibaba/druid/support/calcite/DDLTable.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest72.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest73.java diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index ddd1aab332..cec85b97c5 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -788,6 +788,25 @@ public class SQLUtils { return name; } + public static boolean nameEquals(String a, String b) { + if (a == b) { + return true; + } + + if (a == null || b == null) { + return false; + } + + if (a.equalsIgnoreCase(b)) { + return true; + } + + String normalize_a = normalize(a); + String normalize_b = normalize(b); + + return normalize_a.equalsIgnoreCase(normalize_b); + } + public static boolean isValue(SQLExpr expr) { if (expr instanceof SQLLiteralExpr) { return true; diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index 0465978be0..9f69deb3e6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -15,9 +15,7 @@ */ package com.alibaba.druid.sql.ast.statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLDataType; @@ -237,4 +235,165 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS return null; } + + public List findForeignKey() { + List fkList = new ArrayList(); + for (SQLTableElement element : this.tableElementList) { + if (element instanceof SQLForeignKeyConstraint) { + fkList.add((SQLForeignKeyConstraint) element); + } + } + return fkList; + } + + public boolean hashForeignKey() { + for (SQLTableElement element : this.tableElementList) { + if (element instanceof SQLForeignKeyConstraint) { + return true; + } + } + return false; + } + + public boolean isReferenced(SQLName tableName) { + if (tableName == null) { + return false; + } + + return isReferenced(tableName.getSimpleName()); + } + + public boolean isReferenced(String tableName) { + if (tableName == null) { + return false; + } + + tableName = SQLUtils.normalize(tableName); + + for (SQLTableElement element : this.tableElementList) { + if (element instanceof SQLForeignKeyConstraint) { + SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) element; + String refTableName = fk.getReferencedTableName().getSimpleName(); + + if (SQLUtils.nameEquals(tableName, refTableName)) { + return true; + } + } + } + + return false; + } + + public static class DependencyComparator implements Comparator { + private final Map tables = new HashMap(); + private final Set referencedTableNames = new HashSet(); + + public void add(SQLCreateTableStatement stmt) { + String tableName = stmt.getName().getSimpleName(); + tableName = SQLUtils.normalize(tableName).toLowerCase(); + tables.put(tableName, stmt); + + for (SQLTableElement element : stmt.tableElementList) { + if (element instanceof SQLForeignKeyConstraint) { + SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) element; + String refTableName = fk.getReferencedTableName().getSimpleName(); + refTableName = SQLUtils.normalize(refTableName).toLowerCase(); + referencedTableNames.add(refTableName); + } + } + } + + public int compare(Object a, Object b) { + return compareStmt((SQLCreateTableStatement)a, (SQLCreateTableStatement) b); + } + + public int compareStmt(SQLCreateTableStatement a, SQLCreateTableStatement b) { + if (a == b) { + return 0; + } + + if (a == null) { + return -1; + } + + if (b == null) { + return 1; + } + + int refVal = isReferenced(a, b); + if (refVal == -1) { + return 1; + } + + + refVal = isReferenced(b, a); + + if (refVal == -1) { + return -1; + } + + boolean a_referenced = isReferenced(a); + boolean b_referenced = isReferenced(b); + + if (a_referenced != b_referenced) { + return a_referenced ? 1 : -1; + } + + return 0; + } + + boolean isReferenced(SQLCreateTableStatement stmt) { + String tableName = stmt.getName().getSimpleName(); + tableName = SQLUtils.normalize(tableName).toLowerCase(); + return referencedTableNames.contains(tableName); + } + + int isReferenced(SQLCreateTableStatement a, SQLCreateTableStatement b) { + if (a == b) { + return 0; + } + + if (a.isReferenced(b.getName())) { + return -1; + } + + for (SQLTableElement element : a.tableElementList) { + if (element instanceof SQLForeignKeyConstraint) { + SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) element; + SQLName refTableName = fk.getReferencedTableName(); + + SQLCreateTableStatement refStmt = findStatement(refTableName); + if (refStmt != null) { + int refVal = isReferenced(refStmt, b); + if (refVal != 0) { + return refVal; + } + } + + } + } + + return 0; + } + + public SQLCreateTableStatement findStatement(SQLName name) { + if (name == null) { + return null; + } + + String refTableName = name.getSimpleName(); + refTableName = SQLUtils.normalize(refTableName).toLowerCase(); + return tables.get(refTableName); + } + } + + public static void sort(List stmtList) { + final DependencyComparator comparator = new DependencyComparator(); + + for (SQLCreateTableStatement stmt : stmtList) { + comparator.add(stmt); + } + + Collections.sort(stmtList, comparator); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java index 86590980ca..419114705a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java @@ -58,8 +58,9 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen private Boolean compress; private Integer compressLevel; private boolean compressForOltp; - private boolean onCommit; - private boolean preserveRows; + + private boolean onCommitPreserveRows; + private boolean onCommitDeleteRows; private Boolean cache; @@ -114,20 +115,20 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.cache = cache; } - public boolean isOnCommit() { - return onCommit; + public boolean isOnCommitPreserveRows() { + return onCommitPreserveRows; } - public void setOnCommit(boolean onCommit) { - this.onCommit = onCommit; + public void setOnCommitPreserveRows(boolean onCommitPreserveRows) { + this.onCommitPreserveRows = onCommitPreserveRows; } - public boolean isPreserveRows() { - return preserveRows; + public boolean isOnCommitDeleteRows() { + return onCommitDeleteRows; } - public void setPreserveRows(boolean preserveRows) { - this.preserveRows = preserveRows; + public void setOnCommitDeleteRows(boolean onCommitDeleteRows) { + this.onCommitDeleteRows = onCommitDeleteRows; } public Boolean getLogging() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java index a0ddc6fc64..90ef282676 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; public class OracleSetTransactionStatement extends OracleStatementImpl implements OracleStatement { private boolean readOnly = false; + private boolean write = false; private SQLExpr name; @@ -51,4 +52,11 @@ public class OracleSetTransactionStatement extends OracleStatementImpl implement this.readOnly = readOnly; } + public boolean isWrite() { + return write; + } + + public void setWrite(boolean write) { + this.write = write; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java index 1d8b3c616a..845d9fc8d3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java @@ -124,12 +124,16 @@ public class OracleCreateTableParser extends SQLCreateTableParser { } else if (lexer.token() == Token.ON) { lexer.nextToken(); accept(Token.COMMIT); - stmt.setOnCommit(true); - continue; - } else if (identifierEquals("PRESERVE")) { - lexer.nextToken(); - acceptIdentifier("ROWS"); - stmt.setPreserveRows(true); + + if (identifierEquals("PRESERVE")) { + lexer.nextToken(); + acceptIdentifier("ROWS"); + stmt.setOnCommitPreserveRows(true); + } else { + accept(Token.DELETE); + acceptIdentifier("ROWS"); + stmt.setOnCommitDeleteRows(true); + } continue; } else if (identifierEquals("STORAGE")) { OracleStorageClause storage = ((OracleExprParser) this.exprParser).parseStorage(); 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 76682ea2e2..9645ec2b67 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 @@ -995,13 +995,22 @@ public class OracleStatementParser extends SQLStatementParser { if (identifierEquals("READ")) { lexer.nextToken(); - acceptIdentifier("ONLY"); - stmt.setReadOnly(true); + + if (identifierEquals("ONLY")) { + lexer.nextToken(); + stmt.setReadOnly(true); + } else { + acceptIdentifier("WRITE"); + stmt.setWrite(true); + } } - acceptIdentifier("NAME"); + if (identifierEquals("NAME")) { + lexer.nextToken(); + + stmt.setName(this.exprParser.expr()); + } - stmt.setName(this.exprParser.expr()); return stmt; } 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 d1ddd3fdef..f6dcfd08ce 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 @@ -1503,11 +1503,16 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(OracleSetTransactionStatement x) { if (x.isReadOnly()) { - print0(ucase ? "SET TRANSACTION READ ONLY NAME " : "set transaction read only name "); + print0(ucase ? "SET TRANSACTION READ ONLY" : "set transaction read only"); } else { - print0(ucase ? "SET TRANSACTION NAME " : "set transaction name "); + print0(ucase ? "SET TRANSACTION" : "set transaction"); + } + + SQLExpr name = x.getName(); + if (name != null) { + print0(ucase ? " NAME " : " name "); + name.accept(this); } - x.getName().accept(this); return false; } @@ -2127,14 +2132,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getLobStorage().accept(this); } - if (x.isOnCommit()) { + if (x.isOnCommitPreserveRows()) { println(); - print0(ucase ? "ON COMMIT" : "on commit"); - } - - if (x.isPreserveRows()) { + print0(ucase ? "ON COMMIT PRESERVE ROWS" : "on commit preserve rows"); + } else if (x.isOnCommitDeleteRows()) { println(); - print0(ucase ? "PRESERVE ROWS" : "preserve rows"); + print0(ucase ? "ON COMMIT DELETE ROWS" : "on commit delete rows"); } if (x.isMonitoring()) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 869f77cdc4..0bf6fa13cb 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -89,6 +89,10 @@ public class Lexer { protected String dbType; + private int startPos; + private int posLine; + private int posColumn; + public Lexer(String input){ this(input, null); } @@ -249,7 +253,35 @@ public class Lexer { } public String info() { - return "pos " + this.pos + ", " + this.token + " " + this.stringVal(); + int line = 1; + int column = 1; + for (int i = 0; i < startPos; ++i, column++) { + char ch = text.charAt(i); + if (ch == '\n') { + column = 1; + line++; + } + } + + this.posLine = line; + this.posColumn = posColumn; + + StringBuilder buf = new StringBuilder(); + buf + .append("pos ") + .append(pos) + .append(", line ") + .append(line) + .append(", column ") + .append(column) + .append(", token ") + .append(token); + + if (token == Token.IDENTIFIER || token == Token.LITERAL_ALIAS || token == Token.LITERAL_CHARS) { + buf.append(" ").append(stringVal); + } + + return buf.toString(); } public final void nextTokenComma() { @@ -286,6 +318,7 @@ public class Lexer { } public final void nextTokenValue() { + this.startPos = pos; if (ch == ' ') { scanChar(); } @@ -317,6 +350,7 @@ public class Lexer { } public final void nextToken() { + startPos = pos; bufPos = 0; if (comments != null && comments.size() > 0) { comments = null; @@ -1549,4 +1583,27 @@ public class Lexer { public int getLine() { return line; } + + public void computeRowAndColumn() { + int line = 1; + int column = 1; + for (int i = 0; i < pos; ++i) { + char ch = text.charAt(i); + if (ch == '\n') { + column = 1; + line++; + } + } + + this.posLine = line; + this.posColumn = posColumn; + } + + public int getPosLine() { + return posLine; + } + + public int getPosColumn() { + return posColumn; + } } 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 664d0caab0..2b739ac56f 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -277,7 +277,7 @@ public class SQLParser { // + token + ", actual " + lexer.token() + " " // + lexer.stringVal() + ", pos " + this.lexer.pos()); throw new ParserException("syntax error, error in :'" + arround + "',expect " + token + ", actual " - + lexer.token() + " " + lexer.stringVal()); + + lexer.token() + " " + lexer.info()); } public void accept(Token token) { diff --git a/src/main/java/com/alibaba/druid/support/calcite/DDLColumn.java b/src/main/java/com/alibaba/druid/support/calcite/DDLColumn.java new file mode 100644 index 0000000000..cfcf557633 --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/calcite/DDLColumn.java @@ -0,0 +1,73 @@ +/* + * 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.support.calcite; + +import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeField; + +/** + * Created by wenshao on 17/07/2017. + */ +public class DDLColumn implements RelDataTypeField { + private DDLTable table; + private final SQLColumnDefinition column; + private final int index; + + private final String name; + + public DDLColumn(DDLTable table, SQLColumnDefinition column, int index) { + this.table = table; + this.column = column; + this.name = column.getName().getSimpleName(); + this.index = index; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getIndex() { + return index; + } + + @Override + public RelDataType getType() { + return table; + } + + @Override + public boolean isDynamicStar() { + return false; + } + + @Override + public String getKey() { + return null; + } + + @Override + public RelDataType getValue() { + return null; + } + + @Override + public RelDataType setValue(RelDataType value) { + return null; + } +} diff --git a/src/main/java/com/alibaba/druid/support/calcite/DDLSchema.java b/src/main/java/com/alibaba/druid/support/calcite/DDLSchema.java new file mode 100644 index 0000000000..ed4fc570d2 --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/calcite/DDLSchema.java @@ -0,0 +1,136 @@ +/* + * 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.support.calcite; + +import com.google.common.collect.*; +import org.apache.calcite.linq4j.tree.Expression; +import org.apache.calcite.materialize.Lattice; +import org.apache.calcite.schema.Function; +import org.apache.calcite.schema.Schema; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.schema.Table; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * Created by wenshao on 17/07/2017. + */ +public class DDLSchema implements Schema, SchemaPlus { + private Map tables; + private Map functions; + private Map subSchemas; + + @Override + public Table getTable(String name) { + return tables.get(name); + } + + @Override + public Set getTableNames() { + return tables.keySet(); + } + + @Override + public Collection getFunctions(String name) { + return null; + } + + @Override + public Set getFunctionNames() { + return null; + } + + @Override + public SchemaPlus getParentSchema() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public SchemaPlus getSubSchema(String name) { + return null; + } + + @Override + public SchemaPlus add(String name, Schema schema) { + return null; + } + + @Override + public void add(String name, Table table) { + + } + + @Override + public void add(String name, Function function) { + + } + + @Override + public void add(String name, Lattice lattice) { + + } + + @Override + public Set getSubSchemaNames() { + return subSchemas.keySet(); + } + + @Override + public Expression getExpression(SchemaPlus parentSchema, String name) { + return null; + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public T unwrap(Class clazz) { + return null; + } + + @Override + public void setCacheEnabled(boolean cache) { + + } + + @Override + public boolean isCacheEnabled() { + return false; + } + + public void setPath(ImmutableList> path) { + + } + + @Override + public boolean contentsHaveChangedSince(long lastCheck, long now) { + return false; + } + + @Override + public Schema snapshot(long now) { + return null; + } +} diff --git a/src/main/java/com/alibaba/druid/support/calcite/DDLTable.java b/src/main/java/com/alibaba/druid/support/calcite/DDLTable.java new file mode 100644 index 0000000000..1069fb1bce --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/calcite/DDLTable.java @@ -0,0 +1,184 @@ +/* + * 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.support.calcite; + +import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLTableElement; +import org.apache.calcite.rel.type.*; +import org.apache.calcite.schema.Schema; +import org.apache.calcite.schema.Statistic; +import org.apache.calcite.schema.Table; +import org.apache.calcite.sql.SqlCollation; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlIntervalQualifier; +import org.apache.calcite.sql.type.SqlTypeName; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 17/07/2017. + */ +public class DDLTable implements Table, RelDataType { + private SQLCreateTableStatement stmt; + private List fieldNames = new ArrayList(); + private List columns = new ArrayList(); + private List fields = new ArrayList(); + + public DDLTable(SQLCreateTableStatement stmt) { + this.stmt = stmt; + + for (SQLTableElement e : stmt.getTableElementList()) { + if (e instanceof SQLColumnDefinition) { + SQLColumnDefinition column = (SQLColumnDefinition) e; + String fieldName = column.getName().getSimpleName(); + fieldNames.add(fieldName); + columns.add(column); + DDLColumn field = new DDLColumn(this, column, fields.size()); + this.fields.add(field); + } + } + } + + @Override + public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return this; + } + + @Override + public Statistic getStatistic() { + return null; + } + + @Override + public Schema.TableType getJdbcTableType() { + return Schema.TableType.TABLE; + } + + + @Override + public boolean isStruct() { + return false; + } + + @Override + public List getFieldList() { + return fields; + } + + @Override + public List getFieldNames() { + return fieldNames; + } + + @Override + public int getFieldCount() { + return fieldNames.size(); + } + + @Override + public StructKind getStructKind() { + return null; + } + + @Override + public RelDataTypeField getField(String fieldName, boolean caseSensitive, boolean elideRecord) { + return null; + } + + @Override + public boolean isNullable() { + return false; + } + + @Override + public RelDataType getComponentType() { + return null; + } + + @Override + public RelDataType getKeyType() { + return null; + } + + @Override + public RelDataType getValueType() { + return null; + } + + @Override + public Charset getCharset() { + return null; + } + + @Override + public SqlCollation getCollation() { + return null; + } + + @Override + public SqlIntervalQualifier getIntervalQualifier() { + return null; + } + + @Override + public int getPrecision() { + return 0; + } + + @Override + public int getScale() { + return 0; + } + + @Override + public SqlTypeName getSqlTypeName() { + return null; + } + + @Override + public SqlIdentifier getSqlIdentifier() { + return null; + } + + @Override + public String getFullTypeString() { + return null; + } + + @Override + public RelDataTypeFamily getFamily() { + return null; + } + + @Override + public RelDataTypePrecedenceList getPrecedenceList() { + return null; + } + + @Override + public RelDataTypeComparability getComparability() { + return null; + } + + @Override + public boolean isDynamicStruct() { + return false; + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java new file mode 100644 index 0000000000..92afeeba87 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/CreateCompareTest.java @@ -0,0 +1,82 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by wenshao on 18/07/2017. + */ +public class CreateCompareTest extends TestCase { + public void test_0() throws Exception { + String sql = "create table t7 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t6 (id)\n" + + ");\n" + + "\n" + + "create table t2 (\n" + + "\tint bigint\n" + + ");\n" + + "\n" + + "create table t9 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t8 (id)\n" + + ");\n" + + "\n" + + "create table t6 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t5 (id)\n" + + ");\n" + + "\n" + + "create table t8 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t7 (id)\n" + + ");\n" + + "\n" + + "create table t4 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t2 (id)\n" + + ");\n" + + "\n" + + "create table t5 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t4 (id)\n" + + ");\n" + + "\n" + + "create table t3 (\n" + + "\tint bigint,\n" + + "\tFOREIGN KEY (id) REFERENCES t2 (id)\n" + + ");\n" + + "\n" + + "create table t0 (\n" + + "\tint bigint\n" + + ");\n" + + "\n" + + "create table t1 (\n" + + "\tint bigint\n" + + ");"; + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + + List createStmtList = new ArrayList(); + for (SQLStatement item : stmtList) { + createStmtList.add((SQLCreateTableStatement) item); + } + + SQLCreateTableStatement.sort(createStmtList); + + assertEquals("t9", createStmtList.get(9).getName().getSimpleName()); + assertEquals("t8", createStmtList.get(8).getName().getSimpleName()); + assertEquals("t7", createStmtList.get(7).getName().getSimpleName()); + assertEquals("t6", createStmtList.get(6).getName().getSimpleName()); + assertEquals("t5", createStmtList.get(5).getName().getSimpleName()); + + + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest3.java new file mode 100644 index 0000000000..9d3837c14d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest3.java @@ -0,0 +1,55 @@ +/* + * 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; + +import com.alibaba.druid.sql.OracleTest; +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 org.junit.Assert; + +import java.util.List; + +public class OracleSetTransactionTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = "set transaction read write;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest72.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest72.java new file mode 100644 index 0000000000..9e350da688 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest72.java @@ -0,0 +1,82 @@ +/* + * 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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTableTest72 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + " CREATE GLOBAL TEMPORARY TABLE \"RETL\".\"REFFERAL_MEMBER\" \n" + + " (\t\"ID\" NUMBER NOT NULL ENABLE, \n" + + "\t\"GMT_CREATE\" DATE NOT NULL ENABLE, \n" + + "\t\"GMT_MODIFIED\" DATE NOT NULL ENABLE, \n" + + "\t\"FROM_NAME\" VARCHAR2(128) NOT NULL ENABLE, \n" + + "\t\"FROM_EMAIL\" VARCHAR2(128) NOT NULL ENABLE, \n" + + "\t\"TO_NAME\" VARCHAR2(128), \n" + + "\t\"TO_EMAIL\" VARCHAR2(128) NOT NULL ENABLE, \n" + + "\t\"MESSAGE\" VARCHAR2(512), \n" + + "\t\"GMT_JOIN_MEMBER\" DATE, \n" + + "\t\"SOURCE_CODE\" VARCHAR2(32) NOT NULL ENABLE, \n" + + "\t\"IS_FROM_MEMBER\" CHAR(1) NOT NULL ENABLE, \n" + + "\t\"IS_JOIN\" CHAR(1) NOT NULL ENABLE\n" + + " ) ON COMMIT DELETE ROWS "; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); +// + assertEquals("CREATE GLOBAL TEMPORARY TABLE \"RETL\".\"REFFERAL_MEMBER\" (\n" + + "\t\"ID\" NUMBER NOT NULL ENABLE,\n" + + "\t\"GMT_CREATE\" DATE NOT NULL ENABLE,\n" + + "\t\"GMT_MODIFIED\" DATE NOT NULL ENABLE,\n" + + "\t\"FROM_NAME\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"FROM_EMAIL\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"TO_NAME\" VARCHAR2(128),\n" + + "\t\"TO_EMAIL\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"MESSAGE\" VARCHAR2(512),\n" + + "\t\"GMT_JOIN_MEMBER\" DATE,\n" + + "\t\"SOURCE_CODE\" VARCHAR2(32) NOT NULL ENABLE,\n" + + "\t\"IS_FROM_MEMBER\" CHAR(1) NOT NULL ENABLE,\n" + + "\t\"IS_JOIN\" CHAR(1) NOT NULL ENABLE\n" + + ")\n" + + "ON COMMIT DELETE ROWS",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); +// +// 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(1, visitor.getTables().size()); +// +// assertEquals(3, visitor.getColumns().size()); +// +// assertTrue(visitor.getColumns().contains(new TableStat.Column("JWGZPT.A", "XM"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest73.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest73.java new file mode 100644 index 0000000000..47b85154cb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest73.java @@ -0,0 +1,131 @@ +/* + * 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.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTableTest73 extends OracleTest { + + public void test_types() throws Exception { + String sql = // + "CREATE TABLE \"RDB\".\"RDB_DATA_HIST\" \n" + + " (\t\"TABLE_ID\" NUMBER, \n" + + "\t\"EVENT_TYPE\" VARCHAR2(1), \n" + + "\t\"PK_DATA\" VARCHAR2(64), \n" + + "\t\"TRANSACTION_ID\" NUMBER, \n" + + "\t\"IGNORE_NODE_CLUSTER_ID\" VARCHAR2(32), \n" + + "\t\"GMT_CREATE\" DATE, \n" + + "\t\"ID\" NUMBER\n" + + " ) PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING \n" + + " STORAGE(\n" + + " BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" \n" + + " PARTITION BY RANGE (\"GMT_CREATE\") \n" + + " (PARTITION \"AUTO_P_2012_06_01\" VALUES LESS THAN (TO_DATE(' 2012-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_07_01\" VALUES LESS THAN (TO_DATE(' 2012-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_08_01\" VALUES LESS THAN (TO_DATE(' 2012-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_09_01\" VALUES LESS THAN (TO_DATE(' 2012-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_10_01\" VALUES LESS THAN (TO_DATE(' 2012-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_11_01\" VALUES LESS THAN (TO_DATE(' 2012-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2012_12_01\" VALUES LESS THAN (TO_DATE(' 2012-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2013_01_01\" VALUES LESS THAN (TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2013_02_01\" VALUES LESS THAN (TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOMPRESS , \n" + + " PARTITION \"AUTO_P_2013_03_01\" VALUES LESS THAN (TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) \n" + + " PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n" + + " STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" + + " PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" + + " TABLESPACE \"BISYNC1M\" NOCOM"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); +// + assertEquals("CREATE GLOBAL TEMPORARY TABLE \"RETL\".\"REFFERAL_MEMBER\" (\n" + + "\t\"ID\" NUMBER NOT NULL ENABLE,\n" + + "\t\"GMT_CREATE\" DATE NOT NULL ENABLE,\n" + + "\t\"GMT_MODIFIED\" DATE NOT NULL ENABLE,\n" + + "\t\"FROM_NAME\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"FROM_EMAIL\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"TO_NAME\" VARCHAR2(128),\n" + + "\t\"TO_EMAIL\" VARCHAR2(128) NOT NULL ENABLE,\n" + + "\t\"MESSAGE\" VARCHAR2(512),\n" + + "\t\"GMT_JOIN_MEMBER\" DATE,\n" + + "\t\"SOURCE_CODE\" VARCHAR2(32) NOT NULL ENABLE,\n" + + "\t\"IS_FROM_MEMBER\" CHAR(1) NOT NULL ENABLE,\n" + + "\t\"IS_JOIN\" CHAR(1) NOT NULL ENABLE\n" + + ")\n" + + "ON COMMIT DELETE ROWS",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); +// +// 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(1, visitor.getTables().size()); +// +// assertEquals(3, visitor.getColumns().size()); +// +// assertTrue(visitor.getColumns().contains(new TableStat.Column("JWGZPT.A", "XM"))); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java b/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java index 241830731c..c527df29a6 100644 --- a/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java +++ b/src/test/java/com/alibaba/druid/sql/calcite/CalciteTest.java @@ -1,5 +1,6 @@ package com.alibaba.druid.sql.calcite; +import com.alibaba.druid.support.calcite.DDLSchema; import junit.framework.TestCase; import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.rel.RelNode; @@ -12,9 +13,13 @@ import org.apache.calcite.tools.RelBuilder; */ public class CalciteTest extends TestCase { public void test_calcite() throws Exception { + DDLSchema schema = new DDLSchema(); + final FrameworkConfig config = Frameworks .newConfigBuilder() + .defaultSchema(schema) .build(); + final RelBuilder builder = RelBuilder.create(config); final RelNode node = builder .scan("EMP")