From c2a16d900cc96b8fc59f1af9fecd1057d0c35f99 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 15 Oct 2011 02:09:32 +0000 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81OracleOuter=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://code.alibabatech.com/svn/druid/trunk@967 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../sql/ast/expr/SQLMethodInvokeExpr.java | 1 - .../oracle/parser/OracleExprParser.java | 22 +++++++++++++- .../druid/sql/parser/SQLExprParser.java | 1 + .../druid/bvt/sql/oracle/OracleOuterTest.java | 29 +++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleOuterTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java index a49ddd3e5f..21bf99b8ce 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLMethodInvokeExpr.java @@ -36,7 +36,6 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements Serializable { } public SQLMethodInvokeExpr(String methodName){ - this.methodName = methodName; } 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 85f8b7a796..f28faa0dfc 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 @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; @@ -41,6 +42,7 @@ 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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; @@ -275,7 +277,25 @@ public class OracleExprParser extends SQLExprParser { expr = interval; } - return super.primaryRest(expr); + SQLExpr restExpr = super.primaryRest(expr); + + if (restExpr != expr && restExpr instanceof SQLMethodInvokeExpr) { + SQLMethodInvokeExpr methodInvoke = (SQLMethodInvokeExpr) restExpr; + if (methodInvoke.getParameters().size() == 1) { + SQLExpr paramExpr = methodInvoke.getParameters().get(0); + if (paramExpr instanceof SQLIdentifierExpr && "+".equals(((SQLIdentifierExpr) paramExpr).getName())) { + OracleOuterExpr outerExpr = new OracleOuterExpr(); + if (methodInvoke.getOwner() == null) { + outerExpr.setExpr(new SQLIdentifierExpr(methodInvoke.getMethodName())); + } else { + outerExpr.setExpr(new SQLPropertyExpr(methodInvoke.getOwner(), methodInvoke.getMethodName())); + } + return outerExpr; + } + } + } + + return restExpr; } protected SQLExpr dotRest(SQLExpr expr) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 374b653022..6bf87eb4df 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -484,6 +484,7 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name); + methodInvokeExpr.setOwner(expr); if (lexer.token() == Token.RPAREN) { lexer.nextToken(); } else { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleOuterTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleOuterTest.java new file mode 100644 index 0000000000..7805dc2b14 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleOuterTest.java @@ -0,0 +1,29 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.test.TestUtils; + +public class OracleOuterTest extends TestCase { + + public void test_oracle() throws Exception { + String sql = "SELECT employee_id, manager_id\n" + "FROM employees\n" + + "WHERE employees.manager_id(+) = employees.employee_id;"; + + String expect = "SELECT employee_id, manager_id\n" + "FROM employees\n" + + "WHERE employees.manager_id(+) = employees.employee_id;\n"; + + OracleStatementParser parser = new OracleStatementParser(sql); + SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatementList().get(0); + + String text = TestUtils.outputOracle(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } + +}