From 2107d236c0ceef21bc9137a63fa6c1827f7028cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E9=93=81?= Date: Tue, 3 Nov 2015 14:24:10 +0800 Subject: [PATCH] improved schemastat --- .../statement/SQLCreateTableStatement.java | 21 +++++-- .../statement/MySqlCreateTableStatement.java | 10 +-- .../mysql/parser/MySqlCreateTableParser.java | 2 +- .../mysql/visitor/MySqlOutputVisitor.java | 4 +- .../odps/ast/OdpsCreateTableStatement.java | 17 +----- .../ast/stmt/OracleCreateTableStatement.java | 11 ---- .../druid/sql/visitor/SchemaStatVisitor.java | 4 ++ .../opds/udf/ExportConditionColumns.java | 61 +++++++++++++++++++ .../opds/udf/ExportSelectListColumns.java | 61 +++++++++++++++++++ .../odps/udf/ExportSelectListColumnsTest.java | 20 ++++++ 10 files changed, 173 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/support/opds/udf/ExportConditionColumns.java create mode 100644 src/main/java/com/alibaba/druid/support/opds/udf/ExportSelectListColumns.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/udf/ExportSelectListColumnsTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index 355b35fb31..7359f68fc8 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -24,14 +24,16 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement { - protected boolean ifNotExiists = false; - protected Type type; - protected SQLExprTableSource tableSource; + protected boolean ifNotExiists = false; + protected Type type; + protected SQLExprTableSource tableSource; protected List tableElementList = new ArrayList(); // for postgresql - private SQLExprTableSource inherits; + private SQLExprTableSource inherits; + + protected SQLSelect select; public SQLCreateTableStatement(){ @@ -73,7 +75,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS } public static enum Type { - GLOBAL_TEMPORARY, LOCAL_TEMPORARY + GLOBAL_TEMPORARY, LOCAL_TEMPORARY } public List getTableElementList() { @@ -99,12 +101,21 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS this.inherits = inherits; } + public SQLSelect getSelect() { + return select; + } + + public void setSelect(SQLSelect select) { + this.select = select; + } + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { this.acceptChild(visitor, tableSource); this.acceptChild(visitor, tableElementList); this.acceptChild(visitor, inherits); + this.acceptChild(visitor, select); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java index 04cbd36348..145e91c55d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java @@ -37,8 +37,6 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement private Map tableOptions = new LinkedHashMap(); - protected SQLSelect query; - private SQLPartitioningClause partitioning; private List hints = new ArrayList(); @@ -90,12 +88,14 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement return tableOptions; } + @Deprecated public SQLSelect getQuery() { - return query; + return select; } + @Deprecated public void setQuery(SQLSelect query) { - this.query = query; + this.select = query; } @Override @@ -113,7 +113,7 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement this.acceptChild(visitor, getTableSource()); this.acceptChild(visitor, getTableElementList()); this.acceptChild(visitor, getLike()); - this.acceptChild(visitor, getQuery()); + this.acceptChild(visitor, getSelect()); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index 14455822ed..a1cd8acac9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -581,7 +581,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { if (lexer.token() == (Token.SELECT)) { SQLSelect query = new MySqlSelectParser(this.exprParser).select(); - stmt.setQuery(query); + stmt.setSelect(query); } while (lexer.token() == (Token.HINT)) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index c59ed17cd7..7c660e456a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -520,10 +520,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV x.getPartitioning().accept(this); } - if (x.getQuery() != null) { + if (x.getSelect() != null) { incrementIndent(); println(); - x.getQuery().accept(this); + x.getSelect().accept(this); decrementIndent(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java index 02ee51ead8..d3cacd87c6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java @@ -23,22 +23,19 @@ import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.util.JdbcConstants; public class OdpsCreateTableStatement extends SQLCreateTableStatement { - private SQLExprTableSource like; + private SQLExprTableSource like; - protected SQLExpr comment; + protected SQLExpr comment; protected List partitionColumns = new ArrayList(2); - protected SQLExpr lifecycle; - - protected SQLSelect select; + protected SQLExpr lifecycle; public OdpsCreateTableStatement(){ super(JdbcConstants.ODPS); @@ -76,14 +73,6 @@ public class OdpsCreateTableStatement extends SQLCreateTableStatement { this.lifecycle = lifecycle; } - public SQLSelect getSelect() { - return select; - } - - public void setSelect(SQLSelect select) { - this.select = select; - } - @Override protected void accept0(SQLASTVisitor visitor) { accept0((OdpsASTVisitor) visitor); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java index ed5d7382e2..0940c20441 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java @@ -19,7 +19,6 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLPartitioningClause; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; @@ -30,8 +29,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen private SQLName tablespace; - private SQLSelect select; - private boolean inMemoryMetadata; private boolean cursorSpecificSegment; @@ -200,14 +197,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.tablespace = tablespace; } - public SQLSelect getSelect() { - return select; - } - - public void setSelect(SQLSelect select) { - this.select = select; - } - protected void accept0(SQLASTVisitor visitor) { accept0((OracleASTVisitor) visitor); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index d5cf99ccc8..dc174689a7 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -1136,6 +1136,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { x.getInherits().accept(this); } + if (x.getSelect() != null) { + x.getSelect().accept(this); + } + return false; } diff --git a/src/main/java/com/alibaba/druid/support/opds/udf/ExportConditionColumns.java b/src/main/java/com/alibaba/druid/support/opds/udf/ExportConditionColumns.java new file mode 100644 index 0000000000..2eb77e51f1 --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/opds/udf/ExportConditionColumns.java @@ -0,0 +1,61 @@ +/* + * Copyright 1999-2101 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.support.opds.udf; + +import java.util.List; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.aliyun.odps.udf.UDF; + +public class ExportConditionColumns extends UDF { + + public String evaluate(String sql) { + return evaluate(sql, null); + } + + public String evaluate(String sql, String dbType) { + try { + List statementList = SQLUtils.parseStatements(sql, dbType); + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType); + + for (SQLStatement stmt : statementList) { + stmt.accept(visitor); + } + + StringBuffer buf = new StringBuffer(); + + for (TableStat.Column column : visitor.getColumns()) { + if ((!column.isWhere()) && !column.isJoin()) { + continue; + } + + if (buf.length() != 0) { + buf.append(','); + } + buf.append(column.toString()); + } + + return buf.toString(); + } catch (Throwable ex) { + System.err.println("error sql : " + sql); + ex.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/com/alibaba/druid/support/opds/udf/ExportSelectListColumns.java b/src/main/java/com/alibaba/druid/support/opds/udf/ExportSelectListColumns.java new file mode 100644 index 0000000000..51defb4397 --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/opds/udf/ExportSelectListColumns.java @@ -0,0 +1,61 @@ +/* + * Copyright 1999-2101 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.support.opds.udf; + +import java.util.List; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.aliyun.odps.udf.UDF; + +public class ExportSelectListColumns extends UDF { + + public String evaluate(String sql) { + return evaluate(sql, null); + } + + public String evaluate(String sql, String dbType) { + try { + List statementList = SQLUtils.parseStatements(sql, dbType); + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType); + + for (SQLStatement stmt : statementList) { + stmt.accept(visitor); + } + + StringBuffer buf = new StringBuffer(); + + for (TableStat.Column column : visitor.getColumns()) { + if (!column.isSelect()) { + continue; + } + + if (buf.length() != 0) { + buf.append(','); + } + buf.append(column.toString()); + } + + return buf.toString(); + } catch (Throwable ex) { + System.err.println("error sql : " + sql); + ex.printStackTrace(); + return null; + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/udf/ExportSelectListColumnsTest.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/udf/ExportSelectListColumnsTest.java new file mode 100644 index 0000000000..c99b6d2ae6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/udf/ExportSelectListColumnsTest.java @@ -0,0 +1,20 @@ +package com.alibaba.druid.bvt.sql.odps.udf; + +import com.alibaba.druid.support.opds.udf.ExportSelectListColumns; + +import junit.framework.TestCase; + +public class ExportSelectListColumnsTest extends TestCase { + + private ExportSelectListColumns udf = new ExportSelectListColumns(); + + public void test_0() throws Exception { + String sql = "SELECT fund_base_cv_creative_ocr_judge_control_words_1422189630695(a.tfs, b.ocr_text, a.cates)" + + "\n AS (tfs, control_word, ocr_word, control_type, cates)" + + "\n FROM fund_base_cv_ad_auction_ocr_pv_tfs a" + + "\n JOIN fund_base_cv_ad_auction_ocr_pv_tfs_ocr b ON a.tfs = b.tfs" + + "\n WHERE a.ds=20150819 and b.ds=20150819;"; + + System.out.println(udf.evaluate(sql, "odps")); + } +}