Search in sources :

Example 1 with CursorResultSet

use of org.apache.derby.iapi.sql.execute.CursorResultSet in project derby by apache.

the class InsertResultSet method normalInsertCore.

// Do the work for a "normal" insert
private void normalInsertCore(LanguageConnectionContext lcc, boolean firstExecute) throws StandardException {
    boolean setUserIdentity = constants.hasAutoincrement() && isSingleRowResultSet();
    ExecRow deferredRowBuffer;
    long user_autoinc = 0;
    /* Get or re-use the row changer.
		 */
    if (firstExecute) {
        rowChanger = lcc.getLanguageConnectionFactory().getExecutionFactory().getRowChanger(heapConglom, constants.heapSCOCI, heapDCOCI, constants.irgs, constants.indexCIDS, constants.indexSCOCIs, indexDCOCIs, // number of columns in partial row meaningless for insert
        0, tc, // Changed column ids
        null, constants.getStreamStorableHeapColIds(), activation);
        rowChanger.setIndexNames(constants.indexNames);
    }
    /* decode lock mode for the execution isolation level */
    int lockMode = decodeLockMode(constants.lockMode);
    rowChanger.open(lockMode);
    /* The source does not know whether or not we are doing a
		 * deferred mode insert.  If we are, then we must clear the
		 * index scan info from the activation so that the row changer
		 * does not re-use that information (which won't be valid for
		 * a deferred mode insert).
		 */
    if (constants.deferred) {
        activation.clearIndexScanInfo();
    }
    if (fkInfoArray != null) {
        if (fkChecker == null) {
            fkChecker = new RISetChecker(lcc, tc, fkInfoArray);
        } else {
            fkChecker.reopen();
        }
    }
    if (firstExecute && constants.deferred) {
        Properties properties = new Properties();
        // Get the properties on the old heap
        rowChanger.getHeapConglomerateController().getInternalTablePropertySet(properties);
        /*
			** If deferred we save a copy of the entire row.
			*/
        rowHolder = new TemporaryRowHolderImpl(activation, properties, resultDescription);
        rowChanger.setRowHolder(rowHolder);
    }
    firstExecuteSpecialHandlingAutoGen(firstExecute, rowChanger, constants.targetUUID);
    while (row != null) {
        // auto-generated key columns.
        if (activation.getAutoGeneratedKeysResultsetMode() && autoGeneratedKeysColumnIndexes.length > 0) {
            autoGeneratedKeysRowsHolder.insert(getCompactRow(row, autoGeneratedKeysColumnIndexes));
        }
        // fill in columns that are computed from expressions on other columns
        evaluateGenerationClauses(generationClauses, activation, sourceResultSet, row, false);
        /*
			** If we're doing a deferred insert, insert into the temporary
			** conglomerate.  Otherwise, insert directly into the permanent
			** conglomerates using the rowChanger.
			*/
        if (constants.deferred) {
            rowHolder.insert(row);
        } else {
            // Immediate mode violations will throw, so we only ever
            // see false here with deferred constraint mode for one or more
            // of the constraints being checked.
            boolean allOk = evaluateCheckConstraints();
            if (fkChecker != null) {
                fkChecker.doFKCheck(activation, row);
            }
            // Objectify any streaming columns that are indexed.
            if (constants.irgs.length > 0) {
                DataValueDescriptor[] rowArray = row.getRowArray();
                for (int i = 0; i < rowArray.length; i++) {
                    // System.out.println("checking " + i);
                    if (!constants.indexedCols[i]) {
                        continue;
                    }
                    if (rowArray[i] instanceof StreamStorable)
                        rowArray[i].getObject();
                }
            }
            if (allOk) {
                rowChanger.insertRow(row, false);
            } else {
                RowLocation offendingRow = rowChanger.insertRow(row, true);
                deferredChecks = DeferredConstraintsMemory.rememberCheckViolations(lcc, constants.targetUUID, schemaName, tableName, deferredChecks, violatingCheckConstraints, offendingRow, new CheckInfo[1]);
            }
        }
        rowCount++;
        if (setUserIdentity) {
            dd = lcc.getDataDictionary();
            td = dd.getTableDescriptor(constants.targetUUID);
            int maxColumns = td.getMaxColumnID();
            int col;
            for (col = 1; col <= maxColumns; col++) {
                ColumnDescriptor cd = td.getColumnDescriptor(col);
                if (cd.isAutoincrement()) {
                    break;
                }
            }
            if (col <= maxColumns) {
                DataValueDescriptor dvd = row.cloneColumn(col);
                user_autoinc = dvd.getLong();
            }
        }
        // No need to do a next on a single row source
        if (constants.singleRowSource) {
            row = null;
        } else {
            row = getNextRowCore(sourceResultSet);
        }
    }
    /*
		** If it's a deferred insert, scan the temporary conglomerate and
		** insert the rows into the permanent conglomerates using rowChanger.
		*/
    if (constants.deferred) {
        if (triggerInfo != null) {
            Vector<AutoincrementCounter> v = null;
            if (aiCache != null) {
                v = new Vector<AutoincrementCounter>();
                for (int i = 0; i < aiCache.length; i++) {
                    String s, t, c;
                    if (aiCache[i] == null)
                        continue;
                    Long initialValue = lcc.lastAutoincrementValue((s = constants.getSchemaName()), (t = constants.getTableName()), (c = constants.getColumnName(i)));
                    AutoincrementCounter aic = new AutoincrementCounter(initialValue, constants.getAutoincIncrement(i), aiCache[i].getLong(), s, t, c, i + 1);
                    v.addElement(aic);
                }
            }
            if (triggerActivator == null) {
                triggerActivator = new TriggerEventActivator(lcc, constants.targetUUID, triggerInfo, TriggerExecutionContext.INSERT_EVENT, activation, v);
            } else {
                triggerActivator.reopen();
            }
            // fire BEFORE trigger, do this before checking constraints
            triggerActivator.notifyEvent(TriggerEvents.BEFORE_INSERT, (CursorResultSet) null, rowHolder.getResultSet(), (int[]) null);
        }
        CursorResultSet rs = rowHolder.getResultSet();
        try {
            rs.open();
            while ((deferredRowBuffer = rs.getNextRow()) != null) {
                // we have to set the source row so the check constraint
                // sees the correct row.
                sourceResultSet.setCurrentRow(deferredRowBuffer);
                boolean allOk = evaluateCheckConstraints();
                if (allOk) {
                    rowChanger.insertRow(deferredRowBuffer, false);
                } else {
                    RowLocation offendingRow = rowChanger.insertRow(deferredRowBuffer, true);
                    deferredChecks = DeferredConstraintsMemory.rememberCheckViolations(lcc, constants.targetUUID, schemaName, tableName, deferredChecks, violatingCheckConstraints, offendingRow, new CheckInfo[1]);
                }
            }
        } finally {
            sourceResultSet.clearCurrentRow();
            rs.close();
        }
        if (fkChecker != null) {
            /*
				** Second scan to make sure all the foreign key
				** constraints are ok.  We have to do this after
				** we have completed the inserts in case of self
				** referencing constraints.
				*/
            rs = rowHolder.getResultSet();
            try {
                rs.open();
                while ((deferredRowBuffer = rs.getNextRow()) != null) {
                    fkChecker.doFKCheck(activation, deferredRowBuffer);
                }
            } finally {
                rs.close();
            }
        }
        // fire AFTER trigger
        if (triggerActivator != null) {
            triggerActivator.notifyEvent(TriggerEvents.AFTER_INSERT, (CursorResultSet) null, rowHolder.getResultSet(), (int[]) null);
        }
    }
    if (rowHolder != null) {
        rowHolder.close();
    // rowHolder kept across opens
    }
    if (fkChecker != null) {
        fkChecker.close();
        fkChecker = null;
    }
    if (setIdentity)
        lcc.setIdentityValue(identityVal);
    else /*
                 * find the value of the identity column from the user inserted value
                 * and do a lcc.setIdentityValue(<user_value>);
                 */
    if (setUserIdentity) {
        lcc.setIdentityValue(user_autoinc);
    }
}
Also used : CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) Properties(java.util.Properties) LanguageProperties(org.apache.derby.iapi.sql.LanguageProperties) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) StreamStorable(org.apache.derby.iapi.services.io.StreamStorable) CheckInfo(org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) RowLocation(org.apache.derby.iapi.types.RowLocation)

Example 2 with CursorResultSet

use of org.apache.derby.iapi.sql.execute.CursorResultSet in project derby by apache.

the class InternalTriggerExecutionContext method getOldRowSet.

/**
 * Returns a result set row the old images of the changed rows.
 * For a row trigger, the result set will have a single row.  For
 * a statement trigger, this result set has every row that has
 * changed or will change.  If a statement trigger does not affect
 * a row, then the result set will be empty (i.e. ResultSet.next()
 * will return false).
 *
 * @return the ResultSet containing before images of the rows
 * changed by the triggering event.
 *
 * @exception SQLException if called after the triggering event has
 * completed
 */
public java.sql.ResultSet getOldRowSet() throws SQLException {
    ensureProperContext();
    if (beforeResultSet == null) {
        return null;
    }
    try {
        CursorResultSet brs = beforeResultSet;
        /* We should really shallow clone the result set, because it could be used
			 * at multiple places independently in trigger action.  This is a bug found
			 * during the fix of beetle 4373.
			 */
        if (brs instanceof TemporaryRowHolderResultSet)
            brs = (CursorResultSet) ((TemporaryRowHolderResultSet) brs).clone();
        else if (brs instanceof TableScanResultSet)
            brs = (CursorResultSet) ((TableScanResultSet) brs).clone();
        brs.open();
        java.sql.ResultSet rs = cc.getResultSet(brs);
        resultSetVector.addElement(rs);
        return rs;
    } catch (StandardException se) {
        throw PublicAPI.wrapStandardException(se);
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ResultSet(java.sql.ResultSet)

Example 3 with CursorResultSet

use of org.apache.derby.iapi.sql.execute.CursorResultSet in project derby by apache.

the class InternalTriggerExecutionContext method getNewRowSet.

/**
 * Returns a result set row the new images of the changed rows.
 * For a row trigger, the result set will have a single row.  For
 * a statement trigger, this result set has every row that has
 * changed or will change.  If a statement trigger does not affect
 * a row, then the result set will be empty (i.e. ResultSet.next()
 * will return false).
 *
 * @return the ResultSet containing after images of the rows
 * changed by the triggering event.
 *
 * @exception SQLException if called after the triggering event has
 * completed
 */
public java.sql.ResultSet getNewRowSet() throws SQLException {
    ensureProperContext();
    if (afterResultSet == null) {
        return null;
    }
    try {
        /* We should really shallow clone the result set, because it could be used
			 * at multiple places independently in trigger action.  This is a bug found
			 * during the fix of beetle 4373.
			 */
        CursorResultSet ars = afterResultSet;
        if (ars instanceof TemporaryRowHolderResultSet)
            ars = (CursorResultSet) ((TemporaryRowHolderResultSet) ars).clone();
        else if (ars instanceof TableScanResultSet)
            ars = (CursorResultSet) ((TableScanResultSet) ars).clone();
        ars.open();
        java.sql.ResultSet rs = cc.getResultSet(ars);
        resultSetVector.addElement(rs);
        return rs;
    } catch (StandardException se) {
        throw PublicAPI.wrapStandardException(se);
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ResultSet(java.sql.ResultSet)

Example 4 with CursorResultSet

use of org.apache.derby.iapi.sql.execute.CursorResultSet in project derby by apache.

the class UpdateResultSet method runChecker.

void runChecker(boolean restrictCheckOnly) throws StandardException {
    /*
		** For a deferred update, make sure that there
		** aren't any primary keys that were removed which
		** are referenced.  
		*/
    if (deferred && updatingReferencedKey) {
        ExecRow deletedRow;
        CursorResultSet deletedRows;
        /*
			** For each referenced key that was modified
			*/
        for (int i = 0; i < fkInfoArray.length; i++) {
            if (fkInfoArray[i].type == FKInfo.FOREIGN_KEY) {
                continue;
            }
            deletedRows = deletedRowHolder.getResultSet();
            try {
                /*
					** For each delete row
					*/
                deletedRows.open();
                while ((deletedRow = deletedRows.getNextRow()) != null) {
                    if (!foundRow(deletedRow, fkInfoArray[i].colArray, insertedRowHolder)) {
                        // Argument "1" below: If a PK referenced by an FK
                        // is deferred, require at least one to be present
                        // in the primary table since we have modified the
                        // row's PK, unless postCheck == true, in which the
                        // call to postChecks does the actual checking, and
                        // we need at least one row intact to fulfill the
                        // constraint.
                        riChecker.doRICheck(activation, i, deletedRow, restrictCheckOnly, 1);
                    }
                }
                if (restrictCheckOnly) {
                    riChecker.postCheck(i);
                }
            } finally {
                deletedRows.close();
            }
        }
    }
    /*
		** For a deferred update, make sure that there
		** aren't any foreign keys that were added that
 		** aren't referenced.  
		*/
    if (deferred && updatingForeignKey) {
        ExecRow insertedRow;
        CursorResultSet insertedRows;
        /*
			** For each foreign key that was modified
			*/
        for (int i = 0; i < fkInfoArray.length; i++) {
            if (fkInfoArray[i].type == FKInfo.REFERENCED_KEY) {
                continue;
            }
            insertedRows = insertedRowHolder.getResultSet();
            try {
                /*
					** For each inserted row
					*/
                insertedRows.open();
                while ((insertedRow = insertedRows.getNextRow()) != null) {
                    if (!foundRow(insertedRow, fkInfoArray[i].colArray, deletedRowHolder)) {
                        riChecker.doRICheck(activation, i, insertedRow, restrictCheckOnly, // N/A, not referenced key
                        0);
                    }
                }
            } finally {
                insertedRows.close();
            }
        }
    }
}
Also used : CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow)

Example 5 with CursorResultSet

use of org.apache.derby.iapi.sql.execute.CursorResultSet 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

CursorResultSet (org.apache.derby.iapi.sql.execute.CursorResultSet)13 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)10 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)5 StandardException (org.apache.derby.shared.common.error.StandardException)5 Properties (java.util.Properties)4 RowLocation (org.apache.derby.iapi.types.RowLocation)3 ResultSet (java.sql.ResultSet)2 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)2 CheckInfo (org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo)2 IOException (java.io.IOException)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 StreamStorable (org.apache.derby.iapi.services.io.StreamStorable)1 GeneratedMethod (org.apache.derby.iapi.services.loader.GeneratedMethod)1 Activation (org.apache.derby.iapi.sql.Activation)1 LanguageProperties (org.apache.derby.iapi.sql.LanguageProperties)1 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)1 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)1 TemporaryRowHolder (org.apache.derby.iapi.sql.execute.TemporaryRowHolder)1 BooleanDataValue (org.apache.derby.iapi.types.BooleanDataValue)1