From fe377d2609ae136759c9671c1f72abaa7d66aeb6 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 4 Nov 2014 01:33:30 +0800 Subject: [PATCH] improve sqlparser for pg --- .../sql/ast/statement/SQLSelectQuery.java | 7 +- .../ast/statement/SQLSelectQueryBlock.java | 3 +- .../sql/ast/statement/SQLUnionQuery.java | 3 +- .../postgresql/ast/expr/PGArrayExpr.java | 46 ++++++++ .../postgresql/ast/stmt/PGValuesQuery.java | 27 +++++ .../postgresql/parser/PGExprParser.java | 13 +++ .../dialect/postgresql/parser/PGLexer.java | 1 + .../parser/PGSQLStatementParser.java | 13 ++- .../postgresql/parser/PGSelectParser.java | 10 ++ .../postgresql/visitor/PGASTVisitor.java | 10 ++ .../visitor/PGASTVisitorAdapter.java | 22 ++++ .../postgresql/visitor/PGOutputVisitor.java | 31 ++++++ .../visitor/PGSchemaStatVisitor.java | 22 ++++ .../druid/sql/parser/SQLExprParser.java | 100 +++++++++++------- .../com/alibaba/druid/sql/parser/Token.java | 2 + .../bvt/sql/postgresql/PGDeleteTest6.java | 64 +++++++++++ .../bvt/sql/postgresql/PGDeleteTest7.java | 59 +++++++++++ .../bvt/sql/postgresql/PGDeleteTest8.java | 64 +++++++++++ .../bvt/sql/postgresql/PGSelectTest12.java | 70 ++++++++++++ .../bvt/sql/postgresql/PGSelectTest13.java | 60 +++++++++++ .../bvt/sql/postgresql/PGSelectTest14.java | 64 +++++++++++ .../bvt/sql/postgresql/PGSelectTest15.java | 63 +++++++++++ .../bvt/sql/postgresql/PGSelectTest16.java | 67 ++++++++++++ .../bvt/sql/postgresql/PGSelectTest17.java | 67 ++++++++++++ .../bvt/sql/postgresql/PGSelectTest18.java | 60 +++++++++++ .../bvt/sql/postgresql/PGSelectTest19.java | 59 +++++++++++ .../bvt/sql/postgresql/PGSelectTest20.java | 59 +++++++++++ 27 files changed, 1021 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGArrayExpr.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGValuesQuery.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest6.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest7.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest8.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest12.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest13.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest14.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest15.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest16.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest17.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest18.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest19.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest20.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQuery.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQuery.java index 8ccb07204d..4e6ef71463 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQuery.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQuery.java @@ -15,11 +15,8 @@ */ package com.alibaba.druid.sql.ast.statement; -import com.alibaba.druid.sql.ast.SQLObjectImpl; +import com.alibaba.druid.sql.ast.SQLObject; -public abstract class SQLSelectQuery extends SQLObjectImpl { +public interface SQLSelectQuery extends SQLObject { - public SQLSelectQuery(){ - - } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index 28fef86cf1..e9ed0cab98 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -19,9 +19,10 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLSelectQueryBlock extends SQLSelectQuery { +public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery { protected int distionOption; protected final List selectList = new ArrayList(); diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java index 86e32c6a45..a6b7787e58 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionQuery.java @@ -15,10 +15,11 @@ */ package com.alibaba.druid.sql.ast.statement; +import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLUnionQuery extends SQLSelectQuery { +public class SQLUnionQuery extends SQLObjectImpl implements SQLSelectQuery { private SQLSelectQuery left; private SQLSelectQuery right; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGArrayExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGArrayExpr.java new file mode 100644 index 0000000000..6278121198 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGArrayExpr.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.sql.dialect.postgresql.ast.expr; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor; + +public class PGArrayExpr extends PGExprImpl { + + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + @Override + public void accept0(PGASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, values); + } + visitor.endVisit(this); + } + + @Override + public int hashCode() { + return values.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + PGArrayExpr other = (PGArrayExpr) obj; + if (values == null) { + if (other.values != null) return false; + } else if (!values.equals(other.values)) return false; + return true; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGValuesQuery.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGValuesQuery.java new file mode 100644 index 0000000000..d91f7c7406 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGValuesQuery.java @@ -0,0 +1,27 @@ +package com.alibaba.druid.sql.dialect.postgresql.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; +import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObjectImpl; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor; + +public class PGValuesQuery extends PGSQLObjectImpl implements SQLSelectQuery { + + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + @Override + public void accept0(PGASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, values); + } + visitor.endVisit(this); + } + +} 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 9d7339b059..4428ec5776 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 @@ -18,6 +18,7 @@ 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.dialect.postgresql.ast.PGOrderBy; +import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.SQLExprParser; @@ -62,6 +63,18 @@ public class PGExprParser extends SQLExprParser { return null; } + + public SQLExpr primary() { + if (lexer.token() == Token.ARRAY) { + lexer.nextToken(); + PGArrayExpr array = new PGArrayExpr(); + accept(Token.LBRACKET); + this.exprList(array.getValues(), array); + accept(Token.RBRACKET); + return primaryRest(array); + } + return super.primary(); + } public SQLExpr primaryRest(SQLExpr expr) { if (lexer.token() == Token.COLONCOLON) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java index 9939d3e10f..721c878209 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java @@ -61,6 +61,7 @@ public class PGLexer extends Lexer { map.put("TRUE", Token.TRUE); map.put("FALSE", Token.FALSE); + map.put("ARRAY", Token.ARRAY); DEFAULT_PG_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index 523874cdc3..2e6208d5af 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; @@ -254,6 +255,8 @@ public class PGSQLStatementParser extends SQLStatementParser { query = this.parseUpdateStatement(); } else if (lexer.token() == Token.DELETE) { query = this.parseDeleteStatement(); + } else if (lexer.token() == Token.VALUES) { + query = this.parseSelect(); } else { throw new ParserException("syntax error, support token '" + lexer.token() + "'"); } @@ -266,7 +269,9 @@ public class PGSQLStatementParser extends SQLStatementParser { } public PGSelectStatement parseSelect() { - return new PGSelectStatement(createSQLSelectParser().select()); + PGSelectParser selectParser = createSQLSelectParser(); + SQLSelect select = selectParser.select(); + return new PGSelectStatement(select); } public SQLStatement parseWith() { @@ -282,6 +287,12 @@ public class PGSQLStatementParser extends SQLStatementParser { stmt.setWith(with); return stmt; } + + if (lexer.token() == Token.DELETE) { + PGDeleteStatement stmt = this.parseDeleteStatement(); + stmt.setWith(with); + return stmt; + } throw new ParserException("TODO"); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java index 8ce42e0cb7..1b9ff7dd40 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoOption; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLExprParser; @@ -48,6 +49,15 @@ public class PGSelectParser extends SQLSelectParser { @Override public SQLSelectQuery query() { + if (lexer.token() == Token.VALUES) { + lexer.nextToken(); + accept(Token.LPAREN); + PGValuesQuery valuesQuery = new PGValuesQuery(); + this.exprParser.exprList(valuesQuery.getValues(), valuesQuery); + accept(Token.RPAREN); + return queryRest(valuesQuery); + } + PGSelectQueryBlock queryBlock = new PGSelectQueryBlock(); if (lexer.token() == Token.SELECT) { 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 29c9bbe014..cd69889b78 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,6 +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.PGParameter; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -25,6 +26,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface PGASTVisitor extends SQLASTVisitor { @@ -84,5 +86,13 @@ public interface PGASTVisitor extends SQLASTVisitor { void endVisit(PGTypeCastExpr x); boolean visit(PGTypeCastExpr x); + + void endVisit(PGValuesQuery x); + + boolean visit(PGValuesQuery x); + + void endVisit(PGArrayExpr x); + + boolean visit(PGArrayExpr 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 c4a6f824af..ea99f0fcc6 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,6 +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.PGParameter; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -29,6 +30,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLi import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVisitor { @@ -178,4 +180,24 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi } + @Override + public void endVisit(PGValuesQuery x) { + + } + + @Override + public boolean visit(PGValuesQuery x) { + return true; + } + + @Override + public void endVisit(PGArrayExpr x) { + + } + + @Override + public boolean visit(PGArrayExpr 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 ec3a01ef03..30629e7d6f 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 @@ -20,6 +20,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.PGParameter; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -32,6 +33,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLi import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor { @@ -145,6 +147,9 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor @Override public boolean visit(PGWithClause x) { print("WITH"); + if (x.isRecursive()) { + print(" RECURSIVE "); + } incrementIndent(); println(); printlnAndAccept(x.getWithQuery(), ", "); @@ -495,4 +500,30 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor return false; } + @Override + public void endVisit(PGValuesQuery x) { + + } + + @Override + public boolean visit(PGValuesQuery x) { + print("VALUES("); + printAndAccept(x.getValues(), ", "); + print(")"); + return false; + } + + @Override + public void endVisit(PGArrayExpr x) { + + } + + @Override + public boolean visit(PGArrayExpr x) { + print("ARRAY["); + printAndAccept(x.getValues(), ", "); + print("]"); + return false; + } + } 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 f73918f00a..9526594320 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,6 +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.PGParameter; import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -35,6 +36,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLi import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.stat.TableStat.Mode; @@ -287,4 +289,24 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit public void endVisit(PGTypeCastExpr x) { } + + @Override + public void endVisit(PGValuesQuery x) { + + } + + @Override + public boolean visit(PGValuesQuery x) { + return true; + } + + @Override + public void endVisit(PGArrayExpr x) { + + } + + @Override + public boolean visit(PGArrayExpr x) { + return true; + } } 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 580841ec39..5b4d647ee6 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -517,47 +517,13 @@ public class SQLExprParser extends SQLParser { } break; case ANY: - lexer.nextToken(); - if (lexer.token() == Token.LPAREN) { - SQLAnyExpr anyExpr = new SQLAnyExpr(); - - accept(Token.LPAREN); - SQLSelect anySubQuery = createSelectParser().select(); - anyExpr.setSubQuery(anySubQuery); - accept(Token.RPAREN); - - anySubQuery.setParent(anyExpr); - - sqlExpr = anyExpr; - } else { - sqlExpr = new SQLIdentifierExpr("ANY"); - } + sqlExpr = parseAny(); break; case SOME: - lexer.nextToken(); - SQLSomeExpr someExpr = new SQLSomeExpr(); - - accept(Token.LPAREN); - SQLSelect someSubQuery = createSelectParser().select(); - someExpr.setSubQuery(someSubQuery); - accept(Token.RPAREN); - - someSubQuery.setParent(someExpr); - - sqlExpr = someExpr; + sqlExpr = parseSome(); break; case ALL: - lexer.nextToken(); - SQLAllExpr allExpr = new SQLAllExpr(); - - accept(Token.LPAREN); - SQLSelect allSubQuery = createSelectParser().select(); - allExpr.setSubQuery(allSubQuery); - accept(Token.RPAREN); - - allSubQuery.setParent(allExpr); - - sqlExpr = allExpr; + sqlExpr = parseAll(); break; case LITERAL_ALIAS: sqlExpr = parseAliasExpr(lexer.stringVal()); @@ -579,6 +545,66 @@ public class SQLExprParser extends SQLParser { return primaryRest(sqlExpr); } + + protected SQLExpr parseAll() { + SQLExpr sqlExpr; + lexer.nextToken(); + SQLAllExpr allExpr = new SQLAllExpr(); + + accept(Token.LPAREN); + SQLSelect allSubQuery = createSelectParser().select(); + allExpr.setSubQuery(allSubQuery); + accept(Token.RPAREN); + + allSubQuery.setParent(allExpr); + + sqlExpr = allExpr; + return sqlExpr; + } + + protected SQLExpr parseSome() { + SQLExpr sqlExpr; + lexer.nextToken(); + SQLSomeExpr someExpr = new SQLSomeExpr(); + + accept(Token.LPAREN); + SQLSelect someSubQuery = createSelectParser().select(); + someExpr.setSubQuery(someSubQuery); + accept(Token.RPAREN); + + someSubQuery.setParent(someExpr); + + sqlExpr = someExpr; + return sqlExpr; + } + + protected SQLExpr parseAny() { + SQLExpr sqlExpr; + lexer.nextToken(); + if (lexer.token() == Token.LPAREN) { + accept(Token.LPAREN); + + if (lexer.token() == Token.IDENTIFIER) { + SQLExpr expr = this.expr(); + SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr("ANY"); + methodInvokeExpr.addParameter(expr); + accept(Token.RPAREN); + return methodInvokeExpr; + } + + SQLAnyExpr anyExpr = new SQLAnyExpr(); + SQLSelect anySubQuery = createSelectParser().select(); + anyExpr.setSubQuery(anySubQuery); + accept(Token.RPAREN); + + anySubQuery.setParent(anyExpr); + + sqlExpr = anyExpr; + } else { + sqlExpr = new SQLIdentifierExpr("ANY"); + } + return sqlExpr; + } protected SQLExpr parseAliasExpr(String alias) { return new SQLIdentifierExpr('"' + alias + '"'); 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 5dc23da696..753cb09042 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -220,6 +220,8 @@ public enum Token { // transact-sql TOP("TOP"), + ARRAY("ARRAY"), + // hive EOF, diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest6.java new file mode 100644 index 0000000000..8e7de76035 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest6.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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 com.alibaba.druid.stat.TableStat; + +public class PGDeleteTest6 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH moved_rows AS (" + + " DELETE FROM products" + + " WHERE" + + " \"date\" >= '2010-10-01' AND" + + " \"date\" < '2010-11-01'" + + " RETURNING *" + + ")" + + "INSERT INTO products_log\n" + + "SELECT * FROM moved_rows;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("products"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("products"))); + + Assert.assertTrue(visitor.getColumns().size() == 1); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("products", "date"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest7.java new file mode 100644 index 0000000000..258f7f920b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest7.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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 com.alibaba.druid.stat.TableStat; + +public class PGDeleteTest7 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH t AS (" + + " DELETE FROM foo" + + ")" + + "DELETE FROM bar;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("foo"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bar"))); + + Assert.assertTrue(visitor.getColumns().size() == 0); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("products", "date"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest8.java new file mode 100644 index 0000000000..35618cfeb9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest8.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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 com.alibaba.druid.stat.TableStat; + +public class PGDeleteTest8 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE included_parts(sub_part, part) AS (" + + " SELECT sub_part, part FROM parts WHERE part = 'our_product'" + + " UNION ALL" + + " SELECT p.sub_part, p.part" + + " FROM included_parts pr, parts p" + + " WHERE p.part = pr.sub_part" + + " )" + + "DELETE FROM parts\n" + + " WHERE part IN (SELECT part FROM included_parts);"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("parts"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("included_parts"))); + + Assert.assertTrue(visitor.getColumns().size() == 4); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("parts", "part"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest12.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest12.java new file mode 100644 index 0000000000..35cead9f2f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest12.java @@ -0,0 +1,70 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest12 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH regional_sales AS (" + + " SELECT region, SUM(amount) AS total_sales" + + " FROM orders" + + " GROUP BY region" + + " ), top_regions AS (" + + " SELECT region" + + " FROM regional_sales" + + " WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)" + + " )\n" + + "SELECT region," + + " product," + + " SUM(quantity) AS product_units," + + " SUM(amount) AS product_sales\n" + + "FROM orders\n" + + "WHERE region IN (SELECT region FROM top_regions)\n" + + "GROUP BY region, product;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(4, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest13.java new file mode 100644 index 0000000000..88039282e9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest13.java @@ -0,0 +1,60 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest13 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE t(n) AS (" + + " VALUES (1)" + + " UNION ALL" + + " SELECT n+1 FROM t WHERE n < 100" + + ")\n" + + "SELECT sum(n) FROM t;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest14.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest14.java new file mode 100644 index 0000000000..f8d27586c0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest14.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest14 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE included_parts(sub_part, part, quantity) AS (" + + " SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'" + + " UNION ALL" + + " SELECT p.sub_part, p.part, p.quantity" + + " FROM included_parts pr, parts p" + + " WHERE p.part = pr.sub_part" + + " )\n" + + "SELECT sub_part, SUM(quantity) as total_quantity\n" + + "FROM included_parts\n" + + "GROUP BY sub_part"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(5, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest15.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest15.java new file mode 100644 index 0000000000..c688524192 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest15.java @@ -0,0 +1,63 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest15 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE search_graph(id, link, data, depth) AS (" + + " SELECT g.id, g.link, g.data, 1" + + " FROM graph g" + + " UNION ALL" + + " SELECT g.id, g.link, g.data, sg.depth + 1" + + " FROM graph g, search_graph sg" + + " WHERE g.id = sg.link" + + ")" + + "SELECT * FROM search_graph;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(6, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest16.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest16.java new file mode 100644 index 0000000000..a43c5c7047 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest16.java @@ -0,0 +1,67 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest16 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (" + + " SELECT g.id, g.link, g.data, 1," + + " ARRAY[g.id]," + + " false" + + " FROM graph g" + + " UNION ALL" + + " SELECT g.id, g.link, g.data, sg.depth + 1," + + " path || g.id," + + " g.id = ANY(path)" + + " FROM graph g, search_graph sg" + + " WHERE g.id = sg.link AND NOT cycle" + + ")" + + "SELECT * FROM search_graph;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(8, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest17.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest17.java new file mode 100644 index 0000000000..3aadca77f9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest17.java @@ -0,0 +1,67 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest17 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (" + + " SELECT g.id, g.link, g.data, 1," + + " ARRAY[ROW(g.f1, g.f2)]," + + " false" + + " FROM graph g" + + " UNION ALL" + + " SELECT g.id, g.link, g.data, sg.depth + 1," + + " path || ROW(g.f1, g.f2)," + + " ROW(g.f1, g.f2) = ANY(path)" + + " FROM graph g, search_graph sg" + + " WHERE g.id = sg.link AND NOT cycle" + + ")" + + "SELECT * FROM search_graph;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(10, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest18.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest18.java new file mode 100644 index 0000000000..abd5bc09de --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest18.java @@ -0,0 +1,60 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest18 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH RECURSIVE t(n) AS (" + + " SELECT 1" + + " UNION ALL" + + " SELECT n+1 FROM t" + + ")" + + "SELECT n FROM t LIMIT 100;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest19.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest19.java new file mode 100644 index 0000000000..ebba0f68c4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest19.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest19 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH t AS (" + + " UPDATE products SET price = price * 1.05" + + " RETURNING *" + + ")" + + "SELECT * FROM products;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest20.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest20.java new file mode 100644 index 0000000000..b63fa949b3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectTest20.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2011 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 java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +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; + +public class PGSelectTest20 extends PGTest { + + public void test_0() throws Exception { + String sql = "WITH t AS (" + + " UPDATE products SET price = price * 1.05" + + " RETURNING *" + + ")" + + "SELECT * FROM t;"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getTables().size()); + } +} + +// select categoryId , offerIds from cnres.function_select_get_spt_p4p_offer_list (' 1031918 , 1031919 , 1037004 ') as +// a(categoryId numeric,offerIds character varying(4000)) +// select memberId , offerIds from cnres.function_select_get_seller_hot_offer_list('\'gzyyd168\'') as a(memberId +// character varying(20),offerIds character varying(4000)) +