Liquibase兼容达梦V8记录

1、公司内部目录层级结构,参照liquibase源码目录结构创建

DmDatabase是之前兼容V7版本,当前弃用
DmDatabase是之前兼容V7版本,当前弃用,最新版本是V8

DM8Database
package liquibase.database.core;

import liquibase.CatalogAndSchema;
import liquibase.database.AbstractJdbcDatabase;
import liquibase.database.DatabaseConnection;
import liquibase.database.OfflineConnection;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.DatabaseException;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.exception.ValidationErrors;
import liquibase.executor.ExecutorService;
import liquibase.logging.LogFactory;
import liquibase.statement.DatabaseFunction;
import liquibase.statement.SequenceCurrentValueFunction;
import liquibase.statement.SequenceNextValueFunction;
import liquibase.statement.UniqueConstraint;
import liquibase.statement.core.RawCallStatement;
import liquibase.statement.core.RawSqlStatement;
import liquibase.structure.DatabaseObject;
import liquibase.structure.core.Catalog;
import liquibase.structure.core.Index;
import liquibase.structure.core.PrimaryKey;
import liquibase.structure.core.Schema;
import liquibase.util.JdbcUtils;
import liquibase.util.StringUtils;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DM8Database extends AbstractJdbcDatabase {
    public static final String PRODUCT_NAME = "DM DBMS";
    private Set<String> reservedWords = new HashSet();
    private Set<String> userDefinedTypes = null;
    private Boolean canAccessDbaRecycleBin;
    private Integer databaseMajorVersion;

    public DM8Database() {
        super.unquotedObjectsAreUppercased = true;
        super.setCurrentDateTimeFunction("SYSTIMESTAMP");
        this.dateFunctions.add(new DatabaseFunction("SYSDATE"));
        this.dateFunctions.add(new DatabaseFunction("SYSTIMESTAMP"));
        this.dateFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP"));
        super.sequenceNextValueFunction = "%s.nextval";
        super.sequenceCurrentValueFunction = "%s.currval";
    }

    public int getPriority() {
        return 5;
    }

    public void setConnection(DatabaseConnection conn) {
        this.reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER"));
        Connection sqlConn = null;
        if (!(conn instanceof OfflineConnection)) {
            Method method;
            try {
                if (conn instanceof JdbcConnection) {
                    method = conn.getClass().getMethod("getWrappedConnection");
                    method.setAccessible(true);
                    sqlConn = (Connection)method.invoke(conn);
                }
            } catch (Exception var17) {
                throw new UnexpectedLiquibaseException(var17);
            }

            if (sqlConn != null) {
                try {
                    this.reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
                } catch (SQLException var16) {
                    LogFactory.getLogger().info("Could get sql keywords on OracleDatabase: " + var16.getMessage());
                }

                try {
                    method = sqlConn.getClass().getMethod("setRemarksReporting", Boolean.TYPE);
                    method.setAccessible(true);
                    method.invoke(sqlConn, true);
                } catch (Exception var15) {
                    LogFactory.getLogger().info("Could not set remarks reporting on OracleDatabase: " + var15.getMessage());
                }

                Statement statement = null;
                ResultSet resultSet = null;

                try {
                    statement = sqlConn.createStatement();
                    resultSet = statement.executeQuery("SELECT value FROM v$parameter WHERE name = 'compatible'");
                    String compatibleVersion = null;
                    if (resultSet.next()) {
                        compatibleVersion = resultSet.getString("value");
                    }

                    if (compatibleVersion != null) {
                        Matcher majorVersionMatcher = Pattern.compile("(\\d+)\\..*").matcher(compatibleVersion);
                        if (majorVersionMatcher.matches()) {
                            this.databaseMajorVersion = Integer.valueOf(majorVersionMatcher.group(1));
                        }
                    }
                } catch (SQLException var13) {
                    String message = "Cannot read from v$parameter: " + var13.getMessage();
                    LogFactory.getLogger().info("Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: " + message);
                } finally {
                    JdbcUtils.close(resultSet, statement);
                }
            }
        }

        super.setConnection(conn);
    }

    public String getShortName() {
        return "DM DBMS";
    }

    protected String getDefaultDatabaseProductName() {
        return PRODUCT_NAME;
    }

    public int getDatabaseMajorVersion() throws DatabaseException {
        return this.databaseMajorVersion == null ? super.getDatabaseMajorVersion() : this.databaseMajorVersion;
    }

    public Integer getDefaultPort() {
        return 5236;
    }

    public String getJdbcCatalogName(CatalogAndSchema schema) {
        return null;
    }

    public String getJdbcSchemaName(CatalogAndSchema schema) {
        return this.correctObjectName(schema.getCatalogName() == null ? schema.getSchemaName() : schema.getCatalogName(), Schema.class);
    }

    public String generatePrimaryKeyName(String tableName) {
        return tableName.length() > 27 ? "PK_" + tableName.toUpperCase().substring(0, 27) : "PK_" + tableName.toUpperCase();
    }

    public boolean supportsInitiallyDeferrableColumns() {
        return true;
    }

    public boolean isReservedWord(String objectName) {
        return this.reservedWords.contains(objectName.toUpperCase());
    }

    public boolean supportsSequences() {
        return true;
    }

    public boolean supportsSchemas() {
        return false;
    }

    protected String getConnectionCatalogName() throws DatabaseException {
        if (this.getConnection() instanceof OfflineConnection) {
            return this.getConnection().getCatalog();
        } else {
            try {
                return (String) ExecutorService.getInstance().getExecutor(this).queryForObject(new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"), String.class);
            } catch (Exception var2) {
                LogFactory.getLogger().info("Error getting default schema", var2);
                return null;
            }
        }
    }

    public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
        return PRODUCT_NAME.equalsIgnoreCase(conn.getDatabaseProductName());
    }

    public String getDefaultDriver(String url) {
        return url.startsWith("jdbc:dm") ? "dm.jdbc.driver.DmDriver" : null;
    }

    public String getDefaultCatalogName() {
        return super.getDefaultCatalogName() == null ? null : super.getDefaultCatalogName().toUpperCase();
    }

    public String getDateLiteral(String isoDate) {
        String normalLiteral = super.getDateLiteral(isoDate);
        StringBuffer val;
        if (this.isDateOnly(isoDate)) {
            val = new StringBuffer();
            val.append("to_date(");
            val.append(normalLiteral);
            val.append(", 'YYYY-MM-DD')");
            return val.toString();
        } else if (this.isTimeOnly(isoDate)) {
            val = new StringBuffer();
            val.append("to_date(");
            val.append(normalLiteral);
            val.append(", 'HH24:MI:SS')");
            return val.toString();
        } else if (this.isTimestamp(isoDate)) {
            val = new StringBuffer(26);
            val.append("to_timestamp(");
            val.append(normalLiteral);
            val.append(", 'YYYY-MM-DD HH24:MI:SS.FF')");
            return val.toString();
        } else if (this.isDateTime(isoDate)) {
            normalLiteral = normalLiteral.substring(0, normalLiteral.lastIndexOf(46)) + "'";
            val = new StringBuffer(26);
            val.append("to_date(");
            val.append(normalLiteral);
            val.append(", 'YYYY-MM-DD HH24:MI:SS')");
            return val.toString();
        } else {
            return "UNSUPPORTED:" + isoDate;
        }
    }

    public boolean isSystemObject(DatabaseObject example) {
        if (example == null) {
            return false;
        } else if (this.isLiquibaseObject(example)) {
            return false;
        } else {
            if (example instanceof Schema) {
                if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) {
                    return true;
                }

                if ("SYSTEM".equals(example.getSchema().getCatalogName()) || "SYS".equals(example.getSchema().getCatalogName()) || "CTXSYS".equals(example.getSchema().getCatalogName()) || "XDB".equals(example.getSchema().getCatalogName())) {
                    return true;
                }
            } else if (this.isSystemObject(example.getSchema())) {
                return true;
            }

            if (example instanceof Catalog) {
                if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) {
                    return true;
                }
            } else if (example.getName() != null) {
                if (example.getName().startsWith("BIN$")) {
                    boolean filteredInOriginalQuery = this.canAccessDbaRecycleBin();
                    if (!filteredInOriginalQuery) {
                        filteredInOriginalQuery = StringUtils.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName());
                    }

                    if (filteredInOriginalQuery) {
                        if (!(example instanceof PrimaryKey) && !(example instanceof Index) && !(example instanceof UniqueConstraint)) {
                            return true;
                        }

                        return false;
                    }

                    return true;
                }

                if (example.getName().startsWith("AQ$")) {
                    return true;
                }

                if (example.getName().startsWith("DR$")) {
                    return true;
                }

                if (example.getName().startsWith("SYS_IOT_OVER")) {
                    return true;
                }

                if ((example.getName().startsWith("MDRT_") || example.getName().startsWith("MDRS_")) && example.getName().endsWith("$")) {
                    return true;
                }

                if (example.getName().startsWith("MLOG$_")) {
                    return true;
                }

                if (example.getName().startsWith("RUPD$_")) {
                    return true;
                }

                if (example.getName().startsWith("WM$_")) {
                    return true;
                }

                if (example.getName().equals("CREATE$JAVA$LOB$TABLE")) {
                    return true;
                }

                if (example.getName().equals("JAVA$CLASS$MD5$TABLE")) {
                    return true;
                }

                if (example.getName().startsWith("ISEQ$$_")) {
                    return true;
                }
            }

            return super.isSystemObject(example);
        }
    }

    public boolean supportsTablespaces() {
        return true;
    }

    public boolean supportsAutoIncrement() {
        boolean isAutoIncrementSupported = false;

        try {
            if (this.getDatabaseMajorVersion() >= 12) {
                isAutoIncrementSupported = true;
            }
        } catch (DatabaseException var3) {
            isAutoIncrementSupported = false;
        }

        return isAutoIncrementSupported;
    }

    public boolean supportsRestrictForeignKeys() {
        return false;
    }

    public int getDataTypeMaxParameters(String dataTypeName) {
        if (dataTypeName.toUpperCase().equals("BINARY_FLOAT")) {
            return 0;
        } else {
            return dataTypeName.toUpperCase().equals("BINARY_DOUBLE") ? 0 : super.getDataTypeMaxParameters(dataTypeName);
        }
    }

    public boolean jdbcCallsCatalogsSchemas() {
        return true;
    }

    public Set<String> getUserDefinedTypes() {
        if (this.userDefinedTypes == null) {
            this.userDefinedTypes = new HashSet();
            if (this.getConnection() != null && !(this.getConnection() instanceof OfflineConnection)) {
                try {
                    this.userDefinedTypes.addAll(ExecutorService.getInstance().getExecutor(this).queryForList(new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class));
                } catch (DatabaseException var2) {
                }
            }
        }

        return this.userDefinedTypes;
    }

    public String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) {
        if (databaseFunction != null && databaseFunction.toString().equalsIgnoreCase("current_timestamp")) {
            return databaseFunction.toString();
        } else if (!(databaseFunction instanceof SequenceNextValueFunction) && !(databaseFunction instanceof SequenceCurrentValueFunction)) {
            return super.generateDatabaseFunctionValue(databaseFunction);
        } else {
            String quotedSeq = super.generateDatabaseFunctionValue(databaseFunction);
            return quotedSeq.replaceFirst("\"([^\\.\"]*)\\.([^\\.\"]*)\"", "\"$1\".\"$2\"");
        }
    }

    public ValidationErrors validate() {
        ValidationErrors errors = super.validate();
        DatabaseConnection connection = this.getConnection();
        if (connection != null && !(connection instanceof OfflineConnection)) {
            if (!this.canAccessDbaRecycleBin()) {
                errors.addWarning(this.getDbaRecycleBinWarning());
            }

            return errors;
        } else {
            LogFactory.getInstance().getLog().info("Cannot validate offline database");
            return errors;
        }
    }

    public String getDbaRecycleBinWarning() {
        return "Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where constraints are deleted and restored. Since Oracle doesn't properly restore the original table names referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this issue.\n\nThe user you used to connect to the database (" + this.getConnection().getConnectionUserName() + ") needs to have \"SELECT ON SYS.DBA_RECYCLEBIN\" permissions set before we can perform this operation. Please run the following SQL to set the appropriate permissions, and try running the command again.\n" + "\n" + "     GRANT SELECT ON SYS.DBA_RECYCLEBIN TO " + this.getConnection().getConnectionUserName() + ";";
    }

    public boolean canAccessDbaRecycleBin() {
        if (this.canAccessDbaRecycleBin == null) {
            DatabaseConnection connection = this.getConnection();
            if (connection == null || connection instanceof OfflineConnection) {
                return false;
            }

            Statement statement = null;

            try {
                statement = ((JdbcConnection)connection).createStatement();
                ResultSet resultSet = statement.executeQuery("select 1 from dba_recyclebin where 0=1");
                resultSet.close();
                this.canAccessDbaRecycleBin = true;
            } catch (Exception var7) {
                if (var7 instanceof SQLException && var7.getMessage().startsWith("ORA-00942")) {
                    this.canAccessDbaRecycleBin = false;
                } else {
                    LogFactory.getInstance().getLog().warning("Cannot check dba_recyclebin access", var7);
                    this.canAccessDbaRecycleBin = false;
                }
            } finally {
                JdbcUtils.close((ResultSet)null, statement);
            }
        }

        return this.canAccessDbaRecycleBin;
    }
JdbcDatabaseSnapshot 关于查询/创建的一些处理
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package liquibase.snapshot;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import liquibase.CatalogAndSchema;
import liquibase.database.AbstractJdbcDatabase;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.core.AbstractDb2Database;
import liquibase.database.core.DB2Database;
import liquibase.database.core.DM8Database;
import liquibase.database.core.Db2zDatabase;
import liquibase.database.core.DerbyDatabase;
import liquibase.database.core.FirebirdDatabase;
import liquibase.database.core.HsqlDatabase;
import liquibase.database.core.InformixDatabase;
import liquibase.database.core.Ingres9Database;
import liquibase.database.core.MSSQLDatabase;
import liquibase.database.core.MariaDBDatabase;
import liquibase.database.core.MySQLDatabase;
import liquibase.database.core.OracleDatabase;
import liquibase.database.core.PostgresDatabase;
import liquibase.database.core.SybaseASADatabase;
import liquibase.database.core.SybaseDatabase;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.DatabaseException;
import liquibase.executor.jvm.ColumnMapRowMapper;
import liquibase.executor.jvm.RowMapperNotNullConstraintsResultSetExtractor;
import liquibase.logging.LogService;
import liquibase.logging.LogType;
import liquibase.structure.DatabaseObject;
import liquibase.structure.core.Catalog;
import liquibase.structure.core.Schema;
import liquibase.structure.core.Table;
import liquibase.structure.core.View;
import liquibase.util.JdbcUtils;
import liquibase.util.StringUtils;

public class JdbcDatabaseSnapshot extends DatabaseSnapshot {
    private boolean warnedAboutDbaRecycleBin;
    private static final boolean ignoreWarnAboutDbaRecycleBin = Boolean.getBoolean("liquibase.ignoreRecycleBinWarning");
    private CachingDatabaseMetaData cachingDatabaseMetaData;
    private Set<String> userDefinedTypes;

    public JdbcDatabaseSnapshot(DatabaseObject[] examples, Database database, SnapshotControl snapshotControl) throws DatabaseException, InvalidExampleException {
        super(examples, database, snapshotControl);
    }

    public JdbcDatabaseSnapshot(DatabaseObject[] examples, Database database) throws DatabaseException, InvalidExampleException {
        super(examples, database);
    }

    public CachingDatabaseMetaData getMetaDataFromCache() throws SQLException {
        if (this.cachingDatabaseMetaData == null) {
            DatabaseMetaData databaseMetaData = null;
            if (this.getDatabase().getConnection() != null) {
                databaseMetaData = ((JdbcConnection)this.getDatabase().getConnection()).getUnderlyingConnection().getMetaData();
            }

            this.cachingDatabaseMetaData = new CachingDatabaseMetaData(this.getDatabase(), databaseMetaData);
        }

        return this.cachingDatabaseMetaData;
    }

    private String getAllCatalogsStringScratchData() {
        return (String)this.getScratchData("DatabaseSnapshot.allCatalogsString");
    }

    public class CachingDatabaseMetaData {
        private static final String ASANY_NO_FOREIGN_KEYS_FOUND_SQLSTATE = "WW012";
        private static final String SQL_FILTER_MATCH_ALL = "%";
        private DatabaseMetaData databaseMetaData;
        private Database database;

        public CachingDatabaseMetaData(Database database, DatabaseMetaData metaData) {
            this.databaseMetaData = metaData;
            this.database = database;
        }

        public DatabaseMetaData getDatabaseMetaData() {
            return this.databaseMetaData;
        }

        public List<CachedRow> getForeignKeys(String catalogName, String schemaName, String tableName, String fkName) throws DatabaseException {
            ForeignKeysResultSetCache foreignKeysResultSetCache = new ForeignKeysResultSetCache(this.database, catalogName, schemaName, tableName, fkName);
            ResultSetCache importedKeys = JdbcDatabaseSnapshot.this.getResultSetCache("getImportedKeys");
            importedKeys.setBulkTracking(!(this.database instanceof MSSQLDatabase));
            return importedKeys.get(foreignKeysResultSetCache);
        }

        public List<CachedRow> getIndexInfo(final String catalogName, final String schemaName, final String tableName, final String indexName) throws DatabaseException, SQLException {
            List<CachedRow> indexes = JdbcDatabaseSnapshot.this.getResultSetCache("getIndexInfo").get(new ResultSetCache.UnionResultSetExtractor(this.database) {
                public boolean isBulkFetchMode;

                public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                    return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME"), row.getString("INDEX_NAME")});
                }

                public ResultSetCache.RowData wantedKeyParameters() {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{tableName, indexName});
                }

                public boolean bulkContainsSchema(String schemaKey) {
                    return JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null && CachingDatabaseMetaData.this.database instanceof OracleDatabase;
                }

                public String getSchemaKey(CachedRow row) {
                    return row.getString("TABLE_SCHEM");
                }

                public List<CachedRow> fastFetch() throws SQLException, DatabaseException {
                    List<CachedRow> returnList = new ArrayList();
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                    String sql;
                    if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                        CachingDatabaseMetaData.this.warnAboutDbaRecycleBin();
                        sql = "SELECT c.INDEX_NAME, 3 AS TYPE, c.TABLE_OWNER AS TABLE_SCHEM, c.TABLE_NAME, c.COLUMN_NAME, c.COLUMN_POSITION AS ORDINAL_POSITION, e.COLUMN_EXPRESSION AS FILTER_CONDITION, CASE I.UNIQUENESS WHEN 'UNIQUE' THEN 0 ELSE 1 END AS NON_UNIQUE, CASE c.DESCEND WHEN 'Y' THEN 'D' WHEN 'DESC' THEN 'D' WHEN 'N' THEN 'A' WHEN 'ASC' THEN 'A' END AS ASC_OR_DESC, CASE WHEN tablespace_name = (SELECT default_tablespace FROM user_users) THEN NULL ELSE tablespace_name END AS tablespace_name  FROM ALL_IND_COLUMNS c JOIN ALL_INDEXES i ON i.owner=c.index_owner AND i.index_name = c.index_name and i.table_owner = c.table_owner LEFT OUTER JOIN all_ind_expressions e ON e.index_owner=c.index_owner AND e.index_name = c.index_name AND e.column_position = c.column_position   LEFT OUTER JOIN " + (((OracleDatabase)CachingDatabaseMetaData.this.database).canAccessDbaRecycleBin() ? "dba_recyclebin" : "user_recyclebin") + " d ON d.object_name=c.table_name ";
                        if (this.isBulkFetchMode && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                            sql = sql + "WHERE c.TABLE_OWNER IN ('" + CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class) + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                        } else {
                            sql = sql + "WHERE c.TABLE_OWNER = '" + CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class) + "' ";
                        }

                        sql = sql + "AND i.OWNER = c.TABLE_OWNER AND d.object_name IS NULL ";
                        if (!this.isBulkFetchMode && tableName != null) {
                            sql = sql + " AND c.TABLE_NAME='" + tableName + "'";
                        }

                        if (!this.isBulkFetchMode && indexName != null) {
                            sql = sql + " AND c.INDEX_NAME='" + indexName + "'";
                        }

                        sql = sql + " ORDER BY c.INDEX_NAME, ORDINAL_POSITION";
                        returnList.addAll(this.executeAndExtract(sql, CachingDatabaseMetaData.this.database));
                    } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                        sql = "original_db_name()";
                        if (9 <= CachingDatabaseMetaData.this.database.getDatabaseMajorVersion()) {
                            sql = "db_name()";
                        }

                        String sqlx = "SELECT " + sql + " as TABLE_CAT, object_schema_name(i.object_id) as TABLE_SCHEM, object_name(i.object_id) as TABLE_NAME, CASE is_unique WHEN 1 then 0 else 1 end as NON_UNIQUE, object_name(i.object_id) as INDEX_QUALIFIER, i.name as INDEX_NAME, case i.type when 1 then 1 ELSE 3 end as TYPE, key_ordinal as ORDINAL_POSITION, COL_NAME(c.object_id,c.column_id) AS COLUMN_NAME, case is_descending_key when 0 then 'A' else 'D' end as ASC_OR_DESC, null as CARDINALITY, null as PAGES, i.filter_definition as FILTER_CONDITION, o.type AS INTERNAL_OBJECT_TYPE, i.*, c.*, s.* FROM sys.indexes i join sys.index_columns c on i.object_id=c.object_id and i.index_id=c.index_id join sys.stats s on i.object_id=s.object_id and i.name=s.name join sys.objects o on i.object_id=o.object_id WHERE object_schema_name(i.object_id)='" + CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getSchemaName(), Schema.class) + "'";
                        if (!this.isBulkFetchMode && tableName != null) {
                            sqlx = sqlx + " AND object_name(i.object_id)='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(tableName) + "'";
                        }

                        if (!this.isBulkFetchMode && indexName != null) {
                            sqlx = sqlx + " AND i.name='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(indexName) + "'";
                        }

                        sqlx = sqlx + "ORDER BY i.object_id, i.index_id, c.key_ordinal";
                        returnList.addAll(this.executeAndExtract(sqlx, CachingDatabaseMetaData.this.database));
                    } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                        sql = "SELECT i.CREATOR AS TABLE_SCHEM, i.TBNAME AS TABLE_NAME, i.NAME AS INDEX_NAME, 3 AS TYPE, k.COLNAME AS COLUMN_NAME, k.COLSEQ AS ORDINAL_POSITION, CASE UNIQUERULE WHEN 'D' then 1 else 0 end as NON_UNIQUE, k.ORDERING AS ORDER, i.CREATOR AS INDEX_QUALIFIER FROM SYSIBM.SYSKEYS k JOIN SYSIBM.SYSINDEXES i ON k.IXNAME = i.NAME WHERE  i.CREATOR = '" + CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getSchemaName(), Schema.class) + "'";
                        if (!this.isBulkFetchMode && tableName != null) {
                            sql = sql + " AND i.TBNAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(tableName) + "'";
                        }

                        if (!this.isBulkFetchMode && indexName != null) {
                            sql = sql + " AND i.NAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(indexName) + "'";
                        }

                        sql = sql + "ORDER BY i.NAME, k.COLSEQ";
                        returnList.addAll(this.executeAndExtract(sql, CachingDatabaseMetaData.this.database));
                    } else {
                        List<String> tables = new ArrayList();
                        Iterator var9;
                        if (tableName == null) {
                            var9 = CachingDatabaseMetaData.this.getTables(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), (String)null).iterator();

                            while(var9.hasNext()) {
                                CachedRow row = (CachedRow)var9.next();
                                tables.add(row.getString("TABLE_NAME"));
                            }
                        } else {
                            tables.add(tableName);
                        }

                        var9 = tables.iterator();

                        while(var9.hasNext()) {
                            String tableNamex = (String)var9.next();
                            ResultSet rs = CachingDatabaseMetaData.this.databaseMetaData.getIndexInfo(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), tableNamex, false, true);
                            List<CachedRow> rows = this.extract(rs, CachingDatabaseMetaData.this.database instanceof InformixDatabase);
                            returnList.addAll(rows);
                        }
                    }

                    return returnList;
                }

                public List<CachedRow> bulkFetch() throws SQLException, DatabaseException {
                    this.isBulkFetchMode = true;
                    return this.fastFetch();
                }

                boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                    if (!(CachingDatabaseMetaData.this.database instanceof OracleDatabase) && !(CachingDatabaseMetaData.this.database instanceof MSSQLDatabase)) {
                        return false;
                    } else {
                        return JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null || tableName == null && indexName == null || super.shouldBulkSelect(schemaKey, resultSetCache);
                    }
                }
            });
            return indexes;
        }

        protected void warnAboutDbaRecycleBin() {
            if (!JdbcDatabaseSnapshot.ignoreWarnAboutDbaRecycleBin && !JdbcDatabaseSnapshot.this.warnedAboutDbaRecycleBin && !((OracleDatabase)this.database).canAccessDbaRecycleBin()) {
                LogService.getLog(this.getClass()).warning(LogType.LOG, ((OracleDatabase)this.database).getDbaRecycleBinWarning());
                JdbcDatabaseSnapshot.this.warnedAboutDbaRecycleBin = true;
            }

        }

        public List<CachedRow> getColumns(String catalogName, String schemaName, String tableName, String columnName) throws SQLException, DatabaseException {
            if (this.database instanceof MSSQLDatabase && JdbcDatabaseSnapshot.this.userDefinedTypes == null) {
                JdbcDatabaseSnapshot.this.userDefinedTypes = new HashSet();
                DatabaseConnection databaseConnection = this.database.getConnection();
                if (databaseConnection instanceof JdbcConnection) {
                    Statement stmt = null;
                    ResultSet resultSet = null;

                    try {
                        stmt = ((JdbcConnection)databaseConnection).getUnderlyingConnection().createStatement();
                        resultSet = stmt.executeQuery("select name from " + (catalogName == null ? "" : "[" + catalogName + "].") + "sys.types where is_user_defined=1");

                        while(resultSet.next()) {
                            JdbcDatabaseSnapshot.this.userDefinedTypes.add(resultSet.getString("name").toLowerCase());
                        }
                    } finally {
                        JdbcUtils.close(resultSet, stmt);
                    }
                }
            }

            GetColumnResultSetCache getColumnResultSetCache = new GetColumnResultSetCache(this.database, catalogName, schemaName, tableName, columnName);
            return JdbcDatabaseSnapshot.this.getResultSetCache("getColumns").get(getColumnResultSetCache);
        }

        public List<CachedRow> getNotNullConst(String catalogName, String schemaName, String tableName) throws DatabaseException {
            if (!(this.database instanceof OracleDatabase)) {
                return Collections.emptyList();
            } else {
                GetNotNullConstraintsResultSetCache getNotNullConstraintsResultSetCache = new GetNotNullConstraintsResultSetCache(this.database, catalogName, schemaName, tableName);
                return JdbcDatabaseSnapshot.this.getResultSetCache("getNotNullConst").get(getNotNullConstraintsResultSetCache);
            }
        }

        public List<CachedRow> getTables(final String catalogName, final String schemaName, final String table) throws DatabaseException {
            return JdbcDatabaseSnapshot.this.getResultSetCache("getTables").get(new ResultSetCache.SingleResultSetExtractor(this.database) {
                boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                    return table == null || JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null || super.shouldBulkSelect(schemaKey, resultSetCache);
                }

                public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                    return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME")});
                }

                public ResultSetCache.RowData wantedKeyParameters() {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{table});
                }

                public boolean bulkContainsSchema(String schemaKey) {
                    return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
                }

                public String getSchemaKey(CachedRow row) {
                    return row.getString("TABLE_SCHEM");
                }

                public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                    if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                        return this.queryOracle(catalogAndSchema, table);
                    } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                        return this.queryMssql(catalogAndSchema, table);
                    } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                        return this.queryDb2Zos(catalogAndSchema, table);
                    } else {
                        String catalog = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema);
                        String schema = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getTables(catalog, schema, table == null ? "%" : table, new String[]{"TABLE"}));
                    }
                }

                public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                    if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                        return this.queryOracle(catalogAndSchema, (String)null);
                    } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                        return this.queryMssql(catalogAndSchema, (String)null);
                    } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                        return this.queryDb2Zos(catalogAndSchema, (String)null);
                    } else {
                        String catalog = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema);
                        String schema = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getTables(catalog, schema, "%", new String[]{"TABLE"}));
                    }
                }

                private List<CachedRow> queryMssql(CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException, SQLException {
                    String ownerName = CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getSchemaName(), Schema.class);
                    String databaseName = StringUtils.trimToNull(CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Catalog.class));
                    String dbIdParam;
                    String databasePrefix;
                    if (databaseName == null) {
                        databasePrefix = "";
                        dbIdParam = "";
                    } else {
                        dbIdParam = ", db_id('" + databaseName + "')";
                        databasePrefix = "[" + databaseName + "].";
                    }

                    String sql = "select db_name(" + (databaseName == null ? "" : "db_id('" + databaseName + "')") + ") AS TABLE_CAT, convert(sysname,object_schema_name(o.object_id" + dbIdParam + ")) AS TABLE_SCHEM, convert(sysname,o.name) AS TABLE_NAME, 'TABLE' AS TABLE_TYPE, CAST(ep.value as varchar(max)) as REMARKS from " + databasePrefix + "sys.all_objects o left outer join sys.extended_properties ep on ep.name='MS_Description' and major_id=o.object_id and minor_id=0 where o.type in ('U') and has_perms_by_name(" + (databaseName == null ? "" : "quotename('" + databaseName + "') + '.' + ") + "quotename(object_schema_name(o.object_id" + dbIdParam + ")) + '.' + quotename(o.name), 'object', 'select') = 1 and charindex(substring(o.type,1,1),'U') <> 0 and object_schema_name(o.object_id" + dbIdParam + ")='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(ownerName) + "'";
                    if (tableName != null) {
                        sql = sql + " AND o.name='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(tableName) + "' ";
                    }

                    sql = sql + "order by 4, 1, 2, 3";
                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                }

                private List<CachedRow> queryOracle(CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException, SQLException {
                    String ownerName = CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class);
                    String sql = "SELECT null as TABLE_CAT, a.OWNER as TABLE_SCHEM, a.TABLE_NAME as TABLE_NAME, a.TEMPORARY as TEMPORARY, a.DURATION as DURATION, 'TABLE' as TABLE_TYPE, c.COMMENTS as REMARKS, CASE WHEN A.tablespace_name = (SELECT DEFAULT_TABLESPACE FROM USER_USERS) THEN NULL ELSE tablespace_name END AS tablespace_name  from ALL_TABLES a join ALL_TAB_COMMENTS c on a.TABLE_NAME=c.table_name and a.owner=c.owner ";
                    String allCatalogsString = JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData();
                    if (tableName == null && allCatalogsString != null) {
                        sql = sql + "WHERE a.OWNER IN ('" + ownerName + "', " + allCatalogsString + ")";
                    } else {
                        sql = sql + "WHERE a.OWNER='" + ownerName + "'";
                    }

                    if (tableName != null) {
                        sql = sql + " AND a.TABLE_NAME='" + tableName + "'";
                    }

                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                }

                private List<CachedRow> queryDb2Zos(CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException, SQLException {
                    String ownerName = CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class);
                    String sql = "SELECT CREATOR AS TABLE_SCHEM, NAME AS TABLE_NAME, 'TABLE' AS TABLE_TYPE, REMARKS FROM  SYSIBM.SYSTABLES WHERE TYPE = 'T' ";
                    if (ownerName != null) {
                        sql = sql + "AND CREATOR='" + ownerName + "'";
                    }

                    if (tableName != null) {
                        sql = sql + " AND NAME='" + tableName + "'";
                    }

                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                }
            });
        }

        public List<CachedRow> getViews(final String catalogName, final String schemaName, String viewName) throws DatabaseException {
            final String view;
            if (this.database instanceof DB2Database) {
                view = this.database.correctObjectName(viewName, View.class);
            } else {
                view = viewName;
            }

            return JdbcDatabaseSnapshot.this.getResultSetCache("getViews").get(new ResultSetCache.SingleResultSetExtractor(this.database) {
                boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                    return view == null || JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null || super.shouldBulkSelect(schemaKey, resultSetCache);
                }

                public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                    return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME")});
                }

                public ResultSetCache.RowData wantedKeyParameters() {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{view});
                }

                public boolean bulkContainsSchema(String schemaKey) {
                    return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
                }

                public String getSchemaKey(CachedRow row) {
                    return row.getString("TABLE_SCHEM");
                }

                public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
//                    if (CachingDatabaseMetaData.this.database instanceof DM8Database) {
                        return this.queryDameng(catalogAndSchema, view);
//                    } else if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
//                        return this.queryOracle(catalogAndSchema, view);
//                    } else {
//                        String catalog = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema);
//                        String schema = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
//                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getTables(catalog, schema, view == null ? "%" : view, new String[]{"VIEW"}));
//                    }
                }

                public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
//                    if (CachingDatabaseMetaData.this.database instanceof DM8Database) {
                        return this.queryDameng(catalogAndSchema, (String)null);
//                    } else if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
//                        return this.queryOracle(catalogAndSchema, (String)null);
//                    } else {
//                        String catalog = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema);
//                        String schema = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
//                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getTables(catalog, schema, "%", new String[]{"VIEW"}));
//                    }
                }

                private List<CachedRow> queryOracle(CatalogAndSchema catalogAndSchema, String viewName) throws DatabaseException, SQLException {
                    String ownerName = CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class);
                    String sql = "SELECT null as TABLE_CAT, a.OWNER as TABLE_SCHEM, a.VIEW_NAME as TABLE_NAME, 'TABLE' as TABLE_TYPE, c.COMMENTS as REMARKS, TEXT as OBJECT_BODY";
                    if (CachingDatabaseMetaData.this.database.getDatabaseMajorVersion() > 10) {
                        sql = sql + ", EDITIONING_VIEW";
                    }

                    sql = sql + " from ALL_VIEWS a join ALL_TAB_COMMENTS c on a.VIEW_NAME=c.table_name and a.owner=c.owner ";
                    if (viewName == null && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                        sql = sql + "WHERE a.OWNER IN ('" + ownerName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                    } else {
                        sql = sql + "WHERE a.OWNER='" + ownerName + "'";
                    }

                    if (viewName != null) {
                        sql = sql + " AND a.VIEW_NAME='" + CachingDatabaseMetaData.this.database.correctObjectName(viewName, View.class) + "'";
                    }

                    sql = sql + " AND a.VIEW_NAME not in (select mv.name from all_registered_mviews mv where mv.owner=a.owner)";
                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                }

                private List<CachedRow> queryDameng(CatalogAndSchema catalogAndSchema, String viewName) throws DatabaseException, SQLException {
                    String ownerName = CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Schema.class);
                    String sql = "SELECT null as TABLE_CAT, a.OWNER as TABLE_SCHEM, a.VIEW_NAME as TABLE_NAME, 'TABLE' as TABLE_TYPE, c.COMMENTS as REMARKS, TEXT as OBJECT_BODY";
                    if (CachingDatabaseMetaData.this.database.getDatabaseMajorVersion() > 10) {
                        sql = sql + ", EDITIONING_VIEW";
                    }

                    sql = sql + " from ALL_VIEWS a join ALL_TAB_COMMENTS c on a.VIEW_NAME=c.table_name and a.owner=c.owner ";
                    if (viewName == null && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                        sql = sql + "WHERE a.OWNER IN ('" + ownerName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                    } else {
                        sql = sql + "WHERE a.OWNER='" + ownerName + "'";
                    }

                    if (viewName != null) {
                        sql = sql + " AND a.VIEW_NAME='" + CachingDatabaseMetaData.this.database.correctObjectName(viewName, View.class) + "'";
                    }

                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                }
            });
        }

        public List<CachedRow> getPrimaryKeys(final String catalogName, final String schemaName, final String table) throws DatabaseException {
            return JdbcDatabaseSnapshot.this.getResultSetCache("getPrimaryKeys").get(new ResultSetCache.SingleResultSetExtractor(this.database) {
                public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                    return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME")});
                }

                public ResultSetCache.RowData wantedKeyParameters() {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{table});
                }

                public boolean bulkContainsSchema(String schemaKey) {
                    return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
                }

                public String getSchemaKey(CachedRow row) {
                    return row.getString("TABLE_SCHEM");
                }

                public List<CachedRow> fastFetchQuery() throws SQLException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);

                    try {
                        List<CachedRow> foundPks = new ArrayList();
                        List pkInfox;
                        if (table == null) {
                            pkInfox = CachingDatabaseMetaData.this.getTables(catalogName, schemaName, (String)null);
                            Iterator var4 = pkInfox.iterator();

                            while(var4.hasNext()) {
                                CachedRow tablex = (CachedRow)var4.next();
                                List<CachedRow> pkInfo = this.getPkInfo(schemaName, catalogAndSchema, tablex.getString("TABLE_NAME"));
                                if (pkInfo != null) {
                                    foundPks.addAll(pkInfo);
                                }
                            }

                            return foundPks;
                        } else {
                            pkInfox = this.getPkInfo(schemaName, catalogAndSchema, table);
                            if (pkInfox != null) {
                                foundPks.addAll(pkInfox);
                            }

                            return foundPks;
                        }
                    } catch (DatabaseException var7) {
                        throw new SQLException(var7);
                    }
                }

                private List<CachedRow> getPkInfo(String schemaNamex, CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException, SQLException {
                    String sql;
                    if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                        sql = this.mssqlSql(catalogAndSchema, tableName);
                        List<CachedRow> pkInfo = this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                        return pkInfo;
                    } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                        sql = "SELECT 'NULL' AS TABLE_CAT, SYSTAB.TBCREATOR AS TABLE_SCHEM, SYSTAB.TBNAME AS TABLE_NAME, COLUSE.COLNAME AS COLUMN_NAME, COLUSE.COLSEQ AS KEY_SEQ, SYSTAB.CONSTNAME AS PK_NAME FROM SYSIBM.SYSTABCONST SYSTAB JOIN SYSIBM.SYSKEYCOLUSE COLUSE ON SYSTAB.TBCREATOR = COLUSE.TBCREATOR WHERE SYSTAB.TYPE = 'P' AND SYSTAB.TBNAME='" + table + "' AND SYSTAB.TBCREATOR='" + schemaNamex + "' AND SYSTAB.TBNAME=COLUSE.TBNAME AND SYSTAB.CONSTNAME=COLUSE.CONSTNAME ORDER BY COLUSE.COLNAME";

                        try {
                            return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                        } catch (DatabaseException var7) {
                            throw new SQLException(var7);
                        }
                    } else if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                        CachingDatabaseMetaData.this.warnAboutDbaRecycleBin();
                        sql = "SELECT NULL AS table_cat, c.owner AS table_schem, c.table_name, c.column_name as COLUMN_NAME, c.position AS key_seq, c.constraint_name AS pk_name, k.VALIDATED as VALIDATED FROM all_cons_columns c, all_constraints k LEFT JOIN " + (((OracleDatabase)CachingDatabaseMetaData.this.database).canAccessDbaRecycleBin() ? "dba_recyclebin" : "user_recyclebin") + " d ON d.object_name=k.table_name WHERE k.constraint_type = 'P' AND d.object_name IS NULL AND k.table_name = '" + table + "' AND k.owner = '" + ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema) + "' AND k.constraint_name = c.constraint_name AND k.table_name = c.table_name AND k.owner = c.owner ORDER BY column_name";

                        try {
                            return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                        } catch (DatabaseException var8) {
                            throw new SQLException(var8);
                        }
                    } else {
                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getPrimaryKeys(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), table));
                    }
                }

                private String mssqlSql(CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException {
                    String sql = "SELECT DB_NAME() AS [TABLE_CAT], [s].[name] AS [TABLE_SCHEM], [t].[name] AS [TABLE_NAME], [c].[name] AS [COLUMN_NAME], CASE [ic].[is_descending_key] WHEN 0 THEN N'A' WHEN 1 THEN N'D' END AS [ASC_OR_DESC], [ic].[key_ordinal] AS [KEY_SEQ], [kc].[name] AS [PK_NAME] FROM [sys].[schemas] AS [s] INNER JOIN [sys].[tables] AS [t] ON [t].[schema_id] = [s].[schema_id] INNER JOIN [sys].[key_constraints] AS [kc] ON [kc].[parent_object_id] = [t].[object_id] INNER JOIN [sys].[indexes] AS [i] ON [i].[object_id] = [kc].[parent_object_id] AND [i].[index_id] = [kc].[unique_index_id] INNER JOIN [sys].[index_columns] AS [ic] ON [ic].[object_id] = [i].[object_id] AND [ic].[index_id] = [i].[index_id] INNER JOIN [sys].[columns] AS [c] ON [c].[object_id] = [ic].[object_id] AND [c].[column_id] = [ic].[column_id] WHERE [s].[name] = N'" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(catalogAndSchema.getSchemaName()) + "' " + (tableName == null ? "" : "AND [t].[name] = N'" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(CachingDatabaseMetaData.this.database.correctObjectName(tableName, Table.class)) + "' ") + "AND [kc].[type] = 'PK' AND [ic].[key_ordinal] > 0 ORDER BY [ic].[key_ordinal]";
                    return sql;
                }

                public List<CachedRow> bulkFetchQuery() throws SQLException {
                    CatalogAndSchema catalogAndSchema;
                    if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                        catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                        CachingDatabaseMetaData.this.warnAboutDbaRecycleBin();

                        try {
                            String sql = "SELECT NULL AS table_cat, c.owner AS table_schem, c.table_name, c.column_name, c.position AS key_seq,c.constraint_name AS pk_name, k.VALIDATED as VALIDATED FROM all_cons_columns c, all_constraints k LEFT JOIN " + (((OracleDatabase)CachingDatabaseMetaData.this.database).canAccessDbaRecycleBin() ? "dba_recyclebin" : "user_recyclebin") + " d ON d.object_name=k.table_name WHERE k.constraint_type = 'P' AND d.object_name IS NULL ";
                            if (JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() == null) {
                                sql = sql + "AND k.owner='" + catalogAndSchema.getCatalogName() + "' ";
                            } else {
                                sql = sql + "AND k.owner IN ('" + catalogAndSchema.getCatalogName() + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                            }

                            sql = sql + "AND k.constraint_name = c.constraint_name AND k.table_name = c.table_name AND k.owner = c.owner ORDER BY column_name";
                            return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                        } catch (DatabaseException var3) {
                            throw new SQLException(var3);
                        }
                    } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                        catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);

                        try {
                            return this.executeAndExtract(this.mssqlSql(catalogAndSchema, (String)null), CachingDatabaseMetaData.this.database);
                        } catch (DatabaseException var4) {
                            throw new SQLException(var4);
                        }
                    } else {
                        return null;
                    }
                }

                boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                    if (!(CachingDatabaseMetaData.this.database instanceof OracleDatabase) && !(CachingDatabaseMetaData.this.database instanceof MSSQLDatabase)) {
                        return false;
                    } else {
                        return table == null || JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null || super.shouldBulkSelect(schemaKey, resultSetCache);
                    }
                }
            });
        }

        public List<CachedRow> getUniqueConstraints(final String catalogName, final String schemaName, final String tableName) throws DatabaseException {
            return JdbcDatabaseSnapshot.this.getResultSetCache("getUniqueConstraints").get(new ResultSetCache.SingleResultSetExtractor(this.database) {
                boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                    return tableName == null || JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null || super.shouldBulkSelect(schemaKey, resultSetCache);
                }

                public boolean bulkContainsSchema(String schemaKey) {
                    return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
                }

                public String getSchemaKey(CachedRow row) {
                    return row.getString("CONSTRAINT_SCHEM");
                }

                public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME")});
                }

                public ResultSetCache.RowData wantedKeyParameters() {
                    return new ResultSetCache.RowData(catalogName, schemaName, CachingDatabaseMetaData.this.database, new String[]{tableName});
                }

                public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                    return this.executeAndExtract(this.createSql(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), tableName), JdbcDatabaseSnapshot.this.getDatabase(), CachingDatabaseMetaData.this.database instanceof InformixDatabase);
                }

                public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogName, schemaName)).customize(CachingDatabaseMetaData.this.database);
                    return this.executeAndExtract(this.createSql(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), (String)null), JdbcDatabaseSnapshot.this.getDatabase());
                }

                private String createSql(String catalogNamex, String schemaNamex, String tableNamex) throws SQLException {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(catalogNamex, schemaNamex)).customize(CachingDatabaseMetaData.this.database);
                    String jdbcCatalogName = CachingDatabaseMetaData.this.database.correctObjectName(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), Catalog.class);
                    String jdbcSchemaName = CachingDatabaseMetaData.this.database.correctObjectName(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), Schema.class);
                    Database database = JdbcDatabaseSnapshot.this.getDatabase();
                    String sql;
                    if (database instanceof Ingres9Database) {
                        sql = "select CONSTRAINT_NAME, TABLE_NAME from iiconstraints where schema_name ='" + schemaNamex + "' and constraint_type='U'";
                        if (tableNamex != null) {
                            sql = sql + " and table_name='" + tableNamex + "'";
                        }
                    } else if (!(database instanceof MySQLDatabase) && !(database instanceof HsqlDatabase) && !(database instanceof MariaDBDatabase)) {
                        if (database instanceof PostgresDatabase) {
                            sql = "select CONSTRAINT_NAME, TABLE_NAME from " + database.getSystemSchema() + ".table_constraints where constraint_catalog='" + jdbcCatalogName + "' and constraint_schema='" + jdbcSchemaName + "' and constraint_type='UNIQUE'";
                            if (tableNamex != null) {
                                sql = sql + " and table_name='" + tableNamex + "'";
                            }
                        } else if (database instanceof MSSQLDatabase) {
                            sql = "SELECT [TC].[CONSTRAINT_NAME], [TC].[TABLE_NAME], [TC].[CONSTRAINT_CATALOG] AS INDEX_CATALOG, [TC].[CONSTRAINT_SCHEMA] AS INDEX_SCHEMA, [IDX].[TYPE_DESC], [IDX].[name] AS INDEX_NAME FROM [INFORMATION_SCHEMA].[TABLE_CONSTRAINTS] AS [TC] JOIN sys.indexes AS IDX ON IDX.name=[TC].[CONSTRAINT_NAME] AND object_schema_name(object_id)=[TC].[CONSTRAINT_SCHEMA] WHERE [TC].[CONSTRAINT_TYPE] = 'UNIQUE' AND [TC].[CONSTRAINT_CATALOG] = N'" + database.escapeStringForDatabase(jdbcCatalogName) + "' AND [TC].[CONSTRAINT_SCHEMA] = N'" + database.escapeStringForDatabase(jdbcSchemaName) + "'";
                            if (tableNamex != null) {
                                sql = sql + " AND [TC].[TABLE_NAME] = N'" + database.escapeStringForDatabase(database.correctObjectName(tableNamex, Table.class)) + "'";
                            }
                        } else if (database instanceof OracleDatabase) {
                            CachingDatabaseMetaData.this.warnAboutDbaRecycleBin();
                            sql = "select uc.owner AS CONSTRAINT_SCHEM, uc.constraint_name, uc.table_name,uc.status,uc.deferrable,uc.deferred,ui.tablespace_name, ui.index_name, ui.owner as INDEX_CATALOG, uc.VALIDATED as VALIDATED, ac.COLUMN_NAME as COLUMN_NAME from all_constraints uc join all_indexes ui on uc.index_name = ui.index_name and uc.owner=ui.table_owner and uc.table_name=ui.table_name LEFT OUTER JOIN " + (((OracleDatabase)database).canAccessDbaRecycleBin() ? "dba_recyclebin" : "user_recyclebin") + " d ON d.object_name=ui.table_name LEFT JOIN all_cons_columns ac ON ac.OWNER = uc.OWNER AND ac.TABLE_NAME = uc.TABLE_NAME AND ac.CONSTRAINT_NAME = uc.CONSTRAINT_NAME where uc.constraint_type='U' ";
                            if (tableNamex == null && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                                sql = sql + "and uc.owner IN ('" + jdbcSchemaName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                            } else {
                                sql = sql + "and uc.owner = '" + jdbcSchemaName + "'";
                            }

                            sql = sql + "AND d.object_name IS NULL ";
                            if (tableNamex != null) {
                                sql = sql + " and uc.table_name = '" + tableNamex + "'";
                            }
                        } else if (database instanceof DB2Database) {
                            if (database.getDatabaseProductName().startsWith("DB2 UDB for AS/400")) {
                                sql = "select constraint_name as constraint_name, table_name as table_name from QSYS2.TABLE_CONSTRAINTS where table_schema='" + jdbcSchemaName + "' and constraint_type='UNIQUE'";
                                if (tableNamex != null) {
                                    sql = sql + " and table_name = '" + tableNamex + "'";
                                }
                            } else {
                                sql = "select distinct k.constname as constraint_name, t.tabname as TABLE_NAME from syscat.keycoluse k, syscat.tabconst t where k.constname = t.constname and t.tabschema = '" + jdbcSchemaName + "' and t.type='U'";
                                if (tableNamex != null) {
                                    sql = sql + " and t.tabname = '" + tableNamex + "'";
                                }
                            }
                        } else if (database instanceof Db2zDatabase) {
                            sql = "select distinct k.constname as constraint_name, t.tbname as TABLE_NAME from SYSIBM.SYSKEYCOLUSE k, SYSIBM.SYSTABCONST t where k.constname = t.constname and k.TBCREATOR = t.TBCREATOR and t.TBCREATOR = '" + jdbcSchemaName + "' ";
                            if (tableNamex != null) {
                                sql = sql + " and t.tbname = '" + tableNamex + "'";
                            }
                        } else if (database instanceof FirebirdDatabase) {
                            sql = "SELECT TRIM(RDB$INDICES.RDB$INDEX_NAME) AS CONSTRAINT_NAME, TRIM(RDB$INDICES.RDB$RELATION_NAME) AS TABLE_NAME FROM RDB$INDICES LEFT JOIN RDB$RELATION_CONSTRAINTS ON RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME = RDB$INDICES.RDB$INDEX_NAME WHERE RDB$INDICES.RDB$UNIQUE_FLAG IS NOT NULL AND (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE IS NULL OR TRIM(RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE)='UNIQUE') AND NOT(RDB$INDICES.RDB$INDEX_NAME LIKE 'RDB$%')";
                            if (tableNamex != null) {
                                sql = sql + " AND TRIM(RDB$INDICES.RDB$RELATION_NAME)='" + tableNamex + "'";
                            }
                        } else if (database instanceof DerbyDatabase) {
                            sql = "select c.constraintname as CONSTRAINT_NAME, tablename AS TABLE_NAME from sys.systables t, sys.sysconstraints c, sys.sysschemas s where s.schemaname='" + jdbcCatalogName + "' and t.tableid = c.tableid and t.schemaid=s.schemaid and c.type = 'U'";
                            if (tableNamex != null) {
                                sql = sql + " AND t.tablename = '" + tableNamex + "'";
                            }
                        } else if (database instanceof InformixDatabase) {
                            sql = "select unique sysindexes.idxname as CONSTRAINT_NAME, sysindexes.idxtype, systables.tabname as TABLE_NAME from sysindexes, systables left outer join sysconstraints on sysconstraints.tabid = systables.tabid and sysconstraints.constrtype = 'P' where sysindexes.tabid = systables.tabid and sysindexes.idxtype = 'U' and sysconstraints.idxname != sysindexes.idxname and sysconstraints.tabid = sysindexes.tabid";
                            if (tableNamex != null) {
                                sql = sql + " and systables.tabname = '" + database.correctObjectName(tableNamex, Table.class) + "'";
                            }
                        } else {
                            if (database instanceof SybaseDatabase) {
                                LogService.getLog(this.getClass()).warning(LogType.LOG, "Finding unique constraints not currently supported for Sybase");
                                return null;
                            }

                            if (database instanceof SybaseASADatabase) {
                                sql = "select sysconstraint.constraint_name, sysconstraint.constraint_type, systable.table_name from sysconstraint, systable where sysconstraint.table_object_id = systable.object_id and sysconstraint.constraint_type = 'U'";
                                if (tableNamex != null) {
                                    sql = sql + " and systable.table_name = '" + tableNamex + "'";
                                }
                            } else {
                                sql = "select CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME from " + database.getSystemSchema() + ".constraints where constraint_schema='" + jdbcSchemaName + "' and constraint_catalog='" + jdbcCatalogName + "' and constraint_type='UNIQUE'";
                                if (tableNamex != null) {
                                    sql = sql + " and table_name='" + tableNamex + "'";
                                }
                            }
                        }
                    } else {
                        sql = "select CONSTRAINT_NAME, TABLE_NAME from " + database.getSystemSchema() + ".table_constraints where constraint_schema='" + jdbcCatalogName + "' and constraint_type='UNIQUE'";
                        if (tableNamex != null) {
                            sql = sql + " and table_name='" + tableNamex + "'";
                        }
                    }

                    return sql;
                }
            });
        }

        private class GetNotNullConstraintsResultSetCache extends ResultSetCache.SingleResultSetExtractor {
            final String catalogName;
            final String schemaName;
            final String tableName;

            private GetNotNullConstraintsResultSetCache(Database database, String catalogName, String schemaName, String tableName) {
                super(database);
                this.catalogName = catalogName;
                this.schemaName = schemaName;
                this.tableName = tableName;
            }

            public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEMA"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME")});
            }

            public ResultSetCache.RowData wantedKeyParameters() {
                return new ResultSetCache.RowData(this.catalogName, this.schemaName, CachingDatabaseMetaData.this.database, new String[]{this.tableName});
            }

            public boolean bulkContainsSchema(String schemaKey) {
                return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
            }

            public String getSchemaKey(CachedRow row) {
                return row.getString("TABLE_SCHEMA");
            }

            boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                return !this.tableName.equalsIgnoreCase(CachingDatabaseMetaData.this.database.getDatabaseChangeLogTableName()) && !this.tableName.equalsIgnoreCase(CachingDatabaseMetaData.this.database.getDatabaseChangeLogLockTableName());
            }

            public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
                if (database instanceof OracleDatabase) {
                    return oracleQuery(false);
                }
                return Collections.emptyList();
            }

            public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
                if (database instanceof OracleDatabase) {
                    return oracleQuery(true);
                }
                return Collections.emptyList();
            }

            private List<CachedRow> oracleQuery(boolean bulk) throws DatabaseException, SQLException {
                CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                String jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                String jdbcTableName = CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.tableName);
                String sqlToSelectNotNullConstraints = "SELECT  NULL AS TABLE_CAT, atc.OWNER AS TABLE_SCHEMA, atc.OWNER, atc.TABLE_NAME, atc.COLUMN_NAME, NULLABLE, ac.VALIDATED as VALIDATED, ac.SEARCH_CONDITION, ac.CONSTRAINT_NAME FROM ALL_TAB_COLS atc JOIN all_cons_columns acc ON atc.OWNER = acc.OWNER AND atc.TABLE_NAME = acc.TABLE_NAME AND atc.COLUMN_NAME = acc.COLUMN_NAME JOIN all_constraints ac ON atc.OWNER = ac.OWNER AND atc.TABLE_NAME = ac.TABLE_NAME AND acc.CONSTRAINT_NAME = ac.CONSTRAINT_NAME ";
                if (bulk && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                    sqlToSelectNotNullConstraints = sqlToSelectNotNullConstraints + " WHERE atc.OWNER IN ('" + jdbcSchemaName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")  AND atc.hidden_column='NO' AND ac.CONSTRAINT_TYPE='C'  and ac.search_condition is not null ";
                } else {
                    sqlToSelectNotNullConstraints = sqlToSelectNotNullConstraints + " WHERE atc.OWNER='" + jdbcSchemaName + "' AND atc.hidden_column='NO' AND ac.CONSTRAINT_TYPE='C'  and ac.search_condition is not null ";
                }

                sqlToSelectNotNullConstraints = sqlToSelectNotNullConstraints + (!bulk && this.tableName != null && !this.tableName.isEmpty() ? " AND atc.TABLE_NAME='" + jdbcTableName + "'" : "");
                return this.executeAndExtract(sqlToSelectNotNullConstraints, CachingDatabaseMetaData.this.database);
            }

            protected List<CachedRow> extract(ResultSet resultSet, boolean informixIndexTrimHint) throws SQLException {
                List<CachedRow> cachedRowList = new ArrayList();
                if (!(CachingDatabaseMetaData.this.database instanceof OracleDatabase)) {
                    return cachedRowList;
                } else {
                    resultSet.setFetchSize(CachingDatabaseMetaData.this.database.getFetchSize());

                    try {
                        List<Map> result = (List)(new RowMapperNotNullConstraintsResultSetExtractor(new ColumnMapRowMapper() {
                            protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
                                Object value = super.getColumnValue(rs, index);
                                return value != null && value instanceof String ? value.toString().trim() : value;
                            }
                        })).extractData(resultSet);
                        Iterator var5 = result.iterator();

                        while(var5.hasNext()) {
                            Map row = (Map)var5.next();
                            cachedRowList.add(new CachedRow(row));
                        }
                    } finally {
                        JdbcUtils.closeResultSet(resultSet);
                    }

                    return cachedRowList;
                }
            }
        }

        private class ForeignKeysResultSetCache extends ResultSetCache.UnionResultSetExtractor {
            final String catalogName;
            final String schemaName;
            final String tableName;
            final String fkName;

            private ForeignKeysResultSetCache(Database database, String catalogName, String schemaName, String tableName, String fkName) {
                super(database);
                this.catalogName = catalogName;
                this.schemaName = schemaName;
                this.tableName = tableName;
                this.fkName = fkName;
            }

            public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                return new ResultSetCache.RowData(row.getString("FKTABLE_CAT"), row.getString("FKTABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("FKTABLE_NAME"), row.getString("FK_NAME")});
            }

            public ResultSetCache.RowData wantedKeyParameters() {
                return new ResultSetCache.RowData(this.catalogName, this.schemaName, CachingDatabaseMetaData.this.database, new String[]{this.tableName, this.fkName});
            }

            public boolean bulkContainsSchema(String schemaKey) {
                return CachingDatabaseMetaData.this.database instanceof OracleDatabase;
            }

            public String getSchemaKey(CachedRow row) {
                return row.getString("FKTABLE_SCHEM");
            }

            public List<CachedRow> fastFetch() throws SQLException, DatabaseException {
                CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                List<CachedRow> returnList = new ArrayList();
                List<String> tables = new ArrayList();
                String jdbcCatalogName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema);
                String jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                if (CachingDatabaseMetaData.this.database instanceof DB2Database) {
                    return this.executeAndExtract(this.getDB2Sql(jdbcSchemaName, this.tableName), CachingDatabaseMetaData.this.database);
                } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                    return this.executeAndExtract(this.getDB2ZOSSql(jdbcSchemaName, this.tableName), CachingDatabaseMetaData.this.database);
                } else {
                    Iterator var6;
                    if (this.tableName == null) {
                        var6 = CachingDatabaseMetaData.this.getTables(jdbcCatalogName, jdbcSchemaName, (String)null).iterator();

                        while(var6.hasNext()) {
                            CachedRow row = (CachedRow)var6.next();
                            tables.add(row.getString("TABLE_NAME"));
                        }
                    } else {
                        tables.add(this.tableName);
                    }

                    var6 = tables.iterator();

                    while(var6.hasNext()) {
                        String foundTable = (String)var6.next();
                        if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                            throw new RuntimeException("Should have bulk selected");
                        }

                        returnList.addAll(this.extract(CachingDatabaseMetaData.this.databaseMetaData.getImportedKeys(jdbcCatalogName, jdbcSchemaName, foundTable)));
                    }

                    return returnList;
                }
            }

            public List<CachedRow> bulkFetch() throws SQLException, DatabaseException {
                CatalogAndSchema catalogAndSchema;
                String jdbcSchemaName;
                String sql;
                if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                    catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                    jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                    sql = this.getOracleSql(jdbcSchemaName);
                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                } else if (CachingDatabaseMetaData.this.database instanceof DB2Database) {
                    catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                    jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                    return this.executeAndExtract(this.getDB2Sql(jdbcSchemaName, (String)null), CachingDatabaseMetaData.this.database);
                } else if (CachingDatabaseMetaData.this.database instanceof Db2zDatabase) {
                    catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                    jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                    return this.executeAndExtract(this.getDB2ZOSSql(jdbcSchemaName, (String)null), CachingDatabaseMetaData.this.database);
                } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                    catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                    jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                    sql = this.getMSSQLSql(jdbcSchemaName, this.tableName);
                    return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                } else {
                    throw new RuntimeException("Cannot bulk select");
                }
            }

            protected String getOracleSql(String jdbcSchemaName) {
                String sql = "SELECT  /*+rule*/  NULL AS pktable_cat,    p.owner as pktable_schem,    p.table_name as pktable_name,    pc.column_name as pkcolumn_name,    NULL as fktable_cat,    f.owner as fktable_schem,    f.table_name as fktable_name,    fc.column_name as fkcolumn_name,    fc.position as key_seq,    NULL as update_rule,    decode (f.delete_rule, 'CASCADE', 0, 'SET NULL', 2, 1) as delete_rule,    f.constraint_name as fk_name,    p.constraint_name as pk_name,    decode(f.deferrable, 'DEFERRABLE', 5, 'NOT DEFERRABLE', 7, 'DEFERRED', 6) deferrability,    f.validated as fk_validate FROM all_cons_columns pc INNER JOIN all_constraints p ON pc.owner = p.owner AND pc.constraint_name = p.constraint_name INNER JOIN all_constraints f ON pc.owner = f.r_owner AND pc.constraint_name = f.r_constraint_name INNER JOIN all_cons_columns fc ON fc.owner = f.owner AND fc.constraint_name = f.constraint_name AND fc.position = pc.position ";
                if (JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() == null) {
                    sql = sql + "WHERE f.owner = '" + jdbcSchemaName + "' ";
                } else {
                    sql = sql + "WHERE f.owner IN ('" + jdbcSchemaName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ") ";
                }

                sql = sql + "AND p.constraint_type in ('P', 'U') AND f.constraint_type = 'R' AND p.table_name NOT LIKE 'BIN$%' ORDER BY fktable_schem, fktable_name, key_seq";
                return sql;
            }

            protected String getMSSQLSql(String jdbcSchemaName, String tableName) {
                return "select convert(sysname,db_name()) AS PKTABLE_CAT, convert(sysname,schema_name(o1.schema_id)) AS PKTABLE_SCHEM, convert(sysname,o1.name) AS PKTABLE_NAME, convert(sysname,c1.name) AS PKCOLUMN_NAME, convert(sysname,db_name()) AS FKTABLE_CAT, convert(sysname,schema_name(o2.schema_id)) AS FKTABLE_SCHEM, convert(sysname,o2.name) AS FKTABLE_NAME, convert(sysname,c2.name) AS FKCOLUMN_NAME, isnull(convert(smallint,k.constraint_column_id), convert(smallint,0)) AS KEY_SEQ, convert(smallint, case ObjectProperty(f.object_id, 'CnstIsUpdateCascade') when 1 then 0 else 1 end) AS UPDATE_RULE, convert(smallint, case ObjectProperty(f.object_id, 'CnstIsDeleteCascade') when 1 then 0 else 1 end) AS DELETE_RULE, convert(sysname,object_name(f.object_id)) AS FK_NAME, convert(sysname,i.name) AS PK_NAME, convert(smallint, 7) AS DEFERRABILITY from sys.objects o1, sys.objects o2, sys.columns c1, sys.columns c2, sys.foreign_keys f inner join sys.foreign_key_columns k on (k.constraint_object_id = f.object_id) inner join sys.indexes i on (f.referenced_object_id = i.object_id and f.key_index_id = i.index_id) where o1.object_id = f.referenced_object_id and o2.object_id = f.parent_object_id and c1.object_id = f.referenced_object_id and c2.object_id = f.parent_object_id and c1.column_id = k.referenced_column_id and c2.column_id = k.parent_column_id and ((object_schema_name(o1.object_id)='" + jdbcSchemaName + "' and convert(sysname,schema_name(o2.schema_id))='" + jdbcSchemaName + "' and convert(sysname,o2.name)='" + tableName + "' ) or ( convert(sysname,schema_name(o2.schema_id))='" + jdbcSchemaName + "' and convert(sysname,o2.name)='" + tableName + "' )) order by 5, 6, 7, 9, 8";
            }

            protected String getDB2Sql(String jdbcSchemaName, String tableName) {
                return "SELECT    pk_col.tabschema AS pktable_cat,    pk_col.tabname as pktable_name,    pk_col.colname as pkcolumn_name,   fk_col.tabschema as fktable_cat,    fk_col.tabname as fktable_name,    fk_col.colname as fkcolumn_name,   fk_col.colseq as key_seq,    decode (ref.updaterule, 'A', 3, 'R', 1, 1) as update_rule,    decode (ref.deleterule, 'A', 3, 'C', 0, 'N', 2, 'R', 1, 1) as delete_rule,    ref.constname as fk_name,    ref.refkeyname as pk_name,    7 as deferrability  FROM syscat.references ref join syscat.keycoluse fk_col on ref.constname=fk_col.constname and ref.tabschema=fk_col.tabschema and ref.tabname=fk_col.tabname join syscat.keycoluse pk_col on ref.refkeyname=pk_col.constname and ref.reftabschema=pk_col.tabschema and ref.reftabname=pk_col.tabname WHERE ref.tabschema = '" + jdbcSchemaName + "' and pk_col.colseq=fk_col.colseq " + (tableName != null ? " AND fk_col.tabname='" + tableName + "' " : "") + "ORDER BY fk_col.colseq";
            }

            protected String getDB2ZOSSql(String jdbcSchemaName, String tableName) {
                return "SELECT    ref.REFTBCREATOR AS pktable_cat,    ref.REFTBNAME as pktable_name,    pk_col.colname as pkcolumn_name,   ref.CREATOR as fktable_cat,    ref.TBNAME as fktable_name,    fk_col.colname as fkcolumn_name,   fk_col.colseq as key_seq,    decode (ref.deleterule, 'A', 3, 'C', 0, 'N', 2, 'R', 1, 1) as delete_rule,    ref.relname as fk_name,    pk_col.colname as pk_name,    7 as deferrability  FROM SYSIBM.SYSRELS ref join SYSIBM.SYSFOREIGNKEYS fk_col on ref.relname = fk_col.RELNAME and ref.CREATOR = fk_col.CREATOR and ref.TBNAME = fk_col.TBNAME join SYSIBM.SYSKEYCOLUSE pk_col on ref.REFTBCREATOR = pk_col.TBCREATOR and ref.REFTBNAME = pk_col.TBNAME WHERE ref.CREATOR = '" + jdbcSchemaName + "' and pk_col.colseq=fk_col.colseq " + (tableName != null ? " AND ref.TBNAME='" + tableName + "' " : "") + "ORDER BY fk_col.colseq";
            }

            boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                return !(CachingDatabaseMetaData.this.database instanceof AbstractDb2Database) && !(CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) ? CachingDatabaseMetaData.this.database instanceof OracleDatabase : super.shouldBulkSelect(schemaKey, resultSetCache);
            }
        }

        private class GetColumnResultSetCache extends ResultSetCache.SingleResultSetExtractor {
            final String catalogName;
            final String schemaName;
            final String tableName;
            final String columnName;

            private GetColumnResultSetCache(Database database, String catalogName, String schemaName, String tableName, String columnName) {
                super(database);
                this.catalogName = catalogName;
                this.schemaName = schemaName;
                this.tableName = tableName;
                this.columnName = columnName;
            }

            public ResultSetCache.RowData rowKeyParameters(CachedRow row) {
                return new ResultSetCache.RowData(row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM"), CachingDatabaseMetaData.this.database, new String[]{row.getString("TABLE_NAME"), row.getString("COLUMN_NAME")});
            }

            public ResultSetCache.RowData wantedKeyParameters() {
                return new ResultSetCache.RowData(this.catalogName, this.schemaName, CachingDatabaseMetaData.this.database, new String[]{this.tableName, this.columnName});
            }

            public boolean bulkContainsSchema(String schemaKey) {
                String catalogs = JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData();
                return catalogs != null && schemaKey != null && catalogs.contains("'" + schemaKey.toUpperCase() + "'") && CachingDatabaseMetaData.this.database instanceof OracleDatabase;
            }

            public String getSchemaKey(CachedRow row) {
                return row.getString("TABLE_SCHEM");
            }

            boolean shouldBulkSelect(String schemaKey, ResultSetCache resultSetCache) {
                return !this.tableName.equalsIgnoreCase(CachingDatabaseMetaData.this.database.getDatabaseChangeLogTableName()) && !this.tableName.equalsIgnoreCase(CachingDatabaseMetaData.this.database.getDatabaseChangeLogLockTableName());
            }

            public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {
                if (CachingDatabaseMetaData.this.database instanceof DM8Database) {
                    return this.damengQuery(false);
                } else if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                    return this.oracleQuery(false);
                } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                    return this.mssqlQuery(false);
                } else {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);

                    try {
                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getColumns(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), this.tableName, "%"));
                    } catch (SQLException var3) {
                        if (this.shouldReturnEmptyColumns(var3)) {
                            return new ArrayList();
                        } else {
                            throw var3;
                        }
                    }
                }
            }

            public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {
                if (CachingDatabaseMetaData.this.database instanceof DM8Database) {
                    return this.damengQuery(true);
                } else if (CachingDatabaseMetaData.this.database instanceof OracleDatabase) {
                    return this.oracleQuery(true);
                } else if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase) {
                    return this.mssqlQuery(true);
                } else {
                    CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);

                    try {
                        return this.extract(CachingDatabaseMetaData.this.databaseMetaData.getColumns(((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcCatalogName(catalogAndSchema), ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema), "%", "%"));
                    } catch (SQLException var3) {
                        if (this.shouldReturnEmptyColumns(var3)) {
                            return new ArrayList();
                        } else {
                            throw var3;
                        }
                    }
                }
            }

            protected boolean shouldReturnEmptyColumns(SQLException e) {
                return e.getMessage().contains("references invalid table");
            }

            protected List<CachedRow> oracleQuery(boolean bulk) throws DatabaseException, SQLException {
                CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                boolean getMapDateToTimestamp = true;
                String jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                boolean collectIdentityData = CachingDatabaseMetaData.this.database.getDatabaseMajorVersion() >= 12;
                String sql = "select NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM, 'NO' as IS_AUTOINCREMENT, cc.COMMENTS AS REMARKS,OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE AS DATA_TYPE_NAME, DATA_TYPE_MOD, DATA_TYPE_OWNER, DECODE (c.data_type, 'CHAR', 1, 'VARCHAR2', 12, 'NUMBER', 3, 'LONG', -1, 'DATE', " + (getMapDateToTimestamp ? "93" : "91") + ", 'RAW', -3, 'LONG RAW', -4, 'BLOB', 2004, 'CLOB', 2005, 'BFILE', -13, 'FLOAT', 6, 'TIMESTAMP(6)', 93, 'TIMESTAMP(6) WITH TIME ZONE', -101, 'TIMESTAMP(6) WITH LOCAL TIME ZONE', -102, 'INTERVAL YEAR(2) TO MONTH', -103, 'INTERVAL DAY(2) TO SECOND(6)', -104, 'BINARY_FLOAT', 100, 'BINARY_DOUBLE', 101, 'XMLTYPE', 2009, 1111) AS data_type, DECODE( CHAR_USED, 'C',CHAR_LENGTH, DATA_LENGTH ) as DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, COLUMN_ID as ORDINAL_POSITION, DEFAULT_LENGTH, DATA_DEFAULT, NUM_BUCKETS, CHARACTER_SET_NAME, CHAR_COL_DECL_LENGTH, CHAR_LENGTH, CHAR_USED, VIRTUAL_COLUMN ";
                if (collectIdentityData) {
                    sql = sql + ", DEFAULT_ON_NULL, IDENTITY_COLUMN, ic.GENERATION_TYPE ";
                }

                sql = sql + "FROM ALL_TAB_COLS c JOIN ALL_COL_COMMENTS cc USING ( OWNER, TABLE_NAME, COLUMN_NAME ) ";
                if (collectIdentityData) {
                    sql = sql + "LEFT JOIN ALL_TAB_IDENTITY_COLS ic USING (OWNER, TABLE_NAME, COLUMN_NAME ) ";
                }

                if (bulk && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                    sql = sql + "WHERE OWNER IN ('" + jdbcSchemaName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ") AND hidden_column='NO'";
                } else {
                    sql = sql + "WHERE OWNER='" + jdbcSchemaName + "' AND hidden_column='NO'";
                }

                if (!bulk) {
                    if (this.tableName != null) {
                        sql = sql + " AND TABLE_NAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.tableName) + "'";
                    }

                    if (this.columnName != null) {
                        sql = sql + " AND COLUMN_NAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.columnName) + "'";
                    }
                }

                sql = sql + " AND " + ((OracleDatabase)CachingDatabaseMetaData.this.database).getSystemTableWhereClause("TABLE_NAME");
                sql = sql + " ORDER BY OWNER, TABLE_NAME, c.COLUMN_ID";
                return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
            }

            protected List<CachedRow> damengQuery(boolean bulk) throws DatabaseException, SQLException {
                CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                boolean getMapDateToTimestamp = true;
                String jdbcSchemaName = ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema);
                boolean collectIdentityData = CachingDatabaseMetaData.this.database.getDatabaseMajorVersion() >= 12;
                String sql = "select NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM, 'NO' as IS_AUTOINCREMENT, cc.COMMENTS AS REMARKS,OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE AS DATA_TYPE_NAME, DATA_TYPE_MOD, DATA_TYPE_OWNER, DECODE (c.data_type, 'CHAR', 1, 'VARCHAR2', 12, 'NUMBER', 3, 'LONG', -1, 'DATE', " + (getMapDateToTimestamp ? "93" : "91") + ", 'RAW', -3, 'LONG RAW', -4, 'BLOB', 2004, 'CLOB', 2005, 'BFILE', -13, 'FLOAT', 6, 'TIMESTAMP(6)', 93, 'TIMESTAMP(6) WITH TIME ZONE', -101, 'TIMESTAMP(6) WITH LOCAL TIME ZONE', -102, 'INTERVAL YEAR(2) TO MONTH', -103, 'INTERVAL DAY(2) TO SECOND(6)', -104, 'BINARY_FLOAT', 100, 'BINARY_DOUBLE', 101, 'XMLTYPE', 2009, 1111) AS data_type, DECODE( CHAR_USED, 'C',CHAR_LENGTH, DATA_LENGTH ) as DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, COLUMN_ID as ORDINAL_POSITION, DEFAULT_LENGTH, DATA_DEFAULT, NUM_BUCKETS, CHARACTER_SET_NAME, CHAR_COL_DECL_LENGTH, CHAR_LENGTH, CHAR_USED, VIRTUAL_COLUMN ";
                if (collectIdentityData) {
                    sql = sql + ", DEFAULT_ON_NULL, IDENTITY_COLUMN, ic.GENERATION_TYPE ";
                }

                sql = sql + "FROM ALL_TAB_COLS c JOIN ALL_COL_COMMENTS cc USING ( OWNER, TABLE_NAME, COLUMN_NAME ) ";
                if (collectIdentityData) {
                    sql = sql + "LEFT JOIN ALL_TAB_IDENTITY_COLS ic USING (OWNER, TABLE_NAME, COLUMN_NAME ) ";
                }

                if (bulk && JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() != null) {
                    sql = sql + "WHERE OWNER IN ('" + jdbcSchemaName + "', " + JdbcDatabaseSnapshot.this.getAllCatalogsStringScratchData() + ")";
                } else {
                    sql = sql + "WHERE OWNER='" + jdbcSchemaName + "'";
                }

                if (!bulk) {
                    if (this.tableName != null) {
                        sql = sql + " AND TABLE_NAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.tableName) + "'";
                    }

                    if (this.columnName != null) {
                        sql = sql + " AND COLUMN_NAME='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.columnName) + "'";
                    }
                }

                sql = sql + " AND " + ((OracleDatabase)CachingDatabaseMetaData.this.database).getSystemTableWhereClause("TABLE_NAME");
                sql = sql + " ORDER BY OWNER, TABLE_NAME, c.COLUMN_ID";
                return this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
            }

            protected List<CachedRow> mssqlQuery(boolean bulk) throws DatabaseException, SQLException {
                CatalogAndSchema catalogAndSchema = (new CatalogAndSchema(this.catalogName, this.schemaName)).customize(CachingDatabaseMetaData.this.database);
                String databaseName = StringUtils.trimToNull(CachingDatabaseMetaData.this.database.correctObjectName(catalogAndSchema.getCatalogName(), Catalog.class));
                String dbIdParam;
                String databasePrefix;
                if (databaseName == null) {
                    databasePrefix = "";
                    dbIdParam = "";
                } else {
                    dbIdParam = ", db_id('" + databaseName + "')";
                    databasePrefix = "[" + databaseName + "].";
                }

                String sql = "select db_name(" + (databaseName == null ? "" : "db_id('" + databaseName + "')") + ") AS TABLE_CAT, object_schema_name(c.object_id" + dbIdParam + ") AS TABLE_SCHEM, object_name(c.object_id" + dbIdParam + ") AS TABLE_NAME, c.name AS COLUMN_NAME, is_filestream, is_rowguidcol, CASE WHEN c.is_identity = 'true' THEN 'YES' ELSE 'NO' END as IS_AUTOINCREMENT, {REMARKS_COLUMN_PLACEHOLDER}t.name AS TYPE_NAME, dc.name as COLUMN_DEF_NAME, dc.definition as COLUMN_DEF, CASE t.name WHEN 'bigint' THEN " + -5 + " WHEN 'binary' THEN " + -2 + " WHEN 'bit' THEN " + -7 + " WHEN 'char' THEN " + 1 + " WHEN 'date' THEN " + 91 + " WHEN 'datetime' THEN " + 93 + " WHEN 'datetime2' THEN " + 93 + " WHEN 'datetimeoffset' THEN -155 WHEN 'decimal' THEN " + 3 + " WHEN 'float' THEN " + 8 + " WHEN 'image' THEN " + -4 + " WHEN 'int' THEN " + 4 + " WHEN 'money' THEN " + 3 + " WHEN 'nchar' THEN " + -15 + " WHEN 'ntext' THEN " + -16 + " WHEN 'numeric' THEN " + 2 + " WHEN 'nvarchar' THEN " + -9 + " WHEN 'real' THEN " + 7 + " WHEN 'smalldatetime' THEN " + 93 + " WHEN 'smallint' THEN " + 5 + " WHEN 'smallmoney' THEN " + 3 + " WHEN 'text' THEN " + -1 + " WHEN 'time' THEN " + 92 + " WHEN 'timestamp' THEN " + -2 + " WHEN 'tinyint' THEN " + -6 + " WHEN 'udt' THEN " + -3 + " WHEN 'uniqueidentifier' THEN " + 1 + " WHEN 'varbinary' THEN " + -3 + " WHEN 'varbinary(max)' THEN " + -3 + " WHEN 'varchar' THEN " + 12 + " WHEN 'varchar(max)' THEN " + 12 + " WHEN 'xml' THEN " + -1 + " WHEN 'LONGNVARCHAR' THEN " + 2009 + " ELSE " + 1111 + " END AS data_type, CASE WHEN c.is_nullable = 'true' THEN 1 ELSE 0 END AS NULLABLE, 10 as NUM_PREC_RADIX, c.column_id as ORDINAL_POSITION, c.scale as DECIMAL_DIGITS, c.max_length as COLUMN_SIZE, c.precision as DATA_PRECISION FROM " + databasePrefix + "sys.columns c inner join " + databasePrefix + "sys.types t on c.user_type_id=t.user_type_id {REMARKS_JOIN_PLACEHOLDER}left outer join " + databasePrefix + "sys.default_constraints dc on dc.parent_column_id = c.column_id AND dc.parent_object_id=c.object_id AND type_desc='DEFAULT_CONSTRAINT' WHERE object_schema_name(c.object_id" + dbIdParam + ")='" + ((AbstractJdbcDatabase)CachingDatabaseMetaData.this.database).getJdbcSchemaName(catalogAndSchema) + "'";
                if (!bulk) {
                    if (this.tableName != null) {
                        sql = sql + " and object_name(c.object_id" + dbIdParam + ")='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.tableName) + "'";
                    }

                    if (this.columnName != null) {
                        sql = sql + " and c.name='" + CachingDatabaseMetaData.this.database.escapeStringForDatabase(this.columnName) + "'";
                    }
                }

                sql = sql + "order by object_schema_name(c.object_id" + dbIdParam + "), object_name(c.object_id" + dbIdParam + "), c.column_id";
                if (((MSSQLDatabase)CachingDatabaseMetaData.this.database).isAzureDb() && CachingDatabaseMetaData.this.database.getDatabaseMajorVersion() < 12) {
                    sql = sql.replace("{REMARKS_COLUMN_PLACEHOLDER}", "");
                    sql = sql.replace("{REMARKS_JOIN_PLACEHOLDER}", "");
                } else {
                    sql = sql.replace("{REMARKS_COLUMN_PLACEHOLDER}", "CAST([ep].[value] AS [nvarchar](MAX)) AS [REMARKS], ");
                    sql = sql.replace("{REMARKS_JOIN_PLACEHOLDER}", "left outer join " + databasePrefix + "[sys].[extended_properties] AS [ep] ON [ep].[class] = 1 AND [ep].[major_id] = c.object_id AND [ep].[minor_id] = column_id AND [ep].[name] = 'MS_Description' ");
                }

                List<CachedRow> rows = this.executeAndExtract(sql, CachingDatabaseMetaData.this.database);
                Iterator var8 = rows.iterator();

                while(true) {
                    while(var8.hasNext()) {
                        CachedRow row = (CachedRow)var8.next();
                        String typeName = row.getString("TYPE_NAME");
                        if (!"nvarchar".equals(typeName) && !"nchar".equals(typeName)) {
                            if (row.getInt("DATA_PRECISION") != null && row.getInt("DATA_PRECISION") > 0) {
                                row.set("COLUMN_SIZE", row.getInt("DATA_PRECISION"));
                            }
                        } else {
                            Integer size = row.getInt("COLUMN_SIZE");
                            if (size > 0) {
                                row.set("COLUMN_SIZE", size / 2);
                            }
                        }
                    }

                    return rows;
                }
            }

            protected List<CachedRow> extract(ResultSet resultSet, boolean informixIndexTrimHint) throws SQLException {
                List<CachedRow> rows = super.extract(resultSet, informixIndexTrimHint);
                if (CachingDatabaseMetaData.this.database instanceof MSSQLDatabase && !JdbcDatabaseSnapshot.this.userDefinedTypes.isEmpty()) {
                    Iterator var4 = rows.iterator();

                    while(var4.hasNext()) {
                        CachedRow row = (CachedRow)var4.next();
                        String dataType = (String)row.get("TYPE_NAME");
                        if (JdbcDatabaseSnapshot.this.userDefinedTypes.contains(dataType.toLowerCase())) {
                            row.set("COLUMN_SIZE", (Object)null);
                            row.set("DECIMAL_DIGITS ", (Object)null);
                        }
                    }
                }

                return rows;
            }
        }
    }
}

GetViewDefinitionGeneratorDM
package liquibase.sqlgenerator.core;

import liquibase.CatalogAndSchema;
import liquibase.database.Database;
import liquibase.database.core.DM8Database;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.GetViewDefinitionStatement;

public class GetViewDefinitionGeneratorDM extends GetViewDefinitionGenerator {
    @Override
    public int getPriority() {
        return PRIORITY_DATABASE;
    }

    @Override
    public boolean supports(GetViewDefinitionStatement statement, Database database) {
        return database instanceof DM8Database;
    }

    @Override
    public Sql[] generateSql(GetViewDefinitionStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
        CatalogAndSchema schema = new CatalogAndSchema(statement.getCatalogName(), statement.getSchemaName()).customize(database);

        return new Sql[]{
                new UnparsedSql("SELECT TEXT FROM ALL_VIEWS WHERE upper(VIEW_NAME)='" + statement.getViewName().toUpperCase() + "' AND OWNER='" + schema.getSchemaName() + "'")
        };
    }
}

DmDialect
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.dialect;

import org.hibernate.JDBCException;
import org.hibernate.QueryTimeoutException;
import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.procedure.internal.StandardCallableStatementSupport;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Locale;

/**
 * A dialect for Oracle 8i.
 *
 * @author Steve Ebersole
 */
@SuppressWarnings("deprecation")
public class DmDialect extends Dialect {

    private static final AbstractLimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
        @Override
        public String processSql(String sql, RowSelection selection) {
            final boolean hasOffset = LimitHelper.hasFirstRow( selection );
            sql = sql.trim();
            boolean isForUpdate = false;
            if (sql.toLowerCase(Locale.ROOT).endsWith( " for update" )) {
                sql = sql.substring( 0, sql.length() - 11 );
                isForUpdate = true;
            }

            final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
            if (hasOffset) {
                pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
            }
            else {
                pagingSelect.append( "select * from ( " );
            }
            pagingSelect.append( sql );
            if (hasOffset) {
                pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
            }
            else {
                pagingSelect.append( " ) where rownum <= ?" );
            }

            if (isForUpdate) {
                pagingSelect.append( " for update" );
            }

            return pagingSelect.toString();
        }

        @Override
        public boolean supportsLimit() {
            return true;
        }

        @Override
        public boolean bindLimitParametersInReverseOrder() {
            return true;
        }

        @Override
        public boolean useMaxForLimit() {
            return true;
        }
    };

    private static final int PARAM_LIST_SIZE_LIMIT = 1000;

    /**
     * Constructs a Oracle8iDialect
     */
    public DmDialect() {
        super();
        registerCharacterTypeMappings();
        registerNumericTypeMappings();
        registerDateTimeTypeMappings();
        registerLargeObjectTypeMappings();
        registerReverseHibernateTypeMappings();
        registerFunctions();
        registerDefaultProperties();
    }

    protected void registerCharacterTypeMappings() {
        registerColumnType( Types.CHAR, "char(1)" );
        registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
        registerColumnType( Types.VARCHAR, "long" );
    }

    protected void registerNumericTypeMappings() {
        registerColumnType( Types.BIT, "number(1,0)" );
        registerColumnType( Types.BIGINT, "number(19,0)" );
        registerColumnType( Types.SMALLINT, "number(5,0)" );
        registerColumnType( Types.TINYINT, "number(3,0)" );
        registerColumnType( Types.INTEGER, "number(10,0)" );

        registerColumnType( Types.FLOAT, "float" );
        registerColumnType( Types.DOUBLE, "double precision" );
        registerColumnType( Types.NUMERIC, "number($p,$s)" );
        registerColumnType( Types.DECIMAL, "number($p,$s)" );

        registerColumnType( Types.BOOLEAN, "number(1,0)" );
    }

    protected void registerDateTimeTypeMappings() {
        registerColumnType( Types.DATE, "date" );
        registerColumnType( Types.TIME, "date" );
        registerColumnType( Types.TIMESTAMP, "date" );
    }

    protected void registerLargeObjectTypeMappings() {
        registerColumnType( Types.BINARY, 2000, "raw($l)" );
        registerColumnType( Types.BINARY, "long raw" );

        registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
        registerColumnType( Types.VARBINARY, "long raw" );

        registerColumnType( Types.BLOB, "blob" );
        registerColumnType( Types.CLOB, "clob" );

        registerColumnType( Types.LONGVARCHAR, "long" );
        registerColumnType( Types.LONGVARBINARY, "long raw" );
    }

    protected void registerReverseHibernateTypeMappings() {
    }

    protected void registerFunctions() {
        registerFunction( "abs", new StandardSQLFunction("abs") );
        registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );

        registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
        registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
        registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
        registerFunction( "bitand", new StandardSQLFunction("bitand") );
        registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
        registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
        registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
        registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
        registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
        registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
        registerFunction( "stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE) );
        registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
        registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
        registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
        registerFunction( "variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE) );

        registerFunction( "round", new StandardSQLFunction("round") );
        registerFunction( "trunc", new StandardSQLFunction("trunc") );
        registerFunction( "ceil", new StandardSQLFunction("ceil") );
        registerFunction( "floor", new StandardSQLFunction("floor") );

        registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) );
        registerFunction( "initcap", new StandardSQLFunction("initcap") );
        registerFunction( "lower", new StandardSQLFunction("lower") );
        registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
        registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
        registerFunction( "soundex", new StandardSQLFunction("soundex") );
        registerFunction( "upper", new StandardSQLFunction("upper") );
        registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );

        registerFunction( "to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
        registerFunction( "to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP) );

        registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
        registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) );
        registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );

        registerFunction( "last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
        registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) );
        registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) );
        registerFunction( "uid", new NoArgSQLFunction("uid", StandardBasicTypes.INTEGER, false) );
        registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );

        registerFunction( "rowid", new NoArgSQLFunction("rowid", StandardBasicTypes.LONG, false) );
        registerFunction( "rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) );

        // Multi-param string dialect functions...
        registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") );
        registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) );
        registerFunction( "instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) );
        registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
        registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
        registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
        registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
        registerFunction( "substrb", new StandardSQLFunction("substrb", StandardBasicTypes.STRING) );
        registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );

        registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
        registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) );
        registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "vsize(?1)*8" ) );
        registerFunction( "coalesce", new NvlFunction() );

        // Multi-param numeric dialect functions...
        registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.FLOAT) );
        registerFunction( "log", new StandardSQLFunction("log", StandardBasicTypes.INTEGER) );
        registerFunction( "mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER) );
        registerFunction( "nvl", new StandardSQLFunction("nvl") );
        registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
        registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.FLOAT) );

        // Multi-param date dialect functions...
        registerFunction( "add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) );
        registerFunction( "months_between", new StandardSQLFunction("months_between", StandardBasicTypes.FLOAT) );
        registerFunction( "next_day", new StandardSQLFunction("next_day", StandardBasicTypes.DATE) );

        registerFunction( "str", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
    }

    protected void registerDefaultProperties() {
        getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
        getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
        // Oracle driver reports to support getGeneratedKeys(), but they only
        // support the version taking an array of the names of the columns to
        // be returned (via its RETURNING clause).  No other driver seems to
        // support this overloaded version.
        getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
        getDefaultProperties().setProperty( Environment.BATCH_VERSIONED_DATA, "false" );
    }

    @Override
    protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
        return sqlCode == Types.BOOLEAN ? BitTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode );
    }


    // features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~

    @Override
    public JoinFragment createOuterJoinFragment() {
        return new OracleJoinFragment();
    }

    @Override
    public String getCrossJoinSeparator() {
        return ", ";
    }

    /**
     * Map case support to the Oracle DECODE function.  Oracle did not
     * add support for CASE until 9i.
     * <p/>
     * {@inheritDoc}
     */
    @Override
    public CaseFragment createCaseFragment() {
        return new DecodeCaseFragment();
    }

    @Override
    public LimitHandler getLimitHandler() {
        return LIMIT_HANDLER;
    }

    @Override
    public String getLimitString(String sql, boolean hasOffset) {
        sql = sql.trim();
        boolean isForUpdate = false;
        if ( sql.toLowerCase(Locale.ROOT).endsWith( " for update" ) ) {
            sql = sql.substring( 0, sql.length()-11 );
            isForUpdate = true;
        }

        final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
        if (hasOffset) {
            pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
        }
        else {
            pagingSelect.append( "select * from ( " );
        }
        pagingSelect.append( sql );
        if (hasOffset) {
            pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
        }
        else {
            pagingSelect.append( " ) where rownum <= ?" );
        }

        if ( isForUpdate ) {
            pagingSelect.append( " for update" );
        }

        return pagingSelect.toString();
    }

    /**
     * Allows access to the basic {@link Dialect#getSelectClauseNullString}
     * implementation...
     *
     * @param sqlType The {@link java.sql.Types} mapping type code
     * @return The appropriate select cluse fragment
     */
    public String getBasicSelectClauseNullString(int sqlType) {
        return super.getSelectClauseNullString( sqlType );
    }

    @Override
    public String getSelectClauseNullString(int sqlType) {
        switch(sqlType) {
            case Types.VARCHAR:
            case Types.CHAR:
                return "to_char(null)";
            case Types.DATE:
            case Types.TIMESTAMP:
            case Types.TIME:
                return "to_date(null)";
            default:
                return "to_number(null)";
        }
    }

    @Override
    public String getCurrentTimestampSelectString() {
        return "select sysdate from dual";
    }

    @Override
    public String getCurrentTimestampSQLFunctionName() {
        return "sysdate";
    }


    // features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~

    @Override
    public String getAddColumnString() {
        return "add";
    }

    @Override
    public String getSequenceNextValString(String sequenceName) {
        return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
    }

    @Override
    public String getSelectSequenceNextValString(String sequenceName) {
        return sequenceName + ".nextval";
    }

    @Override
    public String getCreateSequenceString(String sequenceName) {
        //starts with 1, implicitly
        return "create sequence " + sequenceName;
    }

    @Override
    public String getDropSequenceString(String sequenceName) {
        return "drop sequence " + sequenceName;
    }

    @Override
    public String getCascadeConstraintsString() {
        return " cascade constraints";
    }

    @Override
    public boolean dropConstraints() {
        return false;
    }

    @Override
    public String getForUpdateNowaitString() {
        return " for update nowait";
    }

    @Override
    public boolean supportsSequences() {
        return true;
    }

    @Override
    public boolean supportsPooledSequences() {
        return true;
    }

    @Override
    public boolean supportsLimit() {
        return true;
    }

    @Override
    public String getForUpdateString(String aliases) {
        return getForUpdateString() + " of " + aliases;
    }

    @Override
    public String getForUpdateNowaitString(String aliases) {
        return getForUpdateString() + " of " + aliases + " nowait";
    }

    @Override
    public boolean bindLimitParametersInReverseOrder() {
        return true;
    }

    @Override
    public boolean useMaxForLimit() {
        return true;
    }

    @Override
    public boolean forUpdateOfColumns() {
        return true;
    }

    @Override
    public String getQuerySequencesString() {
        return    " select sequence_name from all_sequences"
                + "  union"
                + " select synonym_name"
                + "   from all_synonyms us, all_sequences asq"
                + "  where asq.sequence_name = us.table_name"
                + "    and asq.sequence_owner = us.table_owner";
    }

    @Override
    public String getSelectGUIDString() {
        return "select rawtohex(sys_guid()) from dual";
    }

    @Override
    public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
        return EXTRACTER;
    }

    private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {

        /**
         * Extract the name of the violated constraint from the given SQLException.
         *
         * @param sqle The exception that was the result of the constraint violation.
         * @return The extracted constraint name.
         */
        @Override
        protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
            final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
            if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
                return extractUsingTemplate( "(", ")", sqle.getMessage() );
            }
            else if ( errorCode == 1400 ) {
                // simple nullability constraint
                return null;
            }
            else {
                return null;
            }
        }

    };

    @Override
    public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
        return new SQLExceptionConversionDelegate() {
            @Override
            public JDBCException convert(SQLException sqlException, String message, String sql) {
                // interpreting Oracle exceptions is much much more precise based on their specific vendor codes.

                final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );


                // lock timeouts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                if ( errorCode == 30006 ) {
                    // ORA-30006: resource busy; acquire with WAIT timeout expired
                    throw new LockTimeoutException( message, sqlException, sql );
                }
                else if ( errorCode == 54 ) {
                    // ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
                    throw new LockTimeoutException( message, sqlException, sql );
                }
                else if ( 4021 == errorCode ) {
                    // ORA-04021 timeout occurred while waiting to lock object
                    throw new LockTimeoutException( message, sqlException, sql );
                }


                // deadlocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                if ( 60 == errorCode ) {
                    // ORA-00060: deadlock detected while waiting for resource
                    return new LockAcquisitionException( message, sqlException, sql );
                }
                else if ( 4020 == errorCode ) {
                    // ORA-04020 deadlock detected while trying to lock object
                    return new LockAcquisitionException( message, sqlException, sql );
                }


                // query cancelled ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                if ( 1013 == errorCode ) {
                    // ORA-01013: user requested cancel of current operation
                    throw new QueryTimeoutException(  message, sqlException, sql );
                }


                // data integrity violation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                if ( 1407 == errorCode ) {
                    // ORA-01407: cannot update column to NULL
                    final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException );
                    return new ConstraintViolationException( message, sqlException, sql, constraintName );
                }

                return null;
            }
        };
    }

    @Override
    public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
        //	register the type of the out param - an Oracle specific type
        statement.registerOutParameter( col, OracleTypesHelper.INSTANCE.getOracleCursorTypeSqlType() );
        col++;
        return col;
    }

    @Override
    public ResultSet getResultSet(CallableStatement ps) throws SQLException {
        ps.execute();
        return (ResultSet) ps.getObject( 1 );
    }

    @Override
    public boolean supportsUnionAll() {
        return true;
    }

    @Override
    public boolean supportsCommentOn() {
        return true;
    }

    @Override
    public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
        return new GlobalTemporaryTableBulkIdStrategy(
                new IdTableSupportStandardImpl() {
                    @Override
                    public String generateIdTableName(String baseName) {
                        final String name = super.generateIdTableName( baseName );
                        return name.length() > 30 ? name.substring( 0, 30 ) : name;
                    }

                    @Override
                    public String getCreateIdTableCommand() {
                        return "create global temporary table";
                    }

                    @Override
                    public String getCreateIdTableStatementOptions() {
                        return "on commit delete rows";
                    }
                },
                AfterUseAction.CLEAN
        );
    }

    @Override
    public boolean supportsCurrentTimestampSelection() {
        return true;
    }

    @Override
    public boolean isCurrentTimestampSelectStringCallable() {
        return false;
    }

    @Override
    public boolean supportsEmptyInList() {
        return false;
    }

    @Override
    public boolean supportsExistsInSelect() {
        return false;
    }

    @Override
    public int getInExpressionCountLimit() {
        return PARAM_LIST_SIZE_LIMIT;
    }

    @Override
    public boolean forceLobAsLastValue() {
        return true;
    }

    @Override
    public boolean useFollowOnLocking() {
        return true;
    }

    @Override
    public String getNotExpression( String expression ) {
        return "not (" + expression + ")";
    }

    @Override
    public String getQueryHintString(String sql, List<String> hints) {
        final String hint = StringHelper.join( ", ", hints.iterator() );

        if ( StringHelper.isEmpty( hint ) ) {
            return sql;
        }

        final int pos = sql.indexOf( "select" );
        if ( pos > -1 ) {
            final StringBuilder buffer = new StringBuilder( sql.length() + hint.length() + 8 );
            if ( pos > 0 ) {
                buffer.append( sql.substring( 0, pos ) );
            }
            buffer.append( "select /*+ " ).append( hint ).append( " */" )
                    .append( sql.substring( pos + "select".length() ) );
            sql = buffer.toString();
        }

        return sql;
    }

    @Override
    public int getMaxAliasLength() {
        // Oracle's max identifier length is 30, but Hibernate needs to add "uniqueing info" so we account for that,
        return 20;
    }

    @Override
    public CallableStatementSupport getCallableStatementSupport() {
        // Oracle supports returning cursors
        return StandardCallableStatementSupport.REF_CURSOR_INSTANCE;
    }

    @Override
    public boolean canCreateSchema() {
        return false;
    }
}

liquibase.Database.database
liquibase.database.core.CockroachDatabase
liquibase.database.core.DB2Database
liquibase.database.core.Db2zDatabase
liquibase.database.core.DerbyDatabase
liquibase.database.core.Firebird3Database
liquibase.database.core.FirebirdDatabase
liquibase.database.core.H2Database
liquibase.database.core.HsqlDatabase
liquibase.database.core.InformixDatabase
liquibase.database.core.Ingres9Database
liquibase.database.core.MSSQLDatabase
liquibase.database.core.MariaDBDatabase
liquibase.database.core.MockDatabase
liquibase.database.core.MySQLDatabase
liquibase.database.core.OracleDatabase
liquibase.database.core.PostgresDatabase
liquibase.database.core.SQLiteDatabase
liquibase.database.core.SybaseASADatabase
liquibase.database.core.SybaseDatabase
liquibase.database.core.DM8Database
liquibase.database.core.UnsupportedDatabase

获取最新达梦jar包
        <dependency>
            <groupId>com.dameng</groupId>
            <artifactId>DmJdbcDriver18</artifactId>
            <version>8.1.2.94</version>
        </dependency>
        <dependency>
            <groupId>com.dameng</groupId>
            <artifactId>DmDialect-for-hibernate5.0</artifactId>
            <version>8.1.1.49</version>
        </dependency>
JDBC配置

&compatibleMode=oracle 配置兼容Oracle方式加载,在启动时候会报关于oracle不支持的错误

spring:
  datasource:
    druid:
      url: jdbc:dm://ip:5236/DAMENG1?schema=database&compatibleMode=oracle
      username: user
      password: pwd
      driver-class-name: dm.jdbc.driver.DmDriver
      filters: stat,log4j
      pool-prepared-statements: true
      max-open-prepared-statements: 100
      max-active: 20
      remove-abandoned: true
      remove-abandoned-timeout: 1800
      log-abandoned: true
      db-type: mysql
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.DmDialect
liquibase:
  enabled: false
  change-log: classpath:/db/db.changelog-master.xml
后经验证发现,该几个类可以不用添加

在这里插入图片描述

修改公司内部类创建表逻辑

在这里插入图片描述

自己内部保存,方便查找
要在达梦数据库v8中创建表,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了达梦数据库v8,并按照安装文档完成了安装和配置。 2. 使用数据库管理工具或命令行连接到达梦数据库。 3. 创建一个表空间来存储您的表。您可以使用以下命令创建一个名为"TEST"的表空间: ```sql create tablespace "TEST" datafile '/home/dmdba/dmdbms/data/DMOA/TEST.DBF' size 20240 autoextend on next 1 CACHE = NORMAL; ``` 这将创建一个名为"TEST"的表空间,并指定了数据文件的路径和大小。您可以根据需要进行调整。 4. 在您选择的表空间中创建表。您可以使用常规的SQL创建表的语法来创建表,例如: ```sql create table 表名 ( 列名1 数据类型1, 列名2 数据类型2, ... ); ``` 您可以根据需要定义表的列和数据类型。 请注意,以上步骤仅涵盖了创建表的基本过程。在实际使用达梦数据库v8时,您可能需要考虑其他因素,如表的约束、索引等。您可以参考达梦数据库v8的文档或使用在线文档来了解更多详细信息和操作指南。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [linux安装达梦数据库v8](https://blog.csdn.net/OceanWaves1993/article/details/129936878)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [达梦数据库v8,创建表空间、用户命令语句](https://blog.csdn.net/zhangbest2009/article/details/122146801)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值