}
indexTemplateRow = indexRows[0];
// Fill the partial row with nulls of the correct type
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int cdlSize = cdl.size();
for (int index = 0, numSet = 0; index < cdlSize; index++)
{
if (! zeroBasedBitSet.get(index))
{
continue;
}
numSet++;
ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
DataTypeDescriptor dts = cd.getType();
for (int i = 0; i < bulkFetchSize; i++)
{
// Put the column in both the compact and sparse base rows
baseRows[i].setColumn(index + 1,
dts.getNull());
compactBaseRows[i].setColumn(numSet,
baseRows[i].getColumn(index + 1));
}
// Calculate the approximate row size for the index row
approximateRowSize += dts.getTypeId().getApproximateLengthInBytes(dts);
}
// Get an array of RowLocation template
RowLocation rl[] = new RowLocation[bulkFetchSize];
for (int i = 0; i < bulkFetchSize; i++)
{
rl[i] = scan.newRowLocationTemplate();
// Get an index row based on the base row
indexRowGenerator.getIndexRow(compactBaseRows[i], rl[i], indexRows[i], bitSet);
}
/* now that we got indexTemplateRow, done for duplicate index
*/
if (duplicate)
return;
/* For non-unique indexes, we order by all columns + the RID.
* For unique indexes, we just order by the columns.
* We create a unique index observer for unique indexes
* so that we can catch duplicate key.
* We create a basic sort observer for non-unique indexes
* so that we can reuse the wrappers during an external
* sort.
*/
int numColumnOrderings;
SortObserver sortObserver = null;
if (unique)
{
numColumnOrderings = baseColumnPositions.length;
// if the index is a constraint, use constraintname in possible error messagge
String indexOrConstraintName = indexName;
if (conglomerateUUID != null)
{
ConglomerateDescriptor cd = dd.getConglomerateDescriptor(conglomerateUUID);
if ((isConstraint) && (cd != null && cd.getUUID() != null && td != null))
{
ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td,
cd.getUUID());
indexOrConstraintName = conDesc.getConstraintName();
}
}
sortObserver = new UniqueIndexSortObserver(true, isConstraint,
indexOrConstraintName,
indexTemplateRow,
true,
td.getName());
}
else
{
numColumnOrderings = baseColumnPositions.length + 1;
sortObserver = new BasicSortObserver(true, false,
indexTemplateRow,
true);
}
ColumnOrdering[] order = new ColumnOrdering[numColumnOrderings];
for (int i=0; i < numColumnOrderings; i++)
{
order[i] =
new IndexColumnOrder(
i,
unique || i < numColumnOrderings - 1 ?
isAscending[i] : true);
}
// create the sorter
sortId = tc.createSort((Properties)null,
indexTemplateRow.getRowArrayClone(),
order,
sortObserver,
false, // not in order
scan.getEstimatedRowCount(),
approximateRowSize // est row size, -1 means no idea
);
needToDropSort = true;
// Populate sorter and get the output of the sorter into a row
// source. The sorter has the indexed columns only and the columns
// are in the correct order.
rowSource = loadSorter(baseRows, indexRows, tc,
scan, sortId, rl);
conglomId =
tc.createAndLoadConglomerate(
indexType,
indexTemplateRow.getRowArray(), // index row template
order, //colums sort order
indexRowGenerator.getColumnCollationIds(
td.getColumnDescriptorList()),
indexProperties,
TransactionController.IS_DEFAULT, // not temporary
rowSource,
(long[]) null);
}
finally
{
/* close the table scan */
if (scan != null)
scan.close();
/* close the sorter row source before throwing exception */
if (rowSource != null)
rowSource.closeRowSource();
/*
** drop the sort so that intermediate external sort run can be
** removed from disk
*/
if (needToDropSort)
tc.dropSort(sortId);
}
ConglomerateController indexController =
tc.openConglomerate(
conglomId, false, 0, TransactionController.MODE_TABLE,
TransactionController.ISOLATION_SERIALIZABLE);
// Check to make sure that the conglomerate can be used as an index
if ( ! indexController.isKeyed())
{
indexController.close();
throw StandardException.newException(SQLState.LANG_NON_KEYED_INDEX, indexName,
indexType);
}
indexController.close();
//
// Create a conglomerate descriptor with the conglomId filled in and
// add it.
//
ConglomerateDescriptor cgd =
ddg.newConglomerateDescriptor(conglomId, indexName, true,
indexRowGenerator, isConstraint,
conglomerateUUID, td.getUUID(), sd.getUUID() );
dd.addDescriptor(cgd, sd, DataDictionary.SYSCONGLOMERATES_CATALOG_NUM, false, tc);
// add newly added conglomerate to the list of conglomerate descriptors
// in the td.
ConglomerateDescriptorList cdl = td.getConglomerateDescriptorList();
cdl.add(cgd);
CardinalityCounter cCount = (CardinalityCounter)rowSource;
long numRows;
if ((numRows = cCount.getRowCount()) > 0)
{