db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fuzzylo...@apache.org
Subject svn commit: r155990 [14/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/
Date Thu, 03 Mar 2005 01:30:47 GMT
Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_b2i.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_b2i.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_b2i.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_b2i.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,5002 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.store.T_b2i
+
+   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;
+
+// impl imports are the preferred way to create unit tests.
+import org.apache.derbyTesting.unitTests.harness.T_MultiIterations;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import org.apache.derby.impl.store.access.btree.index.*;
+
+import org.apache.derby.iapi.types.SQLLongint;
+
+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 org.apache.derby.iapi.services.monitor.Monitor;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.context.ContextManager;
+import org.apache.derby.iapi.services.io.FormatIdUtil;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
+import org.apache.derby.iapi.store.access.AccessFactory;
+import org.apache.derby.iapi.store.access.ConglomerateController;
+import org.apache.derby.iapi.store.access.Qualifier;
+import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.iapi.store.access.ScanController;
+import org.apache.derby.iapi.store.access.ScanInfo;
+import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.iapi.store.access.RowUtil;
+import org.apache.derby.iapi.store.access.ColumnOrdering;
+
+import org.apache.derby.iapi.store.raw.ContainerHandle;
+import org.apache.derby.iapi.store.raw.LockingPolicy;
+import org.apache.derby.iapi.store.raw.RawStoreFactory;
+
+import org.apache.derby.iapi.types.DataValueDescriptor;
+
+import org.apache.derby.impl.store.access.btree.BTree;
+import org.apache.derby.impl.store.access.conglomerate.TemplateRow;
+import org.apache.derby.iapi.types.SQLChar;
+
+
+import java.util.Properties;
+
+
+
+public class T_b2i extends T_MultiIterations
+{ 
+
+    private static final String testService = "b2iTest";
+
+    private Object store_module = null; 
+
+    private ContextService contextService = null;
+
+    /* Methods required by T_MultiIterations */
+
+
+    /**
+     * Routine one once per invocation of the test by the driver.
+     * <p>
+     * Do work that should only be done once, no matter how many times
+     * runTests() may be executed.
+     *
+	 * @exception  T_Fail  Thrown on any error.
+     **/
+    protected void setupTest()
+		throws T_Fail
+    {
+		// 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_module = Monitor.createPersistentService(
+				getModuleToTestProtocolName(), testService, startParams);
+			
+			contextService = ContextService.getFactory();
+
+		} catch (StandardException mse) {
+			throw T_Fail.exceptionFail(mse);
+		}
+    }
+
+	/*
+	** Methods required by T_Generic
+	*/
+
+	public String getModuleToTestProtocolName() {
+		return AccessFactory.MODULE;
+	}
+
+    /**
+     * Driver routine for the btree secondary index tests.
+     * <p>
+     *
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     **/
+	protected void runTestSet() throws T_Fail
+	{
+		AccessFactory store = null;
+		TransactionController tc = null;
+		boolean pass = false;
+
+        out.println("executing b2i test");
+
+        store = (AccessFactory) store_module;
+
+		if (store == null)
+        {
+			throw T_Fail.testFailMsg(
+                    getModuleToTestProtocolName() + " service not started.");
+		}
+
+		ContextManager cm1 = contextService.newContextManager();
+		contextService.setCurrentContextManager(cm1);
+
+		REPORT("(unitTestMain) Testing " + testService);
+
+		try {
+
+			tc = store.getTransaction(cm1);
+
+				pass = true;
+
+            if (
+                t_005(tc)   &&
+                t_001(tc)   &&
+                t_003(tc)   &&
+                t_004(tc)   &&
+                t_005(tc)   &&
+                t_006(tc)   &&
+                t_009(tc)   &&
+                t_010(tc)   &&
+                t_011(tc)   &&
+                t_012(tc)   &&
+                t_013(tc)   &&
+                t_014(tc)   &&
+				t_017(tc)   &&
+				t_018(tc)   &&
+				t_019(tc)   &&
+				t_020(tc)   
+                )
+                
+			{
+				pass = true;
+
+                if (SanityManager.DEBUG)
+                {
+                    pass = false;
+
+                    // The following tests depend on SanityManager functionality
+                    // so can not be run in an insane server.
+
+                    if (t_002(tc) &&
+                        t_007(tc) &&
+                        t_008(tc) &&
+                        t_015(tc) &&
+                        t_016(tc)
+                        )
+                        pass = true;
+                }
+			}
+
+			tc.commit();
+			tc.destroy();
+		}
+		catch (StandardException e)
+		{
+			String  msg = e.getMessage();
+			if (msg == null)
+				msg = e.getClass().getName();
+			REPORT(msg);
+
+            e.printStackTrace(out.getPrintWriter());
+            cm1.cleanupOnError(e);
+
+            pass = false;
+		}
+        catch (Throwable t)
+        {
+			String  msg = t.getMessage();
+			if (msg == null)
+				msg = t.getClass().getName();
+			REPORT(msg);
+
+            t.printStackTrace(out.getPrintWriter());
+            cm1.cleanupOnError(t);
+
+            pass = false;
+        }
+		finally {
+			contextService.resetCurrentContextManager(cm1);
+		}
+
+		if (!pass)
+			throw T_Fail.testFailMsg("");
+	}
+
+    /**
+     * Utility routine to create base table for tests.
+     * <p>
+     * A little utility routine to create base tables for tests.  Just
+     * here to make tests a little more readable.  It currently just 
+     * creates a heap table with "num_cols" SQLLongint columns.
+     *
+	 * @return The identifier to be used to open the conglomerate later.
+     *
+     * @param num_cols the number of columns in the base table.
+     *
+	 * @exception  StandardException  Standard exception policy.
+     **/
+
+    void createCongloms(
+    TransactionController   tc,
+    int                     num_cols,
+    boolean                 unique,
+    boolean                 varying_first_col,
+    int                     max_btreerows_per_page,
+    T_CreateConglomRet        ret_val)
+		throws StandardException
+    {
+        T_SecondaryIndexRow index_row  = new T_SecondaryIndexRow();
+        DataValueDescriptor[] base_row = TemplateRow.newU8Row(num_cols);
+
+        if (varying_first_col)
+        {
+            SQLChar    string_col = new SQLChar();
+
+            base_row[0] = string_col;
+        }
+
+        long base_conglomid = 0;
+
+        // create the base table
+        base_conglomid = 
+            tc.createConglomerate(
+                "heap",   // create a heap conglomerate
+                base_row, // base table template row
+                null, //column sort order - not required for heap
+                null,     // default properties
+                TransactionController.IS_DEFAULT);// not temporary
+
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                base_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        // initialize the secondary index row - pointing it at base row
+        RowLocation base_rowloc = base_cc.newRowLocationTemplate();
+        index_row.init(base_row, base_rowloc, num_cols + 1);
+        
+        // create the secondary index
+        Properties properties = 
+            createProperties(
+                null,           // no current properties list 
+                false,          // don't allow duplicates
+                num_cols + 1,   // index on all base row cols + row location
+                (unique ? num_cols : num_cols + 1),   // non-unique index
+                true,           // maintain parent links
+                base_conglomid, // base conglomid
+                num_cols);      // row loc in last column
+
+        if (max_btreerows_per_page > 1)
+        {
+            if (BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER != null)
+            {
+                properties.put(
+                    BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER,
+                    String.valueOf(max_btreerows_per_page));
+            }
+        }
+
+        long index_conglomid = 
+            tc.createConglomerate(
+                "BTREE",    	    // create a btree secondary
+                index_row.getRow(), // index row template
+				null, //column sort order - default
+                properties,         // properties
+                TransactionController.IS_DEFAULT); // not temporary
+
+        // return values to caller
+        ret_val.base_conglomid     = base_conglomid;
+        ret_val.index_conglomid    = index_conglomid;
+        // RESOLVE (mikem - 04/29/98 - why is following line commented out?
+        // ret_val.base_template_row  = TemplateRow.newU8Row(num_cols);
+        ret_val.index_template_row = index_row.getRow();
+
+        return;
+    }
+
+    protected static Properties createProperties(
+    Properties  input_properties,
+    boolean     input_allowduplicates,
+    int         input_nkeyfields,
+    int         input_nuniquecolumns,
+    boolean     input_maintainparentlinks,
+    long        input_baseconglomerateid,
+    int         input_rowlocationcolumn)
+        throws StandardException
+    {
+        Properties properties = 
+            ((input_properties == null) ? new Properties() : input_properties);
+        properties.put(
+            "allowDuplicates",     String.valueOf(input_allowduplicates));
+        properties.put(
+            "nKeyFields",          String.valueOf(input_nkeyfields));
+        properties.put(
+            "nUniqueColumns",      String.valueOf(input_nuniquecolumns));
+        properties.put(
+            "maintainParentLinks", String.valueOf(input_maintainparentlinks));
+        properties.put(
+            "baseConglomerateId",  String.valueOf(input_baseconglomerateid));
+        properties.put(
+            "rowLocationColumn",   String.valueOf(input_rowlocationcolumn));
+        return(properties);
+    }
+
+    /**
+     * Test a single scan.
+     * 
+	 * @exception  StandardException  Standard exception policy.
+     */
+    protected boolean t_scan(
+    TransactionController   tc,
+    long                    conglomid,
+    DataValueDescriptor[]	template,
+    DataValueDescriptor[]	start_key, 
+    int                     start_op,
+    Qualifier               qualifier[][],
+    DataValueDescriptor[]	stop_key,
+    int                     stop_op,
+    int                     expect_numrows,
+    int                     expect_key)
+        throws StandardException
+    {
+
+        // open a new scan
+
+        ScanController scan = 
+            tc.openScan(
+                conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE,
+                (FormatableBitSet) null,
+                start_key, start_op,
+                qualifier,
+                stop_key, stop_op);
+
+        long key     = -42;
+        long numrows = 0;
+
+        while (scan.next())
+        {
+            scan.fetch(template);
+
+            key = ((SQLLongint)template[2]).getLong();
+
+            if (key != expect_key)
+            {
+                return(
+                    FAIL("(t_scan) wrong key, expected (" + expect_key + ")" +
+                     "but got (" + key + ")."));
+            }
+            else
+            {
+                expect_key++;
+                numrows++;
+            }
+        }
+
+        ((B2IForwardScan)scan).checkConsistency();
+        
+        scan.close();
+
+        if (numrows != expect_numrows)
+        {
+            return(FAIL("(t_scan) wrong number of rows. Expected " +
+                 expect_numrows + " rows, but got " + numrows + "rows."));
+        }
+
+        return(true);
+    }
+
+    /**
+     * delete a single key, given key value.  assumes 3 column table, first
+     * column = 1, second column is a unique key, and 3rd column is a 
+     * RecordHandle into the base table.
+     *
+	 * @exception  StandardException  Standard exception policy.
+     */
+    protected boolean t_delete(
+    TransactionController   tc,
+    long                    conglomid,
+    DataValueDescriptor[]   search_key,
+    DataValueDescriptor[]   template) 
+        throws StandardException
+    {
+        SQLLongint column0 = new SQLLongint(-1);
+        SQLLongint column1 = new SQLLongint(-1);
+
+        // open a new scan
+
+        ScanController scan = 
+            tc.openScan(conglomid, false,
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+                        (FormatableBitSet) null,
+                        search_key, ScanController.GE, 
+                        null,
+                        search_key, ScanController.GT); 
+
+        long expect_key = 
+            ((SQLLongint) search_key[1]).getLong();
+
+        int numrows = 0;
+		DataValueDescriptor[] partialRow = new DataValueDescriptor[2];
+		partialRow[0] = column0;
+		partialRow[1] = column1;
+
+        while (scan.next())
+        {
+            numrows++;
+
+			scan.fetch(partialRow);
+
+            if (column0.getLong() != 1)
+                return(FAIL("(t_delete) column[0] value is not 1"));
+
+            if (column1.getLong() != expect_key)
+                return(
+                    FAIL("(t_delete) column[1]  value is not " + expect_key));
+
+            if (!scan.delete())
+            {
+                return(FAIL("(t_delete): delete of row failed"));
+            }
+            if (scan.delete())
+            {
+                return(FAIL("(t_delete): re-delete of row succeeded"));
+            }
+        }
+
+        scan.close();
+
+        // This function expects unique keys, so scan should find single row.
+        if (numrows != 1)
+        {
+            return(FAIL("(t_delete) wrong number of rows. Expected " +
+                   "1 row, but got " + numrows + "rows."));
+        }
+
+        return(true);
+    }
+
+    /**
+     * Test BTreeController.insert()
+     * <p>
+     * Just verify that insert code works for a secondary index.  Just call
+     * the interface and make sure the row got there.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     **/
+    protected boolean t_001(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        REPORT("Starting t_001");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                create_ret.base_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the secondary index
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        if (!(index_cc instanceof B2IController))
+        {
+			throw T_Fail.testFailMsg("openConglomerate returned wrong type");
+        }
+
+        if (!index_cc.isKeyed())
+        {
+			throw T_Fail.testFailMsg("btree is not keyed.");
+        }
+
+        index_cc.checkConsistency();
+
+		// Create a row and insert into base table, remembering it's location.
+		DataValueDescriptor[] r1             = TemplateRow.newU8Row(2);
+        T_SecondaryIndexRow  index_row1      = new T_SecondaryIndexRow();
+        RowLocation          base_rowloc1    = base_cc.newRowLocationTemplate();
+
+        index_row1.init(r1, base_rowloc1, 3);
+		((SQLLongint) r1[0]).setValue(2);
+		((SQLLongint) r1[1]).setValue(2);
+
+		// Insert the row into the base table and remember its location.
+		base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+        // Insert the row into the secondary index.
+        if (index_cc.insert(index_row1.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+		// Make sure we read back the value we wrote from base and index table.
+		DataValueDescriptor[] r2            = TemplateRow.newU8Row(2);
+        T_SecondaryIndexRow   index_row2    = new T_SecondaryIndexRow();
+        RowLocation           base_rowloc2  = base_cc.newRowLocationTemplate();
+
+        index_row2.init(r2, base_rowloc2, 3);
+
+        // base table check:
+        if (!base_cc.fetch(base_rowloc1, r2, (FormatableBitSet) null))
+        {
+            return(FAIL("(t_001) insert into base table failed"));
+        }
+
+        if (((SQLLongint) r2[0]).getLong() != 2 ||
+            ((SQLLongint) r2[1]).getLong() != 2)
+        {
+            return(FAIL("(t_001) insert into base table failed"));
+        }
+
+        // index check - there should be only one record:
+        ScanController scan = 
+            tc.openScan(create_ret.index_conglomid, false,
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+
+        scan.next();
+        scan.fetch(index_row2.getRow());
+
+        // delete the only row in the table, and make sure 
+        // isCurrentPositionDeleted() works.
+        if (scan.isCurrentPositionDeleted())
+            throw T_Fail.testFailMsg("current row should not be deleted\n");
+        if (!scan.doesCurrentPositionQualify())
+            throw T_Fail.testFailMsg("current row should still qualify\n");
+        scan.delete();
+        if (!scan.isCurrentPositionDeleted())
+            throw T_Fail.testFailMsg("current row should be deleted\n");
+        if (scan.doesCurrentPositionQualify())
+            throw T_Fail.testFailMsg("deleted row should not qualify\n");
+
+        // just call the debugging code to make sure it doesn't fail.
+        REPORT("Calling scan.tostring(): " + scan);
+
+        if (scan.next()                                                     ||
+            ((SQLLongint)(index_row2.getRow()[0])).getLong() != 2 ||
+            ((SQLLongint)(index_row2.getRow()[1])).getLong() != 2)
+        {
+            return(FAIL("(t_001) insert into index failed in base cols"));
+        }
+
+        // test the scaninfo interface.
+
+        ScanInfo   scan_info = scan.getScanInfo();
+        Properties prop      = scan_info.getAllScanInfo(null);
+
+        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)))
+				!= 1)
+        {
+            throw T_Fail.testFailMsg(
+                "(scanInfo) wrong numRowsVisited. Expected 1, 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))));
+        }
+
+
+        int compare_result = base_rowloc1.compare(base_rowloc2);
+        if (compare_result != 0)
+        {
+            return(FAIL("(t_001) insert into index failed in recordhandle.\n" +
+                        "\texpected RecordHandle = " + base_rowloc1 + "\n" +
+                        "\tgot      RecordHandle = " + base_rowloc2 + 
+                        "\tcompare result = " + compare_result));
+        }
+
+        index_cc.checkConsistency();
+
+		// Close the conglomerates.
+		base_cc.close();
+		index_cc.close();
+
+        try 
+        {
+            base_cc.insert(r1);
+            return(FAIL("(t_001) insert on closed conglomerate worked"));
+        }
+        catch (StandardException e)
+        {
+            // e.printStackTrace();
+        }
+
+        try 
+        {
+            if (index_cc.insert(r1) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+            return(FAIL("(t_001) insert on closed conglomerate worked"));
+        }
+        catch (StandardException e)
+        {
+            // e.printStackTrace();
+        }
+
+        tc.commit();
+        REPORT("Ending t_001");
+
+        return true;
+    }
+
+    /**
+     * Test backout during critical times of splits.
+     * <p>
+     * Use trace points to force errors in split at critical points:
+     *     leaf_split_abort{1,2,3,4}
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     **/
+    protected boolean t_002(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        ScanController scan         = null;
+
+        // SanityManager.DEBUG_SET("LockTrace");
+
+        REPORT("Starting t_002");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        // Create the btree so that it only allows 2 rows per page.
+        createCongloms(tc, 2, false, false, 2, create_ret);
+
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                create_ret.base_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the secondary index
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        if (!(index_cc instanceof B2IController))
+        {
+			throw T_Fail.testFailMsg("openConglomerate returned wrong type");
+        }
+
+        index_cc.checkConsistency();
+
+		// Create a row and insert into base table, remembering it's location.
+		DataValueDescriptor[]   r1           = TemplateRow.newU8Row(2);
+        T_SecondaryIndexRow     index_row1   = new T_SecondaryIndexRow();
+        RowLocation             base_rowloc1 = base_cc.newRowLocationTemplate();
+
+        index_row1.init(r1, base_rowloc1, 3);
+
+        // Commit the create of the tables so that the following aborts don't
+        // undo that work.
+        tc.commit();
+
+        // Now try aborts of transactions during splits, using magic
+        // trace flags.  This test inserts enough rows to cause a split
+        // and then forces the split to fail at various key points.  The
+        // split should be backed out and also the rows before the split.
+        // The test makes sure that there are some inserts before the forced
+        // split abort.
+        String[] debug_strings = {
+            "leaf_split_growRoot1",
+            "leaf_split_growRoot2",
+            "leaf_split_growRoot3",
+            "leaf_split_growRoot4",
+            "leaf_split_growRoot5",
+            "leaf_split_abort1",
+            "leaf_split_abort2",
+            "leaf_split_abort3",
+            "leaf_split_abort4",
+            "branch_split_abort1",
+            "branch_split_abort2",
+            "branch_split_abort3",
+            "branch_split_abort4",
+            "BTreeController_doIns2"
+            };
+
+        for (int errs = 0; errs < debug_strings.length; errs++)
+        {
+            REPORT("Doing abort test: " + debug_strings[errs]);
+
+            // set the debug flag, which will cause an error
+            // RESOLVE (mmm) these tests should be run from the language to
+            // make sure error handling really works.
+
+            if (SanityManager.DEBUG)
+                SanityManager.DEBUG_SET(debug_strings[errs]);
+            
+            try 
+            {
+
+                // Open the base table
+                base_cc = 
+                    tc.openConglomerate(
+                        create_ret.base_conglomid,
+                        false,
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE);
+
+                // Open the secondary index
+                index_cc =	
+                    tc.openConglomerate(
+                        create_ret.index_conglomid,
+                        false,
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE);
+
+                // insert one row that does not cause failure.
+                ((SQLLongint)r1[0]).setValue(2);
+                ((SQLLongint)r1[1]).setValue(10000 + errs);
+
+                // Insert the row into the base table;remember its location.
+                base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+                // Insert the row into the secondary index.
+                if (index_cc.insert(index_row1.getRow()) != 0)
+                    throw T_Fail.testFailMsg("insert failed");
+
+
+                // set the debug flag, which will cause an error
+                // RESOLVE (mmm) these tests should be run from the 
+                // language to make sure error handling really works.
+                if (SanityManager.DEBUG)
+                    SanityManager.DEBUG_SET(debug_strings[errs]);
+
+                // now insert enough rows to cause failure
+                for (int i = 100; i > 0; i -= 2)
+                {
+                    ((SQLLongint)r1[0]).setValue(2);
+                    ((SQLLongint)r1[1]).setValue(i);
+
+                    // Insert the row into the base table;remember its location.
+                    base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+                    // Insert the row into the secondary index.
+                    if (index_cc.insert(index_row1.getRow()) != 0)
+                    {
+                        throw T_Fail.testFailMsg("insert failed");
+                    }
+                }
+
+                throw T_Fail.testFailMsg(
+                    "debug flag (" + debug_strings[errs] + 
+                    ")did not cause exception.");
+            }
+            catch (StandardException e)
+            {
+                ContextService contextFactory = ContextService.getFactory();
+
+                // Get the context manager.
+                ContextManager cm = contextFactory.getCurrentContextManager();
+
+                if (SanityManager.DEBUG)
+                    SanityManager.ASSERT(cm != null);
+
+                cm.cleanupOnError(e);
+                
+                // RESOLVE (mikem) - when split abort works come up with 
+                // a good sanity check here.
+                //
+                // index check - there should be no records:
+                scan = tc.openScan(create_ret.index_conglomid, false, 
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+
+
+                index_cc =	
+                    tc.openConglomerate(
+                        create_ret.index_conglomid,
+                        false,
+                        TransactionController.OPENMODE_FORUPDATE,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE);
+
+                index_cc.checkConsistency();
+                index_cc.close();
+
+                if (scan.next())
+                {
+                    throw T_Fail.testFailMsg(
+                            "t_002: there are still rows in table.");
+                }
+
+
+                scan.close();
+            }
+
+            // Unset the flag.
+            if (SanityManager.DEBUG)
+                SanityManager.DEBUG_CLEAR(debug_strings[errs]);
+        }
+
+        // Try a simple abort.  The following adds enough rows to cause a 
+        // split.  The result of the split should be a tree with no rows, but
+        // the splits will not be undone.  It is up to the implementation
+        // whether the undo's cause shrinks in the tree.  In the initial
+        // implementation it won't.
+        {
+            tc.commit();
+
+            // Open the base table
+            base_cc = 
+                tc.openConglomerate(
+                    create_ret.base_conglomid,
+                    false,
+                    TransactionController.OPENMODE_FORUPDATE,
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_SERIALIZABLE);
+
+            // Open the secondary index
+            index_cc =	
+                tc.openConglomerate(
+                    create_ret.index_conglomid,
+                    false,
+                    TransactionController.OPENMODE_FORUPDATE,
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_SERIALIZABLE);
+
+            // BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER has been set to 2 so
+            // inserting 3 rows will cause a split at the leaf level.
+            // Make sure that normal abort leaves the committed split.
+            for (int i = 0; i < 3; i++)
+            {
+                ((SQLLongint)r1[0]).setValue(2);
+                ((SQLLongint)r1[1]).setValue(i);
+
+                // Insert the row into the base table;remember its location.
+                base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+                // Insert the row into the secondary index.
+                if (index_cc.insert(index_row1.getRow()) != 0)
+                    throw T_Fail.testFailMsg("insert failed");
+            }
+
+            tc.abort();
+
+            // index check - there should be no records left.
+            ScanController empty_scan = 
+                tc.openScan(create_ret.index_conglomid, false, 
+                            0,
+                            TransactionController.MODE_RECORD,
+                            TransactionController.ISOLATION_SERIALIZABLE,
+							(FormatableBitSet) null,
+                            null, ScanController.NA,
+                            null,
+                            null, ScanController.NA);
+
+            if (empty_scan.next())
+            {
+                throw T_Fail.testFailMsg(
+                    "t_002: there are still rows in table.");
+            }
+        }
+
+        tc.commit();
+        REPORT("Ending t_002");
+
+        return true;
+    }
+
+    private boolean t_003_scan_test_cases(
+    TransactionController   tc,
+    long                    index_conglomid,
+    T_SecondaryIndexRow     template
+    )
+        throws StandardException, T_Fail
+    {
+        boolean     ret_val = true;
+
+        // run through a predicates as described in the openScan() interface //
+        DataValueDescriptor[] start_key  = TemplateRow.newU8Row(1);
+        DataValueDescriptor[] stop_key   = TemplateRow.newU8Row(1);
+
+
+        // test predicate x = 5
+        //
+        //     result set should be: {5,2,16}, {5,4,17}, {5,6,18}
+        //
+        REPORT("scan (x = 5)");
+        ((SQLLongint)start_key[0]).setValue(5);
+        ((SQLLongint)stop_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE, 
+                   null,
+                   stop_key,  ScanController.GT,
+                   3, 16, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+                   
+        //  +---------------------------------------------------------+
+        //  |pred  |start|key|stop |key|rows returned |rows locked    |
+        //  |      |value|op |value|op |              |(serialization)|
+        //  +------+-----+---+-----+---+--------------+---------------+
+        //  |x > 5 |{5}  |GT |null |   |{6,1} .. {9,1}|{5,6} .. {9,1} |
+        //  +-----------------------------------------+---------------+
+        REPORT("scan (x > 5)");
+        ((SQLLongint)start_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GT, 
+                   null,
+                   null,  ScanController.NA,
+                   3, 19, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +---------------------------------------------------------+
+        //  |pred  |start|key|stop |key|rows returned |rows locked    |
+        //  |      |value|op |value|op |              |(serialization)|
+        //  +------+-----+---+-----+---+--------------+---------------+
+        //  |x >= 5|{5}  |GE |null |   |{5,2} .. {9,1}|{4,6} .. {9,1} |
+        //  +-----------------------------------------+---------------+
+        REPORT("scan (x >= 5)");
+        ((SQLLongint)start_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE, 
+                   null,
+                   null,  ScanController.NA,
+                   6, 16, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //
+        //  +---------------------------------------------------------+
+        //  |pred  |start|key|stop |key|rows returned |rows locked    |
+        //  |      |value|op |value|op |              |(serialization)|
+        //  +------+-----+---+-----+---+--------------+---------------+
+        //  |x <= 5|null |   |{5}  |GT |{1,1} .. {5,6}|first .. {5,6} |
+        //  +-----------------------------------------+---------------+
+        REPORT("scan (x <= 5)");
+        ((SQLLongint)stop_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   null, ScanController.NA, 
+                   null,
+                   stop_key,  ScanController.GT,
+                   8, 11, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+        //
+        //  +---------------------------------------------------------+
+        //  |pred  |start|key|stop |key|rows returned |rows locked    |
+        //  |      |value|op |value|op |              |(serialization)|
+        //  +------+-----+---+-----+---+--------------+---------------+
+        // 	|x < 5 |null |   |{5}  |GE |{1,1} .. {4,6}|first .. {4,6} |
+        //  +-----------------------------------------+---------------+
+        REPORT("scan (x < 5)");
+        ((SQLLongint)stop_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   null, ScanController.NA, 
+                   null,
+                   stop_key,  ScanController.GE,
+                   5, 11, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //long        col1[]  = { 1,  3,  4,  4,  4,  5,  5,  5,  6,  7,  9};
+        //long        col2[]  = { 1,  1,  2,  4,  6,  2,  4,  6,  1,  1,  1};
+        //long        col3[]  = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
+        //  +------------------------------------------------------------------+
+        //  |pred             |start|key|stop |key|rows returned|rows locked   |
+        //  |                 |value|op |value|op |             |(serialized)  |
+        //  +-----------------+------+--+-----+--+--------------+--------------+
+	    //  |x >= 5 and x <= 7|{5},  |GE|{7}  |GT|{5,2} .. {7,1}|{4,6} .. {7,1}|
+        // 	+------------------------------------------------------------------+
+        REPORT("scan (x >= 5 and x <= 7)");
+        ((SQLLongint)start_key[0]).setValue(5);
+        ((SQLLongint)stop_key[0]).setValue(7);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE,
+                   null,
+                   stop_key,  ScanController.GT,
+                   5, 16, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +------------------------------------------------------------------+
+        //  |pred             |start|key|stop |key|rows returned|rows locked   |
+        //  |                 |value|op |value|op |             |(serialized)  |
+        //  +-----------------+------+--+-----+--+--------------+--------------+
+	    //  |x = 5 and y > 2  |{5,2} |GT|{5}  |GT|{5,4} .. {5,6}|{5,2} .. {9,1}|
+        // 	+------------------------------------------------------------------+
+        REPORT("scan (x = 5 and y > 2)");
+        start_key  = TemplateRow.newU8Row(2);
+        stop_key   = TemplateRow.newU8Row(1);
+        ((SQLLongint)start_key[0]).setValue(5);
+        ((SQLLongint)start_key[1]).setValue(2);
+        ((SQLLongint)stop_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GT,
+                   null,
+                   stop_key,  ScanController.GT,
+                   2, 17, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +------------------------------------------------------------------+
+        //  |pred             |start|key|stop |key|rows returned|rows locked   |
+        //  |                 |value|op |value|op |             |(serialized)  |
+        //  +-----------------+------+--+-----+--+--------------+--------------+
+        // 	|x = 5 and y >= 2 | {5,2}|GE| {5} |GT|{5,2} .. {5,6}|{4,6} .. {9,1}|
+        // 	+------------------------------------------------------------------+
+        REPORT("scan (x = 5 and y >= 2)");
+        start_key  = TemplateRow.newU8Row(2);
+        stop_key   = TemplateRow.newU8Row(1);
+        ((SQLLongint)start_key[0]).setValue(5);
+        ((SQLLongint)start_key[1]).setValue(2);
+        ((SQLLongint)stop_key[0]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE,
+                   null,
+                   stop_key,  ScanController.GT,
+                   3, 16, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +------------------------------------------------------------------+
+        //  |pred             |start|key|stop |key|rows returned|rows locked   |
+        //  |                 |value|op |value|op |             |(serialized)  |
+        //  +-----------------+------+--+-----+--+--------------+--------------+
+        // 	|x = 5 and y < 5  | {5}  |GE|{5,5}|GE|{5,2} .. {5,4}|{4,6} .. {5,4}|
+        // 	+------------------------------------------------------------------+
+        REPORT("scan (x = 5 and y < 5)");
+        start_key  = TemplateRow.newU8Row(1);
+        stop_key   = TemplateRow.newU8Row(2);
+        ((SQLLongint)start_key[0]).setValue(5);
+        ((SQLLongint)stop_key[0]).setValue(5);
+        ((SQLLongint)stop_key[1]).setValue(5);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE,
+                   null,
+                   stop_key,  ScanController.GE,
+                   2, 16, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +------------------------------------------------------------------+
+        //  |pred             |start|key|stop |key|rows returned|rows locked   |
+        //  |                 |value|op |value|op |             |(serialized)  |
+        //  +-----------------+------+--+-----+--+--------------+--------------+
+        // 	|x = 2            | {2}  |GE| {2} |GT|none          |{1,1} .. {1,1}|
+        // 	+------------------------------------------------------------------+
+        REPORT("scan (x = 2)");
+        start_key  = TemplateRow.newU8Row(1);
+        stop_key   = TemplateRow.newU8Row(1);
+        ((SQLLongint)start_key[0]).setValue(2);
+        ((SQLLongint)stop_key[0]).setValue(2);
+        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
+                   template.getRow(),
+                   start_key, ScanController.GE,
+                   null,
+                   stop_key,  ScanController.GT,
+                   0, 0, T_QualifierTest.ORDER_FORWARD))
+        {
+            ret_val = false;
+        }
+
+        //  +-----------------------------+
+        // 	|max on btree - row locked    |
+        // 	+-----------------------------+
+        //
+        REPORT("max on btree, row locked.");
+        if (!tc.fetchMaxOnBtree(
+                index_conglomid,
+                0,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE,
+                (FormatableBitSet) null,
+                template.getRow()))
+        {
+            throw T_Fail.testFailMsg("found no max.");
+        }
+        else
+        {
+            // make sure right max was found.
+            long key = ((SQLLongint) template.getRow()[2]).getLong();
+            
+            if (key != 21)
+            {
+                throw T_Fail.testFailMsg("wrong max found.");
+            }
+        }
+
+        //  +-----------------------------+
+        // 	|max on btree - table locked    |
+        // 	+-----------------------------+
+        //
+        REPORT("max on btree, table locked.");
+        if (!tc.fetchMaxOnBtree(
+                index_conglomid,
+                0,
+                TransactionController.MODE_TABLE,
+                TransactionController.ISOLATION_SERIALIZABLE,
+                (FormatableBitSet) null,
+                template.getRow()))
+        {
+            throw T_Fail.testFailMsg("found no max.");
+        }
+        else
+        {
+            // make sure right max was found.
+            long key = ((SQLLongint) template.getRow()[2]).getLong();
+            
+            if (key != 21)
+            {
+                throw T_Fail.testFailMsg("wrong max found.");
+            }
+        }
+
+        //  +-----------------------------+
+        // 	|max on btree - row locked    |
+        // 	+-----------------------------+
+        //
+        REPORT("max on btree, row locked.");
+        if (!tc.fetchMaxOnBtree(
+                index_conglomid,
+                0,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_READ_COMMITTED,
+                (FormatableBitSet) null,
+                template.getRow()))
+        {
+            throw T_Fail.testFailMsg("found no max.");
+        }
+        else
+        {
+            // make sure right max was found.
+            long key = ((SQLLongint) template.getRow()[2]).getLong();
+            
+            if (key != 21)
+            {
+                throw T_Fail.testFailMsg("wrong max found.");
+            }
+        }
+
+        //  +-----------------------------+
+        // 	|max on btree - table locked    |
+        // 	+-----------------------------+
+        //
+        REPORT("max on btree, table locked.");
+        if (!tc.fetchMaxOnBtree(
+                index_conglomid,
+                0,
+                TransactionController.MODE_TABLE,
+                TransactionController.ISOLATION_READ_COMMITTED,
+                (FormatableBitSet) null,
+                template.getRow()))
+        {
+            throw T_Fail.testFailMsg("found no max.");
+        }
+        else
+        {
+            // make sure right max was found.
+            long key = ((SQLLongint) template.getRow()[2]).getLong();
+            
+            if (key != 21)
+            {
+                throw T_Fail.testFailMsg("wrong max found.");
+            }
+        }
+
+        return(ret_val);
+    }
+
+    /**
+     * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(), 
+     * BtreeScan.fetch().
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_003(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
+
+        // base row template - last column is just to make row long so that
+        // multiple pages are spanned.
+        DataValueDescriptor[] base_row             = TemplateRow.newU8Row(4);
+        base_row[3] = new SQLChar();
+
+        String   string_1500char = new String();
+        for (int i = 0; i < 300; i++)
+            string_1500char += "mikem";
+
+        boolean     ret_val = true;
+        long        value   = -1;
+        long        col1[]  = { 1,  3,  4,  4,  4,  5,  5,  5,  6,  7,  9};
+        long        col2[]  = { 1,  1,  2,  4,  6,  2,  4,  6,  1,  1,  1};
+        long        col3[]  = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
+
+        // set of deleted rows to make scans more interesting
+        long d_col1[] ={ 0,  2,  3,  4,  4,  5,  5,  5,  6,  7,  8, 10, 11, 12};
+        long d_col2[] ={ 1,  1,  2,  3,  5,  0,  3,  5,  0,  0,  1, 42, 42, 1};
+        long d_col3[] ={91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104};
+
+        REPORT("Starting t_003");
+
+        // create the base table
+        long base_conglomid = 
+            tc.createConglomerate(
+                "heap",                            // create a heap conglomerate
+                base_row,                          // base table template row
+				null, //column sort order - not required for heap
+                null,                              // default properties
+                TransactionController.IS_DEFAULT); // not temporary
+
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                base_conglomid, 
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        // initialize the secondary index row - pointing it at base row
+        index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
+
+        Properties properties = 
+            createProperties(
+                null,               // no current properties list 
+                false,              // don't allow duplicates
+                5,                  // 4 columns in index row
+                5,                  // non-unique index
+                true,               // maintain parent links
+                base_conglomid,     // base conglom id
+                4);                 // row loc in last column
+
+        long index_conglomid = 
+            tc.createConglomerate(
+                "BTREE",    				// create a btree secondary
+                index_row.getRow(),         // row template
+				null, //column sort order - default
+                properties,                 // properties
+                TransactionController.IS_DEFAULT);   // not temporary
+
+		// Open the conglomerate.
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row.
+        T_SecondaryIndexRow template = new T_SecondaryIndexRow();
+        RowLocation         row_loc  = base_cc.newRowLocationTemplate();
+        template.init(base_row, row_loc, 5);
+
+        // insert them in reverse order just to make sure btree is sorting them
+        for (int i = col1.length - 1; i >= 0; i--)
+        {
+            ((SQLLongint)(template.getRow()[0])).setValue(col1[i]);
+            ((SQLLongint)(template.getRow()[1])).setValue(col2[i]);
+            ((SQLLongint)(template.getRow()[2])).setValue(col3[i]);
+            base_row[3] = new SQLChar(string_1500char);
+
+            base_cc.insertAndFetchLocation(base_row, row_loc);
+
+            // Insert the row.
+            // System.out.println("Adding record (" + -(i - (col1.length -1)) +
+            //                ")" + template);
+            if (index_cc.insert(template.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+        }
+
+        index_cc.checkConsistency();
+
+        ((B2IController)index_cc).debugConglomerate();
+
+        ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
+
+        // insert and delete some interesting rows, deleted space management
+        // may or may not clean these up.
+        for (int i = d_col1.length - 1; i >= 0; i--)
+        {
+            ((SQLLongint)(template.getRow()[0])).setValue(d_col1[i]);
+            ((SQLLongint)(template.getRow()[1])).setValue(d_col2[i]);
+            ((SQLLongint)(template.getRow()[2])).setValue(d_col3[i]);
+            base_row[3] = new SQLChar(string_1500char);
+
+            base_cc.insertAndFetchLocation(base_row, row_loc);
+
+            // Insert the row.
+            // System.out.println("Adding record (" + -(i - (col1.length -1)) +
+            //                ")" + template);
+            if (index_cc.insert(template.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+
+            // now delete the row.
+            base_cc.delete(row_loc);
+
+            ScanController delete_scan = 
+                tc.openScan(index_conglomid, false,
+                            TransactionController.OPENMODE_FORUPDATE,
+                            TransactionController.MODE_RECORD,
+                            TransactionController.ISOLATION_SERIALIZABLE,
+                            (FormatableBitSet) null,
+                            template.getRow(), ScanController.GE, 
+                            null,
+                            template.getRow(), ScanController.GT); 
+
+            if (!delete_scan.next())
+            {
+                throw T_Fail.testFailMsg("delete could not find key");
+            }
+            else
+            {
+                delete_scan.delete();
+
+                if (delete_scan.next())
+                    throw T_Fail.testFailMsg("delete found more than one key");
+            }
+
+            delete_scan.close();
+        }
+
+        ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
+
+
+		// Close the conglomerate.
+		index_cc.close();
+
+        tc.commit();
+        REPORT("Ending t_003");
+
+        return(ret_val);
+    }
+
+    /**
+     * Test qualifiers.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_004(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        REPORT("Starting t_004");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+        Properties properties = 
+            createProperties(
+                null,       // no current properties list 
+                false,      // don't allow duplicates
+                4,          // 3 columns in index row
+                4,          // non-unique index
+                true,       // maintain parent links
+                create_ret.base_conglomid,        // fake base conglom for now
+                3);         // row loc in last column
+
+        T_QualifierTest q_test = 
+            new T_QualifierTest(
+                "BTREE",    				    // create a btree secondary
+                properties,                     // properties
+                false,                          // not temporary
+                out,
+                T_QualifierTest.ORDER_FORWARD); // ordered 
+
+        boolean test_result = q_test.t_testqual(tc);
+
+        REPORT("Ending t_004");
+
+        return(test_result);
+    }
+
+    /**
+     * Test Branch splits - number of rows necessary to cause splits is raw
+     * store implementation dependant (currently 5 rows per page in in-memory
+     * implementation).
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_005(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        boolean     ret_val = true;
+
+        REPORT("Starting t_005");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+		// Open the base conglomerate.
+		ConglomerateController base_cc =	
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the index conglomerate.
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+
+		// Create a row.
+		T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
+        RowLocation             rowloc    = base_cc.newRowLocationTemplate();
+        DataValueDescriptor[]   base_row  = TemplateRow.newU8Row(2);
+        index_row.init(base_row, rowloc, 3); 
+
+        // insert them in reverse order just to make sure btree is sorting them
+        for (int i = 200; i >= 0; i -= 4)
+        {
+            ((SQLLongint)base_row[0]).setValue(1);
+            ((SQLLongint)base_row[1]).setValue(i);
+            base_cc.insertAndFetchLocation(base_row, rowloc);
+
+            if (index_cc.insert(index_row.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+        }
+        for (int i = 199; i >= 0; i -= 4)
+        {
+            ((SQLLongint)base_row[0]).setValue(1);
+            ((SQLLongint)base_row[1]).setValue(i);
+
+            base_cc.insertAndFetchLocation(base_row, rowloc);
+            if (index_cc.insert(index_row.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+        }
+
+        index_cc.checkConsistency();
+
+		// Close the conglomerate.
+		index_cc.close();
+
+        tc.commit();
+
+        // Search for each of the keys and delete them one at a time.
+        DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
+        for (int i = 200; i >= 0; i -= 4)
+        {
+            ((SQLLongint)delete_key[0]).setValue(1);
+            ((SQLLongint)delete_key[1]).setValue(i);
+
+            if (!t_delete(
+                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
+            {
+                ret_val = false;
+            }
+        }
+        for (int i = 199; i >= 0; i -= 4)
+        {
+            ((SQLLongint)delete_key[0]).setValue(1);
+            ((SQLLongint)delete_key[1]).setValue(i);
+
+            if (!t_delete(
+                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
+            {
+                ret_val = false;
+            }
+        }
+
+        tc.commit();
+
+		// Open the base conglomerate.
+		base_cc = 
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+
+		// Open the conglomerate.
+		index_cc = 
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        // flush and empty cache to make sure rereading stuff works.
+        RawStoreFactory rawstore = 
+            (RawStoreFactory) Monitor.findServiceModule(
+                this.store_module, RawStoreFactory.MODULE);
+
+        rawstore.idle();
+
+        // now make sure that additional splits don't cause delete bits to 
+        // be enabled (one early bug did so).
+        
+        for (int i = 200; i >= 0; i -= 3)
+        {
+            ((SQLLongint)base_row[0]).setValue(1);
+            ((SQLLongint)base_row[1]).setValue(i);
+
+            base_cc.insertAndFetchLocation(base_row, rowloc);
+            if (index_cc.insert(index_row.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+        }
+        for (int i = 200; i >= 0; i -= 3)
+        {
+            ((SQLLongint)delete_key[0]).setValue(1);
+            ((SQLLongint)delete_key[1]).setValue(i);
+
+            if (!t_delete(
+                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
+            {
+                ret_val = false;
+            }
+        }
+
+        // index check - there should be no records left.
+        ScanController empty_scan = 
+            tc.openScan(create_ret.index_conglomid, false, 
+                        0,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+        if (empty_scan.next())
+			throw T_Fail.testFailMsg("t_005: there are still rows in table.");
+
+        index_cc.checkConsistency();
+
+        for (int i = 600; i >= 400; i -= 3)
+        {
+            ((SQLLongint)base_row[0]).setValue(1);
+            ((SQLLongint)base_row[1]).setValue(i);
+
+            base_cc.insertAndFetchLocation(base_row, rowloc);
+            if (index_cc.insert(index_row.getRow()) != 0)
+                throw T_Fail.testFailMsg("insert failed");
+        }
+
+        index_cc.checkConsistency();
+
+        tc.abort();
+
+        // index check - there should be no records left.
+        empty_scan = 
+            tc.openScan(create_ret.index_conglomid, false,
+                        0,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+        if (empty_scan.next())
+			throw T_Fail.testFailMsg("t_005: there are still rows in table.");
+
+
+        REPORT("Ending t_005");
+
+        return(ret_val);
+    }
+    /**
+     * Test unimplemented interfaces.  
+     *
+     * The following ScanController interfaces are not supported by the
+     * btree implementation, because row locations are not returned outside
+     * the interface.  At some point we may package a key as a row location
+     * but that does not really give any more functionality than using scan
+     * to find your key:
+     *     ScanController.fetchLocation()
+     *     ScanController.newRowLocationTemplate()
+     *     ScanController.replace()
+     *     ConglomerateController.delete()
+     *     ConglomerateController.fetch()
+	 *     ConglomerateController.insertAndFetchLocation()
+	 *     ConglomerateController.newRowLocationTemplate()
+     *     ConglomerateController.replace()
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_006(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        REPORT("Starting t_006");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+		// Open the base conglomerate.
+		ConglomerateController base_cc =	
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the index conglomerate.
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a base row template.
+        DataValueDescriptor[]   base_row    = TemplateRow.newU8Row(2);
+        RowLocation             base_rowloc = base_cc.newRowLocationTemplate();
+
+        T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
+        index_row_from_base_row.init(base_row, base_rowloc, 3);
+        ((SQLLongint)base_row[0]).setValue(1);
+
+		// Create a row.
+		T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
+        index_row.init(TemplateRow.newU8Row(2), 
+                        base_cc.newRowLocationTemplate(), 3);
+
+        // test: make sure scan position is right after inserts before scan
+        //       no split case.  In this case the slot position of the current
+        //       position should change, but the code will keep a record handle
+        //       and not need to reposition by key.
+        // before keys: 1000, 3000
+        // last key gotten froms scan : 0
+        // insert keys:1-900
+        // next key from scan should be: 5
+
+        // insert 1000
+        ((SQLLongint)base_row[1]).setValue(1000);
+        base_cc.insertAndFetchLocation(base_row, base_rowloc);
+        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
+        {
+			throw T_Fail.testFailMsg("insert failed");
+        }
+
+        // try each of the unsupported interfaces:
+        try
+        {
+            index_cc.delete(null);
+            return(FAIL("t_006: ConglomerateController.delete() succeeded."));
+        }
+        catch (StandardException e)
+        {
+        }
+        try
+        {
+            if (!index_cc.fetch(
+                    null, RowUtil.EMPTY_ROW, (FormatableBitSet) null))
+            {
+                return(FAIL("t_006: ConglomerateController.fetch() bad ret."));
+            }
+            return(FAIL("t_006: ConglomerateController.fetch() succeeded."));
+        }
+        catch (StandardException e)
+        {
+        }
+        try
+        {
+            index_cc.insertAndFetchLocation((DataValueDescriptor[]) null, null);
+            return(FAIL(
+                "t_006: ConglomerateController.insertAndFetchLocation() succeeded."));
+        }
+        catch (StandardException e)
+        {
+        }
+        try
+        {
+            RowLocation rowloc = index_cc.newRowLocationTemplate();
+            return(FAIL(
+                "t_006: ConglomerateController.newRowLocationTemplate() succeeded."));
+        }
+        catch (StandardException e)
+        {
+        }
+        try
+        {
+            index_cc.replace(null, null, null);
+            return(FAIL("t_006: ConglomerateController.replace() succeeded."));
+        }
+        catch (StandardException e)
+        {
+        }
+
+        index_cc.close();
+
+        // open a new scan
+
+        ScanController scan = 
+            tc.openScan(create_ret.index_conglomid, false, 
+                        0,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null, 
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+
+        int numrows = 0;
+        while (scan.next())
+        {
+            numrows++;
+
+            scan.fetch(index_row_from_base_row.getRow());
+
+            try
+            {
+                scan.fetchLocation(null);
+                return(FAIL("t_006: scan.fetchLocation() succeeded"));
+            }
+            catch (StandardException e)
+            {
+            }
+
+            try
+            {
+                RowLocation rowloc = scan.newRowLocationTemplate();
+                return(FAIL("t_006: scan.newRowLocationTemplate() succeeded"));
+            }
+            catch (StandardException e)
+            {
+            }
+
+            try
+            {
+                scan.replace(index_row_from_base_row.getRow(), (FormatableBitSet) null);
+                return(FAIL("t_006: scan.replace() succeeded"));
+            }
+            catch (StandardException e)
+            {
+            }
+
+        }
+
+        // make sure that scan.next() continues to return false
+        if (scan.next())
+            return(FAIL("t_006: scan.next() returned true after false."));
+
+        scan.close();
+
+        if (numrows != 1)
+        {
+            return(FAIL("(t_scan) wrong number of rows. Expected " +
+                   "1 row, but got " + numrows + "rows."));
+        }
+
+        REPORT("Ending t_006");
+        return(true);
+    }
+
+    /**
+     * Test multiple scans in a single page/no split 
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_007(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        boolean     ret_val     = true;
+
+        REPORT("Starting t_007");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+		// Open the base conglomerate.
+		ConglomerateController base_cc =	
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the index conglomerate.
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row.
+		T_SecondaryIndexRow   index_row = new T_SecondaryIndexRow();
+        DataValueDescriptor[] base_row  = TemplateRow.newU8Row(2);
+        RowLocation           row_loc   = base_cc.newRowLocationTemplate();
+        index_row.init(base_row, row_loc, 3);
+
+		// Create a row.
+        ((SQLLongint)(index_row.getRow()[0])).setValue(1);
+
+        // test: make sure scan position is right after inserts before scan
+        //       no split case.  In this case the slot position of the current
+        //       position should change, but the code will keep a record handle
+        //       and not need to reposition by key.
+        // before keys: 3, 5
+        // last key gotten froms scan : 0
+        // insert keys:1, 2
+        // next key from scan should be: 5
+
+        // insert 3
+        ((SQLLongint)(index_row.getRow()[1])).setValue(3);
+        base_cc.insertAndFetchLocation(base_row, row_loc);
+        if (index_cc.insert(index_row.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        // insert 5
+        ((SQLLongint)(index_row.getRow()[1])).setValue(5);
+        base_cc.insertAndFetchLocation(base_row, row_loc);
+        if (index_cc.insert(index_row.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        // open a new scan
+
+        ScanController scan = 
+            tc.openScan(create_ret.index_conglomid, false,
+                        0,                        
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(scan.next());
+
+        scan.fetch(index_row.getRow());
+        long key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 3);
+
+        // insert 1
+        ((SQLLongint)(index_row.getRow()[1])).setValue(1);
+        base_cc.insertAndFetchLocation(base_row, row_loc);
+        if (index_cc.insert(index_row.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        // insert 2
+        ((SQLLongint)(index_row.getRow()[1])).setValue(2);
+        base_cc.insertAndFetchLocation(base_row, row_loc);
+        if (index_cc.insert(index_row.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        // current position should not have changed
+        scan.fetch(index_row.getRow());
+        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 3);
+
+        // next position should be 5
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(scan.next());
+        scan.fetch(index_row.getRow());
+        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 5);
+
+        index_cc.close();
+        scan.close();
+
+        REPORT("Ending t_007");
+
+        return(ret_val);
+    }
+    /**
+     * Test multiple scans in a single table/with splits
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_008(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        boolean     ret_val     = true;
+
+        REPORT("Starting t_008");
+
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 0, create_ret);
+
+		// Open the base conglomerate.
+		ConglomerateController base_cc =	
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the index conglomerate.
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a base row template.
+        DataValueDescriptor[]   base_row    = TemplateRow.newU8Row(2);
+        RowLocation             base_rowloc = base_cc.newRowLocationTemplate();
+
+        T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
+        index_row_from_base_row.init(base_row, base_rowloc, 3);
+        ((SQLLongint)base_row[0]).setValue(1);
+
+		// Create a row.
+		T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
+        index_row.init(TemplateRow.newU8Row(2), 
+                        base_cc.newRowLocationTemplate(), 3);
+
+        // test: make sure scan position is right after inserts before scan
+        //       no split case.  In this case the slot position of the current
+        //       position should change, but the code will keep a record handle
+        //       and not need to reposition by key.
+        // before keys: 1000, 3000
+        // last key gotten froms scan : 0
+        // insert keys:1-900
+        // next key from scan should be: 5
+
+        // insert 1000
+        ((SQLLongint)base_row[1]).setValue(1000);
+        base_cc.insertAndFetchLocation(base_row, base_rowloc);
+        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
+        {
+			throw T_Fail.testFailMsg("insert failed");
+        }
+
+        // open a new scan
+
+        ScanController scan = 
+            tc.openScan(create_ret.index_conglomid, false,
+                        0,
+                        TransactionController.MODE_RECORD,
+                        TransactionController.ISOLATION_SERIALIZABLE,
+						(FormatableBitSet) null,
+                        null, ScanController.NA,
+                        null,
+                        null, ScanController.NA);
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(scan.next());
+
+        scan.fetch(index_row.getRow());
+        long key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 1000);
+
+        // The following test works best if 5 rows fit on one page
+
+        //for (int i = 1; i < 900; i++)
+        for (int i = 0; i < 6; i++)
+        {
+            // insert i
+            ((SQLLongint)base_row[1]).setValue(i);
+            base_cc.insertAndFetchLocation(base_row, base_rowloc);
+
+            if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
+            {
+                throw T_Fail.testFailMsg("insert failed");
+            }
+
+            // About every 2nd split page, recheck the position
+            
+            if (i % 10 == 0)
+            {
+                // current position should not have changed
+                scan.fetch(index_row.getRow());
+                key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+                if (SanityManager.DEBUG)
+                    SanityManager.ASSERT(key == 1000);
+            }
+
+        }
+
+        // insert 3000
+        ((SQLLongint)base_row[1]).setValue(3000);
+        base_cc.insertAndFetchLocation(base_row, base_rowloc);
+        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
+        {
+			throw T_Fail.testFailMsg("insert failed");
+        }
+
+        // current position should not have changed
+        scan.fetch(index_row.getRow());
+        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 1000);
+
+        // next position should be 3000
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(scan.next());
+        scan.fetch(index_row.getRow());
+        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(key == 3000);
+
+        index_cc.checkConsistency();
+
+        index_cc.close();
+        scan.close();
+
+        REPORT("Ending t_008");
+
+        return(ret_val);
+    }
+
+    /**
+     * Test unique/nonunique indexes - both positive and negative cases.
+     * <p>
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     **/
+    protected boolean t_009(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        ScanController scan         = null;
+
+        REPORT("Starting t_009");
+
+        // NON-UNIQUE INDEX
+        T_CreateConglomRet create_ret = new T_CreateConglomRet();
+
+        createCongloms(tc, 2, false, false, 2, create_ret);
+
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the secondary index
+		ConglomerateController index_cc =	
+            tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row and insert into base table, remembering it's location.
+		DataValueDescriptor[] r1             = TemplateRow.newU8Row(2);
+        T_SecondaryIndexRow  index_row1      = new T_SecondaryIndexRow();
+        RowLocation          base_rowloc1    = base_cc.newRowLocationTemplate();
+
+        index_row1.init(r1, base_rowloc1, 3);
+
+        ((SQLLongint)r1[0]).setValue(1);
+        ((SQLLongint)r1[1]).setValue(1000);
+
+        // Insert the row into the base table;remember its location.
+        base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+        // Insert the row into the secondary index.
+        if (index_cc.insert(index_row1.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        if (index_cc.insert(index_row1.getRow()) != 
+                ConglomerateController.ROWISDUPLICATE)
+        {
+            throw T_Fail.testFailMsg(
+                "insert of duplicate returned wrong return value:");
+        }
+
+        // Delete the only entry and make sure it can be reinserted in same
+        // xact.
+        DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
+        ((SQLLongint)delete_key[0]).setValue(1);
+        ((SQLLongint)delete_key[1]).setValue(1000);
+
+        if (!t_delete(tc, create_ret.index_conglomid, 
+                 delete_key, create_ret.index_template_row))
+        {
+            throw T_Fail.testFailMsg(
+                "t_008: could not delete key.");
+        }
+
+        if (index_cc.insert(index_row1.getRow()) != 0)
+            throw T_Fail.testFailMsg("insert failed");
+
+        tc.commit();
+
+        // UNIQUE INDEX
+        create_ret = new T_CreateConglomRet();
+
+        // Create the btree so that it only allows 2 rows per page.
+        createCongloms(tc, 2, true, false, 2, create_ret);
+
+        // Open the base table
+        base_cc = tc.openConglomerate(
+                create_ret.base_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Open the secondary index
+		index_cc =	tc.openConglomerate(
+                create_ret.index_conglomid,
+                false,
+                TransactionController.OPENMODE_FORUPDATE,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+		// Create a row and insert into base table, remembering it's location.
+		r1              = TemplateRow.newU8Row(2);
+        index_row1      = new T_SecondaryIndexRow();
+        base_rowloc1    = base_cc.newRowLocationTemplate();
+
+        index_row1.init(r1, base_rowloc1, 3);
+
+        ((SQLLongint)r1[0]).setValue(1);
+        ((SQLLongint)r1[1]).setValue(1000);
+
+        // Insert the row into the base table;remember its location.
+        base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+        // Insert the row into the secondary index.
+        if (index_cc.insert(index_row1.getRow()) != 0)
+			throw T_Fail.testFailMsg("insert failed");
+
+        // Insert the row into the base table;remember its location.
+        base_cc.insertAndFetchLocation(r1, base_rowloc1);
+
+        // Insert the row into the secondary index.
+        if (index_cc.insert(index_row1.getRow()) != 
+                ConglomerateController.ROWISDUPLICATE)
+        {
+            throw T_Fail.testFailMsg(
+                "insert of duplicate returned wrong return value:");
+        }
+
+        // Delete the only entry and make sure it can be reinserted in same
+        // xact.
+        delete_key = TemplateRow.newU8Row(2);
+        ((SQLLongint)delete_key[0]).setValue(1);
+        ((SQLLongint)delete_key[1]).setValue(1000);
+
+        if (!t_delete(tc, create_ret.index_conglomid, 
+                 delete_key, create_ret.index_template_row))
+        {
+            throw T_Fail.testFailMsg(
+                "t_008: could not delete key.");
+        }
+
+
+        if (index_cc.insert(index_row1.getRow()) != 0)
+            throw T_Fail.testFailMsg("insert failed");
+
+        REPORT("Ending t_009");
+
+        return(true);
+    }
+
+    /**
+     * Test restoreToNull
+     *
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     */
+    protected boolean t_010(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        REPORT("Starting t_006");
+
+        B2I testbtree = new B2I();
+
+        // test restoreToNull()
+        testbtree.restoreToNull();
+
+        if (!(testbtree.isNull()))
+            throw T_Fail.testFailMsg("bad restoreToNull/isNull");
+
+        // test bad container open not working.
+        try
+        {
+
+            // the following open should fail with a containerNotFound error
+            
+            // for testing purposes - assume TransactionController can be casted
+            TransactionManager tm = (TransactionManager) tc;
+            ConglomerateController cc = 
+                testbtree.open(
+                    tm, tm.getRawStoreXact(), false, 0, 0, 
+                    (LockingPolicy) null, 
+                    null, null);
+
+            throw T_Fail.testFailMsg("bad open succeeded.");
+        }
+        catch(StandardException t)
+        {
+            // expected path comes here.
+        }
+
+
+        // create the base table
+        DataValueDescriptor[]   base_row        = TemplateRow.newU8Row(2);
+        T_SecondaryIndexRow     index_row1      = new T_SecondaryIndexRow();
+
+        long base_conglomid = tc.createConglomerate(
+                                        "heap",   // create a heap conglomerate
+                                        base_row, // base table template row
+										null, //column sort order - not required for heap
+                                        null,     // default properties
+                                        TransactionController.IS_DEFAULT);
+        // Open the base table
+        ConglomerateController base_cc = 
+            tc.openConglomerate(
+                base_conglomid, 
+                false,
+                0,
+                TransactionController.MODE_RECORD,
+                TransactionController.ISOLATION_SERIALIZABLE);
+
+        RowLocation         base_rowloc1    = base_cc.newRowLocationTemplate();
+
+        index_row1.init(base_row, base_rowloc1, 3);
+
+        // create the secondary index
+        Properties properties = 
+            createProperties(
+                null,           // no current properties list 
+                false,          // don't allow duplicates
+                3,   // index on all base row cols + row location
+                2,   // non-unique index
+                true,           // maintain parent links
+                -42, // fake base conglom for now
+                2);      // row loc in last column
+
+        TransactionManager tm = (TransactionManager) tc;
+
+        // test bad property
+        try
+        {
+            testbtree.create(
+                tm, -1, ContainerHandle.DEFAULT_ASSIGN_ID, index_row1.getRow(),
+                null, null, TransactionController.IS_TEMPORARY); 
+
+            throw T_Fail.testFailMsg("bad create succeeded.");
+        }
+        catch (StandardException t)
+        {
+            // expected path comes here.
+        }
+
+        // try bad properties
+
+        // create the secondary index
+        properties = createProperties(
+                            null,           // no current properties list 
+                            false,          // don't allow duplicates
+                            3,   // index on all base row cols + row location
+                            1,   // 1 unique field leaving 1 non key field 
+                                 // other than the rowlocation - should not be
+                                 // allowed.
+                            true,           // maintain parent links
+                            -42, // fake base conglom for now
+                            2);      // row loc in last column
+        try
+        {
+            long index_conglomid = 
+                tc.createConglomerate(
+                    "BTREE",    				// create a btree secondary
+                    index_row1.getRow(), // row template
+					null, //column sort order - default
+                    properties,                 // properties
+                    TransactionController.IS_DEFAULT); // not temporary
+
+            throw T_Fail.testFailMsg("bad create succeeded.");
+
+        }
+        catch (Throwable t)
+        {
+            // expected path comes here
+        }
+
+
+        REPORT("Ending t_010");
+        return(true);
+    }
+
+    /**
+     * Test Special cases of split.
+     * <p>
+     * Testing: restartSplitFor() call in LeafControlRow().
+     *
+     * The first case is where we split
+     * down the tree and reach the leaf, pick a split point, and then find
+     * that there is not enough room to insert row into parent branch page.
+     *
+     * The second case is the same as the first except the calling code is
+     * trying to split a branch page and the parent branch page doesn't have
+     * room for the row.
+     *
+	 * @exception  StandardException  Standard exception policy.
+	 * @exception  T_Fail  Throws T_Fail on any test failure.
+     **/
+    protected boolean t_011(TransactionController tc)
+        throws StandardException, T_Fail
+    {
+        boolean     ret_val = true;
+

[... 2557 lines stripped ...]


Mime
View raw message