mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser, support petadata.
This commit is contained in:
+31
-10
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
@@ -30,14 +31,15 @@ import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class MySqlDeleteStatement extends SQLDeleteStatement {
|
||||
|
||||
private boolean lowPriority = false;
|
||||
private boolean quick = false;
|
||||
private boolean ignore = false;
|
||||
|
||||
private boolean lowPriority = false;
|
||||
private boolean quick = false;
|
||||
private boolean ignore = false;
|
||||
private SQLOrderBy orderBy;
|
||||
private SQLLimit limit;
|
||||
|
||||
private SQLLimit limit;
|
||||
private List<SQLCommentHint> hints;
|
||||
// for petadata
|
||||
private boolean forceAllPartitions = false;
|
||||
private SQLName forcePartition;
|
||||
|
||||
public MySqlDeleteStatement(){
|
||||
super(JdbcConstants.MYSQL);
|
||||
@@ -137,14 +139,33 @@ public class MySqlDeleteStatement extends SQLDeleteStatement {
|
||||
|
||||
protected void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, getTableSource());
|
||||
acceptChild(visitor, getWhere());
|
||||
acceptChild(visitor, getFrom());
|
||||
acceptChild(visitor, getUsing());
|
||||
acceptChild(visitor, tableSource);
|
||||
acceptChild(visitor, where);
|
||||
acceptChild(visitor, from);
|
||||
acceptChild(visitor, using);
|
||||
acceptChild(visitor, orderBy);
|
||||
acceptChild(visitor, limit);
|
||||
}
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public boolean isForceAllPartitions() {
|
||||
return forceAllPartitions;
|
||||
}
|
||||
|
||||
public void setForceAllPartitions(boolean forceAllPartitions) {
|
||||
this.forceAllPartitions = forceAllPartitions;
|
||||
}
|
||||
|
||||
public SQLName getForcePartition() {
|
||||
return forcePartition;
|
||||
}
|
||||
|
||||
public void setForcePartition(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.forcePartition = x;
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -40,6 +40,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
private List<SQLExpr> procedureArgumentList;
|
||||
private boolean lockInShareMode;
|
||||
private List<SQLCommentHint> hints;
|
||||
private SQLName forcePartition; // for petadata
|
||||
|
||||
public MySqlSelectQueryBlock(){
|
||||
dbType = JdbcConstants.MYSQL;
|
||||
@@ -241,6 +242,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.selectList);
|
||||
acceptChild(visitor, this.forcePartition);
|
||||
acceptChild(visitor, this.from);
|
||||
acceptChild(visitor, this.where);
|
||||
acceptChild(visitor, this.groupBy);
|
||||
@@ -254,6 +256,17 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLName getForcePartition() {
|
||||
return forcePartition;
|
||||
}
|
||||
|
||||
public void setForcePartition(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.forcePartition = x;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toMySqlString(this);
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlShowDatabasePartitionStatusStatement extends MySqlStatementImpl implements MySqlShowStatement {
|
||||
|
||||
private SQLName database;
|
||||
|
||||
public SQLName getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(SQLName database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, database);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
+27
-5
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.SQLLimit;
|
||||
@@ -26,13 +27,17 @@ import com.alibaba.druid.util.JdbcConstants;
|
||||
public class MySqlUpdateStatement extends SQLUpdateStatement implements MySqlStatement {
|
||||
private SQLLimit limit;
|
||||
|
||||
private boolean lowPriority = false;
|
||||
private boolean ignore = false;
|
||||
private boolean commitOnSuccess = false;
|
||||
private boolean rollBackOnFail = false;
|
||||
private boolean queryOnPk = false;
|
||||
private boolean lowPriority = false;
|
||||
private boolean ignore = false;
|
||||
private boolean commitOnSuccess = false;
|
||||
private boolean rollBackOnFail = false;
|
||||
private boolean queryOnPk = false;
|
||||
private SQLExpr targetAffectRow;
|
||||
|
||||
// for petadata
|
||||
private boolean forceAllPartitions = false;
|
||||
private SQLName forcePartition;
|
||||
|
||||
public MySqlUpdateStatement(){
|
||||
super(JdbcConstants.MYSQL);
|
||||
}
|
||||
@@ -119,5 +124,22 @@ public class MySqlUpdateStatement extends SQLUpdateStatement implements MySqlSta
|
||||
this.targetAffectRow = targetAffectRow;
|
||||
}
|
||||
|
||||
public boolean isForceAllPartitions() {
|
||||
return forceAllPartitions;
|
||||
}
|
||||
|
||||
public void setForceAllPartitions(boolean forceAllPartitions) {
|
||||
this.forceAllPartitions = forceAllPartitions;
|
||||
}
|
||||
|
||||
public SQLName getForcePartition() {
|
||||
return forcePartition;
|
||||
}
|
||||
|
||||
public void setForcePartition(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.forcePartition = x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,13 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
}
|
||||
|
||||
parseSelectList(queryBlock);
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FORCE)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.PARTITION);
|
||||
SQLName partition = this.exprParser.name();
|
||||
queryBlock.setForcePartition(partition);
|
||||
}
|
||||
|
||||
parseInto(queryBlock);
|
||||
}
|
||||
@@ -297,6 +304,25 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
update.setTargetAffectRow(targetAffectRow);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FORCE)) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.ALL) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("PARTITIONS");
|
||||
update.setForceAllPartitions(true);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.PARTITIONS)){
|
||||
lexer.nextToken();
|
||||
update.setForceAllPartitions(true);
|
||||
} else if (lexer.token() == Token.PARTITION) {
|
||||
lexer.nextToken();
|
||||
SQLName partition = this.exprParser.name();
|
||||
update.setForcePartition(partition);
|
||||
} else {
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
}
|
||||
}
|
||||
|
||||
SQLSelectParser selectParser = this.exprParser.createSelectParser();
|
||||
SQLTableSource updateTableSource = selectParser.parseTableSource();
|
||||
update.setTableSource(updateTableSource);
|
||||
|
||||
@@ -157,6 +157,26 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FORCE)) {
|
||||
Lexer.SavePoint savePoint = lexer.mark();
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.ALL) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("PARTITIONS");
|
||||
deleteStatement.setForceAllPartitions(true);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.PARTITIONS)){
|
||||
lexer.nextToken();
|
||||
deleteStatement.setForceAllPartitions(true);
|
||||
} else if (lexer.token() == Token.PARTITION) {
|
||||
lexer.nextToken();
|
||||
SQLName partition = this.exprParser.name();
|
||||
deleteStatement.setForcePartition(partition);
|
||||
} else {
|
||||
lexer.reset(savePoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
deleteStatement.setTableSource(createSQLSelectParser().parseTableSource());
|
||||
|
||||
@@ -1740,6 +1760,16 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
return stmt;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.DATABASE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.PARTITION);
|
||||
acceptIdentifier("STATUS");
|
||||
accept(Token.FOR);
|
||||
MySqlShowDatabasePartitionStatusStatement stmt = new MySqlShowDatabasePartitionStatusStatement();
|
||||
stmt.setDatabase(this.exprParser.name());
|
||||
return stmt;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("TRIGGERS")) {
|
||||
lexer.nextToken();
|
||||
MySqlShowTriggersStatement stmt = new MySqlShowTriggersStatement();
|
||||
|
||||
@@ -491,4 +491,7 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(MySqlAlterTablespaceStatement x);
|
||||
void endVisit(MySqlAlterTablespaceStatement x);
|
||||
|
||||
boolean visit(MySqlShowDatabasePartitionStatusStatement x);
|
||||
void endVisit(MySqlShowDatabasePartitionStatusStatement x);
|
||||
|
||||
} //
|
||||
|
||||
@@ -1218,4 +1218,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
|
||||
}
|
||||
|
||||
} //
|
||||
|
||||
@@ -173,6 +173,13 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
printSelectList(x.getSelectList());
|
||||
|
||||
SQLName forcePartition = x.getForcePartition();
|
||||
if (forcePartition != null) {
|
||||
println();
|
||||
print0(ucase ? "FORCE PARTITION " : "force partition ");
|
||||
printExpr(forcePartition);
|
||||
}
|
||||
|
||||
SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
println();
|
||||
@@ -782,6 +789,17 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print0(ucase ? "IGNORE " : "ignore ");
|
||||
}
|
||||
|
||||
if (x.isForceAllPartitions()) {
|
||||
print0(ucase ? "FORCE ALL PARTITIONS " : "force all partitions ");
|
||||
} else {
|
||||
SQLName partition = x.getForcePartition();
|
||||
if (partition != null) {
|
||||
print0(ucase ? "FORCE PARTITION " : "force partition ");
|
||||
printExpr(partition);
|
||||
print(' ');
|
||||
}
|
||||
}
|
||||
|
||||
SQLTableSource from = x.getFrom();
|
||||
if (from == null) {
|
||||
print0(ucase ? "FROM " : "from ");
|
||||
@@ -1593,6 +1611,17 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print(' ');
|
||||
}
|
||||
|
||||
if (x.isForceAllPartitions()) {
|
||||
print0(ucase ? "FORCE ALL PARTITIONS " : "force all partitions ");
|
||||
} else {
|
||||
SQLName partition = x.getForcePartition();
|
||||
if (partition != null) {
|
||||
print0(ucase ? "FORCE PARTITION " : "force partition ");
|
||||
printExpr(partition);
|
||||
print(' ');
|
||||
}
|
||||
}
|
||||
|
||||
printTableSource(x.getTableSource());
|
||||
|
||||
println();
|
||||
@@ -4037,6 +4066,18 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
print0(ucase ? "SHOW DATABASE PARTITION STATUS FOR " : "show database partition status for ");
|
||||
x.getDatabase().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
|
||||
}
|
||||
|
||||
protected void printQuery(SQLSelectQuery x) {
|
||||
Class<?> clazz = x.getClass();
|
||||
if (clazz == MySqlSelectQueryBlock.class) {
|
||||
|
||||
@@ -1344,4 +1344,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
public void endVisit(MySqlAlterTablespaceStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlShowDatabasePartitionStatusStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2992,8 +2992,24 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
if ((token == Token.IDENTIFIER && hash_lower != FnvHash.Constants.CURRENT)
|
||||
|| token == Token.MODEL) {
|
||||
String as = lexer.stringVal();
|
||||
lexer.nextTokenComma();
|
||||
String as;
|
||||
if (lexer.hash_lower == FnvHash.Constants.FORCE && JdbcConstants.MYSQL.equals(dbType)) {
|
||||
String force = lexer.stringVal();
|
||||
|
||||
Lexer.SavePoint savePoint = lexer.mark();
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token == Token.PARTITION) {
|
||||
lexer.reset(savePoint);
|
||||
as = null;
|
||||
} else {
|
||||
as = force;
|
||||
lexer.nextTokenComma();
|
||||
}
|
||||
} else {
|
||||
as = lexer.stringVal();
|
||||
lexer.nextTokenComma();
|
||||
}
|
||||
return new SQLSelectItem(expr, as, connectByRoot);
|
||||
}
|
||||
|
||||
|
||||
@@ -614,5 +614,6 @@ public final class FnvHash {
|
||||
long CLUSTERED = fnv1a_64_lower("CLUSTERED");
|
||||
long SORTED = fnv1a_64_lower("SORTED");
|
||||
long LIFECYCLE = fnv1a_64_lower("LIFECYCLE");
|
||||
long PARTITIONS = fnv1a_64_lower("PARTITIONS");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user