mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<SQLSelectItem> selectList = new ArrayList<SQLSelectItem>();
|
||||
private boolean bracket = false;
|
||||
protected int distionOption;
|
||||
protected final List<SQLSelectItem> selectList = new ArrayList<SQLSelectItem>();
|
||||
|
||||
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<SQLExpr> forUpdateOf;
|
||||
|
||||
protected List<SQLExpr> distributeBy;
|
||||
protected List<SQLExpr> forUpdateOf;
|
||||
protected List<SQLExpr> distributeBy;
|
||||
protected List<SQLSelectOrderByItem> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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<SQLStatement> statementList) {
|
||||
|
||||
@@ -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<SQLName> keyColumns = new ArrayList<SQLName>();
|
||||
|
||||
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<SQLName> getKeyColumns() {
|
||||
return keyColumns;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
+2
-6
@@ -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<SQLExpr> procedureArgumentList;
|
||||
|
||||
private boolean lockInShareMode = false;
|
||||
|
||||
private boolean lockInShareMode;
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
public MySqlSelectQueryBlock(){
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
+5
-4
@@ -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();
|
||||
|
||||
|
||||
+1
-1
@@ -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){
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> sqlCache = new ArrayList<String>();
|
||||
private List<SQLSelectQueryBlock> queryBlockCache = new ArrayList<SQLSelectQueryBlock>();
|
||||
private List<String> printSqlList = new ArrayList<String>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<SQLStatement> 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user