improved sql parser. add new feature JdbcUtils.getCreateTableScript, for issue #1342

This commit is contained in:
wenshao
2017-07-24 01:16:43 +08:00
parent 2d8ded4f0c
commit 7a241d7da5
28 changed files with 662 additions and 40 deletions
@@ -42,9 +42,7 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.util.Utils;
import com.alibaba.druid.util.*;
public class SQLUtils {
public static FormatOption DEFAULT_FORMAT_OPTION = new FormatOption(true, true);
@@ -774,6 +772,10 @@ public class SQLUtils {
}
public static String normalize(String name) {
return normalize(name, null);
}
public static String normalize(String name, String dbType) {
if (name == null) {
return null;
}
@@ -782,7 +784,19 @@ public class SQLUtils {
char c0 = name.charAt(0);
char x0 = name.charAt(name.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
name = name.substring(1, name.length() - 1);
String normalizeName = name.substring(1, name.length() - 1);
if (JdbcConstants.ORACLE.equals(dbType)) {
if (OracleUtils.isKeyword(normalizeName)) {
return name;
}
} else if (JdbcConstants.MYSQL.equals(dbType)) {
if (MySqlUtils.isKeyword(normalizeName)) {
return name;
}
}
return normalizeName;
}
}
@@ -20,7 +20,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public abstract class SQLStatementImpl extends SQLObjectImpl implements SQLStatement {
private String dbType;
protected String dbType;
private boolean afterSemi;
@@ -26,8 +26,10 @@ import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElement {
protected String dbType;
protected SQLName name;
protected SQLDataType dataType;
@@ -287,6 +289,7 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
public SQLColumnDefinition clone() {
SQLColumnDefinition x = new SQLColumnDefinition();
x.setDbType(dbType);
if(name != null) {
x.setName(name.clone());
@@ -341,4 +344,26 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
return x;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public void simplify() {
enable = null;
validate = null;
rely = null;
if (this.name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
@@ -23,4 +23,6 @@ public interface SQLConstraint extends SQLObject {
SQLName getName();
void setName(SQLName value);
void simplify();
}
@@ -15,13 +15,16 @@
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import java.util.List;
public abstract class SQLConstraintImpl extends SQLObjectImpl implements SQLConstraint {
protected String dbType;
protected SQLName name;
private Boolean enable;
@@ -90,4 +93,21 @@ public abstract class SQLConstraintImpl extends SQLObjectImpl implements SQLCons
public void setRely(Boolean rely) {
this.rely = rely;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public void simplify() {
if (this.name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
@@ -20,11 +20,13 @@ import java.util.*;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.ListDG;
import com.alibaba.druid.util.lang.Consumer;
import org.apache.ibatis.jdbc.SQL;
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement {
@@ -59,6 +61,10 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
this.setTableSource(new SQLExprTableSource(name));
}
public void setName(String name) {
this.setName(new SQLIdentifierExpr(name));
}
public SQLExprTableSource getTableSource() {
return tableSource;
}
@@ -414,4 +420,37 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
}
}
public void simplify() {
SQLName name = getName();
if (name instanceof SQLPropertyExpr) {
String tableName = ((SQLPropertyExpr) name).getName();
tableName = SQLUtils.normalize(tableName);
setName(tableName);
name = getName();
}
if (name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) name;
String tableName = identExpr.getName();
tableName = SQLUtils.normalize(tableName, dbType);
identExpr.setName(tableName);
}
if (name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) name;
String tableName = identExpr.getName();
tableName = SQLUtils.normalize(tableName);
identExpr.setName(tableName);
}
for (SQLTableElement element : this.tableElementList) {
if (element instanceof SQLColumnDefinition) {
SQLColumnDefinition column = (SQLColumnDefinition) element;
column.simplify();
} else if (element instanceof SQLConstraint) {
((SQLConstraint) element).simplify();
}
}
}
}
@@ -18,8 +18,10 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint, SQLTableElement {
@@ -58,4 +60,17 @@ public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint,
x.addColumn(columnClone);
}
}
public void simplify() {
super.simplify();
for (SQLExpr column : columns) {
if (column instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) column;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
}
@@ -21,17 +21,17 @@ import com.alibaba.druid.sql.ast.statement.SQLUnique;
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTableConstraint {
private SQLName indexName;
private String indexType;
private boolean hasConstaint;
public MySqlKey(){
dbType = JdbcConstants.MYSQL;
}
@Override
@@ -45,7 +45,7 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, indexName);
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
@@ -58,14 +58,6 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
this.indexType = indexType;
}
public SQLName getIndexName() {
return indexName;
}
public void setIndexName(SQLName indexName) {
this.indexName = indexName;
}
public boolean isHasConstaint() {
return hasConstaint;
}
@@ -17,11 +17,12 @@ package com.alibaba.druid.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlPrimaryKey extends MySqlKey implements SQLPrimaryKey {
public MySqlPrimaryKey(){
dbType = JdbcConstants.MYSQL;
}
protected void accept0(MySqlASTVisitor visitor) {
@@ -28,7 +28,6 @@ public class MySqlUnique extends MySqlKey implements SQLPrimaryKey {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, this.getIndexName());
}
visitor.endVisit(this);
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
/**
* @author kiki
@@ -34,6 +35,10 @@ public class MysqlForeignKey extends SQLForeignKeyImpl {
protected Option onUpdate;
protected Option onDelete;
public MysqlForeignKey() {
dbType = JdbcConstants.MYSQL;
}
public SQLName getIndexName() {
return indexName;
}
@@ -165,8 +165,13 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
return tableGroup;
}
public void setTableGroup(SQLName tableGroup) {
this.tableGroup = tableGroup;
}
@Override
public void simplify() {
tableOptions.clear();
super.simplify();
}
}
@@ -774,7 +774,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_ALIAS) {
SQLName indexName = this.exprParser.name();
if (indexName != null) {
key.setIndexName(indexName);
key.setName(indexName);
}
}
@@ -542,6 +542,7 @@ public class MySqlExprParser extends SQLExprParser {
public SQLColumnDefinition parseColumn() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
column.setName(name());
column.setDataType(parseDataType());
@@ -813,7 +814,7 @@ public class MySqlExprParser extends SQLExprParser {
if (lexer.token() != Token.LPAREN) {
SQLName indexName = name();
unique.setIndexName(indexName);
unique.setName(indexName);
}
//5.5语法 USING BTREE 放在index 名字后
@@ -585,9 +585,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "KEY" : "key");
if (x.getIndexName() != null) {
SQLName name = x.getName();
if (name != null) {
print(' ');
x.getIndexName().accept(this);
name.accept(this);
}
if (x.getIndexType() != null) {
@@ -2844,9 +2845,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "UNIQUE" : "unique");
if (x.getIndexName() != null) {
SQLName name = x.getName();
if (name != null) {
print(' ');
x.getIndexName().accept(this);
name.accept(this);
}
if (x.getIndexType() != null) {
@@ -78,6 +78,29 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
private SQLName of;
private OIDIndex oidIndex;
private boolean monitoring;
public void simplify() {
tablespace = null;
storage = null;
lobStorage = null;
pctfree = null;
pctused = null;
initrans = null;
maxtrans = null;
pctincrease = null;
logging = null;
compress = null;
compressLevel = null;
compressForOltp = false;
onCommitPreserveRows = false;
onCommitDeleteRows = false;
super.simplify();
}
public OracleCreateTableStatement() {
super (JdbcConstants.ORACLE);
@@ -466,4 +489,5 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.name = name;
}
}
}
@@ -192,6 +192,7 @@ public class SQLServerExprParser extends SQLExprParser {
public SQLColumnDefinition createColumnDefinition() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
return column;
}
@@ -1980,6 +1980,7 @@ public class SQLExprParser extends SQLParser {
public SQLColumnDefinition createColumnDefinition() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
return column;
}
@@ -1012,13 +1012,14 @@ public class SQLStatementParser extends SQLParser {
lexer.nextToken();
SQLExpr comment = this.exprParser.primary();
SQLColumnDefinition columnDefinition = new SQLColumnDefinition();
columnDefinition.setName(columnName);
columnDefinition.setComment(comment);
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
column.setName(columnName);
column.setComment(comment);
SQLAlterTableAlterColumn changeColumn = new SQLAlterTableAlterColumn();
changeColumn.setColumn(columnDefinition);
changeColumn.setColumn(column);
stmt.addItem(changeColumn);
} else {
@@ -2232,6 +2233,7 @@ public class SQLStatementParser extends SQLParser {
createView.addColumn(constraint);
} else {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
SQLName expr = this.exprParser.name();
column.setName(expr);
@@ -1311,8 +1311,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
if (aliasMap != null) {
String alias = x.getAlias();
if (alias != null && !aliasMap.containsKey(alias)) {
putAliasMap(aliasMap, alias, ident);
if (alias != null) {
String table = aliasMap.get(alias);
if (!(ident.equals(table) || alias.equals(table))) {
putAliasMap(aliasMap, alias, ident);
}
}
if (!aliasMap.containsKey(ident)) {
putAliasMap(aliasMap, ident, ident);