Search in sources :

Example 26 with Cursor

use of org.h2.mvstore.Cursor in project h2database by h2database.

the class TestMVStore method testIndexSkip.

private void testIndexSkip() {
    MVStore s = openStore(null, 4);
    MVMap<Integer, Integer> map = s.openMap("test");
    for (int i = 0; i < 100; i += 2) {
        map.put(i, 10 * i);
    }
    Cursor<Integer, Integer> c = map.cursor(50);
    // skip must reset the root of the cursor
    c.skip(10);
    for (int i = 70; i < 100; i += 2) {
        assertTrue(c.hasNext());
        assertEquals(i, c.next().intValue());
    }
    assertFalse(c.hasNext());
    for (int i = -1; i < 100; i++) {
        long index = map.getKeyIndex(i);
        if (i < 0 || (i % 2) != 0) {
            assertEquals(i < 0 ? -1 : -(i / 2) - 2, index);
        } else {
            assertEquals(i / 2, index);
        }
    }
    for (int i = -1; i < 60; i++) {
        Integer k = map.getKey(i);
        if (i < 0 || i >= 50) {
            assertNull(k);
        } else {
            assertEquals(i * 2, k.intValue());
        }
    }
    // skip
    c = map.cursor(0);
    assertTrue(c.hasNext());
    assertEquals(0, c.next().intValue());
    c.skip(0);
    assertEquals(2, c.next().intValue());
    c.skip(1);
    assertEquals(6, c.next().intValue());
    c.skip(20);
    assertEquals(48, c.next().intValue());
    c = map.cursor(0);
    c.skip(20);
    assertEquals(40, c.next().intValue());
    c = map.cursor(0);
    assertEquals(0, c.next().intValue());
    assertEquals(12, map.keyList().indexOf(24));
    assertEquals(24, map.keyList().get(12).intValue());
    assertEquals(-14, map.keyList().indexOf(25));
    assertEquals(map.size(), map.keyList().size());
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 27 with Cursor

use of org.h2.mvstore.Cursor in project h2database by h2database.

the class RegularTable method addIndex.

@Override
public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, boolean create, String indexComment) {
    if (indexType.isPrimaryKey()) {
        for (IndexColumn c : cols) {
            Column column = c.column;
            if (column.isNullable()) {
                throw DbException.get(ErrorCode.COLUMN_MUST_NOT_BE_NULLABLE_1, column.getName());
            }
            column.setPrimaryKey(true);
        }
    }
    boolean isSessionTemporary = isTemporary() && !isGlobalTemporary();
    if (!isSessionTemporary) {
        database.lockMeta(session);
    }
    Index index;
    if (isPersistIndexes() && indexType.isPersistent()) {
        int mainIndexColumn;
        if (database.isStarting() && database.getPageStore().getRootPageId(indexId) != 0) {
            mainIndexColumn = -1;
        } else if (!database.isStarting() && mainIndex.getRowCount(session) != 0) {
            mainIndexColumn = -1;
        } else {
            mainIndexColumn = getMainIndexColumn(indexType, cols);
        }
        if (mainIndexColumn != -1) {
            mainIndex.setMainIndexColumn(mainIndexColumn);
            index = new PageDelegateIndex(this, indexId, indexName, indexType, mainIndex, create, session);
        } else if (indexType.isSpatial()) {
            index = new SpatialTreeIndex(this, indexId, indexName, cols, indexType, true, create, session);
        } else {
            index = new PageBtreeIndex(this, indexId, indexName, cols, indexType, create, session);
        }
    } else {
        if (indexType.isHash()) {
            if (cols.length != 1) {
                throw DbException.getUnsupportedException("hash indexes may index only one column");
            }
            if (indexType.isUnique()) {
                index = new HashIndex(this, indexId, indexName, cols, indexType);
            } else {
                index = new NonUniqueHashIndex(this, indexId, indexName, cols, indexType);
            }
        } else if (indexType.isSpatial()) {
            index = new SpatialTreeIndex(this, indexId, indexName, cols, indexType, false, true, session);
        } else {
            index = new TreeIndex(this, indexId, indexName, cols, indexType);
        }
    }
    if (database.isMultiVersion()) {
        index = new MultiVersionIndex(index, this);
    }
    if (index.needRebuild() && rowCount > 0) {
        try {
            Index scan = getScanIndex(session);
            long remaining = scan.getRowCount(session);
            long total = remaining;
            Cursor cursor = scan.find(session, null, null);
            long i = 0;
            int bufferSize = (int) Math.min(rowCount, database.getMaxMemoryRows());
            ArrayList<Row> buffer = new ArrayList<>(bufferSize);
            String n = getName() + ":" + index.getName();
            int t = MathUtils.convertLongToInt(total);
            while (cursor.next()) {
                database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX, n, MathUtils.convertLongToInt(i++), t);
                Row row = cursor.get();
                buffer.add(row);
                if (buffer.size() >= bufferSize) {
                    addRowsToIndex(session, buffer, index);
                }
                remaining--;
            }
            addRowsToIndex(session, buffer, index);
            if (SysProperties.CHECK && remaining != 0) {
                DbException.throwInternalError("rowcount remaining=" + remaining + " " + getName());
            }
        } catch (DbException e) {
            getSchema().freeUniqueName(indexName);
            try {
                index.remove(session);
            } catch (DbException e2) {
                // this could happen, for example on failure in the storage
                // but if that is not the case it means
                // there is something wrong with the database
                trace.error(e2, "could not remove index");
                throw e2;
            }
            throw e;
        }
    }
    index.setTemporary(isTemporary());
    if (index.getCreateSQL() != null) {
        index.setComment(indexComment);
        if (isSessionTemporary) {
            session.addLocalTempTableIndex(index);
        } else {
            database.addSchemaObject(session, index);
        }
    }
    indexes.add(index);
    setModified();
    return index;
}
Also used : SpatialTreeIndex(org.h2.index.SpatialTreeIndex) PageDelegateIndex(org.h2.index.PageDelegateIndex) NonUniqueHashIndex(org.h2.index.NonUniqueHashIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) ArrayList(java.util.ArrayList) NonUniqueHashIndex(org.h2.index.NonUniqueHashIndex) Index(org.h2.index.Index) HashIndex(org.h2.index.HashIndex) ScanIndex(org.h2.index.ScanIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) TreeIndex(org.h2.index.TreeIndex) PageDataIndex(org.h2.index.PageDataIndex) PageDelegateIndex(org.h2.index.PageDelegateIndex) MultiVersionIndex(org.h2.index.MultiVersionIndex) SpatialTreeIndex(org.h2.index.SpatialTreeIndex) NonUniqueHashIndex(org.h2.index.NonUniqueHashIndex) HashIndex(org.h2.index.HashIndex) Cursor(org.h2.index.Cursor) Constraint(org.h2.constraint.Constraint) DbException(org.h2.message.DbException) TreeIndex(org.h2.index.TreeIndex) SpatialTreeIndex(org.h2.index.SpatialTreeIndex) MultiVersionIndex(org.h2.index.MultiVersionIndex) Row(org.h2.result.Row)

Example 28 with Cursor

use of org.h2.mvstore.Cursor in project h2database by h2database.

the class JoinBatch method getValue.

/**
 * Get the value for the given column.
 *
 * @param filterId table filter id
 * @param column the column
 * @return column value for current row
 */
public Value getValue(int filterId, Column column) {
    if (current == null) {
        return null;
    }
    Object x = current.row(filterId);
    assert x != null;
    Row row = current.isRow(filterId) ? (Row) x : ((Cursor) x).get();
    int columnId = column.getColumnId();
    if (columnId == -1) {
        return ValueLong.get(row.getKey());
    }
    Value value = row.getValue(column.getColumnId());
    if (value == null) {
        throw DbException.throwInternalError("value is null: " + column + " " + row);
    }
    return value;
}
Also used : Value(org.h2.value.Value) Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow)

Example 29 with Cursor

use of org.h2.mvstore.Cursor in project h2database by h2database.

the class JoinBatch method start.

private void start() {
    // initialize current row
    current = new JoinRow(new Object[filters.length]);
    // initialize top cursor
    Cursor cursor;
    if (batchedSubQuery) {
        assert viewTopFutureCursor != null;
        cursor = get(viewTopFutureCursor);
    } else {
        // setup usual index cursor
        TableFilter f = top.filter;
        IndexCursor indexCursor = f.getIndexCursor();
        indexCursor.find(f.getSession(), f.getIndexConditions());
        cursor = indexCursor;
    }
    current.updateRow(top.id, cursor, JoinRow.S_NULL, JoinRow.S_CURSOR);
    // we need fake first row because batchedNext always will move to the
    // next row
    JoinRow fake = new JoinRow(null);
    fake.next = current;
    current = fake;
}
Also used : IndexCursor(org.h2.index.IndexCursor) Cursor(org.h2.index.Cursor) IndexCursor(org.h2.index.IndexCursor) ViewCursor(org.h2.index.ViewCursor)

Example 30 with Cursor

use of org.h2.mvstore.Cursor in project h2database by h2database.

the class JoinBatch method fetchCurrent.

@SuppressWarnings("unchecked")
private void fetchCurrent(final int jfId) {
    assert current.prev == null || current.prev.isRow(jfId) : "prev must be already fetched";
    assert jfId == 0 || current.isRow(jfId - 1) : "left must be already fetched";
    assert !current.isRow(jfId) : "double fetching";
    Object x = current.row(jfId);
    assert x != null : "x null";
    // in case of outer join we don't have any future around empty cursor
    boolean newCursor = x == EMPTY_CURSOR;
    if (newCursor) {
        if (jfId == 0) {
            // the top cursor is new and empty, then the whole select will
            // not produce any rows
            current.drop();
            return;
        }
    } else if (current.isFuture(jfId)) {
        // get cursor from a future
        x = get((Future<Cursor>) x);
        current.updateRow(jfId, x, JoinRow.S_FUTURE, JoinRow.S_CURSOR);
        newCursor = true;
    }
    final JoinFilter jf = filters[jfId];
    Cursor c = (Cursor) x;
    assert c != null;
    JoinFilter join = jf.join;
    while (true) {
        if (c == null || !c.next()) {
            if (newCursor && jf.isOuterJoin()) {
                // replace cursor with null-row
                current.updateRow(jfId, jf.getNullRow(), JoinRow.S_CURSOR, JoinRow.S_ROW);
                c = null;
                newCursor = false;
            } else {
                // cursor is done, drop it
                current.drop();
                return;
            }
        }
        if (!jf.isOk(c == null)) {
            // try another row from the cursor
            continue;
        }
        boolean joinEmpty = false;
        if (join != null && !join.collectSearchRows()) {
            if (join.isOuterJoin()) {
                joinEmpty = true;
            } else {
                // join will fail, try next row in the cursor
                continue;
            }
        }
        if (c != null) {
            current = current.copyBehind(jfId);
            // update jf, set current row from cursor
            current.updateRow(jfId, c.get(), JoinRow.S_CURSOR, JoinRow.S_ROW);
        }
        if (joinEmpty) {
            // update jf.join, set an empty cursor
            current.updateRow(join.id, EMPTY_CURSOR, JoinRow.S_NULL, JoinRow.S_CURSOR);
        }
        return;
    }
}
Also used : Cursor(org.h2.index.Cursor) IndexCursor(org.h2.index.IndexCursor) ViewCursor(org.h2.index.ViewCursor)

Aggregations

Cursor (org.h2.index.Cursor)24 Value (org.h2.value.Value)20 Index (org.h2.index.Index)11 Row (org.h2.result.Row)11 SearchRow (org.h2.result.SearchRow)11 ArrayList (java.util.ArrayList)6 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)6 Constraint (org.h2.constraint.Constraint)5 SingleRowCursor (org.h2.index.SingleRowCursor)5 Column (org.h2.table.Column)5 Session (org.h2.engine.Session)4 MultiVersionIndex (org.h2.index.MultiVersionIndex)4 IndexColumn (org.h2.table.IndexColumn)4 H2PkHashIndex (org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex)3 GridH2Row (org.apache.ignite.internal.processors.query.h2.opt.GridH2Row)3 Database (org.h2.engine.Database)3 ValueLong (org.h2.value.ValueLong)3 PreparedStatement (java.sql.PreparedStatement)2 BitSet (java.util.BitSet)2 UUID (java.util.UUID)2