use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class T_ConsistencyChecker method insertBadRowLocation.
/**
* Get the first row from the heap and insert it into
* the specified index, with a bad row location, without
* inserting it into the heap or the other indexes on the table.
*
* @param schemaName The schema name.
* @param tableName The table name.
* @param indexName The specified index.
*
* @exception StandardException Thrown on error
*/
public static void insertBadRowLocation(String schemaName, String tableName, String indexName) throws StandardException {
T_ConsistencyChecker t_cc = new T_ConsistencyChecker(schemaName, tableName, indexName);
t_cc.getContexts();
t_cc.getDescriptors();
/* Open a scan on the heap */
ScanController heapScan = t_cc.openUnqualifiedHeapScan();
// Get the RowLocation
RowLocation baseRL = heapScan.newRowLocationTemplate();
RowLocation badRL = heapScan.newRowLocationTemplate();
heapScan.close();
/* Open a scan on the index */
ExecRow indexRow = t_cc.getIndexTemplateRow(baseRL);
ScanController indexScan = t_cc.openUnqualifiedIndexScan();
// Move to the 1st row in the index
indexScan.next();
// Fetch the 1st row
indexScan.fetch(indexRow.getRowArray());
indexScan.close();
// Insert another copy of the 1st row into the index with a bad row location
int keyLength = t_cc.getIndexDescriptor().getIndexDescriptor().baseColumnPositions().length;
indexRow.setColumn(keyLength + 1, badRL);
ConglomerateController indexCC = t_cc.openIndexCC();
indexCC.insert(indexRow.getRowArray());
indexCC.close();
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class T_ConsistencyChecker method getHeapRowOfNulls.
/* Get a heap row full of nulls */
private ExecRow getHeapRowOfNulls() throws StandardException {
ConglomerateController baseCC;
ExecRow baseRow;
/* Open the heap for reading */
baseCC = tc.openConglomerate(td.getHeapConglomerateId(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
/* Get a row template for the base table */
baseRow = lcc.getLanguageConnectionFactory().getExecutionFactory().getValueRow(td.getNumberOfColumns());
/* Fill the row with nulls of the correct type */
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
DataTypeDescriptor dts = cd.getType();
baseRow.setColumn(cd.getPosition(), dts.getNull());
}
baseCC.close();
return baseRow;
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class T_ConsistencyChecker method reinsertFirstHeapRow.
/**
* Get the first row from the heap and insert it into
* the heap again, without
* inserting it from the indexes on the table.
*
* @param schemaName The schema name.
* @param tableName The table name.
*
* @exception StandardException Thrown on error
*/
public static void reinsertFirstHeapRow(String schemaName, String tableName) throws StandardException {
T_ConsistencyChecker t_cc = new T_ConsistencyChecker(schemaName, tableName, null);
t_cc.getContexts();
t_cc.getDescriptors();
/* Open a scan on the heap */
ScanController heapScan = t_cc.openUnqualifiedHeapScan();
// Move to the 1st row in the heap
heapScan.next();
// Fetch the 1st row
ExecRow firstRow = t_cc.getHeapRowOfNulls();
heapScan.fetch(firstRow.getRowArray());
heapScan.close();
// Insert another copy of the 1st row into the heap
ConglomerateController heapCC = t_cc.openHeapCC();
heapCC.insert(firstRow.getRowArray());
heapCC.close();
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class T_ConsistencyChecker method getIndexTemplateRow.
/* Get a template row for the specified index */
private ExecRow getIndexTemplateRow(RowLocation baseRL) throws StandardException {
int[] baseColumnPositions;
int baseColumns = 0;
ExecRow indexScanTemplate;
baseColumnPositions = id.getIndexDescriptor().baseColumnPositions();
baseColumns = baseColumnPositions.length;
FormatableBitSet indexColsBitSet = new FormatableBitSet();
for (int i = 0; i < baseColumns; i++) {
indexColsBitSet.grow(baseColumnPositions[i]);
indexColsBitSet.set(baseColumnPositions[i] - 1);
}
/* Get a row template */
indexScanTemplate = lcc.getLanguageConnectionFactory().getExecutionFactory().getValueRow(baseColumns + 1);
/* Fill the row with nulls of the correct type */
for (int column = 0; column < baseColumns; column++) {
/* Column positions in the data dictionary are one-based */
ColumnDescriptor cd = td.getColumnDescriptor(baseColumnPositions[column]);
DataTypeDescriptor dts = cd.getType();
indexScanTemplate.setColumn(column + 1, dts.getNull());
}
/* Set the row location in the last column of the index row */
indexScanTemplate.setColumn(baseColumns + 1, baseRL);
return indexScanTemplate;
}
use of org.apache.derby.iapi.sql.execute.ExecRow in project derby by apache.
the class AlterTableConstantAction method defragmentRows.
/**
* Defragment rows in the given table.
* <p>
* Scans the rows at the end of a table and moves them to free spots
* towards the beginning of the table. In the same transaction all
* associated indexes are updated to reflect the new location of the
* base table row.
* <p>
* After a defragment pass, if was possible, there will be a set of
* empty pages at the end of the table which can be returned to the
* operating system by calling truncateEnd(). The allocation bit
* maps will be set so that new inserts will tend to go to empty and
* half filled pages starting from the front of the conglomerate.
*
* @param tc transaction controller to use to do updates.
*/
private void defragmentRows(TransactionController tc) throws StandardException {
GroupFetchScanController base_group_fetch_cc = null;
int num_indexes = 0;
int[][] index_col_map = null;
ScanController[] index_scan = null;
ConglomerateController[] index_cc = null;
DataValueDescriptor[][] index_row = null;
TransactionController nested_tc = null;
try {
nested_tc = tc.startNestedUserTransaction(false, true);
switch(td.getTableType()) {
/* Skip views and vti tables */
case TableDescriptor.VIEW_TYPE:
case TableDescriptor.VTI_TYPE:
return;
// DERBY-719,DERBY-720
default:
break;
}
/* Get a row template for the base table */
ExecRow br = lcc.getLanguageConnectionFactory().getExecutionFactory().getValueRow(td.getNumberOfColumns());
/* Fill the row with nulls of the correct type */
for (ColumnDescriptor cd : td.getColumnDescriptorList()) {
br.setColumn(cd.getPosition(), cd.getType().getNull());
}
DataValueDescriptor[][] row_array = new DataValueDescriptor[100][];
row_array[0] = br.getRowArray();
RowLocation[] old_row_location_array = new RowLocation[100];
RowLocation[] new_row_location_array = new RowLocation[100];
// Create the following 3 arrays which will be used to update
// each index as the scan moves rows about the heap as part of
// the compress:
// index_col_map - map location of index cols in the base row,
// ie. index_col_map[0] is column offset of 1st
// key column in base row. All offsets are 0
// based.
// index_scan - open ScanController used to delete old index row
// index_cc - open ConglomerateController used to insert new
// row
ConglomerateDescriptor[] conglom_descriptors = td.getConglomerateDescriptors();
// conglom_descriptors has an entry for the conglomerate and each
// one of it's indexes.
num_indexes = conglom_descriptors.length - 1;
// if indexes exist, set up data structures to update them
if (num_indexes > 0) {
// allocate arrays
index_col_map = new int[num_indexes][];
index_scan = new ScanController[num_indexes];
index_cc = new ConglomerateController[num_indexes];
index_row = new DataValueDescriptor[num_indexes][];
setup_indexes(nested_tc, td, index_col_map, index_scan, index_cc, index_row);
}
/* Open the heap for reading */
base_group_fetch_cc = nested_tc.defragmentConglomerate(td.getHeapConglomerateId(), false, true, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
int num_rows_fetched;
while ((num_rows_fetched = base_group_fetch_cc.fetchNextGroup(row_array, old_row_location_array, new_row_location_array)) != 0) {
if (num_indexes > 0) {
for (int row = 0; row < num_rows_fetched; row++) {
for (int index = 0; index < num_indexes; index++) {
fixIndex(row_array[row], index_row[index], old_row_location_array[row], new_row_location_array[row], index_cc[index], index_scan[index], index_col_map[index]);
}
}
}
}
// TODO - It would be better if commits happened more frequently
// in the nested transaction, but to do that there has to be more
// logic to catch a ddl that might jump in the middle of the
// above loop and invalidate the various table control structures
// which are needed to properly update the indexes. For example
// the above loop would corrupt an index added midway through
// the loop if not properly handled. See DERBY-1188.
nested_tc.commit();
} finally {
/* Clean up before we leave */
if (base_group_fetch_cc != null) {
base_group_fetch_cc.close();
base_group_fetch_cc = null;
}
if (num_indexes > 0) {
for (int i = 0; i < num_indexes; i++) {
if (index_scan != null && index_scan[i] != null) {
index_scan[i].close();
index_scan[i] = null;
}
if (index_cc != null && index_cc[i] != null) {
index_cc[i].close();
index_cc[i] = null;
}
}
}
if (nested_tc != null) {
nested_tc.destroy();
}
}
}
Aggregations