use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class TableScanResultSet method getNextRowCore.
/**
* Return the next row (if any) from the scan (if open).
*
* @exception StandardException thrown on failure to get next row
*/
public ExecRow getNextRowCore() throws StandardException {
if (isXplainOnlyMode())
return null;
checkCancellationFlag();
if (currentRow == null || scanRepositioned) {
currentRow = getCompactRow(candidate, accessedCols, isKeyed);
}
beginTime = getCurrentTimeMillis();
ExecRow result = null;
if (isOpen && !nextDone) {
/* Only need to do 1 next per scan
* for 1 row scans.
*/
nextDone = oneRowScan;
if (scanControllerOpened) {
boolean moreRows = true;
while (true) {
// ValidateCheckConstraintResultSet..
if (!(moreRows = loopControl(moreRows))) {
break;
}
rowsSeen++;
rowsThisScan++;
/*
** Skip rows where there are start or stop positioners
** that do not implement ordered null semantics and
** there are columns in those positions that contain
** null.
** No need to check if start and stop positions are the
** same, since all predicates in both will be ='s,
** and hence evaluated in the store.
*/
if ((!sameStartStopPosition) && skipRow(candidate)) {
rowsFiltered++;
continue;
}
/* beetle 3865, updateable cursor use index. If we have a hash table that
* holds updated records, and we hit it again, skip it, and remove it from
* hash since we can't hit it again, and we have a space in hash, so can
* stop scanning forward.
*/
if (past2FutureTbl != null) {
RowLocation rowLoc = (RowLocation) currentRow.getColumn(currentRow.nColumns());
if (past2FutureTbl.remove(rowLoc) != null) {
continue;
}
}
result = currentRow;
break;
}
/*
** If we just finished a full scan of the heap, update
** the number of rows in the scan controller.
**
** NOTE: It would be more efficient to only update the
** scan controller if the optimizer's estimated number of
** rows were wrong by more than some threshold (like 10%).
** This would require a little more work than I have the
** time for now, however, as the row estimate that is given
** to this result set is the total number of rows for all
** scans, not the number of rows per scan.
*/
if (!moreRows) {
setRowCountIfPossible(rowsThisScan);
currentRow = null;
}
}
}
setCurrentRow(result);
currentRowIsValid = true;
scanRepositioned = false;
qualify = true;
nextTime += getElapsedMillis(beginTime);
return result;
}
use of org.apache.derby.iapi.types.RowLocation 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.RowLocation 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();
}
}
}
use of org.apache.derby.iapi.types.RowLocation 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.RowLocation in project derby by apache.
the class DeleteResultSet method deleteDeferredRows.
// delete the rows that in case deferred case and
// during cascade delete (All deletes are deferred during cascade action)
void deleteDeferredRows() throws StandardException {
DataValueDescriptor rlColumn;
RowLocation baseRowLocation;
ExecRow defRLRow;
deferredBaseCC = tc.openCompiledConglomerate(false, (TransactionController.OPENMODE_FORUPDATE | TransactionController.OPENMODE_SECONDARY_LOCKED), lockMode, TransactionController.ISOLATION_SERIALIZABLE, constants.heapSCOCI, heapDCOCI);
CursorResultSet rs = rowHolder.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);
rs.open();
while ((defRLRow = rs.getNextRow()) != null) {
rlColumn = defRLRow.getColumn(rlColumnNumber);
baseRowLocation = (RowLocation) (rlColumn).getObject();
/* Get the base row at the given RowLocation */
boolean row_exists = deferredBaseCC.fetch(baseRowLocation, deferredSparseRow.getRowArray(), readBitSet);
// the rows before the dependent result get a chance to delete
if (cascadeDelete && !row_exists)
continue;
if (SanityManager.DEBUG) {
if (!row_exists) {
SanityManager.THROWASSERT("could not find row " + baseRowLocation);
}
}
rc.deleteRow(deferredBaseRow, baseRowLocation);
source.markRowAsDeleted();
}
} finally {
rs.close();
}
}
Aggregations