/src/main/java/com/alibaba/druid/support/opds/udf/SqlCodeStat.java
https://github.com/alibaba/druid · Java · 359 lines · 284 code · 75 blank · 0 comment · 52 complexity · 8007d011d429b7330eccf0b64ef25186 MD5 · raw file
- package com.alibaba.druid.support.opds.udf;
- import com.alibaba.druid.DbType;
- import com.alibaba.druid.sql.SQLUtils;
- import com.alibaba.druid.sql.ast.*;
- import com.alibaba.druid.sql.ast.expr.*;
- import com.alibaba.druid.sql.ast.statement.*;
- import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert;
- import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement;
- import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
- import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
- import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitorAdapter;
- import com.alibaba.druid.sql.parser.SQLParserFeature;
- import com.alibaba.fastjson2.JSON;
- import com.alibaba.fastjson2.JSONWriter;
- import com.alibaba.fastjson2.annotation.JSONField;
- import com.aliyun.odps.udf.UDF;
- import java.util.List;
- public class SqlCodeStat extends UDF {
- public String evaluate(String sql) {
- return evaluate(sql, null, false);
- }
- public String evaluate(String sql, String dbTypeName) {
- return evaluate(sql, dbTypeName, false);
- }
- public String evaluate(String sql, String dbTypeName, boolean throwError) {
- DbType dbType = dbTypeName == null ? null : DbType.valueOf(dbTypeName);
- try {
- List<SQLStatement> stmtList = SQLUtils.parseStatements(
- sql,
- DbType.odps,
- SQLParserFeature.EnableMultiUnion,
- SQLParserFeature.EnableSQLBinaryOpExprGroup
- );
- CodeStatVisitor v = new CodeStatVisitor();
- for (SQLStatement stmt : stmtList) {
- stmt.accept(v);
- }
- return v.toString();
- } catch (Exception ex) {
- if (throwError) {
- throw new IllegalArgumentException("error sql : \n" + sql, ex);
- }
- return null;
- }
- }
- public static class SqlStat {
- @JSONField(ordinal = 0)
- public int statementCount;
- @JSONField(ordinal = 1)
- public int cte;
- @JSONField(ordinal = 2)
- public int union;
- @JSONField(ordinal = 3)
- public int select;
- @JSONField(ordinal = 4)
- public int groupBy;
- @JSONField(ordinal = 5)
- public int orderBy;
- @JSONField(ordinal = 6)
- public int from;
- @JSONField(ordinal = 7)
- public int join;
- @JSONField(ordinal = 8)
- public int over;
- @JSONField(ordinal = 9)
- public int subQuery;
- @JSONField(ordinal = 10)
- public int lateralView;
- @JSONField(ordinal = 40)
- public int insert;
- @JSONField(ordinal = 41)
- public int insertInto;
- @JSONField(ordinal = 42)
- public int insertOverwrite;
- @JSONField(ordinal = 43)
- public int insertSelect;
- @JSONField(ordinal = 44)
- public int insertMulti;
- @JSONField(ordinal = 51)
- public int update;
- @JSONField(ordinal = 52)
- public int delete;
- @JSONField(ordinal = 60)
- public int create;
- @JSONField(ordinal = 61)
- public int createTable;
- @JSONField(ordinal = 62)
- public int createView;
- @JSONField(ordinal = 70)
- public int drop;
- @JSONField(ordinal = 71)
- public int dropTable;
- @JSONField(ordinal = 72)
- public int dropView;
- @JSONField(ordinal = 80)
- public int set;
- @JSONField(ordinal = 90)
- public int alter;
- @JSONField(ordinal = 100)
- public int read;
- @JSONField(ordinal = 200)
- public int condition;
- @JSONField(ordinal = 201)
- public int joinCondition;
- @JSONField(ordinal = 202)
- public int valueCondition;
- @JSONField(ordinal = 203)
- public int otherCondition;
- @JSONField(ordinal = 204)
- public int limit;
- @JSONField(ordinal = 300)
- public int aggregate;
- @JSONField(ordinal = 201)
- public int functionCall;
- @JSONField(ordinal = 202)
- public int having;
- }
- static class CodeStatVisitor extends OdpsASTVisitorAdapter {
- SqlStat stat = new SqlStat();
- public void preVisit(SQLObject x) {
- if (x instanceof SQLStatement) {
- stat.statementCount++;
- if (x instanceof SQLInsertStatement) {
- stat.insert++;
- SQLInsertStatement insert = (SQLInsertStatement) x;
- if (insert.getQuery() != null) {
- stat.insertSelect++;
- }
- if (insert.isOverwrite()) {
- stat.insertOverwrite++;
- } else {
- stat.insertInto++;
- }
- } else if (x instanceof HiveMultiInsertStatement) {
- stat.insert++;
- stat.insertMulti++;
- stat.insertSelect++;
- for (HiveInsert item : ((HiveMultiInsertStatement) x).getItems()) {
- if (item.isOverwrite()) {
- stat.insertOverwrite++;
- } else {
- stat.insertInto++;
- }
- }
- } else if (x instanceof SQLDropStatement) {
- stat.drop++;
- if (x instanceof SQLDropTableStatement) {
- stat.dropTable++;
- } else if (x instanceof SQLDropViewStatement) {
- stat.dropView++;
- }
- } else if (x instanceof SQLCreateStatement) {
- stat.create++;
- if (x instanceof SQLCreateTableStatement) {
- stat.createTable++;
- } else if (x instanceof SQLCreateViewStatement) {
- stat.createView++;
- }
- } else if (x instanceof SQLDeleteStatement) {
- stat.delete++;
- } else if (x instanceof SQLUpdateStatement) {
- stat.update++;
- } else if (x instanceof SQLSetStatement) {
- stat.set++;
- } else if (x instanceof SQLAlterStatement) {
- stat.alter++;
- } else if (x instanceof OdpsReadStatement) {
- stat.read++;
- }
- }
- }
- public boolean visit(SQLUnionQuery x) {
- stat.union++;
- return true;
- }
- public boolean visit(SQLLateralViewTableSource x) {
- stat.lateralView++;
- return true;
- }
- public boolean visit(OdpsSelectQueryBlock x) {
- return visit((SQLSelectQueryBlock) x);
- }
- public boolean visit(SQLSelectQueryBlock x) {
- stat.select++;
- return true;
- }
- public boolean visit(SQLSelectGroupByClause x) {
- stat.groupBy++;
- if (x.getHaving() != null) {
- stat.having++;
- }
- return true;
- }
- public boolean visit(SQLLimit x) {
- stat.limit++;
- return false;
- }
- public boolean visit(SQLWithSubqueryClause.Entry x) {
- stat.cte++;
- return true;
- }
- public boolean visit(SQLOrderBy x) {
- stat.orderBy++;
- return true;
- }
- public boolean visit(SQLExprTableSource x) {
- stat.from++;
- return true;
- }
- public boolean visit(SQLSubqueryTableSource x) {
- stat.from++;
- stat.subQuery++;
- return true;
- }
- public boolean visit(SQLJoinTableSource x) {
- if (!(x.getParent() instanceof SQLJoinTableSource)) {
- stat.from++;
- }
- stat.join++;
- return true;
- }
- public boolean visit(SQLMethodInvokeExpr x) {
- stat.functionCall++;
- return true;
- }
- public boolean visit(SQLAggregateExpr x) {
- stat.aggregate++;
- return true;
- }
- public boolean visit(SQLOver x) {
- stat.over++;
- return true;
- }
- public boolean visit(SQLCastExpr x) {
- stat.functionCall++;
- return true;
- }
- public boolean visit(SQLInListExpr x) {
- stat.condition++;
- return true;
- }
- public boolean visit(SQLBinaryOpExpr x) {
- if (x.getOperator() != null && x.getOperator().isRelational()) {
- stat.condition++;
- SQLExpr left = x.getLeft();
- SQLExpr right = x.getRight();
- if (left instanceof SQLName && right instanceof SQLName) {
- stat.joinCondition++;
- } else if ((left instanceof SQLName || right instanceof SQLName)
- && (left instanceof SQLLiteralExpr || right instanceof SQLLiteralExpr)
- ) {
- stat.valueCondition++;
- } else {
- stat.otherCondition++;
- }
- }
- return true;
- }
- public boolean visit(SQLCaseExpr x) {
- SQLExpr value = x.getValueExpr();
- if (value != null) {
- stat.condition += x.getItems().size();
- }
- if (x.getElseExpr() != null) {
- stat.condition++;
- }
- return true;
- }
- public boolean visit(SQLExistsExpr x) {
- stat.condition++;
- return true;
- }
- public String toString() {
- return JSON.toJSONString(
- stat,
- JSONWriter.Feature.PrettyFormat,
- JSONWriter.Feature.NotWriteDefaultValue
- );
- }
- public java.util.Map toMap() {
- return (java.util.Map) JSON.toJSON(stat);
- }
- }
- }