Search in sources :

Example 1 with LinkedIndex

use of org.h2.index.LinkedIndex in project h2database by h2database.

the class TableLink method readMetaData.

private void readMetaData() throws SQLException {
    DatabaseMetaData meta = conn.getConnection().getMetaData();
    storesLowerCase = meta.storesLowerCaseIdentifiers();
    storesMixedCase = meta.storesMixedCaseIdentifiers();
    storesMixedCaseQuoted = meta.storesMixedCaseQuotedIdentifiers();
    supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers();
    ResultSet rs = meta.getTables(null, originalSchema, originalTable, null);
    if (rs.next() && rs.next()) {
        throw DbException.get(ErrorCode.SCHEMA_NAME_MUST_MATCH, originalTable);
    }
    rs.close();
    rs = meta.getColumns(null, originalSchema, originalTable, null);
    int i = 0;
    ArrayList<Column> columnList = New.arrayList();
    HashMap<String, Column> columnMap = new HashMap<>();
    String catalog = null, schema = null;
    while (rs.next()) {
        String thisCatalog = rs.getString("TABLE_CAT");
        if (catalog == null) {
            catalog = thisCatalog;
        }
        String thisSchema = rs.getString("TABLE_SCHEM");
        if (schema == null) {
            schema = thisSchema;
        }
        if (!Objects.equals(catalog, thisCatalog) || !Objects.equals(schema, thisSchema)) {
            // if the table exists in multiple schemas or tables,
            // use the alternative solution
            columnMap.clear();
            columnList.clear();
            break;
        }
        String n = rs.getString("COLUMN_NAME");
        n = convertColumnName(n);
        int sqlType = rs.getInt("DATA_TYPE");
        String sqlTypeName = rs.getString("TYPE_NAME");
        long precision = rs.getInt("COLUMN_SIZE");
        precision = convertPrecision(sqlType, precision);
        int scale = rs.getInt("DECIMAL_DIGITS");
        scale = convertScale(sqlType, scale);
        int displaySize = MathUtils.convertLongToInt(precision);
        int type = DataType.convertSQLTypeToValueType(sqlType, sqlTypeName);
        Column col = new Column(n, type, precision, scale, displaySize);
        col.setTable(this, i++);
        columnList.add(col);
        columnMap.put(n, col);
    }
    rs.close();
    if (originalTable.indexOf('.') < 0 && !StringUtils.isNullOrEmpty(schema)) {
        qualifiedTableName = schema + "." + originalTable;
    } else {
        qualifiedTableName = originalTable;
    }
    try (Statement stat = conn.getConnection().createStatement()) {
        rs = stat.executeQuery("SELECT * FROM " + qualifiedTableName + " T WHERE 1=0");
        if (columnList.isEmpty()) {
            // alternative solution
            ResultSetMetaData rsMeta = rs.getMetaData();
            for (i = 0; i < rsMeta.getColumnCount(); ) {
                String n = rsMeta.getColumnName(i + 1);
                n = convertColumnName(n);
                int sqlType = rsMeta.getColumnType(i + 1);
                long precision = rsMeta.getPrecision(i + 1);
                precision = convertPrecision(sqlType, precision);
                int scale = rsMeta.getScale(i + 1);
                scale = convertScale(sqlType, scale);
                int displaySize = rsMeta.getColumnDisplaySize(i + 1);
                int type = DataType.getValueTypeFromResultSet(rsMeta, i + 1);
                Column col = new Column(n, type, precision, scale, displaySize);
                col.setTable(this, i++);
                columnList.add(col);
                columnMap.put(n, col);
            }
        }
        rs.close();
    } catch (Exception e) {
        throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, e, originalTable + "(" + e.toString() + ")");
    }
    Column[] cols = columnList.toArray(new Column[0]);
    setColumns(cols);
    int id = getId();
    linkedIndex = new LinkedIndex(this, id, IndexColumn.wrap(cols), IndexType.createNonUnique(false));
    indexes.add(linkedIndex);
    try {
        rs = meta.getPrimaryKeys(null, originalSchema, originalTable);
    } catch (Exception e) {
        // Some ODBC bridge drivers don't support it:
        // some combinations of "DataDirect SequeLink(R) for JDBC"
        // http://www.datadirect.com/index.ssp
        rs = null;
    }
    String pkName = "";
    ArrayList<Column> list;
    if (rs != null && rs.next()) {
        // the problem is, the rows are not sorted by KEY_SEQ
        list = New.arrayList();
        do {
            int idx = rs.getInt("KEY_SEQ");
            if (pkName == null) {
                pkName = rs.getString("PK_NAME");
            }
            while (list.size() < idx) {
                list.add(null);
            }
            String col = rs.getString("COLUMN_NAME");
            col = convertColumnName(col);
            Column column = columnMap.get(col);
            if (idx == 0) {
                // workaround for a bug in the SQLite JDBC driver
                list.add(column);
            } else {
                list.set(idx - 1, column);
            }
        } while (rs.next());
        addIndex(list, IndexType.createPrimaryKey(false, false));
        rs.close();
    }
    try {
        rs = meta.getIndexInfo(null, originalSchema, originalTable, false, true);
    } catch (Exception e) {
        // Oracle throws an exception if the table is not found or is a
        // SYNONYM
        rs = null;
    }
    String indexName = null;
    list = New.arrayList();
    IndexType indexType = null;
    if (rs != null) {
        while (rs.next()) {
            if (rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic) {
                // ignore index statistics
                continue;
            }
            String newIndex = rs.getString("INDEX_NAME");
            if (pkName.equals(newIndex)) {
                continue;
            }
            if (indexName != null && !indexName.equals(newIndex)) {
                addIndex(list, indexType);
                indexName = null;
            }
            if (indexName == null) {
                indexName = newIndex;
                list.clear();
            }
            boolean unique = !rs.getBoolean("NON_UNIQUE");
            indexType = unique ? IndexType.createUnique(false, false) : IndexType.createNonUnique(false);
            String col = rs.getString("COLUMN_NAME");
            col = convertColumnName(col);
            Column column = columnMap.get(col);
            list.add(column);
        }
        rs.close();
    }
    if (indexName != null) {
        addIndex(list, indexType);
    }
}
Also used : HashMap(java.util.HashMap) LinkedIndex(org.h2.index.LinkedIndex) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) DatabaseMetaData(java.sql.DatabaseMetaData) DbException(org.h2.message.DbException) SQLException(java.sql.SQLException) JdbcSQLException(org.h2.jdbc.JdbcSQLException) ResultSetMetaData(java.sql.ResultSetMetaData) ResultSet(java.sql.ResultSet) IndexType(org.h2.index.IndexType)

Example 2 with LinkedIndex

use of org.h2.index.LinkedIndex in project h2database by h2database.

the class TableLink method addIndex.

private void addIndex(List<Column> list, IndexType indexType) {
    // bind the index to the leading recognized columns in the index
    // (null columns might come from a function-based index)
    int firstNull = list.indexOf(null);
    if (firstNull == 0) {
        trace.info("Omitting linked index - no recognized columns.");
        return;
    } else if (firstNull > 0) {
        trace.info("Unrecognized columns in linked index. " + "Registering the index against the leading {0} " + "recognized columns of {1} total columns.", firstNull, list.size());
        list = list.subList(0, firstNull);
    }
    Column[] cols = list.toArray(new Column[0]);
    Index index = new LinkedIndex(this, 0, IndexColumn.wrap(cols), indexType);
    indexes.add(index);
}
Also used : LinkedIndex(org.h2.index.LinkedIndex) Index(org.h2.index.Index) LinkedIndex(org.h2.index.LinkedIndex)

Aggregations

LinkedIndex (org.h2.index.LinkedIndex)2 DatabaseMetaData (java.sql.DatabaseMetaData)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1 Statement (java.sql.Statement)1 HashMap (java.util.HashMap)1 Index (org.h2.index.Index)1 IndexType (org.h2.index.IndexType)1 JdbcSQLException (org.h2.jdbc.JdbcSQLException)1 DbException (org.h2.message.DbException)1