Search in sources :

Example 56 with FormatableBitSet

use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.

the class BTreeController method load.

/**
 * Load rows from rowSource into the opened btree.
 * <p>
 * Efficiently load rows into the already opened btree.  The btree must
 * be table locked, as no row locks will be requested by this routine.
 * On exit from this routine the conglomerate will be closed (on both
 * error or success).
 * <p>
 * This routine does an almost bottom up build of a btree.  It assumes
 * all rows arrive in sorted order, and inserts them directly into the
 * next (to the right) spot in the current leaf until there is no space.
 * Then it calls the generic split code to add the next leaf (RESOLVE -
 * in the future we could optimize this to split bottom up rather than
 * top down for create index).
 *
 * @exception StandardException Standard exception policy.  If conglomerate
 *                              supports uniqueness checks and has been
 *                              created to disallow duplicates, and one of
 *                              the rows being loaded had key columns which
 *                              were duplicate of a row already in the
 *                              conglomerate, then raise
 *                              SQLState.STORE_CONGLOMERATE_DUPLICATE_KEY_EXCEPTION.
 *
 * @see org.apache.derby.iapi.store.access.conglomerate.Conglomerate#load
 */
public long load(TransactionManager xact_manager, boolean createConglom, RowLocationRetRowSource rowSource) throws StandardException {
    long num_rows_loaded = 0;
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(createConglom, "Cannot load a btree incrementally - it must either be entirely logged, or entirely not logged.  Doesn't make sense to log only the allocation when one cannot guarantee to not touch any pre-existing pages");
    }
    if (scratch_template == null) {
        scratch_template = runtime_mem.get_template(getRawTran());
    }
    LeafControlRow current_leaf = null;
    try {
        // Btree must just have been created and empty, so there must
        // be one root leaf page which is empty except for the control row.
        current_leaf = (LeafControlRow) ControlRow.get(this, BTree.ROOTPAGEID);
        int current_insert_slot = 1;
        if (SanityManager.DEBUG) {
            // root must be empty except for the control row.
            SanityManager.ASSERT(current_leaf.page.recordCount() == 1);
        }
        // now loop thru the row source and insert into the btree
        FormatableBitSet validColumns = rowSource.getValidColumns();
        // get the next row and its valid columns from the rowSource
        DataValueDescriptor[] row;
        while ((row = rowSource.getNextRowFromRowSource()) != null) {
            num_rows_loaded++;
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(validColumns == null, "Does not support partial row");
            }
            while (true) {
                if (do_load_insert(row, current_leaf, current_insert_slot)) {
                    // row inserted successfully.
                    break;
                } else {
                    // if insert fails, do a split pass. There is an edge
                    // case where multiple split passes are necessary if
                    // branch splits are necessary, thus the loop.  It is
                    // most likely that only a single split pass will be
                    // necessary.
                    current_leaf = do_load_split(row, current_leaf);
                    current_insert_slot = current_leaf.page.recordCount();
                }
            }
            current_insert_slot++;
        }
        current_leaf.release();
        current_leaf = null;
        // Loading done, must flush all pages to disk since it is unlogged.
        if (!this.getConglomerate().isTemporary())
            container.flushContainer();
    } finally {
        this.close();
    }
    return (num_rows_loaded);
}
Also used : FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 57 with FormatableBitSet

use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.

the class DeleteOperation method writeOptionalDataToBuffer.

/**
 *	    if logical undo, writes out the row that was deleted
 *
 *		@exception IOException Can be thrown by any of the methods of ObjectOutput
 *		@exception StandardException Standard Derby policy.
 */
private void writeOptionalDataToBuffer(RawTransaction t) throws StandardException, IOException {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(this.page != null);
    }
    DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
    int optionalDataStart = logBuffer.getPosition();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(optionalDataStart == 0, "Buffer for writing the optional data should start at position 0");
    }
    if (undo != null)
        this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, recordId, (FormatableBitSet) null, logBuffer, (RecordHandle) null);
    int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
    if (SanityManager.DEBUG) {
        if (optionalDataLength != logBuffer.getUsed())
            SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
    }
    // set the position to the beginning of the buffer
    logBuffer.setPosition(optionalDataStart);
    this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, optionalDataLength);
}
Also used : DynamicByteArrayOutputStream(org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) ByteArray(org.apache.derby.iapi.util.ByteArray) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet)

Example 58 with FormatableBitSet

use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.

the class TemporaryRowHolderResultSet method setupPositionBasedScan.

// open the scan of the temporary heap and the position index
private void setupPositionBasedScan(long position) throws StandardException {
    // incase nothing is inserted yet into the temporary row holder
    if (holder.getTemporaryConglomId() == 0)
        return;
    if (heapCC == null) {
        heapCC = tc.openConglomerate(holder.getTemporaryConglomId(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
    }
    currentRow = rowArray[0].getNewNullRow();
    indexRow = new DataValueDescriptor[2];
    indexRow[0] = new SQLLongint(position);
    indexRow[1] = heapCC.newRowLocationTemplate();
    DataValueDescriptor[] searchRow = new DataValueDescriptor[1];
    searchRow[0] = new SQLLongint(position);
    if (indexsc == null) {
        indexsc = tc.openScan(positionIndexConglomId, // don't hold open across commit
        false, // for read
        0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, // all fields as objects
        (FormatableBitSet) null, // start position - first row
        searchRow, // startSearchOperation
        ScanController.GE, // scanQualifier,
        null, // stop position - through last row
        null, // stopSearchOperation
        ScanController.GT);
    } else {
        indexsc.reopenScan(// startKeyValue
        searchRow, // startSearchOp
        ScanController.GE, // qualifier
        null, // stopKeyValue
        null, // stopSearchOp
        ScanController.GT);
    }
}
Also used : SQLLongint(org.apache.derby.iapi.types.SQLLongint) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 59 with FormatableBitSet

use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.

the class UpdateResultSet method collectAffectedRows.

public boolean collectAffectedRows() throws StandardException {
    boolean rowsFound = false;
    row = getNextRowCore(sourceResultSet);
    if (row != null)
        rowsFound = true;
    else {
        activation.addWarning(StandardException.newWarning(SQLState.LANG_NO_ROW_FOUND));
    }
    // beetle 3865, update cursor use index.
    TableScanResultSet tableScan = (TableScanResultSet) activation.getForUpdateIndexScan();
    boolean notifyCursor = (tableScan != null);
    boolean checkStream = (deferred && rowsFound && !constants.singleRowSource);
    FormatableBitSet streamCols = (checkStream ? checkStreamCols() : null);
    checkStream = (streamCols != null);
    while (row != null) {
        evaluateGenerationClauses(generationClauses, activation, sourceResultSet, row, true);
        /*
			** If we're doing deferred update, write the new row and row
			** location to the temporary conglomerate.  If we're not doing
			** deferred update, update the permanent conglomerates now
			** using the RowChanger.
			*/
        if (deferred) {
            /*
				** If we have a before trigger, we must evaluate the 
				** check constraint after we have executed the trigger.
				** Note that we have compiled checkGM accordingly (to
				** handle the different row shape if we are evaluating
				** against the input result set or a temporary row holder
				** result set).
				*/
            if (triggerInfo == null) {
                boolean allOk = evaluateCheckConstraints();
                if (!allOk) {
                    DataValueDescriptor[] rw = row.getRowArray();
                    SQLRef r = (SQLRef) rw[rw.length - 1];
                    RowLocation baseRowLocation = (RowLocation) r.getObject();
                    deferredChecks = DeferredConstraintsMemory.rememberCheckViolations(lcc, constants.targetUUID, constants.getSchemaName(), constants.getTableName(), deferredChecks, violatingCheckConstraints, baseRowLocation, new CheckInfo[1]);
                }
            }
            /*
				** We are going to only save off the updated
				** columns and the RID.  For a trigger, all columns
				** were marked as needed so we'll copy them all.
				*/
            RowUtil.copyRefColumns(deferredTempRow, row, numberOfBaseColumns, numberOfBaseColumns + 1);
            if (checkStream)
                objectifyStream(deferredTempRow, streamCols);
            insertedRowHolder.insert(deferredTempRow);
            /*
				** Grab a copy of the row to delete.  We are
				** going to use this for deferred RI checks.
				*/
            if (beforeUpdateCopyRequired) {
                RowUtil.copyRefColumns(oldDeletedRow, row, numberOfBaseColumns);
                deletedRowHolder.insert(oldDeletedRow);
            }
            /*
				** If we haven't already, lets get a template to
				** use as a template for our rescan of the base table.
				** Do this now while we have a real row to use
				** as a copy.
				**
				** There is one less column in the base row than
				** there is in source row, because the base row
				** doesn't contain the row location.
				*/
            if (deferredBaseRow == null) {
                deferredBaseRow = RowUtil.getEmptyValueRow(numberOfBaseColumns, lcc);
                RowUtil.copyCloneColumns(deferredBaseRow, row, numberOfBaseColumns);
                /*
					** While we're here, let's also create a sparse row for
					** fetching from the store.
					*/
                deferredSparseRow = makeDeferredSparseRow(deferredBaseRow, baseRowReadList, lcc);
            }
        } else {
            boolean allOk = evaluateCheckConstraints();
            /* Get the RowLocation to update
			 	* NOTE - Column #s in the Row are 1 based.
			 	*/
            RowLocation baseRowLocation = (RowLocation) (row.getColumn(resultWidth)).getObject();
            if (!allOk) {
                deferredChecks = DeferredConstraintsMemory.rememberCheckViolations(lcc, constants.targetUUID, constants.getSchemaName(), constants.getTableName(), deferredChecks, violatingCheckConstraints, baseRowLocation, new CheckInfo[1]);
            }
            RowUtil.copyRefColumns(newBaseRow, row, numberOfBaseColumns, numberOfBaseColumns);
            if (riChecker != null) {
                /*
					** Make sure all foreign keys in the new row
					** are maintained.  Note that we don't bother 
					** checking primary/unique keys that are referenced
					** here.  The reason is that if we are updating
					** a referenced key, we'll be updating in deferred
					** mode, so we wont get here.
					*/
                riChecker.doFKCheck(activation, newBaseRow);
            }
            sourceResultSet.updateRow(newBaseRow, rowChanger);
            rowChanger.updateRow(row, newBaseRow, baseRowLocation);
            // beetle 3865, update cursor use index.
            if (notifyCursor)
                notifyForUpdateCursor(row.getRowArray(), newBaseRow.getRowArray(), baseRowLocation, tableScan);
        }
        rowCount++;
        // No need to do a next on a single row source
        if (constants.singleRowSource) {
            row = null;
        } else {
            row = getNextRowCore(sourceResultSet);
        }
    }
    if (rowCount == 1 && constants.hasAutoincrement())
        lcc.setIdentityValue(identityVal);
    return rowsFound;
}
Also used : CheckInfo(org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) RowLocation(org.apache.derby.iapi.types.RowLocation) SQLRef(org.apache.derby.iapi.types.SQLRef)

Example 60 with FormatableBitSet

use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.

the class UpdateResultSet method updateDeferredRows.

void updateDeferredRows() throws StandardException {
    if (deferred) {
        // we already have everything locked
        deferredBaseCC = tc.openCompiledConglomerate(false, (TransactionController.OPENMODE_SECONDARY_LOCKED | TransactionController.OPENMODE_FORUPDATE), lockMode, TransactionController.ISOLATION_SERIALIZABLE, constants.heapSCOCI, heapDCOCI);
        CursorResultSet rs = insertedRowHolder.getResultSet();
        try {
            /*
				** We need to do a fetch doing a partial row
				** read.  We need to shift our 1-based bit
				** set to a zero based bit set like the store
				** expects.
				*/
            FormatableBitSet readBitSet = RowUtil.shift(baseRowReadList, 1);
            ExecRow deferredTempRow2;
            rs.open();
            while ((deferredTempRow2 = rs.getNextRow()) != null) {
                /*
					** Check the constraint now if we have triggers.
					** Otherwise we evaluated them as we read the
					** rows in from the source.
					*/
                boolean allOk = true;
                if (triggerInfo != null) {
                    sourceResultSet.setCurrentRow(deferredTempRow);
                    allOk = evaluateCheckConstraints();
                }
                /* 
					** The last column is a Ref, which contains a 
					** RowLocation.
					*/
                DataValueDescriptor rlColumn = deferredTempRow2.getColumn(numberOfBaseColumns + 1);
                RowLocation baseRowLocation = (RowLocation) (rlColumn).getObject();
                if (!allOk) {
                    deferredChecks = DeferredConstraintsMemory.rememberCheckViolations(lcc, constants.targetUUID, constants.getSchemaName(), constants.getTableName(), deferredChecks, violatingCheckConstraints, baseRowLocation, new CheckInfo[1]);
                }
                /* Get the base row at the given RowLocation */
                boolean row_exists = deferredBaseCC.fetch(baseRowLocation, deferredSparseRow.getRowArray(), readBitSet);
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(row_exists, "did not find base row in deferred update");
                }
                /*
					** Copy the columns from the temp row to the base row.
					** The base row has fewer columns than the temp row,
					** because it doesn't contain the row location.
					*/
                RowUtil.copyRefColumns(newBaseRow, deferredTempRow2, numberOfBaseColumns);
                rowChanger.updateRow(deferredBaseRow, newBaseRow, baseRowLocation);
            }
        } finally {
            sourceResultSet.clearCurrentRow();
            rs.close();
        }
    }
}
Also used : CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) CheckInfo(org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) RowLocation(org.apache.derby.iapi.types.RowLocation)

Aggregations

FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)146 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)36 RowLocation (org.apache.derby.iapi.types.RowLocation)32 SQLLongint (org.apache.derby.iapi.types.SQLLongint)25 ScanController (org.apache.derby.iapi.store.access.ScanController)24 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)23 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)18 StandardException (org.apache.derby.shared.common.error.StandardException)17 RawTransaction (org.apache.derby.iapi.store.raw.xact.RawTransaction)15 RawContainerHandle (org.apache.derby.iapi.store.raw.data.RawContainerHandle)13 TransactionController (org.apache.derby.iapi.store.access.TransactionController)12 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)11 SQLInteger (org.apache.derby.iapi.types.SQLInteger)11 UUID (org.apache.derby.catalog.UUID)10 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)10 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)9 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)7 SQLChar (org.apache.derby.iapi.types.SQLChar)7 Properties (java.util.Properties)6 ContextManager (org.apache.derby.iapi.services.context.ContextManager)6