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 3d5b90b7c3..32572b498b 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 @@ -58,6 +58,7 @@ public enum SQLBinaryOperator { ILike("ILIKE", 110), NotILike("NOT ILIKE", 110), AT_AT("@@", 110), // postgresql textsearch + SIMILAR_TO("SIMILAR TO", 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 5fc27ccacc..93425c35a3 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -226,6 +226,10 @@ public class Lexer { return token; } + public final String getDbType() { + return this.dbType; + } + public String info() { return this.token + " " + this.stringVal(); } 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 cfbad3574a..551a53866a 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1492,6 +1492,16 @@ public class SQLExprParser extends SQLParser { } } else if (lexer.token() == Token.IN) { expr = inRest(expr); + } else if (JdbcConstants.POSTGRESQL.equals(lexer.dbType) + && identifierEquals("SIMILAR")) { + lexer.nextToken(); + accept(Token.TO); + + rightExp = equality(); + + rightExp = relationalRest(rightExp); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SIMILAR_TO, rightExp, getDbType()); } return expr; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest32.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest32.java new file mode 100644 index 0000000000..78c0777a96 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest32.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 PGSelectTest32 extends PGTest { + + public void test_0() throws Exception { + String sql = "select 'abc' SIMILAR TO '%(b|d)%'"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals("SELECT 'abc' SIMILAR TO '%(b|d)%'", SQLUtils.toPGString(stmt)); + + Assert.assertEquals("select 'abc' similar to '%(b|d)%'", 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()); + } +}