From 41af4e97a89926aa19eec4923ba42019d28e2758 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Wed, 15 Jul 2015 13:16:18 +0800 Subject: [PATCH] improved odps sql parser, support udf --- .../sql/dialect/odps/parser/OdpsExprParser.java | 10 ++++++++++ .../druid/sql/dialect/odps/parser/OdpsLexer.java | 9 +++++++++ .../dialect/odps/visitor/OdpsOutputVisitor.java | 13 +++++++++++++ .../alibaba/druid/bvt/sql/odps/OdpsUDFTest.java | 16 ++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsUDFTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java index 4f679bcaf1..38e3d86e5f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java @@ -21,6 +21,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem; import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.Token; @@ -111,4 +112,13 @@ public class OdpsExprParser extends SQLExprParser { return item; } + + public SQLExpr primaryRest(SQLExpr expr) { + if(lexer.token() == Token.COLON) { + lexer.nextToken(); + expr = dotRest(expr); + return expr; + } + return super.primaryRest(expr); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java index c8e8d6ecf5..d89f6e9968 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsLexer.java @@ -301,4 +301,13 @@ public class OdpsLexer extends Lexer { } } + public void scanVariable() { + if (ch == ':') { + token = Token.COLON; + ch = charAt(++pos); + return; + } + + super.scanVariable(); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index e7e6cc3127..be8636405f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLCaseExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; @@ -621,4 +622,16 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis return false; } + + public boolean visit(SQLMethodInvokeExpr x) { + if (x.getOwner() != null) { + x.getOwner().accept(this); + print(":"); + } + print(x.getMethodName()); + print("("); + printAndAccept(x.getParameters(), ", "); + print(")"); + return false; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsUDFTest.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsUDFTest.java new file mode 100644 index 0000000000..3c26f99dd4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsUDFTest.java @@ -0,0 +1,16 @@ +package com.alibaba.druid.bvt.sql.odps; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; + +import junit.framework.TestCase; + +public class OdpsUDFTest extends TestCase { + + public void test_if() throws Exception { + String sql = "select secods:ip_region('192.168.1.1', 'city') from dual"; + Assert.assertEquals("SELECT secods:ip_region('192.168.1.1', 'city')" // + + "\nFROM dual", SQLUtils.formatOdps(sql)); + } +}