diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index d80f92dddd..b4e3f7c4d8 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor; import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor; import com.alibaba.druid.sql.dialect.h2.visitor.H2OutputVisitor; +import com.alibaba.druid.sql.dialect.h2.visitor.H2SchemaStatVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsOutputVisitor; @@ -402,8 +403,7 @@ public class SQLUtils { } if (JdbcConstants.MYSQL.equals(dbType) || // - JdbcConstants.MARIADB.equals(dbType) || // - JdbcConstants.H2.equals(dbType)) { + JdbcConstants.MARIADB.equals(dbType)) { return new MySqlSchemaStatVisitor(); } @@ -423,6 +423,10 @@ public class SQLUtils { return new OdpsSchemaStatVisitor(); } + if (JdbcConstants.H2.equals(dbType)) { + return new H2SchemaStatVisitor(); + } + return new SchemaStatVisitor(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLReplaceStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLReplaceStatement.java index 92b39dbd53..902aba21b5 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLReplaceStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLReplaceStatement.java @@ -1,3 +1,18 @@ +/* + * 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.ast.statement; import com.alibaba.druid.sql.ast.SQLExpr; diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index b03f518d69..9084363114 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -25,36 +25,36 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.util.FnvHash; public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery, SQLReplaceable { - private boolean bracket = false; - protected int distionOption; - protected final List selectList = new ArrayList(); + private boolean bracket = false; + protected int distionOption; + protected final List selectList = new ArrayList(); - protected SQLTableSource from; - protected SQLExprTableSource into; - protected SQLExpr where; + protected SQLTableSource from; + protected SQLExprTableSource into; + protected SQLExpr where; // for oracle & oceanbase - protected SQLExpr startWith; - protected SQLExpr connectBy; - protected boolean prior = false; - protected boolean noCycle = false; - protected SQLOrderBy orderBySiblings; + protected SQLExpr startWith; + protected SQLExpr connectBy; + protected boolean prior = false; + protected boolean noCycle = false; + protected SQLOrderBy orderBySiblings; - protected SQLSelectGroupByClause groupBy; - protected SQLOrderBy orderBy; - protected boolean parenthesized = false; - protected boolean forUpdate = false; - protected boolean noWait = false; - protected SQLExpr waitTime; - - protected SQLLimit limit; + protected SQLSelectGroupByClause groupBy; + protected SQLOrderBy orderBy; + protected boolean parenthesized = false; + protected boolean forUpdate = false; + protected boolean noWait = false; + protected SQLExpr waitTime; + protected SQLLimit limit; // for oracle - protected List forUpdateOf; - - protected List distributeBy; + protected List forUpdateOf; + protected List distributeBy; protected List sortBy; + protected String cachedSelectList; // optimized for SelectListCache + public SQLSelectQueryBlock(){ } @@ -397,6 +397,15 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery return forUpdateOf.size(); } + public void cloneSelectListTo(SQLSelectQueryBlock x) { + x.distionOption = distionOption; + for (SQLSelectItem item : this.selectList) { + SQLSelectItem item2 = item.clone(); + item2.setParent(x); + x.selectList.add(item2); + } + } + public void cloneTo(SQLSelectQueryBlock x) { x.distionOption = distionOption; @@ -580,4 +589,12 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery setLimit(limit); } + + public String getCachedSelectList() { + return cachedSelectList; + } + + public void setCachedSelectList(String cachedSelectList) { + this.cachedSelectList = cachedSelectList; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java index 20e01cd789..26a016eafc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java @@ -21,10 +21,7 @@ import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock.Isolation; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLExprParser; -import com.alibaba.druid.sql.parser.SQLSelectParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; public class DB2SelectParser extends SQLSelectParser { @@ -32,6 +29,10 @@ public class DB2SelectParser extends SQLSelectParser { super(exprParser); } + public DB2SelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public DB2SelectParser(String sql){ this(new DB2ExprParser(sql)); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java index 090253481a..cd987d37c4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java @@ -39,7 +39,7 @@ public class DB2StatementParser extends SQLStatementParser { } public DB2SelectParser createSQLSelectParser() { - return new DB2SelectParser(this.exprParser); + return new DB2SelectParser(this.exprParser, selectListCache); } public boolean parseStatementListDialect(List statementList) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/ast/H2MergeStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/ast/H2MergeStatement.java deleted file mode 100644 index 1817905004..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/ast/H2MergeStatement.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.alibaba.druid.sql.dialect.h2.ast; - -import com.alibaba.druid.sql.ast.SQLName; -import com.alibaba.druid.sql.ast.SQLStatementImpl; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; - -import java.util.ArrayList; -import java.util.List; - -public class H2MergeStatement extends SQLStatementImpl { - private SQLExprTableSource table; - - private final List keyColumns = new ArrayList(); - - public SQLExprTableSource getTable() { - return table; - } - - public void setTable(SQLName table) { - this.setTable(new SQLExprTableSource(table)); - } - - public void setTable(SQLExprTableSource table) { - if (table != null) { - table.setParent(this); - } - this.table = table; - } - - public List getKeyColumns() { - return keyColumns; - } -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2ExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2ExprParser.java index d1c0ae3a84..f19c9defbd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2ExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2ExprParser.java @@ -1,3 +1,18 @@ +/* + * 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.h2.parser; import com.alibaba.druid.sql.parser.Lexer; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2Lexer.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2Lexer.java index ef1248e3e5..084ebd63b9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2Lexer.java @@ -1,3 +1,18 @@ +/* + * 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.h2.parser; import com.alibaba.druid.sql.parser.Keywords; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2SelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2SelectParser.java index 762661a4e3..886b58d338 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2SelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2SelectParser.java @@ -1,6 +1,22 @@ +/* + * 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.h2.parser; import com.alibaba.druid.sql.parser.SQLExprParser; +import com.alibaba.druid.sql.parser.SQLSelectListCache; import com.alibaba.druid.sql.parser.SQLSelectParser; public class H2SelectParser extends SQLSelectParser { @@ -9,6 +25,10 @@ public class H2SelectParser extends SQLSelectParser { super(exprParser); } + public H2SelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public H2SelectParser(String sql){ this(new H2ExprParser(sql)); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java index 313440dc41..46e734d63e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java @@ -1,3 +1,18 @@ +/* + * 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.h2.parser; import com.alibaba.druid.sql.ast.SQLName; @@ -6,7 +21,6 @@ import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLReplaceStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.dialect.h2.ast.H2MergeStatement; import com.alibaba.druid.sql.parser.*; import com.alibaba.druid.util.FnvHash; import com.alibaba.druid.util.JdbcConstants; @@ -25,7 +39,7 @@ public class H2StatementParser extends SQLStatementParser { } public H2SelectParser createSQLSelectParser() { - return new H2SelectParser(this.exprParser); + return new H2SelectParser(this.exprParser, selectListCache); } public SQLStatement parseMerge() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitor.java index 8bcde2ef58..5866b20fbb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitor.java @@ -1,3 +1,18 @@ +/* + * 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.h2.visitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitorAdapter.java index f47e5d9817..9fcf6331f8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2ASTVisitorAdapter.java @@ -1,3 +1,18 @@ +/* + * 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.h2.visitor; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2EvalVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2EvalVisitor.java index 3da27b6c5d..9e25fc1915 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2EvalVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2EvalVisitor.java @@ -1,3 +1,18 @@ +/* + * 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.h2.visitor; import com.alibaba.druid.sql.ast.expr.*; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2OutputVisitor.java index 8b6e020720..158621e2bc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2OutputVisitor.java @@ -1,3 +1,18 @@ +/* + * 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.h2.visitor; import com.alibaba.druid.sql.ast.SQLExpr; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2SchemaStatVisitor.java index 83aeb4960d..b48c871a40 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/visitor/H2SchemaStatVisitor.java @@ -1,6 +1,21 @@ +/* + * 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.h2.visitor; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; public class H2SchemaStatVisitor extends SchemaStatVisitor implements H2ASTVisitor { -} +} \ No newline at end of file diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java index b5a3f84795..c3a6679220 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java @@ -20,6 +20,7 @@ import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.*; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; @@ -28,21 +29,16 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; import oracle.sql.SQLUtil; public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlObject { - private boolean hignPriority; private boolean straightJoin; - private boolean smallResult; private boolean bigResult; private boolean bufferResult; private Boolean cache; private boolean calcFoundRows; - private SQLName procedureName; private List procedureArgumentList; - - private boolean lockInShareMode = false; - + private boolean lockInShareMode; private List hints; public MySqlSelectQueryBlock(){ diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index 03c28c6080..dad82adf7d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -31,10 +31,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLExprParser; -import com.alibaba.druid.sql.parser.SQLSelectParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; import com.alibaba.druid.util.FnvHash; import java.util.List; @@ -48,6 +45,10 @@ public class MySqlSelectParser extends SQLSelectParser { super(exprParser); } + public MySqlSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public MySqlSelectParser(String sql){ this(new MySqlExprParser(sql)); } @@ -93,6 +94,12 @@ public class MySqlSelectParser extends SQLSelectParser { queryBlock.addBeforeComment(lexer.readAndResetComments()); } + if (lexer.token() == Token.SELECT) { + if (selectListCache != null) { + selectListCache.match(lexer, queryBlock); + } + } + if (lexer.token() == Token.SELECT) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 5b1b046179..891c409708 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -108,7 +108,7 @@ public class MySqlStatementParser extends SQLStatementParser { } public SQLStatement parseSelect() { - MySqlSelectParser selectParser = new MySqlSelectParser(this.exprParser); + MySqlSelectParser selectParser = createSQLSelectParser(); SQLSelect select = selectParser.select(); @@ -120,7 +120,7 @@ public class MySqlStatementParser extends SQLStatementParser { } public SQLUpdateStatement parseUpdateStatement() { - return new MySqlSelectParser(this.exprParser).parseUpdateStatment(); + return new MySqlSelectParser(this.exprParser, selectListCache).parseUpdateStatment(); } protected MySqlUpdateStatement createUpdateStatement() { @@ -2262,8 +2262,8 @@ public class MySqlStatementParser extends SQLStatementParser { return insertStatement; } - public SQLSelectParser createSQLSelectParser() { - return new MySqlSelectParser(this.exprParser); + public MySqlSelectParser createSQLSelectParser() { + return new MySqlSelectParser(this.exprParser, selectListCache); } public SQLStatement parseSet() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 764b6657e1..3903dc4aeb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -116,62 +116,68 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV printlnComments(x.getBeforeCommentsDirect()); } - print0(ucase ? "SELECT " : "select "); + String cachedSelectList = x.getCachedSelectList(); - for (int i = 0, size = x.getHintsSize(); i < size; ++i) { - SQLCommentHint hint = x.getHints().get(i); - hint.accept(this); - print(' '); - } + if (cachedSelectList != null) { + print0(cachedSelectList); + } else { + print0(ucase ? "SELECT " : "select "); - final int distionOption = x.getDistionOption(); - if (SQLSetQuantifier.ALL == distionOption) { - print0(ucase ? "ALL " : "all "); - } else if (SQLSetQuantifier.DISTINCT == distionOption) { - print0(ucase ? "DISTINCT " : "distinct "); - } else if (SQLSetQuantifier.DISTINCTROW == distionOption) { - print0(ucase ? "DISTINCTROW " : "distinctrow "); - } - - if (x.isHignPriority()) { - print0(ucase ? "HIGH_PRIORITY " : "high_priority "); - } - - if (x.isStraightJoin()) { - print0(ucase ? "STRAIGHT_JOIN " : "straight_join "); - } - - if (x.isSmallResult()) { - print0(ucase ? "SQL_SMALL_RESULT " : "sql_small_result "); - } - - if (x.isBigResult()) { - print0(ucase ? "SQL_BIG_RESULT " : "sql_big_result "); - } - - if (x.isBufferResult()) { - print0(ucase ? "SQL_BUFFER_RESULT " : "sql_buffer_result "); - } - - if (x.getCache() != null) { - if (x.getCache().booleanValue()) { - print0(ucase ? "SQL_CACHE " : "sql_cache "); - } else { - print0(ucase ? "SQL_NO_CACHE " : "sql_no_cache "); + for (int i = 0, size = x.getHintsSize(); i < size; ++i) { + SQLCommentHint hint = x.getHints().get(i); + hint.accept(this); + print(' '); } - } - if (x.isCalcFoundRows()) { - print0(ucase ? "SQL_CALC_FOUND_ROWS " : "sql_calc_found_rows "); - } + final int distionOption = x.getDistionOption(); + if (SQLSetQuantifier.ALL == distionOption) { + print0(ucase ? "ALL " : "all "); + } else if (SQLSetQuantifier.DISTINCT == distionOption) { + print0(ucase ? "DISTINCT " : "distinct "); + } else if (SQLSetQuantifier.DISTINCTROW == distionOption) { + print0(ucase ? "DISTINCTROW " : "distinctrow "); + } - printSelectList(x.getSelectList()); + if (x.isHignPriority()) { + print0(ucase ? "HIGH_PRIORITY " : "high_priority "); + } - SQLExprTableSource into = x.getInto(); - if (into != null) { - println(); - print0(ucase ? "INTO " : "into "); - printTableSource(into); + if (x.isStraightJoin()) { + print0(ucase ? "STRAIGHT_JOIN " : "straight_join "); + } + + if (x.isSmallResult()) { + print0(ucase ? "SQL_SMALL_RESULT " : "sql_small_result "); + } + + if (x.isBigResult()) { + print0(ucase ? "SQL_BIG_RESULT " : "sql_big_result "); + } + + if (x.isBufferResult()) { + print0(ucase ? "SQL_BUFFER_RESULT " : "sql_buffer_result "); + } + + if (x.getCache() != null) { + if (x.getCache().booleanValue()) { + print0(ucase ? "SQL_CACHE " : "sql_cache "); + } else { + print0(ucase ? "SQL_NO_CACHE " : "sql_no_cache "); + } + } + + if (x.isCalcFoundRows()) { + print0(ucase ? "SQL_CALC_FOUND_ROWS " : "sql_calc_found_rows "); + } + + printSelectList(x.getSelectList()); + + SQLExprTableSource into = x.getInto(); + if (into != null) { + println(); + print0(ucase ? "INTO " : "into "); + printTableSource(into); + } } SQLTableSource from = x.getFrom(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java index aa3bdf959d..564fbc4008 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java @@ -28,6 +28,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.ast.OdpsValuesTableSource; import com.alibaba.druid.sql.parser.SQLExprParser; +import com.alibaba.druid.sql.parser.SQLSelectListCache; import com.alibaba.druid.sql.parser.SQLSelectParser; import com.alibaba.druid.sql.parser.Token; @@ -37,6 +38,12 @@ public class OdpsSelectParser extends SQLSelectParser { this.exprParser = exprParser; } + public OdpsSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser.getLexer()); + this.exprParser = exprParser; + this.selectListCache = selectListCache; + } + @Override public SQLSelectQuery query() { if (lexer.token() == Token.LPAREN) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index 953d63a3bd..5e14051e24 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -266,7 +266,7 @@ public class OdpsStatementParser extends SQLStatementParser { } public SQLSelectParser createSQLSelectParser() { - return new OdpsSelectParser(this.exprParser); + return new OdpsSelectParser(this.exprParser, selectListCache); } public OdpsInsert parseOdpsInsert() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 01b8f01c3f..422ddf12b7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -47,10 +47,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSo import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLExprParser; -import com.alibaba.druid.sql.parser.SQLSelectParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; public class OracleSelectParser extends SQLSelectParser { @@ -62,6 +59,10 @@ public class OracleSelectParser extends SQLSelectParser { super(exprParser); } + public OracleSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public SQLSelect select() { SQLSelect select = new SQLSelect(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 70c71273e5..340503e96a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1692,7 +1692,7 @@ public class OracleStatementParser extends SQLStatementParser { } public OracleSelectParser createSQLSelectParser() { - return new OracleSelectParser(this.exprParser); + return new OracleSelectParser(this.exprParser, selectListCache); } public OracleStatement parseInsert() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index 7f0e176431..a721fc35d4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -60,7 +60,7 @@ public class PGSQLStatementParser extends SQLStatementParser { } public PGSelectParser createSQLSelectParser() { - return new PGSelectParser(this.exprParser); + return new PGSelectParser(this.exprParser, selectListCache); } public SQLUpdateStatement parseUpdateStatement() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java index 13b3d3df25..73ffed6304 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSelectParser.java @@ -30,10 +30,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.IntoOption; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLExprParser; -import com.alibaba.druid.sql.parser.SQLSelectParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; public class PGSelectParser extends SQLSelectParser { @@ -41,6 +38,10 @@ public class PGSelectParser extends SQLSelectParser { super(exprParser); } + public PGSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public PGSelectParser(String sql){ this(new PGExprParser(sql)); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java index 1e4955c0e0..e9b2875b71 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerSelectParser.java @@ -20,10 +20,7 @@ import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLExprParser; -import com.alibaba.druid.sql.parser.SQLSelectParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; public class SQLServerSelectParser extends SQLSelectParser { @@ -35,6 +32,10 @@ public class SQLServerSelectParser extends SQLSelectParser { super(exprParser); } + public SQLServerSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ + super(exprParser, selectListCache); + } + public SQLSelect select() { SQLSelect select = new SQLSelect(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index 5ab11024f9..b333d22cfa 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -51,7 +51,7 @@ public class SQLServerStatementParser extends SQLStatementParser { } public SQLSelectParser createSQLSelectParser() { - return new SQLServerSelectParser(this.exprParser); + return new SQLServerSelectParser(this.exprParser, selectListCache); } public SQLServerStatementParser(Lexer lexer){ diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index 135d99bf15..33a0c63289 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -15,16 +15,20 @@ */ package com.alibaba.druid.sql.parser; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.parser.DB2ExprParser; import com.alibaba.druid.sql.dialect.db2.parser.DB2Lexer; import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; import com.alibaba.druid.sql.dialect.h2.parser.H2StatementParser; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlLexer; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.dialect.odps.parser.OdpsExprParser; import com.alibaba.druid.sql.dialect.odps.parser.OdpsLexer; import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser; import com.alibaba.druid.sql.dialect.oracle.parser.OracleLexer; import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; @@ -173,4 +177,32 @@ public class SQLParserUtils { return new Lexer(sql); } + + public static SQLSelectQueryBlock createSelectQueryBlock(String dbType) { + if (JdbcConstants.MYSQL.equals(dbType)) { + return new MySqlSelectQueryBlock(); + } + + if (JdbcConstants.ORACLE.equals(dbType)) { + return new OracleSelectQueryBlock(); + } + + if (JdbcConstants.DB2.equals(dbType)) { + return new DB2SelectQueryBlock(); + } + + if (JdbcConstants.POSTGRESQL.equals(dbType)) { + return new DB2SelectQueryBlock(); + } + + if (JdbcConstants.ODPS.equals(dbType)) { + return new DB2SelectQueryBlock(); + } + + if (JdbcConstants.SQL_SERVER.equals(dbType)) { + return new DB2SelectQueryBlock(); + } + + return new SQLSelectQueryBlock(); + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectListCache.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectListCache.java new file mode 100644 index 0000000000..eaa84a2e33 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectListCache.java @@ -0,0 +1,78 @@ +/* + * 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.parser; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SQLSelectListCache { + private final String dbType; + private List sqlCache = new ArrayList(); + private List queryBlockCache = new ArrayList(); + private List printSqlList = new ArrayList(); + + public SQLSelectListCache(String dbType) { + this.dbType = dbType; + } + + public void add(String select) { + if (select == null || select.length() == 0) { + return; + } + + SQLSelectParser selectParser = SQLParserUtils.createSQLStatementParser(select, dbType) + .createSQLSelectParser(); + SQLSelectQueryBlock queryBlock = SQLParserUtils.createSelectQueryBlock(dbType); + selectParser.accept(Token.SELECT); + + selectParser.parseSelectList(queryBlock); + + selectParser.accept(Token.FROM); + selectParser.accept(Token.EOF); + + sqlCache.add(select.substring(6)); + queryBlockCache.add(queryBlock); + printSqlList.add(queryBlock.toString()); + } + + public boolean match(Lexer lexer, SQLSelectQueryBlock queryBlock) { + if (lexer.token != Token.SELECT) { + return false; + } + + int pos = lexer.pos; + String text = lexer.text; + + for (int i = 0; i < sqlCache.size(); i++) { + String block = sqlCache.get(i); + if (text.startsWith(block, pos)) { + //SQLSelectQueryBlock queryBlockCached = queryBlockCache.get(i); + // queryBlockCached.cloneSelectListTo(queryBlock); + String printSql = printSqlList.get(i); + queryBlock.setCachedSelectList(printSql); + + int len = pos + block.length(); + lexer.reset(len, text.charAt(len), Token.FROM); + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index d3a57feb27..e2245ea6b8 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -27,7 +27,8 @@ import com.alibaba.druid.util.FnvHash; import com.alibaba.druid.util.JdbcConstants; public class SQLSelectParser extends SQLParser { - protected SQLExprParser exprParser; + protected SQLExprParser exprParser; + protected SQLSelectListCache selectListCache; public SQLSelectParser(String sql){ super(sql); @@ -38,8 +39,13 @@ public class SQLSelectParser extends SQLParser { } public SQLSelectParser(SQLExprParser exprParser){ + this(exprParser, null); + } + + public SQLSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){ super(exprParser.getLexer(), exprParser.getDbType()); this.exprParser = exprParser; + this.selectListCache = selectListCache; } public SQLSelect select() { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 8b0e23df8b..8788813441 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -29,9 +29,10 @@ import com.alibaba.druid.util.JdbcConstants; public class SQLStatementParser extends SQLParser { - protected SQLExprParser exprParser; - protected boolean parseCompleteValues = true; - protected int parseValuesSize = 3; + protected SQLExprParser exprParser; + protected boolean parseCompleteValues = true; + protected int parseValuesSize = 3; + protected SQLSelectListCache selectListCache = null; public SQLStatementParser(String sql){ this(sql, null); @@ -83,6 +84,20 @@ public class SQLStatementParser extends SQLParser { } public void parseStatementList(List statementList, int max, SQLObject parent) { + if ("select @@session.tx_read_only".equals(lexer.text) + && lexer.token == Token.SELECT) { + SQLSelect select = new SQLSelect(); + MySqlSelectQueryBlock queryBlock = new MySqlSelectQueryBlock(); + queryBlock.addSelectItem(new SQLPropertyExpr(new SQLVariantRefExpr("@@session"), "tx_read_only")); + select.setQuery(queryBlock); + + SQLSelectStatement stmt = new SQLSelectStatement(select); + statementList.add(stmt); + + lexer.reset(29, '\u001A', Token.EOF); + return; + } + for (;;) { if (max != -1) { if (statementList.size() >= max) { @@ -2150,7 +2165,7 @@ public class SQLStatementParser extends SQLParser { } public SQLSelectParser createSQLSelectParser() { - return new SQLSelectParser(this.exprParser); + return new SQLSelectParser(this.exprParser, selectListCache); } public SQLUpdateStatement parseUpdateStatement() { @@ -2959,4 +2974,12 @@ public class SQLStatementParser extends SQLParser { } } } + + public SQLSelectListCache getSelectListCache() { + return selectListCache; + } + + public void setSelectListCache(SQLSelectListCache selectListCache) { + this.selectListCache = selectListCache; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectListCacheTest.java b/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectListCacheTest.java new file mode 100644 index 0000000000..0d1a5afebe --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectListCacheTest.java @@ -0,0 +1,35 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLSelectListCache; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class SQLSelectListCacheTest extends TestCase { + public void test_selectListCache() throws Exception { + SQLSelectListCache selectListCache = new SQLSelectListCache(JdbcConstants.MYSQL); + selectListCache.add("SELECT `mtk_p_mg`.`id` AS `id`, `mtk_p_mg`.`gmt_create` AS `gmtCreate`, `mtk_p_mg`.`gmt_modified` AS `gmtModified`, `mtk_p_mg`.`target` AS `target`, `mtk_p_mg`.`msg_id` AS `msgId` , `mtk_p_mg`.`uuid` AS `uuid`, `mtk_p_mg`.`app_key` AS `appKey`, `mtk_p_mg`.`utdid` AS `utdid`, `mtk_p_mg`.`digest` AS `digest`, `mtk_p_mg`.`content` AS `content` , `mtk_p_mg`.`user_info` AS `userInfo`, `mtk_p_mg`.`status` AS `status`, `mtk_p_mg`.`mesg_status` AS `mesgStatus`, `mtk_p_mg`.`start_time` AS `startTime`, `mtk_p_mg`.`expired` AS `expired` , `mtk_p_mg`.`online` AS `online`, `mtk_p_mg`.`gmt_commit` AS `gmtCommit`, `mtk_p_mg`.`extra_info` AS `extraInfo`, `mtk_p_mg`.`auto_commit` AS `autoCommit`, `mtk_p_mg`.`task_id` AS `taskId` , `mtk_p_mg`.`msg_type` AS `msgType`, `mtk_p_mg`.`push_user_token` AS `pushUserToken`, `mtk_p_mg`.`tb_app_device_token` AS `tbAppDeviceToken`, `mtk_p_mg`.`sdk_version` AS `sdkVersion`, `mtk_p_mg`.`biz_ext_info` AS `bizExtInfo` FROM"); + + String sql = "SELECT `mtk_p_mg`.`id` AS `id`, `mtk_p_mg`.`gmt_create` AS `gmtCreate`, `mtk_p_mg`.`gmt_modified` AS `gmtModified`, `mtk_p_mg`.`target` AS `target`, `mtk_p_mg`.`msg_id` AS `msgId` , `mtk_p_mg`.`uuid` AS `uuid`, `mtk_p_mg`.`app_key` AS `appKey`, `mtk_p_mg`.`utdid` AS `utdid`, `mtk_p_mg`.`digest` AS `digest`, `mtk_p_mg`.`content` AS `content` , `mtk_p_mg`.`user_info` AS `userInfo`, `mtk_p_mg`.`status` AS `status`, `mtk_p_mg`.`mesg_status` AS `mesgStatus`, `mtk_p_mg`.`start_time` AS `startTime`, `mtk_p_mg`.`expired` AS `expired` , `mtk_p_mg`.`online` AS `online`, `mtk_p_mg`.`gmt_commit` AS `gmtCommit`, `mtk_p_mg`.`extra_info` AS `extraInfo`, `mtk_p_mg`.`auto_commit` AS `autoCommit`, `mtk_p_mg`.`task_id` AS `taskId` , `mtk_p_mg`.`msg_type` AS `msgType`, `mtk_p_mg`.`push_user_token` AS `pushUserToken`, `mtk_p_mg`.`tb_app_device_token` AS `tbAppDeviceToken`, `mtk_p_mg`.`sdk_version` AS `sdkVersion`, `mtk_p_mg`.`biz_ext_info` AS `bizExtInfo` FROM mtk_p_mg `mtk_p_mg` FORCE INDEX (idx_targetid) WHERE `mtk_p_mg`.`target` = ? ORDER BY `mtk_p_mg`.`id` DESC LIMIT ?, ?"; + SQLStatementParser statementParser = SQLParserUtils.createSQLStatementParser(sql, JdbcConstants.MYSQL); + statementParser.setSelectListCache(selectListCache); + + List statementList = statementParser.parseStatementList(); + assertEquals(1, statementList.size()); + + SQLStatement stmt = statementList.get(0); + assertEquals("SELECT `mtk_p_mg`.`id` AS `id`, `mtk_p_mg`.`gmt_create` AS `gmtCreate`, `mtk_p_mg`.`gmt_modified` AS `gmtModified`, `mtk_p_mg`.`target` AS `target`, `mtk_p_mg`.`msg_id` AS `msgId`\n" + + "\t, `mtk_p_mg`.`uuid` AS `uuid`, `mtk_p_mg`.`app_key` AS `appKey`, `mtk_p_mg`.`utdid` AS `utdid`, `mtk_p_mg`.`digest` AS `digest`, `mtk_p_mg`.`content` AS `content`\n" + + "\t, `mtk_p_mg`.`user_info` AS `userInfo`, `mtk_p_mg`.`status` AS `status`, `mtk_p_mg`.`mesg_status` AS `mesgStatus`, `mtk_p_mg`.`start_time` AS `startTime`, `mtk_p_mg`.`expired` AS `expired`\n" + + "\t, `mtk_p_mg`.`online` AS `online`, `mtk_p_mg`.`gmt_commit` AS `gmtCommit`, `mtk_p_mg`.`extra_info` AS `extraInfo`, `mtk_p_mg`.`auto_commit` AS `autoCommit`, `mtk_p_mg`.`task_id` AS `taskId`\n" + + "\t, `mtk_p_mg`.`msg_type` AS `msgType`, `mtk_p_mg`.`push_user_token` AS `pushUserToken`, `mtk_p_mg`.`tb_app_device_token` AS `tbAppDeviceToken`, `mtk_p_mg`.`sdk_version` AS `sdkVersion`, `mtk_p_mg`.`biz_ext_info` AS `bizExtInfo`\n" + + "FROM mtk_p_mg `mtk_p_mg` FORCE INDEX (idx_targetid)\n" + + "WHERE `mtk_p_mg`.`target` = ?\n" + + "ORDER BY `mtk_p_mg`.`id` DESC\n" + + "LIMIT ?, ?", stmt.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_52_schema.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_52_schema.java new file mode 100644 index 0000000000..316cca7fc2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_52_schema.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_52_schema extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + String sql = "UPDATE `buyer_0158`.xc_yy_order\n" + + "SET `ALIPAY_BUYER_ID` = ?, `GMT_MODIFIED` = ?\n" + + "WHERE `PAY_ORDER_ID` = ?"; + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + SQLStatement statement = stmtList.get(0); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + /*visitor.setPrettyFormat(false);*/ + statement.accept(visitor); + /* JSONArray array = new JSONArray(); + for(String table : visitor.getTables()){ + array.add(table.replaceAll("`","")); + }*/ + + String psql = out.toString(); + + System.out.println(psql); + + + assertEquals("UPDATE buyer.xc_yy_order\n" + + "SET `ALIPAY_BUYER_ID` = ?, `GMT_MODIFIED` = ?\n" + + "WHERE `PAY_ORDER_ID` = ?", psql); + } +}