Search in sources :

Example 41 with FileStore

use of org.h2.mvstore.FileStore in project SpringStudy by myounghaklee.

the class TestMVStore method testFileHeaderCorruption.

private void testFileHeaderCorruption() throws Exception {
    String fileName = getBaseDir() + "/" + getTestName();
    FileUtils.delete(fileName);
    MVStore.Builder builder = new MVStore.Builder().fileName(fileName).pageSplitSize(1000).autoCommitDisabled();
    try (MVStore s = builder.open()) {
        s.setRetentionTime(0);
        MVMap<Integer, byte[]> map = s.openMap("test");
        map.put(0, new byte[100]);
        for (int i = 0; i < 10; i++) {
            map = s.openMap("test" + i);
            map.put(0, new byte[1000]);
            s.commit();
        }
        FileStore fs = s.getFileStore();
        long size = fs.getFile().size();
        for (int i = 0; i < 100; i++) {
            map = s.openMap("test" + i);
            s.removeMap(map);
            s.commit();
            s.compact(100, 1);
            if (fs.getFile().size() <= size) {
                break;
            }
        }
        // the last chunk is at the end
        s.setReuseSpace(false);
        map = s.openMap("test2");
        map.put(1, new byte[1000]);
    }
    FilePath f = FilePath.get(fileName);
    int blockSize = 4 * 1024;
    // test corrupt file headers
    for (int i = 0; i <= blockSize; i += blockSize) {
        try (FileChannel fc = f.open("rw")) {
            if (i == 0) {
                // corrupt the last block (the end header)
                fc.write(ByteBuffer.allocate(256), fc.size() - 256);
            }
            ByteBuffer buff = ByteBuffer.allocate(4 * 1024);
            fc.read(buff, i);
            String h = new String(buff.array(), StandardCharsets.UTF_8).trim();
            int idx = h.indexOf("fletcher:");
            int old = Character.digit(h.charAt(idx + "fletcher:".length()), 16);
            int bad = (old + 1) & 15;
            buff.put(idx + "fletcher:".length(), (byte) Character.forDigit(bad, 16));
            // note that headers may be overwritten upon successfull opening
            for (int b = 0; b <= i; b += blockSize) {
                buff.rewind();
                fc.write(buff, b);
            }
        }
        if (i == 0) {
            // header should be used
            try (MVStore s = openStore(fileName)) {
                MVMap<Integer, byte[]> map = s.openMap("test");
                assertEquals(100, map.get(0).length);
                map = s.openMap("test2");
                assertFalse(map.containsKey(1));
            }
        } else {
            // both headers are corrupt
            assertThrows(Exception.class, () -> openStore(fileName));
        }
    }
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FilePath(org.h2.store.fs.FilePath) FileStore(org.h2.mvstore.FileStore) FileChannel(java.nio.channels.FileChannel) ByteBuffer(java.nio.ByteBuffer)

Example 42 with FileStore

use of org.h2.mvstore.FileStore in project SpringStudy by myounghaklee.

the class Store method statisticsStart.

/**
 * Start collecting statistics.
 */
public void statisticsStart() {
    FileStore fs = mvStore.getFileStore();
    statisticsStart = fs == null ? 0 : fs.getReadCount();
}
Also used : FileStore(org.h2.mvstore.FileStore)

Example 43 with FileStore

use of org.h2.mvstore.FileStore in project SpringStudy by myounghaklee.

the class InformationSchemaTableLegacy method generateRows.

@Override
public ArrayList<Row> generateRows(SessionLocal session, SearchRow first, SearchRow last) {
    Value indexFrom = null, indexTo = null;
    if (indexColumn >= 0) {
        if (first != null) {
            indexFrom = first.getValue(indexColumn);
        }
        if (last != null) {
            indexTo = last.getValue(indexColumn);
        }
    }
    ArrayList<Row> rows = Utils.newSmallArrayList();
    String catalog = database.getShortName();
    boolean admin = session.getUser().isAdmin();
    switch(type) {
        case TABLES:
            {
                for (Table table : getAllTables(session)) {
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    if (hideTable(table, session)) {
                        continue;
                    }
                    String storageType;
                    if (table.isTemporary()) {
                        if (table.isGlobalTemporary()) {
                            storageType = "GLOBAL TEMPORARY";
                        } else {
                            storageType = "LOCAL TEMPORARY";
                        }
                    } else {
                        storageType = table.isPersistIndexes() ? "CACHED" : "MEMORY";
                    }
                    String sql = table.getCreateSQL();
                    if (!admin) {
                        if (sql != null && sql.contains(DbException.HIDE_SQL)) {
                            // hide the password of linked tables
                            sql = "-";
                        }
                    }
                    add(session, rows, // TABLE_CATALOG
                    catalog, // TABLE_SCHEMA
                    table.getSchema().getName(), // TABLE_NAME
                    tableName, // TABLE_TYPE
                    table.getTableType().toString(), // STORAGE_TYPE
                    storageType, // SQL
                    sql, // REMARKS
                    replaceNullWithEmpty(table.getComment()), // LAST_MODIFICATION
                    ValueBigint.get(table.getMaxDataModificationId()), // ID
                    ValueInteger.get(table.getId()), // TYPE_NAME
                    null, // TABLE_CLASS
                    table.getClass().getName(), // ROW_COUNT_ESTIMATE
                    ValueBigint.get(table.getRowCountApproximation(session)));
                }
                break;
            }
        case COLUMNS:
            {
                // reduce the number of tables to scan - makes some metadata queries
                // 10x faster
                final ArrayList<Table> tablesToList;
                if (indexFrom != null && indexFrom.equals(indexTo)) {
                    String tableName = indexFrom.getString();
                    if (tableName == null) {
                        break;
                    }
                    tablesToList = getTablesByName(session, tableName);
                } else {
                    tablesToList = getAllTables(session);
                }
                for (Table table : tablesToList) {
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    if (hideTable(table, session)) {
                        continue;
                    }
                    Column[] cols = table.getColumns();
                    String collation = database.getCompareMode().getName();
                    for (int j = 0; j < cols.length; j++) {
                        Column c = cols[j];
                        Domain domain = c.getDomain();
                        TypeInfo typeInfo = c.getType();
                        ValueInteger precision = ValueInteger.get(MathUtils.convertLongToInt(typeInfo.getPrecision()));
                        ValueInteger scale = ValueInteger.get(typeInfo.getScale());
                        Sequence sequence = c.getSequence();
                        boolean hasDateTimePrecision;
                        int type = typeInfo.getValueType();
                        switch(type) {
                            case Value.TIME:
                            case Value.TIME_TZ:
                            case Value.DATE:
                            case Value.TIMESTAMP:
                            case Value.TIMESTAMP_TZ:
                            case Value.INTERVAL_SECOND:
                            case Value.INTERVAL_DAY_TO_SECOND:
                            case Value.INTERVAL_HOUR_TO_SECOND:
                            case Value.INTERVAL_MINUTE_TO_SECOND:
                                hasDateTimePrecision = true;
                                break;
                            default:
                                hasDateTimePrecision = false;
                        }
                        boolean isGenerated = c.isGenerated();
                        boolean isInterval = DataType.isIntervalType(type);
                        String createSQLWithoutName = c.getCreateSQLWithoutName();
                        add(session, rows, // TABLE_CATALOG
                        catalog, // TABLE_SCHEMA
                        table.getSchema().getName(), // TABLE_NAME
                        tableName, // COLUMN_NAME
                        c.getName(), // ORDINAL_POSITION
                        ValueInteger.get(j + 1), // COLUMN_DEFAULT
                        isGenerated ? null : c.getDefaultSQL(), // IS_NULLABLE
                        c.isNullable() ? "YES" : "NO", // DATA_TYPE
                        ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)), // CHARACTER_MAXIMUM_LENGTH
                        precision, // CHARACTER_OCTET_LENGTH
                        precision, // NUMERIC_PRECISION
                        precision, // NUMERIC_PRECISION_RADIX
                        ValueInteger.get(10), // NUMERIC_SCALE
                        scale, // DATETIME_PRECISION
                        hasDateTimePrecision ? scale : null, // INTERVAL_TYPE
                        isInterval ? createSQLWithoutName.substring(9) : null, // INTERVAL_PRECISION
                        isInterval ? precision : null, // CHARACTER_SET_NAME
                        CHARACTER_SET_NAME, // COLLATION_NAME
                        collation, // DOMAIN_CATALOG
                        domain != null ? catalog : null, // DOMAIN_SCHEMA
                        domain != null ? domain.getSchema().getName() : null, // DOMAIN_NAME
                        domain != null ? domain.getName() : null, // IS_GENERATED
                        isGenerated ? "ALWAYS" : "NEVER", // GENERATION_EXPRESSION
                        isGenerated ? c.getDefaultSQL() : null, // TYPE_NAME
                        identifier(isInterval ? "INTERVAL" : typeInfo.getDeclaredTypeName()), // NULLABLE
                        ValueInteger.get(c.isNullable() ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls), // IS_COMPUTED
                        ValueBoolean.get(isGenerated), // SELECTIVITY
                        ValueInteger.get(c.getSelectivity()), // SEQUENCE_NAME
                        sequence == null ? null : sequence.getName(), // REMARKS
                        replaceNullWithEmpty(c.getComment()), // SMALLINT
                        null, // COLUMN_TYPE
                        createSQLWithoutName, // COLUMN_ON_UPDATE
                        c.getOnUpdateSQL(), // IS_VISIBLE
                        ValueBoolean.get(c.getVisible()), // CHECK_CONSTRAINT
                        null);
                    }
                }
                break;
            }
        case INDEXES:
            {
                // reduce the number of tables to scan - makes some metadata queries
                // 10x faster
                final ArrayList<Table> tablesToList;
                if (indexFrom != null && indexFrom.equals(indexTo)) {
                    String tableName = indexFrom.getString();
                    if (tableName == null) {
                        break;
                    }
                    tablesToList = getTablesByName(session, tableName);
                } else {
                    tablesToList = getAllTables(session);
                }
                for (Table table : tablesToList) {
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    if (hideTable(table, session)) {
                        continue;
                    }
                    ArrayList<Index> indexes = table.getIndexes();
                    ArrayList<Constraint> constraints = table.getConstraints();
                    for (int j = 0; indexes != null && j < indexes.size(); j++) {
                        Index index = indexes.get(j);
                        if (index.getCreateSQL() == null) {
                            continue;
                        }
                        String constraintName = null;
                        for (int k = 0; constraints != null && k < constraints.size(); k++) {
                            Constraint constraint = constraints.get(k);
                            if (constraint.usesIndex(index)) {
                                if (index.getIndexType().isPrimaryKey()) {
                                    if (constraint.getConstraintType() == Constraint.Type.PRIMARY_KEY) {
                                        constraintName = constraint.getName();
                                    }
                                } else {
                                    constraintName = constraint.getName();
                                }
                            }
                        }
                        IndexColumn[] cols = index.getIndexColumns();
                        int uniqueColumnCount = index.getUniqueColumnCount();
                        String indexClass = index.getClass().getName();
                        for (int k = 0; k < cols.length; k++) {
                            IndexColumn idxCol = cols[k];
                            Column column = idxCol.column;
                            add(session, rows, // TABLE_CATALOG
                            catalog, // TABLE_SCHEMA
                            table.getSchema().getName(), // TABLE_NAME
                            tableName, // NON_UNIQUE
                            ValueBoolean.get(k >= uniqueColumnCount), // INDEX_NAME
                            index.getName(), // ORDINAL_POSITION
                            ValueSmallint.get((short) (k + 1)), // COLUMN_NAME
                            column.getName(), // CARDINALITY
                            ValueInteger.get(0), // PRIMARY_KEY
                            ValueBoolean.get(index.getIndexType().isPrimaryKey()), // INDEX_TYPE_NAME
                            index.getIndexType().getSQL(), // IS_GENERATED
                            ValueBoolean.get(index.getIndexType().getBelongsToConstraint()), // INDEX_TYPE
                            ValueSmallint.get(DatabaseMetaData.tableIndexOther), // ASC_OR_DESC
                            (idxCol.sortType & SortOrder.DESCENDING) != 0 ? "D" : "A", // PAGES
                            ValueInteger.get(0), // FILTER_CONDITION
                            "", // REMARKS
                            replaceNullWithEmpty(index.getComment()), // SQL
                            index.getCreateSQL(), // ID
                            ValueInteger.get(index.getId()), // SORT_TYPE
                            ValueInteger.get(idxCol.sortType), // CONSTRAINT_NAME
                            constraintName, // INDEX_CLASS
                            indexClass);
                        }
                    }
                }
                break;
            }
        case TABLE_TYPES:
            {
                add(session, rows, TableType.TABLE.toString());
                add(session, rows, TableType.TABLE_LINK.toString());
                add(session, rows, TableType.SYSTEM_TABLE.toString());
                add(session, rows, TableType.VIEW.toString());
                add(session, rows, TableType.EXTERNAL_TABLE_ENGINE.toString());
                break;
            }
        case TYPE_INFO:
            {
                for (int i = 1, l = Value.TYPE_COUNT; i < l; i++) {
                    DataType t = DataType.getDataType(i);
                    add(session, rows, // TYPE_NAME
                    Value.getTypeName(t.type), // DATA_TYPE
                    ValueInteger.get(t.sqlType), // PRECISION
                    ValueInteger.get(MathUtils.convertLongToInt(t.maxPrecision)), // PREFIX
                    t.prefix, // SUFFIX
                    t.suffix, // PARAMS
                    t.params, // AUTO_INCREMENT
                    ValueBoolean.FALSE, // MINIMUM_SCALE
                    ValueSmallint.get(MathUtils.convertIntToShort(t.minScale)), // MAXIMUM_SCALE
                    ValueSmallint.get(MathUtils.convertIntToShort(t.maxScale)), // RADIX
                    DataType.isNumericType(i) ? ValueInteger.get(10) : null, // POS
                    ValueInteger.get(t.type), // CASE_SENSITIVE
                    ValueBoolean.get(t.caseSensitive), // NULLABLE
                    ValueSmallint.get((short) DatabaseMetaData.typeNullable), // SEARCHABLE
                    ValueSmallint.get((short) DatabaseMetaData.typeSearchable));
                }
                break;
            }
        case CATALOGS:
            {
                add(session, rows, catalog);
                break;
            }
        case SETTINGS:
            {
                for (Setting s : database.getAllSettings()) {
                    String value = s.getStringValue();
                    if (value == null) {
                        value = Integer.toString(s.getIntValue());
                    }
                    add(session, rows, identifier(s.getName()), value);
                }
                add(session, rows, "info.BUILD_ID", "" + Constants.BUILD_ID);
                add(session, rows, "info.VERSION_MAJOR", "" + Constants.VERSION_MAJOR);
                add(session, rows, "info.VERSION_MINOR", "" + Constants.VERSION_MINOR);
                add(session, rows, "info.VERSION", Constants.FULL_VERSION);
                if (admin) {
                    String[] settings = { "java.runtime.version", "java.vm.name", "java.vendor", "os.name", "os.arch", "os.version", "sun.os.patch.level", "file.separator", "path.separator", "line.separator", "user.country", "user.language", "user.variant", "file.encoding" };
                    for (String s : settings) {
                        add(session, rows, "property." + s, Utils.getProperty(s, ""));
                    }
                }
                add(session, rows, "DEFAULT_NULL_ORDERING", database.getDefaultNullOrdering().name());
                add(session, rows, "EXCLUSIVE", database.getExclusiveSession() == null ? "FALSE" : "TRUE");
                add(session, rows, "MODE", database.getMode().getName());
                add(session, rows, "QUERY_TIMEOUT", Integer.toString(session.getQueryTimeout()));
                add(session, rows, "TIME ZONE", session.currentTimeZone().getId());
                add(session, rows, "TRUNCATE_LARGE_LENGTH", session.isTruncateLargeLength() ? "TRUE" : "FALSE");
                add(session, rows, "VARIABLE_BINARY", session.isVariableBinary() ? "TRUE" : "FALSE");
                add(session, rows, "OLD_INFORMATION_SCHEMA", session.isOldInformationSchema() ? "TRUE" : "FALSE");
                BitSet nonKeywords = session.getNonKeywords();
                if (nonKeywords != null) {
                    add(session, rows, "NON_KEYWORDS", Parser.formatNonKeywords(nonKeywords));
                }
                add(session, rows, "RETENTION_TIME", Integer.toString(database.getRetentionTime()));
                // database settings
                for (Map.Entry<String, String> entry : database.getSettings().getSortedSettings()) {
                    add(session, rows, entry.getKey(), entry.getValue());
                }
                Store store = database.getStore();
                MVStore mvStore = store.getMvStore();
                FileStore fs = mvStore.getFileStore();
                if (fs != null) {
                    add(session, rows, "info.FILE_WRITE", Long.toString(fs.getWriteCount()));
                    add(session, rows, "info.FILE_WRITE_BYTES", Long.toString(fs.getWriteBytes()));
                    add(session, rows, "info.FILE_READ", Long.toString(fs.getReadCount()));
                    add(session, rows, "info.FILE_READ_BYTES", Long.toString(fs.getReadBytes()));
                    add(session, rows, "info.UPDATE_FAILURE_PERCENT", String.format(Locale.ENGLISH, "%.2f%%", 100 * mvStore.getUpdateFailureRatio()));
                    add(session, rows, "info.FILL_RATE", Integer.toString(mvStore.getFillRate()));
                    add(session, rows, "info.CHUNKS_FILL_RATE", Integer.toString(mvStore.getChunksFillRate()));
                    add(session, rows, "info.CHUNKS_FILL_RATE_RW", Integer.toString(mvStore.getRewritableChunksFillRate()));
                    try {
                        add(session, rows, "info.FILE_SIZE", Long.toString(fs.getFile().size()));
                    } catch (IOException ignore) {
                    /**/
                    }
                    add(session, rows, "info.CHUNK_COUNT", Long.toString(mvStore.getChunkCount()));
                    add(session, rows, "info.PAGE_COUNT", Long.toString(mvStore.getPageCount()));
                    add(session, rows, "info.PAGE_COUNT_LIVE", Long.toString(mvStore.getLivePageCount()));
                    add(session, rows, "info.PAGE_SIZE", Integer.toString(mvStore.getPageSplitSize()));
                    add(session, rows, "info.CACHE_MAX_SIZE", Integer.toString(mvStore.getCacheSize()));
                    add(session, rows, "info.CACHE_SIZE", Integer.toString(mvStore.getCacheSizeUsed()));
                    add(session, rows, "info.CACHE_HIT_RATIO", Integer.toString(mvStore.getCacheHitRatio()));
                    add(session, rows, "info.TOC_CACHE_HIT_RATIO", Integer.toString(mvStore.getTocCacheHitRatio()));
                    add(session, rows, "info.LEAF_RATIO", Integer.toString(mvStore.getLeafRatio()));
                }
                break;
            }
        case HELP:
            {
                String resource = "/org/h2/res/help.csv";
                try {
                    final byte[] data = Utils.getResource(resource);
                    final Reader reader = new InputStreamReader(new ByteArrayInputStream(data));
                    final Csv csv = new Csv();
                    csv.setLineCommentCharacter('#');
                    final ResultSet rs = csv.read(reader, null);
                    final int columnCount = rs.getMetaData().getColumnCount() - 1;
                    final String[] values = new String[5];
                    for (int i = 0; rs.next(); i++) {
                        for (int j = 0; j < columnCount; j++) {
                            String s = rs.getString(1 + j);
                            switch(j) {
                                case // SYNTAX column
                                2:
                                    // Strip out the special annotations we use to help build
                                    // the railroad/BNF diagrams
                                    s = Help.stripAnnotationsFromSyntax(s);
                                    break;
                                case // TEXT column
                                3:
                                    s = Help.processHelpText(s);
                            }
                            values[j] = s.trim();
                        }
                        add(session, rows, // ID
                        ValueInteger.get(i), // SECTION
                        values[0], // TOPIC
                        values[1], // SYNTAX
                        values[2], // TEXT
                        values[3]);
                    }
                } catch (Exception e) {
                    throw DbException.convert(e);
                }
                break;
            }
        case SEQUENCES:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) {
                    Sequence s = (Sequence) obj;
                    TypeInfo dataType = s.getDataType();
                    String dataTypeName = Value.getTypeName(dataType.getValueType());
                    ValueInteger declaredScale = ValueInteger.get(dataType.getScale());
                    add(session, rows, // SEQUENCE_CATALOG
                    catalog, // SEQUENCE_SCHEMA
                    s.getSchema().getName(), // SEQUENCE_NAME
                    s.getName(), // DATA_TYPE
                    dataTypeName, // NUMERIC_PRECISION
                    ValueInteger.get(s.getEffectivePrecision()), // NUMERIC_PRECISION_RADIX
                    ValueInteger.get(10), // NUMERIC_SCALE
                    declaredScale, // START_VALUE
                    ValueBigint.get(s.getStartValue()), // MINIMUM_VALUE
                    ValueBigint.get(s.getMinValue()), // MAXIMUM_VALUE
                    ValueBigint.get(s.getMaxValue()), // INCREMENT
                    ValueBigint.get(s.getIncrement()), // CYCLE_OPTION
                    s.getCycle().isCycle() ? "YES" : "NO", // DECLARED_DATA_TYPE
                    dataTypeName, // DECLARED_NUMERIC_PRECISION
                    ValueInteger.get((int) dataType.getPrecision()), // DECLARED_NUMERIC_SCALE
                    declaredScale, // CURRENT_VALUE
                    ValueBigint.get(s.getCurrentValue()), // IS_GENERATED
                    ValueBoolean.get(s.getBelongsToTable()), // REMARKS
                    replaceNullWithEmpty(s.getComment()), // CACHE
                    ValueBigint.get(s.getCacheSize()), // ID
                    ValueInteger.get(s.getId()), // MIN_VALUE
                    ValueBigint.get(s.getMinValue()), // MAX_VALUE
                    ValueBigint.get(s.getMaxValue()), // IS_CYCLE
                    ValueBoolean.get(s.getCycle().isCycle()));
                }
                break;
            }
        case USERS:
            {
                for (RightOwner rightOwner : database.getAllUsersAndRoles()) {
                    if (rightOwner instanceof User) {
                        User u = (User) rightOwner;
                        if (admin || session.getUser() == u) {
                            add(session, rows, // NAME
                            identifier(u.getName()), // ADMIN
                            String.valueOf(u.isAdmin()), // REMARKS
                            replaceNullWithEmpty(u.getComment()), // ID
                            ValueInteger.get(u.getId()));
                        }
                    }
                }
                break;
            }
        case ROLES:
            {
                for (RightOwner rightOwner : database.getAllUsersAndRoles()) {
                    if (rightOwner instanceof Role) {
                        Role r = (Role) rightOwner;
                        if (admin || session.getUser().isRoleGranted(r)) {
                            add(session, rows, // NAME
                            identifier(r.getName()), // REMARKS
                            replaceNullWithEmpty(r.getComment()), // ID
                            ValueInteger.get(r.getId()));
                        }
                    }
                }
                break;
            }
        case RIGHTS:
            {
                if (admin) {
                    for (Right r : database.getAllRights()) {
                        Role role = r.getGrantedRole();
                        DbObject grantee = r.getGrantee();
                        String rightType = grantee.getType() == DbObject.USER ? "USER" : "ROLE";
                        if (role == null) {
                            DbObject object = r.getGrantedObject();
                            Schema schema = null;
                            Table table = null;
                            if (object != null) {
                                if (object instanceof Schema) {
                                    schema = (Schema) object;
                                } else if (object instanceof Table) {
                                    table = (Table) object;
                                    schema = table.getSchema();
                                }
                            }
                            String tableName = (table != null) ? table.getName() : "";
                            String schemaName = (schema != null) ? schema.getName() : "";
                            if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                                continue;
                            }
                            add(session, rows, // GRANTEE
                            identifier(grantee.getName()), // GRANTEETYPE
                            rightType, // GRANTEDROLE
                            "", // RIGHTS
                            r.getRights(), // TABLE_SCHEMA
                            schemaName, // TABLE_NAME
                            tableName, // ID
                            ValueInteger.get(r.getId()));
                        } else {
                            add(session, rows, // GRANTEE
                            identifier(grantee.getName()), // GRANTEETYPE
                            rightType, // GRANTEDROLE
                            identifier(role.getName()), // RIGHTS
                            "", // TABLE_SCHEMA
                            "", // TABLE_NAME
                            "", // ID
                            ValueInteger.get(r.getId()));
                        }
                    }
                }
                break;
            }
        case FUNCTION_ALIASES:
            for (Schema schema : database.getAllSchemas()) {
                for (UserDefinedFunction userDefinedFunction : schema.getAllFunctionsAndAggregates()) {
                    if (userDefinedFunction instanceof FunctionAlias) {
                        FunctionAlias alias = (FunctionAlias) userDefinedFunction;
                        JavaMethod[] methods;
                        try {
                            methods = alias.getJavaMethods();
                        } catch (DbException e) {
                            continue;
                        }
                        for (FunctionAlias.JavaMethod method : methods) {
                            TypeInfo typeInfo = method.getDataType();
                            if (typeInfo == null) {
                                typeInfo = TypeInfo.TYPE_NULL;
                            }
                            add(session, rows, // ALIAS_CATALOG
                            catalog, // ALIAS_SCHEMA
                            alias.getSchema().getName(), // ALIAS_NAME
                            alias.getName(), // JAVA_CLASS
                            alias.getJavaClassName(), // JAVA_METHOD
                            alias.getJavaMethodName(), // DATA_TYPE
                            ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)), // TYPE_NAME
                            typeInfo.getDeclaredTypeName(), // COLUMN_COUNT
                            ValueInteger.get(method.getParameterCount()), // RETURNS_RESULT
                            ValueSmallint.get(typeInfo.getValueType() == Value.NULL ? (short) DatabaseMetaData.procedureNoResult : (short) DatabaseMetaData.procedureReturnsResult), // REMARKS
                            replaceNullWithEmpty(alias.getComment()), // ID
                            ValueInteger.get(alias.getId()), // SOURCE
                            alias.getSource());
                        }
                    } else {
                        add(session, rows, // ALIAS_CATALOG
                        catalog, // ALIAS_SCHEMA
                        database.getMainSchema().getName(), // ALIAS_NAME
                        userDefinedFunction.getName(), // JAVA_CLASS
                        userDefinedFunction.getJavaClassName(), // JAVA_METHOD
                        "", // DATA_TYPE
                        ValueInteger.get(Types.NULL), // TYPE_NAME
                        "NULL", // COLUMN_COUNT
                        ValueInteger.get(1), // RETURNS_RESULT
                        ValueSmallint.get((short) DatabaseMetaData.procedureReturnsResult), // REMARKS
                        replaceNullWithEmpty(userDefinedFunction.getComment()), // ID
                        ValueInteger.get(userDefinedFunction.getId()), // SOURCE
                        "");
                    }
                }
            }
            break;
        case FUNCTION_COLUMNS:
            for (Schema schema : database.getAllSchemas()) {
                for (UserDefinedFunction userDefinedFunction : schema.getAllFunctionsAndAggregates()) {
                    if (userDefinedFunction instanceof FunctionAlias) {
                        FunctionAlias alias = (FunctionAlias) userDefinedFunction;
                        JavaMethod[] methods;
                        try {
                            methods = alias.getJavaMethods();
                        } catch (DbException e) {
                            continue;
                        }
                        for (FunctionAlias.JavaMethod method : methods) {
                            // Add return column index 0
                            TypeInfo typeInfo = method.getDataType();
                            if (typeInfo != null && typeInfo.getValueType() != Value.NULL) {
                                DataType dt = DataType.getDataType(typeInfo.getValueType());
                                add(session, rows, // ALIAS_CATALOG
                                catalog, // ALIAS_SCHEMA
                                alias.getSchema().getName(), // ALIAS_NAME
                                alias.getName(), // JAVA_CLASS
                                alias.getJavaClassName(), // JAVA_METHOD
                                alias.getJavaMethodName(), // COLUMN_COUNT
                                ValueInteger.get(method.getParameterCount()), // POS
                                ValueInteger.get(0), // COLUMN_NAME
                                "P0", // DATA_TYPE
                                ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)), // TYPE_NAME
                                typeInfo.getDeclaredTypeName(), // PRECISION
                                ValueInteger.get(MathUtils.convertLongToInt(dt.defaultPrecision)), // SCALE
                                ValueSmallint.get(MathUtils.convertIntToShort(dt.defaultScale)), // RADIX
                                ValueSmallint.get((short) 10), // NULLABLE
                                ValueSmallint.get((short) DatabaseMetaData.columnNullableUnknown), // COLUMN_TYPE
                                ValueSmallint.get((short) DatabaseMetaData.procedureColumnReturn), // REMARKS
                                "", // COLUMN_DEFAULT
                                null);
                            }
                            Class<?>[] columnList = method.getColumnClasses();
                            for (int k = 0; k < columnList.length; k++) {
                                if (method.hasConnectionParam() && k == 0) {
                                    continue;
                                }
                                Class<?> clazz = columnList[k];
                                TypeInfo columnTypeInfo = ValueToObjectConverter2.classToType(clazz);
                                DataType dt = DataType.getDataType(columnTypeInfo.getValueType());
                                add(session, rows, // ALIAS_CATALOG
                                catalog, // ALIAS_SCHEMA
                                alias.getSchema().getName(), // ALIAS_NAME
                                alias.getName(), // JAVA_CLASS
                                alias.getJavaClassName(), // JAVA_METHOD
                                alias.getJavaMethodName(), // COLUMN_COUNT
                                ValueInteger.get(method.getParameterCount()), // POS
                                ValueInteger.get(k + (method.hasConnectionParam() ? 0 : 1)), // COLUMN_NAME
                                "P" + (k + 1), // DATA_TYPE
                                ValueInteger.get(DataType.convertTypeToSQLType(columnTypeInfo)), // TYPE_NAME
                                columnTypeInfo.getDeclaredTypeName(), // PRECISION
                                ValueInteger.get(MathUtils.convertLongToInt(dt.defaultPrecision)), // SCALE
                                ValueSmallint.get(MathUtils.convertIntToShort(dt.defaultScale)), // RADIX
                                ValueSmallint.get((short) 10), // NULLABLE
                                ValueSmallint.get(clazz.isPrimitive() ? (short) DatabaseMetaData.columnNoNulls : (short) DatabaseMetaData.columnNullable), // COLUMN_TYPE
                                ValueSmallint.get((short) DatabaseMetaData.procedureColumnIn), // REMARKS
                                "", // COLUMN_DEFAULT
                                null);
                            }
                        }
                    }
                }
            }
            break;
        case SCHEMATA:
            {
                String collation = database.getCompareMode().getName();
                for (Schema schema : database.getAllSchemas()) {
                    add(session, rows, // CATALOG_NAME
                    catalog, // SCHEMA_NAME
                    schema.getName(), // SCHEMA_OWNER
                    identifier(schema.getOwner().getName()), // DEFAULT_CHARACTER_SET_NAME
                    CHARACTER_SET_NAME, // DEFAULT_COLLATION_NAME
                    collation, // IS_DEFAULT
                    ValueBoolean.get(schema.getId() == Constants.MAIN_SCHEMA_ID), // REMARKS
                    replaceNullWithEmpty(schema.getComment()), // ID
                    ValueInteger.get(schema.getId()));
                }
                break;
            }
        case TABLE_PRIVILEGES:
            {
                for (Right r : database.getAllRights()) {
                    DbObject object = r.getGrantedObject();
                    if (!(object instanceof Table)) {
                        continue;
                    }
                    Table table = (Table) object;
                    if (hideTable(table, session)) {
                        continue;
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    addPrivileges(session, rows, r.getGrantee(), catalog, table, null, r.getRightMask());
                }
                break;
            }
        case COLUMN_PRIVILEGES:
            {
                for (Right r : database.getAllRights()) {
                    DbObject object = r.getGrantedObject();
                    if (!(object instanceof Table)) {
                        continue;
                    }
                    Table table = (Table) object;
                    if (hideTable(table, session)) {
                        continue;
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    DbObject grantee = r.getGrantee();
                    int mask = r.getRightMask();
                    for (Column column : table.getColumns()) {
                        addPrivileges(session, rows, grantee, catalog, table, column.getName(), mask);
                    }
                }
                break;
            }
        case COLLATIONS:
            {
                for (Locale l : CompareMode.getCollationLocales(false)) {
                    add(session, rows, // KEY
                    CompareMode.getName(l), l.toString());
                }
                break;
            }
        case VIEWS:
            {
                for (Table table : getAllTables(session)) {
                    if (table.getTableType() != TableType.VIEW) {
                        continue;
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    TableView view = (TableView) table;
                    add(session, rows, // TABLE_CATALOG
                    catalog, // TABLE_SCHEMA
                    table.getSchema().getName(), // TABLE_NAME
                    tableName, // VIEW_DEFINITION
                    table.getCreateSQL(), // CHECK_OPTION
                    "NONE", // IS_UPDATABLE
                    "NO", // STATUS
                    view.isInvalid() ? "INVALID" : "VALID", // REMARKS
                    replaceNullWithEmpty(view.getComment()), // ID
                    ValueInteger.get(view.getId()));
                }
                break;
            }
        case IN_DOUBT:
            {
                ArrayList<InDoubtTransaction> prepared = database.getInDoubtTransactions();
                if (prepared != null && admin) {
                    for (InDoubtTransaction prep : prepared) {
                        add(session, rows, // STATE
                        prep.getTransactionName(), prep.getStateDescription());
                    }
                }
                break;
            }
        case CROSS_REFERENCES:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    if (constraint.getConstraintType() != Constraint.Type.REFERENTIAL) {
                        continue;
                    }
                    ConstraintReferential ref = (ConstraintReferential) constraint;
                    IndexColumn[] cols = ref.getColumns();
                    IndexColumn[] refCols = ref.getRefColumns();
                    Table tab = ref.getTable();
                    Table refTab = ref.getRefTable();
                    String tableName = refTab.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    ValueSmallint update = ValueSmallint.get(getRefAction(ref.getUpdateAction()));
                    ValueSmallint delete = ValueSmallint.get(getRefAction(ref.getDeleteAction()));
                    for (int j = 0; j < cols.length; j++) {
                        add(session, rows, // PKTABLE_CATALOG
                        catalog, // PKTABLE_SCHEMA
                        refTab.getSchema().getName(), // PKTABLE_NAME
                        refTab.getName(), // PKCOLUMN_NAME
                        refCols[j].column.getName(), // FKTABLE_CATALOG
                        catalog, // FKTABLE_SCHEMA
                        tab.getSchema().getName(), // FKTABLE_NAME
                        tab.getName(), // FKCOLUMN_NAME
                        cols[j].column.getName(), // ORDINAL_POSITION
                        ValueSmallint.get((short) (j + 1)), // UPDATE_RULE
                        update, // DELETE_RULE
                        delete, // FK_NAME
                        ref.getName(), // PK_NAME
                        ref.getReferencedConstraint().getName(), // DEFERRABILITY
                        ValueSmallint.get((short) DatabaseMetaData.importedKeyNotDeferrable));
                    }
                }
                break;
            }
        case CONSTRAINTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    Constraint.Type constraintType = constraint.getConstraintType();
                    String checkExpression = null;
                    IndexColumn[] indexColumns = null;
                    Table table = constraint.getTable();
                    if (hideTable(table, session)) {
                        continue;
                    }
                    Index index = constraint.getIndex();
                    String uniqueIndexName = null;
                    if (index != null) {
                        uniqueIndexName = index.getName();
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    if (constraintType == Constraint.Type.CHECK) {
                        checkExpression = ((ConstraintCheck) constraint).getExpression().getSQL(HasSQL.DEFAULT_SQL_FLAGS);
                    } else if (constraintType == Constraint.Type.UNIQUE || constraintType == Constraint.Type.PRIMARY_KEY) {
                        indexColumns = ((ConstraintUnique) constraint).getColumns();
                    } else if (constraintType == Constraint.Type.REFERENTIAL) {
                        indexColumns = ((ConstraintReferential) constraint).getColumns();
                    }
                    String columnList = null;
                    if (indexColumns != null) {
                        StringBuilder builder = new StringBuilder();
                        for (int i = 0, length = indexColumns.length; i < length; i++) {
                            if (i > 0) {
                                builder.append(',');
                            }
                            builder.append(indexColumns[i].column.getName());
                        }
                        columnList = builder.toString();
                    }
                    add(session, rows, // CONSTRAINT_CATALOG
                    catalog, // CONSTRAINT_SCHEMA
                    constraint.getSchema().getName(), // CONSTRAINT_NAME
                    constraint.getName(), // CONSTRAINT_TYPE
                    constraintType == Constraint.Type.PRIMARY_KEY ? constraintType.getSqlName() : constraintType.name(), // TABLE_CATALOG
                    catalog, // TABLE_SCHEMA
                    table.getSchema().getName(), // TABLE_NAME
                    tableName, // UNIQUE_INDEX_NAME
                    uniqueIndexName, // CHECK_EXPRESSION
                    checkExpression, // COLUMN_LIST
                    columnList, // REMARKS
                    replaceNullWithEmpty(constraint.getComment()), // SQL
                    constraint.getCreateSQL(), // ID
                    ValueInteger.get(constraint.getId()));
                }
                break;
            }
        case CONSTANTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTANT)) {
                    Constant constant = (Constant) obj;
                    ValueExpression expr = constant.getValue();
                    add(session, rows, // CONSTANT_CATALOG
                    catalog, // CONSTANT_SCHEMA
                    constant.getSchema().getName(), // CONSTANT_NAME
                    constant.getName(), // DATA_TYPE
                    ValueInteger.get(DataType.convertTypeToSQLType(expr.getType())), // REMARKS
                    replaceNullWithEmpty(constant.getComment()), // SQL
                    expr.getSQL(DEFAULT_SQL_FLAGS), // ID
                    ValueInteger.get(constant.getId()));
                }
                break;
            }
        case DOMAINS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.DOMAIN)) {
                    Domain domain = (Domain) obj;
                    Domain parentDomain = domain.getDomain();
                    TypeInfo typeInfo = domain.getDataType();
                    add(session, rows, // DOMAIN_CATALOG
                    catalog, // DOMAIN_SCHEMA
                    domain.getSchema().getName(), // DOMAIN_NAME
                    domain.getName(), // DOMAIN_DEFAULT
                    domain.getDefaultSQL(), // DOMAIN_ON_UPDATE
                    domain.getOnUpdateSQL(), // DATA_TYPE
                    ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)), // PRECISION
                    ValueInteger.get(MathUtils.convertLongToInt(typeInfo.getPrecision())), // SCALE
                    ValueInteger.get(typeInfo.getScale()), // TYPE_NAME
                    typeInfo.getDeclaredTypeName(), // PARENT_DOMAIN_CATALOG
                    parentDomain != null ? catalog : null, // PARENT_DOMAIN_SCHEMA
                    parentDomain != null ? parentDomain.getSchema().getName() : null, // PARENT_DOMAIN_NAME
                    parentDomain != null ? parentDomain.getName() : null, // SELECTIVITY INT
                    ValueInteger.get(Constants.SELECTIVITY_DEFAULT), // REMARKS
                    replaceNullWithEmpty(domain.getComment()), // SQL
                    domain.getCreateSQL(), // ID
                    ValueInteger.get(domain.getId()), // COLUMN_DEFAULT
                    domain.getDefaultSQL(), // IS_NULLABLE
                    "YES", // CHECK_CONSTRAINT
                    null);
                }
                break;
            }
        case TRIGGERS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.TRIGGER)) {
                    TriggerObject trigger = (TriggerObject) obj;
                    Table table = trigger.getTable();
                    add(session, rows, // TRIGGER_CATALOG
                    catalog, // TRIGGER_SCHEMA
                    trigger.getSchema().getName(), // TRIGGER_NAME
                    trigger.getName(), // TRIGGER_TYPE
                    trigger.getTypeNameList(new StringBuilder()).toString(), // TABLE_CATALOG
                    catalog, // TABLE_SCHEMA
                    table.getSchema().getName(), // TABLE_NAME
                    table.getName(), // BEFORE
                    ValueBoolean.get(trigger.isBefore()), // JAVA_CLASS
                    trigger.getTriggerClassName(), // QUEUE_SIZE
                    ValueInteger.get(trigger.getQueueSize()), // NO_WAIT
                    ValueBoolean.get(trigger.isNoWait()), // REMARKS
                    replaceNullWithEmpty(trigger.getComment()), // SQL
                    trigger.getCreateSQL(), // ID
                    ValueInteger.get(trigger.getId()));
                }
                break;
            }
        case SESSIONS:
            {
                for (SessionLocal s : database.getSessions(false)) {
                    if (admin || s == session) {
                        NetworkConnectionInfo networkConnectionInfo = s.getNetworkConnectionInfo();
                        Command command = s.getCurrentCommand();
                        int blockingSessionId = s.getBlockingSessionId();
                        add(session, rows, // ID
                        ValueInteger.get(s.getId()), // USER_NAME
                        s.getUser().getName(), // SERVER
                        networkConnectionInfo == null ? null : networkConnectionInfo.getServer(), // CLIENT_ADDR
                        networkConnectionInfo == null ? null : networkConnectionInfo.getClient(), // CLIENT_INFO
                        networkConnectionInfo == null ? null : networkConnectionInfo.getClientInfo(), // SESSION_START
                        s.getSessionStart(), // ISOLATION_LEVEL
                        session.getIsolationLevel().getSQL(), // STATEMENT
                        command == null ? null : command.toString(), // STATEMENT_START
                        command == null ? null : s.getCommandStartOrEnd(), // CONTAINS_UNCOMMITTED
                        ValueBoolean.get(s.hasPendingTransaction()), // STATE
                        String.valueOf(s.getState()), // BLOCKER_ID
                        blockingSessionId == 0 ? null : ValueInteger.get(blockingSessionId), // SLEEP_SINCE
                        s.getState() == State.SLEEP ? s.getCommandStartOrEnd() : null);
                    }
                }
                break;
            }
        case LOCKS:
            {
                for (SessionLocal s : database.getSessions(false)) {
                    if (admin || s == session) {
                        for (Table table : s.getLocks()) {
                            add(session, rows, // TABLE_SCHEMA
                            table.getSchema().getName(), // TABLE_NAME
                            table.getName(), // SESSION_ID
                            ValueInteger.get(s.getId()), // LOCK_TYPE
                            table.isLockedExclusivelyBy(s) ? "WRITE" : "READ");
                        }
                    }
                }
                break;
            }
        case SESSION_STATE:
            {
                for (String name : session.getVariableNames()) {
                    Value v = session.getVariable(name);
                    StringBuilder builder = new StringBuilder().append("SET @").append(name).append(' ');
                    v.getSQL(builder, DEFAULT_SQL_FLAGS);
                    add(session, rows, // KEY
                    "@" + name, // SQL
                    builder.toString());
                }
                for (Table table : session.getLocalTempTables()) {
                    add(session, rows, // KEY
                    "TABLE " + table.getName(), // SQL
                    table.getCreateSQL());
                }
                String[] path = session.getSchemaSearchPath();
                if (path != null && path.length > 0) {
                    StringBuilder builder = new StringBuilder("SET SCHEMA_SEARCH_PATH ");
                    for (int i = 0, l = path.length; i < l; i++) {
                        if (i > 0) {
                            builder.append(", ");
                        }
                        StringUtils.quoteIdentifier(builder, path[i]);
                    }
                    add(session, rows, // KEY
                    "SCHEMA_SEARCH_PATH", // SQL
                    builder.toString());
                }
                String schema = session.getCurrentSchemaName();
                if (schema != null) {
                    add(session, rows, // KEY
                    "SCHEMA", // SQL
                    StringUtils.quoteIdentifier(new StringBuilder("SET SCHEMA "), schema).toString());
                }
                TimeZoneProvider currentTimeZone = session.currentTimeZone();
                if (!currentTimeZone.equals(DateTimeUtils.getTimeZone())) {
                    add(session, rows, // KEY
                    "TIME ZONE", // SQL
                    StringUtils.quoteStringSQL(new StringBuilder("SET TIME ZONE "), currentTimeZone.getId()).toString());
                }
                break;
            }
        case QUERY_STATISTICS:
            {
                QueryStatisticsData control = database.getQueryStatisticsData();
                if (control != null) {
                    for (QueryStatisticsData.QueryEntry entry : control.getQueries()) {
                        add(session, rows, // SQL_STATEMENT
                        entry.sqlStatement, // EXECUTION_COUNT
                        ValueInteger.get(entry.count), // MIN_EXECUTION_TIME
                        ValueDouble.get(entry.executionTimeMinNanos / 1_000_000d), // MAX_EXECUTION_TIME
                        ValueDouble.get(entry.executionTimeMaxNanos / 1_000_000d), // CUMULATIVE_EXECUTION_TIME
                        ValueDouble.get(entry.executionTimeCumulativeNanos / 1_000_000d), // AVERAGE_EXECUTION_TIME
                        ValueDouble.get(entry.executionTimeMeanNanos / 1_000_000d), // STD_DEV_EXECUTION_TIME
                        ValueDouble.get(entry.getExecutionTimeStandardDeviation() / 1_000_000d), // MIN_ROW_COUNT
                        ValueBigint.get(entry.rowCountMin), // MAX_ROW_COUNT
                        ValueBigint.get(entry.rowCountMax), // CUMULATIVE_ROW_COUNT
                        ValueBigint.get(entry.rowCountCumulative), // AVERAGE_ROW_COUNT
                        ValueDouble.get(entry.rowCountMean), // STD_DEV_ROW_COUNT
                        ValueDouble.get(entry.getRowCountStandardDeviation()));
                    }
                }
                break;
            }
        case SYNONYMS:
            {
                for (TableSynonym synonym : database.getAllSynonyms()) {
                    add(session, rows, // SYNONYM_CATALOG
                    catalog, // SYNONYM_SCHEMA
                    synonym.getSchema().getName(), // SYNONYM_NAME
                    synonym.getName(), // SYNONYM_FOR
                    synonym.getSynonymForName(), // SYNONYM_FOR_SCHEMA
                    synonym.getSynonymForSchema().getName(), // TYPE NAME
                    "SYNONYM", // STATUS
                    "VALID", // REMARKS
                    replaceNullWithEmpty(synonym.getComment()), // ID
                    ValueInteger.get(synonym.getId()));
                }
                break;
            }
        case TABLE_CONSTRAINTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    Constraint.Type constraintType = constraint.getConstraintType();
                    if (constraintType == Constraint.Type.DOMAIN) {
                        continue;
                    }
                    Table table = constraint.getTable();
                    if (hideTable(table, session)) {
                        continue;
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    add(session, rows, // CONSTRAINT_CATALOG
                    catalog, // CONSTRAINT_SCHEMA
                    constraint.getSchema().getName(), // CONSTRAINT_NAME
                    constraint.getName(), // CONSTRAINT_TYPE
                    constraintType.getSqlName(), // TABLE_CATALOG
                    catalog, // TABLE_SCHEMA
                    table.getSchema().getName(), // TABLE_NAME
                    tableName, // IS_DEFERRABLE
                    "NO", // INITIALLY_DEFERRED
                    "NO", // REMARKS
                    replaceNullWithEmpty(constraint.getComment()), // SQL
                    constraint.getCreateSQL(), // ID
                    ValueInteger.get(constraint.getId()));
                }
                break;
            }
        case DOMAIN_CONSTRAINTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    if (((Constraint) obj).getConstraintType() != Constraint.Type.DOMAIN) {
                        continue;
                    }
                    ConstraintDomain constraint = (ConstraintDomain) obj;
                    Domain domain = constraint.getDomain();
                    add(session, rows, // CONSTRAINT_CATALOG
                    catalog, // CONSTRAINT_SCHEMA
                    constraint.getSchema().getName(), // CONSTRAINT_NAME
                    constraint.getName(), // DOMAIN_CATALOG
                    catalog, // DOMAIN_SCHEMA
                    domain.getSchema().getName(), // DOMAIN_NAME
                    domain.getName(), // IS_DEFERRABLE
                    "NO", // INITIALLY_DEFERRED
                    "NO", // REMARKS
                    replaceNullWithEmpty(constraint.getComment()), // SQL
                    constraint.getCreateSQL(), // ID
                    ValueInteger.get(constraint.getId()));
                }
                break;
            }
        case KEY_COLUMN_USAGE:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    Constraint.Type constraintType = constraint.getConstraintType();
                    IndexColumn[] indexColumns = null;
                    if (constraintType == Constraint.Type.UNIQUE || constraintType == Constraint.Type.PRIMARY_KEY) {
                        indexColumns = ((ConstraintUnique) constraint).getColumns();
                    } else if (constraintType == Constraint.Type.REFERENTIAL) {
                        indexColumns = ((ConstraintReferential) constraint).getColumns();
                    }
                    if (indexColumns == null) {
                        continue;
                    }
                    Table table = constraint.getTable();
                    if (hideTable(table, session)) {
                        continue;
                    }
                    String tableName = table.getName();
                    if (!checkIndex(session, tableName, indexFrom, indexTo)) {
                        continue;
                    }
                    ConstraintUnique referenced;
                    if (constraintType == Constraint.Type.REFERENTIAL) {
                        referenced = ((ConstraintReferential) constraint).getReferencedConstraint();
                    } else {
                        referenced = null;
                    }
                    Index index = constraint.getIndex();
                    for (int i = 0; i < indexColumns.length; i++) {
                        IndexColumn indexColumn = indexColumns[i];
                        ValueInteger ordinalPosition = ValueInteger.get(i + 1);
                        ValueInteger positionInUniqueConstraint = null;
                        if (referenced != null) {
                            Column c = ((ConstraintReferential) constraint).getRefColumns()[i].column;
                            IndexColumn[] refColumns = referenced.getColumns();
                            for (int j = 0; j < refColumns.length; j++) {
                                if (refColumns[j].column.equals(c)) {
                                    positionInUniqueConstraint = ValueInteger.get(j + 1);
                                    break;
                                }
                            }
                        }
                        add(session, rows, // CONSTRAINT_CATALOG
                        catalog, // CONSTRAINT_SCHEMA
                        constraint.getSchema().getName(), // CONSTRAINT_NAME
                        constraint.getName(), // TABLE_CATALOG
                        catalog, // TABLE_SCHEMA
                        table.getSchema().getName(), // TABLE_NAME
                        tableName, // COLUMN_NAME
                        indexColumn.columnName, // ORDINAL_POSITION
                        ordinalPosition, // POSITION_IN_UNIQUE_CONSTRAINT
                        positionInUniqueConstraint, // INDEX_CATALOG
                        index != null ? catalog : null, // INDEX_SCHEMA
                        index != null ? index.getSchema().getName() : null, // INDEX_NAME
                        index != null ? index.getName() : null);
                    }
                }
                break;
            }
        case REFERENTIAL_CONSTRAINTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    if (((Constraint) obj).getConstraintType() != Constraint.Type.REFERENTIAL) {
                        continue;
                    }
                    ConstraintReferential constraint = (ConstraintReferential) obj;
                    Table table = constraint.getTable();
                    if (hideTable(table, session)) {
                        continue;
                    }
                    ConstraintUnique unique = constraint.getReferencedConstraint();
                    add(session, rows, // CONSTRAINT_CATALOG
                    catalog, // CONSTRAINT_SCHEMA
                    constraint.getSchema().getName(), // CONSTRAINT_NAME
                    constraint.getName(), // UNIQUE_CONSTRAINT_CATALOG
                    catalog, // UNIQUE_CONSTRAINT_SCHEMA
                    unique.getSchema().getName(), // UNIQUE_CONSTRAINT_NAME
                    unique.getName(), // MATCH_OPTION
                    "NONE", // UPDATE_RULE
                    constraint.getUpdateAction().getSqlName(), // DELETE_RULE
                    constraint.getDeleteAction().getSqlName());
                }
                break;
            }
        case CHECK_CONSTRAINTS:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    Type constraintType = constraint.getConstraintType();
                    if (constraintType == Constraint.Type.CHECK) {
                        ConstraintCheck check = (ConstraintCheck) obj;
                        Table table = check.getTable();
                        if (hideTable(table, session)) {
                            continue;
                        }
                    } else if (constraintType != Constraint.Type.DOMAIN) {
                        continue;
                    }
                    add(session, rows, // CONSTRAINT_CATALOG
                    catalog, // CONSTRAINT_SCHEMA
                    obj.getSchema().getName(), // CONSTRAINT_NAME
                    obj.getName(), // CHECK_CLAUSE
                    constraint.getExpression().getSQL(DEFAULT_SQL_FLAGS, Expression.WITHOUT_PARENTHESES));
                }
                break;
            }
        case CONSTRAINT_COLUMN_USAGE:
            {
                for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
                    Constraint constraint = (Constraint) obj;
                    switch(constraint.getConstraintType()) {
                        case CHECK:
                        case DOMAIN:
                            {
                                HashSet<Column> columns = new HashSet<>();
                                constraint.getExpression().isEverything(ExpressionVisitor.getColumnsVisitor(columns, null));
                                for (Column column : columns) {
                                    Table table = column.getTable();
                                    if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
                                        addConstraintColumnUsage(session, rows, catalog, constraint, column);
                                    }
                                }
                                break;
                            }
                        case REFERENTIAL:
                            {
                                Table table = constraint.getRefTable();
                                if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
                                    for (Column column : constraint.getReferencedColumns(table)) {
                                        addConstraintColumnUsage(session, rows, catalog, constraint, column);
                                    }
                                }
                            }
                        // $FALL-THROUGH$
                        case PRIMARY_KEY:
                        case UNIQUE:
                            {
                                Table table = constraint.getTable();
                                if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
                                    for (Column column : constraint.getReferencedColumns(table)) {
                                        addConstraintColumnUsage(session, rows, catalog, constraint, column);
                                    }
                                }
                            }
                    }
                }
                break;
            }
        default:
            throw DbException.getInternalError("type=" + type);
    }
    return rows;
}
Also used : Locale(java.util.Locale) InDoubtTransaction(org.h2.store.InDoubtTransaction) ConstraintDomain(org.h2.constraint.ConstraintDomain) SchemaObject(org.h2.schema.SchemaObject) QueryStatisticsData(org.h2.engine.QueryStatisticsData) UserDefinedFunction(org.h2.schema.UserDefinedFunction) Constraint(org.h2.constraint.Constraint) Schema(org.h2.schema.Schema) ArrayList(java.util.ArrayList) FileStore(org.h2.mvstore.FileStore) MVStore(org.h2.mvstore.MVStore) Store(org.h2.mvstore.db.Store) Index(org.h2.index.Index) MetaIndex(org.h2.index.MetaIndex) ConstraintReferential(org.h2.constraint.ConstraintReferential) ResultSet(java.sql.ResultSet) JavaMethod(org.h2.schema.FunctionAlias.JavaMethod) JavaMethod(org.h2.schema.FunctionAlias.JavaMethod) NetworkConnectionInfo(org.h2.util.NetworkConnectionInfo) ConstraintCheck(org.h2.constraint.ConstraintCheck) HashSet(java.util.HashSet) DbObject(org.h2.engine.DbObject) Setting(org.h2.engine.Setting) BitSet(java.util.BitSet) Sequence(org.h2.schema.Sequence) RightOwner(org.h2.engine.RightOwner) TypeInfo(org.h2.value.TypeInfo) Role(org.h2.engine.Role) ByteArrayInputStream(java.io.ByteArrayInputStream) Value(org.h2.value.Value) ConstraintUnique(org.h2.constraint.ConstraintUnique) Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) Domain(org.h2.schema.Domain) ConstraintDomain(org.h2.constraint.ConstraintDomain) SessionLocal(org.h2.engine.SessionLocal) User(org.h2.engine.User) Constant(org.h2.schema.Constant) Right(org.h2.engine.Right) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) TriggerObject(org.h2.schema.TriggerObject) DbException(org.h2.message.DbException) DataType(org.h2.value.DataType) InputStreamReader(java.io.InputStreamReader) FunctionAlias(org.h2.schema.FunctionAlias) Csv(org.h2.tools.Csv) ValueSmallint(org.h2.value.ValueSmallint) IOException(java.io.IOException) TimeZoneProvider(org.h2.util.TimeZoneProvider) DbException(org.h2.message.DbException) IOException(java.io.IOException) ValueBigint(org.h2.value.ValueBigint) ValueSmallint(org.h2.value.ValueSmallint) Constraint(org.h2.constraint.Constraint) MVStore(org.h2.mvstore.MVStore) ValueInteger(org.h2.value.ValueInteger) FileStore(org.h2.mvstore.FileStore) ConstraintActionType(org.h2.constraint.ConstraintActionType) Type(org.h2.constraint.Constraint.Type) DataType(org.h2.value.DataType) Command(org.h2.command.Command) ValueExpression(org.h2.expression.ValueExpression)

Aggregations

FileStore (org.h2.store.FileStore)20 FileStore (org.h2.mvstore.FileStore)16 IOException (java.io.IOException)14 MVStore (org.h2.mvstore.MVStore)11 BufferedInputStream (java.io.BufferedInputStream)8 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 FileStoreInputStream (org.h2.store.FileStoreInputStream)8 ByteArrayInputStream (java.io.ByteArrayInputStream)7 BitSet (java.util.BitSet)6 HashSet (java.util.HashSet)6 DbException (org.h2.message.DbException)6 FileStoreOutputStream (org.h2.store.FileStoreOutputStream)6 InputStream (java.io.InputStream)5 InputStreamReader (java.io.InputStreamReader)5 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 Setting (org.h2.engine.Setting)5 Map (java.util.Map)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)4 OutputStream (java.io.OutputStream)3