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);
}
}
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);
}
}
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);
}
}
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();
}
}
}
}
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();
}
}
}
Aggregations