improved sql parser.

This commit is contained in:
wenshao
2017-07-17 10:10:25 +08:00
parent 9e105a68f2
commit 5dac70deb0
20 changed files with 1510 additions and 69 deletions
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -77,6 +78,10 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
this.setTableSource(new SQLExprTableSource(name));
}
public void setName(String name) {
this.setName(new SQLIdentifierExpr(name));
}
public SQLExprTableSource getTableSource() {
return tableSource;
}
@@ -20,6 +20,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplaceable {
@@ -78,6 +79,26 @@ public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplace
this.left = left;
}
public void setLeft(String tableName) {
SQLExprTableSource tableSource;
if (tableName == null || tableName.length() == 0) {
tableSource = null;
} else {
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
}
this.setLeft(tableSource);
}
public void setRight(String tableName) {
SQLExprTableSource tableSource;
if (tableName == null || tableName.length() == 0) {
tableSource = null;
} else {
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
}
this.setRight(tableSource);
}
public SQLTableSource getRight() {
return this.right;
}
@@ -162,6 +162,16 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
this.from = from;
}
public void setFrom(String tableName) {
SQLExprTableSource from;
if (tableName == null || tableName.length() == 0) {
from = null;
} else {
from = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
}
this.setFrom(from);
}
public boolean isParenthesized() {
return parenthesized;
}
@@ -0,0 +1,101 @@
/*
* Copyright 1999-2017 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.sql.dialect.mysql.visitor.transform;
import com.alibaba.druid.sql.SQLUtils;
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.visitor.OracleASTVisitorAdapter;
import oracle.sql.SQLName;
import java.util.ArrayList;
import java.util.List;
/**
* @author wenshao[szujobs@hotmail.com]
*/
public class FromSubqueryResolver extends OracleASTVisitorAdapter {
private final List<SQLStatement> targetList;
private final String viewName;
public FromSubqueryResolver(List<SQLStatement> targetList, String viewName) {
this.targetList = targetList;
this.viewName = viewName;
}
public boolean visit(OracleSelectSubqueryTableSource x) {
return visit((SQLSubqueryTableSource) x);
}
public boolean visit(SQLSubqueryTableSource x) {
String subViewName = generateSubViewName();
SQLObject parent = x.getParent();
if(parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent;
queryBlock.setFrom(subViewName);
} else if(parent instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) parent;
if (join.getLeft() == x) {
join.setLeft(subViewName);
} else if (join.getRight() == x) {
join.setRight(subViewName);
}
}
SQLCreateViewStatement stmt = new SQLCreateViewStatement();
stmt.setName(generateSubViewName());
SQLSelect select = x.getSelect();
stmt.setSubQuery(select);
targetList.add(0, stmt);
stmt.accept(new FromSubqueryResolver(targetList, viewName));
return false;
}
private String generateSubViewName() {
return this.viewName + "_" + targetList.size();
}
public static List<SQLStatement> resolve(SQLCreateViewStatement stmt) {
List<SQLStatement> targetList = new ArrayList<SQLStatement>();
targetList.add(stmt);
String viewName = SQLUtils.normalize(stmt.getName().getSimpleName());
FromSubqueryResolver visitor = new FromSubqueryResolver(targetList, viewName);
stmt.accept(visitor);
String dbType = stmt.getDbType();
for (int i = 0; i < targetList.size() - 1; ++i) {
SQLCreateViewStatement targetStmt = (SQLCreateViewStatement) targetList.get(i);
targetStmt.setDbType(dbType);
targetStmt.setAfterSemi(true);
}
return targetList;
}
}
@@ -156,6 +156,19 @@ public class OdpsExprParser extends SQLExprParser {
return super.equalityRest(expr);
}
public SQLExpr relationalRest(SQLExpr expr) {
if (identifierEquals("REGEXP")) {
lexer.nextToken();
SQLExpr rightExp = equality();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp, JdbcConstants.MYSQL);
}
return super.relationalRest(expr);
}
@Override
public OdpsSelectParser createSelectParser() {
return new OdpsSelectParser(this);
@@ -76,6 +76,7 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
private SQLName of;
private OIDIndex oidIndex;
private boolean monitoring;
public OracleCreateTableStatement() {
super (JdbcConstants.ORACLE);
@@ -262,6 +263,14 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.oidIndex = oidIndex;
}
public boolean isMonitoring() {
return monitoring;
}
public void setMonitoring(boolean monitoring) {
this.monitoring = monitoring;
}
public boolean isCompressForOltp() {
return compressForOltp;
}
@@ -17,6 +17,8 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.SQLUtils;
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.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -119,4 +121,24 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
return x;
}
public void setLeft(String tableName) {
SQLExprTableSource tableSource;
if (tableName == null || tableName.length() == 0) {
tableSource = null;
} else {
tableSource = new OracleSelectTableReference(new SQLIdentifierExpr(tableName));
}
this.setLeft(tableSource);
}
public void setRight(String tableName) {
SQLExprTableSource tableSource;
if (tableName == null || tableName.length() == 0) {
tableSource = null;
} else {
tableSource = new OracleSelectTableReference(new SQLIdentifierExpr(tableName));
}
this.setRight(tableSource);
}
}
@@ -23,7 +23,9 @@ import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
@@ -161,4 +163,14 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
throw new UnsupportedOperationException("not support offset");
}
}
public void setFrom(String tableName) {
SQLExprTableSource from;
if (tableName == null || tableName.length() == 0) {
from = null;
} else {
from = new OracleSelectTableReference(new SQLIdentifierExpr(tableName));
}
this.setFrom(from);
}
}
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
@@ -34,6 +35,10 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
}
public OracleSelectTableReference(SQLExpr expr) {
this.setExpr(expr);
}
public PartitionExtensionClause getPartition() {
return partition;
}
@@ -150,6 +150,10 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
// OracleStorageClause storage = ((OracleExprParser) this.exprParser).parseStorage();
// stmt.setStorage(storage);
// continue;
} else if (identifierEquals("MONITORING")) {
lexer.nextToken();
stmt.setMonitoring(true);
continue;
} else if (lexer.token() == Token.LOB) {
OracleLobStorageClause lobStorage = ((OracleExprParser) this.exprParser).parseLobStorage();
stmt.setLobStorage(lobStorage);
@@ -2137,6 +2137,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
print0(ucase ? "PRESERVE ROWS" : "preserve rows");
}
if (x.isMonitoring()) {
println();
print0(ucase ? "MONITORING" : "monitoring");
}
if (x.getPartitioning() != null) {
println();
x.getPartitioning().accept(this);
@@ -2009,12 +2009,15 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
protected void printCreateTable(SQLCreateTableStatement x) {
print0(ucase ? "CREATE TABLE " : "create table ");
if (SQLCreateTableStatement.Type.GLOBAL_TEMPORARY.equals(x.getType())) {
print0(ucase ? "CREATE " : "create ");
final SQLCreateTableStatement.Type tableType = x.getType();
if (SQLCreateTableStatement.Type.GLOBAL_TEMPORARY.equals(tableType)) {
print0(ucase ? "GLOBAL TEMPORARY " : "global temporary ");
} else if (SQLCreateTableStatement.Type.LOCAL_TEMPORARY.equals(x.getType())) {
} else if (SQLCreateTableStatement.Type.LOCAL_TEMPORARY.equals(tableType)) {
print0(ucase ? "LOCAL TEMPORARY " : "local temporary ");
}
print0(ucase ? "TABLE " : "table ");
printTableSourceExpr(x.getName());
@@ -1,26 +1,23 @@
/*
* Copyright 1999-2017 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.sql.dialect.mysql.visitor;
public class MySql2OracleOutputVisitor extends MySqlOutputVisitor {
public MySql2OracleOutputVisitor(Appendable appender){
super(appender);
}
}
/*
* Copyright 1999-2017 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.sql.visitor;
/**
* Created by wenshao on 16/07/2017.
*/
public interface SQLTransformVisitor extends SQLASTVisitor {
String getSrcDbType();
}