mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser schema repository.
This commit is contained in:
@@ -21,6 +21,7 @@ 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.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||
@@ -235,6 +236,9 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
if (column instanceof SQLIdentifierExpr
|
||||
&& SQLUtils.nameEquals(columnName, ((SQLIdentifierExpr) column).getName())) {
|
||||
return unique.columns.size() > 1;
|
||||
} else if (column instanceof SQLMethodInvokeExpr
|
||||
&& SQLUtils.nameEquals(((SQLMethodInvokeExpr) column).getMethodName(), columnName)) {
|
||||
return true;
|
||||
}
|
||||
} else if (element instanceof MySqlKey) {
|
||||
MySqlKey unique = (MySqlKey) element;
|
||||
@@ -243,6 +247,9 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
if (column instanceof SQLIdentifierExpr
|
||||
&& SQLUtils.nameEquals(columnName, ((SQLIdentifierExpr) column).getName())) {
|
||||
return true;
|
||||
} else if (column instanceof SQLMethodInvokeExpr
|
||||
&& SQLUtils.nameEquals(((SQLMethodInvokeExpr) column).getMethodName(), columnName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,6 +272,9 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
if (column instanceof SQLIdentifierExpr
|
||||
&& SQLUtils.nameEquals(columnName, ((SQLIdentifierExpr) column).getName())) {
|
||||
return unique.columns.size() == 1;
|
||||
} else if (column instanceof SQLMethodInvokeExpr
|
||||
&& SQLUtils.nameEquals(((SQLMethodInvokeExpr) column).getMethodName(), columnName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ public class SQLGrantStatement extends SQLStatementImpl {
|
||||
private boolean adminOption;
|
||||
|
||||
private SQLExpr identifiedBy;
|
||||
private String identifiedByPassword;
|
||||
|
||||
private boolean withGrantOption;
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
@@ -135,4 +138,20 @@ public class SQLGrantStatement extends SQLStatementImpl {
|
||||
public void setIdentifiedBy(SQLExpr identifiedBy) {
|
||||
this.identifiedBy = identifiedBy;
|
||||
}
|
||||
|
||||
public String getIdentifiedByPassword() {
|
||||
return identifiedByPassword;
|
||||
}
|
||||
|
||||
public void setIdentifiedByPassword(String identifiedByPassword) {
|
||||
this.identifiedByPassword = identifiedByPassword;
|
||||
}
|
||||
|
||||
public boolean getWithGrantOption() {
|
||||
return withGrantOption;
|
||||
}
|
||||
|
||||
public void setWithGrantOption(boolean withGrantOption) {
|
||||
this.withGrantOption = withGrantOption;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ 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.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint, SQLTableElement {
|
||||
@@ -122,6 +123,12 @@ public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint,
|
||||
columns.remove(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLMethodInvokeExpr
|
||||
&& SQLUtils.nameEquals(((SQLMethodInvokeExpr) expr).getMethodName(), columnName.getSimpleName())) {
|
||||
columns.remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+5
-4
@@ -215,15 +215,16 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
|
||||
}
|
||||
|
||||
public boolean apply(SQLAlterTableAddIndex item) {
|
||||
if (item.isKey()) {
|
||||
MySqlPrimaryKey x = new MySqlPrimaryKey();
|
||||
if (item.isUnique()) {
|
||||
MySqlUnique x = new MySqlUnique();
|
||||
item.cloneTo(x);
|
||||
x.setParent(this);
|
||||
this.tableElementList.add(x);
|
||||
return true;
|
||||
}
|
||||
if (item.isUnique()) {
|
||||
MySqlUnique x = new MySqlUnique();
|
||||
|
||||
if (item.isKey()) {
|
||||
MySqlKey x = new MySqlKey();
|
||||
item.cloneTo(x);
|
||||
x.setParent(this);
|
||||
this.tableElementList.add(x);
|
||||
|
||||
+7
-6
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
@@ -46,22 +47,22 @@ public class MySqlRenameTableStatement extends MySqlStatementImpl {
|
||||
|
||||
public static class Item extends MySqlObjectImpl {
|
||||
|
||||
private SQLExpr name;
|
||||
private SQLExpr to;
|
||||
private SQLName name;
|
||||
private SQLName to;
|
||||
|
||||
public SQLExpr getName() {
|
||||
public SQLName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SQLExpr name) {
|
||||
public void setName(SQLName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SQLExpr getTo() {
|
||||
public SQLName getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setTo(SQLExpr to) {
|
||||
public void setTo(SQLName to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -21,6 +21,7 @@ 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.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
|
||||
@@ -29,8 +30,8 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlTableIndex extends MySqlObjectImpl implements SQLTableElement {
|
||||
|
||||
private SQLName name;
|
||||
private String indexType;
|
||||
private SQLName name;
|
||||
private String indexType;
|
||||
private List<SQLSelectOrderByItem> columns = new ArrayList<SQLSelectOrderByItem>();
|
||||
|
||||
public MySqlTableIndex(){
|
||||
@@ -106,6 +107,11 @@ public class MySqlTableIndex extends MySqlObjectImpl implements SQLTableElement
|
||||
columns.remove(i);
|
||||
return true;
|
||||
}
|
||||
if (expr instanceof SQLMethodInvokeExpr
|
||||
&& SQLUtils.nameEquals(((SQLMethodInvokeExpr) expr).getMethodName(), columnName.getSimpleName())) {
|
||||
columns.remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -785,6 +785,11 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token() != Token.LPAREN) {
|
||||
SQLName name = this.name();
|
||||
primaryKey.setName(name);
|
||||
}
|
||||
|
||||
accept(Token.LPAREN);
|
||||
for (;;) {
|
||||
primaryKey.addColumn(this.expr());
|
||||
|
||||
@@ -2464,7 +2464,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
if (lexer.token() == Token.COLUMN) {
|
||||
lexer.nextToken();
|
||||
parseAlterTableAddColumn(stmt);
|
||||
} else if (lexer.token() == Token.INDEX) {
|
||||
} else if (lexer.token() == Token.INDEX || identifierEquals("FULLTEXT")) {
|
||||
SQLAlterTableAddIndex item = parseAlterTableAddIndex();
|
||||
item.setParent(stmt);
|
||||
stmt.addItem(item);
|
||||
@@ -2484,31 +2484,52 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.addItem(item);
|
||||
} else if (lexer.token() == Token.CONSTRAINT) {
|
||||
lexer.nextToken();
|
||||
SQLName constraintName = this.exprParser.name();
|
||||
|
||||
if (lexer.token() == Token.PRIMARY) {
|
||||
SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey();
|
||||
|
||||
primaryKey.setName(constraintName);
|
||||
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
|
||||
item.setParent(stmt);
|
||||
|
||||
stmt.addItem(item);
|
||||
} else if (lexer.token() == Token.FOREIGN) {
|
||||
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
|
||||
fk.setName(constraintName);
|
||||
fk.setHasConstraint(true);
|
||||
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(fk);
|
||||
|
||||
stmt.addItem(item);
|
||||
} else if (lexer.token() == Token.UNIQUE) {
|
||||
|
||||
SQLUnique unique = this.exprParser.parseUnique();
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(unique);
|
||||
stmt.addItem(item);
|
||||
} else {
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
SQLName constraintName = this.exprParser.name();
|
||||
|
||||
if (lexer.token() == Token.PRIMARY) {
|
||||
SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey();
|
||||
|
||||
primaryKey.setName(constraintName);
|
||||
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
|
||||
item.setParent(stmt);
|
||||
|
||||
stmt.addItem(item);
|
||||
} else if (lexer.token() == Token.FOREIGN) {
|
||||
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
|
||||
fk.setName(constraintName);
|
||||
fk.setHasConstraint(true);
|
||||
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(fk);
|
||||
|
||||
stmt.addItem(item);
|
||||
} else if (lexer.token() == Token.UNIQUE) {
|
||||
SQLUnique unique = this.exprParser.parseUnique();
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(unique);
|
||||
stmt.addItem(item);
|
||||
} else {
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
}
|
||||
}
|
||||
} else if (lexer.token() == Token.PARTITION) {
|
||||
lexer.nextToken();
|
||||
@@ -2647,7 +2668,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
MySqlRenameTableStatement renameStmt = new MySqlRenameTableStatement();
|
||||
MySqlRenameTableStatement.Item item = new MySqlRenameTableStatement.Item();
|
||||
item.setName(stmt.getTableSource().getExpr());
|
||||
item.setName((SQLName) stmt.getTableSource().getExpr());
|
||||
item.setTo(this.exprParser.name());
|
||||
renameStmt.addItem(item);
|
||||
|
||||
|
||||
@@ -458,15 +458,21 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlTableIndex x) {
|
||||
String indexType = x.getIndexType();
|
||||
|
||||
if ("FULLTEXT".equalsIgnoreCase(indexType)) {
|
||||
print0(ucase ? "FULLTEXT " : "fulltext ");
|
||||
}
|
||||
|
||||
print0(ucase ? "INDEX" : "index");
|
||||
if (x.getName() != null) {
|
||||
print(' ');
|
||||
x.getName().accept(this);
|
||||
}
|
||||
|
||||
if (x.getIndexType() != null) {
|
||||
if (indexType != null && !"FULLTEXT".equalsIgnoreCase(indexType)) {
|
||||
print0(ucase ? " USING " : " using ");
|
||||
print0(x.getIndexType());
|
||||
print0(indexType);
|
||||
}
|
||||
|
||||
print('(');
|
||||
|
||||
+2
-2
@@ -133,9 +133,9 @@ public class MySqlShowColumnOutpuVisitor extends MySqlOutputVisitor {
|
||||
print(" | ");
|
||||
|
||||
if (column.containsNotNullConstaint()) {
|
||||
print("YES");
|
||||
} else {
|
||||
print("NO ");
|
||||
} else {
|
||||
print("YES");
|
||||
}
|
||||
print(" | ");
|
||||
|
||||
|
||||
@@ -613,7 +613,24 @@ public class SQLStatementParser extends SQLParser {
|
||||
if (lexer.token() == Token.IDENTIFIED) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
stmt.setIdentifiedBy(this.exprParser.expr());
|
||||
|
||||
if (identifierEquals("PASSWORD")) {
|
||||
lexer.nextToken();
|
||||
String password = lexer.stringVal();
|
||||
accept(Token.LITERAL_CHARS);
|
||||
stmt.setIdentifiedByPassword(password);
|
||||
} else {
|
||||
stmt.setIdentifiedBy(this.exprParser.expr());
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.GRANT) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("OPTION");
|
||||
stmt.setWithGrantOption(true);
|
||||
}
|
||||
}
|
||||
|
||||
return stmt;
|
||||
@@ -626,6 +643,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("PRIVILEGES")) {
|
||||
privilege = "ALL PRIVILEGES";
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
privilege = "ALL";
|
||||
}
|
||||
@@ -2403,6 +2421,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
protected SQLAlterTableAddIndex parseAlterTableAddIndex() {
|
||||
SQLAlterTableAddIndex item = new SQLAlterTableAddIndex();
|
||||
|
||||
if (identifierEquals("FULLTEXT")) {
|
||||
lexer.nextToken();
|
||||
item.setType("FULLTEXT");
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.UNIQUE) {
|
||||
item.setUnique(true);
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -22,10 +22,7 @@ import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
|
||||
@@ -283,8 +280,17 @@ public class SchemaRepository {
|
||||
MySqlShowCreateTableStatement showCreateTableStmt = (MySqlShowCreateTableStatement) stmt;
|
||||
SQLName table = showCreateTableStmt.getName();
|
||||
SchemaObject schemaObject = findTable(table);
|
||||
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
|
||||
createTableStmt.output(buf);
|
||||
if (schemaObject == null) {
|
||||
buf.append("ERROR 1146 (42S02): Table '" + table + "' doesn't exist\n");
|
||||
} else {
|
||||
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
|
||||
createTableStmt.output(buf);
|
||||
}
|
||||
} else if (stmt instanceof MySqlRenameTableStatement) {
|
||||
MySqlRenameTableStatement renameStmt = (MySqlRenameTableStatement) stmt;
|
||||
for (MySqlRenameTableStatement.Item item : renameStmt.getItems()) {
|
||||
renameTable(item.getName(), item.getTo());
|
||||
}
|
||||
} else if (stmt instanceof SQLShowTablesStatement) {
|
||||
SQLShowTablesStatement showTables = (SQLShowTablesStatement) stmt;
|
||||
SQLName database = showTables.getDatabase();
|
||||
@@ -337,6 +343,36 @@ public class SchemaRepository {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean renameTable(SQLName name, SQLName to) {
|
||||
Schema schema;
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
String schemaName = ((SQLPropertyExpr) name).getOwnernName();
|
||||
schema = findSchema(schemaName);
|
||||
} else {
|
||||
schema = getDefaultSchema();
|
||||
}
|
||||
|
||||
if (schema == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String tableName = name.getSimpleName();
|
||||
SchemaObject schemaObject = schema.findTable(tableName);
|
||||
if (schemaObject != null) {
|
||||
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
|
||||
if (createTableStmt != null) {
|
||||
createTableStmt.setName(to.clone());
|
||||
}
|
||||
|
||||
String toName = SQLUtils.normalize(to.getSimpleName()).toLowerCase();
|
||||
schema.objects.put(toName, schemaObject);
|
||||
|
||||
String name_lower = SQLUtils.normalize(tableName).toLowerCase();
|
||||
schema.objects.remove(name_lower);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private class MySqlResolveVisitor extends MySqlASTVisitorAdapter implements SchemaResolveVisitor {
|
||||
private int options;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user