mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser. for issue #1919
This commit is contained in:
@@ -112,6 +112,9 @@ public class FilterManager {
|
||||
|
||||
try {
|
||||
filter = (Filter) filterClass.newInstance();
|
||||
} catch (ClassCastException e) {
|
||||
LOG.error("load filter error.", e);
|
||||
continue;
|
||||
} catch (InstantiationException e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
|
||||
@@ -78,6 +78,12 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
this.lexer.nextToken();
|
||||
}
|
||||
|
||||
|
||||
public MySqlExprParser(String sql, boolean skipComment,boolean keepComments){
|
||||
this(new MySqlLexer(sql, skipComment, keepComments));
|
||||
this.lexer.nextToken();
|
||||
}
|
||||
|
||||
public SQLExpr relationalRest(SQLExpr expr) {
|
||||
if (identifierEquals("REGEXP")) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -98,6 +98,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
super(new MySqlExprParser(sql, keepComments));
|
||||
}
|
||||
|
||||
public MySqlStatementParser(String sql, boolean skipComment, boolean keepComments) {
|
||||
super(new MySqlExprParser(sql, skipComment, keepComments));
|
||||
}
|
||||
|
||||
public MySqlStatementParser(Lexer lexer) {
|
||||
super(new MySqlExprParser(lexer));
|
||||
}
|
||||
|
||||
+10
@@ -1003,4 +1003,14 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
|
||||
public void endVisit(OracleTreatExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateSynonymStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateSynonymStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
|
||||
public class OracleCreateSynonymStatement extends OracleStatementImpl {
|
||||
private boolean orReplace;
|
||||
private SQLName name;
|
||||
private boolean isPublic;
|
||||
private SQLName object;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
acceptChild(visitor, object);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public void setPublic(boolean value) {
|
||||
isPublic = value;
|
||||
}
|
||||
|
||||
public SQLName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SQLName name) {
|
||||
if (name != null) {
|
||||
name.setParent(this);
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SQLName getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(SQLName object) {
|
||||
if (object != null) {
|
||||
object.setParent(this);
|
||||
}
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public boolean isOrReplace() {
|
||||
return orReplace;
|
||||
}
|
||||
|
||||
public void setOrReplace(boolean orReplace) {
|
||||
this.orReplace = orReplace;
|
||||
}
|
||||
}
|
||||
@@ -968,8 +968,19 @@ public class OracleExprParser extends SQLExprParser {
|
||||
}
|
||||
OracleDbLinkExpr dbLink = new OracleDbLinkExpr();
|
||||
dbLink.setExpr(name);
|
||||
dbLink.setDbLink(lexer.stringVal());
|
||||
|
||||
|
||||
String link = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
while (lexer.token() == Token.DOT) {
|
||||
lexer.nextToken();
|
||||
|
||||
String stringVal = lexer.stringVal();
|
||||
accept(Token.IDENTIFIER);
|
||||
link += "." + stringVal;
|
||||
}
|
||||
|
||||
dbLink.setDbLink(link);
|
||||
return dbLink;
|
||||
}
|
||||
|
||||
|
||||
@@ -2293,4 +2293,29 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
accept(Token.SEMI);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLStatement parseCreateSynonym() {
|
||||
OracleCreateSynonymStatement stmt = new OracleCreateSynonymStatement();
|
||||
accept(Token.CREATE);
|
||||
|
||||
if (lexer.token() == Token.OR) {
|
||||
lexer.nextToken();
|
||||
accept(Token.REPLACE);
|
||||
stmt.setOrReplace(true);
|
||||
}
|
||||
|
||||
if (identifierEquals("PUBLIC")) {
|
||||
lexer.nextToken();
|
||||
stmt.setPublic(true);
|
||||
}
|
||||
|
||||
acceptIdentifier("SYNONYM");
|
||||
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
accept(Token.FOR);
|
||||
|
||||
stmt.setObject(this.exprParser.name());
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,4 +427,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(OracleTreatExpr x);
|
||||
|
||||
void endVisit(OracleTreatExpr x);
|
||||
|
||||
boolean visit(OracleCreateSynonymStatement x);
|
||||
|
||||
void endVisit(OracleCreateSynonymStatement x);
|
||||
}
|
||||
|
||||
+10
@@ -1052,4 +1052,14 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
public void endVisit(OracleTreatExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateSynonymStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateSynonymStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3268,4 +3268,32 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
public void endVisit(OracleTreatExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateSynonymStatement x) {
|
||||
|
||||
if (x.isOrReplace()) {
|
||||
print0(ucase ? "CREATE OR REPLACE " : "create or replace ");
|
||||
} else {
|
||||
print0(ucase ? "CREATE " : "create ");
|
||||
}
|
||||
|
||||
if (x.isPublic()) {
|
||||
print0(ucase ? "PUBLIC " : "public ");
|
||||
}
|
||||
|
||||
print0(ucase ? "SYNONYM " : "synonym ");
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
print0(ucase ? " FOR " : " for ");
|
||||
x.getObject().accept(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateSynonymStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -1445,4 +1445,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
public void endVisit(OracleTreatExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateSynonymStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateSynonymStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1853,9 +1853,21 @@ public class SQLStatementParser extends SQLParser {
|
||||
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateDatabase();
|
||||
} else if (identifierEquals("PUBLIC") || identifierEquals("SHARE")) {
|
||||
} else if (identifierEquals("PUBLIC")) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("SYNONYM")) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateSynonym();
|
||||
} else {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateDbLink();
|
||||
}
|
||||
} else if (identifierEquals("SHARE")) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateDbLink();
|
||||
} else if (identifierEquals("SYNONYM")) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateSynonym();
|
||||
} else if (token == Token.VIEW) {
|
||||
return parseCreateView();
|
||||
} else if (token == Token.TRIGGER) {
|
||||
@@ -1963,6 +1975,10 @@ public class SQLStatementParser extends SQLParser {
|
||||
throw new ParserException("TODO " + lexer.token());
|
||||
}
|
||||
|
||||
public SQLStatement parseCreateSynonym() {
|
||||
throw new ParserException("TODO " + lexer.token());
|
||||
}
|
||||
|
||||
public SQLStatement parseCreateTrigger() {
|
||||
accept(Token.CREATE);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public interface JdbcConstants {
|
||||
public static final String MYSQL = "mysql";
|
||||
public static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
|
||||
public static final String MYSQL_DRIVER_6 = "com.mysql.cj.jdbc.Driver";
|
||||
public static final String MYSQL_DRIVER_REPLICATE = "com.mysql.jdbc.ReplicationDriver";
|
||||
public static final String MYSQL_DRIVER_REPLICATE = "com.mysql.jdbc.";
|
||||
|
||||
public static final String MARIADB = "mariadb";
|
||||
public static final String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.oracle.create;
|
||||
|
||||
import com.alibaba.druid.sql.OracleTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OracleCreateSynonymTest extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = //
|
||||
"CREATE SYNONYM offices \n" +
|
||||
" FOR hr.locations;";
|
||||
|
||||
OracleStatementParser parser = new OracleStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
Assert.assertEquals(0, visitor.getTables().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0")));
|
||||
|
||||
Assert.assertEquals(0, visitor.getColumns().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode")));
|
||||
|
||||
assertEquals("CREATE SYNONYM offices FOR hr.locations;", stmt.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.oracle.create;
|
||||
|
||||
import com.alibaba.druid.sql.OracleTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OracleCreateSynonymTest1 extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = //
|
||||
"CREATE PUBLIC SYNONYM customers FOR oe.customers;";
|
||||
|
||||
OracleStatementParser parser = new OracleStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
Assert.assertEquals(0, visitor.getTables().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0")));
|
||||
|
||||
Assert.assertEquals(0, visitor.getColumns().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode")));
|
||||
|
||||
assertEquals("CREATE PUBLIC SYNONYM customers FOR oe.customers;", stmt.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.oracle.create;
|
||||
|
||||
import com.alibaba.druid.sql.OracleTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OracleCreateSynonymTest2 extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = //
|
||||
"CREATE PUBLIC SYNONYM emp_table \n" +
|
||||
" FOR hr.employees@remote.us.oracle.com;";
|
||||
|
||||
OracleStatementParser parser = new OracleStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
print(statementList);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
Assert.assertEquals(0, visitor.getTables().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0")));
|
||||
|
||||
Assert.assertEquals(0, visitor.getColumns().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode")));
|
||||
|
||||
assertEquals("CREATE PUBLIC SYNONYM emp_table FOR hr.employees@remote.us.oracle.com;", stmt.toString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user