improved sql parser.

This commit is contained in:
wenshao
2017-07-23 16:44:43 +08:00
parent 82fe08109f
commit 6829a23bce
41 changed files with 1183 additions and 514 deletions
@@ -250,45 +250,51 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
printSelectList(x.getSelectList());
if (x.getInto() != null) {
SQLExprTableSource into = x.getInto();
if (into != null) {
println();
print0(ucase ? "INTO " : "into ");
x.getInto().accept(this);
into.accept(this);
}
if (x.getFrom() != null) {
SQLTableSource form = x.getFrom();
if (form != null) {
println();
print0(ucase ? "FROM " : "from ");
x.getFrom().accept(this);
form.accept(this);
}
if (x.getWhere() != null) {
SQLExpr where = x.getWhere();
if (where != null) {
println();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
where.accept(this);
}
printHierarchical(x);
if (x.getGroupBy() != null) {
SQLSelectGroupByClause groupBy = x.getGroupBy();
if (groupBy != null) {
println();
x.getGroupBy().accept(this);
groupBy.accept(this);
}
if (x.getOrderBy() != null) {
SQLOrderBy orderBy = x.getOrderBy();
if (orderBy != null) {
println();
x.getOrderBy().accept(this);
orderBy.accept(this);
}
if (x.getLimit() != null) {
SQLLimit limit = x.getLimit();
if (limit != null) {
println();
x.getLimit().accept(this);
limit.accept(this);
}
if (x.getProcedureName() != null) {
SQLName procedureName = x.getProcedureName();
if (procedureName != null) {
print0(ucase ? " PROCEDURE " : " procedure ");
x.getProcedureName().accept(this);
procedureName.accept(this);
if (!x.getProcedureArgumentList().isEmpty()) {
print('(');
printAndAccept(x.getProcedureArgumentList(), ", ");
@@ -16,17 +16,21 @@
package com.alibaba.druid.sql.dialect.mysql.visitor.transform;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
import oracle.sql.SQLName;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author wenshao[szujobs@hotmail.com]
@@ -34,6 +38,9 @@ import java.util.List;
public class FromSubqueryResolver extends OracleASTVisitorAdapter {
private final List<SQLStatement> targetList;
private final String viewName;
private final Map<String, String> mappings = new LinkedHashMap<String, String>();
private int viewNameSeed = 1;
public FromSubqueryResolver(List<SQLStatement> targetList, String viewName) {
this.targetList = targetList;
@@ -50,13 +57,13 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
SQLObject parent = x.getParent();
if(parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent;
queryBlock.setFrom(subViewName);
queryBlock.setFrom(subViewName, x.getAlias());
} else if(parent instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) parent;
if (join.getLeft() == x) {
join.setLeft(subViewName);
join.setLeft(subViewName, x.getAlias());
} else if (join.getRight() == x) {
join.setRight(subViewName);
join.setRight(subViewName, x.getAlias());
}
}
@@ -64,7 +71,6 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
stmt.setName(generateSubViewName());
SQLSelect select = x.getSelect();
stmt.setSubQuery(select);
@@ -75,6 +81,23 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
return false;
}
public boolean visit(SQLExprTableSource x) {
SQLExpr expr = x.getExpr();
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
String ident = identifierExpr.getName();
String mappingIdent = mappings.get(ident);
if (mappingIdent != null) {
identifierExpr.setName(mappingIdent);
}
}
return false;
}
public boolean visit(OracleSelectTableReference x) {
return visit((SQLExprTableSource) x);
}
private String generateSubViewName() {
return this.viewName + "_" + targetList.size();
}
@@ -86,6 +109,28 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
String viewName = SQLUtils.normalize(stmt.getName().getSimpleName());
FromSubqueryResolver visitor = new FromSubqueryResolver(targetList, viewName);
SQLWithSubqueryClause withSubqueryClause = stmt.getSubQuery().getWithSubQuery();
if (withSubqueryClause != null) {
stmt.getSubQuery().setWithSubQuery(null);
for (SQLWithSubqueryClause.Entry entry : withSubqueryClause.getEntries()) {
String entryName = entry.getName().getName();
SQLCreateViewStatement entryStmt = new SQLCreateViewStatement();
entryStmt.setDbType(stmt.getDbType());
String entryViewName = visitor.generateSubViewName();
entryStmt.setName(entryViewName);
entryStmt.setSubQuery(entry.getSubQuery());
visitor.targetList.add(0, entryStmt);
visitor.mappings.put(entryName, entryViewName);
entryStmt.accept(visitor);
}
}
stmt.accept(visitor);
String dbType = stmt.getDbType();
@@ -95,7 +140,6 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
targetStmt.setAfterSemi(true);
}
return targetList;
}
}
@@ -456,22 +456,23 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
printSelectList(x.getSelectList());
if (x.getFrom() != null) {
SQLTableSource from = x.getFrom();
if (from != null) {
println();
print0(ucase ? "FROM " : "from ");
x.getFrom().accept(this);
from.accept(this);
}
if (x.getWhere() != null) {
SQLExpr where = x.getWhere();
if (where != null) {
println();
print0(ucase ? "WHERE " : "where ");
if (x.getWhere().hasBeforeComment() && isPrettyFormat()) {
if (where.hasBeforeComment() && isPrettyFormat()) {
printlnComments(x.getWhere().getBeforeCommentsDirect());
}
x.getWhere().setParent(x);
x.getWhere().accept(this);
if (x.getWhere().hasAfterComment() && isPrettyFormat()) {
where.accept(this);
if (where.hasAfterComment() && isPrettyFormat()) {
print(' ');
printlnComment(x.getWhere().getAfterCommentsDirect());
}
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -35,6 +36,9 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
}
public OracleSelectJoin(SQLTableSource left, JoinType joinType, SQLTableSource right, SQLExpr condition){
super (left, joinType, right, condition);
}
public OracleSelectPivotBase getPivot() {
return pivot;
@@ -241,6 +241,8 @@ public class OracleExprParser extends SQLExprParser {
}
accept(Token.RPAREN);
// } else if (lexer.token() == Token.RPAREN) {
// return charType;
} else if (restrict) {
accept(Token.LPAREN);
}
@@ -1218,6 +1220,12 @@ public class OracleExprParser extends SQLExprParser {
continue;
}
if (lexer.token() == Token.CACHE) {
lexer.nextToken();
clause.setCache(true);
continue;
}
if (lexer.token() == Token.KEEP_DUPLICATES) {
lexer.nextToken();
clause.setKeepDuplicate(true);
@@ -142,7 +142,7 @@ public class OracleStatementParser extends SQLStatementParser {
}
if (lexer.token() == Token.WITH) {
SQLSelectStatement stmt = new SQLSelectStatement(this.createSQLSelectParser().select());
SQLSelectStatement stmt = new SQLSelectStatement(this.createSQLSelectParser().select(), dbType);
stmt.setParent(parent);
statementList.add(stmt);
continue;