You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by fu...@apache.org on 2005/03/03 02:30:45 UTC

svn commit: r155990 [6/15] - in incubator/derby/code/trunk: ./ java/testing/ java/testing/org/apache/derbyTesting/functionTests/harness/ java/testing/org/apache/derbyTesting/functionTests/master/ java/testing/org/apache/derbyTesting/functionTests/suites/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/ java/testing/org/apache/derbyTesting/functionTests/tests/store/ java/testing/org/apache/derbyTesting/functionTests/tests/unit/ java/testing/org/apache/derbyTesting/unitTests/ java/testing/org/apache/derbyTesting/unitTests/crypto/ java/testing/org/apache/derbyTesting/unitTests/harness/ java/testing/org/apache/derbyTesting/unitTests/lang/ java/testing/org/apache/derbyTesting/unitTests/services/ java/testing/org/apache/derbyTesting/unitTests/store/ java/testing/org/apache/derbyTesting/unitTests/util/

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessFactory.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessFactory.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessFactory.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,4104 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.store.T_AccessFactory
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.store;
+
+import org.apache.derbyTesting.unitTests.harness.T_Generic;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import org.apache.derby.iapi.store.access.*;
+
+import org.apache.derby.iapi.types.SQLLongint;
+
+import org.apache.derby.iapi.services.context.ContextManager;
+import org.apache.derby.iapi.services.context.ContextService;
+
+import org.apache.derby.iapi.services.io.Storable;
+
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.io.FormatIdUtil;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.DataValueDescriptor;
+
+import org.apache.derby.iapi.types.RowLocation;
+
+import org.apache.derby.iapi.store.raw.RawStoreFactory;
+import org.apache.derby.iapi.store.raw.Transaction;
+import org.apache.derby.iapi.reference.Property;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.io.FormatableBitSet;
+import org.apache.derby.iapi.services.i18n.MessageService;
+import java.io.File;
+import java.io.Serializable;
+import java.util.Hashtable;
+import java.util.Properties;
+import org.apache.derby.iapi.types.SQLInteger;
+
+import org.apache.derby.iapi.types.SQLChar;
+
+public class T_AccessFactory extends T_Generic
+{
+    private static final String testService = "accessTest";
+
+    AccessFactory store = null;
+
+	public T_AccessFactory()
+    {
+		super();
+	}
+
+	/*
+	** Methods of UnitTest.
+	*/
+
+	/*
+	** Methods required by T_Generic
+	*/
+
+	public String getModuleToTestProtocolName()
+    {
+		return AccessFactory.MODULE;
+	}
+
+	/**
+		@exception T_Fail Unexpected behaviour from the API
+	 */
+
+	protected void runTests() throws T_Fail
+	{
+		TransactionController tc = null;
+		boolean pass = false;
+
+		// Create a AccessFactory to test.
+
+		// don't automatic boot this service if it gets left around
+		if (startParams == null) 
+        {
+			startParams = new Properties();
+		}
+		startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
+		// remove the service directory to ensure a clean run
+		startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString());
+
+		// see if we are testing encryption
+		startParams = T_Util.setEncryptionParam(startParams);
+
+		try {
+			store = (AccessFactory) Monitor.createPersistentService(
+				getModuleToTestProtocolName(), testService, startParams);
+		} catch (StandardException mse) {
+			throw T_Fail.exceptionFail(mse);
+		}
+
+
+		if (store == null) 
+        {
+			throw T_Fail.testFailMsg(
+                getModuleToTestProtocolName() + " service not started.");
+		}
+
+		REPORT("(unitTestMain) Testing " + testService);
+
+		try {
+
+            ContextManager cm = 
+                    ContextService.getFactory().getCurrentContextManager();
+
+			tc = store.getAndNameTransaction(
+                    cm, AccessFactoryGlobals.USER_TRANS_NAME);
+
+
+			if (
+				dropTest(tc)
+				&& holdCursor(tc)
+				&& readUncommitted(tc)
+                && updatelocks(tc)
+				&& nestedUserTransaction(tc)
+                && sortCost(tc)
+                && storeCost(tc)
+                && partialScan(tc)
+                && scanInfo(tc)
+				&& insertAndUpdateExample(tc)
+				&& insertAndFetchExample(tc)
+				&& scanExample(tc)
+                && alterTable(tc)
+				&& tempTest(tc)
+                && getTableProperties(tc)
+                && insert_bench(tc)
+				&& transactionalProperties(tc)
+				&& commitTest(tc))
+			{
+				pass = true;
+			}
+
+			// Make sure commitNoSync gets executed sometimes.
+			tc.commitNoSync(TransactionController.RELEASE_LOCKS);	
+
+			tc.destroy();
+
+			if (!pass)
+				throw T_Fail.testFailMsg("test failed");
+
+		}
+		catch (StandardException e)
+		{
+			String  msg = e.getMessage();
+			if (msg == null)
+				msg = e.getClass().getName();
+			REPORT(msg);
+            e.printStackTrace();
+			throw T_Fail.exceptionFail(e);
+		}
+        catch (Throwable t)
+        {
+            t.printStackTrace();
+        }
+
+	}
+
+	/*
+	** Methods of T_AccessFactory.
+	*/
+
+    private void flush_cache()
+        throws StandardException
+    {
+        // flush and empty cache to make sure rereading stuff works.
+        RawStoreFactory rawstore = 
+            (RawStoreFactory) Monitor.findServiceModule(
+                this.store, RawStoreFactory.MODULE);
+
+        rawstore.checkpoint();
+    }
+
+	protected boolean insertAndFetchExample(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+		REPORT("(insertAndFetchExample)");
+
+        // First a negative test - make sure heap requires a template:
+
+        try
+        {
+            // Create a heap conglomerate.
+            long conglomid = 
+                tc.createConglomerate(
+                    "heap", // create a heap conglomerate
+                    null,   // ERROR - Heap requires a template!!!
+					null, 	// column sort order not required for heap
+                    null,   // default properties
+                    TransactionController.IS_DEFAULT); // not temporary
+
+            throw T_Fail.testFailMsg("Allowed heap create without template.");
+        }
+        catch (Throwable t)
+        {
+            // expected error, just continue.
+        }
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(1);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+
+
+		// Insert and fetch some values.
+		if (insertAndFetch(tc, conglomid, 33)
+			&& insertAndFetch(tc, conglomid, -1)
+			&& insertAndFetch(tc, conglomid, -1000000000))
+		{
+			return true;
+		}
+		else
+        {
+			return false;
+        }
+	}
+
+	// Insert a single row with a single column containing
+	// the argument integer, and fetch it back, making sure that
+	// we read the correct value.
+	//
+	protected boolean insertAndFetch(
+    TransactionController tc, 
+    long                  conglomid, 
+    int                   value)
+		throws StandardException, T_Fail
+	{
+        StaticCompiledOpenConglomInfo static_info =
+            tc.getStaticCompiledConglomInfo(conglomid);
+
+        DynamicCompiledOpenConglomInfo dynamic_info =
+            tc.getDynamicCompiledConglomInfo(conglomid);
+
+        String curr_xact_name = tc.getTransactionIdString();
+
+        REPORT("(insertAndFetch) xact id = " + curr_xact_name);
+
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openCompiledConglomerate(
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE,
+                static_info,
+                dynamic_info);
+
+		// Create a row.
+		T_AccessRow r1 = new T_AccessRow(1);
+		SQLInteger c1 = new SQLInteger(value);
+		r1.setCol(0, c1);
+
+		// Get a location template
+		RowLocation rowloc = cc.newRowLocationTemplate();
+
+
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
+
+        // quick test to make sure we can hash insert and find row location.
+        Hashtable test_rowloc_hash = new Hashtable();
+        test_rowloc_hash.put(rowloc, rowloc);
+
+        RowLocation hash_find = (RowLocation) test_rowloc_hash.get(rowloc);
+
+        if (!hash_find.equals(rowloc))
+            throw T_Fail.testFailMsg("(insertAndFetch) bad hash lookup 1");
+
+        hash_find = (RowLocation) test_rowloc_hash.remove(rowloc);
+
+        if (!hash_find.equals(rowloc))
+            throw T_Fail.testFailMsg("(insertAndFetch) bad hash lookup 2");
+
+        hash_find = (RowLocation) test_rowloc_hash.remove(rowloc);
+
+        if (hash_find != null)
+            throw T_Fail.testFailMsg("(insertAndFetch) bad hash lookup 3");
+
+
+		// Create a new row of the same type (since the interface expects
+		// the callers to be keeping the row types straight), but with
+		// a different column value.
+		T_AccessRow r2 = new T_AccessRow(1);
+		SQLInteger c2 = new SQLInteger(0);
+		r2.setCol(0, c2);
+
+		// Fetch the stored value.
+		if (!cc.fetch(rowloc, r2.getRowArray(), (FormatableBitSet) null))
+        {
+			throw T_Fail.testFailMsg("(insertAndFetch) fetch found no row.");
+        }
+
+        // Fetch using the fetch partial column interface
+        SQLInteger c3 = new SQLInteger(0);
+		FormatableBitSet singleColumn = new FormatableBitSet(1);
+		singleColumn.set(0);
+		DataValueDescriptor[] c3row = new DataValueDescriptor[1];
+		c3row[0] = c3;
+
+        if (!cc.fetch(rowloc, c3row, singleColumn))
+        {
+			throw T_Fail.testFailMsg("(insertAndFetch) fetch found no row.");
+        }
+
+		// Close the conglomerate.
+		cc.close();
+
+		// Make sure we read back the value we wrote.
+		if (c2.getInt() != value)
+			throw T_Fail.testFailMsg("(insertAndFetch) Fetched value != inserted value.");
+
+        if (c3.getInt() != value)
+			throw T_Fail.testFailMsg("(insertAndFetch) Fetched value != inserted value.");
+		
+        return true;
+	}
+
+	protected boolean insertAndUpdateExample(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+		// Create a heap conglomerate.
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                new T_AccessRow(1).getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+
+		REPORT("(insertAndUpdateExample)");
+
+		// Insert and update some values
+		if (insertAndUpdate(tc, conglomid, -1, -1003152)
+			&& insertAndUpdate(tc, conglomid, 0, 2000000000)
+			&& deletetest(tc, conglomid, 1, 2))
+		{
+			return true;
+		}
+
+		return false;
+	}
+
+	// Insert a single row with a single column containing
+	// the first argument integer, delete it, make sure subsequent
+	// delete, replace, and replace a single column return false.
+	//
+	protected boolean deletetest(
+	TransactionController tc, 
+	long				  conglomid,
+	int					  value1,
+	int					  value2)
+		throws StandardException, T_Fail
+	{
+		boolean ret_val;
+
+		// Open the conglomerate.
+		ConglomerateController cc =	
+			tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row.
+		T_AccessRow r1 = new T_AccessRow(1);
+		r1.setCol(0, new SQLInteger(value1));
+
+		// Get a location template
+		RowLocation rowloc = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
+
+		// delete it.
+		if (!cc.delete(rowloc))
+		{
+			throw T_Fail.testFailMsg("(deleteTest) delete of row failed");
+		}
+
+		// subsequent replace, update a single column, and delete 
+        // should return false 
+
+        // update single column
+        DataValueDescriptor[] update_row  = new DataValueDescriptor[1];
+        FormatableBitSet   update_desc = new FormatableBitSet(1);
+        update_desc.set(0);
+		if (cc.replace(rowloc, update_row, update_desc))
+		{
+			throw T_Fail.testFailMsg(
+            "(deleteTest) partial column row replace returned true on del row");
+		}
+
+        // update whole row.
+		if (cc.replace(rowloc, r1.getRowArray(), (FormatableBitSet) null))
+		{
+			throw T_Fail.testFailMsg("(deleteTest) update returned true on del row");
+		}
+		if (cc.delete(rowloc))
+		{
+			throw T_Fail.testFailMsg("(deleteTest) delete returned true on del row");
+		}
+
+		// Close the conglomerate.
+		cc.close();
+
+		return true;
+	}
+
+	// Insert a single row with a single column containing
+	// the first argument integer, update it to the second
+	// value, and make sure the update happened.
+	//
+	protected boolean insertAndUpdate(TransactionController tc, long conglomid,
+		int value1, int value2)
+		throws StandardException, T_Fail
+	{
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row.
+		T_AccessRow r1 = new T_AccessRow(1);
+		r1.setCol(0, new SQLInteger(value1));
+
+		// Get a location template
+		RowLocation rowloc = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
+
+		// Update it to the second value
+        DataValueDescriptor[] update_row  = new DataValueDescriptor[1];
+        update_row[0] = new SQLInteger(value2);
+
+        FormatableBitSet update_desc = new FormatableBitSet(1);
+        update_desc.set(0);
+
+		cc.replace(rowloc, update_row, update_desc);
+
+		// Create a new row (of the same type, since the interface expects
+		// the callers to be keeping the row types straight.
+		T_AccessRow r2 = new T_AccessRow(1);
+		SQLInteger c2 = new SQLInteger(0);
+		r2.setCol(0, c2);
+
+		// Fetch the stored value.
+		if (!cc.fetch(rowloc, r2.getRowArray(), (FormatableBitSet) null))
+        {
+			throw T_Fail.testFailMsg("(insertAndUpdate) Fetch val not there.");
+        }
+
+		// Close the conglomerate.
+		cc.close();
+
+		// Make sure we read back the value we wrote.
+		if (c2.getInt() != value2)
+			throw T_Fail.testFailMsg("(insertAndUpdate) Fetch value != updated value.");
+		else
+			return true;
+	}
+
+	protected boolean scanExample(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        tc.commit();
+
+        if (!tc.isPristine() || !tc.isIdle() || tc.isGlobal())
+            throw T_Fail.testFailMsg(
+                "(scanExample) bad xact state after commit.");
+
+        if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)        ||
+            (tc.countOpens(TransactionController.OPEN_CONGLOMERATE) > 0) ||
+            (tc.countOpens(TransactionController.OPEN_SCAN) > 0)         ||
+            (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)    ||
+            (tc.countOpens(TransactionController.OPEN_SORT) > 0))
+        {
+            System.out.println("OPENED 0:\n" + tc.debugOpened());
+            return(FAIL("unexpected open count."));
+        }
+
+		// Create a heap conglomerate.
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+
+		REPORT("(scanExample) starting");
+
+
+		// Open it.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+
+		// Insert some values.
+		int values[] = { 11, 22, 33, 44, 55, 66 };
+		T_AccessRow row = new T_AccessRow(1);
+		for (int i = 0; i < values.length; i++)
+		{
+			row.setCol(0, new SQLInteger(values[i]));
+			if (cc.insert(row.getRowArray()) != 0)
+				throw T_Fail.testFailMsg("(scanExample after insert) insert failed ");
+		}
+
+        // For test coverage call the debugging output routine - can't diff it.
+        REPORT("(scanExample) debug output testing: " + tc.debugOpened());
+
+		// Close the conglomerate.
+		cc.close();
+
+        if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)        ||
+            (tc.countOpens(TransactionController.OPEN_CONGLOMERATE) > 0) ||
+            (tc.countOpens(TransactionController.OPEN_SCAN) > 0)         ||
+            (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)    ||
+            (tc.countOpens(TransactionController.OPEN_SORT) > 0))
+        {
+            System.out.println("OPENED 1:\n" + tc.debugOpened());
+            return(FAIL("unexpected open count."));
+        }
+
+		REPORT("(scanExample) rows inserted");
+
+		// Correlates our position in the upcoming scan to the values array.
+		int scanindex = 0;
+
+		// Put a specific column in the row so we can look at it.
+		SQLInteger col = new SQLInteger(0);
+		row.setCol(0, col);
+
+        flush_cache();
+
+        StaticCompiledOpenConglomInfo static_info =
+            tc.getStaticCompiledConglomInfo(conglomid);
+
+		// Open a scan on the conglomerate.
+		ScanController scan1 = tc.openCompiledScan(
+			false, // don't hold
+			0,     // not for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0,    // unused if stop position is null.
+            static_info,
+            tc.getDynamicCompiledConglomInfo(conglomid));
+
+        // check out the RowCountable interface's.
+        
+        if (scan1.getEstimatedRowCount() != 6)
+        {
+            throw T_Fail.testFailMsg(
+                "(scanExample) estimated row count not 6:" + 
+                scan1.getEstimatedRowCount());
+        }
+
+        // Test 2 - ASSERT(should be able to set arbitrary row count)
+
+        scan1.setEstimatedRowCount(5);
+
+        if (scan1.getEstimatedRowCount() != 5)
+        {
+            throw T_Fail.testFailMsg("(scanExample) estimated row count not 5");
+        }
+
+
+		// Iterate through and check that the rows are still there.
+		while (scan1.next())
+		{
+			scan1.fetch(row.getRowArray());
+
+			// Check we got the value we put in.
+			if (col.getInt() != values[scanindex])
+				throw T_Fail.testFailMsg("(scanExample after insert) Row "
+					+ scanindex
+					+ " should have been "
+					+ values[scanindex]
+					+ ", was "
+					+ col.getInt());
+
+			scanindex++;
+		}
+
+        // make sure another next() call continues to return false.
+        if (scan1.next())
+            throw T_Fail.testFailMsg("(scanExample after insert) should continue to return false after reaching end of scan");
+
+        // see if reopen scan interfaces work
+		scan1.reopenScan(
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+        scan1.next();
+        scan1.next();
+        scan1.next();
+        RowLocation third_row_rowloc = scan1.newRowLocationTemplate();
+        scan1.fetchLocation(third_row_rowloc);
+
+        // see if reopen scan interfaces work
+		scan1.reopenScanByRowLocation(
+            third_row_rowloc,
+			null);
+
+        scanindex = 2;
+		while (scan1.next())
+		{
+			scan1.fetch(row.getRowArray());
+
+			// Check we got the value we put in.
+			if (col.getInt() != values[scanindex])
+				throw T_Fail.testFailMsg("(scanExample after insert) Row "
+					+ scanindex
+					+ " should have been "
+					+ values[scanindex]
+					+ ", was "
+					+ col.getInt());
+
+			scanindex++;
+		}
+
+		scan1.close();
+
+		// Check we saw the right number of rows.
+		if (scanindex != values.length)
+			throw T_Fail.testFailMsg("(scanExample after insert) Expected "
+				+ values.length
+				+ "rows, got "
+				+ scanindex);
+
+		REPORT("(scanExample) rows present and accounted for");
+
+		// Open another scan on the conglomerate.
+		ScanController scan2 = tc.openScan(
+			conglomid,
+			false, // don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+		// Iterate with the second scan and fiddle with the values so they
+		// look like the new value array.
+		int newvalues[] = { 22, 33, 444, 55, 6666 };
+ 		while (scan2.next())
+		{
+			scan2.fetch(row.getRowArray());
+
+			switch(((SQLInteger) row.getCol(0)).getInt())
+			{
+			case 11:
+				if (!scan2.delete())
+					throw T_Fail.testFailMsg("(scanExample) delete failed.");
+				break;
+			case 22:
+			case 33:
+			case 55:
+				// leave these alone
+				break;
+			case 44:
+                DataValueDescriptor[] update_row  = new DataValueDescriptor[1];
+                update_row[0] = new SQLInteger(444);
+
+                FormatableBitSet update_desc = new FormatableBitSet(1);
+                update_desc.set(0);
+
+				if (!scan2.replace(update_row, update_desc))
+                {
+					throw T_Fail.testFailMsg(
+                        "(scanExample) partial column row replace failed.");
+                }
+				break;
+			case 66:
+				row.setCol(0, new SQLInteger(6666));
+				if (!scan2.replace(row.getRowArray(), (FormatableBitSet) null))
+					throw T_Fail.testFailMsg("(scanExample) replace failed.");
+				break;
+			default:
+				throw T_Fail.testFailMsg("(scanExample) Read unexpected value.");
+			}
+		}
+		scan2.close();
+
+		REPORT("(scanExample) rows fiddled with");
+
+		// Open a third scan on the conglomerate.
+		ScanController scan3 = tc.openScan(
+			conglomid,
+			false, // don't hold
+			0, // not for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+		// Iterate through and inspect the changes.
+		scanindex = 0;
+		row.setCol(0, col);
+		while (scan3.next())
+		{
+			scan3.fetch(row.getRowArray());
+
+			REPORT("(scanExample) scan3 fetched " + col.getInt());
+
+			// Check we got the value we put in.
+			if (col.getInt() != newvalues[scanindex])
+				throw T_Fail.testFailMsg("(scanExample after changes) Row "
+					+ scanindex
+					+ " should have been "
+					+ newvalues[scanindex]
+					+ ", was "
+					+ col.getInt());
+
+			scanindex++;
+		}
+		scan3.close();
+
+		// Open a third scan on the conglomerate.
+		scan3 = tc.openScan(
+			conglomid,
+			false, // don't hold
+			0, // not for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_READ_UNCOMMITTED,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+		// Iterate through and inspect the changes.
+		scanindex = 0;
+		row.setCol(0, col);
+		while (scan3.next())
+		{
+			scan3.fetch(row.getRowArray());
+
+			REPORT("(scanExample) scan3 fetched " + col.getInt());
+
+			// Check we got the value we put in.
+			if (col.getInt() != newvalues[scanindex])
+				throw T_Fail.testFailMsg("(scanExample after changes) Row "
+					+ scanindex
+					+ " should have been "
+					+ newvalues[scanindex]
+					+ ", was "
+					+ col.getInt());
+
+			scanindex++;
+		}
+		scan3.close();
+
+		// Check we saw the right number of rows.
+		if (scanindex != newvalues.length)
+			throw T_Fail.testFailMsg("(scanExample after changes) Expected "
+				+ newvalues.length
+				+ "rows, got "
+				+ scanindex);
+
+		REPORT("(scanExample) fiddled rows present and accounted for");
+
+		REPORT("(scanExample) testing expected delete errors");
+
+		// Open 4th scan on conglomerate and test "expected" error returns
+		// from replace, partial column replace, delete.
+		ScanController scan4 = tc.openScan(
+			conglomid,
+			false,	// don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+		// Iterate with the second scan find the "22" row, delete it and
+		// then test that operations on that deleted entry FAIL as expected.
+ 		while (scan4.next())
+		{
+			scan4.fetch(row.getRowArray());
+
+            if (!scan4.doesCurrentPositionQualify())
+            {
+                throw T_Fail.testFailMsg("(scanExample doesCurrentPositionQualify() errors) Expected requalify of current row to succeed");
+            }
+
+			if (((SQLInteger) row.getCol(0)).getInt() == 22)
+			{
+				if (!scan4.delete())
+				{
+					throw T_Fail.testFailMsg("(scanExample delete errors) Delete failed.");
+				}
+				break;
+			}
+		}
+
+        if (scan4.doesCurrentPositionQualify())
+        {
+			throw T_Fail.testFailMsg("(scanExample doesCurrentPositionQualify() errors) Expected qualify of deleted row to FAIL");
+        }
+
+        DataValueDescriptor[] update_row  = new DataValueDescriptor[1];
+
+        FormatableBitSet update_desc = new FormatableBitSet(1);
+        update_desc.set(0);
+
+		if (scan4.replace(update_row,  update_desc))
+		{
+			throw T_Fail.testFailMsg("(scanExample delete errors) Expected partial column replace to FAIL");
+		}
+		if (scan4.replace(row.getRowArray(), (FormatableBitSet) null))
+		{
+			throw T_Fail.testFailMsg("(scanExample after changes) Expected replace to FAIL");
+		}
+		if (scan4.delete())
+		{
+			throw T_Fail.testFailMsg("(scanExample after changes) Expected delete to FAIL");
+		}
+
+		scan4.close();
+
+        if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)           ||
+            (tc.countOpens(TransactionController.OPEN_CONGLOMERATE) > 0)    ||
+            (tc.countOpens(TransactionController.OPEN_SCAN) > 0)            ||
+            (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)   ||
+            (tc.countOpens(TransactionController.OPEN_SORT) > 0))
+        {
+            System.out.println("OPENED:\n" + tc.debugOpened());
+            return(FAIL("unexpected open count."));
+        }
+
+
+		REPORT("(scanExample) completed");
+		return true;
+	}
+
+	protected boolean dropTest(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        ConglomerateController cc;
+
+		REPORT("(dropTest) starting");
+
+        // Test of drop conglomerate with abort by doing the following:
+        //     create table
+        //     commit
+        //     drop table
+        //     make sure table is not still there.
+        //     abort
+        //     make sure table is still there.
+
+		// Create a heap conglomerate.
+		long orig_conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+
+        tc.commit();
+
+        tc.dropConglomerate(orig_conglomid);
+
+
+		// Try and Open it - it should fail.
+        try
+        {
+            cc = tc.openConglomerate(
+                    orig_conglomid, 
+                    false,
+                    TransactionController.OPENMODE_FORUPDATE, 
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_SERIALIZABLE);
+
+            throw T_Fail.testFailMsg("Open conglom on deleted conglom worked.");
+        }
+        catch (StandardException e)
+        {
+			if (!e.getMessageId().equals(
+                    SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST))
+            {
+                throw e;
+            }
+
+            // normal path through the test - conglomerate does not exist, 
+            // ignore the expected error
+        }
+
+		// Try and Open a random non-existant conglomerate - it should fail.
+        try
+        {
+            cc = tc.openConglomerate(
+                    42424242, 
+                    false,
+                    TransactionController.OPENMODE_FORUPDATE, 
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_SERIALIZABLE);
+
+            throw T_Fail.testFailMsg("Open conglom on deleted conglom worked.");
+        }
+        catch (StandardException e)
+        {
+			if (!e.getMessageId().equals(
+                    SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST))
+            {
+                throw e;
+            }
+
+            // normal path through the test - conglomerate does not exist, 
+            // ignore the expected error
+        }
+
+		// Try and delete it again - it should fail.
+        try
+        {
+            tc.dropConglomerate(orig_conglomid);
+
+            throw T_Fail.testFailMsg("Delete conglom on deleted conglom worked.");
+        }
+        catch (StandardException e)
+        {
+            // normal path through the test, ignore the expected error
+        }
+
+
+        // cursory test to make sure conglom directory is not screwed up.
+        
+		// Create a heap conglomerate.
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",         // create a heap conglomerate
+                new T_AccessRow(1).getRowArray(),   // 1 SQLInteger() column template.
+				null, 	// column sort order not required for heap
+                null,           // default properties
+                TransactionController.IS_DEFAULT);         // not temporary
+
+        cc = tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        tc.abort();
+
+        // the original conglomerate should be still around after the abort.
+        cc = tc.openConglomerate(
+                orig_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        cc.close();
+
+		return true;
+	}
+
+    /**
+     * Test the access level getTableProperties() call.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean getTableProperties(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+        Properties prop = new Properties();
+
+        prop.put(Property.PAGE_SIZE_PARAMETER,           "8192");
+        prop.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, "99");
+        prop.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,   "42");
+		prop.put(RawStoreFactory.CONTAINER_INITIAL_PAGES,	"22");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(1);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                prop,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        // verify that input properties were used.
+        Properties ret_prop = tc.getUserCreateConglomPropList();
+
+        cc.getTableProperties(ret_prop);
+
+        if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER).
+                compareTo("8192") != 0         ||
+            ret_prop.getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER).
+                compareTo("99") != 0           ||
+            ret_prop.getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER).
+                compareTo("42") != 0           ||
+			ret_prop.getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES).
+				compareTo("22") != 0)
+        {
+			throw T_Fail.testFailMsg(
+                "(getTableProperties) Did not get expected table propertes(1)." +
+                "\nGot pageSize = " + 
+                    ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER) +
+                "\nGot reserved = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER) +
+                "\nGot minimum record size = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER) +
+                "\nGot initial pages = " + 
+                    ret_prop.getProperty(
+                        RawStoreFactory.CONTAINER_INITIAL_PAGES));
+        }
+
+        ret_prop = cc.getInternalTablePropertySet(null);
+
+        if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER).
+                compareTo("8192") != 0         ||
+            ret_prop.getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER).
+                compareTo("99") != 0           ||
+            ret_prop.getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER).
+                compareTo("42") != 0           ||
+			ret_prop.getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES).
+				compareTo("22") != 0)
+        {
+			throw T_Fail.testFailMsg(
+                "(getTableProperties) Did not get expected table propertes(2)." +
+                "\nGot pageSize = " + 
+                    ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER) +
+                "\nGot reserved = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER) +
+                "\nGot minimum record size = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER) +
+                "\nGot initial pages = " + 
+                    ret_prop.getProperty(
+                        RawStoreFactory.CONTAINER_INITIAL_PAGES));
+        }
+
+        ret_prop = new Properties();
+        
+        ret_prop = cc.getInternalTablePropertySet(ret_prop);
+
+        if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER).
+                compareTo("8192") != 0         ||
+            ret_prop.getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER).
+                compareTo("99") != 0           ||
+            ret_prop.getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER).
+                compareTo("42") != 0           ||
+			ret_prop.getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES).
+				compareTo("22") != 0)
+        {
+			throw T_Fail.testFailMsg(
+                "(getTableProperties) Did not get expected table propertes(3)." +
+                "\nGot pageSize = " + 
+                    ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER) +
+                "\nGot reserved = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER) +
+                "\nGot minimum record size = " +
+                    ret_prop.getProperty(
+                        RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER) +
+                "\nGot initial pages = " + 
+                    ret_prop.getProperty(
+                        RawStoreFactory.CONTAINER_INITIAL_PAGES));
+        }
+
+        return(true);
+    }
+
+    /**
+     * Test the access level alter table interface for adding columns.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean alterTable(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+		REPORT("(alterTable) starting");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(1);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a 1 column row. int column = 1.
+		T_AccessRow r1 = new T_AccessRow(1);
+		SQLInteger c1 = new SQLInteger(1);
+		r1.setCol(0, c1);
+
+		// Get a location template
+		RowLocation rowloc1 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
+
+        // create another 1 column row. int column = 2.
+		// Get a location template
+        r1.setCol(0, new SQLInteger(2));
+		RowLocation rowloc2 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
+
+        // At this point the table looks like:
+        // col1
+        // ----
+        // 1
+        // 2
+
+        // RESOLVE - currently the store can't catch the following error:
+        /*
+        // Test that we can't alter while it is open.
+        try
+        {
+            tc.addColumnToConglomerate(conglomid, 1, c1);
+			throw T_Fail.testFailMsg(
+                "(alterTable) Allowed alter table while table was open.");
+        }
+        catch (StandardException t)
+        {
+            // expected error continue the test.
+        }
+        */
+
+        // Test that we can't add data to columns that don't exist
+
+        // Currently we only error check in debug code.  
+        // RESOLVE - should this be a runtime error?
+        if (SanityManager.DEBUG)
+        {
+            try
+            {
+                T_AccessRow two_column_row = new T_AccessRow(2);
+                SQLInteger col1        = new SQLInteger(3);
+                SQLInteger col2        = new SQLInteger(3);
+                cc.insert(two_column_row.getRowArray());
+                throw T_Fail.testFailMsg(
+                    "(alterTable) Allowed insert of bad row.");
+            }
+            catch (StandardException t)
+            {
+                // expected error continue the test.
+            }
+        }
+
+        // Test that we can't fetch data columns that don't exist
+
+        // Currently we only error check for this in sanity code.
+        // RESOLVE - (mikem) should we check for this in released runtime?
+        if (SanityManager.DEBUG)
+        {
+            try
+            {
+                T_AccessRow two_column_row = new T_AccessRow(2);
+                if (!cc.fetch(
+                        rowloc1, two_column_row.getRowArray(), (FormatableBitSet) null))
+                {
+                    throw T_Fail.testFailMsg(
+                        "(alterTable) Allowed fetch of bad row, bad ret val.");
+                }
+
+                throw T_Fail.testFailMsg(
+                    "(alterTable) Allowed fetch of bad row.");
+            }
+            catch (StandardException t)
+            {
+                // expected error continue the test.
+            }
+        }
+
+        // Test that we can't fetch data columns that don't exist
+        // Currently we only error check for this in sanity code.
+        // RESOLVE - (mikem) should we check for this in released runtime?
+        if (SanityManager.DEBUG)
+        {
+            try
+            {
+                DataValueDescriptor[] third_column_row = 
+                    new DataValueDescriptor[3];
+
+                third_column_row[2]         = new SQLInteger(3);
+
+                FormatableBitSet   fetch_desc        = new FormatableBitSet(3);
+                fetch_desc.set(2);
+
+                if (!cc.fetch(
+                        rowloc1, third_column_row, fetch_desc))
+                {
+                    throw T_Fail.testFailMsg(
+                        "(alterTable) Allowed fetch of bad row, bad ret val.");
+                }
+
+                throw T_Fail.testFailMsg(
+                    "(alterTable) Allowed fetch of bad row.");
+            }
+            catch (StandardException t)
+            {
+                // expected error continue the test.
+            }
+        }
+
+        // Test that we can't replace data columns that don't exist
+
+        // Currently we only error check for this in sanity code.
+        // RESOLVE - (mikem) should we check for this in released runtime?
+        if (SanityManager.DEBUG)
+        {
+            try
+            {
+                T_AccessRow two_column_row = new T_AccessRow(2);
+                SQLInteger col1        = new SQLInteger(3);
+                SQLInteger col2        = new SQLInteger(3);
+                cc.replace(rowloc1, two_column_row.getRowArray(), null);
+                throw T_Fail.testFailMsg(
+                    "(alterTable) Allowed replace of bad row.");
+            }
+            catch (StandardException t)
+            {
+                // expected error continue the test.
+            }
+        }
+
+        // Test that we can't replace data columns that don't exist
+        if (SanityManager.DEBUG)
+        {
+            try
+            {
+                DataValueDescriptor[] second_column_row  = 
+                    new DataValueDescriptor[2];
+                second_column_row[1]        = new SQLInteger(3);
+
+                FormatableBitSet   update_desc        = new FormatableBitSet(2);
+                update_desc.set(1);
+
+                cc.replace(rowloc1, second_column_row, update_desc);
+                throw T_Fail.testFailMsg(
+                    "(alterTable) Allowed partial row update of bad column.");
+            }
+            catch (StandardException t)
+            {
+                // expected error continue the test.
+            }
+        }
+
+		// Make sure commitNoSync gets executed sometimes.
+        tc.commitNoSync(TransactionController.RELEASE_LOCKS);
+
+
+        // now alter the conglomerate, add another int column
+        tc.addColumnToConglomerate(conglomid, 1, c1);
+
+        // Open the table after the close done by commit.
+		cc = tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        T_AccessRow two_column_row = new T_AccessRow(2);
+        SQLInteger col1        = new SQLInteger(3);
+        SQLInteger col2        = new SQLInteger(3);
+
+        // fetch the rows and make sure you get null's in new fields.
+        if (!cc.fetch(
+                rowloc1, two_column_row.getRowArray(), (FormatableBitSet) null))
+        {
+			throw T_Fail.testFailMsg(
+                "(alterTable) Row not there.");
+        }
+
+        if ((((SQLInteger)two_column_row.getCol(0)).getInt() != 1) ||
+            (!two_column_row.getCol(1).isNull()))
+        {
+			throw T_Fail.testFailMsg(
+                "(alterTable) Bad column value after alter.");
+        }
+        if (!cc.fetch(
+                rowloc2, two_column_row.getRowArray(), (FormatableBitSet) null))
+        {
+			throw T_Fail.testFailMsg(
+                "(alterTable) Row not there.");
+        }
+
+        if ((((SQLInteger)two_column_row.getCol(0)).getInt() != 2) ||
+            (!two_column_row.getCol(1).isNull()))
+        {
+			throw T_Fail.testFailMsg(
+                "(alterTable) Bad column value after alter.");
+        }
+
+        // make sure insert of 2 column row works.
+        two_column_row = new T_AccessRow(2);
+        two_column_row.setCol(0, new SQLInteger(3));
+        two_column_row.setCol(1, new SQLInteger(300));
+        cc.insert(two_column_row.getRowArray());
+
+
+        // At this point the table looks like:
+        // col1 col2
+        // ---- ----
+        // 1    NA
+        // 2    NA
+        // 3    300
+
+        
+		ScanController scan = tc.openScan(
+			conglomid,
+			false,	// don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+        while (scan.next())
+        {
+            scan.fetch(two_column_row.getRowArray());
+
+            key_value = ((SQLInteger)two_column_row.getCol(0)).getInt();
+
+            switch(key_value)
+            {
+                case 1:
+                {
+                    // Set non-existent column value to 100
+                    if (!two_column_row.getCol(1).isNull())
+                    {
+                        throw T_Fail.testFailMsg(
+                            "(alterTable) Bad column value after alter.");
+                    }
+
+                    // test that replace field works on alter added column
+                    // make result row be: (1, 100)
+
+                    two_column_row.setCol(1, new SQLInteger(100));
+
+                    scan.replace(two_column_row.getRowArray(), (FormatableBitSet) null);
+                    break;
+                }
+                case 2:
+                {
+                    if (!two_column_row.getCol(1).isNull())
+                    {
+                        throw T_Fail.testFailMsg(
+                            "(alterTable) Bad column value after alter.");
+                    }
+
+                    // test that replace row works on alter added column row.
+                    // make result row be: (2, 200)
+                    two_column_row.setCol(1, new SQLInteger(200));
+
+                    scan.replace(two_column_row.getRowArray(), (FormatableBitSet) null);
+
+                    break;
+                }
+                case 3:
+                {
+                    break;
+                }
+                default:
+                {
+                    throw T_Fail.testFailMsg(
+                        "(alterTable) bad row value found in table.");
+                }
+
+            }
+        }
+
+        // reposition the scan
+		scan.reopenScan(
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+        while (scan.next())
+        {
+            scan.fetch(two_column_row.getRowArray());
+
+            key_value = ((SQLInteger) two_column_row.getCol(0)).getInt();
+
+            switch(key_value)
+            {
+                case 1:
+                case 2:
+                case 3:
+                {
+                    int second_col_val = 
+                        ((SQLInteger) two_column_row.getCol(1)).getInt();
+
+                    if (second_col_val != (key_value * 100))
+                    {
+                        throw T_Fail.testFailMsg(
+                            "(alterTable) Bad column value after alter." +
+                            "expected: (" + 
+                                key_value + ", " + key_value * 100 + ")\n" +
+                            "got     : (" +
+                                key_value + ", " + second_col_val  + ")\n");
+                    }
+
+                    break;
+                }
+                default:
+                {
+                    throw T_Fail.testFailMsg(
+                        "(alterTable) bad row value found in table.");
+                }
+            }
+        }
+
+        scan.close();
+
+        tc.commit();
+
+		REPORT("(alterTable) completed");
+		
+        return true;
+	}
+
+
+    /**
+     * Test the access level ScanInfo interface.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean scanInfo(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+		REPORT("(scanInfo) starting");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(2);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a 1 column row. int column = 1.
+		T_AccessRow r1 = new T_AccessRow(2);
+		SQLInteger c1 = new SQLInteger(1);
+		SQLInteger c2 = new SQLInteger(100);
+		r1.setCol(0, c1);
+		r1.setCol(1, c2);
+
+		// Get a location template
+		RowLocation rowloc1 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
+
+        // create another 2 column row. int column = 2.
+		// Get a location template
+        r1.setCol(0, new SQLInteger(2));
+        r1.setCol(1, new SQLInteger(200));
+		RowLocation rowloc2 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
+
+        cc.delete(rowloc2);
+
+        if (tc.isPristine() || tc.isIdle())
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) bad xact state after update xact.");
+        }
+
+        tc.commit();
+
+		ScanController scan = tc.openScan(
+			conglomid,
+			false,	// don't hold
+            0,    // for read
+            TransactionController.MODE_TABLE,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+
+        if (!scan.isTableLocked())
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) table should be table locked.");
+        }
+
+
+        while (scan.next())
+        {
+            scan.fetch(r1.getRowArray());
+        }
+        ScanInfo   scan_info = scan.getScanInfo();
+        Properties prop      = scan_info.getAllScanInfo(null);
+
+        if (!tc.isPristine() || tc.isIdle())
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) bad xact state after update xact.");
+        }
+
+        REPORT(("return from full row scan heap.getScanInfo() = " + prop));
+
+        if (Integer.parseInt(prop.getProperty(
+		   MessageService.getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED)))
+				!= 1)
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) wrong numPagesVisited.  Expected 1, got " + 
+                Integer.parseInt(prop.getProperty(
+		  			MessageService.getTextMessage(
+									SQLState.STORE_RTS_NUM_PAGES_VISITED))));
+        }
+        if (Integer.parseInt(prop.getProperty(
+			MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED)))
+				!= 2)
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) wrong numRowsVisited. Expected 2, got " + 
+                Integer.parseInt(prop.getProperty(
+		  			MessageService.getTextMessage(
+									SQLState.STORE_RTS_NUM_ROWS_VISITED))));
+        }
+        if (Integer.parseInt(prop.getProperty(
+		  MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED)))
+				!= 1)
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) wrong numRowsQualified. Expected 1, got " + 
+                Integer.parseInt(prop.getProperty(
+		  			MessageService.getTextMessage(
+									SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))));
+        }
+
+        // Try a partial Row scan
+
+        // only get the 2nd column.
+        FormatableBitSet validColumns = new FormatableBitSet(3);
+        validColumns.set(1);
+
+		scan = tc.openScan(
+			conglomid,
+			false,	                // don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			validColumns,           // only get the second column
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+        if (scan.isTableLocked())
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) table should be row locked.");
+        }
+
+        scan_info = scan.getScanInfo();
+        prop      = scan_info.getAllScanInfo(null);
+        REPORT(("return from partial scan heap.getScanInfo() = " + prop));
+
+        // RESOLVE - should test the btree one also.
+
+		REPORT("(scanInfo) finishing");
+
+        return true;
+	}
+
+    /**
+     * Test partial scans.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean partialScan(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+		REPORT("(partialScan) starting");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(2);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a 1 column row. int column = 1.
+		T_AccessRow r1 = new T_AccessRow(2);
+		SQLInteger c1 = new SQLInteger(1);
+		SQLInteger c2 = new SQLInteger(100);
+		r1.setCol(0, c1);
+		r1.setCol(1, c2);
+
+		// Get a location template
+		RowLocation rowloc1 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
+
+        // create another 2 column row. int column = 2.
+		// Get a location template
+        r1.setCol(0, new SQLInteger(2));
+        r1.setCol(1, new SQLInteger(200));
+		RowLocation rowloc2 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
+
+        cc.delete(rowloc2);
+
+        tc.commit();
+
+        // Try a partial Row scan with no columns.
+
+        // only get the 2nd column.
+        FormatableBitSet validColumns = new FormatableBitSet();
+
+		ScanController scan = tc.openScan(
+			conglomid,
+			false,	                // don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			validColumns,           // only get the second column
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+        // should see one row.
+
+        if (!scan.next())
+        {
+            throw T_Fail.testFailMsg("(partialScan) did not see first row.");
+        }
+
+        if (scan.next())
+        {
+            throw T_Fail.testFailMsg("(partialScan) saw more than one row.");
+        }
+
+        // RESOLVE - should test the btree one also.
+
+		REPORT("(partialScan) finishing");
+
+        return true;
+	}
+
+
+	// Simple insert into heap performance test
+	protected boolean insert_bench(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        ConglomerateController cc = null;	
+        ScanController scan       = null;	
+        long conglomid            = -1;
+        long before, after;
+
+
+		// Create a row.
+		T_AccessRow r1   = new T_AccessRow(1);
+        long  iter = 100; 
+
+        for (int numcols = 1; numcols < 101; numcols *= 10)
+        {
+            // Create a heap conglomerate.
+            conglomid = 
+                tc.createConglomerate(
+                    "heap",               // create a heap conglomerate
+                    new T_AccessRow(numcols).getRowArray(),   // 1 SQLInteger() column template.
+					null, 	// column sort order not required for heap
+                    null,                 // default properties
+                    TransactionController.IS_DEFAULT);               // not temporary
+
+            tc.commit();
+
+            // Open the conglomerate.
+            cc = tc.openConglomerate(
+                    conglomid, 
+                    false,
+                    TransactionController.OPENMODE_FORUPDATE, 
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_SERIALIZABLE);
+
+            for (int i = 0; i < numcols; i++)
+            {
+                r1.setCol(i, new SQLInteger(numcols));
+            }
+
+            // time before 
+            before = System.currentTimeMillis();
+
+            for (int i = 0; i < iter; i++)
+            {
+                if (cc.insert(r1.getRowArray()) != 0) 
+                    throw T_Fail.testFailMsg("(insert_bench) insert failed ");
+            }
+
+            // time after 
+            after = System.currentTimeMillis();
+
+            REPORT(
+                "insert " + iter + " rows of " + numcols + " integer cols = " +
+                (after - before) + " milliseconds.\n");
+
+
+            // time before 
+            before = System.currentTimeMillis();
+
+            for (int i = 0; i < iter; i++)
+            {
+               if (cc.insert(r1.getRowArray()) != 0) 
+                    throw T_Fail.testFailMsg("(insert_bench) insert failed ");
+            }
+
+            // time after 
+            after = System.currentTimeMillis();
+
+            REPORT(
+                "second insert " + iter + " rows of " + numcols + 
+                " integer cols = " +
+                (after - before) + " milliseconds.\n");
+
+            // Open a scan on the conglomerate.
+            before = System.currentTimeMillis();
+
+            scan = tc.openScan(
+                conglomid,
+                false, // don't hold
+                0, // not for update
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE,
+				(FormatableBitSet) null, // all columns, all as objects
+                null, // start position - first row in conglomerate
+                0,    // unused if start position is null.
+                null, // qualifier - accept all rows
+                null, // stop position - last row in conglomerate
+                0);   // unused if stop position is null.
+
+            // time before 
+            before = System.currentTimeMillis();
+
+            // Iterate through and check that the rows are still there.
+            while (scan.next())
+            {
+                scan.fetch(r1.getRowArray());
+            }
+
+            // time after 
+            after = System.currentTimeMillis();
+
+            REPORT(
+                "scan " + (2 * iter) + " rows of " + numcols + " integer cols = " +
+                (after - before) + " milliseconds.\n");
+
+            // Close the conglomerate.
+            cc.close();
+            tc.commit();
+        }
+
+        return(true);
+	}
+
+    /**
+     * Test the access level SortCost interface.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean sortCost(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+		REPORT("(sortCost) starting");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(2);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a 2 column row.
+		T_AccessRow r1 = new T_AccessRow(2);
+		SQLInteger c1 = new SQLInteger(1);
+		SQLInteger c2 = new SQLInteger(100);
+		r1.setCol(0, c1);
+		r1.setCol(1, c2);
+
+		// Get a location template
+		RowLocation rowloc1 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
+
+        cc.close();
+
+        tc.commit();
+
+        // flush the cache to get the row count updated.
+        flush_cache();
+
+        // Test 1 - Just call for various types of sorts.  Not sure how 
+        // to test the validity.
+		SortCostController scc = tc.openSortCostController(null);
+
+        double estimated_cost = 
+            scc.getSortCost(
+                template_row.getRowArray(),
+                null,
+                false,
+                10000,
+                100,
+                100);
+
+        if (estimated_cost <= 0)
+        {
+            throw T_Fail.testFailMsg(
+                "(storeCost) estimated sort cost :" + estimated_cost);
+        }
+
+		REPORT("(sortCost) finishing");
+
+        return true;
+	}
+
+    /**
+     * Test the access level StoreCost interface.
+     * <p>
+     *
+	 * @return true if the test succeeded.
+     *
+     * @param tc The transaction controller to use in the test.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail Unexpected behaviour from the API
+     **/
+	protected boolean storeCost(
+    TransactionController tc)
+		throws StandardException, T_Fail
+	{
+        int key_value;
+
+		REPORT("(storeCost) starting");
+
+		// Create a heap conglomerate.
+        T_AccessRow template_row = new T_AccessRow(2);
+		long conglomid = 
+            tc.createConglomerate(
+                "heap",       // create a heap conglomerate
+                template_row.getRowArray(), // 1 column template.
+				null, 	// column sort order not required for heap
+                null,         // default properties
+                TransactionController.IS_DEFAULT);       // not temporary
+		// Open the conglomerate.
+		ConglomerateController cc =	
+            tc.openConglomerate(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a 2 column row.
+		T_AccessRow r1 = new T_AccessRow(2);
+		SQLInteger c1 = new SQLInteger(1);
+		SQLInteger c2 = new SQLInteger(100);
+		r1.setCol(0, c1);
+		r1.setCol(1, c2);
+
+		// Get a location template
+		RowLocation rowloc1 = cc.newRowLocationTemplate();
+
+		// Insert the row and remember its location.
+		cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
+
+        cc.close();
+
+        tc.commit();
+
+        // flush the cache to get the row count updated.
+        flush_cache();
+
+        // Test 1 - ASSERT(initial row count after 1 insert should be 1)
+		StoreCostController scc = tc.openStoreCost(conglomid);
+
+
+        if (scc.getEstimatedRowCount() != 1)
+        {
+            throw T_Fail.testFailMsg(
+                "(storeCost) estimated row count not 1:" + 
+                scc.getEstimatedRowCount());
+        }
+
+        // Test 2 - ASSERT(should be able to set arbitrary row count)
+
+        scc.setEstimatedRowCount(5);
+
+        if (scc.getEstimatedRowCount() != 5)
+        {
+            throw T_Fail.testFailMsg("(storeCost) estimated row count not 5");
+        }
+
+        scc.setEstimatedRowCount(1);
+
+
+        // Test 3 - ASSERT(should implement getFetchFromRowLocationCost()) 
+        //     should figure out some way to determine reasonable number is
+        //     returned.
+        double fetch_cost = 
+            scc.getFetchFromRowLocationCost((FormatableBitSet) null, 0);
+        fetch_cost = 
+            scc.getFetchFromRowLocationCost(
+                (FormatableBitSet) new FormatableBitSet(0), 0);
+        REPORT("fetch cost (full row) of row loc = " + fetch_cost);
+        fetch_cost = 
+            scc.getFetchFromRowLocationCost(
+                (FormatableBitSet) new FormatableBitSet(1), 0);
+        FormatableBitSet bit_set = new FormatableBitSet(2);
+        REPORT("fetch cost (no cols) of row loc = " + fetch_cost);
+        bit_set.set(1);
+        fetch_cost = 
+            scc.getFetchFromRowLocationCost(
+                (FormatableBitSet) new FormatableBitSet(1), 0);
+        REPORT("fetch cost (1 col) of row loc = " + fetch_cost);
+
+        // Test 4 - ASSERT(should implement getFetchFromFullKeyCost()) 
+        //     should figure out some way to determine reasonable number is
+        //     returned.
+        /* - RESOLVE HEAP does not implement this.
+        fetch_cost = 
+            scc.getFetchFromFullKeyCost((FormatableBitSet) null, (int[]) null, 0);
+        REPORT("fetch full key cost (full row) of row loc = " + fetch_cost);
+
+        fetch_cost = 
+            scc.getFetchFromFullKeyCost(
+                (FormatableBitSet) new FormatableBitSet(0), (int[]) null, 0);
+        REPORT("fetch full key cost (no cols) of row loc = " + fetch_cost);
+
+        fetch_cost = 
+            scc.getFetchFromFullKeyCost(
+                (FormatableBitSet) new FormatableBitSet(1), (int[]) null, 0);
+        REPORT("fetch full key cost (no cols) of row loc = " + fetch_cost);
+
+        bit_set = new FormatableBitSet(2);
+        bit_set.set(1);
+        fetch_cost = 
+            scc.getFetchFromFullKeyCost(
+                (FormatableBitSet) new FormatableBitSet(1), (int[]) null, 0);
+        REPORT("fetch full key cost (1 col) of row loc = " + fetch_cost);
+        */
+
+        // Test 5 - ASSERT(should implement getScanCost()) 
+        //     should figure out some way to determine reasonable number is
+        //     returned.
+        StoreCostResult cost_result = new T_StoreCostResult();
+
+        scc.getScanCost(
+            StoreCostController.STORECOST_SCAN_NORMAL,
+            -1,             // row count
+            1,              // number of rows fetched at a time from access.
+            false,          // forUpdate
+            (FormatableBitSet) null,  // validColumns
+            new T_AccessRow(2).getRowArray(),  // template
+            null,           // start position - first row in conglomerate
+            0,              // unused if start position is null.
+            null,           // stop position - last row in conglomerate
+            0,              // unused if stop position is null.
+            false,          // reopen_scan?
+            0,              // access_type
+            cost_result);   // cost result.
+
+        REPORT("fetch scan cost (full row) of row loc = " + cost_result);
+
+        scc.getScanCost(
+            StoreCostController.STORECOST_SCAN_NORMAL,
+            -1,             // row count
+            1,              // number of rows fetched at a time from access.
+            false,          // forUpdate
+            new FormatableBitSet(0),  // validColumns
+            new T_AccessRow(2).getRowArray(),  // template
+            null,           // start position - first row in conglomerate
+            0,              // unused if start position is null.
+            null,           // stop position - last row in conglomerate
+            0,              // unused if stop position is null.
+            false,          // reopen_scan?
+            0,              // access_type
+            cost_result);   // cost result.
+
+        REPORT("fetch scan cost (no cols) of row loc = " + cost_result);
+
+        scc.getScanCost(
+            StoreCostController.STORECOST_SCAN_NORMAL,
+            -1,             // row count
+            1,              // number of rows fetched at a time from access.
+            false,          // forUpdate
+            new FormatableBitSet(1),  // validColumns
+            new T_AccessRow(2).getRowArray(),  // template
+            null,           // start position - first row in conglomerate
+            0,              // unused if start position is null.
+            null,           // stop position - last row in conglomerate
+            0,              // unused if stop position is null.
+            false,          // reopen_scan?
+            0,              // access_type
+            cost_result);   // cost result.
+
+        REPORT("fetch scan cost (no cols) of row loc = " + cost_result);
+
+        bit_set = new FormatableBitSet(2);
+        bit_set.set(1);
+        scc.getScanCost(
+            StoreCostController.STORECOST_SCAN_NORMAL,
+            -1,             // row count
+            1,              // number of rows fetched at a time from access.
+            false,          // forUpdate
+            bit_set,        // validColumns
+            new T_AccessRow(2).getRowArray(),  // template
+            null,           // start position - first row in conglomerate
+            0,              // unused if start position is null.
+            null,           // stop position - last row in conglomerate
+            0,              // unused if stop position is null.
+            false,          // reopen_scan?
+            0,              // access_type
+            cost_result);   // cost result.
+
+        REPORT("fetch scan cost (1 cols) of row loc = " + cost_result);
+
+        // make sure you can get a row location.
+		rowloc1 = scc.newRowLocationTemplate();
+
+		REPORT("(storeCost) finishing");
+
+        return true;
+	}
+
+	/**
+		Test transactional properties
+
+		@exception StandardException test failure
+		@exception T_Fail test failure
+	*/
+	protected boolean transactionalProperties(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+		REPORT("start transactionalProperties");
+
+		// put a couple of properties in with different values and types
+
+		tc.setProperty("T_Key_Frog", new SQLLongint(479), false);
+		tc.setProperty("T_Key_Tiger", "Roar, ROAR", false);
+
+
+		long lvalue = ((SQLLongint) (tc.getProperty("T_Key_Frog"))).getLong();
+		if (lvalue != 479)
+			throw T_Fail.testFailMsg("setProperty() - expected 479 - got " + lvalue);
+
+		String svalue = (String) tc.getProperty("T_Key_Tiger");
+		if (!svalue.equals("Roar, ROAR"))
+			throw T_Fail.testFailMsg("setProperty() - expected 'Roar, ROAR' - got " + svalue);
+
+		tc.commit();
+
+		// should still be accessable after the commit
+		lvalue = ((SQLLongint) (tc.getProperty("T_Key_Frog"))).getLong();
+		if (lvalue != 479)
+			throw T_Fail.testFailMsg("setProperty() - expected 479 - got " + lvalue);
+
+		svalue = (String) tc.getProperty("T_Key_Tiger");
+		if (!svalue.equals("Roar, ROAR"))
+			throw T_Fail.testFailMsg("setProperty() - expected 'Roar, ROAR' - got " + svalue);
+
+		tc.commit();
+
+		// see if update works
+		tc.setProperty("T_Key_Tiger", "mieow, mieow", false);
+		svalue = (String) tc.getProperty("T_Key_Tiger");
+		if (!svalue.equals("mieow, mieow"))
+			throw T_Fail.testFailMsg("setProperty() - expected 'mieow, mieow' - got " + svalue);
+
+		tc.commit();
+		svalue = (String) tc.getProperty("T_Key_Tiger");
+		if (!svalue.equals("mieow, mieow"))
+			throw T_Fail.testFailMsg("setProperty() - expected 'mieow, mieow' - got " + svalue);
+
+		// see if an update to a different type works
+		tc.setProperty("T_Key_Tiger", new SQLLongint(570), false);
+		lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger"))).getLong();
+
+		if (lvalue != 570)
+			throw T_Fail.testFailMsg("setProperty() - expected 570 - got " + lvalue);
+
+		tc.commit();
+
+		lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger"))).getLong();
+		if (lvalue != 570)
+			throw T_Fail.testFailMsg("setProperty() - expected 570 - got " + lvalue);
+
+		tc.commit();
+
+		// delete a key
+		tc.setProperty("T_Key_Frog", (Serializable) null, false);
+		if (tc.getProperty("T_Key_Frog") != null)
+			throw T_Fail.testFailMsg("setProperty() - delete failed");
+		tc.commit();
+
+		if (tc.getProperty("T_Key_Frog") != null)
+			throw T_Fail.testFailMsg("setProperty() - delete failed");
+
+		tc.commit();
+
+		// now see if rollback works.
+		tc.setProperty("T_Key_Tiger", new SQLLongint(457), false);
+
+		tc.abort();
+		lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger"))).getLong();
+		if (lvalue != 570)
+			throw T_Fail.testFailMsg("setProperty() - expected 570 - got " + lvalue);
+
+		tc.commit();
+		PASS("transactionalProperties");
+
+		return true;
+	}
+
+
+
+	// Test temporary conglomerates.
+	protected boolean tempTest(TransactionController tc)
+		throws StandardException, T_Fail
+	{
+		REPORT("(tempTest) starting");
+
+		// Create some conglomerates, some temporary, some not.
+		long cid5252t = createAConglom(tc, 5252, true);  // temporary
+		long cid87t = createAConglom(tc, 87, true); // temporary
+		long cid999p = createAConglom(tc, 999, false); // permanent
+		long cid3t = createAConglom(tc, 3, true); // temporary
+
+		// Create an index on two of them
+		long cid5252ti = createBtree(tc, cid5252t, true);
+		long cid999pi = createBtree(tc, cid999p, false);
+
+		int r;
+
+		// Make sure we can read them.
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid5252t, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid5252t) == " + r);
+        }
+		if ((r = checkAConglom(
+                    tc, getBtreeTemplate(tc, cid5252t), cid5252ti, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid5252ti) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid999p, 999)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid999p) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, getBtreeTemplate(tc, cid999p), cid999pi, 999)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid999pi) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid3t, 3)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid3t) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid87t, 87)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after create checkAConglom(cid87t) == " + r);
+        }
+
+		// Drop two of them.
+		tc.dropConglomerate(cid999pi);
+		tc.dropConglomerate(cid999p);
+		tc.dropConglomerate(cid87t);
+
+		// Try dropping the ones we already dropped - expect exceptions
+        try
+        {
+			tc.dropConglomerate(cid999p);
+            throw T_Fail.testFailMsg("(tempTest) drop of dropped cid999p succeeded");
+        }
+        catch (StandardException e)
+        {
+            // normal path through the test, ignore the expected error
+        }
+        try
+        {
+			tc.dropConglomerate(cid999pi);
+            throw T_Fail.testFailMsg("(tempTest) drop of dropped cid999pi succeeded");
+        }
+        catch (StandardException e)
+        {
+            // normal path through the test, ignore the expected error
+        }
+        try
+        {
+			tc.dropConglomerate(cid87t);
+            throw T_Fail.testFailMsg("(tempTest) drop of dropped cid87t succeeded");
+        }
+        catch (StandardException e)
+        {
+            // normal path through the test, ignore the expected error
+        }
+
+		// Make sure the correct ones remain
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid5252t, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after drop checkAConglom(cid5252t) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, getBtreeTemplate(tc, cid5252t), cid5252ti, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after drop checkAConglom(cid5252ti) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid3t, 3)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after drop checkAConglom(cid3t) == " + r);
+        }
+
+		// Make sure commitNoSync gets executed sometimes.
+		tc.commitNoSync(TransactionController.RELEASE_LOCKS);
+
+		// After committing the transaction, the congloms
+		// should still be there (with their rows).
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid5252t, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after commit checkAConglom(cid5252t) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, getBtreeTemplate(tc, cid5252t), cid5252ti, 5252)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after commit checkAConglom(cid5252ti) == " + r);
+        }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid3t, 3)) != 1)
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after commit checkAConglom(cid3t) == " + r);
+        }
+
+
+		// open cid3t for update to force its truncation on the abort.
+		ScanController sc = tc.openScan(
+			cid3t,
+			false, // don't hold
+			TransactionController.OPENMODE_FORUPDATE, // for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			(FormatableBitSet) null, // all columns, all as objects
+			null, // start position - first row in conglomerate
+            0,    // unused if start position is null.
+			null, // qualifier - accept all rows
+			null, // stop position - last row in conglomerate
+            0);   // unused if stop position is null.
+
+		sc.close();
+
+
+		tc.abort();
+
+		// After an abort, the congloms that were opened for update should be there,
+		// but truncated
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid5252t, 5252)) != 1) 
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after abort checkAConglom(cid5252t) == " + r);
+		}
+
+		// RESOLVE(mikem): track 1825
+		// don't want to open temp cantainer with IS_KEPT always.
+		// if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t, 3)) != 0) {
+		//	throw T_Fail.testFailMsg("(tempTest) after abort checkAConglom(cid3t) == " + r);
+		// }
+
+		if ((r = checkAConglom(
+                    tc, (DataValueDescriptor[]) null, cid3t, 3)) != 1) 
+        {
+			throw T_Fail.testFailMsg(
+                    "(tempTest) after abort checkAConglom(cid3t) == " + r);
+		}
+
+		// Due to bug STO84, temp btrees are corrupted after aborts,
+		// so the following will cause problems:
+		/*
+		if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid5252ti, 5252)) != 0)
+		 	throw T_Fail.testFailMsg("(tempTest) after abort checkAConglom(cid5252ti) == " + r);
+		*/
+
+		// Drop index on conglomerate to make sure we can do a drop after truncate.
+		tc.dropConglomerate(cid5252ti);
+		if (tc.conglomerateExists(cid5252ti))
+			throw T_Fail.testFailMsg("(tempTest) after drop cid5252ti still exists");
+
+		// Drop one conglomerate to make sure we can do a drop after truncate.
+		tc.dropConglomerate(cid5252t);
+		if (tc.conglomerateExists(cid5252t))
+			throw T_Fail.testFailMsg("(tempTest) after drop cid5252t still exists");
+
+		// Leave the last one -  raw store is supposed to delete
+		// it when the system reboots
+
+		// Success!
+		REPORT("(tempTest) succeeded");
+		return true;
+	}
+
+	private long createAConglom(TransactionController tc, int testValue, boolean temporary)
+		throws StandardException
+	{
+		// Create a heap conglomerate.
+		long cid = 
+            tc.createConglomerate(
+                "heap",         // create a heap conglomerate
+                new T_AccessRow(1).getRowArray(),   // 1 SQLInteger() column template.
+				null, 	// column sort order not required for heap
+                null,           // default properties
+                temporary ? TransactionController.IS_TEMPORARY : TransactionController.IS_DEFAULT);
+
+		ConglomerateController cc = 
+            tc.openConglomerate(
+                cid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row.
+		T_AccessRow row = new T_AccessRow(1);
+		SQLLongint col = new SQLLongint(testValue);
+		row.setCol(0, col);
+
+		// Stuff in the test value so we can recognize this conglom later.
+		cc.insert(row.getRowArray());
+
+		cc.close();
+
+		return cid;
+	}
+
+    private DataValueDescriptor[] getBtreeTemplate(
+    TransactionController tc, 
+    long                  baseConglomId)
+        throws StandardException
+    {
+		// Open a scan on the base conglomerate which will return all rows.
+		FormatableBitSet singleColumn = new FormatableBitSet(1);
+		singleColumn.set(0);
+		ScanController sc = tc.openScan(baseConglomId, false,
+			0, // not for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			singleColumn, // all columns, all as objects
+			null, 0, null, null, 0);
+
+		// Create the template for the index. This method "knows" that
+		// all rows in the base table have one IntCol
+		T_AccessRow template = new T_AccessRow(2);
+		SQLLongint col0 = new SQLLongint(0);
+		RowLocation col1 = sc.newRowLocationTemplate();
+		template.setCol(0, col0);
+		template.setCol(1, col1);
+
+        sc.close();
+
+        return(template.getRowArray());
+    }
+
+
+	private long createBtree(TransactionController tc, long baseConglomId, boolean temporary)
+		throws StandardException
+	{
+		// Create the properties for the index.
+		// This method knows that there is just one column in the base table
+		Properties indexProps = new Properties();
+		indexProps.put("baseConglomerateId", Long.toString(baseConglomId));
+		indexProps.put("nUniqueColumns", "1");
+		indexProps.put("rowLocationColumn", "1");
+		indexProps.put("nKeyFields", "2");
+
+		// Open a scan on the base conglomerate which will return all rows.
+		FormatableBitSet singleColumn = new FormatableBitSet(1);
+		singleColumn.set(0);
+		ScanController sc = tc.openScan(baseConglomId, false,
+			0, // not for update
+            TransactionController.MODE_RECORD,
+            TransactionController.ISOLATION_SERIALIZABLE,
+			singleColumn, // just the first column.
+			null, 0, null, null, 0);
+
+		// Create the template for the index. This method "knows" that
+		// all rows in the base table have one IntCol
+		T_AccessRow template = new T_AccessRow(2);
+		SQLLongint col0 = new SQLLongint(0);
+		RowLocation col1 = sc.newRowLocationTemplate();
+		template.setCol(0, col0);
+		template.setCol(1, col1);
+
+		DataValueDescriptor[] baseRow = new DataValueDescriptor[1];
+		baseRow[0] = col0;
+
+		// Create a btree secondary index conglomerate.
+		long iid = tc.createConglomerate("BTREE", template.getRowArray(), null, indexProps,
+			temporary ? TransactionController.IS_TEMPORARY : TransactionController.IS_DEFAULT);
+
+		// Open the index so we can stuff in index rows.
+		ConglomerateController cc = 
+            tc.openConglomerate(
+                iid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE, 
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// build the index.
+		while (sc.next())
+		{
+			sc.fetch(baseRow);
+			sc.fetchLocation(col1);
+			cc.insert(template.getRowArray());
+		}
+
+		cc.close();
+
+		return iid;
+	}
+
+	/**
+	Open a scan on the conglomerate for the given conglom id, and verify
+	that it has rows with the given test value.  This is a way of
+	verifying that we got the right conglomerate.  Returns the number of

[... 1481 lines stripped ...]