use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class DataDictionaryImpl method getConstraintDescriptorViaIndex.
/**
* Return a (single or list of) ConstraintDescriptor(s) from
* SYSCONSTRAINTS where the access is from the index to the heap.
*
* @param indexId The id of the index (0 to # of indexes on table) to use
* @param keyRow The supplied ExecIndexRow for search
* @param ti The TabInfoImpl to use
* @param td The TableDescriptor, if supplied.
* @param dList The list to build, if supplied. If null, then caller expects
* a single descriptor
* @param forUpdate Whether or not to open scan for update
*
* @return The last matching descriptor
*
* @exception StandardException Thrown on error
*/
protected ConstraintDescriptor getConstraintDescriptorViaIndex(int indexId, ExecIndexRow keyRow, TabInfoImpl ti, TableDescriptor td, ConstraintDescriptorList dList, boolean forUpdate) throws StandardException {
SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
ConglomerateController heapCC;
ConstraintDescriptor cd = null;
ExecIndexRow indexRow1;
ExecRow outRow;
RowLocation baseRowLocation;
ScanController scanController;
TransactionController tc;
// Get the current transaction controller
tc = getTransactionCompile();
outRow = rf.makeEmptyRow();
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
/* Scan the index and go to the data pages for qualifying rows to
* build the column descriptor.
*/
scanController = tc.openScan(// conglomerate to open
ti.getIndexConglomerate(indexId), // don't hold open across commit
false, (forUpdate) ? TransactionController.OPENMODE_FORUPDATE : 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - exact key match.
keyRow.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier,
null, // stop position - exact key match.
keyRow.getRowArray(), // stopSearchOperation
ScanController.GT);
while (scanController.next()) {
SubConstraintDescriptor subCD = null;
// create an index row template
indexRow1 = getIndexRowFromHeapRow(ti.getIndexRowGenerator(indexId), heapCC.newRowLocationTemplate(), outRow);
scanController.fetch(indexRow1.getRowArray());
baseRowLocation = (RowLocation) indexRow1.getColumn(indexRow1.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, outRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row doesn't exist");
}
switch(rf.getConstraintType(outRow)) {
case DataDictionary.PRIMARYKEY_CONSTRAINT:
case DataDictionary.FOREIGNKEY_CONSTRAINT:
case DataDictionary.UNIQUE_CONSTRAINT:
subCD = getSubKeyConstraint(rf.getConstraintId(outRow), rf.getConstraintType(outRow));
break;
case DataDictionary.CHECK_CONSTRAINT:
subCD = getSubCheckConstraint(rf.getConstraintId(outRow));
break;
default:
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("unexpected value " + "from rf.getConstraintType(outRow)" + rf.getConstraintType(outRow));
}
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(subCD != null, "subCD is expected to be non-null");
}
/* Cache the TD in the SCD so that
* the row factory doesn't need to go
* out to disk to get it.
*/
subCD.setTableDescriptor(td);
cd = (ConstraintDescriptor) rf.buildDescriptor(outRow, subCD, this);
/* If dList is null, then caller only wants a single descriptor - we're done
* else just add the current descriptor to the list.
*/
if (dList == null) {
break;
} else {
dList.add(cd);
}
}
scanController.close();
heapCC.close();
return cd;
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class TabInfoImpl method updateRow.
/**
* Updates a set of base rows in a catalog with the same key on an index
* and updates all the corresponding index rows.
*
* @param key key row
* @param newRows new version of the array of rows
* @param indexNumber index that key operates
* @param indicesToUpdate array of booleans, one for each index on the catalog.
* if a boolean is true, that means we must update the
* corresponding index because changes in the newRow
* affect it.
* @param colsToUpdate array of ints indicating which columns (1 based)
* to update. If null, do all.
* @param tc transaction controller
*
* @exception StandardException Thrown on failure
*/
void updateRow(ExecIndexRow key, ExecRow[] newRows, int indexNumber, boolean[] indicesToUpdate, int[] colsToUpdate, TransactionController tc) throws StandardException {
ConglomerateController heapCC;
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(indicesToUpdate.length == crf.getNumIndexes(), "Wrong number of indices.");
}
RowChanger rc = getRowChanger(tc, colsToUpdate, baseRow);
// Row level locking
rc.openForUpdate(indicesToUpdate, TransactionController.MODE_RECORD, true);
/* Open the heap conglomerate */
heapCC = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
drivingScan = tc.openScan(// conglomerate to open
getIndexConglomerate(indexNumber), // don't hold open across commit
false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
int rowNum = 0;
while (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
rc.updateRow(baseRow, (rowNum == newRows.length - 1) ? newRows[rowNum] : newRows[rowNum++], baseRowLocation);
}
rc.finish();
heapCC.close();
drivingScan.close();
rc.close();
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class TabInfoImpl method getRowInternal.
/**
* @exception StandardException Thrown on failure
*/
private ExecRow getRowInternal(TransactionController tc, ConglomerateController heapCC, ExecIndexRow key, int indexNumber, RowLocation[] rl) throws StandardException {
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
drivingScan = tc.openScan(getIndexConglomerate(indexNumber), // don't hold open across commit
false, // open for read
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
try {
if (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
rl[0] = baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
return baseRow;
} else {
return null;
}
} finally {
drivingScan.close();
}
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class AlterTableConstantAction method compressTable.
/**
* routine to process compress table or ALTER TABLE <t> DROP COLUMN <c>;
* <p>
* Uses class level variable "compressTable" to determine if processing
* compress table or drop column:
* if (!compressTable)
* must be drop column.
* <p>
* Handles rebuilding of base conglomerate and all necessary indexes.
*/
private void compressTable() throws StandardException {
long newHeapConglom;
Properties properties = new Properties();
RowLocation rl;
if (SanityManager.DEBUG) {
if (lockGranularity != '\0') {
SanityManager.THROWASSERT("lockGranularity expected to be '\0', not " + lockGranularity);
}
SanityManager.ASSERT(!compressTable || columnInfo == null, "columnInfo expected to be null");
SanityManager.ASSERT(constraintActions == null, "constraintActions expected to be null");
}
ExecRow emptyHeapRow = td.getEmptyExecRow();
int[] collation_ids = td.getColumnCollationIds();
compressHeapCC = tc.openConglomerate(td.getHeapConglomerateId(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
rl = compressHeapCC.newRowLocationTemplate();
// Get the properties on the old heap
compressHeapCC.getInternalTablePropertySet(properties);
compressHeapCC.close();
compressHeapCC = null;
// Create an array to put base row template
baseRow = new ExecRow[bulkFetchSize];
baseRowArray = new DataValueDescriptor[bulkFetchSize][];
validRow = new boolean[bulkFetchSize];
/* Set up index info */
getAffectedIndexes();
// Get an array of RowLocation template
compressRL = new RowLocation[bulkFetchSize];
indexRows = new ExecIndexRow[numIndexes];
if (!compressTable) {
// must be a drop column, thus the number of columns in the
// new template row and the collation template is one less.
ExecRow newRow = activation.getExecutionFactory().getValueRow(emptyHeapRow.nColumns() - 1);
int[] new_collation_ids = new int[collation_ids.length - 1];
for (int i = 0; i < newRow.nColumns(); i++) {
newRow.setColumn(i + 1, i < droppedColumnPosition - 1 ? emptyHeapRow.getColumn(i + 1) : emptyHeapRow.getColumn(i + 1 + 1));
new_collation_ids[i] = collation_ids[(i < droppedColumnPosition - 1) ? i : (i + 1)];
}
emptyHeapRow = newRow;
collation_ids = new_collation_ids;
}
setUpAllSorts(emptyHeapRow, rl);
// Start by opening a full scan on the base table.
openBulkFetchScan(td.getHeapConglomerateId());
// Get the estimated row count for the sorters
estimatedRowCount = compressHeapGSC.getEstimatedRowCount();
// Create the array of base row template
for (int i = 0; i < bulkFetchSize; i++) {
// create a base row template
baseRow[i] = td.getEmptyExecRow();
baseRowArray[i] = baseRow[i].getRowArray();
compressRL[i] = compressHeapGSC.newRowLocationTemplate();
}
newHeapConglom = tc.createAndLoadConglomerate("heap", emptyHeapRow.getRowArray(), // column sort order - not required for heap
null, collation_ids, properties, TransactionController.IS_DEFAULT, this, (long[]) null);
closeBulkFetchScan();
// Set the "estimated" row count
ScanController compressHeapSC = tc.openScan(newHeapConglom, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, (DataValueDescriptor[]) null, 0, (Qualifier[][]) null, (DataValueDescriptor[]) null, 0);
compressHeapSC.setEstimatedRowCount(rowCount);
compressHeapSC.close();
// RESOLVE DJD CLEANUP
compressHeapSC = null;
/*
** Inform the data dictionary that we are about to write to it.
** There are several calls to data dictionary "get" methods here
** that might be done in "read" mode in the data dictionary, but
** it seemed safer to do this whole operation in "write" mode.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
// Update all indexes
if (compressIRGs.length > 0) {
updateAllIndexes(newHeapConglom, dd);
}
/* Update the DataDictionary
* RESOLVE - this will change in 1.4 because we will get
* back the same conglomerate number
*/
// Get the ConglomerateDescriptor for the heap
long oldHeapConglom = td.getHeapConglomerateId();
ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom);
// Update sys.sysconglomerates with new conglomerate #
dd.updateConglomerateDescriptor(cd, newHeapConglom, tc);
// Now that the updated information is available in the system tables,
// we should invalidate all statements that use the old conglomerates
dm.invalidateFor(td, DependencyManager.COMPRESS_TABLE, lcc);
// Drop the old conglomerate
tc.dropConglomerate(oldHeapConglom);
cleanUp();
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class T_QualifierTest method t_scanNext.
private static boolean t_scanNext(TransactionController tc, long conglomid, DataValueDescriptor[] fetch_template, DataValueDescriptor[] start_key, int start_op, Qualifier[][] qualifier, DataValueDescriptor[] stop_key, int stop_op, int expect_numrows, int input_expect_key, int order) throws StandardException, T_Fail {
HashSet set = null;
boolean ordered = (order == T_QualifierTest.ORDER_FORWARD || order == T_QualifierTest.ORDER_DESC);
int expect_key = input_expect_key;
if (!ordered) {
set = create_hash_set(input_expect_key, expect_numrows, order);
}
/**
********************************************************************
* Forward scan test case
**********************************************************************
*/
ScanController scan = tc.openScan(conglomid, false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, start_key, start_op, qualifier, stop_key, stop_op);
long key = -42;
int numrows = 0;
while (scan.next()) {
scan.fetch(fetch_template);
key = ((SQLLongint) (fetch_template[2])).getLong();
if (ordered) {
if (key != expect_key) {
return (fail("(t_scanNext) wrong key, expected (" + expect_key + ")" + "but got (" + key + ")."));
} else {
if (order == ORDER_DESC)
expect_key--;
else
expect_key++;
}
} else {
if (!set.remove(key)) {
return (fail("(t_scanNext) wrong key, expected (" + expect_key + ")" + "but got (" + key + ")."));
}
}
numrows++;
}
scan.close();
if (numrows != expect_numrows) {
return (fail("(t_scanNext) wrong number of rows. Expected " + expect_numrows + " rows, but got " + numrows + "rows."));
}
return (true);
}
Aggregations