From aa7c29ceeb7470476c6c6c55ed7f0f1320a121c0 Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 19 Sep 2016 15:56:39 +0800 Subject: [PATCH] improved postgresql sql parser support. support Polygon Operators. issue #1391 --- .../druid/sql/ast/expr/SQLBinaryOperator.java | 1 + .../com/alibaba/druid/sql/parser/Lexer.java | 3 ++ .../druid/sql/parser/SQLExprParser.java | 9 ++++ .../com/alibaba/druid/sql/parser/Token.java | 1 + .../bvt/sql/postgresql/PGSelectTest41.java | 52 +++++++++++++++++++ 5 files changed, 66 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest41.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java index 1255bd1de1..144b00fbdf 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java @@ -65,6 +65,7 @@ public enum SQLBinaryOperator { POSIX_Regular_Not_Match_POSIX_Regular_Match_Insensitive("!~*", 110), Array_Contains("@>", 110), Array_ContainedBy("<@", 110), + SAME_AS("~=", 110), RLike("RLIKE", 110), NotRLike("NOT RLIKE", 110), 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 d1eb4a4343..cb2a5f3493 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -650,6 +650,9 @@ public class Lexer { if (ch == '*') { scanChar(); token = Token.TILDE_STAR; + } else if (ch == '=') { + scanChar(); + token = Token.TILDE_EQ; // postsql } else { token = Token.TILDE; } 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 8d37b7fcdc..7ac3fb9229 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -51,6 +51,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLUnique; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; import com.alibaba.druid.util.JdbcConstants; public class SQLExprParser extends SQLParser { @@ -1534,6 +1535,14 @@ public class SQLExprParser extends SQLParser { rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match_POSIX_Regular_Match_Insensitive, rightExp, getDbType()); + } else if (lexer.token() == Token.TILDE_EQ) { + lexer.nextToken(); + + rightExp = equality(); + + rightExp = relationalRest(rightExp); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SAME_AS, rightExp, getDbType()); } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 0a01ba326b..11d59be845 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -303,6 +303,7 @@ public enum Token { BANG_TILDE_STAR("!~*"), TILDE("~"), TILDE_STAR("~*"), + TILDE_EQ("~="), QUES("?"), COLON(":"), COLONCOLON(":"), diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest41.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest41.java new file mode 100644 index 0000000000..64df20d1ec --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest41.java @@ -0,0 +1,52 @@ +/* + * Copyright 1999-2101 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.postgresql; + +import com.alibaba.druid.sql.PGTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor; +import org.junit.Assert; + +import java.util.List; + +public class PGSelectTest41 extends PGTest { + + public void test_0() throws Exception { + String sql = "select polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals("SELECT polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'", SQLUtils.toPGString(stmt)); + + Assert.assertEquals("select polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getTables().size()); + } +}