mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.9-preview_1</version>
|
||||
<version>1.1.11-preview_1</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<name>druid</name>
|
||||
|
||||
@@ -19,7 +19,7 @@ public final class VERSION {
|
||||
|
||||
public final static int MajorVersion = 1;
|
||||
public final static int MinorVersion = 1;
|
||||
public final static int RevisionVersion = 10;
|
||||
public final static int RevisionVersion = 11;
|
||||
|
||||
public static String getVersionNumber() {
|
||||
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
|
||||
|
||||
@@ -1632,7 +1632,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
|
||||
validateConnection(conn);
|
||||
validatedNanos = System.nanoTime();
|
||||
|
||||
|
||||
setFailContinuous(false);
|
||||
setCreateError(null);
|
||||
} catch (SQLException ex) {
|
||||
setCreateError(ex);
|
||||
|
||||
@@ -2294,7 +2294,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
try {
|
||||
physicalConnection = createPhysicalConnection();
|
||||
setFailContinuous(false);
|
||||
} catch (OutOfMemoryError e) {
|
||||
LOG.error("create connection OutOfMemoryError, out memory. ", e);
|
||||
|
||||
@@ -2466,7 +2465,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
try {
|
||||
connection = createPhysicalConnection();
|
||||
setFailContinuous(false);
|
||||
} catch (SQLException e) {
|
||||
LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
|
||||
+ ", state " + e.getSQLState(), e);
|
||||
|
||||
@@ -17,6 +17,9 @@ package com.alibaba.druid.sql.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr {
|
||||
|
||||
public SQLExprImpl(){
|
||||
@@ -27,11 +30,16 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr {
|
||||
|
||||
public abstract int hashCode();
|
||||
|
||||
public abstract SQLExpr clone();
|
||||
public SQLExpr clone() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public List<SQLObject> getChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
protected SQLAggregateOption option;
|
||||
protected final List<SQLExpr> arguments = new ArrayList<SQLExpr>();
|
||||
protected SQLKeep keep;
|
||||
protected SQLExpr filter;
|
||||
protected SQLOver over;
|
||||
protected SQLName overRef;
|
||||
protected SQLOrderBy withinGroup;
|
||||
@@ -186,6 +187,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
if (option != that.option) return false;
|
||||
if (arguments != null ? !arguments.equals(that.arguments) : that.arguments != null) return false;
|
||||
if (keep != null ? !keep.equals(that.keep) : that.keep != null) return false;
|
||||
if (filter != null ? !filter.equals(that.filter) : that.filter != null) return false;
|
||||
if (over != null ? !over.equals(that.over) : that.over != null) return false;
|
||||
if (overRef != null ? !overRef.equals(that.overRef) : that.overRef != null) return false;
|
||||
if (withinGroup != null ? !withinGroup.equals(that.withinGroup) : that.withinGroup != null) return false;
|
||||
@@ -199,6 +201,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
result = 31 * result + (option != null ? option.hashCode() : 0);
|
||||
result = 31 * result + (arguments != null ? arguments.hashCode() : 0);
|
||||
result = 31 * result + (keep != null ? keep.hashCode() : 0);
|
||||
result = 31 * result + (filter != null ? filter.hashCode() : 0);
|
||||
result = 31 * result + (over != null ? over.hashCode() : 0);
|
||||
result = 31 * result + (overRef != null ? overRef.hashCode() : 0);
|
||||
result = 31 * result + (withinGroup != null ? withinGroup.hashCode() : 0);
|
||||
@@ -219,6 +222,10 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
x.setKeep(keep.clone());
|
||||
}
|
||||
|
||||
if (filter != null) {
|
||||
x.setFilter(filter.clone());
|
||||
}
|
||||
|
||||
if (over != null) {
|
||||
x.setOver(over.clone());
|
||||
}
|
||||
@@ -236,6 +243,17 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLExpr getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(SQLExpr x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.filter = x;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
long hash = methodNameHashCod64();
|
||||
|
||||
@@ -277,6 +295,11 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
return true;
|
||||
}
|
||||
|
||||
if (filter == expr) {
|
||||
this.filter = target;
|
||||
target.setParent(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,6 +431,21 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrimaryKey() {
|
||||
for (SQLColumnConstraint constraint : constraints) {
|
||||
if (constraint instanceof SQLColumnPrimaryKey) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent instanceof SQLCreateTableStatement) {
|
||||
return ((SQLCreateTableStatement) parent)
|
||||
.isPrimaryColumn(nameHashCode64());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toSQLString(this, dbType);
|
||||
}
|
||||
|
||||
@@ -1107,4 +1107,12 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
this.rowFormat = x;
|
||||
}
|
||||
|
||||
public boolean isPrimaryColumn(long columnNameHash) {
|
||||
SQLPrimaryKey pk = this.findPrimaryKey();
|
||||
if (pk == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pk.containsColumn(columnNameHash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 1999-2018 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.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDumpStatement extends SQLStatementImpl {
|
||||
private boolean overwrite;
|
||||
private SQLExprTableSource into;
|
||||
|
||||
private SQLSelect select;
|
||||
|
||||
public SQLDumpStatement() {
|
||||
|
||||
}
|
||||
|
||||
public SQLSelect getSelect() {
|
||||
return select;
|
||||
}
|
||||
|
||||
public void setSelect(SQLSelect x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
|
||||
this.select = x;
|
||||
}
|
||||
|
||||
public SQLExprTableSource getInto() {
|
||||
return into;
|
||||
}
|
||||
|
||||
public void setInto(SQLExpr x) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setInto(new SQLExprTableSource(x));
|
||||
}
|
||||
|
||||
public void setInto(SQLExprTableSource x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
|
||||
this.into = x;
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return overwrite;
|
||||
}
|
||||
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
if (into != null) {
|
||||
into.accept(visitor);
|
||||
}
|
||||
|
||||
if (select != null) {
|
||||
select.accept(visitor);
|
||||
}
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,18 @@ public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint,
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsColumn(long columnNameHash) {
|
||||
for (SQLSelectOrderByItem item : columns) {
|
||||
SQLExpr expr = item.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
if (((SQLIdentifierExpr) expr).nameHashCode64() == columnNameHash) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cloneTo(SQLUnique x) {
|
||||
super.cloneTo(x);
|
||||
|
||||
|
||||
@@ -24,4 +24,5 @@ public interface SQLUniqueConstraint extends SQLConstraint {
|
||||
List<SQLSelectOrderByItem> getColumns();
|
||||
|
||||
boolean containsColumn(String column);
|
||||
boolean containsColumn(long columnNameHash);
|
||||
}
|
||||
|
||||
+67
-34
@@ -15,47 +15,22 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
|
||||
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.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlLockTableStatement extends MySqlStatementImpl {
|
||||
|
||||
private SQLExprTableSource tableSource;
|
||||
|
||||
private LockType lockType;
|
||||
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLExprTableSource tableSource) {
|
||||
if (tableSource != null) {
|
||||
tableSource.setParent(this);
|
||||
}
|
||||
this.tableSource = tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLName name) {
|
||||
setTableSource(new SQLExprTableSource(name));
|
||||
}
|
||||
|
||||
public LockType getLockType() {
|
||||
return lockType;
|
||||
}
|
||||
|
||||
public void setLockType(LockType lockType) {
|
||||
this.lockType = lockType;
|
||||
}
|
||||
private List<Item> items = new ArrayList<Item>();
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, tableSource);
|
||||
acceptChild(visitor, items);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
@@ -70,11 +45,69 @@ public class MySqlLockTableStatement extends MySqlStatementImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
public List<Item> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
public void setItems(List<Item> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public LockType getLockType() {
|
||||
if (items.size() == 1) {
|
||||
return items.get(0).lockType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
if (items.size() == 1) {
|
||||
return items.get(0).tableSource;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Item extends MySqlObjectImpl {
|
||||
|
||||
private SQLExprTableSource tableSource = new SQLExprTableSource();
|
||||
|
||||
private LockType lockType;
|
||||
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, tableSource);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLExprTableSource tableSource) {
|
||||
if (tableSource != null) {
|
||||
tableSource.setParent(this);
|
||||
}
|
||||
this.tableSource = tableSource;
|
||||
}
|
||||
|
||||
public LockType getLockType() {
|
||||
return lockType;
|
||||
}
|
||||
|
||||
public void setLockType(LockType lockType) {
|
||||
this.lockType = lockType;
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
-2
@@ -106,7 +106,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
|
||||
stmt.setSelect(query);
|
||||
} else {
|
||||
for (;;) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FULLTEXT)) {
|
||||
if (lexer.token() == Token.FULLTEXT) {
|
||||
Lexer.SavePoint mark = lexer.mark();
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.KEY) {
|
||||
@@ -119,8 +119,51 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
} else if (lexer.token() == Token.INDEX) {
|
||||
lexer.nextToken();
|
||||
MySqlTableIndex idx = new MySqlTableIndex();
|
||||
idx.setIndexType("FULLTEXT");
|
||||
idx.setName(this.exprParser.name());
|
||||
|
||||
accept(Token.LPAREN);
|
||||
for (; ; ) {
|
||||
idx.addColumn(this.exprParser.parseSelectOrderByItem());
|
||||
if (!(lexer.token() == (Token.COMMA))) {
|
||||
break;
|
||||
} else {
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
stmt.getTableElementList().add(idx);
|
||||
accept(Token.RPAREN);
|
||||
if (lexer.token() == Token.RPAREN) {
|
||||
break;
|
||||
} else if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
lexer.reset(mark);
|
||||
MySqlTableIndex idx = new MySqlTableIndex();
|
||||
idx.setIndexType("FULLTEXT");
|
||||
idx.setName(this.exprParser.name());
|
||||
|
||||
accept(Token.LPAREN);
|
||||
for (; ; ) {
|
||||
idx.addColumn(this.exprParser.parseSelectOrderByItem());
|
||||
if (!(lexer.token() == (Token.COMMA))) {
|
||||
break;
|
||||
} else {
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
stmt.getTableElementList().add(idx);
|
||||
accept(Token.RPAREN);
|
||||
if (lexer.token() == Token.RPAREN) {
|
||||
break;
|
||||
} else if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.SPATIAL)) {
|
||||
Lexer.SavePoint mark = lexer.mark();
|
||||
|
||||
@@ -64,6 +64,7 @@ public class MySqlLexer extends Lexer {
|
||||
map.put("MOD", Token.MOD);
|
||||
map.put("CONTAINS", Token.CONTAINS);
|
||||
map.put("RLIKE", Token.RLIKE);
|
||||
map.put("FULLTEXT", Token.FULLTEXT);
|
||||
|
||||
DEFAULT_MYSQL_KEYWORDS = new Keywords(map);
|
||||
}
|
||||
|
||||
+95
-34
@@ -65,7 +65,6 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
private static final String TABLES = "TABLES";
|
||||
private static final String TEMPORARY = "TEMPORARY";
|
||||
private static final String SPATIAL = "SPATIAL";
|
||||
private static final String FULLTEXT = "FULLTEXT";
|
||||
private static final String LOW_PRIORITY = "LOW_PRIORITY";
|
||||
private static final String CONNECTION = "CONNECTION";
|
||||
private static final String EXTENDED = "EXTENDED";
|
||||
@@ -258,7 +257,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
return parseCreateDatabase();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || lexer.identifierEquals(FULLTEXT)
|
||||
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || lexer.token() == Token.FULLTEXT
|
||||
|| lexer.identifierEquals(SPATIAL)) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
@@ -505,8 +504,8 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
if (lexer.token() == Token.UNIQUE) {
|
||||
stmt.setType("UNIQUE");
|
||||
lexer.nextToken();
|
||||
} else if (lexer.identifierEquals(FULLTEXT)) {
|
||||
stmt.setType(FULLTEXT);
|
||||
} else if (lexer.token() == Token.FULLTEXT) {
|
||||
stmt.setType("FULLTEXT");
|
||||
lexer.nextToken();
|
||||
} else if (lexer.identifierEquals(SPATIAL)) {
|
||||
stmt.setType(SPATIAL);
|
||||
@@ -807,31 +806,62 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
MySqlLockTableStatement stmt = new MySqlLockTableStatement();
|
||||
stmt.setTableSource(this.exprParser.name());
|
||||
|
||||
if (lexer.identifierEquals(READ)) {
|
||||
lexer.nextToken();
|
||||
if (lexer.identifierEquals(LOCAL)) {
|
||||
for(;;) {
|
||||
MySqlLockTableStatement.Item item = new MySqlLockTableStatement.Item();
|
||||
|
||||
SQLExprTableSource tableSource = null;
|
||||
SQLName tableName = this.exprParser.name();
|
||||
|
||||
|
||||
if (lexer.token() == Token.AS) {
|
||||
lexer.nextToken();
|
||||
String as = lexer.stringVal();
|
||||
tableSource = new SQLExprTableSource(tableName, as);
|
||||
lexer.nextToken();
|
||||
stmt.setLockType(LockType.READ_LOCAL);
|
||||
} else {
|
||||
stmt.setLockType(LockType.READ);
|
||||
tableSource = new SQLExprTableSource(tableName);
|
||||
}
|
||||
} else if (lexer.identifierEquals(WRITE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setLockType(LockType.WRITE);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier(WRITE);
|
||||
lexer.nextToken();
|
||||
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
|
||||
} else {
|
||||
throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token() + ", " + lexer.info());
|
||||
item.setTableSource(tableSource);
|
||||
stmt.getItems().add(item);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(READ)) {
|
||||
lexer.nextToken();
|
||||
if (lexer.identifierEquals(LOCAL)) {
|
||||
lexer.nextToken();
|
||||
item.setLockType(LockType.READ_LOCAL);
|
||||
} else {
|
||||
item.setLockType(LockType.READ);
|
||||
}
|
||||
} else if (lexer.identifierEquals(WRITE)) {
|
||||
lexer.nextToken();
|
||||
item.setLockType(LockType.WRITE);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier(WRITE);
|
||||
lexer.nextToken();
|
||||
item.setLockType(LockType.LOW_PRIORITY_WRITE);
|
||||
} else {
|
||||
throw new ParserException(
|
||||
"syntax error, expect READ or WRITE OR AS, actual " + lexer.token() + ", " + lexer.info());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.HINT) {
|
||||
item.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.HINT) {
|
||||
stmt.setHints(this.exprParser.parseHints());
|
||||
}
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
}
|
||||
@@ -860,25 +890,56 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
List<SQLCommentHint> hints = this.exprParser.parseHints();
|
||||
|
||||
boolean tddlHints = false;
|
||||
boolean accept = false;
|
||||
|
||||
final Token token = lexer.token();
|
||||
|
||||
boolean acceptHint = false;
|
||||
switch (lexer.token()) {
|
||||
case SELECT:
|
||||
case WITH:
|
||||
case DELETE:
|
||||
case UPDATE:
|
||||
case INSERT:
|
||||
case SHOW:
|
||||
case REPLACE:
|
||||
case TRUNCATE:
|
||||
case DROP:
|
||||
case ALTER:
|
||||
case CREATE:
|
||||
case CHECK:
|
||||
case SET:
|
||||
acceptHint = true;
|
||||
break;
|
||||
case IDENTIFIER:
|
||||
acceptHint = lexer.hash_lower() == FnvHash.Constants.DUMP
|
||||
|| lexer.hash_lower() == FnvHash.Constants.RENAME;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (hints.size() == 1
|
||||
&& statementList.size() == 0
|
||||
&& (token == Token.SELECT || token == Token.DELETE)) {
|
||||
&& acceptHint) {
|
||||
SQLCommentHint hint = hints.get(0);
|
||||
String hintText = hint.getText();
|
||||
if (hintText.startsWith("+TDDL")) {
|
||||
String hintText = hint.getText().toUpperCase();
|
||||
if (hintText.startsWith("+TDDL")
|
||||
|| hintText.startsWith("+ TDDL")
|
||||
|| hintText.startsWith("TDDL")
|
||||
|| hintText.startsWith("!TDDL"))
|
||||
{
|
||||
tddlHints = true;
|
||||
} else if(hintText.startsWith("+")) {
|
||||
accept = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (tddlHints) {
|
||||
SQLStatementImpl stmt;
|
||||
if (token == Token.SELECT) {
|
||||
stmt = (SQLSelectStatement) this.parseStatement();
|
||||
} else {
|
||||
stmt = (SQLDeleteStatement) this.parseStatement();
|
||||
}
|
||||
SQLStatementImpl stmt = (SQLStatementImpl)this.parseStatement();
|
||||
stmt.setHeadHints(hints);
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
} else if (accept) {
|
||||
SQLStatementImpl stmt = (SQLStatementImpl) this.parseStatement();
|
||||
stmt.setHeadHints(hints);
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
@@ -3463,7 +3524,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
parseAlterTableAddColumn(stmt);
|
||||
} else if (lexer.token() == Token.INDEX
|
||||
|| lexer.identifierEquals(FnvHash.Constants.FULLTEXT)
|
||||
|| lexer.token() == Token.FULLTEXT
|
||||
|| lexer.identifierEquals(FnvHash.Constants.SPATIAL)) {
|
||||
SQLAlterTableAddIndex item = parseAlterTableAddIndex();
|
||||
item.setParent(stmt);
|
||||
|
||||
@@ -340,6 +340,10 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(MySqlLockTableStatement x);
|
||||
|
||||
boolean visit(MySqlLockTableStatement.Item x);
|
||||
|
||||
void endVisit(MySqlLockTableStatement.Item x);
|
||||
|
||||
boolean visit(MySqlUnlockTablesStatement x);
|
||||
|
||||
void endVisit(MySqlUnlockTablesStatement x);
|
||||
|
||||
@@ -788,6 +788,16 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlLockTableStatement.Item x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlLockTableStatement.Item x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlUnlockTablesStatement x) {
|
||||
return true;
|
||||
|
||||
@@ -2596,7 +2596,22 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlLockTableStatement x) {
|
||||
print0(ucase ? "LOCK TABLES " : "lock tables ");
|
||||
print0(ucase ? "LOCK TABLES" : "lock tables");
|
||||
List<MySqlLockTableStatement.Item> items = x.getItems();
|
||||
if(items.size() > 0) {
|
||||
print(' ');
|
||||
printAndAccept(items, ", ");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlLockTableStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlLockTableStatement.Item x) {
|
||||
x.getTableSource().accept(this);
|
||||
if (x.getLockType() != null) {
|
||||
print(' ');
|
||||
@@ -2611,7 +2626,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlLockTableStatement x) {
|
||||
public void endVisit(MySqlLockTableStatement.Item x) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -886,6 +886,16 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlLockTableStatement.Item x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlLockTableStatement.Item x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlUnlockTablesStatement x) {
|
||||
return false;
|
||||
|
||||
@@ -334,4 +334,15 @@ public class PGExprParser extends SQLExprParser {
|
||||
}
|
||||
return alias;
|
||||
}
|
||||
|
||||
protected void filter(SQLAggregateExpr x) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FILTER)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
accept(Token.WHERE);
|
||||
SQLExpr filter = this.expr();
|
||||
accept(Token.RPAREN);
|
||||
x.setFilter(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,6 +474,7 @@ public class Lexer {
|
||||
}
|
||||
|
||||
if (c1 == '\'') {
|
||||
bufPos = 0;
|
||||
++pos;
|
||||
ch = '\'';
|
||||
scanString();
|
||||
|
||||
@@ -1445,14 +1445,21 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FILTER)) {
|
||||
filter(aggregateExpr);
|
||||
}
|
||||
|
||||
if (lexer.token == Token.OVER) {
|
||||
over(aggregateExpr);
|
||||
|
||||
}
|
||||
|
||||
return aggregateExpr;
|
||||
}
|
||||
|
||||
protected void filter(SQLAggregateExpr aggregateExpr) {
|
||||
|
||||
}
|
||||
|
||||
protected void over(SQLAggregateExpr aggregateExpr) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -2263,6 +2270,8 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, dbType);
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case TILDE:
|
||||
@@ -2274,6 +2283,8 @@ public class SQLExprParser extends SQLParser {
|
||||
rightExp = relationalRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case TILDE_STAR:
|
||||
@@ -2281,6 +2292,8 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = relational();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match_Insensitive, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case BANG_TILDE:
|
||||
@@ -2288,6 +2301,8 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = relational();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case BANG_TILDE_STAR:
|
||||
@@ -2295,6 +2310,8 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = relational();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match_POSIX_Regular_Match_Insensitive, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case TILDE_EQ:
|
||||
@@ -2302,6 +2319,8 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
rightExp = relational();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SAME_AS, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
case RLIKE:
|
||||
@@ -2331,6 +2350,8 @@ public class SQLExprParser extends SQLParser {
|
||||
rightExp = relational();
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SIMILAR_TO, rightExp, getDbType());
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -370,6 +370,13 @@ public class SQLStatementParser extends SQLParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("DUMP")) {
|
||||
SQLStatement stmt = parseDump();
|
||||
statementList.add(stmt);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.COMMIT)) {
|
||||
SQLStatement stmt = parseCommit();
|
||||
|
||||
@@ -427,6 +434,26 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLStatement parseDump() {
|
||||
SQLDumpStatement stmt = new SQLDumpStatement();
|
||||
acceptIdentifier("DUMP");
|
||||
acceptIdentifier("DATA");
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.OVERWRITE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setOverwrite(true);
|
||||
}
|
||||
|
||||
if (lexer.token == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
stmt.setInto(this.exprParser.expr());
|
||||
}
|
||||
|
||||
SQLSelect select = createSQLSelectParser().select();
|
||||
stmt.setSelect(select);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
|
||||
public SQLStatement parseDrop() {
|
||||
List<String> beforeComments = null;
|
||||
@@ -2777,7 +2804,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
protected SQLAlterTableAddIndex parseAlterTableAddIndex() {
|
||||
SQLAlterTableAddIndex item = new SQLAlterTableAddIndex();
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FULLTEXT)) {
|
||||
if (lexer.token == Token.FULLTEXT) {
|
||||
lexer.nextToken();
|
||||
item.setType("FULLTEXT");
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.SPATIAL)) {
|
||||
|
||||
@@ -102,6 +102,7 @@ public enum Token {
|
||||
IN("IN"),
|
||||
CONTAINS("CONTAINS"),
|
||||
RLIKE("RLIKE"),
|
||||
FULLTEXT("FULLTEXT"),
|
||||
|
||||
NEW("NEW"),
|
||||
ASC("ASC"),
|
||||
|
||||
@@ -1562,6 +1562,13 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
over.accept(this);
|
||||
}
|
||||
|
||||
final SQLExpr filter = x.getFilter();
|
||||
if (filter != null) {
|
||||
print0(ucase ? "FILTER (WHERE " : "filter (where ");
|
||||
printExpr(filter);
|
||||
print(')');
|
||||
}
|
||||
|
||||
this.parameterized = parameterized;
|
||||
return false;
|
||||
}
|
||||
@@ -6579,6 +6586,32 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
List<SQLCommentHint> headHints = x.getHeadHintsDirect();
|
||||
if (headHints != null) {
|
||||
for (SQLCommentHint hint : headHints) {
|
||||
hint.accept(this);
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
print0(ucase ? "DUMP DATA " : "dump data ");
|
||||
|
||||
|
||||
if (x.isOverwrite()) {
|
||||
print0(ucase ? "OVERWRITE " : "overwrite ");
|
||||
}
|
||||
|
||||
SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
into.accept(this);
|
||||
}
|
||||
|
||||
x.getSelect().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void print(float value) {
|
||||
if (this.appender == null) {
|
||||
return;
|
||||
|
||||
@@ -842,4 +842,7 @@ public interface SQLASTVisitor {
|
||||
boolean visit(SQLWindow x);
|
||||
void endVisit(SQLWindow x);
|
||||
|
||||
boolean visit(SQLDumpStatement x);
|
||||
void endVisit(SQLDumpStatement x);
|
||||
|
||||
}
|
||||
|
||||
@@ -1990,7 +1990,6 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWindow x) {
|
||||
return true;
|
||||
@@ -2000,6 +1999,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void endVisit(SQLDumpStatement x) {
|
||||
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
|
||||
@@ -2515,4 +2515,23 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
if (repository != null
|
||||
&& x.getParent() == null) {
|
||||
repository.resolve(x);
|
||||
}
|
||||
|
||||
final SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
into.accept(this);
|
||||
}
|
||||
|
||||
final SQLSelect select = x.getSelect();
|
||||
if (select != null) {
|
||||
select.accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,6 +582,7 @@ public final class FnvHash {
|
||||
long SCHEDULE = fnv1a_64_lower("SCHEDULE");
|
||||
long COMPLETION = fnv1a_64_lower("COMPLETION");
|
||||
long RENAME = fnv1a_64_lower("RENAME");
|
||||
long DUMP = fnv1a_64_lower("DUMP");
|
||||
long AT = fnv1a_64_lower("AT");
|
||||
long LANGUAGE = fnv1a_64_lower("LANGUAGE");
|
||||
long LOGFILE = fnv1a_64_lower("LOGFILE");
|
||||
@@ -649,5 +650,8 @@ public final class FnvHash {
|
||||
long GENERATED = fnv1a_64_lower("GENERATED");
|
||||
long ALWAYS = fnv1a_64_lower("ALWAYS");
|
||||
long INCREMENT = fnv1a_64_lower("INCREMENT");
|
||||
|
||||
long OVERWRITE = fnv1a_64_lower("OVERWRITE");
|
||||
long FILTER = fnv1a_64_lower("FILTER");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ druid.lang = function() {
|
||||
'WebApp' : ['WebApp' , 'Web应用'],
|
||||
'WebURI' : ['WebURI' , 'URI监控'],
|
||||
'Web Session' : ['Web Session' , 'Session监控'],
|
||||
'Spring' : ['Spring' , 'spring监控'],
|
||||
'Spring' : ['Spring' , 'Spring监控'],
|
||||
'JSON API' : ['JSON API' , 'JSON API'],
|
||||
'ResetAll' : ['Reset All' , '重置'],
|
||||
'LogAndReset' : ['Log And Reset' , '记录日志并重置'],
|
||||
@@ -21,8 +21,8 @@ druid.lang = function() {
|
||||
'Drivers' : ['Drivers' , '驱动'],
|
||||
'ResetEnable' : ['ResetEnable' , '是否允许重置'],
|
||||
'ResetCount' : ['ResetCount' , '重置次数'],
|
||||
'JavaVersion' : ['JavaVersion' , 'java版本'],
|
||||
'JavaVMName' : ['JavaVMName' , 'jvm名称'],
|
||||
'JavaVersion' : ['JavaVersion' , 'Java版本'],
|
||||
'JavaVMName' : ['JavaVMName' , 'JVM名称'],
|
||||
'JavaClassPath' : ['JavaClassPath' , 'classpath路径'],
|
||||
'StartTime' : ['StartTime' , '启动时间'],
|
||||
|
||||
@@ -79,9 +79,9 @@ druid.lang = function() {
|
||||
'SQLList' : ['SQL List', 'sql列表'],
|
||||
|
||||
'UserNameDesc' : ['Specify the username used when creating a new connection.', '指定建立连接时使用的用户名'],
|
||||
'URLDesc' : ['The JDBC driver connection URL', 'jdbc连接字符串'],
|
||||
'URLDesc' : ['The JDBC driver connection URL', 'JDBC连接字符串'],
|
||||
'DbTypeDesc' : ['database type', '数据库类型'],
|
||||
'DriverClassNameDesc' : ['The fully qualifed name of the JDBC driver class', 'jdbc驱动的类名'],
|
||||
'DriverClassNameDesc' : ['The fully qualifed name of the JDBC driver class', 'JDBC驱动的类名'],
|
||||
'FilterClassNamesDesc' : ['All the fully qualifed name of the filter classes', 'filter的类名'],
|
||||
'TestOnBorrowDesc' : [' Test or not when borrow a connection', '是否在获得连接后检测其可用性'],
|
||||
'TestWhileIdleDesc' : ['Test or not when a connection is idle for a while', '是否在连接空闲一段时间后检测其可用性'],
|
||||
@@ -232,8 +232,8 @@ druid.lang = function() {
|
||||
'WallStat':['Wall Stat', '防御统计'],
|
||||
'TableStat':['Table Stat', '表访问统计'],
|
||||
'FunctionStat':['Function Stat', '函数调用统计'],
|
||||
'SQLStatWhiteList':['SQL Stat - White List', 'SQL防御统计 - 白名单'],
|
||||
'SQLStatBlackList':['SQL Stat - Black List', 'SQL防御统计 - 黑名单'],
|
||||
'SQLStatWhiteList':['SQL Stat - White List', 'SQL防御统计 - 白名单'],
|
||||
'SQLStatBlackList':['SQL Stat - Black List', 'SQL防御统计 - 黑名单'],
|
||||
/**session-detail*/
|
||||
'PrincipalOnly':['Principal Only', 'Principal过滤'],
|
||||
'SESSIONID':['SESSIONID', 'SESSIONID'],
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.alibaba.druid.bvt.sql.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDumpStatement;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AdsDumpTest_0 extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "/*+dump-merge=true*/DUMP DATA SELECT amp.buyer_add_cart_info.buyer_id,amp.buyer_add_cart_info.pre_score,amp.buyer_add_cart_info.cart_price FROM amp.buyer_add_cart_info JOIN amp.crm_user_base_info ON amp.crm_user_base_info.user_id = amp.buyer_add_cart_info.buyer_id where (((amp.buyer_add_cart_info.seller_id=1921906956)) AND ((amp.buyer_add_cart_info.auction_id=562769960283)) AND ((amp.buyer_add_cart_info.show_price>=13300))) LIMIT 144800 ";
|
||||
|
||||
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
SQLDumpStatement stmt = (SQLDumpStatement)statementList.get(0);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
assertEquals("/*+dump-merge=true*/\n" +
|
||||
"DUMP DATA SELECT amp.buyer_add_cart_info.buyer_id, amp.buyer_add_cart_info.pre_score, amp.buyer_add_cart_info.cart_price\n" +
|
||||
"FROM amp.buyer_add_cart_info\n" +
|
||||
"\tJOIN amp.crm_user_base_info ON amp.crm_user_base_info.user_id = amp.buyer_add_cart_info.buyer_id\n" +
|
||||
"WHERE amp.buyer_add_cart_info.seller_id = 1921906956\n" +
|
||||
"\tAND amp.buyer_add_cart_info.auction_id = 562769960283\n" +
|
||||
"\tAND amp.buyer_add_cart_info.show_price >= 13300\n" +
|
||||
"LIMIT 144800", stmt.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlDumpTest extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "dump data into 'odps://ktv_market_analyzing/bohan_test_001/ds=20171233/seller_bucket=9727' " +
|
||||
"select '6225607' as crowd_snapshot_id, a.seller_id as seller_id, a.buyer_id as buyer_id " +
|
||||
"from amp.otpx_buyer_seller_relation_detail_to_garuda a " +
|
||||
"join amp.otp_user_base_info b on b.user_id= a.buyer_id " +
|
||||
"where(((a.seller_id= 765844183 and a.seller_zone= 765844183%20+ 1000)) and((a.last_pay_date>= 20151226 and a.last_pay_date<= 20171215)) and((a.is_market_target in('3'))))";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(2, visitor.getTables().size());
|
||||
assertEquals(6, visitor.getColumns().size());
|
||||
assertEquals(7, visitor.getConditions().size());
|
||||
|
||||
assertTrue(visitor.containsTable("amp.otp_user_base_info"));
|
||||
assertTrue(visitor.containsTable("amp.otpx_buyer_seller_relation_detail_to_garuda"));
|
||||
// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t2")));
|
||||
|
||||
assertTrue(visitor.containsColumn("amp.otp_user_base_info", "user_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "buyer_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "seller_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "seller_zone"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "is_market_target"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "last_pay_date"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlDumpTest_1 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "DUMP DATA OVERWRITE INTO 'odps://cod_garuda/wenyu_meta_person' select cid, cname, dept, gender, pid from wenyu_meta_person limit 10;";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(1, visitor.getTables().size());
|
||||
assertEquals(5, visitor.getColumns().size());
|
||||
assertEquals(0, visitor.getConditions().size());
|
||||
|
||||
assertTrue(visitor.containsTable("wenyu_meta_person"));
|
||||
// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t2")));
|
||||
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "cid"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "cname"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "dept"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "gender"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "pid"));
|
||||
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.alibaba.druid.bvt.sql.mysql.createTable;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlCreateTableTest112 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "CREATE TABLE opening_lines ( " +
|
||||
"id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY" +
|
||||
", opening_line TEXT(500)" +
|
||||
", author VARCHAR(200)" +
|
||||
", title VARCHAR(200)" +
|
||||
", FULLTEXT idx (opening_line) " +
|
||||
") ENGINE=InnoDB;";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
MySqlCreateTableStatement stmt = (MySqlCreateTableStatement)statementList.get(0);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
assertEquals(5, stmt.getTableElementList().size());
|
||||
|
||||
assertEquals("CREATE TABLE opening_lines (\n" +
|
||||
"\tid INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,\n" +
|
||||
"\topening_line TEXT(500),\n" +
|
||||
"\tauthor VARCHAR(200),\n" +
|
||||
"\ttitle VARCHAR(200),\n" +
|
||||
"\tFULLTEXT INDEX idx(opening_line)\n" +
|
||||
") ENGINE = InnoDB;", stmt.toString());
|
||||
|
||||
SchemaStatVisitor v = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
|
||||
stmt.accept(v);
|
||||
|
||||
assertEquals(4, v.getColumns().size());
|
||||
SQLColumnDefinition column = stmt.findColumn("id");
|
||||
assertNotNull(column);
|
||||
assertEquals(2, column.getConstraints().size());
|
||||
assertTrue(column.isPrimaryKey());
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
package com.alibaba.druid.bvt.sql.mysql.select;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlSelectTest_196_wall extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "update task_info set priority = 1, content = 'x渓螼h\u0013[\u0014\u0006饆蜭�)漉=灔�\u000B\u0011\u0011u�\uE06A圥Z[\u0017殞c怈﹝櫃&c摍0\u007Fj璟\u0004]JWRb峌膮埜\u0014譢\"瓺\\\\塼!.D牡玕\"邥\t� 佥篼緖.W=Rw4�\u001E3\t玭YF螭�\u0004�);\u0011�I\u0017�%\u0017谦漜f*\bm梄恀拒t)/�I�\"uSP蟉�\u0006I3\\\"�\u0016敐\f\\Z殷觀n\\\"餭讖;祵Y換g\uE5B7&柋\u0017�\u0011﹗A欍媞(I=\u0010�x鐹�\u000B!蜿\u0006\u0013�lQw�(33毳圳倀!\uE324=&释烃襲�&b\uE1EF�\u0013mm孺L\u0014嚍_MS7湏痘笫滴;y鶲\b爱骤求秩G-\u001By~殿揀\uE222�\u0003鮝[�Dqo:蟎'~=裼�\u001F垴蟵\\rY�\u0013.\uE3F9R\u000E�\u0012滂燶n鑲�\u0002贛龎=\u0010ミ�\u0007/%�\u001C癳c�\u000E\\Z旊\u001B�\u000B2栣玄岜�#cc吜\uE6C5�\u001B嚮醽nx�\u001B巘肅輕4E鎊\u0018E\u0018跴欱貯i\u0007蘉渚秘\u0007c\u00129狓\u0004F\u001F\f\u0013�觠3\u000B��-XS8�\u0010�\u0019V\u001E諭餸�\u000Fk\\r|\u0014V\u0005躒_A彙?E�*�\u0015琔�\u001Ep共\u000B�\u0006Z\u001F�%楳�\u001D\u001C玾郳\"\uE26B\u0011�\u0006Jj\u0016h\u0005�\u001C�\u0002�\u0002�\u0004j貌`.�\u0001�\u0005韁\"�\u0006z佉\u0012�\u001CxQ�\u0007\u0017@呃-斵曼\\0k砛0k\u0003鬨Z\uE5E9\u007F\u0006^�\u000Es\u0005欳B�\f\\0\\0��+僜'�', attribute = 0, create_time = from_unixtime(1531714297) where id = 2726633030";
|
||||
|
||||
Exception error = null;
|
||||
try {
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
} catch (ParserException ex) {
|
||||
error = ex;
|
||||
}
|
||||
|
||||
assertNotNull(error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql.update;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat.Column;
|
||||
import com.alibaba.druid.wall.WallUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlUpdateTest_17 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "update security_group_ip_count set ip_count=GREATEST(ip_count-?, 0), gmt_modified=now() where group_id=? ";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
// System.out.println("Tables : " + visitor.getTables());
|
||||
// System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(1, visitor.getTables().size());
|
||||
assertEquals(3, visitor.getColumns().size());
|
||||
// assertEquals(2, visitor.getConditions().size());
|
||||
|
||||
assertTrue(visitor.containsTable("security_group_ip_count"));
|
||||
|
||||
assertTrue(visitor.getColumns().contains(new Column("security_group_ip_count", "ip_count")));
|
||||
|
||||
assertEquals("UPDATE security_group_ip_count\n" +
|
||||
"SET ip_count = GREATEST(ip_count - ?, 0), gmt_modified = now()\n" +
|
||||
"WHERE group_id = ?", //
|
||||
stmt.toString());
|
||||
assertEquals("update security_group_ip_count\n" +
|
||||
"set ip_count = GREATEST(ip_count - ?, 0), gmt_modified = now()\n" +
|
||||
"where group_id = ?", //
|
||||
stmt.toLowerCaseString());
|
||||
|
||||
|
||||
assertTrue(WallUtils.isValidateMySql(sql));
|
||||
|
||||
{
|
||||
SQLUpdateStatement update = (SQLUpdateStatement) stmt;
|
||||
SQLExpr where = update.getWhere();
|
||||
assertEquals("group_id = ?", where.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.bvt.sql.sqlserver;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SQLServerUpdateTest6 extends TestCase {
|
||||
|
||||
public void test_update() throws Exception {
|
||||
String sql = "update clients set name =N'小明',age =1";
|
||||
|
||||
String expect = "UPDATE TOP (10) HumanResources.Employee"
|
||||
+ "\nSET VacationHours = VacationHours * 1.25, ModifiedDate = GETDATE()"
|
||||
+ "\nOUTPUT inserted.BusinessEntityID, deleted.VacationHours, inserted.VacationHours, inserted.ModifiedDate"
|
||||
+ "\n\tINTO @MyTableVar;";
|
||||
|
||||
|
||||
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
|
||||
assertEquals("UPDATE clients\n" +
|
||||
"SET name = N'小明', age = 1", stmt.toString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user