use of org.apache.derby.iapi.types.SQLRef 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;
}
use of org.apache.derby.iapi.types.SQLRef in project derby by apache.
the class MergeResultSet method collectAffectedRows.
/**
* <p>
* Loop through the rows in the driving left join.
* </p>
*/
boolean collectAffectedRows() throws StandardException {
DataValueDescriptor rlColumn;
boolean rowsFound = false;
while (true) {
// may need to objectify stream columns here.
// see DMLWriteResultSet.getNextRowCoure(NoPutResultSet)
_row = _drivingLeftJoin.getNextRowCore();
if (_row == null) {
break;
}
// By convention, the last column for the driving left join contains a data value
// containing the RowLocation of the target row.
rowsFound = true;
rlColumn = _row.getColumn(_row.nColumns());
SQLRef baseRowLocation = null;
boolean matched = false;
if (rlColumn != null) {
if (!rlColumn.isNull()) {
matched = true;
// change the HeapRowLocation into a SQLRef, something which the
// temporary table can (de)serialize correctly
baseRowLocation = new SQLRef((RowLocation) rlColumn.getObject());
_row.setColumn(_row.nColumns(), baseRowLocation);
}
}
// find the first clause which applies to this row
MatchingClauseConstantAction matchingClause = null;
int clauseCount = _constants.matchingClauseCount();
int clauseIdx = 0;
for (; clauseIdx < clauseCount; clauseIdx++) {
MatchingClauseConstantAction candidate = _constants.getMatchingClause(clauseIdx);
boolean isWhenMatchedClause = false;
switch(candidate.clauseType()) {
case ConstantAction.WHEN_MATCHED_THEN_UPDATE:
case ConstantAction.WHEN_MATCHED_THEN_DELETE:
isWhenMatchedClause = true;
break;
}
boolean considerClause = (matched == isWhenMatchedClause);
if (considerClause) {
if (candidate.evaluateRefinementClause(activation)) {
matchingClause = candidate;
break;
}
}
}
if (matchingClause != null) {
// this will raise an exception if the row is being touched more than once
if (baseRowLocation != null) {
addSubjectRow(baseRowLocation);
}
//
for (int i = 0; i < _row.nColumns(); i++) {
DataValueDescriptor dvd = _row.getColumn(i + 1);
if (dvd instanceof StreamStorable) {
if (dvd.hasStream()) {
_row.setColumn(i + 1, dvd.cloneValue(true));
}
}
}
_thenRows[clauseIdx] = matchingClause.bufferThenRow(activation, _thenRows[clauseIdx], _row);
_rowCount++;
}
}
return rowsFound;
}
use of org.apache.derby.iapi.types.SQLRef in project derby by apache.
the class TemporaryRowHolderImpl method isRowAlreadyExist.
/**
* Maintain an unique index based on the input row's row location in the
* base table, this index make sures that we don't insert duplicate rows
* into the temporary heap.
* @param inputRow the row we are inserting to temporary row holder
* @exception StandardException on error
*/
private boolean isRowAlreadyExist(ExecRow inputRow) throws StandardException {
DataValueDescriptor rlColumn;
RowLocation baseRowLocation;
rlColumn = inputRow.getColumn(inputRow.nColumns());
if (CID != 0 && rlColumn instanceof SQLRef) {
baseRowLocation = (RowLocation) (rlColumn).getObject();
if (!uniqueIndexCreated) {
TransactionController tc = activation.getTransactionController();
int numKeys = 2;
uniqueIndexRow = new DataValueDescriptor[numKeys];
uniqueIndexRow[0] = baseRowLocation;
uniqueIndexRow[1] = baseRowLocation;
Properties props = makeIndexProperties(uniqueIndexRow, CID);
uniqueIndexConglomId = tc.createConglomerate("BTREE", uniqueIndexRow, null, // no collation needed for index on row locations.
null, props, (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT));
uniqueIndex_cc = tc.openConglomerate(uniqueIndexConglomId, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
uniqueIndexCreated = true;
}
uniqueIndexRow[0] = baseRowLocation;
uniqueIndexRow[1] = baseRowLocation;
// Insert the row into the secondary index.
int status;
if ((status = uniqueIndex_cc.insert(uniqueIndexRow)) != 0) {
if (status == ConglomerateController.ROWISDUPLICATE) {
// okay; we don't insert duplicates
return true;
} else {
if (SanityManager.DEBUG) {
if (status != 0) {
SanityManager.THROWASSERT("got funky status (" + status + ") back from " + "Unique Index insert()");
}
}
}
}
}
return false;
}
Aggregations