diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 72f16d93f9..905213a014 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -274,7 +274,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV if (x.getProcedureName() != null) { print0(ucase ? " PROCEDURE " : " procedure "); x.getProcedureName().accept(this); - if (x.getProcedureArgumentList().size() > 0) { + if (!x.getProcedureArgumentList().isEmpty()) { print('('); printAndAccept(x.getProcedureArgumentList(), ", "); print(')'); @@ -364,7 +364,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public boolean visit(SQLDataType x) { print0(x.getName()); - if (x.getArguments().size() > 0) { + if (!x.getArguments().isEmpty()) { print('('); printAndAccept(x.getArguments(), ", "); print(')'); @@ -393,9 +393,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV return false; } + @Override public boolean visit(SQLCharacterDataType x) { print0(x.getName()); - if (x.getArguments().size() > 0) { + if (!x.getArguments().isEmpty()) { print('('); printAndAccept(x.getArguments(), ", "); print(')'); @@ -758,7 +759,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV String charset = (String) x.getAttribute("USING"); if (charset != null) { print0(ucase ? " USING " : " using "); - ; print0(charset); } print(')'); @@ -960,7 +960,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV decrementIndent(); } - if (x.getValuesList().size() != 0) { + if (!x.getValuesList().isEmpty()) { println(); printValuesList(x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 13e336b291..a583fa876b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -210,12 +210,8 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS stat.incrementInsertCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); - } - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, x.getAlias(), ident); + putAliasMap(aliasMap, ident, ident); } accept(x.getColumns()); 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 b3e7708640..51f77ce647 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 @@ -229,12 +229,8 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle break; } - if (aliasMap != null) { - if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); - } - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, x.getAlias(), ident); + putAliasMap(aliasMap, ident, ident); return false; } @@ -653,7 +649,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } if (alias != null) { - aliasMap.put(alias, null); + putAliasMap(aliasMap, alias, null); subQueryMap.put(alias, x.getSubQuery()); } } @@ -851,9 +847,9 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle Map aliasMap = getAliasMap(); if (aliasMap != null) { if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); + putAliasMap(aliasMap, x.getAlias(), ident); } - aliasMap.put(ident, ident); + putAliasMap(aliasMap, ident, ident); } x.getOn().accept(this); @@ -936,9 +932,9 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle Map aliasMap = getAliasMap(); if (aliasMap != null) { if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); + putAliasMap(aliasMap, x.getAlias(), ident); } - aliasMap.put(ident, ident); + putAliasMap(aliasMap, ident, ident); } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index ed32cf5d5b..a6df65ee9a 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -16,6 +16,7 @@ package com.alibaba.druid.sql.visitor; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -121,12 +122,11 @@ import com.alibaba.druid.stat.TableStat.Column; import com.alibaba.druid.stat.TableStat.Condition; import com.alibaba.druid.stat.TableStat.Mode; import com.alibaba.druid.stat.TableStat.Relationship; -import com.alibaba.druid.util.StringUtils; public class SchemaStatVisitor extends SQLASTVisitorAdapter { protected final HashMap tableStats = new LinkedHashMap(); - protected final Set columns = new LinkedHashSet(); + protected final Map columns = new LinkedHashMap(); protected final List conditions = new ArrayList(); protected final Set relationships = new LinkedHashSet(); protected final List orderByColumns = new ArrayList(); @@ -174,7 +174,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { Column column = this.getColumn(tableName, columnName); if (column == null && columnName != null) { column = new Column(tableName, columnName); - columns.add(column); + columns.put(column, column); } return column; } @@ -189,9 +189,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (stat == null) { stat = new TableStat(); tableStats.put(new TableStat.Name(tableName), stat); - if (alias != null) { - aliasMap.put(alias, tableName); - } + putAliasMap(aliasMap, alias, tableName); } return stat; } @@ -567,9 +565,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementDeleteCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, ident, ident); } return false; @@ -599,9 +595,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementDropCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, ident, ident); } return false; @@ -624,12 +618,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementInsertCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - if (x.getAlias() != null) { - aliasMap.put(x.getAlias(), ident); - } - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, x.getAlias(), ident); + putAliasMap(aliasMap, ident, ident); } accept(x.getColumns()); @@ -637,6 +627,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } + + protected static void putAliasMap(Map aliasMap, String name, String value) { + if (aliasMap == null || name == null) { + return; + } + aliasMap.put(name.toLowerCase(), value); + } protected void accept(SQLObject x) { if (x != null) { @@ -752,14 +749,23 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { Map aliasMap = getAliasMap(); if (aliasMap != null) { - for (Map.Entry entry : aliasMap.entrySet()) { - if (entry.getKey() == null) { - continue; - } - if (entry.getKey().equalsIgnoreCase(name)) { - return entry.getValue(); - } + if (aliasMap.containsKey(name)) { + return aliasMap.get(name); } + + String name_lcase = name.toLowerCase(); + if (name_lcase != name && aliasMap.containsKey(name_lcase)) { + return aliasMap.get(name_lcase); + } + +// for (Map.Entry entry : aliasMap.entrySet()) { +// if (entry.getKey() == null) { +// continue; +// } +// if (entry.getKey().equalsIgnoreCase(name)) { +// return entry.getValue(); +// } +// } } return name; @@ -928,22 +934,18 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return tableStats.containsKey(new TableStat.Name(tableName)); } - public Set getColumns() { - return columns; + public Collection getColumns() { + return columns.values(); } public Column getColumn(String tableName, String columnName) { - for (Column column : this.columns) { - if (aliasMap != null && aliasMap.containsKey(columnName) && aliasMap.get(columnName) == null) { - return null; - } - - if (StringUtils.equalsIgnoreCase(tableName, column.getTable()) - && StringUtils.equalsIgnoreCase(columnName, column.getName())) { - return column; - } + if (aliasMap != null && aliasMap.containsKey(columnName) && aliasMap.get(columnName) == null) { + return null; } - return null; + + Column column = new Column(tableName, columnName); + + return this.columns.get(column); } public boolean visit(SQLSelectStatement x) { @@ -963,7 +965,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (Boolean.TRUE == with.getRecursive()) { if (aliasMap != null && alias != null) { - aliasMap.put(alias, null); + putAliasMap(aliasMap, alias, null); subQueryMap.put(alias, x.getSubQuery().getQuery()); } @@ -972,7 +974,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { x.getSubQuery().accept(this); if (aliasMap != null && alias != null) { - aliasMap.put(alias, null); + putAliasMap(aliasMap, alias, null); subQueryMap.put(alias, x.getSubQuery().getQuery()); } } @@ -987,7 +989,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { Map aliasMap = getAliasMap(); if (aliasMap != null && x.getAlias() != null) { - aliasMap.put(x.getAlias(), null); + putAliasMap(aliasMap, x.getAlias(), null); subQueryMap.put(x.getAlias(), query); } return false; @@ -1042,10 +1044,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (aliasMap != null) { String alias = x.getAlias(); if (alias != null && !aliasMap.containsKey(alias)) { - aliasMap.put(alias, ident); + putAliasMap(aliasMap, alias, ident); } if (!aliasMap.containsKey(ident)) { - aliasMap.put(ident, ident); + putAliasMap(aliasMap, ident, ident); } } } else { @@ -1063,9 +1065,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { Map aliasMap = this.getAliasMap(); if (alias != null && (!alias.isEmpty()) && aliasMap != null) { if (x.getExpr() instanceof SQLName) { - aliasMap.put(alias, x.getExpr().toString()); + putAliasMap(aliasMap, alias, x.getExpr().toString()); } else { - aliasMap.put(alias, null); + putAliasMap(aliasMap, alias, null); } } @@ -1124,7 +1126,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementUpdateCount(); Map aliasMap = getAliasMap(); - aliasMap.put(ident, ident); + putAliasMap(aliasMap, ident, ident); } else { x.getTableSource().accept(this); } @@ -1144,7 +1146,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setCurrentTable(tableName); if (x.getAlias() != null) { - this.aliasMap.put(x.getAlias(), tableName); + putAliasMap(this.aliasMap, x.getAlias(), tableName); } TableStat stat = getTableStat(tableName); @@ -1328,9 +1330,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementDropIndexCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - aliasMap.put(ident, ident); - } + putAliasMap(aliasMap, ident, ident); } return false; } @@ -1348,9 +1348,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { stat.incrementDropIndexCount(); Map aliasMap = getAliasMap(); - if (aliasMap != null) { - aliasMap.put(table, table); - } + putAliasMap(aliasMap, table, table); for (SQLSelectOrderByItem item : x.getItems()) { SQLExpr expr = item.getExpr(); diff --git a/src/main/java/com/alibaba/druid/stat/TableStat.java b/src/main/java/com/alibaba/druid/stat/TableStat.java index 45cd18f44c..a05f4f78d4 100644 --- a/src/main/java/com/alibaba/druid/stat/TableStat.java +++ b/src/main/java/com/alibaba/druid/stat/TableStat.java @@ -394,6 +394,8 @@ public class TableStat { private boolean join; private Map attributes = new HashMap(); + + private transient String fullName; public Column(){ @@ -410,6 +412,19 @@ public class TableStat { public void setTable(String table) { this.table = table; + this.fullName = null; + } + + public String getFullName() { + if (fullName == null) { + if (table != null) { + fullName = name; + } else { + fullName = table + '.' + name; + } + } + + return fullName; } public boolean isWhere() { @@ -458,6 +473,7 @@ public class TableStat { public void setName(String name) { this.name = name; + this.fullName = null; } public Map getAttributes() { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest.java index 6492ec5626..7b45b7ae4e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest.java @@ -40,8 +40,9 @@ public class MySqlAlterTableTest extends TestCase { MySqlStatementParser parser = new MySqlStatementParser(sql); SQLStatement stmt = parser.parseStatementList().get(0); parser.match(Token.EOF); - String output = SQLUtils.toMySqlString(stmt); - Assert.assertEquals("ALTER TABLE `test`.`tb1`\n\tCHARACTER SET = utf8, COLLATE = utf8_general_ci", output); + + Assert.assertEquals("ALTER TABLE `test`.`tb1`\n\tCHARACTER SET = utf8, COLLATE = utf8_general_ci", SQLUtils.toMySqlString(stmt)); + Assert.assertEquals("alter table `test`.`tb1`\n\tcharacter set = utf8, collate = utf8_general_ci", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); } public void test_alter_2() throws Exception { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest5.java new file mode 100644 index 0000000000..e7a61d0376 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest5.java @@ -0,0 +1,34 @@ +/* + * Copyright 1999-2101 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.odps; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; + +import junit.framework.TestCase; + +public class OdpsSelectTest5 extends TestCase { + + public void test_distribute_by() throws Exception { + String sql = "select * from t where ds='20160303' and hour in ('18') ";// + Assert.assertEquals("SELECT *" + + "\nFROM t" + + "\nWHERE ds = '20160303'" + + "\n\tAND hour IN ('18')", SQLUtils.formatOdps(sql)); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java index 2dc8e70c82..ff3252700d 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest6.java @@ -28,14 +28,11 @@ import com.alibaba.druid.stat.TableStat; public class OracleMergeTest6 extends OracleTest { public void test_0() throws Exception { - String sql = "MERGE INTO console_stb_ipstatus T1 " - + // - "USING (SELECT '02222601005592002863423471' AS stbid FROM dual) T2 " - + // - "ON ( T1.stbid=T2.stbid) " - + // - "WHEN MATCHED THEN update set t1.ip='10.104.131.175',t1.port='6666',t1.status = 1, t1.time = to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss') " - + // + String sql = "MERGE INTO console_stb_ipstatus T1 " + // + "USING (SELECT '02222601005592002863423471' AS stbid FROM dual) T2 " + // + "ON ( T1.stbid=T2.stbid) " + // + "WHEN MATCHED THEN " + // + "update set t1.ip='10.104.131.175',t1.port='6666',t1.status = 1, t1.time = to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss') " + // "WHEN NOT MATCHED THEN insert (id, stbid, ip, port, time, firsttime, status) " + // "values (CONSOLE_SEQ.nextval,'02222601005592002863423471','10.104.131.175','6666',to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss'),to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss'),1) "; diff --git a/src/test/java/com/alibaba/druid/test/OdpsSelectTest6.java b/src/test/java/com/alibaba/druid/test/OdpsSelectTest6.java new file mode 100644 index 0000000000..2ceb0278a8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/test/OdpsSelectTest6.java @@ -0,0 +1,53 @@ +/* + * Copyright 1999-2101 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.test; + +import java.io.File; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser; +import com.alibaba.druid.sql.parser.SQLStatementParser; + +import junit.framework.TestCase; + +public class OdpsSelectTest6 extends TestCase { + + public void test_distribute_by() throws Exception { + File file = new File("/Users/wenshao/Downloads/datasafe_base_dev.udf_test.txt"); + String sql = FileUtils.readFileToString(file, "UTF-8"); + + + SQLStatementParser parser = new OdpsStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + +// Assert.assertEquals("SELECT *" +// + "\nFROM t" +// + "\nWHERE ds = '20160303'" +// + "\n\tAND hour IN ('18')", SQLUtils.formatOdps(sql)); + } + +}