mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql paser for aliyun analyticdb.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDumpStatement extends SQLStatementImpl {
|
||||
private boolean overwrite;
|
||||
private SQLExprTableSource into;
|
||||
|
||||
private SQLSelect select;
|
||||
|
||||
public SQLDumpStatement() {
|
||||
|
||||
}
|
||||
|
||||
public SQLSelect getSelect() {
|
||||
return select;
|
||||
}
|
||||
|
||||
public void setSelect(SQLSelect x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
|
||||
this.select = x;
|
||||
}
|
||||
|
||||
public SQLExprTableSource getInto() {
|
||||
return into;
|
||||
}
|
||||
|
||||
public void setInto(SQLExpr x) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setInto(new SQLExprTableSource(x));
|
||||
}
|
||||
|
||||
public void setInto(SQLExprTableSource x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
|
||||
this.into = x;
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return overwrite;
|
||||
}
|
||||
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
if (into != null) {
|
||||
into.accept(visitor);
|
||||
}
|
||||
|
||||
if (select != null) {
|
||||
select.accept(visitor);
|
||||
}
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -370,6 +370,13 @@ public class SQLStatementParser extends SQLParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("DUMP")) {
|
||||
SQLStatement stmt = parseDump();
|
||||
statementList.add(stmt);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.COMMIT)) {
|
||||
SQLStatement stmt = parseCommit();
|
||||
|
||||
@@ -427,6 +434,26 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLStatement parseDump() {
|
||||
SQLDumpStatement stmt = new SQLDumpStatement();
|
||||
acceptIdentifier("DUMP");
|
||||
acceptIdentifier("DATA");
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.OVERWRITE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setOverwrite(true);
|
||||
}
|
||||
|
||||
if (lexer.token == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
stmt.setInto(this.exprParser.expr());
|
||||
}
|
||||
|
||||
SQLSelect select = createSQLSelectParser().select();
|
||||
stmt.setSelect(select);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
|
||||
public SQLStatement parseDrop() {
|
||||
List<String> beforeComments = null;
|
||||
|
||||
@@ -6579,6 +6579,32 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
List<SQLCommentHint> headHints = x.getHeadHintsDirect();
|
||||
if (headHints != null) {
|
||||
for (SQLCommentHint hint : headHints) {
|
||||
hint.accept(this);
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
print0(ucase ? "DUMP DATA " : "dump data ");
|
||||
|
||||
|
||||
if (x.isOverwrite()) {
|
||||
print0(ucase ? "OVERWRITE " : "overwrite ");
|
||||
}
|
||||
|
||||
SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
into.accept(this);
|
||||
}
|
||||
|
||||
x.getSelect().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void print(float value) {
|
||||
if (this.appender == null) {
|
||||
return;
|
||||
|
||||
@@ -842,4 +842,7 @@ public interface SQLASTVisitor {
|
||||
boolean visit(SQLWindow x);
|
||||
void endVisit(SQLWindow x);
|
||||
|
||||
boolean visit(SQLDumpStatement x);
|
||||
void endVisit(SQLDumpStatement x);
|
||||
|
||||
}
|
||||
|
||||
@@ -1990,7 +1990,6 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWindow x) {
|
||||
return true;
|
||||
@@ -2000,6 +1999,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void endVisit(SQLDumpStatement x) {
|
||||
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
|
||||
@@ -2515,4 +2515,23 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDumpStatement x) {
|
||||
if (repository != null
|
||||
&& x.getParent() == null) {
|
||||
repository.resolve(x);
|
||||
}
|
||||
|
||||
final SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
into.accept(this);
|
||||
}
|
||||
|
||||
final SQLSelect select = x.getSelect();
|
||||
if (select != null) {
|
||||
select.accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,5 +649,7 @@ public final class FnvHash {
|
||||
long GENERATED = fnv1a_64_lower("GENERATED");
|
||||
long ALWAYS = fnv1a_64_lower("ALWAYS");
|
||||
long INCREMENT = fnv1a_64_lower("INCREMENT");
|
||||
|
||||
long OVERWRITE = fnv1a_64_lower("OVERWRITE");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlDumpTest extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "dump data into 'odps://ktv_market_analyzing/bohan_test_001/ds=20171233/seller_bucket=9727' " +
|
||||
"select '6225607' as crowd_snapshot_id, a.seller_id as seller_id, a.buyer_id as buyer_id " +
|
||||
"from amp.otpx_buyer_seller_relation_detail_to_garuda a " +
|
||||
"join amp.otp_user_base_info b on b.user_id= a.buyer_id " +
|
||||
"where(((a.seller_id= 765844183 and a.seller_zone= 765844183%20+ 1000)) and((a.last_pay_date>= 20151226 and a.last_pay_date<= 20171215)) and((a.is_market_target in('3'))))";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(2, visitor.getTables().size());
|
||||
assertEquals(6, visitor.getColumns().size());
|
||||
assertEquals(7, visitor.getConditions().size());
|
||||
|
||||
assertTrue(visitor.containsTable("amp.otp_user_base_info"));
|
||||
assertTrue(visitor.containsTable("amp.otpx_buyer_seller_relation_detail_to_garuda"));
|
||||
// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t2")));
|
||||
|
||||
assertTrue(visitor.containsColumn("amp.otp_user_base_info", "user_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "buyer_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "seller_id"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "seller_zone"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "is_market_target"));
|
||||
assertTrue(visitor.containsColumn("amp.otpx_buyer_seller_relation_detail_to_garuda", "last_pay_date"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.mysql;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlDumpTest_1 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "DUMP DATA OVERWRITE INTO 'odps://cod_garuda/wenyu_meta_person' select cid, cname, dept, gender, pid from wenyu_meta_person limit 10;";
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(1, visitor.getTables().size());
|
||||
assertEquals(5, visitor.getColumns().size());
|
||||
assertEquals(0, visitor.getConditions().size());
|
||||
|
||||
assertTrue(visitor.containsTable("wenyu_meta_person"));
|
||||
// assertTrue(visitor.getTables().containsKey(new TableStat.Name("t2")));
|
||||
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "cid"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "cname"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "dept"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "gender"));
|
||||
assertTrue(visitor.containsColumn("wenyu_meta_person", "pid"));
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user