diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGIntervalExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGIntervalExpr.java new file mode 100644 index 0000000000..b5840689a2 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGIntervalExpr.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.sql.dialect.postgresql.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLExprImpl; +import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +/** + * Created by tianzhen.wtz on 2014/12/29 0029 16:10. + * 类说明: + */ +public class PGIntervalExpr extends SQLExprImpl implements SQLLiteralExpr,PGExpr{ + + private SQLExpr value; + + + public SQLExpr getValue() { + return value; + } + + public void setValue(SQLExpr value) { + this.value = value; + } + + @Override + public void accept0(PGASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } + + @Override + public boolean equals(Object o) { + return false; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + this.accept0((PGASTVisitor) visitor); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGExprParser.java index 64272f67a0..6f8963b423 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGExprParser.java @@ -17,25 +17,9 @@ package com.alibaba.druid.sql.dialect.postgresql.parser; import com.alibaba.druid.sql.ast.SQLDataType; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.expr.SQLBinaryExpr; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLTimestampExpr; -import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; -import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.dialect.postgresql.ast.PGOrderBy; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCircleExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGDateField; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGInetExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGLineSegmentsExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGMacAddrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.*; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.Token; @@ -110,6 +94,18 @@ public class PGExprParser extends SQLExprParser { return super.primary(); } + @Override + protected SQLExpr parseInterval() { + accept(Token.INTERVAL); + PGIntervalExpr intervalExpr=new PGIntervalExpr(); + if (lexer.token() != Token.LITERAL_CHARS) { + return new SQLIdentifierExpr("INTERVAL"); + } + intervalExpr.setValue(new SQLCharExpr(lexer.stringVal())); + lexer.nextToken(); + return intervalExpr; + } + public SQLExpr primaryRest(SQLExpr expr) { if (lexer.token() == Token.COLONCOLON) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java index a72d3485c4..a8b705376c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java @@ -17,18 +17,7 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCircleExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGInetExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGLineSegmentsExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGMacAddrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.*; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; @@ -140,4 +129,8 @@ public interface PGASTVisitor extends SQLASTVisitor { boolean visit(PGLineSegmentsExpr x); + void endVisit(PGIntervalExpr x); + + boolean visit(PGIntervalExpr x); + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java index 1e8ad94639..3dcc0263f8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java @@ -17,18 +17,7 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCircleExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGInetExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGLineSegmentsExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGMacAddrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.*; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; @@ -299,4 +288,14 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi return true; } + @Override + public void endVisit(PGIntervalExpr x) { + + } + + @Override + public boolean visit(PGIntervalExpr x) { + return true; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java index 3895100da7..1a4c8979ab 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java @@ -21,18 +21,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCircleExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGInetExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGLineSegmentsExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGMacAddrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.*; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; @@ -641,7 +630,19 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor x.getValue().accept(this); return false; } - + + @Override + public void endVisit(PGIntervalExpr x) { + + } + + @Override + public boolean visit(PGIntervalExpr x) { + print("INTERVAL "); + x.getValue().accept(this); + return true; + } + @Override public void endVisit(PGLineSegmentsExpr x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java index 93a1e9dff7..081625e84d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java @@ -23,18 +23,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCircleExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGInetExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGLineSegmentsExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGMacAddrExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr; -import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.*; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; @@ -398,7 +387,17 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit public boolean visit(PGLineSegmentsExpr x) { return true; } - + + @Override + public void endVisit(PGIntervalExpr x) { + + } + + @Override + public boolean visit(PGIntervalExpr x) { + return true; + } + @Override public void endVisit(PGLineSegmentsExpr x) { diff --git a/src/test/java/com/alibaba/druid/sql/parser/PGIntervalSQLTest.java b/src/test/java/com/alibaba/druid/sql/parser/PGIntervalSQLTest.java new file mode 100644 index 0000000000..e7a2bccdde --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/parser/PGIntervalSQLTest.java @@ -0,0 +1,37 @@ +package com.alibaba.druid.sql.parser; + +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; +import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * Created by tianzhen.wtz on 2014/12/26 0026 20:44. + * 类说明: + */ +public class PGIntervalSQLTest extends TestCase{ + + + public void testIntrevalSQL(){ + String sql1="select timestamp '2001-09-28 01:00' + interval '23 hours'"; + String sql1Result="SELECT TIMESTAMP '2001-09-28 01:00' + INTERVAL '23 hours'"; + equal(sql1,sql1Result); + + String sql2="select interval '1 day' - interval '1 hour'"; + String sql2Result="SELECT INTERVAL '1 day' - INTERVAL '1 hour'"; + equal(sql2,sql2Result); + + String sql3="select date_part('month', interval '2 years 3 months')"; + String sql3Result="SELECT date_part('month', INTERVAL '2 years 3 months')"; + equal(sql3,sql3Result); + } + + + private void equal(String targetSql,String resultSql){ + PGSQLStatementParser parser=new PGSQLStatementParser(targetSql); + PGSelectStatement statement = parser.parseSelect(); + Assert.assertTrue(statement.toString().equals(resultSql)); + + } + +}