Search in sources :

Example 41 with Cursor

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

the class ScriptCommand method generateInsertValues.

private int generateInsertValues(int count, Table table) throws IOException {
    PlanItem plan = table.getBestPlanItem(session, null, null, -1, null, null);
    Index index = plan.getIndex();
    Cursor cursor = index.find(session, null, null);
    Column[] columns = table.getColumns();
    StatementBuilder buff = new StatementBuilder("INSERT INTO ");
    buff.append(table.getSQL()).append('(');
    for (Column col : columns) {
        buff.appendExceptFirst(", ");
        buff.append(Parser.quoteIdentifier(col.getName()));
    }
    buff.append(") VALUES");
    if (!simple) {
        buff.append('\n');
    }
    buff.append('(');
    String ins = buff.toString();
    buff = null;
    while (cursor.next()) {
        Row row = cursor.get();
        if (buff == null) {
            buff = new StatementBuilder(ins);
        } else {
            buff.append(",\n(");
        }
        for (int j = 0; j < row.getColumnCount(); j++) {
            if (j > 0) {
                buff.append(", ");
            }
            Value v = row.getValue(j);
            if (v.getPrecision() > lobBlockSize) {
                int id;
                if (v.getType() == Value.CLOB) {
                    id = writeLobStream(v);
                    buff.append("SYSTEM_COMBINE_CLOB(").append(id).append(')');
                } else if (v.getType() == Value.BLOB) {
                    id = writeLobStream(v);
                    buff.append("SYSTEM_COMBINE_BLOB(").append(id).append(')');
                } else {
                    buff.append(v.getSQL());
                }
            } else {
                buff.append(v.getSQL());
            }
        }
        buff.append(')');
        count++;
        if ((count & 127) == 0) {
            checkCanceled();
        }
        if (simple || buff.length() > Constants.IO_BUFFER_SIZE) {
            add(buff.toString(), true);
            buff = null;
        }
    }
    if (buff != null) {
        add(buff.toString(), true);
    }
    return count;
}
Also used : Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) StatementBuilder(org.h2.util.StatementBuilder) Value(org.h2.value.Value) PlanItem(org.h2.table.PlanItem) Index(org.h2.index.Index) ValueString(org.h2.value.ValueString) Row(org.h2.result.Row) Cursor(org.h2.index.Cursor) Constraint(org.h2.constraint.Constraint)

Example 42 with Cursor

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

the class Database method removeMeta.

/**
 * Remove the given object from the meta data.
 *
 * @param session the session
 * @param id the id of the object to remove
 */
public synchronized void removeMeta(Session session, int id) {
    if (id > 0 && !starting) {
        SearchRow r = meta.getTemplateSimpleRow(false);
        r.setValue(0, ValueInt.get(id));
        boolean wasLocked = lockMeta(session);
        Cursor cursor = metaIdIndex.find(session, r, r);
        if (cursor.next()) {
            if (SysProperties.CHECK) {
                if (lockMode != Constants.LOCK_MODE_OFF && !wasLocked) {
                    throw DbException.throwInternalError();
                }
            }
            Row found = cursor.get();
            meta.removeRow(session, found);
            if (isMultiVersion()) {
                // TODO this should work without MVCC, but avoid risks at
                // the moment
                session.log(meta, UndoLogRecord.DELETE, found);
            }
            if (SysProperties.CHECK) {
                checkMetaFree(session, id);
            }
        } else if (!wasLocked) {
            unlockMetaDebug(session);
            // must not keep the lock if it was not locked
            // otherwise updating sequences may cause a deadlock
            meta.unlock(session);
            session.unlock(meta);
        }
        objectIds.clear(id);
    }
}
Also used : Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) Cursor(org.h2.index.Cursor) SearchRow(org.h2.result.SearchRow)

Example 43 with Cursor

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

the class Database method open.

private synchronized void open(int traceLevelFile, int traceLevelSystemOut) {
    if (persistent) {
        String dataFileName = databaseName + Constants.SUFFIX_OLD_DATABASE_FILE;
        boolean existsData = FileUtils.exists(dataFileName);
        String pageFileName = databaseName + Constants.SUFFIX_PAGE_FILE;
        String mvFileName = databaseName + Constants.SUFFIX_MV_FILE;
        boolean existsPage = FileUtils.exists(pageFileName);
        boolean existsMv = FileUtils.exists(mvFileName);
        if (existsData && (!existsPage && !existsMv)) {
            throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, "Old database: " + dataFileName + " - please convert the database " + "to a SQL script and re-create it.");
        }
        if (existsPage && !FileUtils.canWrite(pageFileName)) {
            readOnly = true;
        }
        if (existsMv && !FileUtils.canWrite(mvFileName)) {
            readOnly = true;
        }
        if (existsPage && !existsMv) {
            dbSettings.mvStore = false;
        }
        if (readOnly) {
            if (traceLevelFile >= TraceSystem.DEBUG) {
                String traceFile = Utils.getProperty("java.io.tmpdir", ".") + "/" + "h2_" + System.currentTimeMillis();
                traceSystem = new TraceSystem(traceFile + Constants.SUFFIX_TRACE_FILE);
            } else {
                traceSystem = new TraceSystem(null);
            }
        } else {
            traceSystem = new TraceSystem(databaseName + Constants.SUFFIX_TRACE_FILE);
        }
        traceSystem.setLevelFile(traceLevelFile);
        traceSystem.setLevelSystemOut(traceLevelSystemOut);
        trace = traceSystem.getTrace(Trace.DATABASE);
        trace.info("opening {0} (build {1})", databaseName, Constants.BUILD_ID);
        if (autoServerMode) {
            if (readOnly || fileLockMethod == FileLockMethod.NO || fileLockMethod == FileLockMethod.SERIALIZED || fileLockMethod == FileLockMethod.FS || !persistent) {
                throw DbException.getUnsupportedException("autoServerMode && (readOnly || " + "fileLockMethod == NO || " + "fileLockMethod == SERIALIZED || " + "fileLockMethod == FS || " + "inMemory)");
            }
        }
        String lockFileName = databaseName + Constants.SUFFIX_LOCK_FILE;
        if (readOnly) {
            if (FileUtils.exists(lockFileName)) {
                throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Lock file exists: " + lockFileName);
            }
        }
        if (!readOnly && fileLockMethod != FileLockMethod.NO) {
            if (fileLockMethod != FileLockMethod.FS) {
                lock = new FileLock(traceSystem, lockFileName, Constants.LOCK_SLEEP);
                lock.lock(fileLockMethod);
                if (autoServerMode) {
                    startServer(lock.getUniqueId());
                }
            }
        }
        if (SysProperties.MODIFY_ON_WRITE) {
            while (isReconnectNeeded()) {
            // wait until others stopped writing
            }
        } else {
            while (isReconnectNeeded() && !beforeWriting()) {
            // wait until others stopped writing and
            // until we can write (the file is not yet open -
            // no need to re-connect)
            }
        }
        deleteOldTempFiles();
        starting = true;
        if (SysProperties.MODIFY_ON_WRITE) {
            try {
                getPageStore();
            } catch (DbException e) {
                if (e.getErrorCode() != ErrorCode.DATABASE_IS_READ_ONLY) {
                    throw e;
                }
                pageStore = null;
                while (!beforeWriting()) {
                // wait until others stopped writing and
                // until we can write (the file is not yet open -
                // no need to re-connect)
                }
                getPageStore();
            }
        } else {
            getPageStore();
        }
        starting = false;
        if (mvStore == null) {
            writer = WriterThread.create(this, writeDelay);
        } else {
            setWriteDelay(writeDelay);
        }
    } else {
        if (autoServerMode) {
            throw DbException.getUnsupportedException("autoServerMode && inMemory");
        }
        traceSystem = new TraceSystem(null);
        trace = traceSystem.getTrace(Trace.DATABASE);
        if (dbSettings.mvStore) {
            getPageStore();
        }
    }
    systemUser = new User(this, 0, SYSTEM_USER_NAME, true);
    mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true);
    infoSchema = new Schema(this, -1, "INFORMATION_SCHEMA", systemUser, true);
    schemas.put(mainSchema.getName(), mainSchema);
    schemas.put(infoSchema.getName(), infoSchema);
    publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true);
    roles.put(Constants.PUBLIC_ROLE_NAME, publicRole);
    systemUser.setAdmin(true);
    systemSession = new Session(this, systemUser, ++nextSessionId);
    lobSession = new Session(this, systemUser, ++nextSessionId);
    CreateTableData data = new CreateTableData();
    ArrayList<Column> cols = data.columns;
    Column columnId = new Column("ID", Value.INT);
    columnId.setNullable(false);
    cols.add(columnId);
    cols.add(new Column("HEAD", Value.INT));
    cols.add(new Column("TYPE", Value.INT));
    cols.add(new Column("SQL", Value.STRING));
    boolean create = true;
    if (pageStore != null) {
        create = pageStore.isNew();
    }
    data.tableName = "SYS";
    data.id = 0;
    data.temporary = false;
    data.persistData = persistent;
    data.persistIndexes = persistent;
    data.create = create;
    data.isHidden = true;
    data.session = systemSession;
    meta = mainSchema.createTable(data);
    IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId });
    metaIdIndex = meta.addIndex(systemSession, "SYS_ID", 0, pkCols, IndexType.createPrimaryKey(false, false), true, null);
    objectIds.set(0);
    starting = true;
    Cursor cursor = metaIdIndex.find(systemSession, null, null);
    ArrayList<MetaRecord> records = New.arrayList();
    while (cursor.next()) {
        MetaRecord rec = new MetaRecord(cursor.get());
        objectIds.set(rec.getId());
        records.add(rec);
    }
    Collections.sort(records);
    synchronized (systemSession) {
        for (MetaRecord rec : records) {
            rec.execute(this, systemSession, eventListener);
        }
    }
    if (mvStore != null) {
        mvStore.initTransactions();
        mvStore.removeTemporaryMaps(objectIds);
    }
    recompileInvalidViews(systemSession);
    starting = false;
    if (!readOnly) {
        // set CREATE_BUILD in a new database
        String name = SetTypes.getTypeName(SetTypes.CREATE_BUILD);
        if (settings.get(name) == null) {
            Setting setting = new Setting(this, allocateObjectId(), name);
            setting.setIntValue(Constants.BUILD_ID);
            lockMeta(systemSession);
            addDatabaseObject(systemSession, setting);
        }
        // mark all ids used in the page store
        if (pageStore != null) {
            BitSet f = pageStore.getObjectIds();
            for (int i = 0, len = f.length(); i < len; i++) {
                if (f.get(i) && !objectIds.get(i)) {
                    trace.info("unused object id: " + i);
                    objectIds.set(i);
                }
            }
        }
    }
    getLobStorage().init();
    systemSession.commit(true);
    trace.info("opened {0}", databaseName);
    if (checkpointAllowed > 0) {
        afterWriting();
    }
}
Also used : Schema(org.h2.schema.Schema) BitSet(java.util.BitSet) TraceSystem(org.h2.message.TraceSystem) CreateTableData(org.h2.command.ddl.CreateTableData) Cursor(org.h2.index.Cursor) Constraint(org.h2.constraint.Constraint) DbException(org.h2.message.DbException) IndexColumn(org.h2.table.IndexColumn) IndexColumn(org.h2.table.IndexColumn) Column(org.h2.table.Column) FileLock(org.h2.store.FileLock)

Example 44 with Cursor

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

the class ConstraintReferential method existsRow.

private boolean existsRow(Session session, Index searchIndex, SearchRow check, Row excluding) {
    Table searchTable = searchIndex.getTable();
    searchTable.lock(session, false, false);
    Cursor cursor = searchIndex.find(session, check, check);
    while (cursor.next()) {
        SearchRow found;
        found = cursor.getSearchRow();
        if (excluding != null && found.getKey() == excluding.getKey()) {
            continue;
        }
        Column[] cols = searchIndex.getColumns();
        boolean allEqual = true;
        int len = Math.min(columns.length, cols.length);
        for (int i = 0; i < len; i++) {
            int idx = cols[i].getColumnId();
            Value c = check.getValue(idx);
            Value f = found.getValue(idx);
            if (searchTable.compareTypeSafe(c, f) != 0) {
                allEqual = false;
                break;
            }
        }
        if (allEqual) {
            return true;
        }
    }
    return false;
}
Also used : Table(org.h2.table.Table) Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) Value(org.h2.value.Value) Cursor(org.h2.index.Cursor) SearchRow(org.h2.result.SearchRow)

Example 45 with Cursor

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

the class PageStore method compact.

/**
 * Shrink the file so there are no empty pages at the end.
 *
 * @param compactMode 0 if no compacting should happen, otherwise
 * TransactionCommand.SHUTDOWN_COMPACT or TransactionCommand.SHUTDOWN_DEFRAG
 */
public synchronized void compact(int compactMode) {
    if (!database.getSettings().pageStoreTrim) {
        return;
    }
    if (SysProperties.MODIFY_ON_WRITE && readMode && compactMode == 0) {
        return;
    }
    openForWriting();
    // find the last used page
    int lastUsed = -1;
    for (int i = getFreeListId(pageCount); i >= 0; i--) {
        lastUsed = getFreeList(i).getLastUsed();
        if (lastUsed != -1) {
            break;
        }
    }
    // open a new log at the very end
    // (to be truncated later)
    writeBack();
    log.free();
    recoveryRunning = true;
    try {
        logFirstTrunkPage = lastUsed + 1;
        allocatePage(logFirstTrunkPage);
        log.openForWriting(logFirstTrunkPage, true);
        // ensure the free list is backed up again
        log.checkpoint();
    } finally {
        recoveryRunning = false;
    }
    long start = System.nanoTime();
    boolean isCompactFully = compactMode == CommandInterface.SHUTDOWN_COMPACT;
    boolean isDefrag = compactMode == CommandInterface.SHUTDOWN_DEFRAG;
    if (database.getSettings().defragAlways) {
        isCompactFully = isDefrag = true;
    }
    int maxCompactTime = database.getSettings().maxCompactTime;
    int maxMove = database.getSettings().maxCompactCount;
    if (isCompactFully || isDefrag) {
        maxCompactTime = Integer.MAX_VALUE;
        maxMove = Integer.MAX_VALUE;
    }
    int blockSize = isCompactFully ? COMPACT_BLOCK_SIZE : 1;
    int firstFree = MIN_PAGE_COUNT;
    for (int x = lastUsed, j = 0; x > MIN_PAGE_COUNT && j < maxMove; x -= blockSize) {
        for (int full = x - blockSize + 1; full <= x; full++) {
            if (full > MIN_PAGE_COUNT && isUsed(full)) {
                synchronized (this) {
                    firstFree = getFirstFree(firstFree);
                    if (firstFree == -1 || firstFree >= full) {
                        j = maxMove;
                        break;
                    }
                    if (compact(full, firstFree)) {
                        j++;
                        long now = System.nanoTime();
                        if (now > start + TimeUnit.MILLISECONDS.toNanos(maxCompactTime)) {
                            j = maxMove;
                            break;
                        }
                    }
                }
            }
        }
    }
    if (isDefrag) {
        log.checkpoint();
        writeBack();
        cache.clear();
        ArrayList<Table> tables = database.getAllTablesAndViews(false);
        recordedPagesList = New.arrayList();
        recordedPagesIndex = new IntIntHashMap();
        recordPageReads = true;
        Session sysSession = database.getSystemSession();
        for (Table table : tables) {
            if (!table.isTemporary() && TableType.TABLE == table.getTableType()) {
                Index scanIndex = table.getScanIndex(sysSession);
                Cursor cursor = scanIndex.find(sysSession, null, null);
                while (cursor.next()) {
                    cursor.get();
                }
                for (Index index : table.getIndexes()) {
                    if (index != scanIndex && index.canScan()) {
                        cursor = index.find(sysSession, null, null);
                        while (cursor.next()) {
                        // the data is already read
                        }
                    }
                }
            }
        }
        recordPageReads = false;
        int target = MIN_PAGE_COUNT - 1;
        int temp = 0;
        for (int i = 0, size = recordedPagesList.size(); i < size; i++) {
            log.checkpoint();
            writeBack();
            int source = recordedPagesList.get(i);
            Page pageSource = getPage(source);
            if (!pageSource.canMove()) {
                continue;
            }
            while (true) {
                Page pageTarget = getPage(++target);
                if (pageTarget == null || pageTarget.canMove()) {
                    break;
                }
            }
            if (target == source) {
                continue;
            }
            temp = getFirstFree(temp);
            if (temp == -1) {
                DbException.throwInternalError("no free page for defrag");
            }
            cache.clear();
            swap(source, target, temp);
            int index = recordedPagesIndex.get(target);
            if (index != IntIntHashMap.NOT_FOUND) {
                recordedPagesList.set(index, source);
                recordedPagesIndex.put(source, index);
            }
            recordedPagesList.set(i, target);
            recordedPagesIndex.put(target, i);
        }
        recordedPagesList = null;
        recordedPagesIndex = null;
    }
    // TODO can most likely be simplified
    checkpoint();
    log.checkpoint();
    writeIndexRowCounts();
    log.checkpoint();
    writeBack();
    commit(pageStoreSession);
    writeBack();
    log.checkpoint();
    log.free();
    // truncate the log
    recoveryRunning = true;
    try {
        setLogFirstPage(++logKey, 0, 0);
    } finally {
        recoveryRunning = false;
    }
    writeBack();
    for (int i = getFreeListId(pageCount); i >= 0; i--) {
        lastUsed = getFreeList(i).getLastUsed();
        if (lastUsed != -1) {
            break;
        }
    }
    int newPageCount = lastUsed + 1;
    if (newPageCount < pageCount) {
        freed.set(newPageCount, pageCount, false);
    }
    pageCount = newPageCount;
    // the easiest way to remove superfluous entries
    freeLists.clear();
    trace.debug("pageCount: " + pageCount);
    long newLength = (long) pageCount << pageSizeShift;
    if (file.length() != newLength) {
        file.setLength(newLength);
        writeCount++;
    }
}
Also used : IntIntHashMap(org.h2.util.IntIntHashMap) RegularTable(org.h2.table.RegularTable) Table(org.h2.table.Table) Index(org.h2.index.Index) PageIndex(org.h2.index.PageIndex) PageDelegateIndex(org.h2.index.PageDelegateIndex) MultiVersionIndex(org.h2.index.MultiVersionIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) PageDataIndex(org.h2.index.PageDataIndex) Cursor(org.h2.index.Cursor) Session(org.h2.engine.Session)

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