diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java index 8b5006cc1c..ddf4eba5d7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleOutputVisitor.java @@ -693,6 +693,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print("("); incrementIndent(); x.getSelect().accept(this); + println(); decrementIndent(); print(")"); 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 80f838b8f3..4ad2f1166c 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 @@ -31,6 +31,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateTimeUnit; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType; @@ -142,6 +143,9 @@ public class OracleExprParser extends SQLExprParser { lexer.nextToken(); return primaryRest(doubleExpr); + case TABLE: + lexer.nextToken(); + return primaryRest(new SQLIdentifierExpr("TABLE")); case PLUS: lexer.nextToken(); switch (lexer.token()) { @@ -211,6 +215,24 @@ public class OracleExprParser extends SQLExprParser { } } + + public SQLExpr primaryRest(SQLExpr expr) throws ParserException { + if (lexer.token() == Token.MONKEYS_AT) { + lexer.nextToken(); + + OracleDbLinkExpr dblink = new OracleDbLinkExpr(); + dblink.setExpr(expr); + + String link = lexer.stringVal(); + accept(Token.IDENTIFIER); + dblink.setDbLink(link); + + expr = dblink; + } + + return super.primaryRest(expr); + } + public OracleDateExpr parseDate() { accept(Token.DATE); 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 734da8432d..f5b38f507b 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 @@ -1,10 +1,13 @@ package com.alibaba.druid.sql.dialect.oracle.parser; +import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar; + import java.util.HashMap; import java.util.Map; import com.alibaba.druid.sql.parser.Keywords; import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.SQLParseException; import com.alibaba.druid.sql.parser.Token; public class OracleLexer extends Lexer { @@ -102,6 +105,47 @@ public class OracleLexer extends Lexer { super(input); super.keywods = DEFAULT_ORACLE_KEYWORDS; } + + public void scanVariable() { + if (ch == '@') { + scanChar(); + token = Token.MONKEYS_AT; + return; + } + + if (ch != ':') { + throw new SQLParseException("illegal variable"); + } + + int hash = ch; + + np = bp; + sp = 1; + char ch; + + for (;;) { + ch = buf[++bp]; + + if (!isIdentifierChar(ch)) { + break; + } + + hash = 31 * hash + ch; + + sp++; + continue; + } + + this.ch = buf[bp]; + + stringVal = symbolTable.addSymbol(buf, np, sp, hash); + Token tok = keywods.getKeyword(stringVal); + if (tok != null) { + token = tok; + } else { + token = Token.IDENTIFIER; + } + } public void scanComment() { if (ch != '/') { 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 1296c7152c..43370dfb12 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -248,7 +248,6 @@ public class Lexer { throw new SQLParseException("TODO"); // TODO case '@': scanVariable(); - token = Token.VARIANT; return; case '/': int nextChar = buf[bp + 1]; @@ -508,12 +507,7 @@ public class Lexer { this.ch = buf[bp]; stringVal = symbolTable.addSymbol(buf, np, sp, hash); - Token tok = keywods.getKeyword(stringVal); - if (tok != null) { - token = tok; - } else { - token = Token.IDENTIFIER; - } + token = Token.VARIANT; } public void scanComment() { 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 aabb6bfeb8..d70863f027 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -399,9 +399,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { } else { print("("); incrementIndent(); - + println(); x.getSubQuery().accept(this); - + println(); decrementIndent(); print(")"); } @@ -858,8 +858,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { print("("); incrementIndent(); x.getSelect().accept(this); + println(); decrementIndent(); print(")"); + + if (x.getAlias() != null) { + print(' '); + print(x.getAlias()); + } return false; } diff --git a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java index 7f62f45f4e..0ef16e2cb1 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java @@ -16,7 +16,7 @@ import com.alibaba.druid.util.JdbcUtils; public class OracleSQLParserResourceTest extends TestCase { public void test_0() throws Exception { - for (int i = 0; i <= 46; ++i) { + for (int i = 0; i <= 52; ++i) { String resource = "bvt/parser/oracle-" + i + ".txt"; exec_test(resource); } diff --git a/src/test/resources/bvt/parser/mysql-3.txt b/src/test/resources/bvt/parser/mysql-3.txt index 0dc19860db..b5e781797b 100644 --- a/src/test/resources/bvt/parser/mysql-3.txt +++ b/src/test/resources/bvt/parser/mysql-3.txt @@ -8,4 +8,5 @@ SELECT COUNT(*) FROM (SELECT COUNT(*) FROM m_web_uri_m5 WHERE monitor_item_id = ? AND app_num = ? AND inst_num = ? AND service_tag = ? AND monitor_item_id = ? AND collect_date >= ? AND collect_date < ? AND (1 = 0 OR c_URI IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83)) - GROUP BY c_URI) \ No newline at end of file + GROUP BY c_URI + ) A \ No newline at end of file diff --git a/src/test/resources/bvt/parser/mysql-6.txt b/src/test/resources/bvt/parser/mysql-6.txt index a3e40e062d..a6edb8a5d9 100644 --- a/src/test/resources/bvt/parser/mysql-6.txt +++ b/src/test/resources/bvt/parser/mysql-6.txt @@ -42,4 +42,5 @@ FROM (SELECT a.activity_offer_id AS adResourceId, a.title AS adResourceName, a.b , c.position_name AS positionName, c.charge_setting AS feeRegulation, a.priority_weight AS priorityWeight, a.audit_state AS adResourceState, 0 AS adResourceType , a.gmt_create, a.refuse_remark FROM q_activity_offer_enroll a, q_custinfo b, q_activity_position c - WHERE a.custid = b.custid AND a.activity_position_id = c.activity_position_id AND c.activity_id = ?) + WHERE a.custid = b.custid AND a.activity_position_id = c.activity_position_id AND c.activity_id = ? + ) a diff --git a/src/test/resources/bvt/parser/mysql-8.txt b/src/test/resources/bvt/parser/mysql-8.txt index 7b6dc81ad2..6530e84e30 100644 --- a/src/test/resources/bvt/parser/mysql-8.txt +++ b/src/test/resources/bvt/parser/mysql-8.txt @@ -12,5 +12,7 @@ FROM c_examinepaper a, (SELECT examine_id WHERE level_limit = ? AND status = 1 MINUS SELECT DISTINCT examine_id - FROM course) + FROM course + ) b WHERE a.examine_id = b.examine_id + diff --git a/src/test/resources/bvt/parser/oracle-11.txt b/src/test/resources/bvt/parser/oracle-11.txt index 078d35a639..4577657905 100644 --- a/src/test/resources/bvt/parser/oracle-11.txt +++ b/src/test/resources/bvt/parser/oracle-11.txt @@ -5,8 +5,10 @@ UPDATE employees SET salary = WHERE last_name = 'Chung'; --------------------------- UPDATE employees -SET salary = (SELECT salary +SET salary = ( + SELECT salary FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '2' MINUTE) - WHERE last_name = 'Chung') + WHERE last_name = 'Chung' + ) WHERE last_name = 'Chung'; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-15.txt b/src/test/resources/bvt/parser/oracle-15.txt index 82e03db175..175e5f7467 100644 --- a/src/test/resources/bvt/parser/oracle-15.txt +++ b/src/test/resources/bvt/parser/oracle-15.txt @@ -27,12 +27,17 @@ FROM (SELECT A.*, rownum AS cnt , E.DESCRIPTION AS CUSTSTATNAME, F.DESCRIPTION AS B2BCUSTTYPENAME, NULL AS CUSTSERVICERNAME, G.DESCRIPTION AS B2BVALIDFLAGNAME, A.VALIDFLAG FROM Q_CUSTOMERS A, Q_CUSTINFO C, (SELECT * FROM Q_DOMAINCDSTRING - WHERE DOMAINCD = 'CUSTOMERS_CUSTSTAT') E, (SELECT * + WHERE DOMAINCD = 'CUSTOMERS_CUSTSTAT' + ) E, (SELECT * FROM Q_DOMAINCDSTRING - WHERE DOMAINCD = 'CUSTOMERS_B2BCUSTTYPE') F, (SELECT * + WHERE DOMAINCD = 'CUSTOMERS_B2BCUSTTYPE' + ) F, (SELECT * FROM Q_DOMAINCDSTRING - WHERE DOMAINCD = 'CUSTOMERS_B2BVALIDFLAG') G + WHERE DOMAINCD = 'CUSTOMERS_B2BVALIDFLAG' + ) G WHERE A.CUSTID = C.CUSTID AND A.CUSTSTAT = CODE(+) AND A.B2BCUSTTYPE = CODE(+) AND A.b2bValidFlag = CODE(+) AND A.MEMBERID = ? - ORDER BY A.CUSTID DESC) A - WHERE ROWNUM < ?) -WHERE CNT > ?; \ No newline at end of file + ORDER BY A.CUSTID DESC + ) A + WHERE ROWNUM < ? + ) +WHERE CNT > ?; diff --git a/src/test/resources/bvt/parser/oracle-16.txt b/src/test/resources/bvt/parser/oracle-16.txt index 25e8909bee..2275d5be00 100644 --- a/src/test/resources/bvt/parser/oracle-16.txt +++ b/src/test/resources/bvt/parser/oracle-16.txt @@ -14,6 +14,8 @@ FROM (SELECT A.*, ROWNUM AS CNT FROM (SELECT ID, CLASSTYPE, KEY, VALUE FROM Q_SYSCONSTANTS WHERE CLASSTYPE = ? - ORDER BY ID DESC) A - WHERE ROWNUM < ?) + ORDER BY ID DESC + ) A + WHERE ROWNUM < ? + ) WHERE CNT > ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-17.txt b/src/test/resources/bvt/parser/oracle-17.txt index 49042986e9..3eec099c14 100644 --- a/src/test/resources/bvt/parser/oracle-17.txt +++ b/src/test/resources/bvt/parser/oracle-17.txt @@ -31,7 +31,9 @@ FROM (SELECT custid, memberid, createtime, planid, auditstate , p.createid, p.custappdate, p.modifytime, p.gmtcreate, p.executeState , c.custname, row_number() OVER ( ORDER BY p.memberid ASC, p.createtime DESC) AS cnt, p.planbatchid FROM q_plan p, q_custinfo c - WHERE p.custid = c.custid AND p.applytype = 0 AND p.createtime BETWEEN to_date(?, 'yyyy-mm-dd') AND to_date(?, 'yyyy-mm-dd hh24:mi:ss') AND (p.auditstate = ? AND p.executestate = 1) AND auditstate != 3 AND p.memberid IN (?)) t - WHERE t.cnt < ?) k + WHERE p.custid = c.custid AND p.applytype = 0 AND p.createtime BETWEEN to_date(?, 'yyyy-mm-dd') AND to_date(?, 'yyyy-mm-dd hh24:mi:ss') AND (p.auditstate = ? AND p.executestate = 1) AND auditstate != 3 AND p.memberid IN (?) + ) t + WHERE t.cnt < ? + ) k WHERE k.cnt > ? -ORDER BY memberid ASC, createtime DESC; +ORDER BY memberid ASC, createtime DESC; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-19.txt b/src/test/resources/bvt/parser/oracle-19.txt index c0683488ef..7421c95ef5 100644 --- a/src/test/resources/bvt/parser/oracle-19.txt +++ b/src/test/resources/bvt/parser/oracle-19.txt @@ -15,6 +15,8 @@ FROM (SELECT rownum AS rnm, z.* FROM (SELECT name AS value, value AS KEY FROM app_resource_cae WHERE is_deleted = 'n' AND type = 'fuse' - ORDER BY ordering) z - WHERE rownum < ?) + ORDER BY ordering + ) z + WHERE rownum < ? + ) WHERE rnm >= ?; diff --git a/src/test/resources/bvt/parser/oracle-2.txt b/src/test/resources/bvt/parser/oracle-2.txt index f5cc399f82..215b19981a 100644 --- a/src/test/resources/bvt/parser/oracle-2.txt +++ b/src/test/resources/bvt/parser/oracle-2.txt @@ -3,5 +3,6 @@ SELECT employee_id FROM (SELECT employee_id+1 AS employee_id FROM employees) --------------------------- SELECT employee_id FROM (SELECT employee_id + 1 AS employee_id - FROM employees) + FROM employees + ) FOR UPDATE; diff --git a/src/test/resources/bvt/parser/oracle-21.txt b/src/test/resources/bvt/parser/oracle-21.txt index 55489ceb26..facadd42ee 100644 --- a/src/test/resources/bvt/parser/oracle-21.txt +++ b/src/test/resources/bvt/parser/oracle-21.txt @@ -21,9 +21,12 @@ FROM (SELECT rownum AS rnm, z.* FROM (SELECT DISTINCT tt.id AS use_less_id, tt.* FROM (SELECT t.*, rct.parent_id, RCT.NAME AS trunk_name FROM rc_clot_info t, rc_clot_trunk rct - WHERE t.is_deleted = 'n' AND t.trunk_id = rct.id) tt + WHERE t.is_deleted = 'n' AND t.trunk_id = rct.id + ) tt START WITH trunk_name = 'rc.mf.Caesar' CONNECT BY PRIOR parent_id = trunk_id - ORDER BY load_order NULLS LAST) z - WHERE rownum < ?) + ORDER BY load_order NULLS LAST + ) z + WHERE rownum < ? + ) WHERE rnm >= ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-22.txt b/src/test/resources/bvt/parser/oracle-22.txt index 920fe82d29..da7041d143 100644 --- a/src/test/resources/bvt/parser/oracle-22.txt +++ b/src/test/resources/bvt/parser/oracle-22.txt @@ -33,7 +33,11 @@ FROM (SELECT rownum AS rnm, z.* UNION ALL SELECT lower(b.role_name) || '#' || a.permission_id, 'y' FROM app_role_permission A, app_role_base_role B - WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.role_name = b.base_role_name)) c - ORDER BY c.KEY) z - WHERE rownum < ?) + WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.role_name = b.base_role_name + ) + ) c + ORDER BY c.KEY + ) z + WHERE rownum < ? + ) WHERE rnm >= ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-23.txt b/src/test/resources/bvt/parser/oracle-23.txt index 753e41a83b..e9e19e16a5 100644 --- a/src/test/resources/bvt/parser/oracle-23.txt +++ b/src/test/resources/bvt/parser/oracle-23.txt @@ -13,5 +13,6 @@ SELECT nodeId, nodeName, taskflowName, taskflowVersion FROM (SELECT /*+use_hash(n f) ordered*/ n.ID AS nodeId, n.name AS nodeName, f.name AS taskflowName, f.version AS taskflowVersion FROM "HT_TASK_FLOW_NODE_WA_2" n, "HT_TASK_FLOW_WA_2" f WHERE n.owner = ? AND (n.STATUS IN (?) AND n.GMT_MODIFIED < ? AND n.IS_AUTO = 'Y' AND n.task_flow_id = f.id) - ORDER BY f.priority DESC NULLS LAST, f.gmt_create ASC) + ORDER BY f.priority DESC NULLS LAST, f.gmt_create ASC + ) WHERE rownum < ?; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-24.txt b/src/test/resources/bvt/parser/oracle-24.txt index 62b61b0342..4b810a6732 100644 --- a/src/test/resources/bvt/parser/oracle-24.txt +++ b/src/test/resources/bvt/parser/oracle-24.txt @@ -19,5 +19,6 @@ SELECT INDUSTRY_ID, sale_type, service_type, RISK_TYPE, to_char(gmt_create, 'yyy FROM (SELECT /*+use_hash(a b c) ordered*/ b.service_type, b.RISK_TYPE, b.sale_type, b.INDUSTRY_ID, b.GMT_CREATE , row_number() OVER (PARTITION BY (b.service_type, b.RISK_TYPE, b.sale_type, b.INDUSTRY_ID) ORDER BY b.GMT_CREATE) AS xh FROM "HT_TASK_FLOW_WA_2" a, "HT_TASK_FLOW_BIZ_WA_2" b, "HT_TASK_FLOW_NODE_WA_2" c - WHERE a.id = b.task_flow_id AND a.id = c.task_flow_id AND c.status = 'waiting' AND c.IS_AUTO = 'N' AND a.status = 'running' AND c.name IN (?)) + WHERE a.id = b.task_flow_id AND a.id = c.task_flow_id AND c.status = 'waiting' AND c.IS_AUTO = 'N' AND a.status = 'running' AND c.name IN (?) + ) WHERE xh = 1; diff --git a/src/test/resources/bvt/parser/oracle-25.txt b/src/test/resources/bvt/parser/oracle-25.txt index ebbf8e01ee..f95160324d 100644 --- a/src/test/resources/bvt/parser/oracle-25.txt +++ b/src/test/resources/bvt/parser/oracle-25.txt @@ -59,9 +59,13 @@ FROM (SELECT row_.*, rownum AS rownum_ , sus.OBJECT_TYPE AS OBJECT_TYPE, sus.CONFIRM_TYPE AS CONFIRM_TYPE, sus.OPERATOR AS OPERATOR, sus.FILTER_TYPE AS FILTER_TYPE, sus.MEMBER_ID AS MEMBER_ID , sus.MEMBER_SEQ AS MEMBER_SEQ, sus.RISK_TYPE AS RISK_TYPE, 'N' AS IS_DRAFT FROM bops_sus_posting sus, ws_product p, member m - WHERE 1 = 1 AND p.company_id = m.company_id AND m.login_id = ? AND (p.sale_type IN (?) AND p.id = sus.object_id)) results) + WHERE 1 = 1 AND p.company_id = m.company_id AND m.login_id = ? AND (p.sale_type IN (?) AND p.id = sus.object_id) + ) results + ) WHERE rn = 1 - ORDER BY gmt_modified DESC) row_ - WHERE rownum <= ?) + ORDER BY gmt_modified DESC + ) row_ + WHERE rownum <= ? + ) WHERE rownum_ >= ?; diff --git a/src/test/resources/bvt/parser/oracle-26.txt b/src/test/resources/bvt/parser/oracle-26.txt index 28065ed7df..c3befb8ea6 100644 --- a/src/test/resources/bvt/parser/oracle-26.txt +++ b/src/test/resources/bvt/parser/oracle-26.txt @@ -16,6 +16,8 @@ FROM (SELECT rownum AS rnm, z.* FROM (SELECT name AS KEY, value FROM app_resource t WHERE t.type = 'VODKA._CTPCLEAN_NIRVANA_URL' AND is_deleted = 'n' - ORDER BY id) z - WHERE rownum < ?) + ORDER BY id + ) z + WHERE rownum < ? + ) WHERE rnm >= ?; diff --git a/src/test/resources/bvt/parser/oracle-3.txt b/src/test/resources/bvt/parser/oracle-3.txt index f5cc399f82..215b19981a 100644 --- a/src/test/resources/bvt/parser/oracle-3.txt +++ b/src/test/resources/bvt/parser/oracle-3.txt @@ -3,5 +3,6 @@ SELECT employee_id FROM (SELECT employee_id+1 AS employee_id FROM employees) --------------------------- SELECT employee_id FROM (SELECT employee_id + 1 AS employee_id - FROM employees) + FROM employees + ) FOR UPDATE; diff --git a/src/test/resources/bvt/parser/oracle-31.txt b/src/test/resources/bvt/parser/oracle-31.txt index 1dd551a17f..05a4f846ce 100644 --- a/src/test/resources/bvt/parser/oracle-31.txt +++ b/src/test/resources/bvt/parser/oracle-31.txt @@ -7,6 +7,7 @@ PIVOT --------------------------- SELECT * FROM (SELECT EXTRACT(YEAR FROM order_date) AS year, order_mode, order_total - FROM orders) + FROM orders + ) PIVOT (SUM(order_total) FOR order_mode IN ('direct' AS Store, 'online' AS Internet)); diff --git a/src/test/resources/bvt/parser/oracle-47.txt b/src/test/resources/bvt/parser/oracle-47.txt new file mode 100644 index 0000000000..ac4a2f0395 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-47.txt @@ -0,0 +1,12 @@ +SELECT * FROM employees + WHERE department_id NOT IN + (SELECT department_id FROM departments + WHERE location_id = 1700) + ORDER BY last_name; +--------------------------- +SELECT * +FROM employees +WHERE department_id NOT IN (SELECT department_id + FROM departments + WHERE location_id = 1700) +ORDER BY last_name; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-48.txt b/src/test/resources/bvt/parser/oracle-48.txt new file mode 100644 index 0000000000..5496862c40 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-48.txt @@ -0,0 +1,6 @@ +SELECT t1.department_id, t2.* FROM hr_info t1, TABLE(t1.people) t2 + WHERE t2.department_id = t1.department_id; +--------------------------- +SELECT t1.department_id, t2.* +FROM hr_info t1, TABLE(t1.people) t2 +WHERE t2.department_id = t1.department_id; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-49.txt b/src/test/resources/bvt/parser/oracle-49.txt new file mode 100644 index 0000000000..36b1e7508c --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-49.txt @@ -0,0 +1,13 @@ +SELECT t1.department_id, t2.* + FROM hr_info t1, TABLE(CAST(MULTISET( + SELECT t3.last_name, t3.department_id, t3.salary + FROM people t3 + WHERE t3.department_id = t1.department_id) + AS people_tab_typ)) t2; +--------------------------- +SELECT t1.department_id, t2.* +FROM hr_info t1, TABLE(CAST(MULTISET(( + SELECT t3.last_name, t3.department_id, t3.salary + FROM people t3 + WHERE t3.department_id = t1.department_id + )) AS people_tab_typ)) t2; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-5.txt b/src/test/resources/bvt/parser/oracle-5.txt index 51cd4438c8..f6fb1a6443 100644 --- a/src/test/resources/bvt/parser/oracle-5.txt +++ b/src/test/resources/bvt/parser/oracle-5.txt @@ -12,6 +12,8 @@ ORDER BY a.department_id; SELECT a.department_id AS "Department", a.num_emp / b.total_count AS "%_Employees", a.sal_sum / b.total_sal AS "%_Salary" FROM (SELECT department_id, COUNT(*) AS num_emp, SUM(salary) AS sal_sum FROM employees - GROUP BY department_id) a, (SELECT COUNT(*) AS total_count, SUM(salary) AS total_sal - FROM employees) b + GROUP BY department_id + ) a, (SELECT COUNT(*) AS total_count, SUM(salary) AS total_sal + FROM employees + ) b ORDER BY a.department_id; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-50.txt b/src/test/resources/bvt/parser/oracle-50.txt new file mode 100644 index 0000000000..f82be34ae2 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-50.txt @@ -0,0 +1,10 @@ +SELECT LPAD(' ',2*(LEVEL-1)) || last_name org_chart, + employee_id, manager_id, job_id + FROM employees + START WITH job_id = 'AD_VP' + CONNECT BY PRIOR employee_id = manager_id; +--------------------------- +SELECT LPAD(' ', 2 * (LEVEL - 1)) || last_name AS org_chart, employee_id, manager_id, job_id +FROM employees +START WITH job_id = 'AD_VP' +CONNECT BY PRIOR employee_id = manager_id; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/oracle-51.txt b/src/test/resources/bvt/parser/oracle-51.txt new file mode 100644 index 0000000000..807e699944 --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-51.txt @@ -0,0 +1,12 @@ +SELECT LPAD(' ',2*(LEVEL-1)) || last_name org_chart, + employee_id, manager_id, job_id + FROM employees + WHERE job_id != 'FI_MGR' + START WITH job_id = 'AD_VP' + CONNECT BY PRIOR employee_id = manager_id; +--------------------------- +SELECT LPAD(' ', 2 * (LEVEL - 1)) || last_name AS org_chart, employee_id, manager_id, job_id +FROM employees +WHERE job_id != 'FI_MGR' +START WITH job_id = 'AD_VP' +CONNECT BY PRIOR employee_id = manager_id; diff --git a/src/test/resources/bvt/parser/oracle-52.txt b/src/test/resources/bvt/parser/oracle-52.txt new file mode 100644 index 0000000000..f61a1c7eeb --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-52.txt @@ -0,0 +1,7 @@ +SELECT last_name, department_name + FROM employees@remote, departments + WHERE employees.department_id = departments.department_id; +--------------------------- +SELECT last_name, department_name +FROM employees@remote, departments +WHERE employees.department_id = departments.department_id;