From b52d70d40dc0a47670773153affe974f9fc915ee Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 17 Jul 2017 16:47:03 +0800 Subject: [PATCH] improved odps sql parser. --- .../sql/ast/statement/SQLJoinTableSource.java | 2 + .../druid/sql/parser/SQLSelectParser.java | 14 +++- .../druid/bvt/sql/odps/OdpsSelectTest32.java | 64 +++++++++++++++++++ .../druid/bvt/sql/odps/OdpsSelectTest33.java | 64 +++++++++++++++++++ 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest32.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest33.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java index f57f82e872..c1922fb75c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java @@ -179,6 +179,8 @@ public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplace NATURAL_JOIN("NATURAL JOIN"), // NATURAL_INNER_JOIN("NATURAL INNER JOIN"), // LEFT_OUTER_JOIN("LEFT JOIN"), // + LEFT_SEMI_JOIN("LEFT SEMI JOIN"), // + LEFT_ANTI_JOIN("LEFT ANTI JOIN"), // RIGHT_OUTER_JOIN("RIGHT JOIN"), // FULL_OUTER_JOIN("FULL JOIN"),// STRAIGHT_JOIN("STRAIGHT_JOIN"), // diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index 61d50b8b4c..a54cebbd1b 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -471,12 +471,22 @@ public class SQLSelectParser extends SQLParser { if (lexer.token() == Token.LEFT) { lexer.nextToken(); - if (lexer.token() == Token.OUTER) { + + if (identifierEquals("SEMI")) { lexer.nextToken(); + joinType = SQLJoinTableSource.JoinType.LEFT_SEMI_JOIN; + } else if (identifierEquals("ANTI")) { + lexer.nextToken(); + joinType = SQLJoinTableSource.JoinType.LEFT_ANTI_JOIN; + } else if (lexer.token() == Token.OUTER) { + lexer.nextToken(); + joinType = SQLJoinTableSource.JoinType.LEFT_OUTER_JOIN; + } else { + joinType = SQLJoinTableSource.JoinType.LEFT_OUTER_JOIN; } accept(Token.JOIN); - joinType = SQLJoinTableSource.JoinType.LEFT_OUTER_JOIN; + } else if (lexer.token() == Token.RIGHT) { lexer.nextToken(); if (lexer.token() == Token.OUTER) { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest32.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest32.java new file mode 100644 index 0000000000..2f6daa25a4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest32.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2017 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 com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsSelectTest32 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "SELECT * from mytable1 a LEFT SEMI JOIN mytable2 b on a.id=b.id;";// + assertEquals("SELECT *\n" + + "FROM mytable1 a\n" + + "LEFT SEMI JOIN mytable2 b\n" + + "ON a.id = b.id;", SQLUtils.formatOdps(sql)); + + assertEquals("select *\n" + + "from mytable1 a\n" + + "left semi join mytable2 b\n" + + "on a.id = b.id;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(2, visitor.getTables().size()); + assertEquals(2, visitor.getColumns().size()); + assertEquals(2, visitor.getConditions().size()); + +// System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest33.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest33.java new file mode 100644 index 0000000000..49ef1215bc --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest33.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2017 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 com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsSelectTest33 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "SELECT * from mytable1 a LEFT ANTI JOIN mytable2 b on a.id=b.id;";// + assertEquals("SELECT *\n" + + "FROM mytable1 a\n" + + "LEFT ANTI JOIN mytable2 b\n" + + "ON a.id = b.id;", SQLUtils.formatOdps(sql)); + + assertEquals("select *\n" + + "from mytable1 a\n" + + "left anti join mytable2 b\n" + + "on a.id = b.id;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(2, visitor.getTables().size()); + assertEquals(2, visitor.getColumns().size()); + assertEquals(2, visitor.getConditions().size()); + +// System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +}