mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve parser ddl support
This commit is contained in:
@@ -53,25 +53,27 @@ import com.alibaba.druid.support.logging.LogFactory;
|
||||
*/
|
||||
public class DruidPooledConnection extends PoolableWrapper implements javax.sql.PooledConnection, Connection {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(DruidPooledConnection.class);
|
||||
private final static Log LOG = LogFactory.getLog(DruidPooledConnection.class);
|
||||
|
||||
public static final int MAX_RECORD_SQL_COUNT = 10;
|
||||
|
||||
protected Connection conn;
|
||||
protected volatile DruidConnectionHolder holder;
|
||||
protected TransactionInfo transactionInfo;
|
||||
private final boolean dupCloseLogEnable;
|
||||
private volatile boolean traceEnable = false;
|
||||
private boolean disable = false;
|
||||
private boolean closed = false;
|
||||
private volatile boolean traceEnable = false;
|
||||
private boolean disable = false;
|
||||
private boolean closed = false;
|
||||
private final Thread ownerThread;
|
||||
|
||||
private long connectedTimeNano;
|
||||
private volatile boolean running = false;
|
||||
private volatile boolean running = false;
|
||||
|
||||
private volatile boolean abandoned = false;
|
||||
private volatile boolean abandoned = false;
|
||||
|
||||
private StackTraceElement[] connectStackTrace;
|
||||
|
||||
private Throwable disableError = null;
|
||||
private Throwable disableError = null;
|
||||
|
||||
public DruidPooledConnection(DruidConnectionHolder holder){
|
||||
super(holder.getConnection());
|
||||
@@ -686,7 +688,10 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
|
||||
}
|
||||
|
||||
if (transactionInfo != null) {
|
||||
transactionInfo.getSqlList().add(sql);
|
||||
List<String> sqlList = transactionInfo.getSqlList();
|
||||
if (sqlList.size() < MAX_RECORD_SQL_COUNT) {
|
||||
sqlList.add(sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLStatement {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean orReplace = false;
|
||||
protected SQLName name;
|
||||
protected SQLSelect subQuery;
|
||||
|
||||
@@ -37,6 +38,14 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
|
||||
}
|
||||
|
||||
public boolean isOrReplace() {
|
||||
return orReplace;
|
||||
}
|
||||
|
||||
public void setOrReplace(boolean orReplace) {
|
||||
this.orReplace = orReplace;
|
||||
}
|
||||
|
||||
public SQLName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -284,11 +284,24 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
public SQLStatement parseCreate() {
|
||||
char markChar = lexer.current();
|
||||
int markBp = lexer.bp();
|
||||
|
||||
accept(Token.CREATE);
|
||||
|
||||
boolean replace = false;
|
||||
if (lexer.token() == Token.OR) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("REPLACE");
|
||||
replace = true;
|
||||
}
|
||||
|
||||
List<SQLCommentHint> hints = this.exprParser.parseHints();
|
||||
|
||||
if (lexer.token() == Token.TABLE || identifierEquals(TEMPORARY)) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
MySqlCreateTableParser parser = new MySqlCreateTableParser(this.exprParser);
|
||||
MySqlCreateTableStatement stmt = parser.parseCrateTable(false);
|
||||
stmt.setHints(hints);
|
||||
@@ -296,19 +309,32 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.DATABASE) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
return parseCreateDatabase();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals(FULLTEXT)
|
||||
|| identifierEquals(SPATIAL)) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
return parseCreateIndex();
|
||||
}
|
||||
|
||||
if (identifierEquals(USER)) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
return parseCreateUser();
|
||||
}
|
||||
|
||||
|
||||
if (lexer.token() == Token.VIEW) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
|
||||
return parseCreateView();
|
||||
}
|
||||
|
||||
@@ -1494,7 +1520,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
parseValueClause(stmt.getValuesList(), 0);
|
||||
} else if (lexer.token() == Token.SELECT) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
||||
@@ -1871,7 +1897,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(valueExprList);
|
||||
valueClauseList.add(values);
|
||||
} else {
|
||||
@@ -2222,11 +2248,11 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
if (identifierEquals("COLUMN")) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
|
||||
SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn();
|
||||
SQLColumnDefinition columnDef = this.exprParser.parseColumn();
|
||||
alterColumn.setColumn(columnDef);
|
||||
|
||||
|
||||
stmt.getItems().add(alterColumn);
|
||||
} else if (identifierEquals("CHANGE")) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -1078,6 +1078,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlDropViewStatement x) {
|
||||
setMode(x, Mode.Drop);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,11 @@ public class SQLServerExprParser extends SQLExprParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.PERCENT) {
|
||||
lexer.nextToken();
|
||||
top.setPercent(true);
|
||||
}
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ public class SQLServerLexer extends Lexer {
|
||||
map.put("TOP", Token.TOP);
|
||||
map.put("USE", Token.USE);
|
||||
map.put("WITH", Token.WITH);
|
||||
map.put("PERCENT", Token.PERCENT);
|
||||
|
||||
DEFAULT_SQL_SERVER_KEYWORDS = new Keywords(map);
|
||||
}
|
||||
|
||||
+2
-4
@@ -76,9 +76,7 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.TOP) {
|
||||
SQLServerTop top = new SQLServerTop();
|
||||
lexer.nextToken();
|
||||
top.setExpr(createExprParser().primary());
|
||||
SQLServerTop top = this.createExprParser().parseTop();
|
||||
queryBlock.setTop(top);
|
||||
}
|
||||
|
||||
@@ -101,7 +99,7 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
return queryRest(queryBlock);
|
||||
}
|
||||
|
||||
protected SQLExprParser createExprParser() {
|
||||
protected SQLServerExprParser createExprParser() {
|
||||
return new SQLServerExprParser(lexer);
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -96,6 +96,10 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
|
||||
print(")");
|
||||
}
|
||||
|
||||
if (x.isPercent()) {
|
||||
print(" PERCENT");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -644,6 +644,12 @@ public class SQLStatementParser extends SQLParser {
|
||||
if (lexer.token() == Token.CREATE) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.OR) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("REPLACE");
|
||||
createView.setOrReplace(true);
|
||||
}
|
||||
|
||||
this.accept(Token.VIEW);
|
||||
|
||||
|
||||
@@ -808,6 +808,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
case Merge:
|
||||
stat.incrementMergeCount();
|
||||
break;
|
||||
case Drop:
|
||||
stat.incrementDropCount();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -445,7 +445,14 @@ public class TableStat {
|
||||
}
|
||||
|
||||
public static enum Mode {
|
||||
Insert(1), Update(2), Delete(4), Select(8), Merge(16), Truncate(32), Alter(64);
|
||||
Insert(1), //
|
||||
Update(2), //
|
||||
Delete(4), //
|
||||
Select(8), //
|
||||
Merge(16), //
|
||||
Truncate(32), //
|
||||
Alter(64), //
|
||||
Drop(128);
|
||||
|
||||
public final int mark;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import junit.framework.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
@@ -30,14 +30,14 @@ import com.alibaba.druid.stat.TableStat.Column;
|
||||
public class MySqlCreateTableTest9 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "CREATE VIEW view AS\n" + //
|
||||
String sql = "CREATE VIEW v AS\n" + //
|
||||
"SELECT ProductID,ProductName\n" + //
|
||||
"FROM Products\n" + //
|
||||
"WHERE Discontinued=No";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
MySqlCreateTableStatement stmt = (MySqlCreateTableStatement) statementList.get(0);
|
||||
SQLCreateViewStatement stmt = (SQLCreateViewStatement) statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2011 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 java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
import com.alibaba.druid.stat.TableStat.Column;
|
||||
|
||||
public class MySqlCreateViewTest extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "CREATE OR REPLACE VIEW view_name AS\n" + //
|
||||
"SELECT fname\n" + //
|
||||
"FROM table_name\n" + //
|
||||
"WHERE fid = ?";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLCreateViewStatement stmt = (SQLCreateViewStatement) statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.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());
|
||||
|
||||
Assert.assertEquals(1, visitor.getTables().size());
|
||||
Assert.assertEquals(2, visitor.getColumns().size());
|
||||
Assert.assertEquals(1, visitor.getConditions().size());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table_name")));
|
||||
|
||||
Assert.assertTrue(visitor.getColumns().contains(new Column("table_name", "fid")));
|
||||
Assert.assertTrue(visitor.getColumns().contains(new Column("table_name", "fname")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 1999-2011 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 java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDropViewStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
import com.alibaba.druid.stat.TableStat.Column;
|
||||
|
||||
public class MySqlDropViewTest extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "DROP VIEW view_name";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
MySqlDropViewStatement stmt = (MySqlDropViewStatement) statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.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());
|
||||
|
||||
Assert.assertEquals(1, visitor.getTables().size());
|
||||
Assert.assertEquals(0, visitor.getColumns().size());
|
||||
Assert.assertEquals(0, visitor.getConditions().size());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("view_name")));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2011 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 junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
|
||||
import com.alibaba.druid.sql.test.TestUtils;
|
||||
|
||||
public class SQLServerSelectTest15 extends TestCase {
|
||||
|
||||
public void test_simple() throws Exception {
|
||||
String sql = "SELECT TOP 50 PERCENT * FROM Persons"; //
|
||||
|
||||
String expect = "SELECT TOP 50 PERCENT *\n" + //
|
||||
"FROM Persons";
|
||||
|
||||
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
|
||||
String text = TestUtils.outputSqlServer(stmt);
|
||||
|
||||
Assert.assertEquals(expect, text);
|
||||
|
||||
System.out.println(text);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user