0001: /*
0002:
0003: Derby - Class org.apache.derbyTesting.unitTests.store.T_b2i
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derbyTesting.unitTests.store;
0023:
0024: // impl imports are the preferred way to create unit tests.
0025: import org.apache.derbyTesting.unitTests.harness.T_MultiIterations;
0026: import org.apache.derbyTesting.unitTests.harness.T_Fail;
0027:
0028: import org.apache.derby.impl.store.access.btree.index.*;
0029:
0030: import org.apache.derby.iapi.types.SQLLongint;
0031:
0032: import org.apache.derby.iapi.reference.Property;
0033: import org.apache.derby.iapi.reference.SQLState;
0034:
0035: import org.apache.derby.iapi.services.io.FormatableBitSet;
0036: import org.apache.derby.iapi.services.i18n.MessageService;
0037:
0038: import org.apache.derby.iapi.services.monitor.Monitor;
0039:
0040: import org.apache.derby.iapi.services.sanity.SanityManager;
0041: import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
0042: import org.apache.derby.iapi.services.context.ContextService;
0043: import org.apache.derby.iapi.services.context.ContextManager;
0044: import org.apache.derby.iapi.services.io.FormatIdUtil;
0045:
0046: import org.apache.derby.iapi.error.StandardException;
0047: import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
0048: import org.apache.derby.iapi.store.access.AccessFactory;
0049: import org.apache.derby.iapi.store.access.ConglomerateController;
0050: import org.apache.derby.iapi.store.access.Qualifier;
0051: import org.apache.derby.iapi.types.RowLocation;
0052: import org.apache.derby.iapi.store.access.ScanController;
0053: import org.apache.derby.iapi.store.access.ScanInfo;
0054: import org.apache.derby.iapi.store.access.TransactionController;
0055: import org.apache.derby.iapi.store.access.RowUtil;
0056: import org.apache.derby.iapi.store.access.ColumnOrdering;
0057:
0058: import org.apache.derby.iapi.store.raw.ContainerHandle;
0059: import org.apache.derby.iapi.store.raw.LockingPolicy;
0060: import org.apache.derby.iapi.store.raw.RawStoreFactory;
0061:
0062: import org.apache.derby.iapi.types.DataValueDescriptor;
0063:
0064: import org.apache.derby.impl.store.access.btree.BTree;
0065: import org.apache.derby.impl.store.access.conglomerate.TemplateRow;
0066: import org.apache.derby.iapi.types.SQLChar;
0067:
0068: import java.util.Properties;
0069:
0070: public class T_b2i extends T_MultiIterations {
0071:
0072: private static final String testService = "b2iTest";
0073:
0074: private Object store_module = null;
0075:
0076: private ContextService contextService = null;
0077:
0078: /* Methods required by T_MultiIterations */
0079:
0080: /**
0081: * Routine one once per invocation of the test by the driver.
0082: * <p>
0083: * Do work that should only be done once, no matter how many times
0084: * runTests() may be executed.
0085: *
0086: * @exception T_Fail Thrown on any error.
0087: **/
0088: protected void setupTest() throws T_Fail {
0089: // don't automatic boot this service if it gets left around
0090: if (startParams == null) {
0091: startParams = new Properties();
0092: }
0093: startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
0094: // remove the service directory to ensure a clean run
0095: startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE
0096: .toString());
0097:
0098: // see if we are testing encryption
0099: startParams = T_Util.setEncryptionParam(startParams);
0100:
0101: try {
0102: store_module = Monitor.createPersistentService(
0103: getModuleToTestProtocolName(), testService,
0104: startParams);
0105:
0106: contextService = ContextService.getFactory();
0107:
0108: } catch (StandardException mse) {
0109: throw T_Fail.exceptionFail(mse);
0110: }
0111: }
0112:
0113: /*
0114: ** Methods required by T_Generic
0115: */
0116:
0117: public String getModuleToTestProtocolName() {
0118: return AccessFactory.MODULE;
0119: }
0120:
0121: /**
0122: * Driver routine for the btree secondary index tests.
0123: * <p>
0124: *
0125: * @exception T_Fail Throws T_Fail on any test failure.
0126: **/
0127: protected void runTestSet() throws T_Fail {
0128: AccessFactory store = null;
0129: TransactionController tc = null;
0130: boolean pass = false;
0131:
0132: out.println("executing b2i test");
0133:
0134: store = (AccessFactory) store_module;
0135:
0136: if (store == null) {
0137: throw T_Fail.testFailMsg(getModuleToTestProtocolName()
0138: + " service not started.");
0139: }
0140:
0141: ContextManager cm1 = contextService.newContextManager();
0142: contextService.setCurrentContextManager(cm1);
0143:
0144: REPORT("(unitTestMain) Testing " + testService);
0145:
0146: try {
0147:
0148: tc = store.getTransaction(cm1);
0149:
0150: pass = true;
0151:
0152: if (t_005(tc) && t_001(tc) && t_003(tc) && t_004(tc)
0153: && t_005(tc) && t_006(tc) && t_009(tc) && t_010(tc)
0154: && t_011(tc) && t_012(tc) && t_013(tc) && t_014(tc)
0155: && t_017(tc) && t_018(tc) && t_019(tc) && t_020(tc))
0156:
0157: {
0158: pass = true;
0159:
0160: if (SanityManager.DEBUG) {
0161: pass = false;
0162:
0163: // The following tests depend on SanityManager functionality
0164: // so can not be run in an insane server.
0165:
0166: if (t_002(tc) && t_007(tc) && t_008(tc)
0167: && t_015(tc) && t_016(tc))
0168: pass = true;
0169: }
0170: }
0171:
0172: tc.commit();
0173: tc.destroy();
0174: } catch (StandardException e) {
0175: String msg = e.getMessage();
0176: if (msg == null)
0177: msg = e.getClass().getName();
0178: REPORT(msg);
0179:
0180: e.printStackTrace(out.getPrintWriter());
0181: cm1.cleanupOnError(e);
0182:
0183: pass = false;
0184: } catch (Throwable t) {
0185: String msg = t.getMessage();
0186: if (msg == null)
0187: msg = t.getClass().getName();
0188: REPORT(msg);
0189:
0190: t.printStackTrace(out.getPrintWriter());
0191: cm1.cleanupOnError(t);
0192:
0193: pass = false;
0194: } finally {
0195: contextService.resetCurrentContextManager(cm1);
0196: }
0197:
0198: if (!pass)
0199: throw T_Fail.testFailMsg("");
0200: }
0201:
0202: /**
0203: * Utility routine to create base table for tests.
0204: * <p>
0205: * A little utility routine to create base tables for tests. Just
0206: * here to make tests a little more readable. It currently just
0207: * creates a heap table with "num_cols" SQLLongint columns.
0208: *
0209: * @return The identifier to be used to open the conglomerate later.
0210: *
0211: * @param num_cols the number of columns in the base table.
0212: *
0213: * @exception StandardException Standard exception policy.
0214: **/
0215:
0216: void createCongloms(TransactionController tc, int num_cols,
0217: boolean unique, boolean varying_first_col,
0218: int max_btreerows_per_page, T_CreateConglomRet ret_val)
0219: throws StandardException {
0220: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
0221: DataValueDescriptor[] base_row = TemplateRow.newU8Row(num_cols);
0222:
0223: if (varying_first_col) {
0224: SQLChar string_col = new SQLChar();
0225:
0226: base_row[0] = string_col;
0227: }
0228:
0229: long base_conglomid = 0;
0230:
0231: // create the base table
0232: base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0233: base_row, // base table template row
0234: null, //column sort order - not required for heap
0235: null, // default properties
0236: TransactionController.IS_DEFAULT);// not temporary
0237:
0238: // Open the base table
0239: ConglomerateController base_cc = tc.openConglomerate(
0240: base_conglomid, false,
0241: TransactionController.OPENMODE_FORUPDATE,
0242: TransactionController.MODE_RECORD,
0243: TransactionController.ISOLATION_SERIALIZABLE);
0244:
0245: // initialize the secondary index row - pointing it at base row
0246: RowLocation base_rowloc = base_cc.newRowLocationTemplate();
0247: index_row.init(base_row, base_rowloc, num_cols + 1);
0248:
0249: // create the secondary index
0250: Properties properties = createProperties(null, // no current properties list
0251: false, // don't allow duplicates
0252: num_cols + 1, // index on all base row cols + row location
0253: (unique ? num_cols : num_cols + 1), // non-unique index
0254: true, // maintain parent links
0255: base_conglomid, // base conglomid
0256: num_cols); // row loc in last column
0257:
0258: if (max_btreerows_per_page > 1) {
0259: if (BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER != null) {
0260: properties.put(
0261: BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER,
0262: String.valueOf(max_btreerows_per_page));
0263: }
0264: }
0265:
0266: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
0267: index_row.getRow(), // index row template
0268: null, //column sort order - default
0269: properties, // properties
0270: TransactionController.IS_DEFAULT); // not temporary
0271:
0272: // return values to caller
0273: ret_val.base_conglomid = base_conglomid;
0274: ret_val.index_conglomid = index_conglomid;
0275: // RESOLVE (mikem - 04/29/98 - why is following line commented out?
0276: // ret_val.base_template_row = TemplateRow.newU8Row(num_cols);
0277: ret_val.index_template_row = index_row.getRow();
0278:
0279: return;
0280: }
0281:
0282: protected static Properties createProperties(
0283: Properties input_properties, boolean input_allowduplicates,
0284: int input_nkeyfields, int input_nuniquecolumns,
0285: boolean input_maintainparentlinks,
0286: long input_baseconglomerateid, int input_rowlocationcolumn)
0287: throws StandardException {
0288: Properties properties = ((input_properties == null) ? new Properties()
0289: : input_properties);
0290: properties.put("allowDuplicates", String
0291: .valueOf(input_allowduplicates));
0292: properties.put("nKeyFields", String.valueOf(input_nkeyfields));
0293: properties.put("nUniqueColumns", String
0294: .valueOf(input_nuniquecolumns));
0295: properties.put("maintainParentLinks", String
0296: .valueOf(input_maintainparentlinks));
0297: properties.put("baseConglomerateId", String
0298: .valueOf(input_baseconglomerateid));
0299: properties.put("rowLocationColumn", String
0300: .valueOf(input_rowlocationcolumn));
0301: return (properties);
0302: }
0303:
0304: /**
0305: * Test a single scan.
0306: *
0307: * @exception StandardException Standard exception policy.
0308: */
0309: protected boolean t_scan(TransactionController tc, long conglomid,
0310: DataValueDescriptor[] template,
0311: DataValueDescriptor[] start_key, int start_op,
0312: Qualifier qualifier[][], DataValueDescriptor[] stop_key,
0313: int stop_op, int expect_numrows, int expect_key)
0314: throws StandardException {
0315:
0316: // open a new scan
0317:
0318: ScanController scan = tc.openScan(conglomid, false,
0319: TransactionController.OPENMODE_FORUPDATE,
0320: TransactionController.MODE_RECORD,
0321: TransactionController.ISOLATION_SERIALIZABLE,
0322: (FormatableBitSet) null, start_key, start_op,
0323: qualifier, stop_key, stop_op);
0324:
0325: long key = -42;
0326: long numrows = 0;
0327:
0328: while (scan.next()) {
0329: scan.fetch(template);
0330:
0331: key = ((SQLLongint) template[2]).getLong();
0332:
0333: if (key != expect_key) {
0334: return (FAIL("(t_scan) wrong key, expected ("
0335: + expect_key + ")" + "but got (" + key + ")."));
0336: } else {
0337: expect_key++;
0338: numrows++;
0339: }
0340: }
0341:
0342: ((B2IForwardScan) scan).checkConsistency();
0343:
0344: scan.close();
0345:
0346: if (numrows != expect_numrows) {
0347: return (FAIL("(t_scan) wrong number of rows. Expected "
0348: + expect_numrows + " rows, but got " + numrows
0349: + "rows."));
0350: }
0351:
0352: return (true);
0353: }
0354:
0355: /**
0356: * delete a single key, given key value. assumes 3 column table, first
0357: * column = 1, second column is a unique key, and 3rd column is a
0358: * RecordHandle into the base table.
0359: *
0360: * @exception StandardException Standard exception policy.
0361: */
0362: protected boolean t_delete(TransactionController tc,
0363: long conglomid, DataValueDescriptor[] search_key,
0364: DataValueDescriptor[] template) throws StandardException {
0365: SQLLongint column0 = new SQLLongint(-1);
0366: SQLLongint column1 = new SQLLongint(-1);
0367:
0368: // open a new scan
0369:
0370: ScanController scan = tc.openScan(conglomid, false,
0371: TransactionController.OPENMODE_FORUPDATE,
0372: TransactionController.MODE_RECORD,
0373: TransactionController.ISOLATION_SERIALIZABLE,
0374: (FormatableBitSet) null, search_key, ScanController.GE,
0375: null, search_key, ScanController.GT);
0376:
0377: long expect_key = ((SQLLongint) search_key[1]).getLong();
0378:
0379: int numrows = 0;
0380: DataValueDescriptor[] partialRow = new DataValueDescriptor[2];
0381: partialRow[0] = column0;
0382: partialRow[1] = column1;
0383:
0384: while (scan.next()) {
0385: numrows++;
0386:
0387: scan.fetch(partialRow);
0388:
0389: if (column0.getLong() != 1)
0390: return (FAIL("(t_delete) column[0] value is not 1"));
0391:
0392: if (column1.getLong() != expect_key)
0393: return (FAIL("(t_delete) column[1] value is not "
0394: + expect_key));
0395:
0396: if (!scan.delete()) {
0397: return (FAIL("(t_delete): delete of row failed"));
0398: }
0399: if (scan.delete()) {
0400: return (FAIL("(t_delete): re-delete of row succeeded"));
0401: }
0402: }
0403:
0404: scan.close();
0405:
0406: // This function expects unique keys, so scan should find single row.
0407: if (numrows != 1) {
0408: return (FAIL("(t_delete) wrong number of rows. Expected "
0409: + "1 row, but got " + numrows + "rows."));
0410: }
0411:
0412: return (true);
0413: }
0414:
0415: /**
0416: * Test BTreeController.insert()
0417: * <p>
0418: * Just verify that insert code works for a secondary index. Just call
0419: * the interface and make sure the row got there.
0420: *
0421: * @exception StandardException Standard exception policy.
0422: * @exception T_Fail Throws T_Fail on any test failure.
0423: **/
0424: protected boolean t_001(TransactionController tc)
0425: throws StandardException, T_Fail {
0426: REPORT("Starting t_001");
0427:
0428: T_CreateConglomRet create_ret = new T_CreateConglomRet();
0429:
0430: createCongloms(tc, 2, false, false, 0, create_ret);
0431:
0432: // Open the base table
0433: ConglomerateController base_cc = tc.openConglomerate(
0434: create_ret.base_conglomid, false,
0435: TransactionController.OPENMODE_FORUPDATE,
0436: TransactionController.MODE_RECORD,
0437: TransactionController.ISOLATION_SERIALIZABLE);
0438:
0439: // Open the secondary index
0440: ConglomerateController index_cc = tc.openConglomerate(
0441: create_ret.index_conglomid, false,
0442: TransactionController.OPENMODE_FORUPDATE,
0443: TransactionController.MODE_RECORD,
0444: TransactionController.ISOLATION_SERIALIZABLE);
0445:
0446: if (!(index_cc instanceof B2IController)) {
0447: throw T_Fail
0448: .testFailMsg("openConglomerate returned wrong type");
0449: }
0450:
0451: if (!index_cc.isKeyed()) {
0452: throw T_Fail.testFailMsg("btree is not keyed.");
0453: }
0454:
0455: index_cc.checkConsistency();
0456:
0457: // Create a row and insert into base table, remembering it's location.
0458: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
0459: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
0460: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
0461:
0462: index_row1.init(r1, base_rowloc1, 3);
0463: ((SQLLongint) r1[0]).setValue(2);
0464: ((SQLLongint) r1[1]).setValue(2);
0465:
0466: // Insert the row into the base table and remember its location.
0467: base_cc.insertAndFetchLocation(r1, base_rowloc1);
0468:
0469: // Insert the row into the secondary index.
0470: if (index_cc.insert(index_row1.getRow()) != 0)
0471: throw T_Fail.testFailMsg("insert failed");
0472:
0473: // Make sure we read back the value we wrote from base and index table.
0474: DataValueDescriptor[] r2 = TemplateRow.newU8Row(2);
0475: T_SecondaryIndexRow index_row2 = new T_SecondaryIndexRow();
0476: RowLocation base_rowloc2 = base_cc.newRowLocationTemplate();
0477:
0478: index_row2.init(r2, base_rowloc2, 3);
0479:
0480: // base table check:
0481: if (!base_cc.fetch(base_rowloc1, r2, (FormatableBitSet) null)) {
0482: return (FAIL("(t_001) insert into base table failed"));
0483: }
0484:
0485: if (((SQLLongint) r2[0]).getLong() != 2
0486: || ((SQLLongint) r2[1]).getLong() != 2) {
0487: return (FAIL("(t_001) insert into base table failed"));
0488: }
0489:
0490: // index check - there should be only one record:
0491: ScanController scan = tc.openScan(create_ret.index_conglomid,
0492: false, TransactionController.OPENMODE_FORUPDATE,
0493: TransactionController.MODE_RECORD,
0494: TransactionController.ISOLATION_SERIALIZABLE,
0495: (FormatableBitSet) null, null, ScanController.NA, null,
0496: null, ScanController.NA);
0497:
0498: scan.next();
0499: scan.fetch(index_row2.getRow());
0500:
0501: // delete the only row in the table, and make sure
0502: // isCurrentPositionDeleted() works.
0503: if (scan.isCurrentPositionDeleted())
0504: throw T_Fail
0505: .testFailMsg("current row should not be deleted\n");
0506: if (!scan.doesCurrentPositionQualify())
0507: throw T_Fail
0508: .testFailMsg("current row should still qualify\n");
0509: scan.delete();
0510: if (!scan.isCurrentPositionDeleted())
0511: throw T_Fail.testFailMsg("current row should be deleted\n");
0512: if (scan.doesCurrentPositionQualify())
0513: throw T_Fail
0514: .testFailMsg("deleted row should not qualify\n");
0515:
0516: // just call the debugging code to make sure it doesn't fail.
0517: REPORT("Calling scan.tostring(): " + scan);
0518:
0519: if (scan.next()
0520: || ((SQLLongint) (index_row2.getRow()[0])).getLong() != 2
0521: || ((SQLLongint) (index_row2.getRow()[1])).getLong() != 2) {
0522: return (FAIL("(t_001) insert into index failed in base cols"));
0523: }
0524:
0525: // test the scaninfo interface.
0526:
0527: ScanInfo scan_info = scan.getScanInfo();
0528: Properties prop = scan_info.getAllScanInfo(null);
0529:
0530: if (Integer.parseInt(prop.getProperty(MessageService
0531: .getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED))) != 1) {
0532: throw T_Fail
0533: .testFailMsg("(scanInfo) wrong numPagesVisited. Expected 1, got "
0534: + Integer
0535: .parseInt(prop
0536: .getProperty(MessageService
0537: .getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED))));
0538: }
0539: if (Integer.parseInt(prop.getProperty(MessageService
0540: .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED))) != 1) {
0541: throw T_Fail
0542: .testFailMsg("(scanInfo) wrong numRowsVisited. Expected 1, got "
0543: + Integer
0544: .parseInt(prop
0545: .getProperty(MessageService
0546: .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED))));
0547: }
0548: if (Integer
0549: .parseInt(prop
0550: .getProperty(MessageService
0551: .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))) != 1) {
0552: throw T_Fail
0553: .testFailMsg("(scanInfo) wrong numRowsQualified. Expected 1, got "
0554: + Integer
0555: .parseInt(prop
0556: .getProperty(MessageService
0557: .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))));
0558: }
0559:
0560: int compare_result = base_rowloc1.compare(base_rowloc2);
0561: if (compare_result != 0) {
0562: return (FAIL("(t_001) insert into index failed in recordhandle.\n"
0563: + "\texpected RecordHandle = "
0564: + base_rowloc1
0565: + "\n"
0566: + "\tgot RecordHandle = "
0567: + base_rowloc2
0568: + "\tcompare result = "
0569: + compare_result));
0570: }
0571:
0572: index_cc.checkConsistency();
0573:
0574: // Close the conglomerates.
0575: base_cc.close();
0576: index_cc.close();
0577:
0578: try {
0579: base_cc.insert(r1);
0580: return (FAIL("(t_001) insert on closed conglomerate worked"));
0581: } catch (StandardException e) {
0582: // e.printStackTrace();
0583: }
0584:
0585: try {
0586: if (index_cc.insert(r1) != 0)
0587: throw T_Fail.testFailMsg("insert failed");
0588: return (FAIL("(t_001) insert on closed conglomerate worked"));
0589: } catch (StandardException e) {
0590: // e.printStackTrace();
0591: }
0592:
0593: tc.commit();
0594: REPORT("Ending t_001");
0595:
0596: return true;
0597: }
0598:
0599: /**
0600: * Test backout during critical times of splits.
0601: * <p>
0602: * Use trace points to force errors in split at critical points:
0603: * leaf_split_abort{1,2,3,4}
0604: *
0605: * @exception StandardException Standard exception policy.
0606: * @exception T_Fail Throws T_Fail on any test failure.
0607: **/
0608: protected boolean t_002(TransactionController tc)
0609: throws StandardException, T_Fail {
0610: ScanController scan = null;
0611:
0612: // SanityManager.DEBUG_SET("LockTrace");
0613:
0614: REPORT("Starting t_002");
0615:
0616: T_CreateConglomRet create_ret = new T_CreateConglomRet();
0617:
0618: // Create the btree so that it only allows 2 rows per page.
0619: createCongloms(tc, 2, false, false, 2, create_ret);
0620:
0621: // Open the base table
0622: ConglomerateController base_cc = tc.openConglomerate(
0623: create_ret.base_conglomid, false,
0624: TransactionController.OPENMODE_FORUPDATE,
0625: TransactionController.MODE_RECORD,
0626: TransactionController.ISOLATION_SERIALIZABLE);
0627:
0628: // Open the secondary index
0629: ConglomerateController index_cc = tc.openConglomerate(
0630: create_ret.index_conglomid, false,
0631: TransactionController.OPENMODE_FORUPDATE,
0632: TransactionController.MODE_RECORD,
0633: TransactionController.ISOLATION_SERIALIZABLE);
0634:
0635: if (!(index_cc instanceof B2IController)) {
0636: throw T_Fail
0637: .testFailMsg("openConglomerate returned wrong type");
0638: }
0639:
0640: index_cc.checkConsistency();
0641:
0642: // Create a row and insert into base table, remembering it's location.
0643: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
0644: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
0645: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
0646:
0647: index_row1.init(r1, base_rowloc1, 3);
0648:
0649: // Commit the create of the tables so that the following aborts don't
0650: // undo that work.
0651: tc.commit();
0652:
0653: // Now try aborts of transactions during splits, using magic
0654: // trace flags. This test inserts enough rows to cause a split
0655: // and then forces the split to fail at various key points. The
0656: // split should be backed out and also the rows before the split.
0657: // The test makes sure that there are some inserts before the forced
0658: // split abort.
0659: String[] debug_strings = { "leaf_split_growRoot1",
0660: "leaf_split_growRoot2", "leaf_split_growRoot3",
0661: "leaf_split_growRoot4", "leaf_split_growRoot5",
0662: "leaf_split_abort1", "leaf_split_abort2",
0663: "leaf_split_abort3", "leaf_split_abort4",
0664: "branch_split_abort1", "branch_split_abort2",
0665: "branch_split_abort3", "branch_split_abort4",
0666: "BTreeController_doIns2" };
0667:
0668: for (int errs = 0; errs < debug_strings.length; errs++) {
0669: REPORT("Doing abort test: " + debug_strings[errs]);
0670:
0671: // set the debug flag, which will cause an error
0672: // RESOLVE (mmm) these tests should be run from the language to
0673: // make sure error handling really works.
0674:
0675: if (SanityManager.DEBUG)
0676: SanityManager.DEBUG_SET(debug_strings[errs]);
0677:
0678: try {
0679:
0680: // Open the base table
0681: base_cc = tc.openConglomerate(
0682: create_ret.base_conglomid, false,
0683: TransactionController.OPENMODE_FORUPDATE,
0684: TransactionController.MODE_RECORD,
0685: TransactionController.ISOLATION_SERIALIZABLE);
0686:
0687: // Open the secondary index
0688: index_cc = tc.openConglomerate(
0689: create_ret.index_conglomid, false,
0690: TransactionController.OPENMODE_FORUPDATE,
0691: TransactionController.MODE_RECORD,
0692: TransactionController.ISOLATION_SERIALIZABLE);
0693:
0694: // insert one row that does not cause failure.
0695: ((SQLLongint) r1[0]).setValue(2);
0696: ((SQLLongint) r1[1]).setValue(10000 + errs);
0697:
0698: // Insert the row into the base table;remember its location.
0699: base_cc.insertAndFetchLocation(r1, base_rowloc1);
0700:
0701: // Insert the row into the secondary index.
0702: if (index_cc.insert(index_row1.getRow()) != 0)
0703: throw T_Fail.testFailMsg("insert failed");
0704:
0705: // set the debug flag, which will cause an error
0706: // RESOLVE (mmm) these tests should be run from the
0707: // language to make sure error handling really works.
0708: if (SanityManager.DEBUG)
0709: SanityManager.DEBUG_SET(debug_strings[errs]);
0710:
0711: // now insert enough rows to cause failure
0712: for (int i = 100; i > 0; i -= 2) {
0713: ((SQLLongint) r1[0]).setValue(2);
0714: ((SQLLongint) r1[1]).setValue(i);
0715:
0716: // Insert the row into the base table;remember its location.
0717: base_cc.insertAndFetchLocation(r1, base_rowloc1);
0718:
0719: // Insert the row into the secondary index.
0720: if (index_cc.insert(index_row1.getRow()) != 0) {
0721: throw T_Fail.testFailMsg("insert failed");
0722: }
0723: }
0724:
0725: throw T_Fail.testFailMsg("debug flag ("
0726: + debug_strings[errs]
0727: + ")did not cause exception.");
0728: } catch (StandardException e) {
0729: ContextService contextFactory = ContextService
0730: .getFactory();
0731:
0732: // Get the context manager.
0733: ContextManager cm = contextFactory
0734: .getCurrentContextManager();
0735:
0736: if (SanityManager.DEBUG)
0737: SanityManager.ASSERT(cm != null);
0738:
0739: cm.cleanupOnError(e);
0740:
0741: // RESOLVE (mikem) - when split abort works come up with
0742: // a good sanity check here.
0743: //
0744: // index check - there should be no records:
0745: scan = tc.openScan(create_ret.index_conglomid, false,
0746: TransactionController.OPENMODE_FORUPDATE,
0747: TransactionController.MODE_RECORD,
0748: TransactionController.ISOLATION_SERIALIZABLE,
0749: (FormatableBitSet) null, null,
0750: ScanController.NA, null, null,
0751: ScanController.NA);
0752:
0753: index_cc = tc.openConglomerate(
0754: create_ret.index_conglomid, false,
0755: TransactionController.OPENMODE_FORUPDATE,
0756: TransactionController.MODE_RECORD,
0757: TransactionController.ISOLATION_SERIALIZABLE);
0758:
0759: index_cc.checkConsistency();
0760: index_cc.close();
0761:
0762: if (scan.next()) {
0763: throw T_Fail
0764: .testFailMsg("t_002: there are still rows in table.");
0765: }
0766:
0767: scan.close();
0768: }
0769:
0770: // Unset the flag.
0771: if (SanityManager.DEBUG)
0772: SanityManager.DEBUG_CLEAR(debug_strings[errs]);
0773: }
0774:
0775: // Try a simple abort. The following adds enough rows to cause a
0776: // split. The result of the split should be a tree with no rows, but
0777: // the splits will not be undone. It is up to the implementation
0778: // whether the undo's cause shrinks in the tree. In the initial
0779: // implementation it won't.
0780: {
0781: tc.commit();
0782:
0783: // Open the base table
0784: base_cc = tc.openConglomerate(create_ret.base_conglomid,
0785: false, TransactionController.OPENMODE_FORUPDATE,
0786: TransactionController.MODE_RECORD,
0787: TransactionController.ISOLATION_SERIALIZABLE);
0788:
0789: // Open the secondary index
0790: index_cc = tc.openConglomerate(create_ret.index_conglomid,
0791: false, TransactionController.OPENMODE_FORUPDATE,
0792: TransactionController.MODE_RECORD,
0793: TransactionController.ISOLATION_SERIALIZABLE);
0794:
0795: // BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER has been set to 2 so
0796: // inserting 3 rows will cause a split at the leaf level.
0797: // Make sure that normal abort leaves the committed split.
0798: for (int i = 0; i < 3; i++) {
0799: ((SQLLongint) r1[0]).setValue(2);
0800: ((SQLLongint) r1[1]).setValue(i);
0801:
0802: // Insert the row into the base table;remember its location.
0803: base_cc.insertAndFetchLocation(r1, base_rowloc1);
0804:
0805: // Insert the row into the secondary index.
0806: if (index_cc.insert(index_row1.getRow()) != 0)
0807: throw T_Fail.testFailMsg("insert failed");
0808: }
0809:
0810: tc.abort();
0811:
0812: // index check - there should be no records left.
0813: ScanController empty_scan = tc.openScan(
0814: create_ret.index_conglomid, false, 0,
0815: TransactionController.MODE_RECORD,
0816: TransactionController.ISOLATION_SERIALIZABLE,
0817: (FormatableBitSet) null, null, ScanController.NA,
0818: null, null, ScanController.NA);
0819:
0820: if (empty_scan.next()) {
0821: throw T_Fail
0822: .testFailMsg("t_002: there are still rows in table.");
0823: }
0824: }
0825:
0826: tc.commit();
0827: REPORT("Ending t_002");
0828:
0829: return true;
0830: }
0831:
0832: private boolean t_003_scan_test_cases(TransactionController tc,
0833: long index_conglomid, T_SecondaryIndexRow template)
0834: throws StandardException, T_Fail {
0835: boolean ret_val = true;
0836:
0837: // run through a predicates as described in the openScan() interface //
0838: DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
0839: DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
0840:
0841: // test predicate x = 5
0842: //
0843: // result set should be: {5,2,16}, {5,4,17}, {5,6,18}
0844: //
0845: REPORT("scan (x = 5)");
0846: ((SQLLongint) start_key[0]).setValue(5);
0847: ((SQLLongint) stop_key[0]).setValue(5);
0848: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0849: .getRow(), template.getRow(), start_key,
0850: ScanController.GE, null, stop_key, ScanController.GT,
0851: 3, 16, T_QualifierTest.ORDER_FORWARD)) {
0852: ret_val = false;
0853: }
0854:
0855: // +---------------------------------------------------------+
0856: // |pred |start|key|stop |key|rows returned |rows locked |
0857: // | |value|op |value|op | |(serialization)|
0858: // +------+-----+---+-----+---+--------------+---------------+
0859: // |x > 5 |{5} |GT |null | |{6,1} .. {9,1}|{5,6} .. {9,1} |
0860: // +-----------------------------------------+---------------+
0861: REPORT("scan (x > 5)");
0862: ((SQLLongint) start_key[0]).setValue(5);
0863: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0864: .getRow(), template.getRow(), start_key,
0865: ScanController.GT, null, null, ScanController.NA, 3,
0866: 19, T_QualifierTest.ORDER_FORWARD)) {
0867: ret_val = false;
0868: }
0869:
0870: // +---------------------------------------------------------+
0871: // |pred |start|key|stop |key|rows returned |rows locked |
0872: // | |value|op |value|op | |(serialization)|
0873: // +------+-----+---+-----+---+--------------+---------------+
0874: // |x >= 5|{5} |GE |null | |{5,2} .. {9,1}|{4,6} .. {9,1} |
0875: // +-----------------------------------------+---------------+
0876: REPORT("scan (x >= 5)");
0877: ((SQLLongint) start_key[0]).setValue(5);
0878: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0879: .getRow(), template.getRow(), start_key,
0880: ScanController.GE, null, null, ScanController.NA, 6,
0881: 16, T_QualifierTest.ORDER_FORWARD)) {
0882: ret_val = false;
0883: }
0884:
0885: //
0886: // +---------------------------------------------------------+
0887: // |pred |start|key|stop |key|rows returned |rows locked |
0888: // | |value|op |value|op | |(serialization)|
0889: // +------+-----+---+-----+---+--------------+---------------+
0890: // |x <= 5|null | |{5} |GT |{1,1} .. {5,6}|first .. {5,6} |
0891: // +-----------------------------------------+---------------+
0892: REPORT("scan (x <= 5)");
0893: ((SQLLongint) stop_key[0]).setValue(5);
0894: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0895: .getRow(), template.getRow(), null, ScanController.NA,
0896: null, stop_key, ScanController.GT, 8, 11,
0897: T_QualifierTest.ORDER_FORWARD)) {
0898: ret_val = false;
0899: }
0900: //
0901: // +---------------------------------------------------------+
0902: // |pred |start|key|stop |key|rows returned |rows locked |
0903: // | |value|op |value|op | |(serialization)|
0904: // +------+-----+---+-----+---+--------------+---------------+
0905: // |x < 5 |null | |{5} |GE |{1,1} .. {4,6}|first .. {4,6} |
0906: // +-----------------------------------------+---------------+
0907: REPORT("scan (x < 5)");
0908: ((SQLLongint) stop_key[0]).setValue(5);
0909: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0910: .getRow(), template.getRow(), null, ScanController.NA,
0911: null, stop_key, ScanController.GE, 5, 11,
0912: T_QualifierTest.ORDER_FORWARD)) {
0913: ret_val = false;
0914: }
0915:
0916: //long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
0917: //long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
0918: //long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
0919: // +------------------------------------------------------------------+
0920: // |pred |start|key|stop |key|rows returned|rows locked |
0921: // | |value|op |value|op | |(serialized) |
0922: // +-----------------+------+--+-----+--+--------------+--------------+
0923: // |x >= 5 and x <= 7|{5}, |GE|{7} |GT|{5,2} .. {7,1}|{4,6} .. {7,1}|
0924: // +------------------------------------------------------------------+
0925: REPORT("scan (x >= 5 and x <= 7)");
0926: ((SQLLongint) start_key[0]).setValue(5);
0927: ((SQLLongint) stop_key[0]).setValue(7);
0928: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0929: .getRow(), template.getRow(), start_key,
0930: ScanController.GE, null, stop_key, ScanController.GT,
0931: 5, 16, T_QualifierTest.ORDER_FORWARD)) {
0932: ret_val = false;
0933: }
0934:
0935: // +------------------------------------------------------------------+
0936: // |pred |start|key|stop |key|rows returned|rows locked |
0937: // | |value|op |value|op | |(serialized) |
0938: // +-----------------+------+--+-----+--+--------------+--------------+
0939: // |x = 5 and y > 2 |{5,2} |GT|{5} |GT|{5,4} .. {5,6}|{5,2} .. {9,1}|
0940: // +------------------------------------------------------------------+
0941: REPORT("scan (x = 5 and y > 2)");
0942: start_key = TemplateRow.newU8Row(2);
0943: stop_key = TemplateRow.newU8Row(1);
0944: ((SQLLongint) start_key[0]).setValue(5);
0945: ((SQLLongint) start_key[1]).setValue(2);
0946: ((SQLLongint) stop_key[0]).setValue(5);
0947: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0948: .getRow(), template.getRow(), start_key,
0949: ScanController.GT, null, stop_key, ScanController.GT,
0950: 2, 17, T_QualifierTest.ORDER_FORWARD)) {
0951: ret_val = false;
0952: }
0953:
0954: // +------------------------------------------------------------------+
0955: // |pred |start|key|stop |key|rows returned|rows locked |
0956: // | |value|op |value|op | |(serialized) |
0957: // +-----------------+------+--+-----+--+--------------+--------------+
0958: // |x = 5 and y >= 2 | {5,2}|GE| {5} |GT|{5,2} .. {5,6}|{4,6} .. {9,1}|
0959: // +------------------------------------------------------------------+
0960: REPORT("scan (x = 5 and y >= 2)");
0961: start_key = TemplateRow.newU8Row(2);
0962: stop_key = TemplateRow.newU8Row(1);
0963: ((SQLLongint) start_key[0]).setValue(5);
0964: ((SQLLongint) start_key[1]).setValue(2);
0965: ((SQLLongint) stop_key[0]).setValue(5);
0966: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0967: .getRow(), template.getRow(), start_key,
0968: ScanController.GE, null, stop_key, ScanController.GT,
0969: 3, 16, T_QualifierTest.ORDER_FORWARD)) {
0970: ret_val = false;
0971: }
0972:
0973: // +------------------------------------------------------------------+
0974: // |pred |start|key|stop |key|rows returned|rows locked |
0975: // | |value|op |value|op | |(serialized) |
0976: // +-----------------+------+--+-----+--+--------------+--------------+
0977: // |x = 5 and y < 5 | {5} |GE|{5,5}|GE|{5,2} .. {5,4}|{4,6} .. {5,4}|
0978: // +------------------------------------------------------------------+
0979: REPORT("scan (x = 5 and y < 5)");
0980: start_key = TemplateRow.newU8Row(1);
0981: stop_key = TemplateRow.newU8Row(2);
0982: ((SQLLongint) start_key[0]).setValue(5);
0983: ((SQLLongint) stop_key[0]).setValue(5);
0984: ((SQLLongint) stop_key[1]).setValue(5);
0985: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
0986: .getRow(), template.getRow(), start_key,
0987: ScanController.GE, null, stop_key, ScanController.GE,
0988: 2, 16, T_QualifierTest.ORDER_FORWARD)) {
0989: ret_val = false;
0990: }
0991:
0992: // +------------------------------------------------------------------+
0993: // |pred |start|key|stop |key|rows returned|rows locked |
0994: // | |value|op |value|op | |(serialized) |
0995: // +-----------------+------+--+-----+--+--------------+--------------+
0996: // |x = 2 | {2} |GE| {2} |GT|none |{1,1} .. {1,1}|
0997: // +------------------------------------------------------------------+
0998: REPORT("scan (x = 2)");
0999: start_key = TemplateRow.newU8Row(1);
1000: stop_key = TemplateRow.newU8Row(1);
1001: ((SQLLongint) start_key[0]).setValue(2);
1002: ((SQLLongint) stop_key[0]).setValue(2);
1003: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
1004: .getRow(), template.getRow(), start_key,
1005: ScanController.GE, null, stop_key, ScanController.GT,
1006: 0, 0, T_QualifierTest.ORDER_FORWARD)) {
1007: ret_val = false;
1008: }
1009:
1010: // +-----------------------------+
1011: // |max on btree - row locked |
1012: // +-----------------------------+
1013: //
1014: REPORT("max on btree, row locked.");
1015: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
1016: TransactionController.MODE_RECORD,
1017: TransactionController.ISOLATION_SERIALIZABLE,
1018: (FormatableBitSet) null, template.getRow())) {
1019: throw T_Fail.testFailMsg("found no max.");
1020: } else {
1021: // make sure right max was found.
1022: long key = ((SQLLongint) template.getRow()[2]).getLong();
1023:
1024: if (key != 21) {
1025: throw T_Fail.testFailMsg("wrong max found.");
1026: }
1027: }
1028:
1029: // +-----------------------------+
1030: // |max on btree - table locked |
1031: // +-----------------------------+
1032: //
1033: REPORT("max on btree, table locked.");
1034: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
1035: TransactionController.MODE_TABLE,
1036: TransactionController.ISOLATION_SERIALIZABLE,
1037: (FormatableBitSet) null, template.getRow())) {
1038: throw T_Fail.testFailMsg("found no max.");
1039: } else {
1040: // make sure right max was found.
1041: long key = ((SQLLongint) template.getRow()[2]).getLong();
1042:
1043: if (key != 21) {
1044: throw T_Fail.testFailMsg("wrong max found.");
1045: }
1046: }
1047:
1048: // +-----------------------------+
1049: // |max on btree - row locked |
1050: // +-----------------------------+
1051: //
1052: REPORT("max on btree, row locked.");
1053: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
1054: TransactionController.MODE_RECORD,
1055: TransactionController.ISOLATION_READ_COMMITTED,
1056: (FormatableBitSet) null, template.getRow())) {
1057: throw T_Fail.testFailMsg("found no max.");
1058: } else {
1059: // make sure right max was found.
1060: long key = ((SQLLongint) template.getRow()[2]).getLong();
1061:
1062: if (key != 21) {
1063: throw T_Fail.testFailMsg("wrong max found.");
1064: }
1065: }
1066:
1067: // +-----------------------------+
1068: // |max on btree - table locked |
1069: // +-----------------------------+
1070: //
1071: REPORT("max on btree, table locked.");
1072: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
1073: TransactionController.MODE_TABLE,
1074: TransactionController.ISOLATION_READ_COMMITTED,
1075: (FormatableBitSet) null, template.getRow())) {
1076: throw T_Fail.testFailMsg("found no max.");
1077: } else {
1078: // make sure right max was found.
1079: long key = ((SQLLongint) template.getRow()[2]).getLong();
1080:
1081: if (key != 21) {
1082: throw T_Fail.testFailMsg("wrong max found.");
1083: }
1084: }
1085:
1086: return (ret_val);
1087: }
1088:
1089: /**
1090: * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
1091: * BtreeScan.fetch().
1092: *
1093: * @exception StandardException Standard exception policy.
1094: * @exception T_Fail Throws T_Fail on any test failure.
1095: */
1096: protected boolean t_003(TransactionController tc)
1097: throws StandardException, T_Fail {
1098: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1099:
1100: // base row template - last column is just to make row long so that
1101: // multiple pages are spanned.
1102: DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
1103: base_row[3] = new SQLChar();
1104:
1105: String string_1500char = new String();
1106: for (int i = 0; i < 300; i++)
1107: string_1500char += "mikem";
1108:
1109: boolean ret_val = true;
1110: long value = -1;
1111: long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9 };
1112: long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1 };
1113: long col3[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
1114:
1115: // set of deleted rows to make scans more interesting
1116: long d_col1[] = { 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12 };
1117: long d_col2[] = { 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1 };
1118: long d_col3[] = { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
1119: 102, 103, 104 };
1120:
1121: REPORT("Starting t_003");
1122:
1123: // create the base table
1124: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1125: base_row, // base table template row
1126: null, //column sort order - not required for heap
1127: null, // default properties
1128: TransactionController.IS_DEFAULT); // not temporary
1129:
1130: // Open the base table
1131: ConglomerateController base_cc = tc.openConglomerate(
1132: base_conglomid, false,
1133: TransactionController.OPENMODE_FORUPDATE,
1134: TransactionController.MODE_RECORD,
1135: TransactionController.ISOLATION_SERIALIZABLE);
1136:
1137: // initialize the secondary index row - pointing it at base row
1138: index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
1139:
1140: Properties properties = createProperties(null, // no current properties list
1141: false, // don't allow duplicates
1142: 5, // 4 columns in index row
1143: 5, // non-unique index
1144: true, // maintain parent links
1145: base_conglomid, // base conglom id
1146: 4); // row loc in last column
1147:
1148: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
1149: index_row.getRow(), // row template
1150: null, //column sort order - default
1151: properties, // properties
1152: TransactionController.IS_DEFAULT); // not temporary
1153:
1154: // Open the conglomerate.
1155: ConglomerateController index_cc = tc.openConglomerate(
1156: index_conglomid, false,
1157: TransactionController.OPENMODE_FORUPDATE,
1158: TransactionController.MODE_RECORD,
1159: TransactionController.ISOLATION_SERIALIZABLE);
1160:
1161: // Create a row.
1162: T_SecondaryIndexRow template = new T_SecondaryIndexRow();
1163: RowLocation row_loc = base_cc.newRowLocationTemplate();
1164: template.init(base_row, row_loc, 5);
1165:
1166: // insert them in reverse order just to make sure btree is sorting them
1167: for (int i = col1.length - 1; i >= 0; i--) {
1168: ((SQLLongint) (template.getRow()[0])).setValue(col1[i]);
1169: ((SQLLongint) (template.getRow()[1])).setValue(col2[i]);
1170: ((SQLLongint) (template.getRow()[2])).setValue(col3[i]);
1171: base_row[3] = new SQLChar(string_1500char);
1172:
1173: base_cc.insertAndFetchLocation(base_row, row_loc);
1174:
1175: // Insert the row.
1176: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
1177: // ")" + template);
1178: if (index_cc.insert(template.getRow()) != 0)
1179: throw T_Fail.testFailMsg("insert failed");
1180: }
1181:
1182: index_cc.checkConsistency();
1183:
1184: ((B2IController) index_cc).debugConglomerate();
1185:
1186: ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
1187:
1188: // insert and delete some interesting rows, deleted space management
1189: // may or may not clean these up.
1190: for (int i = d_col1.length - 1; i >= 0; i--) {
1191: ((SQLLongint) (template.getRow()[0])).setValue(d_col1[i]);
1192: ((SQLLongint) (template.getRow()[1])).setValue(d_col2[i]);
1193: ((SQLLongint) (template.getRow()[2])).setValue(d_col3[i]);
1194: base_row[3] = new SQLChar(string_1500char);
1195:
1196: base_cc.insertAndFetchLocation(base_row, row_loc);
1197:
1198: // Insert the row.
1199: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
1200: // ")" + template);
1201: if (index_cc.insert(template.getRow()) != 0)
1202: throw T_Fail.testFailMsg("insert failed");
1203:
1204: // now delete the row.
1205: base_cc.delete(row_loc);
1206:
1207: ScanController delete_scan = tc.openScan(index_conglomid,
1208: false, TransactionController.OPENMODE_FORUPDATE,
1209: TransactionController.MODE_RECORD,
1210: TransactionController.ISOLATION_SERIALIZABLE,
1211: (FormatableBitSet) null, template.getRow(),
1212: ScanController.GE, null, template.getRow(),
1213: ScanController.GT);
1214:
1215: if (!delete_scan.next()) {
1216: throw T_Fail.testFailMsg("delete could not find key");
1217: } else {
1218: delete_scan.delete();
1219:
1220: if (delete_scan.next())
1221: throw T_Fail
1222: .testFailMsg("delete found more than one key");
1223: }
1224:
1225: delete_scan.close();
1226: }
1227:
1228: ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
1229:
1230: // Close the conglomerate.
1231: index_cc.close();
1232:
1233: tc.commit();
1234: REPORT("Ending t_003");
1235:
1236: return (ret_val);
1237: }
1238:
1239: /**
1240: * Test qualifiers.
1241: *
1242: * @exception StandardException Standard exception policy.
1243: * @exception T_Fail Throws T_Fail on any test failure.
1244: */
1245: protected boolean t_004(TransactionController tc)
1246: throws StandardException, T_Fail {
1247: REPORT("Starting t_004");
1248:
1249: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1250:
1251: createCongloms(tc, 2, false, false, 0, create_ret);
1252:
1253: Properties properties = createProperties(null, // no current properties list
1254: false, // don't allow duplicates
1255: 4, // 3 columns in index row
1256: 4, // non-unique index
1257: true, // maintain parent links
1258: create_ret.base_conglomid, // fake base conglom for now
1259: 3); // row loc in last column
1260:
1261: T_QualifierTest q_test = new T_QualifierTest("BTREE", // create a btree secondary
1262: properties, // properties
1263: false, // not temporary
1264: out, T_QualifierTest.ORDER_FORWARD); // ordered
1265:
1266: boolean test_result = q_test.t_testqual(tc);
1267:
1268: REPORT("Ending t_004");
1269:
1270: return (test_result);
1271: }
1272:
1273: /**
1274: * Test Branch splits - number of rows necessary to cause splits is raw
1275: * store implementation dependant (currently 5 rows per page in in-memory
1276: * implementation).
1277: *
1278: * @exception StandardException Standard exception policy.
1279: * @exception T_Fail Throws T_Fail on any test failure.
1280: */
1281: protected boolean t_005(TransactionController tc)
1282: throws StandardException, T_Fail {
1283: boolean ret_val = true;
1284:
1285: REPORT("Starting t_005");
1286:
1287: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1288:
1289: createCongloms(tc, 2, false, false, 0, create_ret);
1290:
1291: // Open the base conglomerate.
1292: ConglomerateController base_cc = tc.openConglomerate(
1293: create_ret.base_conglomid, false,
1294: TransactionController.OPENMODE_FORUPDATE,
1295: TransactionController.MODE_RECORD,
1296: TransactionController.ISOLATION_SERIALIZABLE);
1297:
1298: // Open the index conglomerate.
1299: ConglomerateController index_cc = tc.openConglomerate(
1300: create_ret.index_conglomid, false,
1301: TransactionController.OPENMODE_FORUPDATE,
1302: TransactionController.MODE_RECORD,
1303: TransactionController.ISOLATION_SERIALIZABLE);
1304:
1305: // Create a row.
1306: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1307: RowLocation rowloc = base_cc.newRowLocationTemplate();
1308: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1309: index_row.init(base_row, rowloc, 3);
1310:
1311: // insert them in reverse order just to make sure btree is sorting them
1312: for (int i = 200; i >= 0; i -= 4) {
1313: ((SQLLongint) base_row[0]).setValue(1);
1314: ((SQLLongint) base_row[1]).setValue(i);
1315: base_cc.insertAndFetchLocation(base_row, rowloc);
1316:
1317: if (index_cc.insert(index_row.getRow()) != 0)
1318: throw T_Fail.testFailMsg("insert failed");
1319: }
1320: for (int i = 199; i >= 0; i -= 4) {
1321: ((SQLLongint) base_row[0]).setValue(1);
1322: ((SQLLongint) base_row[1]).setValue(i);
1323:
1324: base_cc.insertAndFetchLocation(base_row, rowloc);
1325: if (index_cc.insert(index_row.getRow()) != 0)
1326: throw T_Fail.testFailMsg("insert failed");
1327: }
1328:
1329: index_cc.checkConsistency();
1330:
1331: // Close the conglomerate.
1332: index_cc.close();
1333:
1334: tc.commit();
1335:
1336: // Search for each of the keys and delete them one at a time.
1337: DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
1338: for (int i = 200; i >= 0; i -= 4) {
1339: ((SQLLongint) delete_key[0]).setValue(1);
1340: ((SQLLongint) delete_key[1]).setValue(i);
1341:
1342: if (!t_delete(tc, create_ret.index_conglomid, delete_key,
1343: index_row.getRow())) {
1344: ret_val = false;
1345: }
1346: }
1347: for (int i = 199; i >= 0; i -= 4) {
1348: ((SQLLongint) delete_key[0]).setValue(1);
1349: ((SQLLongint) delete_key[1]).setValue(i);
1350:
1351: if (!t_delete(tc, create_ret.index_conglomid, delete_key,
1352: index_row.getRow())) {
1353: ret_val = false;
1354: }
1355: }
1356:
1357: tc.commit();
1358:
1359: // Open the base conglomerate.
1360: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
1361: TransactionController.OPENMODE_FORUPDATE,
1362: TransactionController.MODE_RECORD,
1363: TransactionController.ISOLATION_SERIALIZABLE);
1364:
1365: // Open the conglomerate.
1366: index_cc = tc.openConglomerate(create_ret.index_conglomid,
1367: false, TransactionController.OPENMODE_FORUPDATE,
1368: TransactionController.MODE_RECORD,
1369: TransactionController.ISOLATION_SERIALIZABLE);
1370:
1371: // flush and empty cache to make sure rereading stuff works.
1372: RawStoreFactory rawstore = (RawStoreFactory) Monitor
1373: .findServiceModule(this .store_module,
1374: RawStoreFactory.MODULE);
1375:
1376: rawstore.idle();
1377:
1378: // now make sure that additional splits don't cause delete bits to
1379: // be enabled (one early bug did so).
1380:
1381: for (int i = 200; i >= 0; i -= 3) {
1382: ((SQLLongint) base_row[0]).setValue(1);
1383: ((SQLLongint) base_row[1]).setValue(i);
1384:
1385: base_cc.insertAndFetchLocation(base_row, rowloc);
1386: if (index_cc.insert(index_row.getRow()) != 0)
1387: throw T_Fail.testFailMsg("insert failed");
1388: }
1389: for (int i = 200; i >= 0; i -= 3) {
1390: ((SQLLongint) delete_key[0]).setValue(1);
1391: ((SQLLongint) delete_key[1]).setValue(i);
1392:
1393: if (!t_delete(tc, create_ret.index_conglomid, delete_key,
1394: index_row.getRow())) {
1395: ret_val = false;
1396: }
1397: }
1398:
1399: // index check - there should be no records left.
1400: ScanController empty_scan = tc.openScan(
1401: create_ret.index_conglomid, false, 0,
1402: TransactionController.MODE_RECORD,
1403: TransactionController.ISOLATION_SERIALIZABLE,
1404: (FormatableBitSet) null, null, ScanController.NA, null,
1405: null, ScanController.NA);
1406: if (empty_scan.next())
1407: throw T_Fail
1408: .testFailMsg("t_005: there are still rows in table.");
1409:
1410: index_cc.checkConsistency();
1411:
1412: for (int i = 600; i >= 400; i -= 3) {
1413: ((SQLLongint) base_row[0]).setValue(1);
1414: ((SQLLongint) base_row[1]).setValue(i);
1415:
1416: base_cc.insertAndFetchLocation(base_row, rowloc);
1417: if (index_cc.insert(index_row.getRow()) != 0)
1418: throw T_Fail.testFailMsg("insert failed");
1419: }
1420:
1421: index_cc.checkConsistency();
1422:
1423: tc.abort();
1424:
1425: // index check - there should be no records left.
1426: empty_scan = tc.openScan(create_ret.index_conglomid, false, 0,
1427: TransactionController.MODE_RECORD,
1428: TransactionController.ISOLATION_SERIALIZABLE,
1429: (FormatableBitSet) null, null, ScanController.NA, null,
1430: null, ScanController.NA);
1431: if (empty_scan.next())
1432: throw T_Fail
1433: .testFailMsg("t_005: there are still rows in table.");
1434:
1435: REPORT("Ending t_005");
1436:
1437: return (ret_val);
1438: }
1439:
1440: /**
1441: * Test unimplemented interfaces.
1442: *
1443: * The following ScanController interfaces are not supported by the
1444: * btree implementation, because row locations are not returned outside
1445: * the interface. At some point we may package a key as a row location
1446: * but that does not really give any more functionality than using scan
1447: * to find your key:
1448: * ScanController.fetchLocation()
1449: * ScanController.newRowLocationTemplate()
1450: * ScanController.replace()
1451: * ConglomerateController.delete()
1452: * ConglomerateController.fetch()
1453: * ConglomerateController.insertAndFetchLocation()
1454: * ConglomerateController.newRowLocationTemplate()
1455: * ConglomerateController.replace()
1456: *
1457: * @exception StandardException Standard exception policy.
1458: * @exception T_Fail Throws T_Fail on any test failure.
1459: */
1460: protected boolean t_006(TransactionController tc)
1461: throws StandardException, T_Fail {
1462: REPORT("Starting t_006");
1463:
1464: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1465:
1466: createCongloms(tc, 2, false, false, 0, create_ret);
1467:
1468: // Open the base conglomerate.
1469: ConglomerateController base_cc = tc.openConglomerate(
1470: create_ret.base_conglomid, false,
1471: TransactionController.OPENMODE_FORUPDATE,
1472: TransactionController.MODE_RECORD,
1473: TransactionController.ISOLATION_SERIALIZABLE);
1474:
1475: // Open the index conglomerate.
1476: ConglomerateController index_cc = tc.openConglomerate(
1477: create_ret.index_conglomid, false,
1478: TransactionController.OPENMODE_FORUPDATE,
1479: TransactionController.MODE_RECORD,
1480: TransactionController.ISOLATION_SERIALIZABLE);
1481:
1482: // Create a base row template.
1483: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1484: RowLocation base_rowloc = base_cc.newRowLocationTemplate();
1485:
1486: T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
1487: index_row_from_base_row.init(base_row, base_rowloc, 3);
1488: ((SQLLongint) base_row[0]).setValue(1);
1489:
1490: // Create a row.
1491: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1492: index_row.init(TemplateRow.newU8Row(2), base_cc
1493: .newRowLocationTemplate(), 3);
1494:
1495: // test: make sure scan position is right after inserts before scan
1496: // no split case. In this case the slot position of the current
1497: // position should change, but the code will keep a record handle
1498: // and not need to reposition by key.
1499: // before keys: 1000, 3000
1500: // last key gotten froms scan : 0
1501: // insert keys:1-900
1502: // next key from scan should be: 5
1503:
1504: // insert 1000
1505: ((SQLLongint) base_row[1]).setValue(1000);
1506: base_cc.insertAndFetchLocation(base_row, base_rowloc);
1507: if (index_cc.insert(index_row_from_base_row.getRow()) != 0) {
1508: throw T_Fail.testFailMsg("insert failed");
1509: }
1510:
1511: // try each of the unsupported interfaces:
1512: try {
1513: index_cc.delete(null);
1514: return (FAIL("t_006: ConglomerateController.delete() succeeded."));
1515: } catch (StandardException e) {
1516: }
1517: try {
1518: if (!index_cc.fetch(null, RowUtil.EMPTY_ROW,
1519: (FormatableBitSet) null)) {
1520: return (FAIL("t_006: ConglomerateController.fetch() bad ret."));
1521: }
1522: return (FAIL("t_006: ConglomerateController.fetch() succeeded."));
1523: } catch (StandardException e) {
1524: }
1525: try {
1526: index_cc.insertAndFetchLocation(
1527: (DataValueDescriptor[]) null, null);
1528: return (FAIL("t_006: ConglomerateController.insertAndFetchLocation() succeeded."));
1529: } catch (StandardException e) {
1530: }
1531: try {
1532: RowLocation rowloc = index_cc.newRowLocationTemplate();
1533: return (FAIL("t_006: ConglomerateController.newRowLocationTemplate() succeeded."));
1534: } catch (StandardException e) {
1535: }
1536: try {
1537: index_cc.replace(null, null, null);
1538: return (FAIL("t_006: ConglomerateController.replace() succeeded."));
1539: } catch (StandardException e) {
1540: }
1541:
1542: index_cc.close();
1543:
1544: // open a new scan
1545:
1546: ScanController scan = tc.openScan(create_ret.index_conglomid,
1547: false, 0, TransactionController.MODE_RECORD,
1548: TransactionController.ISOLATION_SERIALIZABLE,
1549: (FormatableBitSet) null, null, ScanController.NA, null,
1550: null, ScanController.NA);
1551:
1552: int numrows = 0;
1553: while (scan.next()) {
1554: numrows++;
1555:
1556: scan.fetch(index_row_from_base_row.getRow());
1557:
1558: try {
1559: scan.fetchLocation(null);
1560: return (FAIL("t_006: scan.fetchLocation() succeeded"));
1561: } catch (StandardException e) {
1562: }
1563:
1564: try {
1565: RowLocation rowloc = scan.newRowLocationTemplate();
1566: return (FAIL("t_006: scan.newRowLocationTemplate() succeeded"));
1567: } catch (StandardException e) {
1568: }
1569:
1570: try {
1571: scan.replace(index_row_from_base_row.getRow(),
1572: (FormatableBitSet) null);
1573: return (FAIL("t_006: scan.replace() succeeded"));
1574: } catch (StandardException e) {
1575: }
1576:
1577: }
1578:
1579: // make sure that scan.next() continues to return false
1580: if (scan.next())
1581: return (FAIL("t_006: scan.next() returned true after false."));
1582:
1583: scan.close();
1584:
1585: if (numrows != 1) {
1586: return (FAIL("(t_scan) wrong number of rows. Expected "
1587: + "1 row, but got " + numrows + "rows."));
1588: }
1589:
1590: REPORT("Ending t_006");
1591: return (true);
1592: }
1593:
1594: /**
1595: * Test multiple scans in a single page/no split
1596: *
1597: * @exception StandardException Standard exception policy.
1598: * @exception T_Fail Throws T_Fail on any test failure.
1599: */
1600: protected boolean t_007(TransactionController tc)
1601: throws StandardException, T_Fail {
1602: boolean ret_val = true;
1603:
1604: REPORT("Starting t_007");
1605:
1606: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1607:
1608: createCongloms(tc, 2, false, false, 0, create_ret);
1609:
1610: // Open the base conglomerate.
1611: ConglomerateController base_cc = tc.openConglomerate(
1612: create_ret.base_conglomid, false,
1613: TransactionController.OPENMODE_FORUPDATE,
1614: TransactionController.MODE_RECORD,
1615: TransactionController.ISOLATION_SERIALIZABLE);
1616:
1617: // Open the index conglomerate.
1618: ConglomerateController index_cc = tc.openConglomerate(
1619: create_ret.index_conglomid, false,
1620: TransactionController.OPENMODE_FORUPDATE,
1621: TransactionController.MODE_RECORD,
1622: TransactionController.ISOLATION_SERIALIZABLE);
1623:
1624: // Create a row.
1625: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1626: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1627: RowLocation row_loc = base_cc.newRowLocationTemplate();
1628: index_row.init(base_row, row_loc, 3);
1629:
1630: // Create a row.
1631: ((SQLLongint) (index_row.getRow()[0])).setValue(1);
1632:
1633: // test: make sure scan position is right after inserts before scan
1634: // no split case. In this case the slot position of the current
1635: // position should change, but the code will keep a record handle
1636: // and not need to reposition by key.
1637: // before keys: 3, 5
1638: // last key gotten froms scan : 0
1639: // insert keys:1, 2
1640: // next key from scan should be: 5
1641:
1642: // insert 3
1643: ((SQLLongint) (index_row.getRow()[1])).setValue(3);
1644: base_cc.insertAndFetchLocation(base_row, row_loc);
1645: if (index_cc.insert(index_row.getRow()) != 0)
1646: throw T_Fail.testFailMsg("insert failed");
1647:
1648: // insert 5
1649: ((SQLLongint) (index_row.getRow()[1])).setValue(5);
1650: base_cc.insertAndFetchLocation(base_row, row_loc);
1651: if (index_cc.insert(index_row.getRow()) != 0)
1652: throw T_Fail.testFailMsg("insert failed");
1653:
1654: // open a new scan
1655:
1656: ScanController scan = tc.openScan(create_ret.index_conglomid,
1657: false, 0, TransactionController.MODE_RECORD,
1658: TransactionController.ISOLATION_SERIALIZABLE,
1659: (FormatableBitSet) null, null, ScanController.NA, null,
1660: null, ScanController.NA);
1661:
1662: if (SanityManager.DEBUG)
1663: SanityManager.ASSERT(scan.next());
1664:
1665: scan.fetch(index_row.getRow());
1666: long key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1667:
1668: if (SanityManager.DEBUG)
1669: SanityManager.ASSERT(key == 3);
1670:
1671: // insert 1
1672: ((SQLLongint) (index_row.getRow()[1])).setValue(1);
1673: base_cc.insertAndFetchLocation(base_row, row_loc);
1674: if (index_cc.insert(index_row.getRow()) != 0)
1675: throw T_Fail.testFailMsg("insert failed");
1676:
1677: // insert 2
1678: ((SQLLongint) (index_row.getRow()[1])).setValue(2);
1679: base_cc.insertAndFetchLocation(base_row, row_loc);
1680: if (index_cc.insert(index_row.getRow()) != 0)
1681: throw T_Fail.testFailMsg("insert failed");
1682:
1683: // current position should not have changed
1684: scan.fetch(index_row.getRow());
1685: key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1686:
1687: if (SanityManager.DEBUG)
1688: SanityManager.ASSERT(key == 3);
1689:
1690: // next position should be 5
1691: if (SanityManager.DEBUG)
1692: SanityManager.ASSERT(scan.next());
1693: scan.fetch(index_row.getRow());
1694: key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1695:
1696: if (SanityManager.DEBUG)
1697: SanityManager.ASSERT(key == 5);
1698:
1699: index_cc.close();
1700: scan.close();
1701:
1702: REPORT("Ending t_007");
1703:
1704: return (ret_val);
1705: }
1706:
1707: /**
1708: * Test multiple scans in a single table/with splits
1709: *
1710: * @exception StandardException Standard exception policy.
1711: * @exception T_Fail Throws T_Fail on any test failure.
1712: */
1713: protected boolean t_008(TransactionController tc)
1714: throws StandardException, T_Fail {
1715: boolean ret_val = true;
1716:
1717: REPORT("Starting t_008");
1718:
1719: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1720:
1721: createCongloms(tc, 2, false, false, 0, create_ret);
1722:
1723: // Open the base conglomerate.
1724: ConglomerateController base_cc = tc.openConglomerate(
1725: create_ret.base_conglomid, false,
1726: TransactionController.OPENMODE_FORUPDATE,
1727: TransactionController.MODE_RECORD,
1728: TransactionController.ISOLATION_SERIALIZABLE);
1729:
1730: // Open the index conglomerate.
1731: ConglomerateController index_cc = tc.openConglomerate(
1732: create_ret.index_conglomid, false,
1733: TransactionController.OPENMODE_FORUPDATE,
1734: TransactionController.MODE_RECORD,
1735: TransactionController.ISOLATION_SERIALIZABLE);
1736:
1737: // Create a base row template.
1738: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1739: RowLocation base_rowloc = base_cc.newRowLocationTemplate();
1740:
1741: T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
1742: index_row_from_base_row.init(base_row, base_rowloc, 3);
1743: ((SQLLongint) base_row[0]).setValue(1);
1744:
1745: // Create a row.
1746: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1747: index_row.init(TemplateRow.newU8Row(2), base_cc
1748: .newRowLocationTemplate(), 3);
1749:
1750: // test: make sure scan position is right after inserts before scan
1751: // no split case. In this case the slot position of the current
1752: // position should change, but the code will keep a record handle
1753: // and not need to reposition by key.
1754: // before keys: 1000, 3000
1755: // last key gotten froms scan : 0
1756: // insert keys:1-900
1757: // next key from scan should be: 5
1758:
1759: // insert 1000
1760: ((SQLLongint) base_row[1]).setValue(1000);
1761: base_cc.insertAndFetchLocation(base_row, base_rowloc);
1762: if (index_cc.insert(index_row_from_base_row.getRow()) != 0) {
1763: throw T_Fail.testFailMsg("insert failed");
1764: }
1765:
1766: // open a new scan
1767:
1768: ScanController scan = tc.openScan(create_ret.index_conglomid,
1769: false, 0, TransactionController.MODE_RECORD,
1770: TransactionController.ISOLATION_SERIALIZABLE,
1771: (FormatableBitSet) null, null, ScanController.NA, null,
1772: null, ScanController.NA);
1773:
1774: if (SanityManager.DEBUG)
1775: SanityManager.ASSERT(scan.next());
1776:
1777: scan.fetch(index_row.getRow());
1778: long key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1779:
1780: if (SanityManager.DEBUG)
1781: SanityManager.ASSERT(key == 1000);
1782:
1783: // The following test works best if 5 rows fit on one page
1784:
1785: //for (int i = 1; i < 900; i++)
1786: for (int i = 0; i < 6; i++) {
1787: // insert i
1788: ((SQLLongint) base_row[1]).setValue(i);
1789: base_cc.insertAndFetchLocation(base_row, base_rowloc);
1790:
1791: if (index_cc.insert(index_row_from_base_row.getRow()) != 0) {
1792: throw T_Fail.testFailMsg("insert failed");
1793: }
1794:
1795: // About every 2nd split page, recheck the position
1796:
1797: if (i % 10 == 0) {
1798: // current position should not have changed
1799: scan.fetch(index_row.getRow());
1800: key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1801: if (SanityManager.DEBUG)
1802: SanityManager.ASSERT(key == 1000);
1803: }
1804:
1805: }
1806:
1807: // insert 3000
1808: ((SQLLongint) base_row[1]).setValue(3000);
1809: base_cc.insertAndFetchLocation(base_row, base_rowloc);
1810: if (index_cc.insert(index_row_from_base_row.getRow()) != 0) {
1811: throw T_Fail.testFailMsg("insert failed");
1812: }
1813:
1814: // current position should not have changed
1815: scan.fetch(index_row.getRow());
1816: key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1817:
1818: if (SanityManager.DEBUG)
1819: SanityManager.ASSERT(key == 1000);
1820:
1821: // next position should be 3000
1822: if (SanityManager.DEBUG)
1823: SanityManager.ASSERT(scan.next());
1824: scan.fetch(index_row.getRow());
1825: key = ((SQLLongint) (index_row.getRow()[1])).getLong();
1826:
1827: if (SanityManager.DEBUG)
1828: SanityManager.ASSERT(key == 3000);
1829:
1830: index_cc.checkConsistency();
1831:
1832: index_cc.close();
1833: scan.close();
1834:
1835: REPORT("Ending t_008");
1836:
1837: return (ret_val);
1838: }
1839:
1840: /**
1841: * Test unique/nonunique indexes - both positive and negative cases.
1842: * <p>
1843: *
1844: * @exception StandardException Standard exception policy.
1845: * @exception T_Fail Throws T_Fail on any test failure.
1846: **/
1847: protected boolean t_009(TransactionController tc)
1848: throws StandardException, T_Fail {
1849: ScanController scan = null;
1850:
1851: REPORT("Starting t_009");
1852:
1853: // NON-UNIQUE INDEX
1854: T_CreateConglomRet create_ret = new T_CreateConglomRet();
1855:
1856: createCongloms(tc, 2, false, false, 2, create_ret);
1857:
1858: // Open the base table
1859: ConglomerateController base_cc = tc.openConglomerate(
1860: create_ret.base_conglomid, false,
1861: TransactionController.OPENMODE_FORUPDATE,
1862: TransactionController.MODE_RECORD,
1863: TransactionController.ISOLATION_SERIALIZABLE);
1864:
1865: // Open the secondary index
1866: ConglomerateController index_cc = tc.openConglomerate(
1867: create_ret.index_conglomid, false,
1868: TransactionController.OPENMODE_FORUPDATE,
1869: TransactionController.MODE_RECORD,
1870: TransactionController.ISOLATION_SERIALIZABLE);
1871:
1872: // Create a row and insert into base table, remembering it's location.
1873: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
1874: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
1875: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
1876:
1877: index_row1.init(r1, base_rowloc1, 3);
1878:
1879: ((SQLLongint) r1[0]).setValue(1);
1880: ((SQLLongint) r1[1]).setValue(1000);
1881:
1882: // Insert the row into the base table;remember its location.
1883: base_cc.insertAndFetchLocation(r1, base_rowloc1);
1884:
1885: // Insert the row into the secondary index.
1886: if (index_cc.insert(index_row1.getRow()) != 0)
1887: throw T_Fail.testFailMsg("insert failed");
1888:
1889: if (index_cc.insert(index_row1.getRow()) != ConglomerateController.ROWISDUPLICATE) {
1890: throw T_Fail
1891: .testFailMsg("insert of duplicate returned wrong return value:");
1892: }
1893:
1894: // Delete the only entry and make sure it can be reinserted in same
1895: // xact.
1896: DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
1897: ((SQLLongint) delete_key[0]).setValue(1);
1898: ((SQLLongint) delete_key[1]).setValue(1000);
1899:
1900: if (!t_delete(tc, create_ret.index_conglomid, delete_key,
1901: create_ret.index_template_row)) {
1902: throw T_Fail.testFailMsg("t_008: could not delete key.");
1903: }
1904:
1905: if (index_cc.insert(index_row1.getRow()) != 0)
1906: throw T_Fail.testFailMsg("insert failed");
1907:
1908: tc.commit();
1909:
1910: // UNIQUE INDEX
1911: create_ret = new T_CreateConglomRet();
1912:
1913: // Create the btree so that it only allows 2 rows per page.
1914: createCongloms(tc, 2, true, false, 2, create_ret);
1915:
1916: // Open the base table
1917: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
1918: TransactionController.OPENMODE_FORUPDATE,
1919: TransactionController.MODE_RECORD,
1920: TransactionController.ISOLATION_SERIALIZABLE);
1921:
1922: // Open the secondary index
1923: index_cc = tc.openConglomerate(create_ret.index_conglomid,
1924: false, TransactionController.OPENMODE_FORUPDATE,
1925: TransactionController.MODE_RECORD,
1926: TransactionController.ISOLATION_SERIALIZABLE);
1927:
1928: // Create a row and insert into base table, remembering it's location.
1929: r1 = TemplateRow.newU8Row(2);
1930: index_row1 = new T_SecondaryIndexRow();
1931: base_rowloc1 = base_cc.newRowLocationTemplate();
1932:
1933: index_row1.init(r1, base_rowloc1, 3);
1934:
1935: ((SQLLongint) r1[0]).setValue(1);
1936: ((SQLLongint) r1[1]).setValue(1000);
1937:
1938: // Insert the row into the base table;remember its location.
1939: base_cc.insertAndFetchLocation(r1, base_rowloc1);
1940:
1941: // Insert the row into the secondary index.
1942: if (index_cc.insert(index_row1.getRow()) != 0)
1943: throw T_Fail.testFailMsg("insert failed");
1944:
1945: // Insert the row into the base table;remember its location.
1946: base_cc.insertAndFetchLocation(r1, base_rowloc1);
1947:
1948: // Insert the row into the secondary index.
1949: if (index_cc.insert(index_row1.getRow()) != ConglomerateController.ROWISDUPLICATE) {
1950: throw T_Fail
1951: .testFailMsg("insert of duplicate returned wrong return value:");
1952: }
1953:
1954: // Delete the only entry and make sure it can be reinserted in same
1955: // xact.
1956: delete_key = TemplateRow.newU8Row(2);
1957: ((SQLLongint) delete_key[0]).setValue(1);
1958: ((SQLLongint) delete_key[1]).setValue(1000);
1959:
1960: if (!t_delete(tc, create_ret.index_conglomid, delete_key,
1961: create_ret.index_template_row)) {
1962: throw T_Fail.testFailMsg("t_008: could not delete key.");
1963: }
1964:
1965: if (index_cc.insert(index_row1.getRow()) != 0)
1966: throw T_Fail.testFailMsg("insert failed");
1967:
1968: REPORT("Ending t_009");
1969:
1970: return (true);
1971: }
1972:
1973: /**
1974: * Test restoreToNull
1975: *
1976: *
1977: * @exception StandardException Standard exception policy.
1978: * @exception T_Fail Throws T_Fail on any test failure.
1979: */
1980: protected boolean t_010(TransactionController tc)
1981: throws StandardException, T_Fail {
1982: REPORT("Starting t_006");
1983:
1984: B2I testbtree = new B2I();
1985:
1986: // test restoreToNull()
1987: testbtree.restoreToNull();
1988:
1989: if (!(testbtree.isNull()))
1990: throw T_Fail.testFailMsg("bad restoreToNull/isNull");
1991:
1992: // test bad container open not working.
1993: try {
1994:
1995: // the following open should fail with a containerNotFound error
1996:
1997: // for testing purposes - assume TransactionController can be casted
1998: TransactionManager tm = (TransactionManager) tc;
1999: ConglomerateController cc = testbtree.open(tm, tm
2000: .getRawStoreXact(), false, 0, 0,
2001: (LockingPolicy) null, null, null);
2002:
2003: throw T_Fail.testFailMsg("bad open succeeded.");
2004: } catch (StandardException t) {
2005: // expected path comes here.
2006: }
2007:
2008: // create the base table
2009: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2010: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2011:
2012: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2013: base_row, // base table template row
2014: null, //column sort order - not required for heap
2015: null, // default properties
2016: TransactionController.IS_DEFAULT);
2017: // Open the base table
2018: ConglomerateController base_cc = tc.openConglomerate(
2019: base_conglomid, false, 0,
2020: TransactionController.MODE_RECORD,
2021: TransactionController.ISOLATION_SERIALIZABLE);
2022:
2023: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2024:
2025: index_row1.init(base_row, base_rowloc1, 3);
2026:
2027: // create the secondary index
2028: Properties properties = createProperties(null, // no current properties list
2029: false, // don't allow duplicates
2030: 3, // index on all base row cols + row location
2031: 2, // non-unique index
2032: true, // maintain parent links
2033: -42, // fake base conglom for now
2034: 2); // row loc in last column
2035:
2036: TransactionManager tm = (TransactionManager) tc;
2037:
2038: // test bad property
2039: try {
2040: testbtree.create(tm, -1, ContainerHandle.DEFAULT_ASSIGN_ID,
2041: index_row1.getRow(), null, null,
2042: TransactionController.IS_TEMPORARY);
2043:
2044: throw T_Fail.testFailMsg("bad create succeeded.");
2045: } catch (StandardException t) {
2046: // expected path comes here.
2047: }
2048:
2049: // try bad properties
2050:
2051: // create the secondary index
2052: properties = createProperties(null, // no current properties list
2053: false, // don't allow duplicates
2054: 3, // index on all base row cols + row location
2055: 1, // 1 unique field leaving 1 non key field
2056: // other than the rowlocation - should not be
2057: // allowed.
2058: true, // maintain parent links
2059: -42, // fake base conglom for now
2060: 2); // row loc in last column
2061: try {
2062: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
2063: index_row1.getRow(), // row template
2064: null, //column sort order - default
2065: properties, // properties
2066: TransactionController.IS_DEFAULT); // not temporary
2067:
2068: throw T_Fail.testFailMsg("bad create succeeded.");
2069:
2070: } catch (Throwable t) {
2071: // expected path comes here
2072: }
2073:
2074: REPORT("Ending t_010");
2075: return (true);
2076: }
2077:
2078: /**
2079: * Test Special cases of split.
2080: * <p>
2081: * Testing: restartSplitFor() call in LeafControlRow().
2082: *
2083: * The first case is where we split
2084: * down the tree and reach the leaf, pick a split point, and then find
2085: * that there is not enough room to insert row into parent branch page.
2086: *
2087: * The second case is the same as the first except the calling code is
2088: * trying to split a branch page and the parent branch page doesn't have
2089: * room for the row.
2090: *
2091: * @exception StandardException Standard exception policy.
2092: * @exception T_Fail Throws T_Fail on any test failure.
2093: **/
2094: protected boolean t_011(TransactionController tc)
2095: throws StandardException, T_Fail {
2096: boolean ret_val = true;
2097:
2098: REPORT("Starting t_011");
2099:
2100: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2101:
2102: createCongloms(tc, 2, false, true, 0, create_ret);
2103:
2104: // Open the base conglomerate.
2105: ConglomerateController base_cc = tc.openConglomerate(
2106: create_ret.base_conglomid, false,
2107: TransactionController.OPENMODE_FORUPDATE,
2108: TransactionController.MODE_RECORD,
2109: TransactionController.ISOLATION_SERIALIZABLE);
2110:
2111: // Open the index conglomerate.
2112: ConglomerateController index_cc = tc.openConglomerate(
2113: create_ret.index_conglomid, false,
2114: TransactionController.OPENMODE_FORUPDATE,
2115: TransactionController.MODE_RECORD,
2116: TransactionController.ISOLATION_SERIALIZABLE);
2117:
2118: // Create a row.
2119: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2120: RowLocation rowloc = base_cc.newRowLocationTemplate();
2121: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2122: base_row[0] = new SQLChar("aaaaaaaaaa");
2123: index_row.init(base_row, rowloc, 3);
2124:
2125: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2126: ((SQLLongint) base_row[1]).setValue(1);
2127: base_cc.insertAndFetchLocation(base_row, rowloc);
2128:
2129: // CAUSE LEAF splitFor to loop:
2130: // pick numbers so that split will happen in middle of page. Do this
2131: // by first inserting last row in table and then insert smaller rows,
2132: // then insert rows before it until the table is just ready to split
2133: // the root, and finally insert some shorter rows in such a way as
2134: // they cause a split but the split point is chosen with one of the
2135: // larger rows as the descriminator causing 1st splitfor pass to fail
2136: // and loop back and do a splitFor the larger row.
2137:
2138: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("m", 1000));
2139: {
2140: ((SQLLongint) base_row[1]).setValue(0);
2141: base_cc.insertAndFetchLocation(base_row, rowloc);
2142:
2143: if (index_cc.insert(index_row.getRow()) != 0)
2144: throw T_Fail.testFailMsg("insert failed");
2145: }
2146:
2147: // insert enough rows to make a 2 level btree where if another row
2148: // with a 1000 byte string would cause a root split.
2149: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2150: for (int i = 0; i < 5; i++) {
2151: ((SQLLongint) base_row[1]).setValue(i);
2152: base_cc.insertAndFetchLocation(base_row, rowloc);
2153:
2154: if (index_cc.insert(index_row.getRow()) != 0)
2155: throw T_Fail.testFailMsg("insert failed");
2156: }
2157:
2158: // insert a shorter leaf row, such that it will fit in the root, but
2159: // make the split point pick a longer row descriminator which won't
2160: // fit in the root page.
2161: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("z", 500));
2162: for (int i = 10; i > 8; i--) {
2163: ((SQLLongint) base_row[1]).setValue(i);
2164: base_cc.insertAndFetchLocation(base_row, rowloc);
2165:
2166: if (index_cc.insert(index_row.getRow()) != 0)
2167: throw T_Fail.testFailMsg("insert failed");
2168: }
2169:
2170: index_cc.checkConsistency();
2171:
2172: // Close the conglomerate.
2173: index_cc.close();
2174:
2175: tc.dropConglomerate(create_ret.index_conglomid);
2176: tc.dropConglomerate(create_ret.base_conglomid);
2177:
2178: tc.abort();
2179:
2180: REPORT("Ending t_011");
2181:
2182: return (ret_val);
2183: }
2184:
2185: /**
2186: * Test Special cases of split.
2187: * <p>
2188: * Testing: restartSplitFor() call in BranchControlRow().
2189: *
2190: * The second case is the same as the first except the calling code is
2191: * trying to split a branch page and the parent branch page doesn't have
2192: * room for the row.
2193: *
2194: * @exception StandardException Standard exception policy.
2195: * @exception T_Fail Throws T_Fail on any test failure.
2196: **/
2197: protected boolean t_012(TransactionController tc)
2198: throws StandardException, T_Fail {
2199: boolean ret_val = true;
2200:
2201: REPORT("Starting t_011");
2202:
2203: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2204:
2205: createCongloms(tc, 2, false, true, 0, create_ret);
2206:
2207: // Open the base conglomerate.
2208: ConglomerateController base_cc = tc.openConglomerate(
2209: create_ret.base_conglomid, false,
2210: TransactionController.OPENMODE_FORUPDATE,
2211: TransactionController.MODE_RECORD,
2212: TransactionController.ISOLATION_SERIALIZABLE);
2213:
2214: // Open the index conglomerate.
2215: ConglomerateController index_cc = tc.openConglomerate(
2216: create_ret.index_conglomid, false,
2217: TransactionController.OPENMODE_FORUPDATE,
2218: TransactionController.MODE_RECORD,
2219: TransactionController.ISOLATION_SERIALIZABLE);
2220:
2221: // Create a row.
2222: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2223: RowLocation rowloc = base_cc.newRowLocationTemplate();
2224: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2225: base_row[0] = new SQLChar("aaaaaaaaaa");
2226: index_row.init(base_row, rowloc, 3);
2227:
2228: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2229: ((SQLLongint) base_row[1]).setValue(1);
2230: base_cc.insertAndFetchLocation(base_row, rowloc);
2231:
2232: // CAUSE BRANCH splitFor to loop:
2233: // pick numbers so that split will happen in middle of page. Do this
2234: // by first inserting last row in table and then insert smaller rows,
2235: // then insert rows before it until the table is just ready to split
2236: // the root, and finally insert some shorter rows in such a way as
2237: // they cause a split but the split point is chosen with one of the
2238: // larger rows as the descriminator causing 1st splitfor pass to fail
2239: // and loop back and do a splitFor the larger row.
2240:
2241: // insert enough rows so the tree is 3 levels, just ready to go to
2242: // 4 levels.
2243: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("ma", 500));
2244: for (int i = 0; i < 3; i++) {
2245: ((SQLLongint) base_row[1]).setValue(i);
2246: base_cc.insertAndFetchLocation(base_row, rowloc);
2247:
2248: if (index_cc.insert(index_row.getRow()) != 0)
2249: throw T_Fail.testFailMsg("insert failed");
2250: }
2251: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("m", 1000));
2252: for (int i = 3; i < 23; i++) {
2253: ((SQLLongint) base_row[1]).setValue(i);
2254: base_cc.insertAndFetchLocation(base_row, rowloc);
2255:
2256: if (index_cc.insert(index_row.getRow()) != 0)
2257: throw T_Fail.testFailMsg("insert failed");
2258: }
2259:
2260: ((SQLChar) base_row[0]).setValue(T_b2i.repeatString("a", 600));
2261: for (int i = 123; i > 111; i--) {
2262: ((SQLLongint) base_row[1]).setValue(i * 2);
2263: base_cc.insertAndFetchLocation(base_row, rowloc);
2264:
2265: if (index_cc.insert(index_row.getRow()) != 0)
2266: throw T_Fail.testFailMsg("insert failed");
2267: }
2268: {
2269: ((SQLLongint) base_row[1]).setValue(227);
2270: base_cc.insertAndFetchLocation(base_row, rowloc);
2271:
2272: if (index_cc.insert(index_row.getRow()) != 0)
2273: throw T_Fail.testFailMsg("insert failed");
2274: }
2275:
2276: // ((B2IController)index_cc).printTree();
2277: tc.commit();
2278:
2279: // Close the conglomerate.
2280: index_cc.close();
2281:
2282: REPORT("Ending t_012");
2283:
2284: return (ret_val);
2285: }
2286:
2287: /**
2288: * Test backout during critical times of splits.
2289: * <p>
2290: * Force logical undo of an operation which generated an internal update
2291: * of a btree record:
2292: * case 1:
2293: * o insert into unique btree key1, rowlocation_1
2294: * o delete from btree key1, rowlocation_1
2295: * - this will mark the record logically deleted.
2296: * o insert enough records to move the logically deleted row to another
2297: * page to exercise logical undo of the delete.
2298: * o insert into btree key1, rowlocation_2
2299: * - this internally will generate a logical update field on the
2300: * record.
2301: * o insert enough records to move the logically deleted row to another
2302: * page to exercise logical undo of the delete.
2303: * o abort.
2304: *
2305: * case 2:
2306: * o same as case 1 but don't change the rowlocation_1 value. This
2307: * simulates what the language will generate on an update of a key
2308: * field.
2309: *
2310: *
2311: * @exception StandardException Standard exception policy.
2312: * @exception T_Fail Throws T_Fail on any test failure.
2313: **/
2314: protected boolean t_013(TransactionController tc)
2315: throws StandardException, T_Fail {
2316: ScanController scan = null;
2317:
2318: // SanityManager.DEBUG_SET("LockTrace");
2319:
2320: REPORT("Starting t_013");
2321:
2322: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2323:
2324: // Create the btree so that it only allows 2 rows per page.
2325: createCongloms(tc, 2, true, false, 5, create_ret);
2326:
2327: // Open the base table
2328: ConglomerateController base_cc = tc.openConglomerate(
2329: create_ret.base_conglomid, false,
2330: TransactionController.OPENMODE_FORUPDATE,
2331: TransactionController.MODE_RECORD,
2332: TransactionController.ISOLATION_SERIALIZABLE);
2333:
2334: // Open the secondary index
2335: ConglomerateController index_cc = tc.openConglomerate(
2336: create_ret.index_conglomid, false,
2337: TransactionController.OPENMODE_FORUPDATE,
2338: TransactionController.MODE_RECORD,
2339: TransactionController.ISOLATION_SERIALIZABLE);
2340:
2341: // Create an index row object for the "delete row"
2342: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
2343: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2344: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2345:
2346: index_row1.init(r1, base_rowloc1, 3);
2347:
2348: // Create another index row object for the other inserts.
2349: DataValueDescriptor[] r2 = TemplateRow.newU8Row(2);
2350: T_SecondaryIndexRow index_row2 = new T_SecondaryIndexRow();
2351: RowLocation base_rowloc2 = base_cc.newRowLocationTemplate();
2352:
2353: index_row2.init(r2, base_rowloc2, 3);
2354:
2355: // Commit the create of the tables so that the following aborts don't
2356: // undo that work.
2357: tc.commit();
2358:
2359: // CASE 1:
2360: tc.commit();
2361:
2362: // Open the base table
2363: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
2364: TransactionController.OPENMODE_FORUPDATE,
2365: TransactionController.MODE_RECORD,
2366: TransactionController.ISOLATION_SERIALIZABLE);
2367:
2368: // Open the secondary index
2369: index_cc = tc.openConglomerate(create_ret.index_conglomid,
2370: false, TransactionController.OPENMODE_FORUPDATE,
2371: TransactionController.MODE_RECORD,
2372: TransactionController.ISOLATION_SERIALIZABLE);
2373:
2374: ((SQLLongint) r1[0]).setValue(1);
2375:
2376: // insert row which will be deleted (key = 100, base_rowloc1):
2377: ((SQLLongint) r1[1]).setValue(100);
2378: base_cc.insertAndFetchLocation(r1, base_rowloc1);
2379:
2380: // Insert the row into the secondary index.
2381: if (index_cc.insert(index_row1.getRow()) != 0)
2382: throw T_Fail.testFailMsg("insert failed");
2383:
2384: // insert enough rows so that the logical undo of the insert will
2385: // need to search the tree. The tree has been set to split after
2386: // 5 rows are on a page, so 10 should be plenty.
2387: for (int i = 0; i < 10; i++) {
2388: ((SQLLongint) r2[1]).setValue(i);
2389:
2390: // Insert the row into the base table;remember its location.
2391: base_cc.insertAndFetchLocation(r2, base_rowloc2);
2392:
2393: // Insert the row into the secondary index.
2394: if (index_cc.insert(index_row2.getRow()) != 0)
2395: throw T_Fail.testFailMsg("insert failed");
2396: }
2397:
2398: // delete row which was inserted (key = 100, base_rowloc1):
2399: if (!t_delete(tc, create_ret.index_conglomid, index_row1
2400: .getRow(), create_ret.index_template_row)) {
2401: throw T_Fail.testFailMsg("t_008: could not delete key.");
2402: }
2403: base_cc.delete(base_rowloc1);
2404:
2405: // insert enough rows so that the logical undo of the delete will
2406: // need to search the tree. The tree has been set to split after
2407: // 5 rows are on a page, so 10 should be plenty.
2408: for (int i = 10; i < 20; i++) {
2409: ((SQLLongint) r2[1]).setValue(i);
2410:
2411: // Insert the row into the base table;remember its location.
2412: base_cc.insertAndFetchLocation(r2, base_rowloc2);
2413:
2414: // Insert the row into the secondary index.
2415: if (index_cc.insert(index_row2.getRow()) != 0)
2416: throw T_Fail.testFailMsg("insert failed");
2417: }
2418:
2419: // insert row which will be deleted (key = 100, base_rowloc1):
2420: ((SQLLongint) r1[1]).setValue(100);
2421: base_cc.insertAndFetchLocation(r1, base_rowloc1);
2422:
2423: // Insert the row into the secondary index.
2424: if (index_cc.insert(index_row1.getRow()) != 0)
2425: throw T_Fail.testFailMsg("insert failed");
2426:
2427: // insert enough rows so that the logical undo of the update field will
2428: // need to search the tree. The tree has been set to split after
2429: // 5 rows are on a page, so 10 should be plenty.
2430: for (int i = 20; i < 30; i++) {
2431: ((SQLLongint) r2[1]).setValue(i);
2432:
2433: // Insert the row into the base table;remember its location.
2434: base_cc.insertAndFetchLocation(r2, base_rowloc2);
2435:
2436: // Insert the row into the secondary index.
2437: if (index_cc.insert(index_row2.getRow()) != 0)
2438: throw T_Fail.testFailMsg("insert failed");
2439: }
2440:
2441: // RESOLVE (mikem) - check that the right row is at key 100.
2442:
2443: tc.abort();
2444:
2445: // index check - there should be no records left.
2446: ScanController empty_scan = tc.openScan(
2447: create_ret.index_conglomid, false, 0,
2448: TransactionController.MODE_RECORD,
2449: TransactionController.ISOLATION_SERIALIZABLE,
2450: (FormatableBitSet) null, null, ScanController.NA, null,
2451: null, ScanController.NA);
2452:
2453: if (empty_scan.next())
2454: throw T_Fail
2455: .testFailMsg("t_002: there are still rows in table.");
2456:
2457: tc.commit();
2458: REPORT("Ending t_013");
2459:
2460: return true;
2461: }
2462:
2463: /**
2464: * Test getTableProperties() of BTreeController.
2465: * <p>
2466: *
2467: *
2468: * @exception StandardException Standard exception policy.
2469: * @exception T_Fail Throws T_Fail on any test failure.
2470: **/
2471: protected boolean t_014(TransactionController tc)
2472: throws StandardException, T_Fail {
2473: ScanController scan = null;
2474:
2475: // SanityManager.DEBUG_SET("LockTrace");
2476:
2477: REPORT("Starting t_014");
2478:
2479: // create the base table
2480: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2481: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2482:
2483: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2484: base_row, // base table template row
2485: null, //column sort order - not required for heap
2486: null, // default properties
2487: TransactionController.IS_DEFAULT);
2488:
2489: // Open the base table
2490: ConglomerateController base_cc = tc.openConglomerate(
2491: base_conglomid, false, 0,
2492: TransactionController.MODE_RECORD,
2493: TransactionController.ISOLATION_SERIALIZABLE);
2494:
2495: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2496:
2497: index_row1.init(base_row, base_rowloc1, 3);
2498:
2499: // create the secondary index
2500: Properties properties = createProperties(null, // no current properties list
2501: false, // don't allow duplicates
2502: 3, // index on all base row cols + row location
2503: 2, // non-unique index
2504: true, // maintain parent links
2505: base_conglomid, // fake base conglom for now
2506: 2); // row loc in last column
2507:
2508: properties.put(Property.PAGE_SIZE_PARAMETER, "8192");
2509: properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER,
2510: "99");
2511: properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,
2512: "42");
2513:
2514: TransactionManager tm = (TransactionManager) tc;
2515:
2516: // Create a index.
2517: long conglomid = tc.createConglomerate("BTREE", // create a heap conglomerate
2518: index_row1.getRow(), // 1 column template.
2519: null, //column sort order - default
2520: properties, // default properties
2521: TransactionController.IS_DEFAULT); // not temporary
2522:
2523: // Open the conglomerate.
2524: ConglomerateController cc = tc.openConglomerate(conglomid,
2525: false, TransactionController.OPENMODE_FORUPDATE,
2526: TransactionController.MODE_RECORD,
2527: TransactionController.ISOLATION_SERIALIZABLE);
2528:
2529: // verify that input properties were used.
2530: Properties ret_prop = new Properties();
2531: ret_prop.put(Property.PAGE_SIZE_PARAMETER, "");
2532: ret_prop.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, "");
2533: ret_prop.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, "");
2534:
2535: cc.getTableProperties(ret_prop);
2536:
2537: if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER)
2538: .compareTo("8192") != 0
2539: || ret_prop.getProperty(
2540: RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
2541: .compareTo("0") != 0
2542: || ret_prop.getProperty(
2543: RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
2544: .compareTo("1") != 0) {
2545: throw T_Fail
2546: .testFailMsg("(getTableProperties) Did not get expected table propertes."
2547: + "\nGot pageSize = "
2548: + ret_prop
2549: .getProperty(Property.PAGE_SIZE_PARAMETER)
2550: + "\nGot reserved = "
2551: + ret_prop
2552: .getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
2553: + "\nGot minimum record size = "
2554: + ret_prop
2555: .getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER));
2556: }
2557:
2558: tc.commit();
2559:
2560: REPORT("Ending t_014");
2561: return (true);
2562: }
2563:
2564: /**
2565: * Test latch release during critical time during row level locking.
2566: * <p>
2567: * Use trace points to force errors in split at critical points:
2568: * leaf_split_abort{1,2,3,4}
2569: *
2570: * @exception StandardException Standard exception policy.
2571: * @exception T_Fail Throws T_Fail on any test failure.
2572: **/
2573: protected boolean t_015(TransactionController tc)
2574: throws StandardException, T_Fail {
2575: ScanController scan = null;
2576:
2577: // SanityManager.DEBUG_SET("LockTrace");
2578:
2579: REPORT("Starting t_015");
2580:
2581: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2582:
2583: // Create the btree so that it only allows 2 rows per page.
2584: createCongloms(tc, 2, false, false, 2, create_ret);
2585:
2586: // Open the base table
2587: ConglomerateController base_cc = tc.openConglomerate(
2588: create_ret.base_conglomid, false,
2589: TransactionController.OPENMODE_FORUPDATE,
2590: TransactionController.MODE_RECORD,
2591: TransactionController.ISOLATION_SERIALIZABLE);
2592:
2593: // Open the secondary index
2594: ConglomerateController index_cc = tc.openConglomerate(
2595: create_ret.index_conglomid, false,
2596: TransactionController.OPENMODE_FORUPDATE,
2597: TransactionController.MODE_RECORD,
2598: TransactionController.ISOLATION_SERIALIZABLE);
2599:
2600: if (!(index_cc instanceof B2IController)) {
2601: throw T_Fail
2602: .testFailMsg("openConglomerate returned wrong type");
2603: }
2604:
2605: index_cc.checkConsistency();
2606:
2607: // Create a row and insert into base table, remembering it's location.
2608: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
2609: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2610: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2611:
2612: index_row1.init(r1, base_rowloc1, 3);
2613:
2614: // Commit the create of the tables so that the following aborts don't
2615: // undo that work.
2616: tc.commit();
2617:
2618: // Now load up the table with multiple pages of data.
2619:
2620: // Open the base table
2621: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
2622: TransactionController.OPENMODE_FORUPDATE,
2623: TransactionController.MODE_RECORD,
2624: TransactionController.ISOLATION_SERIALIZABLE);
2625:
2626: // Open the secondary index
2627: index_cc = tc.openConglomerate(create_ret.index_conglomid,
2628: false, TransactionController.OPENMODE_FORUPDATE,
2629: TransactionController.MODE_RECORD,
2630: TransactionController.ISOLATION_SERIALIZABLE);
2631:
2632: // now insert enough rows to cause failure
2633: for (int i = 100; i > 0; i -= 2) {
2634: ((SQLLongint) r1[0]).setValue(2);
2635: ((SQLLongint) r1[1]).setValue(i);
2636:
2637: // Insert the row into the base table;remember its location.
2638: base_cc.insertAndFetchLocation(r1, base_rowloc1);
2639:
2640: // Insert the row into the secondary index.
2641: if (index_cc.insert(index_row1.getRow()) != 0) {
2642: throw T_Fail.testFailMsg("insert failed");
2643: }
2644: }
2645:
2646: // Now try simulated lock wait/latch release paths through the code.
2647: String[] latch_debug_strings = {
2648: "B2iRowLocking3_1_lockScanRow1",
2649: "B2iRowLocking3_2_lockScanRow1",
2650: "B2iRowLocking3_3_lockScanRow1",
2651: "BTreeScan_positionAtStartPosition1",
2652: "BTreeScan_positionAtNextPage1",
2653: // "BTreeScan_reposition1",
2654: "BTreeScan_fetchNextGroup1", };
2655:
2656: for (int errs = 0; errs < latch_debug_strings.length; errs++) {
2657: REPORT("Doing latch release tests: "
2658: + latch_debug_strings[errs]);
2659:
2660: // set the debug flag, which will cause a simulated lock wait
2661: // latch release path through the code.
2662: if (SanityManager.DEBUG)
2663: SanityManager.DEBUG_SET(latch_debug_strings[errs]);
2664:
2665: // Just scan the rows and make sure you see them all, mostly just
2666: // a test to make sure no errors are thrown by the latch release
2667: // code paths.
2668: scan = tc.openScan(create_ret.index_conglomid, false, 0,
2669: TransactionController.MODE_RECORD,
2670: TransactionController.ISOLATION_SERIALIZABLE,
2671: (FormatableBitSet) null, null, ScanController.NA,
2672: null, null, ScanController.NA);
2673:
2674: int row_count = 0;
2675: while (scan.next()) {
2676: row_count++;
2677: }
2678:
2679: scan.close();
2680:
2681: if (row_count != 50)
2682: throw T_Fail.testFailMsg("wrong scan count = "
2683: + row_count);
2684: }
2685:
2686: tc.abort();
2687: REPORT("Ending t_015");
2688:
2689: return true;
2690: }
2691:
2692: /**
2693: * Test deadlocks during critical times of row level locking.
2694: * <p>
2695: * Use trace points to force errors in split at critical points:
2696: * leaf_split_abort{1,2,3,4}
2697: *
2698: * @exception StandardException Standard exception policy.
2699: * @exception T_Fail Throws T_Fail on any test failure.
2700: **/
2701: protected boolean t_016(TransactionController tc)
2702: throws StandardException, T_Fail {
2703: ScanController scan = null;
2704:
2705: // SanityManager.DEBUG_SET("LockTrace");
2706:
2707: REPORT("Starting t_016");
2708:
2709: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2710:
2711: // Create the btree so that it only allows 2 rows per page.
2712: createCongloms(tc, 2, false, false, 2, create_ret);
2713:
2714: // Open the base table
2715: ConglomerateController base_cc = tc.openConglomerate(
2716: create_ret.base_conglomid, false,
2717: TransactionController.OPENMODE_FORUPDATE,
2718: TransactionController.MODE_RECORD,
2719: TransactionController.ISOLATION_SERIALIZABLE);
2720:
2721: // Open the secondary index
2722: ConglomerateController index_cc = tc.openConglomerate(
2723: create_ret.index_conglomid, false,
2724: TransactionController.OPENMODE_FORUPDATE,
2725: TransactionController.MODE_RECORD,
2726: TransactionController.ISOLATION_SERIALIZABLE);
2727:
2728: if (!(index_cc instanceof B2IController)) {
2729: throw T_Fail
2730: .testFailMsg("openConglomerate returned wrong type");
2731: }
2732:
2733: index_cc.checkConsistency();
2734:
2735: // Create a row and insert into base table, remembering it's location.
2736: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
2737: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2738: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2739:
2740: index_row1.init(r1, base_rowloc1, 3);
2741:
2742: // Commit the create of the tables so that the following aborts don't
2743: // undo that work.
2744: tc.commit();
2745:
2746: // Open the base table
2747: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
2748: TransactionController.OPENMODE_FORUPDATE,
2749: TransactionController.MODE_RECORD,
2750: TransactionController.ISOLATION_SERIALIZABLE);
2751:
2752: // Open the secondary index
2753: index_cc = tc.openConglomerate(create_ret.index_conglomid,
2754: false, TransactionController.OPENMODE_FORUPDATE,
2755: TransactionController.MODE_RECORD,
2756: TransactionController.ISOLATION_SERIALIZABLE);
2757:
2758: // now insert enough rows to cause failure
2759: for (int i = 100; i > 0; i -= 2) {
2760: ((SQLLongint) r1[0]).setValue(2);
2761: ((SQLLongint) r1[1]).setValue(i);
2762:
2763: // Insert the row into the base table;remember its location.
2764: base_cc.insertAndFetchLocation(r1, base_rowloc1);
2765:
2766: // Insert the row into the secondary index.
2767: if (index_cc.insert(index_row1.getRow()) != 0) {
2768: throw T_Fail.testFailMsg("insert failed");
2769: }
2770: }
2771:
2772: tc.abort();
2773:
2774: // Now try simulated deadlocks
2775: // RESOLVE (Mikem) - test out aborts and errors during inserts.
2776: String[] deadlock_debug_strings = {
2777: "B2iRowLocking3_1_lockScanRow2",
2778: "B2iRowLocking3_2_lockScanRow2",
2779: "B2iRowLocking3_3_lockScanRow2",
2780: // "BTreeController_doIns2",
2781: "BTreeScan_positionAtStartPosition2",
2782: "BTreeScan_positionAtNextPage2",
2783: // "BTreeScan_reposition2",
2784: "BTreeScan_fetchNextGroup2" };
2785:
2786: for (int errs = 0; errs < deadlock_debug_strings.length; errs++) {
2787: try {
2788: REPORT("Doing deadlock tests: "
2789: + deadlock_debug_strings[errs]);
2790:
2791: // set the debug flag, which will cause a simulated lock wait
2792: // latch release path through the code.
2793: if (SanityManager.DEBUG)
2794: SanityManager
2795: .DEBUG_SET(deadlock_debug_strings[errs]);
2796:
2797: // Just scan the rows and make sure you see them all, mostly just
2798: // a test to make sure no errors are thrown by the latch release
2799: // code paths.
2800: scan = tc.openScan(create_ret.index_conglomid, false,
2801: 0, TransactionController.MODE_RECORD,
2802: TransactionController.ISOLATION_SERIALIZABLE,
2803: (FormatableBitSet) null, null,
2804: ScanController.NA, null, null,
2805: ScanController.NA);
2806:
2807: int row_count = 0;
2808: while (scan.next()) {
2809: row_count++;
2810: }
2811:
2812: scan.close();
2813:
2814: throw T_Fail.testFailMsg("expected deadlock");
2815: } catch (StandardException e) {
2816: if (!e.getMessageId().equals(SQLState.DEADLOCK))
2817: throw e;
2818:
2819: ContextService contextFactory = ContextService
2820: .getFactory();
2821:
2822: // Get the context manager.
2823: ContextManager cm = contextFactory
2824: .getCurrentContextManager();
2825:
2826: if (SanityManager.DEBUG)
2827: SanityManager.ASSERT(cm != null);
2828:
2829: cm.cleanupOnError(e);
2830: }
2831: }
2832:
2833: tc.commit();
2834: REPORT("Ending t_016");
2835:
2836: return true;
2837: }
2838:
2839: /**
2840: * Test simple btree insert performance
2841: *
2842: * @exception StandardException Standard exception policy.
2843: * @exception T_Fail Throws T_Fail on any test failure.
2844: */
2845: protected boolean t_perf(TransactionController tc)
2846: throws StandardException, T_Fail {
2847: boolean ret_val = true;
2848:
2849: REPORT("Starting t_005");
2850:
2851: T_CreateConglomRet create_ret = new T_CreateConglomRet();
2852:
2853: createCongloms(tc, 2, false, false, 0, create_ret);
2854:
2855: // Open the base conglomerate.
2856: ConglomerateController base_cc = tc.openConglomerate(
2857: create_ret.base_conglomid, false,
2858: TransactionController.OPENMODE_FORUPDATE,
2859: TransactionController.MODE_RECORD,
2860: TransactionController.ISOLATION_SERIALIZABLE);
2861:
2862: // Open the index conglomerate.
2863: ConglomerateController index_cc = tc.openConglomerate(
2864: create_ret.index_conglomid, false,
2865: TransactionController.OPENMODE_FORUPDATE,
2866: TransactionController.MODE_RECORD,
2867: TransactionController.ISOLATION_SERIALIZABLE);
2868:
2869: // Create a row.
2870: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2871: RowLocation rowloc = base_cc.newRowLocationTemplate();
2872: DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2873: index_row.init(base_row, rowloc, 3);
2874:
2875: ((SQLLongint) base_row[0]).setValue(1);
2876: ((SQLLongint) base_row[1]).setValue(1);
2877: base_cc.insertAndFetchLocation(base_row, rowloc);
2878:
2879: long startms = System.currentTimeMillis();
2880:
2881: // insert them in reverse order just to make sure btree is sorting them
2882: for (int i = 0; i < 2000; i++) {
2883: ((SQLLongint) base_row[1]).setValue(i);
2884: // base_cc.insertAndFetchLocation(base_row, rowloc);
2885: // ((HeapRowLocation)rowloc).setFrom(0xffffffffffffffffl, 0xfffffff);
2886:
2887: if (index_cc.insert(index_row.getRow()) != 0)
2888: throw T_Fail.testFailMsg("insert failed");
2889: }
2890:
2891: // ((B2IController)index_cc).printTree();
2892: tc.commit();
2893: long endms = System.currentTimeMillis();
2894: long elapsedms = endms - startms;
2895:
2896: System.out.println(" Elapsed (ms) " + elapsedms);
2897: System.out.println(" inserts/second "
2898: + (1000 * 1000 / elapsedms));
2899:
2900: // Close the conglomerate.
2901: index_cc.close();
2902:
2903: REPORT("Ending t_011");
2904:
2905: return (ret_val);
2906: }
2907:
2908: private boolean t_desc_scan_test_cases(TransactionController tc,
2909: long index_conglomid, T_SecondaryIndexRow template)
2910: throws StandardException, T_Fail {
2911: boolean ret_val = true;
2912:
2913: // run through a predicates as described in the openScan() interface //
2914: DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
2915: DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
2916:
2917: // test predicate x = 5
2918: //
2919: // result set should be:{5,6,18}, {5,4,17}, {5,6,16} //descending
2920: //
2921: REPORT("scan (x = 5)");
2922: ((SQLLongint) start_key[0]).setValue(5);
2923: ((SQLLongint) stop_key[0]).setValue(5);
2924: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
2925: .getRow(), template.getRow(), start_key,
2926: ScanController.GE, null, stop_key, ScanController.GT,
2927: 3, 18, T_QualifierTest.ORDER_DESC)) {
2928: ret_val = false;
2929: }
2930:
2931: // +---------------------------------------------------------+
2932: // |pred |start|key|stop |key|rows returned |rows locked |
2933: // | |value|op |value|op | |(serialization)|
2934: // +------+-----+---+-----+---+--------------+---------------+
2935: // |x > 5 |null |na |5 |GE |{9,1} .. {6,1}|{5,6} .. {9,1} |
2936: // +-----------------------------------------+---------------+
2937: REPORT("scan (x > 5)");
2938: ((SQLLongint) stop_key[0]).setValue(5);
2939: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
2940: .getRow(), template.getRow(), null, ScanController.NA,
2941: null, stop_key, ScanController.GE, 3, 21,
2942: T_QualifierTest.ORDER_DESC)) {
2943: ret_val = false;
2944: }
2945:
2946: // +---------------------------------------------------------+
2947: // |pred |start|key|stop |key|rows returned |rows locked |
2948: // | |value|op |value|op | |(serialization)|
2949: // +------+-----+---+-----+---+--------------+---------------+
2950: // |x >= 5| null|na |5 |GT |{9,1} .. {5,2}|{4,6} .. {9,1} |
2951: // +-----------------------------------------+---------------+
2952: REPORT("scan (x >= 5)");
2953: ((SQLLongint) stop_key[0]).setValue(5);
2954: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
2955: .getRow(), template.getRow(), null, ScanController.NA,
2956: null, stop_key, ScanController.GT, 6, 21,
2957: T_QualifierTest.ORDER_DESC)) {
2958: ret_val = false;
2959: }
2960:
2961: //
2962: // +---------------------------------------------------------+
2963: // |pred |start|key|stop |key|rows returned |rows locked |
2964: // | |value|op |value|op | |(serialization)|
2965: // +------+-----+---+-----+---+--------------+---------------+
2966: // |x <= 5|5 |GE |null |na |{5,6} .. {1,1}|first .. {5,6} |
2967: // +-----------------------------------------+---------------+
2968: REPORT("scan (x <= 5)");
2969: ((SQLLongint) start_key[0]).setValue(5);
2970: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
2971: .getRow(), template.getRow(), start_key,
2972: ScanController.GE, null, null, ScanController.NA, 8,
2973: 18, T_QualifierTest.ORDER_DESC)) {
2974: ret_val = false;
2975: }
2976: //
2977: // +---------------------------------------------------------+
2978: // |pred |start|key|stop |key|rows returned |rows locked |
2979: // | |value|op |value|op | |(serialization)|
2980: // +------+-----+---+-----+---+--------------+---------------+
2981: // |x < 5 |5 | GT|null | |{4,6} .. {1,1}|first .. {4,6} |
2982: // +-----------------------------------------+---------------+
2983: REPORT("scan (x < 5)");
2984: ((SQLLongint) start_key[0]).setValue(5);
2985: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
2986: .getRow(), template.getRow(), start_key,
2987: ScanController.GT, null, null, ScanController.NA, 5,
2988: 15, T_QualifierTest.ORDER_DESC)) {
2989: ret_val = false;
2990: }
2991:
2992: //long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
2993: //long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
2994: //long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
2995: // +------------------------------------------------------------------+
2996: // |pred |start|key|stop |key|rows returned|rows locked |
2997: // | |value|op |value|op | |(serialized) |
2998: // +-----------------+------+--+-----+--+--------------+--------------+
2999: // |x >= 5 and x <= 7|{7}, |GE|{5} |GT|{5,2} .. {7,1}|{4,6} .. {7,1}|
3000: // +------------------------------------------------------------------+
3001: REPORT("scan (x >= 5 and x <= 7)");
3002: ((SQLLongint) start_key[0]).setValue(7);
3003: ((SQLLongint) stop_key[0]).setValue(5);
3004: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3005: .getRow(), template.getRow(), start_key,
3006: ScanController.GE, null, stop_key, ScanController.GT,
3007: 5, 20, T_QualifierTest.ORDER_DESC)) {
3008: ret_val = false;
3009: }
3010:
3011: // +------------------------------------------------------------------+
3012: // |pred |start|key|stop |key|rows returned|rows locked |
3013: // | |value|op |value|op | |(serialized) |
3014: // +-----------------+------+--+-----+--+--------------+--------------+
3015: // |x = 5 and y > 2 |{5} |GE|{5,2 |GE|{5,4} .. {5,6}|{5,2} .. {9,1}|
3016: // +------------------------------------------------------------------+
3017: REPORT("scan (x = 5 and y > 2)");
3018: start_key = TemplateRow.newU8Row(1);
3019: stop_key = TemplateRow.newU8Row(2);
3020: ((SQLLongint) start_key[0]).setValue(5);
3021: ((SQLLongint) stop_key[0]).setValue(5);
3022: ((SQLLongint) stop_key[1]).setValue(2);
3023: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3024: .getRow(), template.getRow(), start_key,
3025: ScanController.GE, null, stop_key, ScanController.GE,
3026: 2, 18, T_QualifierTest.ORDER_DESC)) {
3027: ret_val = false;
3028: }
3029:
3030: // +------------------------------------------------------------------+
3031: // |pred |start|key|stop |key|rows returned|rows locked |
3032: // | |value|op |value|op | |(serialized) |
3033: // +-----------------+------+--+-----+--+--------------+--------------+
3034: // |x = 5 and y >= 2 |{5} |GE|{5,2}|GT|{5,2} .. {5,6}|{4,6} .. {9,1}|
3035: // +------------------------------------------------------------------+
3036: REPORT("scan (x = 5 and y >= 2)");
3037: start_key = TemplateRow.newU8Row(1);
3038: stop_key = TemplateRow.newU8Row(2);
3039: ((SQLLongint) start_key[0]).setValue(5);
3040: ((SQLLongint) stop_key[0]).setValue(5);
3041: ((SQLLongint) stop_key[1]).setValue(2);
3042: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3043: .getRow(), template.getRow(), start_key,
3044: ScanController.GE, null, stop_key, ScanController.GT,
3045: 3, 18, T_QualifierTest.ORDER_DESC)) {
3046: ret_val = false;
3047: }
3048:
3049: // +------------------------------------------------------------------+
3050: // |pred |start|key|stop |key|rows returned|rows locked |
3051: // | |value|op |value|op | |(serialized) |
3052: // +-----------------+------+--+-----+--+--------------+--------------+
3053: // |x = 5 and y < 5 | {5,5}} |GE|{5}|GT|{5,2} .. {5,4}|{4,6} .. {5,4}|
3054: // +------------------------------------------------------------------+
3055: REPORT("scan (x = 5 and y < 5)");
3056: start_key = TemplateRow.newU8Row(2);
3057: stop_key = TemplateRow.newU8Row(1);
3058: ((SQLLongint) start_key[0]).setValue(5);
3059: ((SQLLongint) start_key[1]).setValue(5);
3060: ((SQLLongint) stop_key[0]).setValue(5);
3061: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3062: .getRow(), template.getRow(), start_key,
3063: ScanController.GE, null, stop_key, ScanController.GT,
3064: 2, 17, T_QualifierTest.ORDER_DESC)) {
3065: ret_val = false;
3066: }
3067:
3068: // +------------------------------------------------------------------+
3069: // |pred |start|key|stop |key|rows returned|rows locked |
3070: // | |value|op |value|op | |(serialized) |
3071: // +-----------------+------+--+-----+--+--------------+--------------+
3072: // |x = 2 | {2} |GE| {2} |GT|none |{1,1} .. {1,1}|
3073: // +------------------------------------------------------------------+
3074: REPORT("scan (x = 2)");
3075: start_key = TemplateRow.newU8Row(1);
3076: stop_key = TemplateRow.newU8Row(1);
3077: ((SQLLongint) start_key[0]).setValue(2);
3078: ((SQLLongint) stop_key[0]).setValue(2);
3079: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3080: .getRow(), template.getRow(), start_key,
3081: ScanController.GE, null, stop_key, ScanController.GT,
3082: 0, 0, T_QualifierTest.ORDER_DESC)) {
3083: ret_val = false;
3084: }
3085:
3086: // +-----------------------------+
3087: // |minium on btree - row locked |
3088: // +-----------------------------+
3089: //
3090: REPORT("minimum on btree, row locked.");
3091: // the following function actually returns
3092: // the minimum values because the index is in descending order
3093: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3094: TransactionController.MODE_RECORD,
3095: TransactionController.ISOLATION_SERIALIZABLE,
3096: (FormatableBitSet) null, template.getRow())) {
3097: throw T_Fail.testFailMsg("found no min.");
3098: } else {
3099: // make sure right min was found.
3100: long key = ((SQLLongint) template.getRow()[2]).getLong();
3101:
3102: if (key != 11) {
3103: throw T_Fail.testFailMsg("wrong minimum found.");
3104: }
3105: }
3106:
3107: // +-----------------------------+
3108: // |min on btree - table locked |
3109: // +-----------------------------+
3110: //
3111: REPORT("min on btree, table locked.");
3112: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3113: TransactionController.MODE_TABLE,
3114: TransactionController.ISOLATION_SERIALIZABLE,
3115: (FormatableBitSet) null, template.getRow())) {
3116: throw T_Fail.testFailMsg("found no min.");
3117: } else {
3118: // make sure right min was found.
3119: long key = ((SQLLongint) template.getRow()[2]).getLong();
3120:
3121: if (key != 11) {
3122: throw T_Fail.testFailMsg("wrong min found.");
3123: }
3124: }
3125:
3126: // +-----------------------------+
3127: // |min on btree - row locked |
3128: // +-----------------------------+
3129: //
3130: REPORT("min on btree, row locked.");
3131: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3132: TransactionController.MODE_RECORD,
3133: TransactionController.ISOLATION_READ_COMMITTED,
3134: (FormatableBitSet) null, template.getRow())) {
3135: throw T_Fail.testFailMsg("found no max.");
3136: } else {
3137: // make sure right min was found.
3138: long key = ((SQLLongint) template.getRow()[2]).getLong();
3139:
3140: if (key != 11) {
3141: throw T_Fail.testFailMsg("wrong min found.");
3142: }
3143: }
3144:
3145: // +-----------------------------+
3146: // |min on btree - table locked |
3147: // +-----------------------------+
3148: //
3149: REPORT("min on btree, table locked.");
3150: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3151: TransactionController.MODE_TABLE,
3152: TransactionController.ISOLATION_READ_COMMITTED,
3153: (FormatableBitSet) null, template.getRow())) {
3154: throw T_Fail.testFailMsg("found no min.");
3155: } else {
3156: // make sure right min was found.
3157: long key = ((SQLLongint) template.getRow()[2]).getLong();
3158:
3159: if (key != 11) {
3160: throw T_Fail.testFailMsg("wrong min found.");
3161: }
3162: }
3163:
3164: return (ret_val);
3165: }
3166:
3167: /**
3168: * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
3169: * BtreeScan.fetch() with descending indexes.
3170: *
3171: * @exception StandardException Standard exception policy.
3172: * @exception T_Fail Throws T_Fail on any test failure.
3173: */
3174: protected boolean t_017(TransactionController tc)
3175: throws StandardException, T_Fail {
3176: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
3177:
3178: // base row template - last column is just to make row long so that
3179: // multiple pages are spanned.
3180: DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
3181: base_row[3] = new SQLChar();
3182:
3183: String string_1500char = new String();
3184: for (int i = 0; i < 300; i++)
3185: string_1500char += "mikem";
3186:
3187: boolean ret_val = true;
3188: long value = -1;
3189: long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9 };
3190: long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1 };
3191: long col3[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
3192:
3193: // set of deleted rows to make scans more interesting
3194: long d_col1[] = { 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12 };
3195: long d_col2[] = { 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1 };
3196: long d_col3[] = { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
3197: 102, 103, 104 };
3198:
3199: REPORT("Starting t_017");
3200:
3201: // create the base table
3202: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
3203: base_row, // base table template row
3204: null, //column sort order - not required for heap
3205: null, // default properties
3206: TransactionController.IS_DEFAULT); // not temporary
3207:
3208: // Open the base table
3209: ConglomerateController base_cc = tc.openConglomerate(
3210: base_conglomid, false,
3211: TransactionController.OPENMODE_FORUPDATE,
3212: TransactionController.MODE_RECORD,
3213: TransactionController.ISOLATION_SERIALIZABLE);
3214:
3215: // initialize the secondary index row - pointing it at base row
3216: index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
3217:
3218: Properties properties = createProperties(null, // no current properties list
3219: false, // don't allow duplicates
3220: 5, // 4 columns in index row
3221: 5, // non-unique index
3222: true, // maintain parent links
3223: base_conglomid, // base conglom id
3224: 4); // row loc in last column
3225:
3226: // create the index with all the columns in descending order
3227: ColumnOrdering order[] = new ColumnOrdering[5];
3228: order[0] = new T_ColumnOrderingImpl(0, false); // descending
3229: order[1] = new T_ColumnOrderingImpl(1, false); // descending
3230: order[2] = new T_ColumnOrderingImpl(2, false); // descending
3231: order[3] = new T_ColumnOrderingImpl(3, false); // descending
3232: order[4] = new T_ColumnOrderingImpl(4, true); // asccending
3233:
3234: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
3235: index_row.getRow(), // row template
3236: order, //column sort order - default
3237: properties, // properties
3238: TransactionController.IS_DEFAULT); // not temporary
3239:
3240: // Open the conglomerate.
3241: ConglomerateController index_cc = tc.openConglomerate(
3242: index_conglomid, false,
3243: TransactionController.OPENMODE_FORUPDATE,
3244: TransactionController.MODE_RECORD,
3245: TransactionController.ISOLATION_SERIALIZABLE);
3246:
3247: // Create a row.
3248: T_SecondaryIndexRow template = new T_SecondaryIndexRow();
3249: RowLocation row_loc = base_cc.newRowLocationTemplate();
3250: template.init(base_row, row_loc, 5);
3251:
3252: // insert them in reverse order just to make sure btree is sorting them
3253: for (int i = col1.length - 1; i >= 0; i--) {
3254: ((SQLLongint) (template.getRow()[0])).setValue(col1[i]);
3255: ((SQLLongint) (template.getRow()[1])).setValue(col2[i]);
3256: ((SQLLongint) (template.getRow()[2])).setValue(col3[i]);
3257: base_row[3] = new SQLChar(string_1500char);
3258:
3259: base_cc.insertAndFetchLocation(base_row, row_loc);
3260:
3261: // Insert the row.
3262: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
3263: // ")" + template);
3264: if (index_cc.insert(template.getRow()) != 0)
3265: throw T_Fail.testFailMsg("insert failed");
3266: }
3267:
3268: index_cc.checkConsistency();
3269:
3270: ((B2IController) index_cc).debugConglomerate();
3271:
3272: ret_val = t_desc_scan_test_cases(tc, index_conglomid, template);
3273:
3274: // insert and delete some interesting rows, deleted space management
3275: // may or may not clean these up.
3276: for (int i = d_col1.length - 1; i >= 0; i--) {
3277: ((SQLLongint) (template.getRow()[0])).setValue(d_col1[i]);
3278: ((SQLLongint) (template.getRow()[1])).setValue(d_col2[i]);
3279: ((SQLLongint) (template.getRow()[2])).setValue(d_col3[i]);
3280: base_row[3] = new SQLChar(string_1500char);
3281:
3282: base_cc.insertAndFetchLocation(base_row, row_loc);
3283:
3284: // Insert the row.
3285: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
3286: // ")" + template);
3287: if (index_cc.insert(template.getRow()) != 0)
3288: throw T_Fail.testFailMsg("insert failed");
3289:
3290: // now delete the row.
3291: base_cc.delete(row_loc);
3292:
3293: ScanController delete_scan = tc.openScan(index_conglomid,
3294: false, TransactionController.OPENMODE_FORUPDATE,
3295: TransactionController.MODE_RECORD,
3296: TransactionController.ISOLATION_SERIALIZABLE,
3297: (FormatableBitSet) null, template.getRow(),
3298: ScanController.GE, null, template.getRow(),
3299: ScanController.GT);
3300:
3301: if (!delete_scan.next()) {
3302: throw T_Fail.testFailMsg("delete could not find key");
3303: } else {
3304: delete_scan.delete();
3305:
3306: if (delete_scan.next())
3307: throw T_Fail
3308: .testFailMsg("delete found more than one key");
3309: }
3310:
3311: delete_scan.close();
3312: }
3313:
3314: ret_val = t_desc_scan_test_cases(tc, index_conglomid, template);
3315:
3316: // Close the conglomerate.
3317: index_cc.close();
3318:
3319: tc.commit();
3320: REPORT("Ending t_017");
3321:
3322: return (ret_val);
3323: }
3324:
3325: /* test cases for ASC DESC ASC DESC column sort order index
3326: SORTED DATA
3327: col1, col2, col3
3328: AS DS AS -- sort order
3329: 1, 1, 11
3330: 3, 2, 12
3331: 4, 6, 15
3332: 4, 4, 14
3333: 4, 2, 13
3334: 5, 6, 18
3335: 5, 4, 17
3336: 5, 2, 16
3337: 6, 1, 19
3338: 7, 1, 20
3339: 9, 1, 21
3340: */
3341:
3342: private boolean t_ascdesc_scan_test_cases(TransactionController tc,
3343: long index_conglomid, T_SecondaryIndexRow template)
3344: throws StandardException, T_Fail {
3345: boolean ret_val = true;
3346:
3347: // run through a predicates as described in the openScan() interface //
3348: DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
3349: DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
3350:
3351: // test predicate x = 5
3352: //
3353: // result set should be:{5,6,18}, {5,4,17}, {5,6,16}
3354: //
3355: REPORT("scan (x = 5)");
3356: ((SQLLongint) start_key[0]).setValue(5);
3357: ((SQLLongint) stop_key[0]).setValue(5);
3358: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3359: .getRow(), template.getRow(), start_key,
3360: ScanController.GE, null, stop_key, ScanController.GT,
3361: 3, 18, T_QualifierTest.ORDER_DESC)) {
3362: ret_val = false;
3363: }
3364:
3365: REPORT("scan (x > 5)");
3366: ((SQLLongint) start_key[0]).setValue(5);
3367: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3368: .getRow(), template.getRow(), start_key,
3369: ScanController.GT, null, null, ScanController.NA, 3,
3370: 19, T_QualifierTest.ORDER_FORWARD)) {
3371: ret_val = false;
3372: }
3373:
3374: REPORT("scan (x >= 5)");
3375: ((SQLLongint) start_key[0]).setValue(5);
3376: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3377: .getRow(), template.getRow(), start_key,
3378: ScanController.GE, null, null, ScanController.NA, 6,
3379: 16, T_QualifierTest.ORDER_NONE)) {
3380: ret_val = false;
3381: }
3382:
3383: REPORT("scan (x <= 5)");
3384: ((SQLLongint) stop_key[0]).setValue(5);
3385: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3386: .getRow(), template.getRow(), null, ScanController.NA,
3387: null, stop_key, ScanController.GT, 8, 11,
3388: T_QualifierTest.ORDER_NONE)) {
3389: ret_val = false;
3390: }
3391:
3392: REPORT("scan (x < 5)");
3393: ((SQLLongint) stop_key[0]).setValue(5);
3394: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3395: .getRow(), template.getRow(), null, ScanController.NA,
3396: null, stop_key, ScanController.GE, 5, 11,
3397: T_QualifierTest.ORDER_NONE)) {
3398: ret_val = false;
3399: }
3400:
3401: REPORT("scan (x >= 5 and x <= 7)");
3402: ((SQLLongint) start_key[0]).setValue(5);
3403: ((SQLLongint) stop_key[0]).setValue(7);
3404: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3405: .getRow(), template.getRow(), start_key,
3406: ScanController.GE, null, stop_key, ScanController.GT,
3407: 5, 16, T_QualifierTest.ORDER_NONE)) {
3408: ret_val = false;
3409: }
3410:
3411: REPORT("scan (x = 5 and y > 2)");
3412: start_key = TemplateRow.newU8Row(1);
3413: stop_key = TemplateRow.newU8Row(2);
3414: ((SQLLongint) start_key[0]).setValue(5);
3415: ((SQLLongint) stop_key[0]).setValue(5);
3416: ((SQLLongint) stop_key[1]).setValue(2);
3417: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3418: .getRow(), template.getRow(), start_key,
3419: ScanController.GE, null, stop_key, ScanController.GE,
3420: 2, 18, T_QualifierTest.ORDER_DESC)) {
3421: ret_val = false;
3422: }
3423:
3424: REPORT("scan (x = 5 and y >= 2)");
3425: start_key = TemplateRow.newU8Row(1);
3426: stop_key = TemplateRow.newU8Row(2);
3427: ((SQLLongint) start_key[0]).setValue(5);
3428: ((SQLLongint) stop_key[0]).setValue(5);
3429: ((SQLLongint) stop_key[1]).setValue(2);
3430: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3431: .getRow(), template.getRow(), start_key,
3432: ScanController.GE, null, stop_key, ScanController.GT,
3433: 3, 18, T_QualifierTest.ORDER_DESC)) {
3434: ret_val = false;
3435: }
3436:
3437: REPORT("scan (x = 5 and y < 5)");
3438: start_key = TemplateRow.newU8Row(2);
3439: stop_key = TemplateRow.newU8Row(1);
3440: ((SQLLongint) start_key[0]).setValue(5);
3441: ((SQLLongint) start_key[1]).setValue(5);
3442: ((SQLLongint) stop_key[0]).setValue(5);
3443: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3444: .getRow(), template.getRow(), start_key,
3445: ScanController.GE, null, stop_key, ScanController.GT,
3446: 2, 17, T_QualifierTest.ORDER_DESC)) {
3447: ret_val = false;
3448: }
3449:
3450: REPORT("scan (x = 2)");
3451: start_key = TemplateRow.newU8Row(1);
3452: stop_key = TemplateRow.newU8Row(1);
3453: ((SQLLongint) start_key[0]).setValue(2);
3454: ((SQLLongint) stop_key[0]).setValue(2);
3455: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3456: .getRow(), template.getRow(), start_key,
3457: ScanController.GE, null, stop_key, ScanController.GT,
3458: 0, 0, T_QualifierTest.ORDER_DESC)) {
3459: ret_val = false;
3460: }
3461:
3462: // +-----------------------------+---------------
3463: // |last leaf last row on btree - row locked |
3464: // +-----------------------------+---------------
3465: //
3466: REPORT("minimum on btree, row locked.");
3467:
3468: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3469: TransactionController.MODE_RECORD,
3470: TransactionController.ISOLATION_SERIALIZABLE,
3471: (FormatableBitSet) null, template.getRow())) {
3472: throw T_Fail
3473: .testFailMsg("found last row in the last leaf.");
3474: } else {
3475: // make sure right min was found.
3476: long key = ((SQLLongint) template.getRow()[2]).getLong();
3477:
3478: if (key != 21) {
3479: throw T_Fail
3480: .testFailMsg("wrong last row in the last leaf.");
3481: }
3482: }
3483:
3484: // +-----------------------------+--------------
3485: // |last row in the last leaf - table locked |
3486: // +-----------------------------+--------------
3487: //
3488: REPORT("last row in the last leaf, table locked.");
3489: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3490: TransactionController.MODE_TABLE,
3491: TransactionController.ISOLATION_SERIALIZABLE,
3492: (FormatableBitSet) null, template.getRow())) {
3493: throw T_Fail.testFailMsg("found no min.");
3494: } else {
3495: // make sure right last row in the last leaf found.
3496: long key = ((SQLLongint) template.getRow()[2]).getLong();
3497:
3498: if (key != 21) {
3499: throw T_Fail
3500: .testFailMsg("wrong last row in the last leaf found.");
3501: }
3502: }
3503:
3504: // +-----------------------------+-----------
3505: // |last row in the last leaf- row locked |
3506: // +-----------------------------+-----------
3507: //
3508: REPORT("last row in the last leaf, row locked.");
3509: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3510: TransactionController.MODE_RECORD,
3511: TransactionController.ISOLATION_READ_COMMITTED,
3512: (FormatableBitSet) null, template.getRow())) {
3513: throw T_Fail.testFailMsg("found no max.");
3514: } else {
3515: // make sure right last row in the last leaf found.
3516: long key = ((SQLLongint) template.getRow()[2]).getLong();
3517:
3518: if (key != 21) {
3519: throw T_Fail
3520: .testFailMsg("wrong last row in the last leaf found.");
3521: }
3522: }
3523:
3524: // +-----------------------------+-------------
3525: // |last row in the last leaf- table locked |
3526: // +-----------------------------+-------------
3527: //
3528: REPORT("last row in the last leaf, table locked.");
3529: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3530: TransactionController.MODE_TABLE,
3531: TransactionController.ISOLATION_READ_COMMITTED,
3532: (FormatableBitSet) null, template.getRow())) {
3533: throw T_Fail
3534: .testFailMsg("found no last row in the last leaf");
3535: } else {
3536: // make sure right min was found.
3537: long key = ((SQLLongint) template.getRow()[2]).getLong();
3538:
3539: if (key != 21) {
3540: throw T_Fail
3541: .testFailMsg("wrong last row in the last leaf found.");
3542: }
3543: }
3544:
3545: return (ret_val);
3546: }
3547:
3548: /**
3549: * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
3550: * BtreeScan.fetch() with alternating ascending and descending coulmn
3551: * sort order indexes.
3552: *
3553: * @exception StandardException Standard exception policy.
3554: * @exception T_Fail Throws T_Fail on any test failure.
3555: */
3556: protected boolean t_018(TransactionController tc)
3557: throws StandardException, T_Fail {
3558: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
3559:
3560: // base row template - last column is just to make row long so that
3561: // multiple pages are spanned.
3562: DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
3563: base_row[3] = new SQLChar();
3564:
3565: String string_1500char = new String();
3566: for (int i = 0; i < 300; i++)
3567: string_1500char += "mikem";
3568:
3569: boolean ret_val = true;
3570: long value = -1;
3571: long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9 };
3572: long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1 };
3573: long col3[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
3574:
3575: // set of deleted rows to make scans more interesting
3576: long d_col1[] = { 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12 };
3577: long d_col2[] = { 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1 };
3578: long d_col3[] = { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
3579: 102, 103, 104 };
3580:
3581: REPORT("Starting t_018");
3582:
3583: // create the base table
3584: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
3585: base_row, // base table template row
3586: null, //column sort order - not required for heap
3587: null, // default properties
3588: TransactionController.IS_DEFAULT); // not temporary
3589:
3590: // Open the base table
3591: ConglomerateController base_cc = tc.openConglomerate(
3592: base_conglomid, false,
3593: TransactionController.OPENMODE_FORUPDATE,
3594: TransactionController.MODE_RECORD,
3595: TransactionController.ISOLATION_SERIALIZABLE);
3596:
3597: // initialize the secondary index row - pointing it at base row
3598: index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
3599:
3600: Properties properties = createProperties(null, // no current properties list
3601: false, // don't allow duplicates
3602: 5, // 4 columns in index row
3603: 5, // non-unique index
3604: true, // maintain parent links
3605: base_conglomid, // base conglom id
3606: 4); // row loc in last column
3607:
3608: // create the index with all the columns in descending order
3609: ColumnOrdering order[] = new ColumnOrdering[5];
3610: order[0] = new T_ColumnOrderingImpl(0, true); // Ascending
3611: order[1] = new T_ColumnOrderingImpl(1, false); // descending
3612: order[2] = new T_ColumnOrderingImpl(2, true); // Ascending
3613: order[3] = new T_ColumnOrderingImpl(3, false); // descending
3614: order[4] = new T_ColumnOrderingImpl(4, true); // asccending
3615:
3616: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
3617: index_row.getRow(), // row template
3618: order, //column sort order - default
3619: properties, // properties
3620: TransactionController.IS_DEFAULT); // not temporary
3621:
3622: // Open the conglomerate.
3623: ConglomerateController index_cc = tc.openConglomerate(
3624: index_conglomid, false,
3625: TransactionController.OPENMODE_FORUPDATE,
3626: TransactionController.MODE_RECORD,
3627: TransactionController.ISOLATION_SERIALIZABLE);
3628:
3629: // Create a row.
3630: T_SecondaryIndexRow template = new T_SecondaryIndexRow();
3631: RowLocation row_loc = base_cc.newRowLocationTemplate();
3632: template.init(base_row, row_loc, 5);
3633:
3634: // insert them in reverse order just to make sure btree is sorting them
3635: for (int i = col1.length - 1; i >= 0; i--) {
3636: ((SQLLongint) (template.getRow()[0])).setValue(col1[i]);
3637: ((SQLLongint) (template.getRow()[1])).setValue(col2[i]);
3638: ((SQLLongint) (template.getRow()[2])).setValue(col3[i]);
3639: base_row[3] = new SQLChar(string_1500char);
3640:
3641: base_cc.insertAndFetchLocation(base_row, row_loc);
3642:
3643: // Insert the row.
3644: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
3645: // ")" + template);
3646: if (index_cc.insert(template.getRow()) != 0)
3647: throw T_Fail.testFailMsg("insert failed");
3648: }
3649:
3650: index_cc.checkConsistency();
3651:
3652: ((B2IController) index_cc).debugConglomerate();
3653:
3654: ret_val = t_ascdesc_scan_test_cases(tc, index_conglomid,
3655: template);
3656:
3657: // insert and delete some interesting rows, deleted space management
3658: // may or may not clean these up.
3659: for (int i = d_col1.length - 1; i >= 0; i--) {
3660: ((SQLLongint) (template.getRow()[0])).setValue(d_col1[i]);
3661: ((SQLLongint) (template.getRow()[1])).setValue(d_col2[i]);
3662: ((SQLLongint) (template.getRow()[2])).setValue(d_col3[i]);
3663: base_row[3] = new SQLChar(string_1500char);
3664:
3665: base_cc.insertAndFetchLocation(base_row, row_loc);
3666:
3667: // Insert the row.
3668: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
3669: // ")" + template);
3670: if (index_cc.insert(template.getRow()) != 0)
3671: throw T_Fail.testFailMsg("insert failed");
3672:
3673: // now delete the row.
3674: base_cc.delete(row_loc);
3675:
3676: ScanController delete_scan = tc.openScan(index_conglomid,
3677: false, TransactionController.OPENMODE_FORUPDATE,
3678: TransactionController.MODE_RECORD,
3679: TransactionController.ISOLATION_SERIALIZABLE,
3680: (FormatableBitSet) null, template.getRow(),
3681: ScanController.GE, null, template.getRow(),
3682: ScanController.GT);
3683:
3684: if (!delete_scan.next()) {
3685: throw T_Fail.testFailMsg("delete could not find key");
3686: } else {
3687: delete_scan.delete();
3688:
3689: if (delete_scan.next())
3690: throw T_Fail
3691: .testFailMsg("delete found more than one key");
3692: }
3693:
3694: delete_scan.close();
3695: }
3696:
3697: ret_val = t_ascdesc_scan_test_cases(tc, index_conglomid,
3698: template);
3699:
3700: // Close the conglomerate.
3701: index_cc.close();
3702:
3703: tc.commit();
3704: REPORT("Ending t_018");
3705:
3706: return (ret_val);
3707: }
3708:
3709: /* test cases for ASC DESC DESC ASC column sort order index
3710: SORTED DATA
3711: col1, col2, col3
3712: DS AS DS -- sort order
3713: 9, 1, 21
3714: 7, 1, 20
3715: 6, 1, 19
3716: 5, 2, 16
3717: 5, 4, 17
3718: 5, 6, 18
3719: 4, 2, 13
3720: 4, 4, 14
3721: 4, 6, 15
3722: 3, 1, 12
3723: 1, 1, 11
3724: */
3725: private boolean t_ascdesc1_scan_test_cases(
3726: TransactionController tc, long index_conglomid,
3727: T_SecondaryIndexRow template) throws StandardException,
3728: T_Fail {
3729: boolean ret_val = true;
3730:
3731: // run through a predicates as described in the openScan() interface //
3732: DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
3733: DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
3734:
3735: REPORT("scan (x = 5)");
3736: ((SQLLongint) start_key[0]).setValue(5);
3737: ((SQLLongint) stop_key[0]).setValue(5);
3738: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3739: .getRow(), template.getRow(), start_key,
3740: ScanController.GE, null, stop_key, ScanController.GT,
3741: 3, 16, T_QualifierTest.ORDER_FORWARD)) {
3742: ret_val = false;
3743: }
3744:
3745: REPORT("scan (x > 5)");
3746: ((SQLLongint) stop_key[0]).setValue(5);
3747: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3748: .getRow(), template.getRow(), null, ScanController.NA,
3749: null, stop_key, ScanController.GE, 3, 21,
3750: T_QualifierTest.ORDER_DESC)) {
3751: ret_val = false;
3752: }
3753:
3754: REPORT("scan (x >= 5)");
3755: ((SQLLongint) stop_key[0]).setValue(5);
3756: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3757: .getRow(), template.getRow(), null, ScanController.NA,
3758: null, stop_key, ScanController.GT, 6, 16,
3759: T_QualifierTest.ORDER_NONE)) {
3760: ret_val = false;
3761: }
3762:
3763: REPORT("scan (x <= 5)");
3764: ((SQLLongint) start_key[0]).setValue(5);
3765: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3766: .getRow(), template.getRow(), start_key,
3767: ScanController.GE, null, null, ScanController.NA, 8,
3768: 11, T_QualifierTest.ORDER_NONE)) {
3769: ret_val = false;
3770: }
3771:
3772: REPORT("scan (x < 5)");
3773: ((SQLLongint) start_key[0]).setValue(5);
3774: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3775: .getRow(), template.getRow(), start_key,
3776: ScanController.GT, null, null, ScanController.NA, 5,
3777: 11, T_QualifierTest.ORDER_NONE)) {
3778: ret_val = false;
3779: }
3780:
3781: REPORT("scan (x >= 5 and x <= 7)");
3782: ((SQLLongint) start_key[0]).setValue(7);
3783: ((SQLLongint) stop_key[0]).setValue(5);
3784: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3785: .getRow(), template.getRow(), start_key,
3786: ScanController.GE, null, stop_key, ScanController.GT,
3787: 5, 16, T_QualifierTest.ORDER_NONE)) {
3788: ret_val = false;
3789: }
3790:
3791: REPORT("scan (x = 5 and y > 2)");
3792: start_key = TemplateRow.newU8Row(2);
3793: stop_key = TemplateRow.newU8Row(1);
3794: ((SQLLongint) start_key[0]).setValue(5);
3795: ((SQLLongint) start_key[1]).setValue(2);
3796: ((SQLLongint) stop_key[0]).setValue(5);
3797: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3798: .getRow(), template.getRow(), start_key,
3799: ScanController.GT, null, stop_key, ScanController.GT,
3800: 2, 17, T_QualifierTest.ORDER_FORWARD)) {
3801: ret_val = false;
3802: }
3803:
3804: REPORT("scan (x = 5 and y >= 2)");
3805: start_key = TemplateRow.newU8Row(2);
3806: stop_key = TemplateRow.newU8Row(1);
3807: ((SQLLongint) start_key[0]).setValue(5);
3808: ((SQLLongint) start_key[1]).setValue(2);
3809: ((SQLLongint) stop_key[0]).setValue(5);
3810: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3811: .getRow(), template.getRow(), start_key,
3812: ScanController.GE, null, stop_key, ScanController.GT,
3813: 3, 16, T_QualifierTest.ORDER_FORWARD)) {
3814: ret_val = false;
3815: }
3816:
3817: REPORT("scan (x = 5 and y < 5)");
3818: start_key = TemplateRow.newU8Row(1);
3819: stop_key = TemplateRow.newU8Row(2);
3820: ((SQLLongint) start_key[0]).setValue(5);
3821: ((SQLLongint) stop_key[0]).setValue(5);
3822: ((SQLLongint) stop_key[1]).setValue(5);
3823:
3824: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3825: .getRow(), template.getRow(), start_key,
3826: ScanController.GE, null, stop_key, ScanController.GT,
3827: 2, 16, T_QualifierTest.ORDER_FORWARD)) {
3828: ret_val = false;
3829: }
3830:
3831: REPORT("scan (x = 2)");
3832: start_key = TemplateRow.newU8Row(1);
3833: stop_key = TemplateRow.newU8Row(1);
3834: ((SQLLongint) start_key[0]).setValue(2);
3835: ((SQLLongint) stop_key[0]).setValue(2);
3836: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3837: .getRow(), template.getRow(), start_key,
3838: ScanController.GE, null, stop_key, ScanController.GT,
3839: 0, 0, T_QualifierTest.ORDER_DESC)) {
3840: ret_val = false;
3841: }
3842:
3843: // values '2' does not exist as such in the data set
3844: REPORT("scan (x > 2)");
3845: stop_key = TemplateRow.newU8Row(1);
3846: ((SQLLongint) stop_key[0]).setValue(2);
3847: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3848: .getRow(), template.getRow(), null, ScanController.NA,
3849: null, stop_key, ScanController.GE, 10, 12,
3850: T_QualifierTest.ORDER_NONE)) {
3851: ret_val = false;
3852: }
3853:
3854: // values '2' does not exist as such in the data set
3855: REPORT("scan (x >= 2)");
3856: stop_key = TemplateRow.newU8Row(1);
3857: ((SQLLongint) stop_key[0]).setValue(2);
3858: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3859: .getRow(), template.getRow(), null, ScanController.NA,
3860: null, stop_key, ScanController.GT, 10, 12,
3861: T_QualifierTest.ORDER_NONE)) {
3862: ret_val = false;
3863: }
3864:
3865: // values '2' does not exist as such in the data set
3866: REPORT("scan (x < 2)");
3867: start_key = TemplateRow.newU8Row(1);
3868: ((SQLLongint) start_key[0]).setValue(2);
3869: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3870: .getRow(), template.getRow(), start_key,
3871: ScanController.GT, null, null, ScanController.NA, 1,
3872: 11, T_QualifierTest.ORDER_NONE)) {
3873: ret_val = false;
3874: }
3875:
3876: // values '2' does not exist as such in the data set
3877: REPORT("scan (x <= 2)");
3878: start_key = TemplateRow.newU8Row(1);
3879: ((SQLLongint) start_key[0]).setValue(2);
3880: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3881: .getRow(), template.getRow(), start_key,
3882: ScanController.GE, null, null, ScanController.NA, 1,
3883: 11, T_QualifierTest.ORDER_NONE)) {
3884: ret_val = false;
3885: }
3886:
3887: REPORT("scan (x >= 2 and x <= 7)");
3888: ((SQLLongint) start_key[0]).setValue(7);
3889: ((SQLLongint) stop_key[0]).setValue(2);
3890: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3891: .getRow(), template.getRow(), start_key,
3892: ScanController.GE, null, stop_key, ScanController.GT,
3893: 9, 12, T_QualifierTest.ORDER_NONE)) {
3894: ret_val = false;
3895: }
3896:
3897: REPORT("scan (x = 2 and y > 2)");
3898: start_key = TemplateRow.newU8Row(2);
3899: stop_key = TemplateRow.newU8Row(1);
3900: ((SQLLongint) start_key[0]).setValue(2);
3901: ((SQLLongint) start_key[1]).setValue(2);
3902: ((SQLLongint) stop_key[0]).setValue(2);
3903: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3904: .getRow(), template.getRow(), start_key,
3905: ScanController.GT, null, stop_key, ScanController.GT,
3906: 0, 0, T_QualifierTest.ORDER_NONE)) {
3907: ret_val = false;
3908: }
3909:
3910: REPORT("scan (x = 2 and y >= 2)");
3911: start_key = TemplateRow.newU8Row(2);
3912: stop_key = TemplateRow.newU8Row(1);
3913: ((SQLLongint) start_key[0]).setValue(2);
3914: ((SQLLongint) start_key[1]).setValue(2);
3915: ((SQLLongint) stop_key[0]).setValue(2);
3916: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3917: .getRow(), template.getRow(), start_key,
3918: ScanController.GE, null, stop_key, ScanController.GT,
3919: 0, 0, T_QualifierTest.ORDER_NONE)) {
3920: ret_val = false;
3921: }
3922:
3923: REPORT("scan (x = 4 and y <=2)");
3924: start_key = TemplateRow.newU8Row(1);
3925: stop_key = TemplateRow.newU8Row(2);
3926: ((SQLLongint) start_key[0]).setValue(4);
3927: ((SQLLongint) stop_key[0]).setValue(4);
3928: ((SQLLongint) stop_key[1]).setValue(2);
3929:
3930: if (!T_QualifierTest.t_scan(tc, index_conglomid, template
3931: .getRow(), template.getRow(), start_key,
3932: ScanController.GE, null, stop_key, ScanController.GT,
3933: 1, 13, T_QualifierTest.ORDER_DESC)) {
3934: ret_val = false;
3935: }
3936:
3937: // +-----------------------------+---------------
3938: // |last leaf last row on btree - row locked |
3939: // +-----------------------------+---------------
3940: //
3941: REPORT("last row in the last leaf, row locked.");
3942:
3943: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3944: TransactionController.MODE_RECORD,
3945: TransactionController.ISOLATION_SERIALIZABLE,
3946: (FormatableBitSet) null, template.getRow())) {
3947: throw T_Fail
3948: .testFailMsg("found last row in the last leaf.");
3949: } else {
3950: // make sure right min was found.
3951: long key = ((SQLLongint) template.getRow()[2]).getLong();
3952:
3953: if (key != 11) {
3954: throw T_Fail
3955: .testFailMsg("wrong last row in the last leaf.");
3956: }
3957: }
3958:
3959: // +-----------------------------+--------------
3960: // |last row in the last leaf - table locked |
3961: // +-----------------------------+--------------
3962: //
3963: REPORT("last row in the last leaf, table locked.");
3964: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3965: TransactionController.MODE_TABLE,
3966: TransactionController.ISOLATION_SERIALIZABLE,
3967: (FormatableBitSet) null, template.getRow())) {
3968: throw T_Fail.testFailMsg("found no min.");
3969: } else {
3970: // make sure right last row in the last leaf found.
3971: long key = ((SQLLongint) template.getRow()[2]).getLong();
3972:
3973: if (key != 11) {
3974: throw T_Fail
3975: .testFailMsg("wrong last row in the last leaf found.");
3976: }
3977: }
3978:
3979: // +-----------------------------+-----------
3980: // |last row in the last leaf- row locked |
3981: // +-----------------------------+-----------
3982: //
3983: REPORT("last row in the last leaf, row locked.");
3984: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
3985: TransactionController.MODE_RECORD,
3986: TransactionController.ISOLATION_READ_COMMITTED,
3987: (FormatableBitSet) null, template.getRow())) {
3988: throw T_Fail.testFailMsg("found no max.");
3989: } else {
3990: // make sure right last row in the last leaf found.
3991: long key = ((SQLLongint) template.getRow()[2]).getLong();
3992:
3993: if (key != 11) {
3994: throw T_Fail
3995: .testFailMsg("wrong last row in the last leaf found.");
3996: }
3997: }
3998:
3999: // +-----------------------------+-------------
4000: // |last row in the last leaf- table locked |
4001: // +-----------------------------+-------------
4002: //
4003: REPORT("last row in the last leaf, table locked.");
4004: if (!tc.fetchMaxOnBtree(index_conglomid, 0,
4005: TransactionController.MODE_TABLE,
4006: TransactionController.ISOLATION_READ_COMMITTED,
4007: (FormatableBitSet) null, template.getRow())) {
4008: throw T_Fail
4009: .testFailMsg("found no last row in the last leaf");
4010: } else {
4011: // make sure right min was found.
4012: long key = ((SQLLongint) template.getRow()[2]).getLong();
4013:
4014: if (key != 11) {
4015: throw T_Fail
4016: .testFailMsg("wrong last row in the last leaf found.");
4017: }
4018: }
4019:
4020: return (ret_val);
4021: }
4022:
4023: /**
4024: * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
4025: * BtreeScan.fetch() with alternating ascending and descending coulmn
4026: * sort order indexes.
4027: *
4028: * @exception StandardException Standard exception policy.
4029: * @exception T_Fail Throws T_Fail on any test failure.
4030: */
4031: protected boolean t_019(TransactionController tc)
4032: throws StandardException, T_Fail {
4033: T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
4034:
4035: // base row template - last column is just to make row long so that
4036: // multiple pages are spanned.
4037: DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
4038: base_row[3] = new SQLChar();
4039:
4040: String string_1500char = new String();
4041: for (int i = 0; i < 300; i++)
4042: string_1500char += "mikem";
4043:
4044: boolean ret_val = true;
4045: long value = -1;
4046: long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9 };
4047: long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1 };
4048: long col3[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
4049:
4050: // set of deleted rows to make scans more interesting
4051: long d_col1[] = { 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12 };
4052: long d_col2[] = { 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1 };
4053: long d_col3[] = { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
4054: 102, 103, 104 };
4055:
4056: REPORT("Starting t_019");
4057:
4058: // create the base table
4059: long base_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
4060: base_row, // base table template row
4061: null, //column sort order - not required for heap
4062: null, // default properties
4063: TransactionController.IS_DEFAULT); // not temporary
4064:
4065: // Open the base table
4066: ConglomerateController base_cc = tc.openConglomerate(
4067: base_conglomid, false,
4068: TransactionController.OPENMODE_FORUPDATE,
4069: TransactionController.MODE_RECORD,
4070: TransactionController.ISOLATION_SERIALIZABLE);
4071:
4072: // initialize the secondary index row - pointing it at base row
4073: index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
4074:
4075: Properties properties = createProperties(null, // no current properties list
4076: false, // don't allow duplicates
4077: 5, // 4 columns in index row
4078: 5, // non-unique index
4079: true, // maintain parent links
4080: base_conglomid, // base conglom id
4081: 4); // row loc in last column
4082:
4083: // create the index with all the columns in descending order
4084: ColumnOrdering order[] = new ColumnOrdering[5];
4085: order[0] = new T_ColumnOrderingImpl(0, false); // Descending
4086: order[1] = new T_ColumnOrderingImpl(1, true); // Ascending
4087: order[2] = new T_ColumnOrderingImpl(2, true); // Ascending
4088: order[3] = new T_ColumnOrderingImpl(3, false); // descending
4089: order[4] = new T_ColumnOrderingImpl(4, true); // asccending
4090:
4091: long index_conglomid = tc.createConglomerate("BTREE", // create a btree secondary
4092: index_row.getRow(), // row template
4093: order, //column sort order - default
4094: properties, // properties
4095: TransactionController.IS_DEFAULT); // not temporary
4096:
4097: // Open the conglomerate.
4098: ConglomerateController index_cc = tc.openConglomerate(
4099: index_conglomid, false,
4100: TransactionController.OPENMODE_FORUPDATE,
4101: TransactionController.MODE_RECORD,
4102: TransactionController.ISOLATION_SERIALIZABLE);
4103:
4104: // Create a row.
4105: T_SecondaryIndexRow template = new T_SecondaryIndexRow();
4106: RowLocation row_loc = base_cc.newRowLocationTemplate();
4107: template.init(base_row, row_loc, 5);
4108:
4109: // insert them in reverse order just to make sure btree is sorting them
4110: for (int i = col1.length - 1; i >= 0; i--) {
4111: ((SQLLongint) (template.getRow()[0])).setValue(col1[i]);
4112: ((SQLLongint) (template.getRow()[1])).setValue(col2[i]);
4113: ((SQLLongint) (template.getRow()[2])).setValue(col3[i]);
4114: base_row[3] = new SQLChar(string_1500char);
4115:
4116: base_cc.insertAndFetchLocation(base_row, row_loc);
4117:
4118: // Insert the row.
4119: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
4120: // ")" + template);
4121: if (index_cc.insert(template.getRow()) != 0)
4122: throw T_Fail.testFailMsg("insert failed");
4123: }
4124:
4125: index_cc.checkConsistency();
4126:
4127: ((B2IController) index_cc).debugConglomerate();
4128:
4129: ret_val = t_ascdesc1_scan_test_cases(tc, index_conglomid,
4130: template);
4131:
4132: // insert and delete some interesting rows, deleted space management
4133: // may or may not clean these up.
4134: for (int i = d_col1.length - 1; i >= 0; i--) {
4135: ((SQLLongint) (template.getRow()[0])).setValue(d_col1[i]);
4136: ((SQLLongint) (template.getRow()[1])).setValue(d_col2[i]);
4137: ((SQLLongint) (template.getRow()[2])).setValue(d_col3[i]);
4138: base_row[3] = new SQLChar(string_1500char);
4139:
4140: base_cc.insertAndFetchLocation(base_row, row_loc);
4141:
4142: // Insert the row.
4143: // System.out.println("Adding record (" + -(i - (col1.length -1)) +
4144: // ")" + template);
4145: if (index_cc.insert(template.getRow()) != 0)
4146: throw T_Fail.testFailMsg("insert failed");
4147:
4148: // now delete the row.
4149: base_cc.delete(row_loc);
4150:
4151: ScanController delete_scan = tc.openScan(index_conglomid,
4152: false, TransactionController.OPENMODE_FORUPDATE,
4153: TransactionController.MODE_RECORD,
4154: TransactionController.ISOLATION_SERIALIZABLE,
4155: (FormatableBitSet) null, template.getRow(),
4156: ScanController.GE, null, template.getRow(),
4157: ScanController.GT);
4158:
4159: if (!delete_scan.next()) {
4160: throw T_Fail.testFailMsg("delete could not find key");
4161: } else {
4162: delete_scan.delete();
4163:
4164: if (delete_scan.next())
4165: throw T_Fail
4166: .testFailMsg("delete found more than one key");
4167: }
4168:
4169: delete_scan.close();
4170: }
4171:
4172: ret_val = t_ascdesc1_scan_test_cases(tc, index_conglomid,
4173: template);
4174:
4175: // Close the conglomerate.
4176: index_cc.close();
4177:
4178: tc.commit();
4179: REPORT("Ending t_019");
4180:
4181: return (ret_val);
4182: }
4183:
4184: /**
4185: * Test read uncommitted cases on scan.
4186: * <p>
4187: *
4188: * @exception StandardException Standard exception policy.
4189: * @exception T_Fail Throws T_Fail on any test failure.
4190: **/
4191: protected boolean t_020(TransactionController tc)
4192: throws StandardException, T_Fail {
4193: ScanController scan = null;
4194:
4195: REPORT("Starting t_020");
4196:
4197: T_CreateConglomRet create_ret = new T_CreateConglomRet();
4198:
4199: // Create the btree so that it only allows 2 rows per page.
4200: createCongloms(tc, 2, false, false, 2, create_ret);
4201:
4202: // Open the base table
4203: ConglomerateController base_cc = tc.openConglomerate(
4204: create_ret.base_conglomid, false,
4205: TransactionController.OPENMODE_FORUPDATE,
4206: TransactionController.MODE_RECORD,
4207: TransactionController.ISOLATION_SERIALIZABLE);
4208:
4209: // Open the secondary index
4210: ConglomerateController index_cc = tc.openConglomerate(
4211: create_ret.index_conglomid, false,
4212: TransactionController.OPENMODE_FORUPDATE,
4213: TransactionController.MODE_RECORD,
4214: TransactionController.ISOLATION_SERIALIZABLE);
4215:
4216: // objects used to insert rows into base and index tables.
4217: DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
4218: T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
4219: RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
4220:
4221: index_row1.init(r1, base_rowloc1, 3);
4222:
4223: // insert one row into the table/index
4224:
4225: // Open the base table
4226: base_cc = tc.openConglomerate(create_ret.base_conglomid, false,
4227: TransactionController.OPENMODE_FORUPDATE,
4228: TransactionController.MODE_RECORD,
4229: TransactionController.ISOLATION_SERIALIZABLE);
4230:
4231: // Open the secondary index
4232: index_cc = tc.openConglomerate(create_ret.index_conglomid,
4233: false, TransactionController.OPENMODE_FORUPDATE,
4234: TransactionController.MODE_RECORD,
4235: TransactionController.ISOLATION_SERIALIZABLE);
4236:
4237: // insert one row that does not cause failure.
4238: ((SQLLongint) r1[0]).setValue(2);
4239: ((SQLLongint) r1[1]).setValue(10000);
4240:
4241: // Insert the row into the base table;remember its location.
4242: base_cc.insertAndFetchLocation(r1, base_rowloc1);
4243:
4244: // Insert the row into the secondary index.
4245: if (index_cc.insert(index_row1.getRow()) != 0)
4246: throw T_Fail.testFailMsg("insert failed");
4247:
4248: // Commit the create of the tables so that the following aborts don't
4249: // undo that work.
4250: tc.commit();
4251:
4252: // TEST 1 - position a read uncommitted scan on a row which is
4253: // purged by a split trying to get space on the page, and then see
4254: // what happens when the scan trys to continue. This can only happen
4255: // currently if the same transaction deletes the row and while having
4256: // the scan open also does inserts onto the same page. Otherwise the
4257: // btree scan will maintain a "page scan locks" which will prevent
4258: // the row from being purged out from underneath it.
4259:
4260: tc.commit();
4261: REPORT("Ending t_020");
4262:
4263: return true;
4264: }
4265:
4266: public static String repeatString(String data, int repeat) {
4267:
4268: String s = data;
4269: for (int i = 1; i < repeat; i++)
4270: s += data;
4271:
4272: return s;
4273: }
4274:
4275: }
4276:
4277: class T_CreateConglomRet {
4278: public long base_conglomid;
4279: public long index_conglomid;
4280: // public DataValueDescriptor[] base_template_row;
4281: public DataValueDescriptor[] index_template_row;
4282: }
|