improved mysql parser for 'create procedure statement support'

This commit is contained in:
高铁
2016-01-13 09:16:25 +08:00
parent 4536e6e9b6
commit adada50173
18 changed files with 300 additions and 176 deletions
@@ -18,54 +18,40 @@ package com.alibaba.druid.sql.dialect.mysql.ast.clause;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
/**
*
* @Description: MySql declare statement
* @author zz email:455910092@qq.com
* @date 2015-9-14
* @version V1.0
*/
public class MySqlDeclareStatement extends MySqlStatementImpl{
//var type
private SQLDataType type;
//var list
private List<SQLExpr> varList=new ArrayList<SQLExpr>();
public class MySqlDeclareStatement extends MySqlStatementImpl {
public List<SQLExpr> getVarList() {
return varList;
}
public void addVar(SQLExpr expr)
{
varList.add(expr);
}
private List<SQLDeclareItem> varList = new ArrayList<SQLDeclareItem>();
public void setVarList(List<SQLExpr> varList) {
this.varList = varList;
}
public List<SQLDeclareItem> getVarList() {
return varList;
}
public SQLDataType getType() {
return type;
}
public void addVar(SQLDeclareItem expr) {
varList.add(expr);
}
public void setType(SQLDataType type) {
this.type = type;
}
public void setVarList(List<SQLDeclareItem> varList) {
this.varList = varList;
}
@Override
public void accept0(MySqlASTVisitor visitor) {
// TODO Auto-generated method stub
if (visitor.visit(this)) {
acceptChild(visitor, type);
acceptChild(visitor, varList);
}
visitor.endVisit(this);
}
@Override
public void accept0(MySqlASTVisitor visitor) {
// TODO Auto-generated method stub
if (visitor.visit(this)) {
acceptChild(visitor, varList);
}
visitor.endVisit(this);
}
}
@@ -20,6 +20,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
@@ -29,7 +30,6 @@ import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
@@ -378,7 +378,7 @@ public class MySqlStatementParser extends SQLStatementParser {
return parseCreateTrigger();
}
//parse create procedure
if (lexer.token() == Token.PROCEDURE) {
if (lexer.token() == Token.PROCEDURE || identifierEquals("DEFINER")) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
@@ -2765,12 +2765,19 @@ public class MySqlStatementParser extends SQLStatementParser {
*/
SQLCreateProcedureStatement stmt = new SQLCreateProcedureStatement();
accept(Token.CREATE);
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
stmt.setOrReplace(true);
}
if(identifierEquals("DEFINER")) {
lexer.nextToken();
accept(Token.EQ);
SQLName definer = this.exprParser.name();
stmt.setDefiner(definer);
} else {
accept(Token.CREATE);
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
stmt.setOrReplace(true);
}
}
accept(Token.PROCEDURE);
@@ -2793,6 +2800,10 @@ public class MySqlStatementParser extends SQLStatementParser {
* @param parameters
*/
private void parserParameters(List<SQLParameter> parameters) {
if (lexer.token() == Token.RPAREN) {
return;
}
for (;;) {
SQLParameter parameter = new SQLParameter();
@@ -3264,37 +3275,35 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse declare statement
*/
public MySqlDeclareStatement parseDeclare()
{
MySqlDeclareStatement stmt=new MySqlDeclareStatement();
accept(Token.DECLARE);
//lexer.nextToken();
for(;;)
{
SQLExpr var = exprParser.primary();
if (var instanceof SQLIdentifierExpr) {
var = new SQLVariantRefExpr(((SQLIdentifierExpr) var).getName());
}
stmt.addVar(var);
if(lexer.token()==Token.COMMA)
{
accept(Token.COMMA);
continue;
}
else if(lexer.token()!=Token.EOF)
{
//var type
stmt.setType(exprParser.parseDataType());
break;
}
else
{
setErrorEndPos(lexer.pos());
printError(lexer.token());
}
}
return stmt;
}
public MySqlDeclareStatement parseDeclare() {
MySqlDeclareStatement stmt = new MySqlDeclareStatement();
accept(Token.DECLARE);
// lexer.nextToken();
for (;;) {
SQLDeclareItem item = new SQLDeclareItem();
item.setName(exprParser.name());
stmt.addVar(item);
if (lexer.token() == Token.COMMA) {
accept(Token.COMMA);
continue;
} else if (lexer.token() != Token.EOF) {
// var type
item.setDataType(exprParser.parseDataType());
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
SQLExpr defaultValue = this.exprParser.primary();
item.setValue(defaultValue);
}
break;
} else {
throw new ParserException("TODO");
}
}
return stmt;
}
/**
* parse assign statement
@@ -164,8 +164,12 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTVisitor {
{
this.dbType = JdbcConstants.MYSQL;
}
public MySqlOutputVisitor(Appendable appender){
super(appender);
@@ -3179,8 +3183,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
int paramSize = x.getParameters().size();
print0(" (");
if (paramSize > 0) {
print0(" (");
incrementIndent();
println();
@@ -3195,8 +3199,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
decrementIndent();
println();
print(')');
}
print(')');
println();
x.getBlock().setParent(x);
@@ -3317,13 +3321,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(MySqlDeclareStatement x) {
print0(ucase ? "DECLARE " : "declare ");
for (int i = 0; i < x.getVarList().size(); i++) {
x.getVarList().get(i).accept(this);
if(i!=x.getVarList().size()-1)
print0(", ");
}
print(' ');
x.getType().accept(this);
printAndAccept(x.getVarList(), ", ");
return false;
}
@@ -17,11 +17,10 @@ package com.alibaba.druid.sql.dialect.mysql.visitor;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
@@ -1359,11 +1358,11 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
@Override
public boolean visit(MySqlDeclareStatement x) {
for (SQLExpr item : x.getVarList()) {
for (SQLDeclareItem item : x.getVarList()) {
item.setParent(x);
SQLVariantRefExpr var = (SQLVariantRefExpr)item;
this.variants.put(var.getName(), var);
SQLName var = (SQLName)item.getName();
this.variants.put(var.toString(), var);
}
return false;
@@ -1,93 +0,0 @@
/*
* Copyright 1999-2101 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.sqlserver.ast;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
public class SQLServerDeclareItem extends SQLServerObjectImpl {
protected Type type;
protected SQLExpr name;
protected SQLDataType dataType;
protected SQLExpr value;
protected List<SQLTableElement> tableElementList = new ArrayList<SQLTableElement>();
@Override
public void accept0(SQLServerASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.name);
acceptChild(visitor, this.dataType);
acceptChild(visitor, this.value);
acceptChild(visitor, this.tableElementList);
}
visitor.endVisit(this);
}
public SQLExpr getName() {
return name;
}
public void setName(SQLExpr name) {
this.name = name;
}
public SQLDataType getDataType() {
return dataType;
}
public void setDataType(SQLDataType dataType) {
this.dataType = dataType;
}
public SQLExpr getValue() {
return value;
}
public void setValue(SQLExpr value) {
this.value = value;
}
public List<SQLTableElement> getTableElementList() {
return tableElementList;
}
public void setTableElementList(List<SQLTableElement> tableElementList) {
this.tableElementList = tableElementList;
}
public enum Type {
TABLE, LOCAL, CURSOR;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
}
@@ -18,14 +18,14 @@ package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
public class SQLServerDeclareStatement extends SQLServerObjectImpl implements SQLServerStatement {
protected List<SQLServerDeclareItem> items = new ArrayList<SQLServerDeclareItem>();
protected List<SQLDeclareItem> items = new ArrayList<SQLDeclareItem>();
private String dbType;
@@ -37,11 +37,11 @@ public class SQLServerDeclareStatement extends SQLServerObjectImpl implements SQ
visitor.endVisit(this);
}
public List<SQLServerDeclareItem> getItems() {
public List<SQLDeclareItem> getItems() {
return items;
}
public void setItems(List<SQLServerDeclareItem> items) {
public void setItems(List<SQLDeclareItem> items) {
this.items = items;
}
@@ -21,6 +21,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
@@ -34,7 +35,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement;
@@ -171,7 +171,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
SQLServerDeclareStatement declareStatement = new SQLServerDeclareStatement();
for (;;) {
SQLServerDeclareItem item = new SQLServerDeclareItem();
SQLDeclareItem item = new SQLDeclareItem();
declareStatement.getItems().add(item);
item.setName(this.exprParser.name());
@@ -182,7 +182,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
item.setType(SQLServerDeclareItem.Type.TABLE);
item.setType(SQLDeclareItem.Type.TABLE);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
@@ -221,10 +221,10 @@ public class SQLServerStatementParser extends SQLStatementParser {
}
break;
} else if (lexer.token() == Token.CURSOR) {
item.setType(SQLServerDeclareItem.Type.CURSOR);
item.setType(SQLDeclareItem.Type.CURSOR);
lexer.nextToken();
} else {
item.setType(SQLServerDeclareItem.Type.LOCAL);
item.setType(SQLDeclareItem.Type.LOCAL);
item.setDataType(this.exprParser.parseDataType());
if (lexer.token() == Token.EQ) {
lexer.nextToken();
@@ -16,7 +16,6 @@
package com.alibaba.druid.sql.dialect.sqlserver.visitor;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
@@ -79,10 +78,6 @@ public interface SQLServerASTVisitor extends SQLASTVisitor {
boolean visit(SQLServerOutput x);
void endVisit(SQLServerOutput x);
boolean visit(SQLServerDeclareItem x);
void endVisit(SQLServerDeclareItem x);
boolean visit(SQLServerDeclareStatement x);
@@ -16,7 +16,6 @@
package com.alibaba.druid.sql.dialect.sqlserver.visitor;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
@@ -146,16 +145,6 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements
}
@Override
public boolean visit(SQLServerDeclareItem x) {
return true;
}
@Override
public void endVisit(SQLServerDeclareItem x) {
}
@Override
public boolean visit(SQLServerDeclareStatement x) {
return true;
@@ -26,7 +26,6 @@ import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
@@ -429,48 +428,6 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
}
@Override
public boolean visit(SQLServerDeclareItem x) {
x.getName().accept(this);
if(x.getType() == SQLServerDeclareItem.Type.TABLE) {
print0(ucase ? " TABLE" : " table");
int size = x.getTableElementList().size();
if (size > 0) {
print0(" (");
incrementIndent();
println();
for (int i = 0; i < size; ++i) {
if (i != 0) {
print(',');
println();
}
x.getTableElementList().get(i).accept(this);
}
decrementIndent();
println();
print(')');
}
} else if (x.getType() == SQLServerDeclareItem.Type.CURSOR) {
print0(ucase ? " CURSOR" : " cursor");
} else {
print(' ');
x.getDataType().accept(this);
if (x.getValue() != null) {
print0(" = ");
x.getValue().accept(this);
}
}
return false;
}
@Override
public void endVisit(SQLServerDeclareItem x) {
}
@Override
public boolean visit(SQLServerDeclareStatement x) {
print0(ucase ? "DECLARE " : "declare ");
@@ -17,13 +17,13 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
@@ -176,19 +176,9 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL
}
@Override
public boolean visit(SQLServerDeclareItem x) {
return false;
}
@Override
public void endVisit(SQLServerDeclareItem x) {
}
@Override
public boolean visit(SQLServerDeclareStatement x) {
for (SQLServerDeclareItem item : x.getItems()) {
for (SQLDeclareItem item : x.getItems()) {
item.setParent(x);
SQLExpr name = item.getName();