pg sql parser support insert

This commit is contained in:
温少
2012-02-23 09:35:22 +08:00
parent 27ba9c0d55
commit 97ecbaefe2
27 changed files with 677 additions and 146 deletions
@@ -0,0 +1,25 @@
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLDefaultExpr extends SQLLiteralExpr {
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object o) {
return o instanceof SQLDefaultExpr;
}
@Override
public int hashCode() {
return 0;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
visitor.visit(this);
visitor.endVisit(this);
}
}
@@ -27,12 +27,12 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLInsertStatement extends SQLStatementImpl {
private static final long serialVersionUID = 1L;
private SQLName tableName;
private String alias;
protected SQLName tableName;
protected String alias;
private final List<SQLExpr> columns = new ArrayList<SQLExpr>();
private ValuesClause values;
private SQLSelect query;
protected final List<SQLExpr> columns = new ArrayList<SQLExpr>();
protected ValuesClause values;
protected SQLSelect query;
public SQLInsertStatement(){
@@ -22,7 +22,7 @@ public class SQLSelectStatement extends SQLStatementImpl {
private static final long serialVersionUID = 1L;
private SQLSelect select;
protected SQLSelect select;
public SQLSelectStatement(){
@@ -1,7 +0,0 @@
package com.alibaba.druid.sql.dialect.postgresql.ast;
import com.alibaba.druid.sql.ast.SQLStatement;
public interface PGSQLStatement extends SQLStatement, PGSQLObject {
}
@@ -4,42 +4,43 @@ 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.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
public class PGWithQuery extends PGSQLObjectImpl {
private static final long serialVersionUID = 1L;
private SQLExpr name;
private final List<SQLExpr> columns = new ArrayList<SQLExpr>();
private SQLSelectQuery subQuery;
public SQLExpr getName() {
return name;
}
private static final long serialVersionUID = 1L;
private SQLExpr name;
private final List<SQLExpr> columns = new ArrayList<SQLExpr>();
private SQLStatement query;
public void setName(SQLExpr name) {
this.name = name;
}
public SQLExpr getName() {
return name;
}
public SQLSelectQuery getSubQuery() {
return subQuery;
}
public void setName(SQLExpr name) {
this.name = name;
}
public void setSubQuery(SQLSelectQuery subQuery) {
this.subQuery = subQuery;
}
public SQLStatement getQuery() {
return query;
}
public List<SQLExpr> getColumns() {
return columns;
}
public void setQuery(SQLStatement query) {
this.query = query;
}
@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, columns);
acceptChild(visitor, subQuery);
}
visitor.endVisit(this);
}
public List<SQLExpr> getColumns() {
return columns;
}
@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, columns);
acceptChild(visitor, query);
}
visitor.endVisit(this);
}
}
@@ -1,10 +1,11 @@
package com.alibaba.druid.sql.dialect.postgresql.ast;
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -0,0 +1,72 @@
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.SQLInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class PGInsertStatement extends SQLInsertStatement implements PGSQLStatement {
private static final long serialVersionUID = 1L;
private PGWithClause with;
private List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
private SQLExpr returning;
public SQLExpr getReturning() {
return returning;
}
public void setReturning(SQLExpr returning) {
this.returning = returning;
}
public PGWithClause getWith() {
return with;
}
public void setWith(PGWithClause with) {
this.with = with;
}
public ValuesClause getValues() {
if (valuesList.size() == 0) {
return null;
}
return valuesList.get(0);
}
public void setValues(ValuesClause values) {
if (valuesList.size() == 0) {
valuesList.add(values);
} else {
valuesList.set(0, values);
}
}
public List<ValuesClause> getValuesList() {
return valuesList;
}
protected void accept0(SQLASTVisitor visitor) {
accept0((PGASTVisitor) visitor);
}
@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
this.acceptChild(visitor, with);
this.acceptChild(visitor, tableName);
this.acceptChild(visitor, columns);
this.acceptChild(visitor, valuesList);
this.acceptChild(visitor, query);
this.acceptChild(visitor, returning);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,8 @@
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObject;
public interface PGSQLStatement extends SQLStatement, PGSQLObject {
}
@@ -1,4 +1,6 @@
package com.alibaba.druid.sql.dialect.postgresql.ast;
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObjectImpl;
public abstract class PGSQLStatementImpl extends PGSQLObjectImpl implements PGSQLStatement {
@@ -1,4 +1,4 @@
package com.alibaba.druid.sql.dialect.postgresql.ast;
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import java.util.ArrayList;
import java.util.List;
@@ -6,6 +6,8 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObjectImpl;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -0,0 +1,32 @@
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class PGSelectStatement extends SQLSelectStatement implements PGSQLStatement {
private static final long serialVersionUID = 1L;
private PGWithClause with;
public PGWithClause getWith() {
return with;
}
public void setWith(PGWithClause with) {
this.with = with;
}
protected void accept0(SQLASTVisitor visitor) {
accept0((PGASTVisitor) visitor);
}
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.with);
acceptChild(visitor, this.select);
}
visitor.endVisit(this);
}
}
@@ -1,4 +1,4 @@
package com.alibaba.druid.sql.dialect.postgresql.ast;
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
@@ -5,10 +5,14 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGTruncateStatement;
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.stmt.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGTruncateStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLStatementParser;
@@ -29,7 +33,55 @@ public class PGSQLStatementParser extends SQLStatementParser {
return new PGSelectParser(this.lexer);
}
public SQLDeleteStatement parseDeleteStatement() throws ParserException {
public PGInsertStatement parseInsert() {
accept(Token.INSERT);
accept(Token.INTO);
PGInsertStatement stmt = new PGInsertStatement();
SQLName tableName = this.exprParser.name();
stmt.setTableName(tableName);
if (lexer.token() == Token.IDENTIFIER) {
stmt.setAlias(lexer.stringVal());
lexer.nextToken();
}
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
this.exprParser.exprList(stmt.getColumns());
accept(Token.RPAREN);
}
if (lexer.token() == (Token.VALUES)) {
lexer.nextToken();
for (;;) {
accept(Token.LPAREN);
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
this.exprParser.exprList(values.getValues());
stmt.getValuesList().add(values);
accept(Token.RPAREN);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
} else if (lexer.token() == (Token.SELECT)) {
SQLQueryExpr queryExpr = (SQLQueryExpr) this.createExprParser().expr();
stmt.setQuery(queryExpr.getSubQuery());
}
if (lexer.token() == Token.RETURNING) {
lexer.nextToken();
SQLExpr returning = this.exprParser.expr();
stmt.setReturning(returning);
}
return stmt;
}
public PGDeleteStatement parseDeleteStatement() throws ParserException {
lexer.nextToken();
PGDeleteStatement deleteStatement = new PGDeleteStatement();
@@ -72,7 +124,7 @@ public class PGSQLStatementParser extends SQLStatementParser {
deleteStatement.setWhere(where);
}
}
if (lexer.token() == Token.RETURNING) {
lexer.nextToken();
accept(Token.STAR);
@@ -131,11 +183,91 @@ public class PGSQLStatementParser extends SQLStatementParser {
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
if (lexer.token() == Token.WITH) {
SQLStatement stmt = parseSelect();
SQLStatement stmt = parseWith();
statementList.add(stmt);
return true;
}
return false;
}
public PGWithClause parseWithClause() {
lexer.nextToken();
PGWithClause withClause = new PGWithClause();
if (lexer.token() == Token.RECURSIVE) {
lexer.nextToken();
withClause.setRecursive(true);
}
for (;;) {
PGWithQuery withQuery = withQuery();
withClause.getWithQuery().add(withQuery);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
return withClause;
}
private PGWithQuery withQuery() {
PGWithQuery withQuery = new PGWithQuery();
withQuery.setName(this.createExprParser().expr());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (;;) {
SQLExpr expr = this.createExprParser().expr();
withQuery.getColumns().add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
accept(Token.RPAREN);
}
accept(Token.AS);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLStatement query;
if (lexer.token() == Token.SELECT) {
query = this.parseSelect();
} else if (lexer.token() == Token.INSERT) {
query = this.parseInsert();
} else if (lexer.token() == Token.UPDATE) {
query = this.parseUpdateStatement();
} else if (lexer.token() == Token.DELETE) {
query = this.parseDeleteStatement();
} else {
throw new ParserException("syntax error, support token '" + lexer.token() + "'");
}
withQuery.setQuery(query);
accept(Token.RPAREN);
}
return withQuery;
}
public SQLStatement parseWith() {
PGWithClause with = this.parseWithClause();
if (lexer.token() == Token.INSERT) {
PGInsertStatement stmt = this.parseInsert();
stmt.setWith(with);
return stmt;
}
throw new ParserException("TODO");
}
}
@@ -4,10 +4,8 @@ import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.IntoClause;
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.stmt.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLSelectParser;
@@ -28,30 +26,6 @@ public class PGSelectParser extends SQLSelectParser {
protected SQLSelectQuery query() throws ParserException {
PGSelectQueryBlock queryBlock = new PGSelectQueryBlock();
if (lexer.token() == Token.WITH) {
lexer.nextToken();
PGWithClause withClause = new PGWithClause();
if (lexer.token() == Token.RECURSIVE) {
lexer.nextToken();
withClause.setRecursive(true);
}
for (;;) {
PGWithQuery withQuery = withQuery();
withClause.getWithQuery().add(withQuery);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
queryBlock.setWith(withClause);
}
accept(Token.SELECT);
if (lexer.token() == Token.DISTINCT) {
@@ -221,37 +195,5 @@ public class PGSelectParser extends SQLSelectParser {
return queryRest(queryBlock);
}
private PGWithQuery withQuery() {
PGWithQuery withQuery = new PGWithQuery();
withQuery.setName(expr());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (;;) {
SQLExpr expr = this.createExprParser().expr();
withQuery.getColumns().add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
accept(Token.RPAREN);
}
accept(Token.AS);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLSelectQuery subQuery = query();
withQuery.setSubQuery(subQuery);
accept(Token.RPAREN);
}
return withQuery;
}
}
@@ -1,11 +1,13 @@
package com.alibaba.druid.sql.dialect.postgresql.visitor;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGTruncateStatement;
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.stmt.PGDeleteStatement;
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.PGTruncateStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public interface PGASTVisitor extends SQLASTVisitor {
@@ -45,4 +47,12 @@ public interface PGASTVisitor extends SQLASTVisitor {
void endVisit(PGCurrentOfExpr x);
boolean visit(PGCurrentOfExpr x);
void endVisit(PGInsertStatement x);
boolean visit(PGInsertStatement x);
void endVisit(PGSelectStatement x);
boolean visit(PGSelectStatement x);
}
@@ -1,12 +1,14 @@
package com.alibaba.druid.sql.dialect.postgresql.visitor;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
@@ -110,5 +112,25 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi
public boolean visit(PGCurrentOfExpr x) {
return true;
}
@Override
public void endVisit(PGInsertStatement x) {
}
@Override
public boolean visit(PGInsertStatement x) {
return true;
}
@Override
public void endVisit(PGSelectStatement x) {
}
@Override
public boolean visit(PGSelectStatement x) {
return true;
}
}
@@ -2,14 +2,17 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
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.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
@@ -109,7 +112,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
print("(");
incrementIndent();
println();
x.getSubQuery().accept(this);
x.getQuery().accept(this);
decrementIndent();
println();
print(")");
@@ -324,4 +327,72 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
return false;
}
@Override
public void endVisit(PGInsertStatement x) {
}
@Override
public boolean visit(PGInsertStatement x) {
if (x.getWith() != null) {
x.getWith().accept(this);
println();
}
print("INSERT INTO ");
x.getTableName().accept(this);
if (x.getColumns().size() > 0) {
incrementIndent();
println();
print("(");
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print(", ");
}
x.getColumns().get(i).accept(this);
}
print(")");
decrementIndent();
}
if (x.getValues() != null) {
println();
print("VALUES ");
printlnAndAccept(x.getValuesList(), ", ");
} else {
if (x.getQuery() != null) {
println();
x.getQuery().accept(this);
}
}
if (x.getReturning() != null) {
println();
print("RETURNING ");
x.getReturning().accept(this);
}
return false;
}
@Override
public void endVisit(PGSelectStatement x) {
}
@Override
public boolean visit(PGSelectStatement x) {
if (x.getWith() != null) {
x.getWith().accept(this);
println();
}
return visit((SQLSelectStatement) x);
}
}
@@ -5,14 +5,18 @@ import java.util.Map;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGTruncateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.FetchClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
@@ -163,4 +167,31 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
public boolean visit(PGCurrentOfExpr x) {
return false;
}
@Override
public void endVisit(PGInsertStatement x) {
}
@Override
public boolean visit(PGInsertStatement x) {
if (x.getWith() != null) {
x.getWith().accept(this);
}
return visit((SQLInsertStatement) x);
}
@Override
public void endVisit(PGSelectStatement x) {
}
@Override
public boolean visit(PGSelectStatement x) {
if (x.getWith() != null) {
x.getWith().accept(this);
}
return visit((SQLSelectStatement) x);
}
}
@@ -98,6 +98,7 @@ public class Keywords {
map.put("LOCK", Token.LOCK);
map.put("SOME", Token.SOME);
map.put("ANY", Token.ANY);
map.put("DEFAULT", Token.DEFAULT);
DEFAULT_KEYWORDS = new Keywords(map);
}
@@ -34,6 +34,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
@@ -193,6 +194,10 @@ public class SQLExprParser extends SQLParser {
sqlExpr = new SQLVariantRefExpr(lexer.stringVal());
lexer.nextToken();
break;
case DEFAULT:
sqlExpr = new SQLDefaultExpr();
lexer.nextToken();
break;
case CASE:
SQLCaseExpr caseExpr = new SQLCaseExpr();
lexer.nextToken();
@@ -352,10 +357,6 @@ public class SQLExprParser extends SQLParser {
case INTERVAL:
sqlExpr = parseInterval();
break;
case DEFAULT:
lexer.nextToken();
sqlExpr = new SQLIdentifierExpr("DEFAULT");
break;
case ANY:
lexer.nextToken();
if (lexer.token() == Token.LPAREN) {
@@ -34,6 +34,7 @@ import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
@@ -865,16 +866,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
return false;
}
@Override
public void endVisit(SQLTruncateStatement x) {
}
@Override
public boolean visit(SQLTruncateStatement x) {
print("TRUNCATE TABLE ");
printAndAccept(x.getTableNames(), ", ");
return false;
}
@Override
public boolean visit(SQLDefaultExpr x) {
print("DEFAULT");
return false;
}
}
@@ -30,6 +30,7 @@ import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr;
import com.alibaba.druid.sql.ast.expr.SQLDateLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexStringLiteralExpr;
@@ -319,4 +320,8 @@ public interface SQLASTVisitor {
void endVisit(SQLTruncateStatement x);
boolean visit(SQLTruncateStatement x);
void endVisit(SQLDefaultExpr x);
boolean visit(SQLDefaultExpr x);
}
@@ -30,6 +30,7 @@ import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr;
import com.alibaba.druid.sql.ast.expr.SQLDateLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexStringLiteralExpr;
@@ -550,4 +551,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
public boolean visit(SQLTruncateStatement x) {
return true;
}
@Override
public void endVisit(SQLDefaultExpr x) {
}
@Override
public boolean visit(SQLDefaultExpr x) {
return true;
}
}
@@ -0,0 +1,44 @@
package com.alibaba.druid.bvt.sql.postgresql;
import java.util.List;
import junit.framework.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 PGInsertTest2 extends PGTest {
public void test_0() throws Exception {
String sql = "INSERT INTO films (code, title, did, date_prod, kind) VALUES"
+ " ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'), "
+ "('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getFields());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films")));
Assert.assertEquals(5, visitor.getFields().size());
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "kind")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "code")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "date_prod")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "title")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "did")));
}
}
@@ -0,0 +1,40 @@
package com.alibaba.druid.bvt.sql.postgresql;
import java.util.List;
import junit.framework.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 PGInsertTest3 extends PGTest {
public void test_0() throws Exception {
String sql = "INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getFields());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films")));
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("tmp_films")));
Assert.assertEquals(2, visitor.getFields().size());
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("tmp_films", "date_prod")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("tmp_films", "*")));
}
}
@@ -0,0 +1,39 @@
package com.alibaba.druid.bvt.sql.postgresql;
import java.util.List;
import junit.framework.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 PGInsertTest4 extends PGTest {
public void test_0() throws Exception {
String sql = "INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING did;";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getFields());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("distributors")));
Assert.assertEquals(2, visitor.getFields().size());
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("distributors", "did")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("distributors", "dname")));
}
}
@@ -0,0 +1,44 @@
package com.alibaba.druid.bvt.sql.postgresql;
import java.util.List;
import junit.framework.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 PGInsertTest5 extends PGTest {
public void test_0() throws Exception {
String sql = "WITH upd AS (" + //
" UPDATE employees SET sales_count = sales_count + 1 WHERE id =" + //
" (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')" + //
" RETURNING *" + //
")" + //
"INSERT INTO employees_log SELECT *, current_timestamp FROM upd;";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
System.out.println(output(statementList));
Assert.assertEquals(1, statementList.size());
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getFields());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("distributors")));
Assert.assertEquals(2, visitor.getFields().size());
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("distributors", "did")));
Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("distributors", "dname")));
}
}