package util;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Synonym;
import bean.Table;
import bean.View;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLShowStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.gauss.ast.stmt.GaussAlterSessionStatement;
import com.alibaba.druid.sql.dialect.gauss.ast.stmt.GaussAlterSystemKillSessionStatement;
import com.alibaba.druid.sql.dialect.greenplum.ast.stmt.GPAlterSchemaStatement;
import com.alibaba.druid.sql.dialect.greenplum.ast.stmt.GPAlterViewStatement;
import com.alibaba.druid.sql.dialect.greenplum.ast.stmt.GPCreateTableStatement;
import com.alibaba.druid.sql.dialect.greenplum.ast.stmt.GPCreateViewStatement;
import com.alibaba.druid.sql.dialect.greenplum.ast.stmt.GPDropSchemaStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import util.log.SQLLogger;
import util.sqlparse.DB2Parse;
import util.sqlparse.DmParse;
import util.sqlparse.HiveParse;
import util.sqlparse.KingBaseParse;
import util.sqlparse.MySqlParse;
import util.sqlparse.OracleParse;
import util.sqlparse.PostgreSqlParse;
import util.sqlparse.visitor.common.names.NameWrapper;

public class JdbcUtil {
   public static List<DataBase> dataBaseList;
   public static boolean init;

   public static void initData(String json) {
      JdbcCacheUtil.initData(json);
   }

   public static void refreshData(String json) {
      JdbcCacheUtil.refreshData(json);
   }

   public static void initDataAsynchronous(String json) {
      JdbcCacheUtil.initDataAsynchronous(json);
   }

   public static Connection getConnection(String url, String username, String password) {
      Connection connection = null;

      try {
         connection = DriverManager.getConnection(url, username, password);
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      return connection;
   }

   public static Connection getGaussConnection(String url, String username, String password) throws ClassNotFoundException {
      Connection connection = null;
      Class.forName("org.postgresql.Driver");

      try {
         connection = DriverManager.getConnection(url, username, password);
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      return connection;
   }

   public static Connection getDB2Connection(String url, String username, String password) throws ClassNotFoundException {
      Connection connection = null;
      Class.forName("com.ibm.db2.jcc.DB2Driver");

      try {
         connection = DriverManager.getConnection(url, username, password);
         String defaultSchema = connection.getMetaData().getURL();
         System.out.println("Default Schema: " + defaultSchema);
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      return connection;
   }

   public static Connection getDmConnection(String url, String username, String password) {
      Connection connection = null;

      try {
         String driver = "dm.jdbc.driver.DmDriver";
         Class.forName(driver);
         connection = DriverManager.getConnection(url, username, password);
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      return connection;
   }

   public static void closeConnection(Connection connection) {
      if (connection != null) {
         try {
            connection.close();
         } catch (SQLException throwables) {
            throwables.printStackTrace();
         }
      }

   }

   public static List<Column> getTableColumns(String ip_port, String schemaName, String tableName, String alias, HashMap<String, List<Column>> tableList) throws SQLException {
      if (tableName == null) {
         return new ArrayList<>();
      } else {
         List<Column> result = (List)tableList.get(tableName);
         if (result != null) {
            return result;
         } else {
            tableName = tableName.replaceAll("[`\"]", "");
            schemaName = schemaName.replaceAll("[`\"]", "");
            result = new ArrayList();

            for(DataBase dataBase : dataBaseList) {
               if (dataBase.getIp_port().equalsIgnoreCase(ip_port.trim())) {
                  boolean caseSensitive = dataBase.isCaseSensitive();
                  if (!"mysql".equals(dataBase.getDbType()) && !"KUNDB".equals(dataBase.getDbType()) && !"kundb".equals(dataBase.getDbType()) && !"kingbase".equals(dataBase.getDbType()) && !"dm".equals(dataBase.getDbType()) && !"db2".equals(dataBase.getDbType()) && !"oracle".equals(dataBase.getDbType()) && !"sqlserver".equals(dataBase.getDbType()) && !"sql server".equals(dataBase.getDbType()) && !"mssqlserver".equals(dataBase.getDbType()) && !"spark".equals(dataBase.getDbType()) && !"hive_tdh".equals(dataBase.getDbType()) && !"HIVE_TDH".equals(dataBase.getDbType()) && !"postgresql".equals(dataBase.getDbType()) && !"sparksql".equals(dataBase.getDbType())) {
                     if (!dataBase.isRedis()) {
                        if (!dataBase.isRedis()) {
                           for(Schema schema : dataBase.getSchemaList()) {
                              if (schema.getName().equalsIgnoreCase(schemaName)) {
                                 for(Table table : schema.getTableList()) {
                                    if (table.getName().equalsIgnoreCase(tableName) && (!caseSensitive || table.getName().equals(tableName))) {
                                       normalizeColumn(alias, result, schema, table);
                                    }
                                 }
                              }
                           }
                        } else {
                           NameWrapper nameWrapper = NameWrapper.create(DbType.of(dataBase.getDbType()), dataBase.simpleCache);
                           Schema schemaFromRedis = nameWrapper.getSchemaFromRedis(schemaName, caseSensitive);
                           Table tableFromRedis = nameWrapper.getTableFromRedis(schemaFromRedis, tableName, caseSensitive);
                           normalizeColumn(alias, result, schemaFromRedis, tableFromRedis);
                        }
                     }
                  } else {
                     NameWrapper nameWrapper = NameWrapper.create(DbType.of(dataBase.getDbType()), dataBase.simpleCache);
                     Table table = nameWrapper.getTable(schemaName, tableName);
                     if (table != null && table.getColumnList() != null) {
                        for(Column column : table.getColumnList()) {
                           String colName = "";
                           if ("".equals(alias)) {
                              colName = column.getColumnName();
                           } else {
                              alias = alias.replaceAll("[`\"]", "");
                              colName = alias + "." + column.getColumnName();
                           }

                           Column col = new Column();
                           col.setSchema(column.getSchema());
                           col.setTable(column.getTable());
                           col.setColumnName(colName);
                           col.setDataType(column.getDataType());
                           result.add(col);
                        }
                     }
                  }
               }
            }

            return result;
         }
      }
   }

   private static void normalizeColumn(String alias, List<Column> result, Schema schema, Table table) {
      for(Column column : table.getColumnList()) {
         String colName = "";
         if ("".equals(alias)) {
            colName = column.getColumnName();
         } else {
            colName = alias + "." + column.getColumnName();
         }

         Column col = new Column();
         col.setSchema(schema.getName());
         col.setTable(table.getName());
         col.setColumnName(colName);
         col.setDataType(column.getDataType());
         result.add(col);
      }

   }

   public static List<Column> getTableColumnsNormal(String ip_port, String schemaName, String tableName, String alias, HashMap<String, List<Column>> tableList) throws SQLException {
      List<Column> result = (List)tableList.get(tableName);
      if (result != null) {
         return result;
      } else {
         tableName = tableName.replaceAll("[`\"]", "");
         result = new ArrayList();

         for(DataBase dataBase : dataBaseList) {
            if (dataBase.getIp_port().equalsIgnoreCase(ip_port.trim())) {
               if (!"mysql".equals(dataBase.getDbType()) && !"KUNDB".equals(dataBase.getDbType()) && !"kundb".equals(dataBase.getDbType()) && !"kingbase".equals(dataBase.getDbType()) && !"dm".equals(dataBase.getDbType()) && !"db2".equals(dataBase.getDbType()) && !"oracle".equals(dataBase.getDbType()) && !"sqlserver".equals(dataBase.getDbType()) && !"sql server".equals(dataBase.getDbType()) && !"mssqlserver".equals(dataBase.getDbType()) && !"spark".equals(dataBase.getDbType()) && !"hive_tdh".equals(dataBase.getDbType()) && !"HIVE_TDH".equals(dataBase.getDbType()) && !"sparksql".equals(dataBase.getDbType())) {
                  if (!dataBase.isRedis()) {
                     for(Schema schema : dataBase.getSchemaList()) {
                        if (schema.getName().equalsIgnoreCase(schemaName)) {
                           for(Table table : schema.getTableList()) {
                              if (table.getName().equalsIgnoreCase(tableName)) {
                                 normalizeColumn(alias, result, table);
                              }
                           }
                        }
                     }
                  } else {
                     NameWrapper nameWrapper2 = NameWrapper.create(DbType.of(dataBase.getDbType()), dataBase.simpleCache);
                     Schema schemaFromRedis = nameWrapper2.getSchemaFromRedis(schemaName, false);
                     Table tableFromRedis = nameWrapper2.getTableFromRedis(schemaFromRedis, tableName, false);
                     normalizeColumn(alias, result, schemaFromRedis, tableFromRedis);
                  }
               } else {
                  NameWrapper nameWrapper = NameWrapper.create(DbType.of(dataBase.getDbType()), dataBase.simpleCache);
                  Table item = nameWrapper.getTable(schemaName, tableName);
                  if (item != null && item.getColumnList() != null) {
                     for(Column column : item.getColumnList()) {
                        String colName = "";
                        if ("".equals(alias)) {
                           colName = column.getColumnName();
                        } else {
                           colName = alias + "." + column.getColumnName();
                        }

                        Column col = new Column();
                        col.setColumnName(colName);
                        result.add(col);
                     }
                  }
               }
            }
         }

         return result;
      }
   }

   private static void normalizeColumn(String alias, List<Column> result, Table table) {
      for(Column column : table.getColumnList()) {
         String colName = "";
         if ("".equals(alias)) {
            colName = column.getColumnName();
         } else {
            colName = alias + "." + column.getColumnName();
         }

         Column col = new Column();
         col.setColumnName(colName);
         result.add(col);
      }

   }

   public static Map<String, String> getTables(String ip_port, String schemaName, String tableName) throws SQLException {
      Map<String, String> result = new HashMap();
      tableName = tableName.replaceAll("[`\"]", "");
      result.put("table_type", "TABLE");
      result.put("table_name", tableName);

      for(DataBase dataBase : dataBaseList) {
         if (dataBase.getIp_port().equalsIgnoreCase(ip_port)) {
            if (!dataBase.isRedis()) {
               if (dataBase.getSchemaList() != null) {
                  for(Schema schema : dataBase.getSchemaList()) {
                     if (schema.getName().equalsIgnoreCase(schemaName)) {
                        List<Synonym> synonymList = schema.getSynonymList();
                        if (synonymList != null) {
                           for(Synonym synonym : synonymList) {
                              if (synonym.getName().equalsIgnoreCase(tableName)) {
                                 result.put("table_type", "SYNONYM");
                                 result.put("table_name", synonym.getTableName());
                                 tableName = synonym.getTableName();
                              }
                           }
                        }

                        if (schema.getViewList() != null) {
                           for(View view : schema.getViewList()) {
                              if (view.getName().equalsIgnoreCase(tableName)) {
                                 result.put("table_type", "VIEW");
                                 result.put("create_view", view.getCreate_sql());
                                 return result;
                              }
                           }
                        }
                     }
                  }
               }
            } else {
               NameWrapper nameWrapper = NameWrapper.create(DbType.of(dataBase.getDbType()), dataBase.simpleCache);
               View view = nameWrapper.getView(schemaName, tableName, false);
               if (view != null) {
                  result.put("table_type", "VIEW");
                  result.put("create_view", view.getCreate_sql());
                  return result;
               }
            }
         }
      }

      return result;
   }

   public static SQLSelectQueryBlock mysqlJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      try {
         SQLLogger.log((String)params.get("sql"));
         SQLTableSource from = query.getFrom();
         MySqlParse MySqlParse = new MySqlParse(params);
         Map<String, String> tableMap = MySqlParse.parseFrom(from, (Map)null, "", true);

         for(String key : tableMap.keySet()) {
            String tableName = (String)tableMap.get(key);
            List<Column> result = (List)tableList.get(tableName);
            if (result == null) {
               Map var11 = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            }
         }

         return query;
      } catch (Exception e) {
         SQLLogger.log((String)params.get("sql"), e.toString());
         throw new SQLException(e);
      }
   }

   public static SQLSelectQueryBlock doPareAndRepalce(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList, Map<String, String> replaceMap) throws SQLException {
      try {
         SQLTableSource from = query.getFrom();
         Map<String, String> tableMap = null;
         String dbType = (String)params.get("dbType");
         if ("postgresql".equals(dbType)) {
            PostgreSqlParse postgreSqlParse = new PostgreSqlParse(params);
            tableMap = postgreSqlParse.parseFromAndReplace(from, (Map)null, "", replaceMap);
         } else if ("mysql".equals(dbType)) {
            MySqlParse mySqlParse = new MySqlParse(params);
            tableMap = mySqlParse.parseFromAndReplace(from, (Map)null, "", replaceMap);
         } else if ("dm".equals(dbType)) {
            DmParse dmSqlParse = new DmParse(params);
            tableMap = dmSqlParse.parseFromAndReplace(from, (Map)null, "", replaceMap);
         }

         for(String key : tableMap.keySet()) {
            String tableName = (String)tableMap.get(key);
            List<Column> result = (List)tableList.get(tableName);
            if (result == null) {
               Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
               if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
                  String alias = from.getAlias();
                  String view_sql = (String)tables.get("create_view");
                  SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
                  query.setFrom(stmt.getSelect(), alias == null ? tableName : alias);
               }
            }
         }

         return query;
      } catch (SQLException e) {
         SQLLogger.log((String)params.get("sql"), e.toString());
         throw e;
      }
   }

   public static SQLSelectQueryBlock db2JudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      DB2Parse db2Parse = new DB2Parse(params);
      Map<String, String> tableMap = db2Parse.parseFrom(from, (Map)null);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String alias = from.getAlias();
               String view_sql = (String)tables.get("create_view");
               SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               query.setFrom(stmt.getSelect(), alias == null ? tableName : alias);
            }
         }
      }

      return query;
   }

   public static SQLSelectQueryBlock sqlServerJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      DB2Parse db2Parse = new DB2Parse(params);
      Map<String, String> tableMap = db2Parse.parseFrom(from, (Map)null);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2].split(";")[0], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String alias = from.getAlias();
               String view_sql = (String)tables.get("create_view");
               SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               query.setFrom(stmt.getSelect(), alias == null ? tableName : alias);
            }
         }
      }

      return query;
   }

   public static SQLSelectQueryBlock kingBaseJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      KingBaseParse kingBaseParse = new KingBaseParse(params);
      Map<String, String> tableMap = kingBaseParse.parseFrom(from, (Map)null);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null && !"".equals(params.get("url"))) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String alias = from.getAlias();
               String view_sql = (String)tables.get("create_view");
               SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               query.setFrom(stmt.getSelect(), alias == null ? tableName : alias);
            }
         }
      }

      return query;
   }

   public static OracleSelectQueryBlock oracleJudgeViewAndModify(OracleSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      OracleParse oracleParse = new OracleParse(params);
      Map<String, String> tableMap = oracleParse.parseFrom(from, (Map)null, "", true);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            String[] split = ((String)params.get("url")).split("@")[1].split(":");
            Map<String, String> tables = getTables(split[0] + ":" + split[1], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String view_sql = (String)tables.get("create_view");
               SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               query.setFrom(stmt.getSelect(), tableName);
            } else if ("SYNONYM".equalsIgnoreCase((String)tables.get("table_type"))) {
               String table_name = (String)tables.get("table_name");
               query.setFrom(table_name);
            }
         }
      }

      return query;
   }

   public static SQLSelectQueryBlock postgreJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      PostgreSqlParse postgreSqlParse = new PostgreSqlParse(params);
      Map<String, String> tableMap = postgreSqlParse.parseFrom(from, (Map)null, "", true);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String view_sql = (String)tables.get("create_view");
               SQLStatement statement = (SQLStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               if (statement instanceof PGSelectStatement) {
                  PGSelectStatement stmt = (PGSelectStatement)statement;
                  query.setFrom(stmt.getSelect(), tableName);
               } else if (statement instanceof SQLSelectStatement) {
                  SQLSelectStatement stmt = (SQLSelectStatement)statement;
                  query.setFrom(stmt.getSelect(), tableName);
               }
            }
         }
      }

      return query;
   }

   public static SQLSelectQueryBlock hiveJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      HiveParse hiveParse = new HiveParse(params);
      Map<String, String> tableMap = hiveParse.parseFrom(from, (Map)null);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String view_sql = (String)tables.get("create_view");
               SQLStatement stmt = (SQLStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               if (stmt instanceof SQLCreateViewStatement) {
                  SQLCreateViewStatement vst = (SQLCreateViewStatement)stmt;
                  SQLSelect select = vst.getSubQuery();
                  query.setFrom(select, tableName);
               } else if (stmt instanceof SQLSelectStatement) {
                  SQLSelectStatement selectStatement = (SQLSelectStatement)stmt;
                  SQLSelect select = selectStatement.getSelect();
                  query.setFrom(select, tableName);
               }
            }
         }
      }

      return query;
   }

   public static SQLSelectQueryBlock dmJudgeViewAndModify(SQLSelectQueryBlock query, Map<String, String> params, HashMap<String, List<Column>> tableList) throws SQLException {
      SQLTableSource from = query.getFrom();
      DmParse dmParse = new DmParse(params);
      Map<String, String> tableMap = dmParse.parseFrom(from, (Map)null, "", false);

      for(String key : tableMap.keySet()) {
         String tableName = (String)tableMap.get(key);
         List<Column> result = (List)tableList.get(tableName);
         if (result == null) {
            Map<String, String> tables = getTables(((String)params.get("url")).split("/")[2], (String)params.get("schema"), tableName);
            if ("VIEW".equalsIgnoreCase((String)tables.get("table_type"))) {
               String view_sql = (String)tables.get("create_view");
               SQLSelectStatement stmt = (SQLSelectStatement)SQLUtils.parseStatements(view_sql, (String)params.get("dbType")).get(0);
               query.setFrom(stmt.getSelect(), tableName);
            } else if ("SYNONYM".equalsIgnoreCase((String)tables.get("table_type"))) {
               String table_name = (String)tables.get("table_name");
               query.setFrom(table_name, table_name);
            }
         }
      }

      return query;
   }

   public static String getSqlType(String sql, String dbType) {
      SQLLogger.log(sql);
      SQLStatement statement = null;

      try {
         if (StringJoin.isEmpty(dbType)) {
            dbType = "mysql";
         }

         List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
         SQLStatement sqlStatement = (SQLStatement)stmtList.get(0);
         if (sqlStatement instanceof SQLSelectStatement) {
            if (((SQLSelectStatement)sqlStatement).getSelect().getQuery() instanceof SQLUnionQuery) {
               return "union";
            }

            return "select";
         }

         if (sqlStatement instanceof SQLShowStatement) {
            return "show";
         }

         statement = sqlStatement;
      } catch (Exception e) {
         e.printStackTrace();
         SQLLogger.log(sql, e.toString());
      }

      sql = sql.trim();
      String sqlType = "";
      if (followRules_like(sql, "(?i)^(insert)(\\s+?)(into)(\\s+?)(select)(.*)(from)")) {
         sqlType = "insert_select";
      } else if (followRules_like(sql, "(?i)^(insert)(\\s+?)(into)(.*)")) {
         sqlType = "insert";
      } else if (followRules_like(sql, "(?i)^(update)(.*)(set)")) {
         sqlType = "update";
      } else if (followRules_like(sql, "(?i)^(replace)(.*)(into)")) {
         sqlType = "replace";
      } else if (followRules_like(sql, "(?i)^(delete)(\\s+?)(from)(.*)")) {
         sqlType = "delete";
      } else if (followRules_like(sql, "(?i)^(truncate)(\\s+?)(table)?")) {
         sqlType = "truncate";
      } else if (followRules_like(sql, "(?i)^(create)(\\s+?)(table|view)")) {
         sqlType = "create";
      } else if (followRules_like(sql, "(?i)^(alter)(\\s+?)(table)")) {
         sqlType = "alter";
      } else if (followRules_like(sql, "(?i)^(drop)(\\s+?)(table|view)")) {
         sqlType = "drop";
      } else if (followRules_like(sql, "(?i)^(grant)(.*)(to)")) {
         sqlType = "grant";
      } else if (followRules_like(sql, "(?i)^(revoke)(.*)(on)(.*)(from)")) {
         sqlType = "revoke";
      } else if (followRules_like(sql, "(?i)(\\s+)(union|union all|INTERSECT|MINUS)(\\s+)")) {
         sqlType = "union";
      } else if (followRules_like(sql, "(?i)^(with)(.*?)(as)(.*)(select)")) {
         sqlType = "with_select";
      } else if (followRules_like(sql, "(?i)^(select)(.*?)(from)")) {
         sqlType = "select";
      } else if (followRules_like(sql, "(?i)^(merge)(\\s+?)(into)(.*)")) {
         sqlType = "merge";
      } else if (followRules_like(sql, "(?i)^(alter)(\\s+?)(schema)(.*)")) {
         sqlType = "alter schema";
      } else if (statement != null) {
         if (!(statement instanceof SQLInsertStatement) && !(statement instanceof OracleMultiInsertStatement)) {
            if (statement instanceof SQLUpdateStatement) {
               sqlType = "update";
            } else if (statement instanceof SQLDeleteStatement) {
               sqlType = "delete";
            } else if (statement instanceof GaussAlterSessionStatement) {
               sqlType = "alter_session";
            } else if (statement instanceof GaussAlterSystemKillSessionStatement) {
               sqlType = "alter_system_kill_session";
            } else if (!(statement instanceof GPCreateTableStatement) && !(statement instanceof GPCreateViewStatement)) {
               if (statement instanceof GPDropSchemaStatement) {
                  sqlType = "drop schema";
               } else if (statement instanceof GPAlterSchemaStatement) {
                  sqlType = "alter schema";
               } else if (statement instanceof GPAlterViewStatement) {
                  sqlType = "alter view";
               }
            } else {
               sqlType = "create";
            }
         } else {
            sqlType = "insert";
         }
      }

      return sqlType;
   }

   public static boolean followRules(String sql, String reg) {
      reg = "^" + reg + "$";
      Pattern compile = Pattern.compile(reg, 34);
      Matcher matcher = compile.matcher(sql);
      return matcher.find();
   }

   public static boolean followRulesCaseSens(String sql, String reg) {
      reg = "^" + reg + "$";
      Pattern compile = Pattern.compile(reg, 32);
      Matcher matcher = compile.matcher(sql);
      return matcher.find();
   }

   public static boolean followRules_like(String sql, String reg) {
      Pattern compile = Pattern.compile(reg, 34);
      Matcher matcher = compile.matcher(sql);
      return matcher.find();
   }

   public static boolean sqlRegex(String sql, String reg) {
      if (sql == null) {
         return false;
      } else if (reg.equals("*")) {
         return sql.indexOf("*") != -1;
      } else {
         Pattern compile = Pattern.compile(reg, 34);
         Matcher matcher = compile.matcher(sql);
         return matcher.find();
      }
   }

   public static String sqlSplit(String sql) {
      String result = "";
      String reg = "(\\()(.*)(\\))";
      Pattern compile = Pattern.compile(reg, 34);
      Matcher matcher = compile.matcher(sql);
      if (matcher.find()) {
         result = matcher.group(2).trim();
      }

      return result;
   }

   public static String getWithTableName(String sql) {
      String result = "";
      String reg = "(?i)(with)(\\s+RECURSIVE\\s+)?(.*)(as)";
      Pattern compile = Pattern.compile(reg, 34);
      Matcher matcher = compile.matcher(sql);
      if (matcher.find()) {
         result = matcher.group(3).trim();
      }

      return result;
   }

   public static String getColumnDataType(String ip_port, String schema_real, String tableName, String alias, String columnName) {
      try {
          List<Column> tableColumns = getTableColumns(ip_port, schema_real, tableName, alias, new HashMap());
          for(Column tableColumn : tableColumns) {
            if (tableColumn.getColumnName().equalsIgnoreCase(alias + "." + columnName)) {
               return tableColumn.getDataType();
            }
         }
      } catch (SQLException throwables) {
         throwables.printStackTrace();
      }

      return null;
   }

   public static void main(String[] args) throws ClassNotFoundException {
      String url = "jdbc:db2://192.168.2.127:50000/test:currentSchema=RY;";
      getDB2Connection(url, "fooxr", "admin");
   }

   static {
      dataBaseList = JdbcCacheUtil.dataBaseList;
      init = false;
   }
}
