diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java b/core/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java index 6269f3282d..1edce8acd2 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.dialect.db2.parser; +import com.alibaba.druid.DbType; import com.alibaba.druid.sql.parser.DialectFeature; import com.alibaba.druid.sql.parser.Keywords; import com.alibaba.druid.sql.parser.Lexer; @@ -67,7 +68,7 @@ public DB2Lexer(String input) { } public DB2Lexer(String input, SQLParserFeature... features) { - super(input); + super(input, DbType.db2); for (SQLParserFeature feature : features) { config(feature, true); } diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index 0d7ec8ba2a..8112fd2648 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -1088,7 +1088,7 @@ public boolean visit(OracleDatetimeExpr x) { if (timeZone instanceof SQLIdentifierExpr) { if (((SQLIdentifierExpr) timeZone).getName().equalsIgnoreCase("LOCAL")) { - print0(ucase ? " AT LOCAL" : "alter session set "); + print0(ucase ? " AT LOCAL" : " at local"); return false; } } @@ -2991,7 +2991,7 @@ public boolean visit(SQLMergeStatement.WhenDelete x) { } SQLExpr where = x.getWhere(); if (where != null) { - print0(ucase ? " WHERE " : " where"); + print0(ucase ? " WHERE " : " where "); printExpr(where, parameterized); } return false; diff --git a/core/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java b/core/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java index 440a5416c9..5ab886f82a 100644 --- a/core/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java +++ b/core/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java @@ -1699,10 +1699,14 @@ static void extractColumns(SchemaResolveVisitor visitor, return; // skip } } - + String subQueryAlias = from.getAlias(); for (SQLSelectItem subSelectItem : subSelectList) { String alias = subSelectItem.computeAlias(); - columns.add(new SQLSelectItem(new SQLIdentifierExpr(alias))); + if (subQueryAlias != null) { + columns.add(new SQLSelectItem(new SQLPropertyExpr(subQueryAlias, alias))); + } else { + columns.add(new SQLSelectItem(new SQLIdentifierExpr(alias))); + } } } else if (from instanceof SQLUnionQueryTableSource) { SQLSelectQueryBlock firstQueryBlock = ((SQLUnionQueryTableSource) from).getUnion().getFirstQueryBlock(); diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/resolve/Resolve_AllColumn_Test.java b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/resolve/Resolve_AllColumn_Test.java index 9613414681..79cc03c4c0 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/resolve/Resolve_AllColumn_Test.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/resolve/Resolve_AllColumn_Test.java @@ -83,4 +83,24 @@ public void test_resolve_2() throws Exception { "\tFROM t_emp\n" + ") x", stmt.toString()); } + + public void test_resolve_3() throws Exception { + SchemaRepository repository = new SchemaRepository(DbType.mysql); + + repository.acceptDDL("create table t_emp(emp_id bigint, name varchar(20));"); + repository.acceptDDL("create table t_emp_copy(emp_copy_id bigint, name_copy varchar(20));"); + + SQLStatement stmt = SQLUtils.parseSingleMysqlStatement("select * from (select * from t_emp) a, (select * from t_emp_copy) b where a.emp_id = b.emp_copy_id"); + repository.resolve(stmt, SchemaResolveVisitor.Option.ResolveAllColumn); + + assertEquals("SELECT a.emp_id, a.name, b.emp_copy_id, b.name_copy\n" + + "FROM (\n" + + "\tSELECT emp_id, name\n" + + "\tFROM t_emp\n" + + ") a, (\n" + + "\t\tSELECT emp_copy_id, name_copy\n" + + "\t\tFROM t_emp_copy\n" + + "\t) b\n" + + "WHERE a.emp_id = b.emp_copy_id", stmt.toString()); + } } diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_MergeWhenDelete.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_MergeWhenDelete.java new file mode 100644 index 0000000000..6776efe0f3 --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_MergeWhenDelete.java @@ -0,0 +1,43 @@ +/* + * Copyright 1999-2018 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.visitor; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import junit.framework.TestCase; + +import java.util.List; + +public class OracleOutputVisitorTest_MergeWhenDelete extends TestCase { + public void test_0() throws Exception { + String sql = "merge into target_table t using source_table s on (t.id = s.id) " + + "when matched then update set t.name = s.name " + + "where t.status = 'ACTIVE' " + + "delete where t.status = 'INACTIVE'" + + "when not matched then insert (id, name) values " + + "(s.id, s.name) where s.status = 'ACTIVE';"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + assertEquals(1, statementList.size()); + + String formatSql = SQLUtils.toSQLString(stmt, DbType.oracle, new SQLUtils.FormatOption(false, false, false)); + assertEquals("merge into target_table t using source_table s on (t.id = s.id) when matched then update set t.name = s.name where t.status = 'ACTIVE' delete where t.status = 'INACTIVE' when not matched then insert (id, name) values (s.id, s.name) where s.status = 'ACTIVE';", formatSql); + } +} diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_timestampAtLocal.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_timestampAtLocal.java new file mode 100644 index 0000000000..6d8ef06590 --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleOutputVisitorTest_timestampAtLocal.java @@ -0,0 +1,38 @@ +/* + * Copyright 1999-2018 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.visitor; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import junit.framework.TestCase; + +import java.util.List; + +public class OracleOutputVisitorTest_timestampAtLocal extends TestCase { + public void test_0() throws Exception { + String sql = "INSERT INTO ALL_TYPE_FIELDS (\"TIMESTAMP WITH LOCAL TIME ZONE\", \"TIMESTAMP WITH LOCAL TIME ZONE\") VALUES (SYSTIMESTAMP AT LOCAL, SYSTIMESTAMP AT TIME ZONE 'UTC')"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + assertEquals(1, statementList.size()); + + String formatSql = SQLUtils.toSQLString(stmt, DbType.oracle, new SQLUtils.FormatOption(false, false, false)); + assertEquals("insert into ALL_TYPE_FIELDS (\"TIMESTAMP WITH LOCAL TIME ZONE\", \"TIMESTAMP WITH LOCAL TIME ZONE\") values (SYSTIMESTAMP at local, SYSTIMESTAMP at time zone 'UTC')", formatSql); + } +}