// If the container is being created in the same operation, don't log
// page allocation.
if (createConglom)
mode |= ContainerHandle.MODE_CREATE_UNLOGGED;
OpenConglomerate open_conglom = new OpenHeap();
if (open_conglom.init(
(ContainerHandle) null,
heap,
heap.format_ids,
xact_manager,
xact_manager.getRawStoreXact(),
false,
mode,
TransactionController.MODE_TABLE,
xact_manager.getRawStoreXact().newLockingPolicy(
LockingPolicy.MODE_CONTAINER,
TransactionController.ISOLATION_SERIALIZABLE, true),
(DynamicCompiledOpenConglomInfo) null) == null)
{
throw StandardException.newException(
SQLState.HEAP_CONTAINER_NOT_FOUND,
new Long(heap.id.getContainerId()));
}
this.init(open_conglom);
// For bulk loading, we always use only brand new page because the row
// insertion itself is not logged. We cannot pollute pages with
// pre-existing data with unlogged rows because nobody is going to wipe
// out these rows if the transaction rolls back. We are counting on
// the allocation page rollback to obliterate these rows if the
// transaction fails, or, in the CREAT_UNLOGGED case, the whole
// container to be removed.
Page page = open_conglom.getContainer().addPage();
boolean callbackWithRowLocation = rowSource.needsRowLocation();
RecordHandle rh;
HeapRowLocation rowlocation;
if (callbackWithRowLocation)
rowlocation = new HeapRowLocation();
else
rowlocation = null;
FormatableBitSet validColumns = rowSource.getValidColumns();
try
{
// get the next row and its valid columns from the rowSource
DataValueDescriptor[] row;
while ((row = rowSource.getNextRowFromRowSource()) != null)
{
num_rows_loaded++;
if (SanityManager.DEBUG)
{
// Make sure valid columns are in the list. The RowUtil
// call is too expensive to make in a released system for
// every insert.
int invalidColumn =
RowUtil.columnOutOfRange(
row, validColumns, heap.format_ids.length);
if (invalidColumn >= 0)
{
throw(StandardException.newException(
SQLState.HEAP_TEMPLATE_MISMATCH,
new Long(invalidColumn),
new Long(heap.format_ids.length)));
}
}
// Insert it onto this page as long as it can fit more rows.
if ((rh = page.insert(
row, validColumns, Page.INSERT_DEFAULT,
AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD))
== null)
{
// Insert faied, row did not fit. Get a new page.
page.unlatch();
page = null;
page = open_conglom.getContainer().addPage();
// RESOLVE (mikem) - no long rows yet so the following code
// will get an exception from the raw store for a row that
// does not fit on a page.
//
// Multi-thread considerations aside, the raw store will
// guarantee that any size row will fit on an empty page.
rh = page.insert(
row, validColumns, Page.INSERT_OVERFLOW,
AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
}
// Else, the row fit. If we are expected to call back with the
// row location, do so. All the while keep the page latched
// and go for the next row.
if (callbackWithRowLocation)
{
rowlocation.setFrom(rh);
rowSource.rowLocation(rowlocation);
}
}
page.unlatch();
page = null;
// Done with the container, now we need to flush it to disk since
// it is unlogged.
if (!heap.isTemporary())
open_conglom.getContainer().flushContainer();
}
finally
{
// If an error happened here, don't bother flushing the
// container since the changes should be rolled back anyhow.