improved sql paser for aliyun analyticdb.

This commit is contained in:
wenshao
2018-05-31 13:51:32 +08:00
parent 9c8b14bd4a
commit ca38876d1e
10 changed files with 444 additions and 1 deletions
@@ -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