Source Code Cross Referenced for T_RawStoreFactory.java in  » Database-DBMS » db-derby-10.2 » org » apache » derbyTesting » unitTests » store » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derbyTesting.unitTests.store 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derbyTesting.unitTests.store.T_RawStoreFactory
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:        import org.apache.derby.iapi.store.raw.*;
0025:
0026:        // impl imports are the preferred way to create unit tests.
0027:        import org.apache.derbyTesting.unitTests.harness.T_MultiThreadedIterations;
0028:        import org.apache.derbyTesting.unitTests.harness.T_Fail;
0029:
0030:        import org.apache.derby.iapi.services.context.ContextService;
0031:        import org.apache.derby.iapi.services.context.ContextManager;
0032:        import org.apache.derby.iapi.services.locks.*;
0033:        import org.apache.derby.iapi.services.monitor.Monitor;
0034:        import org.apache.derby.iapi.services.sanity.SanityManager;
0035:        import org.apache.derby.iapi.services.uuid.UUIDFactory;
0036:        import org.apache.derby.catalog.UUID;
0037:        import org.apache.derby.iapi.services.property.PropertyUtil;
0038:        import org.apache.derby.iapi.error.ExceptionSeverity;
0039:        import org.apache.derby.iapi.error.StandardException;
0040:
0041:        import org.apache.derby.iapi.store.access.*;
0042:        import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
0043:
0044:        import org.apache.derby.iapi.store.raw.xact.RawTransaction;
0045:        import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
0046:        import org.apache.derby.iapi.store.raw.log.LogInstant;
0047:
0048:        import org.apache.derby.iapi.types.DataValueDescriptor;
0049:
0050:        // impl a logInstant implemented as log counter to test truncateLWMs
0051:        import org.apache.derby.impl.store.raw.log.LogCounter;
0052:
0053:        import org.apache.derby.iapi.types.SQLChar;
0054:
0055:        import org.apache.derby.iapi.reference.Property;
0056:
0057:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0058:
0059:        import java.io.*;
0060:        import java.util.Properties;
0061:
0062:        /**
0063:         A protocol unit test for the RawStore interface.
0064:         */
0065:
0066:        public class T_RawStoreFactory extends T_MultiThreadedIterations {
0067:
0068:            static protected final String REC_001 = "McLaren";
0069:            static protected final String REC_002 = "Ferrari";
0070:            static protected final String REC_003 = "Benetton";
0071:            static protected final String REC_004 = "Prost";
0072:            static protected final String REC_005 = "Tyrell";
0073:            static protected final String REC_006 = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
0074:            static protected final String REC_007 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
0075:            static protected final String REC_008 = "z";
0076:            static protected final String REC_009 = "nanonano";
0077:            static protected final String REC_010 = "fuzzbutt";
0078:            static protected final String REC_011 = "mork";
0079:            static protected final String REC_012 = "orson";
0080:            static protected final String REC_013 = "mindy";
0081:            static protected final String REC_014 = "thomas";
0082:            static protected final String REC_015 = "henry";
0083:            static protected final String REC_016 = "gordon";
0084:            static protected final String REC_017 = "mavis";
0085:            static protected final String REC_018 = "fatcontroller";
0086:            static protected final String REC_UNDO = "Lotus";
0087:            static protected final String REC_NULL = "NULL";
0088:
0089:            static final FormatableBitSet BS_COL_0 = new FormatableBitSet(1);
0090:
0091:            static protected final String SP1 = "savepoint1";
0092:            static protected final String SP2 = "savepoint2";
0093:
0094:            private static final String TEST_ROLLBACK_OFF = "derby.RawStore.RollbackTestOff";
0095:
0096:            private static boolean testRollbackProperty;// initialize in start
0097:            static protected boolean testRollback; // each thread has its own test rollback value
0098:
0099:            static protected RawStoreFactory factory;
0100:            static protected LockFactory lf;
0101:            static protected ContextService contextService;
0102:
0103:            static protected UUIDFactory uuidfactory;
0104:            protected T_Util t_util;
0105:            protected int openMode; // mode flags used in all open containers.
0106:            protected boolean logDataForPurges = true; //used to test non-logged data purges
0107:
0108:            public T_RawStoreFactory() {
0109:                super ();
0110:                BS_COL_0.set(0);
0111:            }
0112:
0113:            /**
0114:              @exception StandardException cannot startup the context service
0115:             */
0116:            public void boot(boolean create, Properties startParams)
0117:                    throws StandardException {
0118:                super .boot(create, startParams);
0119:                contextService = ContextService.getFactory();
0120:            }
0121:
0122:            /*
0123:             ** Methods required by T_Generic
0124:             */
0125:
0126:            protected String getModuleToTestProtocolName() {
0127:                return RawStoreFactory.MODULE;
0128:            }
0129:
0130:            /**
0131:            	Set up test
0132:
0133:            	@exception T_Fail Unexpected behaviour from the API
0134:             */
0135:            protected void setupTest() throws T_Fail {
0136:
0137:                String rollbackOff = PropertyUtil
0138:                        .getSystemProperty(TEST_ROLLBACK_OFF);
0139:                testRollback = !Boolean.valueOf(rollbackOff).booleanValue();
0140:
0141:                testRollbackProperty = testRollback; // testRollbackProperty never changes
0142:
0143:                // don't automatic boot this service if it gets left around
0144:                if (startParams == null) {
0145:                    startParams = new Properties();
0146:                }
0147:                startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
0148:                // remove the service directory to ensure a clean run
0149:                startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE
0150:                        .toString());
0151:
0152:                // see if we are testing encryption
0153:                startParams = T_Util.setEncryptionParam(startParams);
0154:
0155:                try {
0156:
0157:                    factory = (RawStoreFactory) Monitor
0158:                            .createPersistentService(
0159:                                    getModuleToTestProtocolName(),
0160:                                    getTestService(), startParams);
0161:
0162:                    if (factory == null) {
0163:                        throw T_Fail.testFailMsg(getModuleToTestProtocolName()
0164:                                + " service not started.");
0165:                    }
0166:
0167:                    lf = factory.getLockFactory();
0168:                    if (lf == null) {
0169:                        throw T_Fail
0170:                                .testFailMsg("LockFactory.MODULE not found");
0171:                    }
0172:
0173:                    uuidfactory = Monitor.getMonitor().getUUIDFactory();
0174:
0175:                } catch (StandardException mse) {
0176:                    throw T_Fail.exceptionFail(mse);
0177:                }
0178:
0179:                REPORT("testRollback=" + testRollback);
0180:
0181:                return;
0182:            }
0183:
0184:            protected String getTestService() {
0185:                return "rawStoreTest";
0186:            }
0187:
0188:            /**
0189:             * T_MultiThreadedIteration method
0190:             *
0191:             * @exception T_Fail Unexpected behaviour from the API
0192:             */
0193:            protected void joinSetupTest() throws T_Fail {
0194:
0195:                T_Fail
0196:                        .T_ASSERT(factory != null,
0197:                                "raw store factory not setup ");
0198:                T_Fail.T_ASSERT(lf != null, "Lock factory not setup ");
0199:                T_Fail.T_ASSERT(contextService != null,
0200:                        "Context service not setup ");
0201:
0202:                testRollback = testRollbackProperty;
0203:
0204:            }
0205:
0206:            protected T_MultiThreadedIterations newTestObject() {
0207:                try {
0208:                    Class this Class = this .getClass();
0209:                    return (T_MultiThreadedIterations) (this Class.newInstance());
0210:                } catch (InstantiationException ie) {
0211:                    return new T_RawStoreFactory();
0212:                } catch (IllegalAccessException iae) {
0213:                    return new T_RawStoreFactory();
0214:                }
0215:            }
0216:
0217:            /**
0218:              run the test
0219:
0220:              @exception T_Fail Unexpected behaviour from the API
0221:             */
0222:            protected void runTestSet() throws T_Fail {
0223:
0224:                // get a utility helper
0225:                t_util = new T_Util(factory, lf, contextService);
0226:
0227:                ContextManager cm1 = contextService.newContextManager();
0228:                contextService.setCurrentContextManager(cm1);
0229:
0230:                try {
0231:
0232:                    // Run the tests with data not logged for purges.
0233:                    REPORT("Running tests with no data logged  for purges");
0234:                    openMode = 0; // logged by default
0235:                    runPurgeWithNoDataLoggesTests();
0236:
0237:                    // Run the tests in normal logged mode
0238:                    REPORT("Running tests with logging requested");
0239:                    openMode = 0; // logged by default
0240:                    runEachTest();
0241:
0242:                    // run the tests on temp tables
0243:                    REPORT("Running tests for temp tables");
0244:                    testRollback = false; // obviously, we can't test rollback if we are not logging
0245:                    runTempTests();
0246:
0247:                    // Run the tests in unlogged mode
0248:                    REPORT("Running tests in unlogged mode");
0249:                    openMode = ContainerHandle.MODE_UNLOGGED
0250:                            | ContainerHandle.MODE_CREATE_UNLOGGED;
0251:                    testRollback = false; // obviously, we can't test rollback if we are not logging
0252:                    runEachTest();
0253:
0254:                    // if more runs are added here then you probably want to reset testRollback to
0255:                    // its initial value, or add the runs before the unlogged mode.
0256:
0257:                } catch (StandardException se) {
0258:
0259:                    cm1.cleanupOnError(se);
0260:                    throw T_Fail.exceptionFail(se);
0261:                } finally {
0262:                    contextService.resetCurrentContextManager(cm1);
0263:                }
0264:            }
0265:
0266:            protected void runEachTest() throws T_Fail, StandardException {
0267:
0268:                t_util.setOpenMode(openMode);
0269:
0270:                // Transaction tests
0271:                T000();
0272:                T001();
0273:                T002();
0274:                T003();
0275:                T004();
0276:                T005();
0277:                T006();
0278:                T007();
0279:                T008();
0280:                T009();
0281:                T010();
0282:                T011();
0283:                T012();
0284:
0285:                // ContainerHandle tests
0286:                C010(0);
0287:                C011();
0288:                C012(1);
0289:                C014();
0290:                C200();
0291:                C201(0);
0292:                C201(1);
0293:
0294:                // Page tests
0295:                P001(0);
0296:                P002(0);
0297:                P003(0);
0298:                P004(0);
0299:                P005(0);
0300:                P006();
0301:                P007(0);
0302:                P008(0);
0303:                P009(0);
0304:                P011(0);
0305:                P012(0);
0306:                P013();
0307:                P014();
0308:                P015();
0309:                P016();
0310:                P017();
0311:                P018();
0312:                P019(); // test addPage with preallocation turned on
0313:                P020(); // test createContainer with initialPage set to 10 pages
0314:                P021(); // test preAllocate
0315:                P022();
0316:                P023(0); // overflowThreshold test
0317:
0318:                // long row tests
0319:                P030(0);
0320:                P031(0);
0321:                P032(0);
0322:                P033(0);
0323:                P034(0);
0324:
0325:                P035(0); // long column test
0326:
0327:                //run  the following test because they do lot of checks 
0328:                //on rollbacking when contyainer is unlogged nothing is rolled back
0329:                if ((openMode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED) {
0330:                    openMode = 0; //run them as logged for time being
0331:                    t_util.setOpenMode(openMode);
0332:                }
0333:
0334:                // reclaiming space from long column and long rows - temp container
0335:                // row space is not reclaimed.
0336:                P036();
0337:                P037();
0338:                P038();
0339:                P039();
0340:                P040();
0341:                P041();
0342:                P042();
0343:                P043();
0344:
0345:                P050(); // rollback tests
0346:                P051();
0347:                P052();
0348:                P053();
0349:                P054();
0350:                P055(0);
0351:                P056(0);
0352:
0353:                P061(); // sparse row test
0354:
0355:                P071(); // serializable column test
0356:
0357:                // update/update partial tests with long rows
0358:                P701(0);
0359:                P702(0);
0360:                P703(0);
0361:                P704(0);
0362:                P705(0);
0363:
0364:                P706(0, false);
0365:                P706(0, true);
0366:                P707(0);
0367:                P708(0, false);
0368:                P708(0, true);
0369:
0370:                L001(); // large log record test
0371:
0372:                // checkpoint test
0373:                CP001();
0374:            }
0375:
0376:            protected void runTempTests() throws T_Fail, StandardException {
0377:
0378:                REPORT("Thread " + threadNumber + " entering temp tests ");
0379:
0380:                openMode = 0; // logged by default
0381:                t_util.setOpenMode(openMode); // logged mode should be overriden for temp tables
0382:
0383:                // now tests for temporary tables
0384:
0385:                C010(ContainerHandle.TEMPORARY_SEGMENT);
0386:                C012(ContainerHandle.TEMPORARY_SEGMENT);
0387:                //P001(ContainerHandle.TEMPORARY_SEGMENT);
0388:                //P002(ContainerHandle.TEMPORARY_SEGMENT);
0389:                P003(ContainerHandle.TEMPORARY_SEGMENT);
0390:                P004(ContainerHandle.TEMPORARY_SEGMENT);
0391:                P005(ContainerHandle.TEMPORARY_SEGMENT);
0392:                P011(ContainerHandle.TEMPORARY_SEGMENT);
0393:                P012(ContainerHandle.TEMPORARY_SEGMENT);
0394:                P030(ContainerHandle.TEMPORARY_SEGMENT);
0395:
0396:                // update/update partial tests with long rows
0397:                P055(ContainerHandle.TEMPORARY_SEGMENT);
0398:                P056(ContainerHandle.TEMPORARY_SEGMENT);
0399:
0400:                P701(ContainerHandle.TEMPORARY_SEGMENT);
0401:                P702(ContainerHandle.TEMPORARY_SEGMENT);
0402:                P703(ContainerHandle.TEMPORARY_SEGMENT);
0403:                P704(ContainerHandle.TEMPORARY_SEGMENT);
0404:                P705(ContainerHandle.TEMPORARY_SEGMENT);
0405:                P706(ContainerHandle.TEMPORARY_SEGMENT, false);
0406:                P706(ContainerHandle.TEMPORARY_SEGMENT, true);
0407:                P707(ContainerHandle.TEMPORARY_SEGMENT);
0408:
0409:                // tests specific to temp tables
0410:
0411:                // checking truncate at commit/rollback works
0412:                TC001();
0413:                TC002(ContainerHandle.MODE_TRUNCATE_ON_COMMIT, true);
0414:                TC002(ContainerHandle.MODE_TRUNCATE_ON_COMMIT, false);
0415:                TC002(0, false);
0416:
0417:                // checking an explict drop works ...
0418:                TC003(ContainerHandle.MODE_TRUNCATE_ON_COMMIT, true);
0419:                TC003(ContainerHandle.MODE_TRUNCATE_ON_COMMIT, false);
0420:                TC003(0, false);
0421:                TC003(0, true);
0422:                TC003(ContainerHandle.MODE_DROP_ON_COMMIT, true);
0423:                TC003(ContainerHandle.MODE_DROP_ON_COMMIT, false);
0424:
0425:                // various combinations of opens ...
0426:                TC004all();
0427:
0428:                REPORT("Thread " + threadNumber + " exiting temp tests ");
0429:            }
0430:
0431:            protected void runPurgeWithNoDataLoggesTests() throws T_Fail,
0432:                    StandardException {
0433:
0434:                REPORT("Thread " + threadNumber
0435:                        + " entering purges with no data logged tests ");
0436:                logDataForPurges = false;
0437:                P005(0);
0438:                P006();
0439:                P014();
0440:                P036();
0441:                P037();
0442:                P709();
0443:                P710();
0444:                P711();
0445:                REPORT("Thread " + threadNumber
0446:                        + " exiting purge with no data logged tests ");
0447:                logDataForPurges = true;
0448:            }
0449:
0450:            /*
0451:             ** The tests
0452:             **		Tnnn indicates a test that is mainly testing the Transaction interface
0453:             **		Cnnn indicates a test that is mainly testing the ContainerHandle interface
0454:             **		Pnnn indicates a test that is mainly testing the Page interface
0455:             **
0456:             **	nnn < 200 tends to indicate purely API tests, ie checking methods
0457:             **		are callable and return the right value. This includes negative tests.
0458:             **
0459:             **  nnn >= 200 tends to indicate more involved tests, ie ones that test the
0460:             **			methods actually did something.
0461:
0462:             */
0463:
0464:            /**
0465:            	T000 - ensure a transaction starts out idle.
0466:
0467:            	@exception T_Fail Unexpected behaviour from the API
0468:            	@exception StandardException Unexpected exception from the implementation
0469:             */
0470:            protected void T000() throws T_Fail, StandardException {
0471:
0472:                Transaction t1 = t_util.t_startTransaction();
0473:
0474:                t1.close();
0475:
0476:                t1 = t_util.t_startInternalTransaction();
0477:
0478:                t1.close();
0479:
0480:                t1 = t_util.t_startTransaction();
0481:                Transaction ti = t_util.t_startInternalTransaction();
0482:
0483:                ti.close();
0484:
0485:                t1.close();
0486:
0487:                PASS("T000");
0488:            }
0489:
0490:            /**
0491:            	T001 - start and commit an empty transaction.
0492:
0493:            	@exception T_Fail Unexpected behaviour from the API
0494:            	@exception StandardException Unexpected exception from the implementation
0495:             */
0496:            protected void T001() throws T_Fail, StandardException {
0497:
0498:                Transaction t1 = t_util.t_startTransaction();
0499:
0500:                t_util.t_commit(t1);
0501:
0502:                t1.close();
0503:
0504:                PASS("T001");
0505:            }
0506:
0507:            /**
0508:            	T002 - start and abort an empty transaction.
0509:
0510:            	@exception T_Fail Unexpected behaviour from the API
0511:            	@exception StandardException Unexpected exception from the implementation
0512:             */
0513:            protected void T002() throws T_Fail, StandardException {
0514:
0515:                Transaction t1 = t_util.t_startTransaction();
0516:
0517:                t_util.t_abort(t1);
0518:
0519:                t1.close();
0520:
0521:                PASS("T002");
0522:            }
0523:
0524:            /**
0525:            	T003 - start and commit an empty transaction and then ensure
0526:            	that the transaction remains open for another commit.
0527:
0528:            	@exception T_Fail Unexpected behaviour from the API
0529:            	@exception StandardException Unexpected exception from the implementation
0530:             */
0531:            protected void T003() throws T_Fail, StandardException {
0532:
0533:                Transaction t1 = t_util.t_startTransaction();
0534:
0535:                t_util.t_commit(t1);
0536:
0537:                t_util.t_commit(t1);
0538:                t_util.t_abort(t1);
0539:
0540:                t1.close();
0541:
0542:                PASS("T003");
0543:            }
0544:
0545:            /**
0546:            	T004 - start and abort an empty transaction and then ensure
0547:            	that the transaction remains open for a commit and another abort.
0548:
0549:            	@exception T_Fail Unexpected behaviour from the API
0550:            	@exception StandardException Unexpected exception from the implementation
0551:             */
0552:            protected void T004() throws T_Fail, StandardException {
0553:
0554:                Transaction t1 = t_util.t_startTransaction();
0555:
0556:                t_util.t_abort(t1);
0557:
0558:                t_util.t_commit(t1);
0559:
0560:                t_util.t_abort(t1);
0561:
0562:                t1.close();
0563:
0564:                PASS("T004");
0565:            }
0566:
0567:            /**
0568:            	T005 check transaction identifiers on idle transactions.
0569:
0570:            	@exception T_Fail Unexpected behaviour from the API
0571:            	@exception StandardException Unexpected exception from the implementation
0572:
0573:             */
0574:            protected void T005() throws T_Fail, StandardException {
0575:
0576:                Transaction t1 = t_util.t_startTransaction();
0577:
0578:                // local transactions do not have global id's
0579:                GlobalTransactionId id1 = t1.getGlobalId();
0580:                if (id1 != null)
0581:                    throw T_Fail
0582:                            .testFailMsg("null not returned from local Transaction.getId()");
0583:                t1.close();
0584:
0585:                byte[] global_id = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0586:                        13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
0587:                        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
0588:                        41, 42, 44, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
0589:                        55, 56, 57, 58, 59, 60, 61, 62, 63 };
0590:                byte[] branch_id = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0591:                        13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
0592:                        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
0593:                        41, 42, 44, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
0594:                        55, 56, 57, 58, 59, 60, 61, 62, 63 };
0595:
0596:                t1 = t_util.t_startGlobalTransaction(42, global_id, branch_id);
0597:
0598:                id1 = t1.getGlobalId();
0599:
0600:                if (!id1.equals(id1))
0601:                    throw T_Fail
0602:                            .testFailMsg("TransactionId does not compare equal to itself");
0603:
0604:                if (!id1.equals(t1.getGlobalId()))
0605:                    throw T_Fail
0606:                            .testFailMsg("TransactionId has changed without any activity on Transaction");
0607:
0608:                if (id1.equals(this ))
0609:                    throw T_Fail
0610:                            .testFailMsg("TransactionId compared equal to an non-transaction id object");
0611:
0612:                t1.close();
0613:                t1 = null;
0614:
0615:                // change the branch_id for the second global xact.
0616:                branch_id[63] = 82;
0617:                Transaction t2 = t_util.t_startGlobalTransaction(42, global_id,
0618:                        branch_id);
0619:
0620:                GlobalTransactionId id2 = t2.getGlobalId();
0621:                if (id2 == null)
0622:                    throw T_Fail
0623:                            .testFailMsg("null returned from Transaction.getId()");
0624:
0625:                if (id1.equals(id2))
0626:                    throw T_Fail
0627:                            .testFailMsg("TransactionId's returned equal from different transactions");
0628:                if (id2.equals(id1))
0629:                    throw T_Fail
0630:                            .testFailMsg("TransactionId's returned equal from different transactions");
0631:
0632:                t2.close();
0633:
0634:                PASS("T005");
0635:            }
0636:
0637:            /**
0638:            	T006 - savepoint basic API testing
0639:
0640:            	@exception T_Fail Unexpected behaviour from the API
0641:            	@exception StandardException Unexpected exception from the implementation
0642:             */
0643:            protected void T006() throws T_Fail, StandardException {
0644:
0645:                Transaction t1 = t_util.t_startTransaction();
0646:
0647:                // check a random savepoint name is not accepted
0648:                t_util.t_checkInvalidSavePoint(t1, "sdfjsdfg");
0649:
0650:                t1.setSavePoint(SP1, null);
0651:
0652:                t1.rollbackToSavePoint(SP1, null); // leaves savepoint around
0653:                t1.rollbackToSavePoint(SP1, null); // therefore this should work
0654:
0655:                t1.releaseSavePoint(SP1, null);
0656:
0657:                // SP1 should no longer exist
0658:                t_util.t_checkInvalidSavePoint(t1, SP1);
0659:
0660:                // should be able to re-use it ...
0661:                t1.setSavePoint(SP1, null);
0662:                t1.rollbackToSavePoint(SP1, null); // leaves savepoint around
0663:                t1.rollbackToSavePoint(SP1, null); // therefore this should work
0664:
0665:                t1.releaseSavePoint(SP1, null);
0666:                t_util.t_checkInvalidSavePoint(t1, SP1);
0667:
0668:                t_util.t_commit(t1);
0669:                t1.close();
0670:
0671:                PASS("T006");
0672:            }
0673:
0674:            /**
0675:            	T007 - savepoint nesting testing
0676:
0677:            	@exception T_Fail Unexpected behaviour from the API
0678:            	@exception StandardException Unexpected exception from the implementation
0679:             */
0680:            protected void T007() throws T_Fail, StandardException {
0681:
0682:                Transaction t1 = t_util.t_startTransaction();
0683:                int position = 0;
0684:
0685:                /*
0686:                 ** Push two save points and release the first, both should disappear
0687:                 */
0688:                t1.setSavePoint(SP1, null);
0689:                t1.setSavePoint(SP2, null);
0690:
0691:                position = t1.releaseSavePoint(SP1, null);
0692:                if (position != 0)
0693:                    throw T_Fail
0694:                            .testFailMsg("Save Point Position in the stack isincorrect:"
0695:                                    + position);
0696:
0697:                // SP1 and SP2 should no longer exist
0698:                t_util.t_checkInvalidSavePoint(t1, SP1);
0699:                t_util.t_checkInvalidSavePoint(t1, SP2);
0700:
0701:                /*
0702:                 ** Push two save points and remove the second, first should remain
0703:                 */
0704:                t1.setSavePoint(SP1, null);
0705:                t1.setSavePoint(SP2, null);
0706:
0707:                t1.rollbackToSavePoint(SP2, null); // leaves savepoint around
0708:                position = t1.rollbackToSavePoint(SP2, null); // therefore this should work
0709:
0710:                if (position != 2)
0711:                    throw T_Fail
0712:                            .testFailMsg("Save Point Position in the stack isincorrect:"
0713:                                    + position);
0714:
0715:                position = t1.releaseSavePoint(SP2, null);
0716:                if (position != 1)
0717:                    throw T_Fail
0718:                            .testFailMsg("Save Point Position in the stack is incorrect:"
0719:                                    + position);
0720:
0721:                t_util.t_checkInvalidSavePoint(t1, SP2);
0722:
0723:                t1.rollbackToSavePoint(SP1, null); // this is the main test
0724:
0725:                t1.releaseSavePoint(SP1, null);
0726:                t_util.t_checkInvalidSavePoint(t1, SP1);
0727:
0728:                /*
0729:                 ** Push two save points and rollback to the first, the second should disappear
0730:                 */
0731:                t1.setSavePoint(SP1, null);
0732:                t1.setSavePoint(SP2, null);
0733:
0734:                position = t1.rollbackToSavePoint(SP1, null); // leaves SP1, removes SP2
0735:                if (position != 1)
0736:                    throw T_Fail
0737:                            .testFailMsg("Save Point Position in the stack is incorrect:"
0738:                                    + position);
0739:
0740:                t_util.t_checkInvalidSavePoint(t1, SP2);
0741:                t1.rollbackToSavePoint(SP1, null);
0742:
0743:                t1.releaseSavePoint(SP1, null);
0744:
0745:                t_util.t_commit(t1);
0746:                t1.close();
0747:
0748:                PASS("T007");
0749:            }
0750:
0751:            /**
0752:            	T008 - savepoint  testing, ensure save points disappear at commit or abort.
0753:
0754:            	@exception T_Fail Unexpected behaviour from the API
0755:            	@exception StandardException Unexpected exception from the implementation
0756:             */
0757:            protected void T008() throws T_Fail, StandardException {
0758:
0759:                Transaction t1 = t_util.t_startTransaction();
0760:                int position1 = 0;
0761:                int position2 = 0;
0762:
0763:                position1 = t1.setSavePoint(SP1, null);
0764:                position2 = t1.setSavePoint(SP2, null);
0765:
0766:                if (position1 != 1 && position2 != 2)
0767:                    throw T_Fail
0768:                            .testFailMsg("Save Point Position in the Stack seeme to wrong");
0769:
0770:                t1.commit();
0771:
0772:                t_util.t_checkInvalidSavePoint(t1, SP1);
0773:                t_util.t_checkInvalidSavePoint(t1, SP2);
0774:
0775:                position1 = t1.setSavePoint(SP1, null);
0776:                position2 = t1.setSavePoint(SP2, null);
0777:
0778:                if (position1 != 1 && position2 != 2)
0779:                    throw T_Fail
0780:                            .testFailMsg("Save Point Position in the Stack seeme to wrong");
0781:
0782:                t1.abort();
0783:                position1 = t1.setSavePoint(SP1, null);
0784:                position2 = t1.setSavePoint(SP2, null);
0785:                if (position1 != 1 && position2 != 2)
0786:                    throw T_Fail
0787:                            .testFailMsg("Save Point Position in the Stack seeme to wrong");
0788:                t1.abort();
0789:                t_util.t_checkInvalidSavePoint(t1, SP1);
0790:                t_util.t_checkInvalidSavePoint(t1, SP2);
0791:
0792:                t1.close();
0793:
0794:                PASS("T008");
0795:            }
0796:
0797:            /**
0798:            	T009 - add a container and remove it within the same transaction.
0799:            	@exception T_Fail Unexpected behaviour from the API
0800:            	@exception StandardException Unexpected exception from the implementation
0801:
0802:             */
0803:
0804:            protected void T009() throws StandardException, T_Fail {
0805:                Transaction t = t_util.t_startTransaction();
0806:
0807:                long cid = t_util.t_addContainer(t, 0, 4096);
0808:                t_util.t_dropContainer(t, 0, cid);
0809:
0810:                ContainerKey id = new ContainerKey(0, cid);
0811:                ContainerHandle ch = t.openContainer(id,
0812:                        ContainerHandle.MODE_READONLY);
0813:                if (ch != null)
0814:                    throw T_Fail
0815:                            .testFailMsg("Dropped Container should not open");
0816:
0817:                t_util.t_commit(t);
0818:
0819:                t.close();
0820:
0821:                PASS("T009");
0822:            }
0823:
0824:            /**
0825:            	T010 - add a container with a default size and remove it within the same transaction.
0826:            	@exception T_Fail Unexpected behaviour from the API
0827:            	@exception StandardException Unexpected exception from the implementation
0828:
0829:             */
0830:
0831:            protected void T010() throws StandardException, T_Fail {
0832:                Transaction t1 = t_util.t_startTransaction();
0833:
0834:                long cid = t_util.t_addContainer(t1, 0);
0835:
0836:                t_util.t_dropContainer(t1, 0, cid);
0837:
0838:                ContainerKey id = new ContainerKey(0, cid);
0839:                ContainerHandle ch = t1.openContainer(id,
0840:                        ContainerHandle.MODE_READONLY);
0841:                if (ch != null)
0842:                    throw T_Fail
0843:                            .testFailMsg("Dropped Container should not open");
0844:
0845:                t_util.t_commit(t1);
0846:
0847:                t1.close();
0848:
0849:                PASS("T010");
0850:            }
0851:
0852:            /**
0853:            	T011 - see that a container remains open over the commit of an open transaction..
0854:            	@exception T_Fail Unexpected behaviour from the API
0855:            	@exception StandardException Unexpected exception from the implementation
0856:
0857:             */
0858:
0859:            protected void T011() throws StandardException, T_Fail {
0860:
0861:                Transaction t = t_util.t_startInternalTransaction();
0862:
0863:                long cid = t_util.t_addContainer(t, 0);
0864:
0865:                ContainerHandle c;
0866:
0867:                c = t_util.t_openContainer(t, 0, cid, true);
0868:
0869:                t.commit();
0870:
0871:                // container should still be open
0872:                Page page = t_util.t_getPage(c,
0873:                        ContainerHandle.FIRST_PAGE_NUMBER);
0874:
0875:                t.commit();
0876:
0877:                // page should still be latched
0878:                if (!page.isLatched())
0879:                    throw T_Fail
0880:                            .testFailMsg("page not latched after commit of internal transaction");
0881:
0882:                page.unlatch();
0883:                c.close();
0884:
0885:                t.commit();
0886:
0887:                c = t_util.t_openContainer(t, 0, cid, true);
0888:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
0889:
0890:                // container and page should be closed
0891:                t.abort();
0892:                if (page.isLatched())
0893:                    throw T_Fail
0894:                            .testFailMsg("page latched after abort of internal transaction");
0895:
0896:                try {
0897:                    page = t_util.t_getLastPage(c);
0898:                    throw T_Fail
0899:                            .testFailMsg("container open after abort of internal transaction");
0900:
0901:                } catch (StandardException te) {
0902:                }
0903:
0904:                t_util.t_dropContainer(t, 0, cid); // cleanup
0905:
0906:                t_util.t_commit(t);
0907:
0908:                t.close();
0909:
0910:                PASS("T011");
0911:            }
0912:
0913:            /**
0914:            	Test Xact.makeRecordHandle()
0915:
0916:            	@exception T_Fail Unexpected behaviour from the API
0917:            	@exception StandardException Unexpected exception from the implementation
0918:             */
0919:            protected void T012() throws StandardException, T_Fail {
0920:
0921:                Transaction t = t_util.t_startTransaction();
0922:
0923:                long cid = t_util.t_addContainer(t, 0);
0924:
0925:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
0926:                Page page = t_util.t_getPage(c,
0927:                        ContainerHandle.FIRST_PAGE_NUMBER);
0928:
0929:                RecordHandle r1, r2;
0930:                RecordHandle new_r1, new_r2;
0931:
0932:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
0933:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
0934:
0935:                r1 = t_util.t_insertAtSlot(page, 0, row1);
0936:                new_r1 = c.makeRecordHandle(r1.getPageNumber(), r1.getId());
0937:
0938:                t_util.t_checkFetch(page, new_r1, REC_001);
0939:
0940:                r2 = t_util.t_insertAtSlot(page, 1, row2);
0941:
0942:                if (r2 != null) {
0943:                    new_r2 = c.makeRecordHandle(r2.getPageNumber(), r2.getId());
0944:                    t_util.t_checkFetch(page, r2, REC_002);
0945:                }
0946:
0947:                t_util.t_commit(t);
0948:                t.close();
0949:
0950:                PASS("T012");
0951:
0952:            }
0953:
0954:            /**
0955:            	C010 - Create a container within a transaction, commit and the re-open
0956:            	the container twice.
0957:
0958:            	@exception T_Fail Unexpected behaviour from the API
0959:            	@exception StandardException Unexpected exception from the implementation
0960:
0961:             */
0962:            protected void C010(int segment) throws T_Fail, StandardException {
0963:
0964:                Transaction t = t_util.t_startTransaction();
0965:
0966:                long cid = t_util.t_addContainer(t, segment);
0967:
0968:                t_util.t_commit(t);
0969:
0970:                ContainerHandle c1, c2;
0971:
0972:                c1 = t_util.t_openContainer(t, segment, cid, true);
0973:                c1 = t_util.t_openContainer(t, segment, cid, true);
0974:                t_util.t_dropContainer(t, segment, cid); // cleanup
0975:
0976:                t_util.t_commit(t);
0977:                t.close();
0978:
0979:                PASS("C010");
0980:
0981:            }
0982:
0983:            /**
0984:            	C011 - Create a container withina transaction, commit and the re-open
0985:            	the container in update and non-update mode.
0986:            	
0987:            	@exception T_Fail Unexpected behaviour from the API
0988:            	@exception StandardException Unexpected exception from the implementation
0989:
0990:             */
0991:            protected void C011() throws T_Fail, StandardException {
0992:
0993:                Transaction t = t_util.t_startTransaction();
0994:
0995:                long cid = t_util.t_addContainer(t, 0);
0996:
0997:                t_util.t_commit(t);
0998:
0999:                ContainerHandle c1, c2;
1000:
1001:                c1 = t_util.t_openContainer(t, 0, cid, false);
1002:                c1 = t_util.t_openContainer(t, 0, cid, true);
1003:
1004:                t_util.t_dropContainer(t, 0, cid); // cleanup
1005:
1006:                t_util.t_commit(t);
1007:                t.close();
1008:                PASS("C011");
1009:
1010:            }
1011:
1012:            /**
1013:            	C012 - Drop a container within a transaction, commit, see that it is deleted.
1014:            	Drop a container within a transaction, rollback and re-open and see
1015:            	that it is not deleted. 
1016:
1017:            	@exception T_Fail Unexpected behaviour from the API
1018:            	@exception StandardException Standard Derby error policy
1019:             */
1020:            protected void C012(long segment) throws T_Fail, StandardException {
1021:
1022:                Transaction t = t_util.t_startTransaction();
1023:
1024:                long cid = t_util.t_addContainer(t, segment);
1025:                t_util.t_commit(t);
1026:
1027:                ContainerHandle c1 = t_util.t_openContainer(t, segment, cid,
1028:                        true);
1029:
1030:                t_util.t_dropContainer(t, segment, cid);
1031:
1032:                if (testRollback) {
1033:                    t_util.t_abort(t); // this should rollback the drop
1034:                    c1 = t_util.t_openContainer(t, segment, cid, true);
1035:
1036:                    REPORT("rollback of drop container tested");
1037:
1038:                    t_util.t_dropContainer(t, segment, cid);
1039:                }
1040:
1041:                t_util.t_commit(t);
1042:
1043:                ContainerKey id = new ContainerKey(segment, cid);
1044:                c1 = t.openContainer(id,
1045:                        (ContainerHandle.MODE_FORUPDATE | openMode)); // this should fail
1046:                if (c1 != null)
1047:                    throw T_Fail
1048:                            .testFailMsg("Deleted Container should fail to open");
1049:
1050:                t_util.t_commit(t);
1051:                t.close();
1052:                PASS("C012");
1053:            }
1054:
1055:            /**
1056:            	C014 - Open a container for locking only.
1057:            	@exception T_Fail Unexpected behaviour from the API
1058:            	@exception StandardException Standard Derby error policy
1059:             */
1060:            protected void C014() throws T_Fail, StandardException {
1061:
1062:                Transaction t = t_util.t_startTransaction();
1063:
1064:                ContainerKey id = new ContainerKey(77, 45);
1065:                ContainerHandle c = t.openContainer(id,
1066:                        ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY);
1067:
1068:                if (c == null)
1069:                    throw T_Fail
1070:                            .testFailMsg("open of a container for lock only failed.");
1071:
1072:                RecordHandle rh1 = c.makeRecordHandle(23, 456);
1073:                if (rh1 == null)
1074:                    throw T_Fail.testFailMsg("makeRecordHandle returned null");
1075:                c.getLockingPolicy().lockRecordForRead(t, c, rh1, true, true);
1076:
1077:                RecordHandle rh2 = c.makeRecordHandle(23, 7);
1078:                if (rh2 == null)
1079:                    throw T_Fail.testFailMsg("makeRecordHandle returned null");
1080:                c.getLockingPolicy().lockRecordForRead(t, c, rh2, true, false);
1081:
1082:                RecordHandle rh3 = c.makeRecordHandle(23, 9);
1083:                c.getLockingPolicy().lockRecordForWrite(t, rh3, false, true);
1084:                if (rh3 == null)
1085:                    throw T_Fail.testFailMsg("makeRecordHandle returned null");
1086:
1087:                c.getLockingPolicy().unlockRecordAfterRead(t, c, rh2, false,
1088:                        true);
1089:
1090:                c.close();
1091:
1092:                t.commit();
1093:
1094:                t.close();
1095:
1096:                PASS("C014");
1097:            }
1098:
1099:            /**
1100:            	@exception T_Fail Unexpected behaviour from the API
1101:            	@exception StandardException Unexpected exception from the implementation
1102:             */
1103:            protected void C200() throws T_Fail, StandardException {
1104:
1105:                Transaction t1 = t_util.t_startTransaction();
1106:
1107:                long cid = t_util.t_addContainer(t1, 0);
1108:
1109:                t_util.t_commit(t1);
1110:
1111:                ContainerHandle c1;
1112:                Page lastPage;
1113:                RecordHandle rh001, rh002, rh003;
1114:                T_RawStoreRow row;
1115:
1116:                REPORT("see if the container can be opened again");
1117:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1118:
1119:                c1.close();
1120:                t_util.t_commit(t1);
1121:
1122:                REPORT("insert a record into the container.");
1123:
1124:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1125:
1126:                lastPage = t_util.t_getLastPage(c1);
1127:                if (lastPage == null)
1128:                    throw T_Fail.testFailMsg("Could get container's last page");
1129:
1130:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1131:                    throw T_Fail.testFailMsg("Initial page must be "
1132:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1133:                            + lastPage.getPageNumber());
1134:
1135:                row = new T_RawStoreRow(REC_001);
1136:                if (!lastPage.spaceForInsert())
1137:                    throw T_Fail.testFailMsg("No room for record on page");
1138:
1139:                rh001 = t_util.t_insert(lastPage, row);
1140:                if (rh001 == null)
1141:                    throw T_Fail.testFailMsg("Failed to insert record");
1142:
1143:                // see if we can fetch that record
1144:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1145:
1146:                lastPage.unlatch();
1147:                lastPage = null;
1148:
1149:                t_util.t_commit(t1);
1150:                c1 = null;
1151:
1152:                REPORT("read record just inserted.");
1153:
1154:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1155:
1156:                lastPage = t_util.t_getLastPage(c1);
1157:                if (lastPage == null)
1158:                    throw T_Fail.testFailMsg("Could get container's last page");
1159:
1160:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1161:                t_util.t_checkFetchFirst(lastPage, REC_001);
1162:                t_util.t_checkFetchLast(lastPage, REC_001);
1163:
1164:                t_util.t_commit(t1);
1165:                lastPage = null;
1166:                c1 = null;
1167:
1168:                REPORT("insert 2 more records.");
1169:
1170:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1171:
1172:                lastPage = t_util.t_getLastPage(c1);
1173:                if (lastPage == null)
1174:                    throw T_Fail.testFailMsg("Could get container's last page");
1175:
1176:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1177:                    throw T_Fail.testFailMsg("Initial page must be "
1178:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1179:                            + lastPage.getPageNumber());
1180:
1181:                row = new T_RawStoreRow(REC_002);
1182:                if (!lastPage.spaceForInsert())
1183:                    throw T_Fail.testFailMsg("No room for record on page");
1184:
1185:                if (!lastPage.recordExists(rh001, false))
1186:                    throw T_Fail.testFailMsg("Record 001 has vanished");
1187:
1188:                //
1189:
1190:                // RESOLVE: just insert them for now, order is 002,001,003
1191:                // 001 is already on the page
1192:
1193:                rh002 = t_util.t_insertAtSlot(lastPage, 0, row);
1194:                row = new T_RawStoreRow(REC_003);
1195:                rh003 = t_util.t_insert(lastPage, row);
1196:                // Order is 002, 001, 003
1197:
1198:                lastPage.unlatch();
1199:                lastPage = null;
1200:
1201:                t_util.t_commit(t1);
1202:                c1 = null;
1203:
1204:                REPORT("checks on all 3 records.");
1205:
1206:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1207:
1208:                lastPage = t_util.t_getLastPage(c1);
1209:                if (lastPage == null)
1210:                    throw T_Fail.testFailMsg("Could get container's last page");
1211:
1212:                // Order is 002, 001, 003
1213:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1214:                t_util.t_checkFetch(lastPage, rh002, REC_002);
1215:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1216:
1217:                t_util.t_checkFetch(lastPage, lastPage.getRecordHandle(rh001
1218:                        .getId()), REC_001);
1219:                t_util.t_checkFetch(lastPage, lastPage.getRecordHandle(rh002
1220:                        .getId()), REC_002);
1221:
1222:                lastPage.unlatch();
1223:                lastPage = null;
1224:
1225:                t_util.t_commit(t1);
1226:
1227:                REPORT("start deleting.");
1228:
1229:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1230:
1231:                lastPage = t_util.t_getLastPage(c1);
1232:                if (lastPage == null)
1233:                    throw T_Fail.testFailMsg("Could get container's last page");
1234:
1235:                // Order is 002, 001, 003
1236:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1237:                t_util.t_checkFetch(lastPage, rh002, REC_002);
1238:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1239:
1240:                lastPage.delete(rh001, (LogicalUndo) null);
1241:                if (lastPage.fetch(rh001, new DataValueDescriptor[0],
1242:                        (FormatableBitSet) null, false) != null) {
1243:                    throw T_Fail.testFailMsg("deleted record is still present");
1244:                }
1245:                // Order is 002,  003
1246:                t_util.t_checkFetch(lastPage, rh002, REC_002);
1247:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1248:
1249:                t_util.t_checkFetchNext(lastPage, rh002, REC_003);
1250:                t_util.t_checkFetchPrevious(lastPage, rh003, REC_002);
1251:
1252:                lastPage.delete(rh002, (LogicalUndo) null);
1253:                if (lastPage.fetch(rh002, new DataValueDescriptor[0],
1254:                        (FormatableBitSet) null, false) != null) {
1255:                    throw T_Fail.testFailMsg("deleted record is still present");
1256:                }
1257:
1258:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1259:                t_util.t_checkFetchFirst(lastPage, REC_003);
1260:                t_util.t_checkFetchLast(lastPage, REC_003);
1261:
1262:                lastPage.unlatch();
1263:                lastPage = null;
1264:
1265:                t_util.t_commit(t1);
1266:
1267:                REPORT("update the remaining record.");
1268:
1269:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1270:
1271:                lastPage = t_util.t_getLastPage(c1);
1272:                if (lastPage == null)
1273:                    throw T_Fail.testFailMsg("Could get container's last page");
1274:
1275:                // Order is 003
1276:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1277:
1278:                T_RawStoreRow urow = new T_RawStoreRow(REC_004);
1279:
1280:                if (lastPage.fetch(rh003, new DataValueDescriptor[0],
1281:                        (FormatableBitSet) null, true) == null) {
1282:                    throw T_Fail.testFailMsg("fetch for update returned false");
1283:                }
1284:
1285:                if (!lastPage.update(rh003, urow.getRow(),
1286:                        (FormatableBitSet) null))
1287:                    throw T_Fail.testFailMsg("update returned false");
1288:
1289:                // Order is 003
1290:                t_util.t_checkFetch(lastPage, rh003, REC_004);
1291:
1292:                lastPage.unlatch();
1293:                lastPage = null;
1294:
1295:                t_util.t_commit(t1);
1296:
1297:                t_util.t_dropContainer(t1, 0, cid); // cleanup
1298:
1299:                t_util.t_commit(t1);
1300:                t1.close();
1301:
1302:                PASS("C200");
1303:
1304:            }
1305:
1306:            /**
1307:            	C201 - Create container with different page size, minimum record size,
1308:            	inserting into these containers to check if the variables are set correctly.
1309:
1310:            	@exception T_Fail Unexpected behaviour from the API
1311:            	@exception StandardException Unexpected exception from the implementation
1312:             */
1313:            protected void C201(int whatPage) throws T_Fail, StandardException {
1314:
1315:                int pageSize = (whatPage == 0 ? 4096 : 32768);
1316:
1317:                Transaction t1 = t_util.t_startTransaction();
1318:
1319:                REPORT("create container with pageSize " + pageSize
1320:                        + ", spareSpace " + 0 + ", minimumRecordSize "
1321:                        + pageSize / 2);
1322:                long cid = t_util.t_addContainer(t1, 0, pageSize, 0,
1323:                        pageSize / 2, false);
1324:
1325:                t_util.t_commit(t1);
1326:
1327:                ContainerHandle c1;
1328:                Page lastPage;
1329:                RecordHandle rh001, rh002, rh003;
1330:                T_RawStoreRow row;
1331:
1332:                REPORT("see if the container can be opened again");
1333:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1334:
1335:                c1.close();
1336:                t_util.t_commit(t1);
1337:
1338:                REPORT("insert a record into the container.");
1339:
1340:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1341:
1342:                lastPage = t_util.t_getLastPage(c1);
1343:                if (lastPage == null)
1344:                    throw T_Fail
1345:                            .testFailMsg("Couldn't get container's last page");
1346:
1347:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1348:                    throw T_Fail.testFailMsg("Initial page must be "
1349:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1350:                            + lastPage.getPageNumber());
1351:
1352:                row = new T_RawStoreRow(REC_001);
1353:                if (!lastPage.spaceForInsert())
1354:                    throw T_Fail.testFailMsg("No room for record on page");
1355:
1356:                rh001 = t_util.t_insert(lastPage, row);
1357:                if (rh001 == null)
1358:                    throw T_Fail.testFailMsg("Failed to insert record");
1359:
1360:                // see if we can fetch that record
1361:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1362:
1363:                lastPage.unlatch();
1364:                lastPage = null;
1365:
1366:                t_util.t_commit(t1);
1367:                c1 = null;
1368:
1369:                REPORT("read record just inserted.");
1370:
1371:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1372:
1373:                lastPage = t_util.t_getLastPage(c1);
1374:                if (lastPage == null)
1375:                    throw T_Fail
1376:                            .testFailMsg("Couldn't get container's last page");
1377:
1378:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1379:                t_util.t_checkFetchFirst(lastPage, REC_001);
1380:                t_util.t_checkFetchLast(lastPage, REC_001);
1381:
1382:                t_util.t_commit(t1);
1383:                lastPage = null;
1384:                c1 = null;
1385:
1386:                // negative testing
1387:                REPORT("try inserting 1 more record, but there should be no room on page for it.");
1388:
1389:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1390:
1391:                lastPage = t_util.t_getLastPage(c1);
1392:                if (lastPage == null)
1393:                    throw T_Fail
1394:                            .testFailMsg("Couldn't get container's last page");
1395:
1396:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1397:                    throw T_Fail.testFailMsg("Initial page must be "
1398:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1399:                            + lastPage.getPageNumber());
1400:
1401:                row = new T_RawStoreRow(REC_002);
1402:                if (lastPage.spaceForInsert()) {
1403:                    throw T_Fail
1404:                            .testFailMsg("Did not get no room for record on page error");
1405:                }
1406:
1407:                if (!lastPage.recordExists(rh001, false))
1408:                    throw T_Fail.testFailMsg("Record 001 has vanished");
1409:
1410:                lastPage.unlatch();
1411:                lastPage = null;
1412:
1413:                t_util.t_commit(t1);
1414:                c1 = null;
1415:
1416:                t_util.t_dropContainer(t1, 0, cid); // cleanup
1417:                t_util.t_commit(t1);
1418:                //t1.close();
1419:
1420:                //t1 = t_util.t_startTransaction();
1421:
1422:                REPORT("create container with pageSize " + pageSize
1423:                        + ", spareSpace " + 0 + ", minimumRecordSize "
1424:                        + pageSize);
1425:                REPORT("this should set minimumRecordSize to the default 100");
1426:                cid = t_util
1427:                        .t_addContainer(t1, 0, pageSize, 0, pageSize, false);
1428:
1429:                t_util.t_commit(t1);
1430:
1431:                REPORT("see if the container can be opened again");
1432:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1433:
1434:                c1.close();
1435:                t_util.t_commit(t1);
1436:
1437:                REPORT("insert a record into the container.");
1438:
1439:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1440:
1441:                lastPage = t_util.t_getLastPage(c1);
1442:                if (lastPage == null)
1443:                    throw T_Fail
1444:                            .testFailMsg("Couldn't get container's last page");
1445:
1446:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1447:                    throw T_Fail.testFailMsg("Initial page must be "
1448:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1449:                            + lastPage.getPageNumber());
1450:
1451:                row = new T_RawStoreRow(REC_001);
1452:                if (!lastPage.spaceForInsert())
1453:                    throw T_Fail.testFailMsg("No room for record on page");
1454:
1455:                rh001 = t_util.t_insert(lastPage, row);
1456:                if (rh001 == null)
1457:                    throw T_Fail.testFailMsg("Failed to insert record");
1458:
1459:                // see if we can fetch that record
1460:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1461:
1462:                lastPage.unlatch();
1463:                lastPage = null;
1464:
1465:                t_util.t_commit(t1);
1466:                c1 = null;
1467:
1468:                REPORT("read record just inserted.");
1469:
1470:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1471:
1472:                lastPage = t_util.t_getLastPage(c1);
1473:                if (lastPage == null)
1474:                    throw T_Fail
1475:                            .testFailMsg("Couldn't get container's last page");
1476:
1477:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1478:                t_util.t_checkFetchFirst(lastPage, REC_001);
1479:                t_util.t_checkFetchLast(lastPage, REC_001);
1480:
1481:                t_util.t_commit(t1);
1482:                lastPage = null;
1483:                c1 = null;
1484:
1485:                REPORT("insert 2 more records.");
1486:
1487:                c1 = t_util.t_openContainer(t1, 0, cid, true);
1488:
1489:                lastPage = t_util.t_getLastPage(c1);
1490:                if (lastPage == null)
1491:                    throw T_Fail.testFailMsg("Could get container's last page");
1492:
1493:                if (lastPage.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
1494:                    throw T_Fail.testFailMsg("Initial page must be "
1495:                            + ContainerHandle.FIRST_PAGE_NUMBER + ", is "
1496:                            + lastPage.getPageNumber());
1497:
1498:                row = new T_RawStoreRow(REC_002);
1499:                if (!lastPage.spaceForInsert())
1500:                    throw T_Fail.testFailMsg("No room for record on page");
1501:
1502:                if (!lastPage.recordExists(rh001, false))
1503:                    throw T_Fail.testFailMsg("Record 001 has vanished");
1504:
1505:                rh002 = t_util.t_insertAtSlot(lastPage, 0, row);
1506:                row = new T_RawStoreRow(REC_003);
1507:                rh003 = t_util.t_insert(lastPage, row);
1508:
1509:                lastPage.unlatch();
1510:                lastPage = null;
1511:
1512:                t_util.t_commit(t1);
1513:                c1 = null;
1514:
1515:                REPORT("checks on all 3 records.");
1516:
1517:                c1 = t_util.t_openContainer(t1, 0, cid, false);
1518:
1519:                lastPage = t_util.t_getLastPage(c1);
1520:                if (lastPage == null)
1521:                    throw T_Fail.testFailMsg("Could get container's last page");
1522:
1523:                // Order is 002, 001, 003
1524:                t_util.t_checkFetch(lastPage, rh001, REC_001);
1525:                t_util.t_checkFetch(lastPage, rh002, REC_002);
1526:                t_util.t_checkFetch(lastPage, rh003, REC_003);
1527:
1528:                t_util.t_checkFetch(lastPage, lastPage.getRecordHandle(rh001
1529:                        .getId()), REC_001);
1530:                t_util.t_checkFetch(lastPage, lastPage.getRecordHandle(rh002
1531:                        .getId()), REC_002);
1532:
1533:                lastPage.unlatch();
1534:                lastPage = null;
1535:
1536:                t_util.t_commit(t1);
1537:
1538:                c1 = null;
1539:
1540:                // clean ip
1541:                t_util.t_dropContainer(t1, 0, cid);
1542:                t_util.t_commit(t1);
1543:                t1.close();
1544:
1545:                PASS("C201 - " + whatPage);
1546:
1547:            }
1548:
1549:            /**
1550:            	Page tests
1551:             */
1552:            /**
1553:               Create a container, ensure it has one page with no records. Then test
1554:            all the things we can do with an empty page opened read-only in the container.
1555:            Then add a new page, ensure it has the correct page number and is empty.
1556:            @exception T_Fail Unexpected behaviour from the API
1557:            @exception StandardException Unexpected exception from the implementation
1558:             */
1559:            protected void P001(long segment) throws T_Fail, StandardException {
1560:
1561:                Transaction t = t_util.t_startTransaction();
1562:
1563:                long cid = t_util.t_addContainer(t, segment);
1564:
1565:                t_util.t_commit(t);
1566:
1567:                // Get the first page & check the record counts are zero
1568:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
1569:                        false);
1570:                Page page = t_util.t_getPage(c,
1571:                        ContainerHandle.FIRST_PAGE_NUMBER);
1572:
1573:                t_util.t_checkEmptyPage(page);
1574:
1575:                if (Page.FIRST_SLOT_NUMBER != 0)
1576:                    throw T_Fail
1577:                            .testFailMsg("Page.FIRST_SLOT_NUMBER must be 0, is "
1578:                                    + Page.FIRST_SLOT_NUMBER);
1579:
1580:                page.unlatch();
1581:                page = null;
1582:
1583:                // get the last page and check it is the first page
1584:                page = t_util.t_getLastPage(c);
1585:
1586:                t_util.t_checkPageNumber(page,
1587:                        ContainerHandle.FIRST_PAGE_NUMBER);
1588:
1589:                t_util.t_checkEmptyPage(page);
1590:
1591:                t_util.t_commit(t);
1592:
1593:                // t_util.t_addPage checks that the page is empty.
1594:                c = t_util.t_openContainer(t, segment, cid, true);
1595:                page = t_util.t_addPage(c);
1596:
1597:                t_util.t_checkPageNumber(page,
1598:                        ContainerHandle.FIRST_PAGE_NUMBER + 1);
1599:                page.unlatch();
1600:
1601:                page = t_util.t_addPage(c);
1602:                t_util.t_checkPageNumber(page,
1603:                        ContainerHandle.FIRST_PAGE_NUMBER + 2);
1604:                page.unlatch();
1605:
1606:                t_util.t_commit(t);
1607:
1608:                c = t_util.t_openContainer(t, segment, cid, true);
1609:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1610:                t_util.t_updateSlotOutOfRange(page, 0);
1611:                t_util.t_updateSlotOutOfRange(page, -1);
1612:                t_util.t_updateSlotOutOfRange(page, 1);
1613:
1614:                t_util.t_dropContainer(t, segment, cid); // cleanup
1615:                t_util.t_commit(t);
1616:
1617:                // RESOLVE drop container
1618:
1619:                t.close();
1620:
1621:                PASS("P001");
1622:            }
1623:
1624:            /**
1625:            	Insert rows on the first page until the page is full, then add a page
1626:            	and repeat the test (for a total of three pages with full rows).
1627:            	Fetch the rows back by handle and slot methods.
1628:
1629:            	@exception T_Fail Unexpected behaviour from the API
1630:            	@exception StandardException Unexpected exception from the implementation
1631:             */
1632:            protected void P002(long segment) throws StandardException, T_Fail {
1633:
1634:                Transaction t = t_util.t_startTransaction();
1635:
1636:                long cid = t_util.t_addContainer(t, segment);
1637:
1638:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
1639:                        true);
1640:                Page page = t_util.t_getPage(c,
1641:                        ContainerHandle.FIRST_PAGE_NUMBER);
1642:                t_util.t_checkEmptyPage(page);
1643:
1644:                RecordHandle rh;
1645:                T_RawStoreRow row;
1646:                int recordCount[] = { 0, 0, 0 };
1647:
1648:                for (int i = 0; i < 3;) {
1649:                    row = new T_RawStoreRow(REC_001 + i + "X" + recordCount[i]);
1650:
1651:                    boolean spaceThere = page.spaceForInsert();
1652:
1653:                    rh = t_util.t_insert(page, row);
1654:
1655:                    if (rh != null) {
1656:                        recordCount[i]++;
1657:                        if (!spaceThere)
1658:                            REPORT("record inserted after spaceForInsert() returned false, count is "
1659:                                    + recordCount[i]);
1660:                    } else {
1661:                        if (spaceThere)
1662:                            REPORT("record insert failed after spaceForInsert() returned true, count is "
1663:                                    + recordCount[i]);
1664:                    }
1665:
1666:                    t_util.t_checkRecordCount(page, recordCount[i],
1667:                            recordCount[i]);
1668:
1669:                    if (rh != null)
1670:                        continue;
1671:
1672:                    page.unlatch();
1673:                    page = null;
1674:
1675:                    if (++i < 3) {
1676:                        page = t_util.t_addPage(c);
1677:                        t_util.t_checkEmptyPage(page);
1678:                    }
1679:                }
1680:                t_util.t_commit(t);
1681:
1682:                for (int i = 0; i < 3; i++) {
1683:                    REPORT("RecordCount on page " + i + "=" + recordCount[i]);
1684:                }
1685:
1686:                // now check that we read the same number of records back
1687:                // using the handle interface
1688:                c = t_util.t_openContainer(t, segment, cid, false);
1689:
1690:                long pageNumber = ContainerHandle.FIRST_PAGE_NUMBER;
1691:                for (int i = 0; i < 3; i++, pageNumber++) {
1692:                    page = t_util.t_getPage(c, pageNumber);
1693:                    t_util.t_checkRecordCount(page, recordCount[i],
1694:                            recordCount[i]);
1695:                    rh = t_util.t_checkFetchFirst(page, REC_001 + i + "X" + 0);
1696:                    for (int j = 1; j < recordCount[i]; j++)
1697:                        rh = t_util.t_checkFetchNext(page, rh, REC_001 + i
1698:                                + "X" + j);
1699:
1700:                    try {
1701:                        rh = page.fetchFromSlot(null,
1702:                                page.getSlotNumber(rh) + 1,
1703:                                new DataValueDescriptor[0],
1704:                                (FetchDescriptor) null, false);
1705:
1706:                        throw T_Fail
1707:                                .testFailMsg("reading more rows on page than were written");
1708:                    } catch (StandardException se) {
1709:                        // expected error.
1710:                    }
1711:
1712:                    rh = t_util.t_checkFetchLast(page, REC_001 + i + "X"
1713:                            + (recordCount[i] - 1));
1714:                    for (int j = recordCount[i] - 2; j >= 0; j--)
1715:                        rh = t_util.t_checkFetchPrevious(page, rh, REC_001 + i
1716:                                + "X" + j);
1717:
1718:                    page.unlatch();
1719:                    page = null;
1720:                }
1721:                t_util.t_commit(t);
1722:
1723:                // now check that we read the same number of records back
1724:                // using the slot interface
1725:                c = t_util.t_openContainer(t, segment, cid, false);
1726:
1727:                pageNumber = ContainerHandle.FIRST_PAGE_NUMBER;
1728:                for (int i = 0; i < 3; i++, pageNumber++) {
1729:                    page = t_util.t_getPage(c, pageNumber);
1730:
1731:                    for (int j = 0; j < recordCount[i]; j++)
1732:                        t_util.t_checkFetchBySlot(page, j, REC_001 + i + "X"
1733:                                + j, false, false);
1734:
1735:                    t_util.t_readOnlySlotOutOfRange(page, recordCount[i]);
1736:
1737:                    page.unlatch();
1738:                    page = null;
1739:                }
1740:
1741:                t_util.t_dropContainer(t, segment, cid); // cleanup
1742:
1743:                t_util.t_commit(t);
1744:
1745:                t.close();
1746:
1747:                PASS("P002");
1748:            }
1749:
1750:            /**
1751:            	Test Page.delete
1752:
1753:            	@exception T_Fail Unexpected behaviour from the API
1754:            	@exception StandardException Unexpected exception from the implementation
1755:
1756:            	@see Page#delete
1757:             */
1758:
1759:            protected void P003(long segment) throws StandardException, T_Fail {
1760:
1761:                Transaction t = t_util.t_startTransaction();
1762:
1763:                long cid = t_util.t_addContainer(t, segment);
1764:
1765:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
1766:                        true);
1767:                Page page = t_util.t_getPage(c,
1768:                        ContainerHandle.FIRST_PAGE_NUMBER);
1769:
1770:                RecordHandle r1, r2;
1771:
1772:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
1773:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
1774:
1775:                r1 = t_util.t_insertAtSlot(page, 0, row1);
1776:                r2 = t_util.t_insertAtSlot(page, 1, row2);
1777:
1778:                t_util.t_checkFetch(page, r1, REC_001);
1779:                if (r2 != null)
1780:                    t_util.t_checkFetch(page, r2, REC_002);
1781:
1782:                t_util.t_checkRecordCount(page, 2, r2 == null ? 1 : 2);
1783:
1784:                // delete the first
1785:                if (!page.delete(r1, (LogicalUndo) null))
1786:                    throw T_Fail.testFailMsg("delete() returned false");
1787:
1788:                t_util.t_checkRecordCount(page, 2, r2 == null ? 0 : 1);
1789:
1790:                if (page.delete(r1, (LogicalUndo) null))
1791:                    throw T_Fail
1792:                            .testFailMsg("delete() returned true on already deleted record");
1793:
1794:                t_util.t_checkRecordCount(page, 2, r2 == null ? 0 : 1);
1795:
1796:                if (page.recordExists(r1, false))
1797:                    throw T_Fail
1798:                            .testFailMsg("recordExists() returned true for deleted record");
1799:
1800:                // check the other record is still there
1801:                if (r2 != null)
1802:                    t_util.t_checkFetch(page, r2, REC_002);
1803:
1804:                if (!page.isDeletedAtSlot(0))
1805:                    throw T_Fail
1806:                            .testFailMsg("isDeletedAtSlot() doesn't represent correct state");
1807:
1808:                t_util.t_dropContainer(t, segment, cid); // cleanup
1809:
1810:                t_util.t_commit(t);
1811:                t.close();
1812:
1813:                PASS("P003");
1814:            }
1815:
1816:            /**
1817:            	Test Page.update
1818:
1819:            	@exception T_Fail Unexpected behaviour from the API
1820:            	@exception StandardException Unexpected exception from the implementation
1821:
1822:            	@see Page#update
1823:             */
1824:            protected void P004(long segment) throws StandardException, T_Fail {
1825:
1826:                Transaction t = t_util.t_startTransaction();
1827:
1828:                long cid = t_util.t_addContainer(t, segment);
1829:
1830:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
1831:                        true);
1832:                Page page = t_util.t_getPage(c,
1833:                        ContainerHandle.FIRST_PAGE_NUMBER);
1834:
1835:                RecordHandle r1, r2;
1836:
1837:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
1838:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
1839:
1840:                r1 = t_util.t_insertAtSlot(page, 0, row1);
1841:                r2 = t_util.t_insertAtSlot(page, 1, row2);
1842:
1843:                t_util.t_checkFetch(page, r1, REC_001);
1844:                if (r2 != null)
1845:                    t_util.t_checkFetch(page, r2, REC_002);
1846:
1847:                row1 = new T_RawStoreRow((String) null);
1848:                if (!page.update(r1, row1.getRow(), (FormatableBitSet) null))
1849:                    throw T_Fail.testFailMsg("update() returned false");
1850:
1851:                t_util.t_checkFetch(page, r1, (String) null);
1852:                if (r2 != null)
1853:                    t_util.t_checkFetch(page, r2, REC_002);
1854:
1855:                t_util.t_checkFetch(page, r1, (String) null);
1856:                if (r2 != null)
1857:                    t_util.t_checkFetch(page, r2, REC_002);
1858:
1859:                row1 = new T_RawStoreRow(REC_003);
1860:                if (!page.update(r1, row1.getRow(), (FormatableBitSet) null))
1861:                    throw T_Fail.testFailMsg("update() returned false");
1862:
1863:                t_util.t_checkFetch(page, r1, REC_003);
1864:                if (r2 != null)
1865:                    t_util.t_checkFetch(page, r2, REC_002);
1866:
1867:                // now delete the record we have been updating
1868:                if (!page.delete(r1, (LogicalUndo) null))
1869:                    throw T_Fail.testFailMsg("delete returned false");
1870:
1871:                row1 = new T_RawStoreRow(REC_004);
1872:                if (page.update(r1, row1.getRow(), (FormatableBitSet) null))
1873:                    throw T_Fail
1874:                            .testFailMsg("update returned true on deleted record");
1875:
1876:                page.deleteAtSlot(0, false, (LogicalUndo) null);
1877:
1878:                t_util.t_checkFetch(page, r1, REC_003);
1879:
1880:                if (!page.update(r1, row1.getRow(), (FormatableBitSet) null))
1881:                    throw T_Fail.testFailMsg("update returned false");
1882:
1883:                t_util.t_checkFetch(page, r1, REC_004);
1884:
1885:                t_util.t_dropContainer(t, segment, cid); // cleanup
1886:
1887:                t_util.t_commit(t);
1888:                t.close();
1889:
1890:                PASS("P004");
1891:
1892:            }
1893:
1894:            /* test repeated insert */
1895:            protected void P005(long segment) throws StandardException, T_Fail {
1896:                Transaction t = t_util.t_startTransaction();
1897:
1898:                long cid = t_util.t_addContainer(t, segment);
1899:
1900:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
1901:                        true);
1902:                Page page1 = t_util.t_getLastPage(c);
1903:
1904:                T_RawStoreRow row0 = new T_RawStoreRow(
1905:                        "long row xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx long row ");
1906:                T_RawStoreRow row1 = new T_RawStoreRow(
1907:                        "medium row yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy medium row");
1908:
1909:                t_util.t_insertAtSlot(page1, 0, row0);
1910:
1911:                int i = 0;
1912:                while (page1.spaceForInsert()) {
1913:                    if (t_util.t_insertAtSlot(page1, 1, row1) == null)
1914:                        break;
1915:                    i++;
1916:                }
1917:
1918:                int count1 = page1.recordCount();
1919:
1920:                Page page2 = t_util.t_addPage(c);
1921:                t_util.t_insertAtSlot(page2, 0, row0);
1922:
1923:                i = 1;
1924:                while (page2.spaceForInsert()) {
1925:                    if (t_util.t_insertAtSlot(page2, i++, row1) == null)
1926:                        break;
1927:                }
1928:
1929:                int count2 = page2.recordCount();
1930:
1931:                // now purge them all and start over
1932:                page1.purgeAtSlot(1, page1.recordCount() - 1, logDataForPurges);
1933:                page2.purgeAtSlot(1, page2.recordCount() - 1, logDataForPurges);
1934:                if (page1.recordCount() != 1)
1935:                    throw T_Fail.testFailMsg("purge did not clean up page");
1936:
1937:                if (page2.recordCount() != 1)
1938:                    throw T_Fail.testFailMsg("purge did not clean up page");
1939:
1940:                i = 0;
1941:                while (page1.spaceForInsert()) {
1942:                    if (t_util.t_insertAtSlot(page1, 1, row1) == null)
1943:                        return;
1944:                    i++;
1945:                }
1946:
1947:                if (page1.recordCount() != count1)
1948:                    throw T_Fail
1949:                            .testFailMsg("cannot insert back same number of rows we purged");
1950:
1951:                i = 1;
1952:                while (page2.spaceForInsert()) {
1953:                    if (t_util.t_insertAtSlot(page2, i++, row1) == null)
1954:                        break;
1955:                }
1956:
1957:                if (page2.recordCount() != count2)
1958:                    throw T_Fail
1959:                            .testFailMsg("cannot insert back same number of rows we purged");
1960:
1961:                page1.unlatch();
1962:                page2.unlatch();
1963:
1964:                t_util.t_dropContainer(t, segment, cid); // cleanup
1965:
1966:                t_util.t_commit(t);
1967:                t.close();
1968:
1969:                PASS("P005");
1970:            }
1971:
1972:            /*
1973:            	P006
1974:
1975:            	test page time stamp - make sure all operation changes page time stamp
1976:             */
1977:            protected void P006() throws StandardException, T_Fail {
1978:                Transaction t = t_util.t_startTransaction();
1979:                PageTimeStamp ts;
1980:
1981:                long cid = t_util.t_addContainer(t, 0);
1982:                t_util.t_commit(t);
1983:
1984:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1985:                Page page1 = t_util.t_getLastPage(c);
1986:
1987:                ts = page1.currentTimeStamp();
1988:                if (ts != null && !page1.equalTimeStamp(ts))
1989:                    throw T_Fail
1990:                            .testFailMsg("page returns non-null time stamp which is not equal to its current time stamp");
1991:
1992:                T_RawStoreRow row = new T_RawStoreRow(REC_001);
1993:                RecordHandle rh = t_util.t_insert(page1, row);
1994:
1995:                if (page1.equalTimeStamp(ts))
1996:                    throw T_Fail
1997:                            .testFailMsg("timestamp on page not changed after insert operation");
1998:                page1.setTimeStamp(ts);
1999:                if (ts != null && !page1.equalTimeStamp(ts))
2000:                    throw T_Fail
2001:                            .testFailMsg("page returns non-null time stamp which is not equal to its current time stamp");
2002:
2003:                // failed update should not change time stamp
2004:                t_util.t_updateSlotOutOfRange(page1, 3);
2005:                if (ts != null && !page1.equalTimeStamp(ts))
2006:                    throw T_Fail
2007:                            .testFailMsg("failed pdate should not change time stamp");
2008:
2009:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2010:                page1.update(rh, row2.getRow(), (FormatableBitSet) null);
2011:                if (page1.equalTimeStamp(ts))
2012:                    throw T_Fail
2013:                            .testFailMsg("timestamp on page not changed after update operation");
2014:
2015:                page1.setTimeStamp(ts);
2016:
2017:                T_RawStoreRow upd1 = new T_RawStoreRow(REC_003);
2018:                page1.update(rh, upd1.getRow(), BS_COL_0);
2019:                if (page1.equalTimeStamp(ts))
2020:                    throw T_Fail
2021:                            .testFailMsg("timestamp on page not changed after update field operation");
2022:
2023:                page1.setTimeStamp(ts);
2024:
2025:                page1.delete(rh, (LogicalUndo) null);
2026:                if (page1.equalTimeStamp(ts))
2027:                    throw T_Fail
2028:                            .testFailMsg("timestamp on page not changed after delete operation");
2029:
2030:                page1.setTimeStamp(ts);
2031:
2032:                page1.purgeAtSlot(0, 1, logDataForPurges);
2033:                if (page1.equalTimeStamp(ts))
2034:                    throw T_Fail
2035:                            .testFailMsg("timestamp on page not changed after delete operation");
2036:
2037:                page1.setTimeStamp(ts);
2038:                page1.unlatch();
2039:
2040:                if (testRollback) {
2041:                    t_util.t_abort(t);
2042:                    c = t_util.t_openContainer(t, 0, cid, true);
2043:                    page1 = t_util.t_getLastPage(c);
2044:
2045:                    if (page1.equalTimeStamp(ts))
2046:                        throw T_Fail
2047:                                .testFailMsg("timestamp on page not changed after rollback");
2048:
2049:                    page1.setTimeStamp(ts);
2050:                }
2051:
2052:                Page page2 = c.addPage();
2053:                Page page3 = c.addPage();
2054:
2055:                page2.setTimeStamp(ts);
2056:
2057:                if (ts != null) {
2058:                    try {
2059:                        if (page3.equalTimeStamp(ts))
2060:                            throw T_Fail
2061:                                    .testFailMsg("timestamp on 2 different pages should not equate");
2062:                    } catch (StandardException se) {
2063:                        // either throw an exception or return false is OK
2064:                    }
2065:                }
2066:
2067:                t_util.t_dropContainer(t, 0, cid); // cleanup
2068:                t_util.t_commit(t);
2069:                t.close();
2070:
2071:                PASS("P006");
2072:
2073:            }
2074:
2075:            /**
2076:            	P007
2077:
2078:            	this test exercises repeated updates on a 1K page
2079:
2080:            	2 rows (with 1 column) will be inserted into the page.
2081:            	We expand the row data in slot 0 by 1 byte until the page is completely full,
2082:            	and overflows the record to an overflow page.
2083:
2084:            	@exception T_Fail Unexpected behaviour from the API
2085:            	@exception StandardException Unexpected exception from the implementation
2086:             */
2087:
2088:            protected void P007(long segment) throws StandardException, T_Fail {
2089:
2090:                Transaction t = t_util.t_startTransaction();
2091:
2092:                // PART 1:
2093:                // insert two 1-column rows into the page, expand the first row, until it overflows.
2094:                long cid = t_util.t_addContainer(t, segment, 4096, 0, 1, false);
2095:
2096:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
2097:                        true);
2098:                Page page = t_util.t_getLastPage(c);
2099:
2100:                T_RawStoreRow row = new T_RawStoreRow(REC_001); // McLaren
2101:                T_RawStoreRow row2 = new T_RawStoreRow(
2102:                        new String(new char[300]));
2103:
2104:                RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row);
2105:                RecordHandle r2 = t_util.t_insertAtSlot(page, 1, row2);
2106:
2107:                // update the row size 1 byte larger, until the page is full
2108:                String rowData = REC_001;
2109:                // 900 is an estimated number, because for 1K page,
2110:                // if you expand your row by 1 byte 900 times, the row will overflow for sure.
2111:                for (int i = 0; i <= 900; i++) {
2112:                    t_util.t_checkFetch(page, r1, rowData);
2113:
2114:                    rowData = rowData + REC_008; // "z"
2115:                    row = new T_RawStoreRow(rowData);
2116:                    page.updateAtSlot(0, row.getRow(), (FormatableBitSet) null);
2117:                }
2118:
2119:                t_util.t_dropContainer(t, segment, cid); // cleanup
2120:
2121:                // PART 2:
2122:                // insert two 2-column rows into the page,
2123:                // expand the first row by expanding the first column by 300 bytes,
2124:                // and shrinking the second column by 300 bytes.  Update should secceed.
2125:                cid = t_util.t_addContainer(t, segment, 4096, 0, 1, false);
2126:                c = t_util.t_openContainer(t, segment, cid, true);
2127:                page = t_util.t_getLastPage(c);
2128:                long pid = page.getPageNumber();
2129:
2130:                row = new T_RawStoreRow(2);
2131:                row.setColumn(0, REC_001); // small column
2132:                row.setColumn(1, new String(new char[400])); // large column
2133:
2134:                r1 = t_util.t_insertAtSlot(page, 0, row);
2135:                r2 = t_util.t_insertAtSlot(page, 1, row2);
2136:
2137:                row.setColumn(0, REC_001 + new String(new char[300]));
2138:                row.setColumn(1, new String(new char[100]));
2139:
2140:                page.updateAtSlot(0, row.getRow(), (FormatableBitSet) null);
2141:
2142:                Page page2 = t_util.t_addPage(c);
2143:                long pid2 = page2.getPageNumber();
2144:                if (pid2 != (pid + 1))
2145:                    throw T_Fail
2146:                            .testFailMsg("The update should not have overflowed the record");
2147:
2148:                // Now, shrink the first column by 300 bytes, and expand the second column by 300 bytes.
2149:                // the update should also succeed.
2150:                row.setColumn(0, REC_001);
2151:                row.setColumn(1, new String(new char[400]));
2152:
2153:                page.updateAtSlot(0, row.getRow(), (FormatableBitSet) null);
2154:
2155:                Page page3 = t_util.t_addPage(c);
2156:                long pid3 = page3.getPageNumber();
2157:                if (pid3 != (pid2 + 1))
2158:                    throw T_Fail
2159:                            .testFailMsg("The update should not have overflowed the record");
2160:
2161:                t_util.t_dropContainer(t, segment, cid); // cleanup
2162:
2163:                t_util.t_commit(t);
2164:                t.close();
2165:
2166:                PASS("P007");
2167:
2168:            }
2169:
2170:            /**
2171:            	P008
2172:
2173:            	this test exercises repeated inserts with small rows on a 1K page
2174:
2175:            	we will insert as many rows as possible into the page.  Then we reduce the row by 1 byte at a time,
2176:            	we will try to insert another smaller row.
2177:            	This test also tests spaceForInsert().
2178:
2179:            	@exception T_Fail Unexpected behaviour from the API
2180:            	@exception StandardException Unexpected exception from the implementation
2181:             */
2182:
2183:            protected void P008(long segment) throws StandardException, T_Fail {
2184:                Transaction t = t_util.t_startTransaction();
2185:
2186:                long cid = t_util.t_addContainer(t, segment, 4096, 0, 1, false);
2187:
2188:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
2189:                        true);
2190:                Page page1 = t_util.t_getLastPage(c);
2191:
2192:                T_RawStoreRow row = new T_RawStoreRow(REC_001); // McLaren
2193:
2194:                t_util.t_insertAtSlot(page1, 0, row);
2195:
2196:                int i = 0;
2197:                while (page1.spaceForInsert(row.getRow(),
2198:                        (FormatableBitSet) null, 100)) {
2199:                    // if it says there is enough room for this row, the insert should succeed.
2200:                    if (t_util.t_insertAtSlot(page1, 1, row) == null)
2201:                        throw T_Fail
2202:                                .testFailMsg("There is space for this insert.  It shouldn't have failed.  "
2203:                                        + "record #" + i);
2204:                    i++;
2205:                }
2206:
2207:                REPORT(i + " rows inserted.");
2208:
2209:                // We got out of the while loop because there is no room for the insert.
2210:                // So, if the insert succeed, then we have a problem.
2211:                if (t_util.t_insertAtSlot(page1, 1, row) != null)
2212:                    throw T_Fail
2213:                            .testFailMsg("There is no space for this insert.  It should have failed.");
2214:
2215:                // Now, we will try to fill the page with smaller rows.
2216:                String[] s = new String[7];
2217:                s[6] = "McLare";
2218:                s[5] = "McLar";
2219:                s[4] = "McLa";
2220:                s[3] = "McL";
2221:                s[2] = "Mc";
2222:                s[1] = "M";
2223:                s[0] = null;
2224:                // reduce the row by 1 byte
2225:                i = 6;
2226:                boolean notDone = true;
2227:                do {
2228:                    row = new T_RawStoreRow(s[i]);
2229:                    if (page1.spaceForInsert(row.getRow(),
2230:                            (FormatableBitSet) null, 100)) {
2231:                        // If it says there is enough room for the row, then the insert should succed.
2232:                        if (t_util.t_insertAtSlot(page1, 1, row) == null)
2233:                            throw T_Fail
2234:                                    .testFailMsg("There should be space for this insert, row is "
2235:                                            + s[i]);
2236:                        else
2237:                            notDone = false;
2238:                    } else
2239:                        i--;
2240:                } while ((notDone) && (i >= 0));
2241:
2242:                page1.unlatch();
2243:
2244:                t_util.t_dropContainer(t, segment, cid); // cleanup
2245:
2246:                t_util.t_commit(t);
2247:                t.close();
2248:
2249:                PASS("P008");
2250:            }
2251:
2252:            /**
2253:            	P009
2254:
2255:            	this test exercises repeated shrinking and expanding of fields using updateFieldBySlot
2256:
2257:            	we will insert as many rows as possible into the page. Then set some of the columns to null,
2258:            	That should not create more space on the page for inserts, because the extra space become
2259:            	reservedspace for the row.  So, the next insert should fail.
2260:
2261:            	@exception T_Fail Unexpected behaviour from the API
2262:            	@exception StandardException Unexpected exception from the implementation
2263:             */
2264:
2265:            protected void P009(long segment) throws StandardException, T_Fail {
2266:                int slot = 0;
2267:                int i = 0;
2268:                int j = 0;
2269:                String field = REC_001;
2270:
2271:                Transaction t = t_util.t_startTransaction();
2272:
2273:                long cid = t_util.t_addContainer(t, segment);
2274:
2275:                // Get the first page & check the record counts are zero
2276:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
2277:                        true);
2278:                Page page = t_util.t_getPage(c,
2279:                        ContainerHandle.FIRST_PAGE_NUMBER);
2280:
2281:                t_util.t_checkEmptyPage(page);
2282:
2283:                // Create a 13-column row
2284:                T_RawStoreRow row = new T_RawStoreRow(13);
2285:                row.setColumn(0, (String) null);
2286:                row.setColumn(1, REC_001);
2287:                row.setColumn(2, REC_002);
2288:                row.setColumn(3, REC_003);
2289:                row.setColumn(4, REC_004);
2290:                row.setColumn(5, REC_005);
2291:                row.setColumn(6, REC_006);
2292:                row.setColumn(7, REC_007);
2293:                row.setColumn(8, (String) null);
2294:                row.setColumn(9, (String) null);
2295:                row.setColumn(10, REC_007);
2296:                row.setColumn(11, (String) null);
2297:                row.setColumn(12, REC_006);
2298:
2299:                // insert the row into the page until the page is full
2300:                int numRows = 0;
2301:                slot = page.FIRST_SLOT_NUMBER;
2302:                while (page.spaceForInsert(row.getRow(),
2303:                        (FormatableBitSet) null, 100)) {
2304:                    t_util.t_insert(page, row);
2305:                    numRows++;
2306:                }
2307:                REPORT(numRows + " rows inserted ");
2308:
2309:                // update all the fields in the even number rows to null
2310:                // set all the fields in the odd number rows to REC_001
2311:                DataValueDescriptor col = new SQLChar(); // null
2312:                for (i = page.FIRST_SLOT_NUMBER; i < (page.FIRST_SLOT_NUMBER + 2); i++) {
2313:
2314:                    for (slot = i; slot <= (numRows - 1); slot += 2) {
2315:
2316:                        for (j = 0; j <= 12; j++) {
2317:                            if (page.updateFieldAtSlot(slot, j, col, null) == null) {
2318:
2319:                                throw T_Fail
2320:                                        .testFailMsg("Failed to update field "
2321:                                                + j + ", in row " + slot);
2322:                            }
2323:                        }
2324:                    }
2325:
2326:                    col = new SQLChar(REC_001);
2327:                }
2328:
2329:                // fetch all the fields, and see if they are correct
2330:                DataValueDescriptor storedColumn = new SQLChar();
2331:                field = null;
2332:                for (i = page.FIRST_SLOT_NUMBER; i < (page.FIRST_SLOT_NUMBER + 2); i++) {
2333:
2334:                    for (slot = i; slot <= (numRows - 1); slot += 2) {
2335:
2336:                        for (j = 0; j <= 12; j++) {
2337:
2338:                            t_util.t_checkFetchColFromSlot(page, slot, j,
2339:                                    storedColumn, false, field);
2340:
2341:                        }
2342:                    }
2343:
2344:                    field = REC_001;
2345:                }
2346:
2347:                // Now if we try to insert the old row again, there should still be no room
2348:                if (page.spaceForInsert())
2349:                    throw T_Fail
2350:                            .testFailMsg("Did not get no room for record on page error");
2351:
2352:                // update the first and last field of every row to REC_006
2353:                col = new SQLChar(REC_006);
2354:                for (slot = page.FIRST_SLOT_NUMBER; slot <= (numRows - 1); slot++) {
2355:                    if (page.updateFieldAtSlot(slot, 0, col, null) == null
2356:                            || page.updateFieldAtSlot(slot, 12, col, null) == null) {
2357:
2358:                        throw T_Fail
2359:                                .testFailMsg("Failed to update fields to REC_006 in row "
2360:                                        + slot);
2361:                    }
2362:                }
2363:
2364:                // update field 5 and 6 of every row to REC_007
2365:                col = new SQLChar(REC_007);
2366:                for (slot = page.FIRST_SLOT_NUMBER; slot <= (numRows - 1); slot++) {
2367:                    if (page.updateFieldAtSlot(slot, 5, col, null) == null
2368:                            || page.updateFieldAtSlot(slot, 6, col, null) == null) {
2369:
2370:                        throw T_Fail
2371:                                .testFailMsg("Failed to update fields to REC_007 in row "
2372:                                        + slot);
2373:                    }
2374:                }
2375:
2376:                // fetch all the fields again, and see if they are correct
2377:                for (i = page.FIRST_SLOT_NUMBER; i < (page.FIRST_SLOT_NUMBER + 2); i++) {
2378:
2379:                    for (slot = i; slot <= (numRows - 1); slot += 2) {
2380:
2381:                        for (j = 0; j <= 12; j++) {
2382:
2383:                            switch (j) {
2384:                            case 0:
2385:                            case 12:
2386:                                field = REC_006;
2387:                                break;
2388:                            case 5:
2389:                            case 6:
2390:                                field = REC_007;
2391:                                break;
2392:                            default:
2393:                                if ((slot % 2) == 0)
2394:                                    field = null;
2395:                                else
2396:                                    field = REC_001;
2397:                                break;
2398:                            }
2399:
2400:                            t_util.t_checkFetchColFromSlot(page, slot, j,
2401:                                    storedColumn, false, field);
2402:
2403:                        }
2404:                    }
2405:                }
2406:
2407:                // We now try to insert the old row one last time, there should still be no room
2408:                if (page.spaceForInsert())
2409:                    throw T_Fail
2410:                            .testFailMsg("Did not get no room for record on page error");
2411:
2412:                // now we want to increase row 0 and column 5 one byte at a time, until the page is full
2413:                // but, every 5 increases we will reduce the field size by one byte
2414:                field = REC_007;
2415:                i = 0;
2416:                String field_pre = null;
2417:                while (true) {
2418:                    if ((i % 5) != 0) {
2419:                        field_pre = field;
2420:                        field += REC_008;
2421:                    } else {
2422:                        field = field_pre;
2423:                    }
2424:
2425:                    if (((i % 10) == 3) || ((i % 10) == 7)) {
2426:                        page.unlatch();
2427:                        page = null;
2428:
2429:                        factory.idle();
2430:
2431:                        page = t_util.t_getPage(c,
2432:                                ContainerHandle.FIRST_PAGE_NUMBER);
2433:                    }
2434:
2435:                    col = new SQLChar(field);
2436:
2437:                    try {
2438:                        page.updateFieldAtSlot(0, 5, col, null);
2439:                    } catch (StandardException se) {
2440:                        // now we have filled the page
2441:                        if (i < 809) {
2442:                            throw T_Fail
2443:                                    .testFailMsg("should be able to update Row 0 Column 5 809 times"
2444:                                            + ", but only updated "
2445:                                            + i
2446:                                            + " times.  Note: you maybe getting this error if your page format has changed.");
2447:                        } else {
2448:                            REPORT("Row 0 Column 5 was updated " + i
2449:                                    + " times.");
2450:                        }
2451:                        break;
2452:                    }
2453:                    i++;
2454:                }
2455:
2456:                // The page is completely full at this point.
2457:                // update Row 1 Column 1 from REC_001 to REC_002.  They are the same length
2458:                page.unlatch();
2459:                page = null;
2460:                factory.idle();
2461:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2462:                col = new SQLChar(REC_002);
2463:                if (page.updateFieldAtSlot(1, 1, col, null) == null) {
2464:                    throw T_Fail
2465:                            .testFailMsg("update Row 1 and Column 1 to same length data failed.");
2466:                }
2467:
2468:                REPORT("updated col1 in row 1 to same length");
2469:
2470:                // now expand update Row 1 Column 1 by one byte.  This should fail.
2471:                page.unlatch();
2472:                page = null;
2473:                factory.idle();
2474:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2475:                field = REC_002 + REC_008;
2476:                col = new SQLChar(field);
2477:                try {
2478:                    page.updateFieldAtSlot(1, 1, col, null);
2479:                    throw T_Fail
2480:                            .testFailMsg("update Row 1 and Column 1 to longer length should have failed.");
2481:                } catch (StandardException se) {
2482:                    ;
2483:                }
2484:
2485:                // clean up
2486:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
2487:                    t_util.t_dropContainer(t, segment, cid); // cleanup
2488:                }
2489:
2490:                t_util.t_commit(t);
2491:                t.close();
2492:
2493:                PASS("P009: segment " + segment);
2494:
2495:            }
2496:
2497:            /**
2498:            	P011
2499:
2500:            	this test exercises insertAtSlot, (LogicalUndo)null
2501:
2502:            	@exception T_Fail Unexpected behaviour from the API
2503:            	@exception StandardException Unexpected exception from the implementation
2504:             */
2505:            protected void P011(long segment) throws StandardException, T_Fail {
2506:                Transaction t = t_util.t_startTransaction();
2507:                long cid = t_util.t_addContainer(t, segment);
2508:                t_util.t_commit(t);
2509:
2510:                // Get the first page
2511:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
2512:                        true);
2513:                Page page = t_util.t_getPage(c,
2514:                        ContainerHandle.FIRST_PAGE_NUMBER);
2515:
2516:                // REPORT("insert 2 records at FIRST_SLOT_NUMBER");
2517:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2518:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2519:                T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
2520:                T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
2521:
2522:                // try inserting at slot -1 and slot 1
2523:                try {
2524:                    RecordHandle r = t_util.t_insertAtSlot(page, -1, row1);
2525:                    throw T_Fail.testFailMsg("insert at slot -1 succeeded");
2526:                } catch (StandardException se) {
2527:                    // throw if not a statement exception.
2528:                    if (se.getSeverity() > ExceptionSeverity.STATEMENT_SEVERITY)
2529:                        throw se;
2530:                }
2531:
2532:                try {
2533:                    RecordHandle r = t_util.t_insertAtSlot(page, 1, row1);
2534:                    throw T_Fail.testFailMsg("insert at slot 1 succeeded");
2535:                } catch (StandardException se) {
2536:                    // throw if not a statement exception.
2537:                    if (se.getSeverity() > ExceptionSeverity.STATEMENT_SEVERITY)
2538:                        throw se;
2539:                }
2540:
2541:                RecordHandle r1, r2, r3, r4;
2542:                // first insert to a page must suceed
2543:                r3 = t_util.t_insertAtSlot(page, Page.FIRST_SLOT_NUMBER, row3);
2544:                t_util.t_checkFetch(page, r3, REC_003);
2545:                t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER,
2546:                        REC_003, false, false);
2547:
2548:                r1 = r2 = r4 = null;
2549:                r1 = t_util.t_insertAtSlot(page, Page.FIRST_SLOT_NUMBER, row1);
2550:
2551:                if (r1 != null) {
2552:                    t_util.t_checkFetch(page, r1, REC_001);
2553:                    t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER,
2554:                            REC_001, false, false);
2555:                } else {
2556:                    t_util.t_abort(t);
2557:                    t.close();
2558:                    REPORT("P011 not run - could not fit 4 rows on page");
2559:                    return;
2560:                }
2561:
2562:                // REPORT("insert a record at 2nd slot");
2563:                r2 = t_util.t_insertAtSlot(page, Page.FIRST_SLOT_NUMBER + 1,
2564:                        row2);
2565:
2566:                if (r2 != null) {
2567:                    t_util.t_checkFetch(page, r2, REC_002);
2568:                    t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER + 1,
2569:                            REC_002, false, false);
2570:                } else {
2571:                    t_util.t_abort(t);
2572:                    t.close();
2573:                    REPORT("P011 not completed - could not fit 4 rows on page");
2574:                    return;
2575:                }
2576:
2577:                // REPORT("insert a record at the end");
2578:                r4 = t_util.t_insertAtSlot(page, 3, row4);
2579:                if (r4 != null) {
2580:                    t_util.t_checkFetch(page, r4, REC_004);
2581:                    t_util.t_checkFetchBySlot(page, 3, REC_004, false, false);
2582:                } else {
2583:                    t_util.t_abort(t);
2584:                    t.close();
2585:                    REPORT("P011 not completed - could not fit 4 rows on page");
2586:                    return;
2587:                }
2588:
2589:                // REPORT("make sure records are in the correct order");
2590:                // order is REC_001 REC_002 REC_003 REC_004 
2591:
2592:                t_util.t_checkFetchFirst(page, REC_001);
2593:                t_util.t_checkFetchNext(page, r1, REC_002);
2594:                t_util.t_checkFetchNext(page, r2, REC_003);
2595:                t_util.t_checkFetchNext(page, r3, REC_004);
2596:                t_util.t_checkFetchLast(page, REC_004);
2597:
2598:                // check the fetch by slot interface
2599:                t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER,
2600:                        REC_001, false, true);
2601:                t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER + 1,
2602:                        REC_002, false, false);
2603:                t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER + 2,
2604:                        REC_003, false, true);
2605:                t_util.t_checkFetchBySlot(page, Page.FIRST_SLOT_NUMBER + 3,
2606:                        REC_004, false, false);
2607:
2608:                // clean up
2609:
2610:                t_util.t_dropContainer(t, segment, cid); // cleanup
2611:
2612:                t_util.t_commit(t);
2613:                t.close();
2614:
2615:                PASS("P011");
2616:
2617:            }
2618:
2619:            /**
2620:              P012
2621:
2622:              this test exercises updateAtSlot
2623:
2624:            	@exception T_Fail Unexpected behaviour from the API
2625:            	@exception StandardException Unexpected exception from the implementation
2626:             */
2627:            protected void P012(long segment) throws StandardException, T_Fail {
2628:                Transaction t = t_util.t_startTransaction();
2629:                long cid = t_util.t_addContainer(t, segment);
2630:
2631:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
2632:                        true);
2633:                Page page = t_util.t_getPage(c,
2634:                        ContainerHandle.FIRST_PAGE_NUMBER);
2635:
2636:                // REPORT("insert 3 records");
2637:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2638:
2639:                T_RawStoreRow row2 = new T_RawStoreRow(2);
2640:                row2.setColumn(0, (String) null);
2641:                row2.setColumn(1, REC_001);
2642:
2643:                T_RawStoreRow row3 = new T_RawStoreRow(3);
2644:                row3.setColumn(0, REC_001);
2645:                row3.setColumn(1, REC_002);
2646:                row3.setColumn(2, REC_003);
2647:
2648:                RecordHandle r1, r2, r3;
2649:                r1 = t_util.t_insertAtSlot(page, 0, row1);
2650:
2651:                r2 = r3 = null;
2652:                r2 = t_util.t_insertAtSlot(page, 1, row2);
2653:
2654:                if (r2 == null) {
2655:                    REPORT("P012 not completed - cannot insert second row");
2656:                    return;
2657:                }
2658:
2659:                r3 = t_util.t_insertAtSlot(page, 2, row3);
2660:                if (r3 == null) {
2661:                    REPORT("P012 not completed - cannot insert third row");
2662:                    return;
2663:                }
2664:
2665:                // check that they are inserted correctly
2666:                t_util.t_checkFetch(page, r1, row1);
2667:                t_util.t_checkFetch(page, r2, row2);
2668:                t_util.t_checkFetch(page, r3, row3);
2669:
2670:                // REPORT("update that grows the #columns in row");
2671:                T_RawStoreRow upd1 = new T_RawStoreRow(2);
2672:                upd1.setColumn(0, (String) null);
2673:                upd1.setColumn(1, REC_001);
2674:
2675:                r1 = page.updateAtSlot(0, upd1.getRow(),
2676:                        (FormatableBitSet) null);
2677:                t_util.t_checkFetch(page, r1, upd1);
2678:                t_util.t_checkFetch(page, r2, row2);
2679:                t_util.t_checkFetch(page, r3, row3);
2680:
2681:                // REPORT("update that shrinks the #columns in row");
2682:                T_RawStoreRow upd2 = new T_RawStoreRow(REC_004);
2683:
2684:                r2 = page.updateAtSlot(1, upd2.getRow(),
2685:                        (FormatableBitSet) null);
2686:                t_util.t_checkFetch(page, r1, upd1);
2687:                t_util.t_checkFetch(page, r2, upd2);
2688:                t_util.t_checkFetch(page, r3, row3);
2689:
2690:                // REPORT("update same #columns in row");
2691:                T_RawStoreRow upd3 = new T_RawStoreRow(3);
2692:                upd3.setColumn(0, REC_003);
2693:                upd3.setColumn(1, REC_002);
2694:                upd3.setColumn(2, REC_001);
2695:
2696:                r3 = page.updateAtSlot(2, upd3.getRow(),
2697:                        (FormatableBitSet) null);
2698:                t_util.t_checkFetch(page, r1, upd1);
2699:                t_util.t_checkFetch(page, r2, upd2);
2700:                t_util.t_checkFetch(page, r3, upd3);
2701:
2702:                // clean up
2703:
2704:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
2705:                    t_util.t_dropContainer(t, segment, cid); // cleanup
2706:                }
2707:
2708:                t_util.t_commit(t);
2709:                t.close();
2710:
2711:                PASS("P012");
2712:            }
2713:
2714:            /**
2715:              P013
2716:
2717:              this test exercises deleteAtSlot and isDeletedAtSlot
2718:            	@exception T_Fail Unexpected behaviour from the API
2719:            	@exception StandardException Unexpected exception from the implementation
2720:             */
2721:            protected void P013() throws StandardException, T_Fail {
2722:                Transaction t = t_util.t_startTransaction();
2723:                long cid = t_util.t_addContainer(t, 0);
2724:
2725:                t_util.t_commit(t);
2726:
2727:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2728:                Page page = t_util.t_getPage(c,
2729:                        ContainerHandle.FIRST_PAGE_NUMBER);
2730:
2731:                // REPORT("insert 2 records");
2732:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2733:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2734:
2735:                RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
2736:                RecordHandle r2;
2737:                r2 = t_util.t_insertAtSlot(page, 1, row2);
2738:                if (r2 == null) {
2739:                    REPORT("P013 not completed - could not fit two rows on a page");
2740:                    return;
2741:                }
2742:
2743:                t_util.t_checkRecordCount(page, 2, 2);
2744:
2745:                // REPORT("delete them one by one");
2746:                page.deleteAtSlot(0, true, (LogicalUndo) null);
2747:
2748:                t_util.t_checkRecordCount(page, 2, 1);
2749:
2750:                if (!page.isDeletedAtSlot(0))
2751:                    throw T_Fail.testFailMsg("Failed to delete record 0");
2752:                if (page.isDeletedAtSlot(1))
2753:                    throw T_Fail.testFailMsg("Record mistakenly deleted");
2754:
2755:                page.deleteAtSlot(1, true, (LogicalUndo) null);
2756:                t_util.t_checkRecordCount(page, 2, 0);
2757:                if (!page.isDeletedAtSlot(1))
2758:                    throw T_Fail.testFailMsg("Failed to delete record 1");
2759:
2760:                page.deleteAtSlot(0, false, (LogicalUndo) null);
2761:                t_util.t_checkRecordCount(page, 2, 1);
2762:                if (page.isDeletedAtSlot(0))
2763:                    throw T_Fail.testFailMsg("Failed to undelete record 0");
2764:                if (!page.isDeletedAtSlot(1))
2765:                    throw T_Fail.testFailMsg("Record mistakenly undeleted");
2766:
2767:                page.deleteAtSlot(1, false, (LogicalUndo) null);
2768:                t_util.t_checkRecordCount(page, 2, 2);
2769:                if (page.isDeletedAtSlot(1))
2770:                    throw T_Fail.testFailMsg("Failed to undelete record 1");
2771:
2772:                // try the negative tests
2773:                try {
2774:                    page.deleteAtSlot(0, false, (LogicalUndo) null);
2775:                    throw T_Fail
2776:                            .testFailMsg("undeleted on undeleted record succeeded");
2777:                } catch (StandardException se) {
2778:                    // throw if not a statement exception.
2779:                    if (se.getSeverity() > ExceptionSeverity.STATEMENT_SEVERITY)
2780:                        throw se;
2781:                }
2782:
2783:                page.deleteAtSlot(0, true, (LogicalUndo) null);
2784:                try {
2785:                    page.deleteAtSlot(0, true, (LogicalUndo) null);
2786:                    throw T_Fail
2787:                            .testFailMsg("deleted on deleted record succeeded");
2788:                } catch (StandardException se) {
2789:                    // throw if not a statement exception.
2790:                    if (se.getSeverity() > ExceptionSeverity.STATEMENT_SEVERITY)
2791:                        throw se;
2792:                }
2793:
2794:                t_util.t_checkRecordCount(page, 2, 1);
2795:                // clean up
2796:                PASS("P013");
2797:
2798:                t_util.t_dropContainer(t, 0, cid); // cleanup
2799:
2800:                t_util.t_commit(t);
2801:                t.close();
2802:
2803:            }
2804:
2805:            /**
2806:              P014
2807:
2808:              this test exercises purgeAtSlot
2809:            	@exception T_Fail Unexpected behaviour from the API
2810:            	@exception StandardException Unexpected exception from the implementation
2811:             */
2812:            protected void P014() throws StandardException, T_Fail {
2813:                Transaction t = t_util.t_startTransaction();
2814:                long cid = t_util.t_addContainer(t, 0);
2815:                t_util.t_commit(t);
2816:
2817:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2818:                Page page = t_util.t_getPage(c,
2819:                        ContainerHandle.FIRST_PAGE_NUMBER);
2820:
2821:                // REPORT("insert 5 records");
2822:                T_RawStoreRow row0 = new T_RawStoreRow(REC_001);
2823:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2824:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2825:                T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
2826:                T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
2827:
2828:                RecordHandle r0, r1, r2, r3, r4;
2829:                r0 = t_util.t_insertAtSlot(page, 0, row0);
2830:                r1 = t_util.t_insertAtSlot(page, 1, row1);
2831:                r2 = t_util.t_insertAtSlot(page, 2, row2);
2832:                r3 = t_util.t_insertAtSlot(page, 3, row3);
2833:                r4 = t_util.t_insertAtSlot(page, 4, row4);
2834:
2835:                if (r3 != null)
2836:                    page.deleteAtSlot(3, true, (LogicalUndo) null);
2837:
2838:                // REPORT("commit it");
2839:                t_util.t_commit(t);
2840:
2841:                c = t_util.t_openContainer(t, 0, cid, true);
2842:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2843:
2844:                try {
2845:                    page.purgeAtSlot(-1, 1, logDataForPurges);
2846:                    throw T_Fail
2847:                            .testFailMsg("negative slot number did not cause an exception");
2848:                } catch (StandardException se) {
2849:                } // expected
2850:
2851:                try {
2852:                    page.purgeAtSlot(4, 4, logDataForPurges);
2853:                    throw T_Fail
2854:                            .testFailMsg("purging more rows than is on page did not cause an exception");
2855:                } catch (StandardException se) {
2856:                } // expected
2857:
2858:                // if not all the rows are there, do minimal test
2859:                if (r4 == null) {
2860:                    int rcount = page.recordCount();
2861:                    page.purgeAtSlot(0, 1, logDataForPurges);
2862:                    if (page.recordCount() != rcount - 1)
2863:                        T_Fail.testFailMsg("failed to purge a record, expect "
2864:                                + (rcount - 1) + " got " + page.recordCount());
2865:
2866:                    if (testRollback) {
2867:                        t_util.t_abort(t);
2868:
2869:                        c = t_util.t_openContainer(t, 0, cid, true);
2870:                        page = t_util.t_getPage(c,
2871:                                ContainerHandle.FIRST_PAGE_NUMBER);
2872:                        if (logDataForPurges)
2873:                            t_util.t_checkFetchBySlot(page, 0, REC_001, false,
2874:                                    true);
2875:                        else
2876:                            t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
2877:                                    true);
2878:                        if (page.recordCount() != rcount)
2879:                            T_Fail
2880:                                    .testFailMsg("failed to rollback purge, expect "
2881:                                            + rcount
2882:                                            + " got "
2883:                                            + page.recordCount());
2884:                    } else {
2885:                        t_util.t_commit(t);
2886:                    }
2887:                    PASS("minimal P014");
2888:                    return;
2889:                }
2890:
2891:                // REPORT("purge 2 records from middle");
2892:                page.purgeAtSlot(1, 2, logDataForPurges);
2893:                t_util.t_checkFetchBySlot(page, 0, REC_001, false, true);
2894:                t_util.t_checkFetchBySlot(page, 1, REC_003, true, true);
2895:                t_util.t_checkFetchBySlot(page, 2, REC_004, false, true);
2896:
2897:                if (page.recordCount() != 3)
2898:                    T_Fail
2899:                            .testFailMsg("page expect to have 3 records, recordCount() = "
2900:                                    + page.recordCount());
2901:
2902:                // REPORT("purge all records from the page");
2903:                page.purgeAtSlot(0, 3, logDataForPurges);
2904:                if (page.recordCount() != 0)
2905:                    T_Fail
2906:                            .testFailMsg("page expect to have 0 records, recordCount() = "
2907:                                    + page.recordCount());
2908:
2909:                if (testRollback) {
2910:
2911:                    REPORT("testing rollback");
2912:                    t_util.t_abort(t);
2913:
2914:                    c = t_util.t_openContainer(t, 0, cid, true);
2915:                    page = t_util.t_getPage(c,
2916:                            ContainerHandle.FIRST_PAGE_NUMBER);
2917:
2918:                    if (logDataForPurges) {
2919:                        t_util
2920:                                .t_checkFetchBySlot(page, 0, REC_001, false,
2921:                                        true);
2922:                        t_util
2923:                                .t_checkFetchBySlot(page, 1, REC_001, false,
2924:                                        true);
2925:                        t_util
2926:                                .t_checkFetchBySlot(page, 2, REC_002, false,
2927:                                        true);
2928:                        t_util.t_checkFetchBySlot(page, 3, REC_003, true, true);
2929:                        t_util
2930:                                .t_checkFetchBySlot(page, 4, REC_004, false,
2931:                                        true);
2932:                    } else {
2933:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
2934:                                true);
2935:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
2936:                                true);
2937:                        t_util.t_checkFetchBySlot(page, 2, REC_NULL, false,
2938:                                true);
2939:                        t_util
2940:                                .t_checkFetchBySlot(page, 3, REC_NULL, true,
2941:                                        true);
2942:                        t_util.t_checkFetchBySlot(page, 4, REC_NULL, false,
2943:                                true);
2944:                    }
2945:
2946:                    if (page.recordCount() != 5)
2947:                        T_Fail
2948:                                .testFailMsg("page expect to have 5 records, recordCount() = "
2949:                                        + page.recordCount());
2950:
2951:                    // REPORT("purge 3 records from the end");
2952:                    page.purgeAtSlot(2, 3, logDataForPurges);
2953:                    if (logDataForPurges) {
2954:                        t_util
2955:                                .t_checkFetchBySlot(page, 0, REC_001, false,
2956:                                        true);
2957:                        t_util
2958:                                .t_checkFetchBySlot(page, 1, REC_001, false,
2959:                                        true);
2960:                    } else {
2961:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
2962:                                true);
2963:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
2964:                                true);
2965:                    }
2966:                    if (page.recordCount() != 2)
2967:                        T_Fail
2968:                                .testFailMsg("page expect to have 2 records, recordCount() = "
2969:                                        + page.recordCount());
2970:
2971:                    // REPORT("rollback");
2972:                    t_util.t_abort(t);
2973:
2974:                    c = t_util.t_openContainer(t, 0, cid, true);
2975:                    page = t_util.t_getPage(c,
2976:                            ContainerHandle.FIRST_PAGE_NUMBER);
2977:                    if (logDataForPurges) {
2978:                        t_util
2979:                                .t_checkFetchBySlot(page, 0, REC_001, false,
2980:                                        true);
2981:                        t_util
2982:                                .t_checkFetchBySlot(page, 1, REC_001, false,
2983:                                        true);
2984:                        t_util
2985:                                .t_checkFetchBySlot(page, 2, REC_002, false,
2986:                                        true);
2987:                        t_util.t_checkFetchBySlot(page, 3, REC_003, true, true);
2988:                        t_util
2989:                                .t_checkFetchBySlot(page, 4, REC_004, false,
2990:                                        true);
2991:                    } else {
2992:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
2993:                                true);
2994:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
2995:                                true);
2996:                        t_util.t_checkFetchBySlot(page, 2, REC_NULL, false,
2997:                                true);
2998:                        t_util
2999:                                .t_checkFetchBySlot(page, 3, REC_NULL, true,
3000:                                        true);
3001:                        t_util.t_checkFetchBySlot(page, 4, REC_NULL, false,
3002:                                true);
3003:                    }
3004:
3005:                    if (page.recordCount() != 5)
3006:                        T_Fail
3007:                                .testFailMsg("page expect to have 5 records, recordCount() = "
3008:                                        + page.recordCount());
3009:
3010:                    // REPORT("make sure delete record is reconstituted as such");
3011:                    if (page.isDeletedAtSlot(1))
3012:                        T_Fail
3013:                                .testFailMsg("rolled back purged undeleted record cause record to be deleted");
3014:                    if (!page.isDeletedAtSlot(3))
3015:                        T_Fail
3016:                                .testFailMsg("rolled back purged deleted record cause record to be undeleted");
3017:                }
3018:                PASS("P014");
3019:
3020:                t_util.t_dropContainer(t, 0, cid); // cleanup
3021:                t_util.t_commit(t);
3022:                t.close();
3023:            }
3024:
3025:            /**
3026:              P015
3027:
3028:              this test exercises updateAtSlot
3029:
3030:            	@exception T_Fail Unexpected behaviour from the API
3031:            	@exception StandardException Unexpected exception from the implementation
3032:             */
3033:            protected void P015() throws StandardException, T_Fail {
3034:                Transaction t = t_util.t_startTransaction();
3035:                long cid = t_util.t_addContainer(t, 0);
3036:
3037:                t_util.t_commit(t);
3038:
3039:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3040:                Page page = t_util.t_getPage(c,
3041:                        ContainerHandle.FIRST_PAGE_NUMBER);
3042:
3043:                // REPORT("insert 3 records");
3044:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3045:
3046:                T_RawStoreRow row2 = new T_RawStoreRow(2);
3047:                row2.setColumn(0, (String) null);
3048:                row2.setColumn(1, REC_001);
3049:
3050:                T_RawStoreRow row3 = new T_RawStoreRow(3);
3051:                row3.setColumn(0, REC_001);
3052:                row3.setColumn(1, REC_002);
3053:                row3.setColumn(2, REC_003);
3054:
3055:                RecordHandle r1, r2, r3;
3056:                r1 = t_util.t_insertAtSlot(page, 0, row1);
3057:
3058:                r2 = r3 = null;
3059:                r2 = t_util.t_insertAtSlot(page, 1, row2);
3060:
3061:                if (r2 == null) {
3062:                    REPORT("P015 not completed - cannot insert second row");
3063:                    return;
3064:                }
3065:
3066:                r3 = t_util.t_insertAtSlot(page, 2, row3);
3067:
3068:                if (r3 == null) {
3069:                    REPORT("P015 not completed - cannot insert third row");
3070:                    return;
3071:                }
3072:
3073:                // check that they are inserted correctly
3074:                t_util.t_checkFetch(page, r1, row1);
3075:                t_util.t_checkFetch(page, r2, row2);
3076:                t_util.t_checkFetch(page, r3, row3);
3077:
3078:                // now update the middle row with a large value
3079:                T_RawStoreRow row2u = new T_RawStoreRow(2);
3080:                row2u
3081:                        .setColumn(
3082:                                0,
3083:                                "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789");
3084:                row2u
3085:                        .setColumn(
3086:                                1,
3087:                                "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789");
3088:
3089:                page.updateAtSlot(1, row2u.getRow(), (FormatableBitSet) null);
3090:                t_util.t_checkFetch(page, r2, row2u);
3091:
3092:                // now update the field of the first record with a large value
3093:                ((T_RawStoreRow) row1)
3094:                        .setColumn(
3095:                                0,
3096:                                "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
3097:
3098:                FormatableBitSet validColumn = new FormatableBitSet(2);
3099:
3100:                validColumn.clear();
3101:                validColumn.set(0);
3102:
3103:                page.updateAtSlot(0, row1.getRow(), validColumn);
3104:
3105:                t_util.t_checkFetch(page, r1, row1);
3106:
3107:                ((T_RawStoreRow) row3)
3108:                        .setColumn(
3109:                                1,
3110:                                "XXabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
3111:
3112:                validColumn.clear();
3113:                validColumn.set(1);
3114:
3115:                page.updateAtSlot(2, row3.getRow(), validColumn);
3116:                t_util.t_checkFetch(page, r3, row3);
3117:
3118:                // clean up
3119:                PASS("P015");
3120:
3121:                t_util.t_dropContainer(t, 0, cid); // cleanup
3122:
3123:                t_util.t_commit(t);
3124:                t.close();
3125:
3126:            }
3127:
3128:            /*
3129:            	P016
3130:
3131:            	this test exercises copyAndPurge
3132:            	@exception T_Fail Unexpected behaviour from the API
3133:            	@exception StandardException Unexpected exception from the implementation
3134:             */
3135:            protected void P016() throws StandardException, T_Fail {
3136:                Transaction t = t_util.t_startTransaction();
3137:                long cid = t_util.t_addContainer(t, 0);
3138:                long cid2 = t_util.t_addContainer(t, 0);
3139:
3140:                t_util.t_commit(t);
3141:
3142:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3143:
3144:                Page page1 = t_util.t_getPage(c,
3145:                        ContainerHandle.FIRST_PAGE_NUMBER);
3146:                Page page2 = t_util.t_addPage(c);
3147:                long pid1 = page1.getPageNumber();
3148:                long pid2 = page2.getPageNumber();
3149:
3150:                t_util.t_checkEmptyPage(page2);
3151:
3152:                // first fill up page 1
3153:
3154:                int i = 0;
3155:                int deleted = 0;
3156:                RecordHandle rh;
3157:
3158:                T_RawStoreRow row;
3159:
3160:                for (i = 0, row = new T_RawStoreRow("row at slot " + i); page1
3161:                        .spaceForInsert(); i++, row = new T_RawStoreRow(
3162:                        "row at slot " + i)) {
3163:                    rh = t_util.t_insertAtSlot(page1, i, row);
3164:                    if (rh == null)
3165:                        break;
3166:
3167:                    // delete every third row
3168:                    if ((i % 3) == 1) {
3169:                        deleted++;
3170:                        page1.delete(rh, (LogicalUndo) null);
3171:                    }
3172:                }
3173:
3174:                int recordCount = i;
3175:
3176:                // negative testing
3177:                // copy into page of different container
3178:                ContainerHandle c2 = t_util.t_openContainer(t, 0, cid2, true);
3179:                Page wrongPage = t_util.t_getPage(c2,
3180:                        ContainerHandle.FIRST_PAGE_NUMBER);
3181:                try {
3182:                    page1.copyAndPurge(wrongPage, 0, recordCount, 0);
3183:                    throw T_Fail
3184:                            .testFailMsg("copying to page from a different contaier should cause and exception");
3185:                } catch (StandardException se) {
3186:                } // expected
3187:
3188:                try {
3189:                    page1.copyAndPurge(page2, 1, 0, 0);
3190:                    throw T_Fail
3191:                            .testFailMsg("copying zero rows should cause an exception");
3192:                } catch (StandardException se) {
3193:                } // expected
3194:
3195:                try {
3196:                    page1.copyAndPurge(page2, 1, recordCount, 0);
3197:                    throw T_Fail
3198:                            .testFailMsg("copying more rows than page contains should cause an exception");
3199:                } catch (StandardException se) {
3200:                } // expected
3201:
3202:                try {
3203:                    page1.copyAndPurge(page2, 0, 1, 1);
3204:                    throw T_Fail
3205:                            .testFailMsg("copying rows to nonexistant slot should cause an exception");
3206:                } catch (StandardException se) {
3207:                } // expected
3208:
3209:                // copy the whole page to page2
3210:                page1.copyAndPurge(page2, 0, recordCount, 0);
3211:
3212:                // check
3213:                t_util.t_checkEmptyPage(page1);
3214:
3215:                for (i = 0; i < recordCount; i++) {
3216:                    t_util.t_checkFetchBySlot(page2, i, "row at slot " + i,
3217:                            ((i % 3) == 1), true);
3218:                }
3219:                t_util.t_checkRecordCount(page2, recordCount, recordCount
3220:                        - deleted);
3221:
3222:                t_util.t_commit(t);
3223:
3224:                if (recordCount > 2) {
3225:                    // now copy and purge part of the page
3226:                    c = t_util.t_openContainer(t, 0, cid, true);
3227:                    page1 = t_util.t_getPage(c, pid1);
3228:                    page2 = t_util.t_getPage(c, pid2);
3229:
3230:                    // insert 2 rows into page1
3231:                    T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3232:                    T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3233:                    t_util.t_insertAtSlot(page1, 0, row1);
3234:                    t_util.t_insertAtSlot(page1, 1, row2);
3235:
3236:                    page2.copyAndPurge(page1, 1, recordCount - 2, 1);
3237:
3238:                    t_util.t_checkFetchBySlot(page2, 0, "row at slot " + 0,
3239:                            false, true);
3240:
3241:                    // need to figure out the delete status of the last row on page 2
3242:                    boolean tdeleted = ((recordCount - 1) % 3) == 1;
3243:                    t_util.t_checkFetchBySlot(page2, 1, "row at slot "
3244:                            + (recordCount - 1), tdeleted, true);
3245:
3246:                    if (((recordCount - 1) % 3) == 1)
3247:                        t_util.t_checkRecordCount(page2, 2, 1); // last record on page2 was deleted
3248:                    else
3249:                        t_util.t_checkRecordCount(page2, 2, 2); // last record on page2 was not deleted
3250:
3251:                    t_util.t_checkFetchBySlot(page1, 0, REC_001, false, false);
3252:                    for (i = 1; i < recordCount - 1; i++) {
3253:                        t_util.t_checkFetchBySlot(page1, i, "row at slot " + i,
3254:                                ((i % 3) == 1), false);
3255:                    }
3256:                    t_util.t_checkFetchBySlot(page1, recordCount - 1, REC_002,
3257:                            false, false);
3258:                    if (((recordCount - 1) % 3) == 1)
3259:                        // one (the last one) of the deleted rows did not get copied over
3260:                        t_util.t_checkRecordCount(page1, recordCount,
3261:                                recordCount - deleted + 1);
3262:                    else
3263:                        t_util.t_checkRecordCount(page1, recordCount,
3264:                                recordCount - deleted);
3265:
3266:                    if (testRollback) {
3267:                        t_util.t_abort(t);
3268:
3269:                        c = t_util.t_openContainer(t, 0, cid, true);
3270:                        page1 = t_util.t_getPage(c, pid1);
3271:                        page2 = t_util.t_getPage(c, pid2);
3272:
3273:                        // the two inserted rows is rolled back by deletion
3274:                        t_util.t_checkFetchBySlot(page1, 0, REC_001, true,
3275:                                false);
3276:                        t_util.t_checkFetchBySlot(page1, 1, REC_002, true,
3277:                                false);
3278:                        t_util.t_checkRecordCount(page1, 2, 0);
3279:
3280:                        for (i = 0; i < recordCount; i++) {
3281:                            t_util.t_checkFetchBySlot(page2, i, "row at slot "
3282:                                    + i, ((i % 3) == 1), true);
3283:                        }
3284:                        t_util.t_checkRecordCount(page2, recordCount,
3285:                                recordCount - deleted);
3286:
3287:                        REPORT("tested roll back of copyAndPurge");
3288:                    }
3289:
3290:                    PASS("P016");
3291:                }
3292:
3293:                t_util.t_dropContainer(t, 0, cid); // cleanup
3294:                t_util.t_dropContainer(t, 0, cid2); // cleanup
3295:                t_util.t_commit(t);
3296:                t.close();
3297:            }
3298:
3299:            /*
3300:            	P017
3301:            	this test getInvalidRecordHandle and makeRecordHandle 
3302:
3303:            	@exception T_Fail Unexpected behaviour from the API
3304:            	@exception StandardException Unexpected exception from the implementation
3305:             */
3306:            protected void P017() throws StandardException, T_Fail {
3307:                Transaction t = t_util.t_startTransaction();
3308:
3309:                long cid = t_util.t_addContainer(t, 0);
3310:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3311:
3312:                Page page1 = t_util.t_getPage(c,
3313:                        ContainerHandle.FIRST_PAGE_NUMBER);
3314:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3315:
3316:                RecordHandle valid = t_util.t_insert(page1, row1);
3317:                RecordHandle special = page1
3318:                        .makeRecordHandle(RecordHandle.RECORD_ID_PROTECTION_HANDLE);
3319:
3320:                RecordHandle[] rhs = new RecordHandle[RecordHandle.FIRST_RECORD_ID];
3321:                rhs[0] = page1.getInvalidRecordHandle();
3322:                rhs[1] = page1
3323:                        .makeRecordHandle(RecordHandle.RECORD_ID_PROTECTION_HANDLE);
3324:                rhs[2] = page1
3325:                        .makeRecordHandle(RecordHandle.DEALLOCATE_PROTECTION_HANDLE);
3326:                rhs[3] = page1
3327:                        .makeRecordHandle(RecordHandle.PREVIOUS_KEY_HANDLE);
3328:                rhs[4] = page1
3329:                        .makeRecordHandle(RecordHandle.RESERVED4_RECORD_HANDLE);
3330:                rhs[5] = page1
3331:                        .makeRecordHandle(RecordHandle.RESERVED5_RECORD_HANDLE);
3332:
3333:                for (int i = 0; i < RecordHandle.FIRST_RECORD_ID; i++) {
3334:                    try {
3335:                        page1.recordExists(rhs[i], true);
3336:                        throw T_Fail
3337:                                .testFailMsg("record exists for invalid record "
3338:                                        + rhs[i]);
3339:                    } catch (StandardException se) {
3340:                        /* expected */
3341:                    }
3342:
3343:                    try {
3344:                        page1.fetch(rhs[i], new DataValueDescriptor[0],
3345:                                (FormatableBitSet) null, true);
3346:                        throw T_Fail.testFailMsg("fetched an invalid record "
3347:                                + rhs[i]);
3348:                    } catch (StandardException se) {
3349:                        /* expected */
3350:                    }
3351:
3352:                    try {
3353:                        page1.update(rhs[i], row1.getRow(),
3354:                                (FormatableBitSet) null);
3355:                        throw T_Fail.testFailMsg("updated an invalid record "
3356:                                + rhs[i]);
3357:                    } catch (StandardException se) {
3358:                        /* expected */
3359:                    }
3360:
3361:                    try {
3362:                        page1.update(rhs[i], row1.getRow(), BS_COL_0);
3363:                        throw T_Fail
3364:                                .testFailMsg("updated an invalid record field");
3365:                    } catch (StandardException se) {
3366:                        /* expected */
3367:                    }
3368:
3369:                    try {
3370:                        page1.delete(rhs[i], null);
3371:                        throw T_Fail.testFailMsg("delete an invalid record "
3372:                                + rhs[i]);
3373:                    } catch (StandardException se) {
3374:                        /* expected */
3375:                    }
3376:
3377:                    try {
3378:                        page1.fetchNumFields(rhs[i]);
3379:                        throw T_Fail
3380:                                .testFailMsg("fetch num fields on invalid record "
3381:                                        + rhs[i]);
3382:                    } catch (StandardException se) {
3383:                        /* expected */
3384:                    }
3385:
3386:                    try {
3387:                        page1.getSlotNumber(rhs[i]);
3388:                        throw T_Fail
3389:                                .testFailMsg("got slot number of invalid record "
3390:                                        + rhs[i]);
3391:                    } catch (StandardException se) {
3392:                        /* expected */
3393:                    }
3394:
3395:                }
3396:                PASS("P017");
3397:
3398:                t_util.t_dropContainer(t, 0, cid);
3399:                t_util.t_commit(t);
3400:                t.close();
3401:            }
3402:
3403:            /*
3404:            	P018
3405:
3406:            	this test exercises track # 590, test that copyRows successfully
3407:                notices that a copy can't be done.
3408:
3409:            	@exception T_Fail Unexpected behaviour from the API
3410:            	@exception StandardException Unexpected exception from the implementation
3411:             */
3412:            protected void P018() throws StandardException, T_Fail {
3413:                Transaction t = t_util.t_startTransaction();
3414:
3415:                // create container with 0 spare space, 1 minimum record size to easily
3416:                // force absolutely full page.  Record id's are not reusable.
3417:                long cid = t_util.t_addContainer(t, 0, 4096, 0, 1, false);
3418:
3419:                t_util.t_commit(t);
3420:
3421:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3422:
3423:                Page page1 = t_util.t_getPage(c,
3424:                        ContainerHandle.FIRST_PAGE_NUMBER);
3425:                Page page2 = t_util.t_addPage(c);
3426:                long pid1 = page1.getPageNumber();
3427:                long pid2 = page2.getPageNumber();
3428:
3429:                t_util.t_checkEmptyPage(page2);
3430:
3431:                // first fill up page 1
3432:
3433:                int i = 0;
3434:                int deleted = 0;
3435:                RecordHandle rh;
3436:
3437:                T_RawStoreRow row;
3438:
3439:                // first insert and purge 100 rows, setting the next recid to be 
3440:                // greater than 64.  This will cause the next
3441:                // recid to be allocated to be greater than 64, this means 
3442:                // that new recid's added to the page take 2 bytes rather than 1.
3443:                for (i = 0; i < 100; i++) {
3444:                    row = new T_RawStoreRow("r" + i);
3445:
3446:                    rh = t_util.t_insertAtSlot(page1, 0, row);
3447:
3448:                    page1.purgeAtSlot(0, 1, logDataForPurges);
3449:                }
3450:
3451:                // fill up another page starting with "small" record id's.
3452:                for (i = 0; true; i++) {
3453:                    row = new T_RawStoreRow("r" + i);
3454:
3455:                    rh = t_util.t_insertAtSlot(page2, i, row);
3456:
3457:                    if (rh == null)
3458:                        break;
3459:                }
3460:
3461:                // an attempt to copy all the rows should get an error, because the
3462:                // recid's are bigger so all the records will not fit.
3463:                try {
3464:                    page2.copyAndPurge(page1, 0, page2.recordCount(), 0);
3465:
3466:                    throw T_Fail
3467:                            .testFailMsg("copying rows with expanding recids should cause an exception");
3468:                } catch (StandardException se) {
3469:                    // expect a out of space error.
3470:
3471:                }
3472:
3473:                // cleanup after first part of test.
3474:                t_util.t_dropContainer(t, 0, cid);
3475:                t_util.t_commit(t);
3476:
3477:                // Now test that with the reusable record id's that the copy works.
3478:
3479:                // create container with 0 spare space, 1 minimum record size to easily
3480:                // force absolutely full page.  This container will allow 
3481:                // reusable record id's which will mean the copy should succeed.
3482:                cid = t_util.t_addContainer(t, 0, 4096, 0, 1, true);
3483:
3484:                t_util.t_commit(t);
3485:
3486:                c = t_util.t_openContainer(t, 0, cid, true);
3487:
3488:                page1 = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3489:                page2 = t_util.t_addPage(c);
3490:                pid1 = page1.getPageNumber();
3491:                pid2 = page2.getPageNumber();
3492:
3493:                t_util.t_checkEmptyPage(page2);
3494:
3495:                // first fill up page 1
3496:
3497:                i = 0;
3498:
3499:                // first insert and purge 100 rows, setting the next recid to be 
3500:                // greater than 64.  This will cause the next
3501:                // recid to be allocated to be greater than 64, this means 
3502:                // that new recid's added to the page take 2 bytes rather than 1.
3503:                for (i = 0; i < 100; i++) {
3504:                    row = new T_RawStoreRow("r" + i);
3505:
3506:                    rh = t_util.t_insertAtSlot(page1, 0, row);
3507:
3508:                    page1.purgeAtSlot(0, 1, logDataForPurges);
3509:                }
3510:
3511:                // fill up another page starting with "small" record id's.
3512:                for (i = 0; true; i++) {
3513:                    row = new T_RawStoreRow("r" + i);
3514:
3515:                    rh = t_util.t_insertAtSlot(page2, i, row);
3516:
3517:                    if (rh == null)
3518:                        break;
3519:                }
3520:                long pnum2 = page2.getPageNumber();
3521:                int numrows = page2.recordCount();
3522:
3523:                // an attempt to copy all the rows should  get an error, 
3524:                try {
3525:                    // This copy should not succeed.
3526:                    page2.copyAndPurge(page1, 0, page2.recordCount(), 0);
3527:
3528:                    throw T_Fail
3529:                            .testFailMsg("copying rows with expanding recids should cause an exception");
3530:                } catch (StandardException se) {
3531:                    // expect a out of space error.
3532:                }
3533:
3534:                // now deallocated this page and get it to go thru a reuse cycle
3535:                t_util.t_removePage(c, page1);
3536:                t_util.t_commit(t);
3537:
3538:                c = t_util.t_openContainer(t, 0, cid, true);
3539:                page1 = t_util.t_addPage(c);
3540:                int tries = 0;
3541:                while (page1.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER) {
3542:                    REPORT("getting page " + page1.getPageNumber());
3543:
3544:                    t_util.t_commit(t);
3545:
3546:                    if (tries++ > 100)
3547:                        throw T_Fail
3548:                                .testFailMsg("failed to get back first page after "
3549:                                        + tries + " tries");
3550:                    c = t_util.t_openContainer(t, 0, cid, true);
3551:                    page1 = t_util.t_addPage(c);
3552:                }
3553:                page2 = t_util.t_getPage(c, pnum2);
3554:
3555:                t_util.t_checkRecordCount(page2, numrows, numrows);
3556:                t_util.t_checkEmptyPage(page1);
3557:
3558:                // now the attempt to copy all the rows should succeed
3559:                try {
3560:                    page2.copyAndPurge(page1, 0, page2.recordCount(), 0);
3561:                } catch (StandardException se) {
3562:                    throw T_Fail
3563:                            .testFailMsg("copying rows with non-expanding recids should not cause an exception");
3564:                }
3565:
3566:                PASS("P018");
3567:
3568:                t_util.t_dropContainer(t, 0, cid); // cleanup
3569:                t_util.t_commit(t);
3570:                t.close();
3571:            }
3572:
3573:            /**
3574:            	Test bulk load and preallocation
3575:            	@exception T_Fail Unexpected behaviour from the API
3576:            	@exception StandardException Unexpected exception from the implementation
3577:             */
3578:            protected void P019() throws StandardException, T_Fail {
3579:                Transaction t = t_util.t_startTransaction();
3580:
3581:                long cid = t_util.t_addContainer(t, 0, 4096, 0, 1, false);
3582:                t_util.t_commit(t);
3583:
3584:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3585:
3586:                // add page for bulk load
3587:                Page p1 = c.addPage(ContainerHandle.ADD_PAGE_BULK);
3588:                long pnum1 = p1.getPageNumber();
3589:                p1.unlatch();
3590:
3591:                // since the interface does not guarentee that anything special will
3592:                // actually happen, can't really test that. Just make sure that
3593:                // everything else works
3594:                Page p2 = c.addPage();
3595:                long pnum2 = p2.getPageNumber();
3596:                p2.unlatch();
3597:
3598:                Page p3 = c.addPage(ContainerHandle.ADD_PAGE_BULK);
3599:                long pnum3 = p3.getPageNumber();
3600:                p3.unlatch();
3601:
3602:                Page p = c.getFirstPage(); // this is the first page that came with the
3603:                // container when it was created
3604:
3605:                try {
3606:                    long pnum0 = p.getPageNumber();
3607:                    p.unlatch();
3608:                    p = c.getNextPage(pnum0);
3609:                    if (p.getPageNumber() != pnum1)
3610:                        throw T_Fail.testFailMsg("expected pagenum " + pnum1
3611:                                + " got " + p.getPageNumber());
3612:                    p.unlatch();
3613:                    p = null;
3614:
3615:                    p = c.getNextPage(pnum1);
3616:                    if (p.getPageNumber() != pnum2)
3617:                        throw T_Fail.testFailMsg("expected pagenum " + pnum2
3618:                                + " got " + p.getPageNumber());
3619:                    p.unlatch();
3620:                    p = null;
3621:
3622:                    p = c.getNextPage(pnum2);
3623:                    if (p.getPageNumber() != pnum3)
3624:                        throw T_Fail.testFailMsg("expected pagenum " + pnum3
3625:                                + " got " + p.getPageNumber());
3626:                    p.unlatch();
3627:                    p = null;
3628:
3629:                    p = c.getNextPage(pnum3);
3630:                    if (p != null)
3631:                        throw T_Fail.testFailMsg("expected null page after "
3632:                                + pnum3 + " got " + p.getPageNumber());
3633:
3634:                    // make sure rollback is unaffected
3635:                    if (testRollback) {
3636:                        t_util.t_abort(t);
3637:                        c = t_util.t_openContainer(t, 0, cid, true);
3638:                        p = t_util.t_getPage(c, pnum0);
3639:                        t_util.t_checkEmptyPage(p);
3640:                        p.unlatch();
3641:                        p = null;
3642:
3643:                        p = t_util.t_getPage(c, pnum1);
3644:                        t_util.t_checkEmptyPage(p);
3645:                        p.unlatch();
3646:                        p = null;
3647:
3648:                        p = t_util.t_getPage(c, pnum2);
3649:                        t_util.t_checkEmptyPage(p);
3650:                        p.unlatch();
3651:                        p = null;
3652:
3653:                        p = t_util.t_getPage(c, pnum3);
3654:                        t_util.t_checkEmptyPage(p);
3655:                        p.unlatch();
3656:                        p = null;
3657:
3658:                        p = t_util.t_getLastPage(c);
3659:                        if (p.getPageNumber() != pnum3)
3660:                            throw T_Fail.testFailMsg("expect last page to be "
3661:                                    + pnum3 + " got " + p.getPageNumber());
3662:                        p.unlatch();
3663:                        p = null;
3664:                    }
3665:
3666:                    t_util.t_dropContainer(t, 0, cid); // cleanup
3667:
3668:                } finally {
3669:                    if (p != null)
3670:                        p.unlatch();
3671:                    p = null;
3672:                    t_util.t_commit(t);
3673:                    t.close();
3674:                }
3675:                PASS("P019 - container " + cid);
3676:
3677:            }
3678:
3679:            /**
3680:            	Test create container with initial page set to 100 pages
3681:            	@exception T_Fail Unexpected behaviour from the API
3682:            	@exception StandardException Unexpected exception from the implementation
3683:             */
3684:            protected void P020() throws StandardException, T_Fail {
3685:                Transaction t = t_util.t_startTransaction();
3686:                Properties tableProperties = new Properties();
3687:                tableProperties.put(Property.PAGE_SIZE_PARAMETER, Integer
3688:                        .toString(4096));
3689:                tableProperties.put(RawStoreFactory.CONTAINER_INITIAL_PAGES,
3690:                        Integer.toString(100));
3691:
3692:                long cid = t_util.t_addContainer(t, 0, tableProperties);
3693:                if (cid < 0)
3694:                    throw T_Fail.testFailMsg("addContainer");
3695:
3696:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3697:
3698:                Page p1 = c.getFirstPage();
3699:                if (p1.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
3700:                    throw T_Fail
3701:                            .testFailMsg("expect first page to have FIRST_PAGE_NUMBER");
3702:                p1.unlatch();
3703:
3704:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3705:                    throw T_Fail
3706:                            .testFailMsg("expect to have only 1 page allocated");
3707:
3708:                t_util.t_dropContainer(t, 0, cid); // cleanup
3709:                t_util.t_commit(t);
3710:                t.close();
3711:                PASS("P020 - container " + cid);
3712:            }
3713:
3714:            /**
3715:            	Test preAllocate
3716:            	@exception T_Fail Unexpected behaviour from the API
3717:            	@exception StandardException Unexpected exception from the implementation
3718:             */
3719:            protected void P021() throws StandardException, T_Fail {
3720:                Transaction t = t_util.t_startTransaction();
3721:                long cid = t_util.t_addContainer(t, 0, 4096);
3722:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3723:
3724:                // now preallocate 10 pages
3725:                c.preAllocate(10);
3726:
3727:                Page p1 = c.getFirstPage();
3728:                if (p1.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
3729:                    throw T_Fail
3730:                            .testFailMsg("expect first page to have FIRST_PAGE_NUMBER");
3731:                p1.unlatch();
3732:
3733:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3734:                    throw T_Fail
3735:                            .testFailMsg("expect to have only 1 page allocated");
3736:
3737:                t_util.t_dropContainer(t, 0, cid); // cleanup
3738:                t_util.t_commit(t);
3739:                t.close();
3740:                PASS("P021 - container " + cid);
3741:            }
3742:
3743:            /**
3744:            	Test minimumRecordSize: this is to make sure that logRow and storeRecord
3745:            	are consistent with each other when it comes to reserve space.
3746:
3747:            	@exception T_Fail Unexpected behaviour from the API
3748:            	@exception StandardException Unexpected exception from the implementation
3749:             */
3750:            protected void P022() throws StandardException, T_Fail {
3751:                Transaction t = t_util.t_startTransaction();
3752:
3753:                // create container with 4096 page size, 0 spare space, 9 minimum record size
3754:                long cid = t_util.t_addContainer(t, 0, 4096, 0, 9, false);
3755:
3756:                t_util.t_commit(t);
3757:
3758:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3759:
3760:                Page page1 = t_util.t_getPage(c,
3761:                        ContainerHandle.FIRST_PAGE_NUMBER);
3762:
3763:                RecordHandle rh;
3764:                T_RawStoreRow row;
3765:
3766:                // insert records to fill the page.
3767:                for (int i = 0; i < 60; i++) {
3768:                    row = new T_RawStoreRow("r" + i);
3769:                    rh = t_util.t_insertAtSlot(page1, 0, row);
3770:                }
3771:
3772:                // cleanup after first part of test.
3773:                t_util.t_dropContainer(t, 0, cid); // cleanup
3774:                t_util.t_commit(t);
3775:                t.close();
3776:                PASS("P022");
3777:            }
3778:
3779:            /**
3780:            	Test overflowThreshold: this is to make sure that logRow and storeRecord
3781:            	are consistent with each other when it comes to reserve space.
3782:
3783:            	@exception T_Fail Unexpected behaviour from the API
3784:            	@exception StandardException Unexpected exception from the implementation
3785:             */
3786:            protected void P023(int segment) throws StandardException, T_Fail {
3787:
3788:                Transaction t = t_util.t_startTransaction();
3789:                // create a container with 1K page, 0 spareSpace, and 0 minimumRecordSize
3790:                long cid = t_util.t_addContainer(t, segment, 4096, 0, 0, false);
3791:                t_util.t_commit(t);
3792:
3793:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
3794:                        true);
3795:                Page page = t_util.t_getPage(c,
3796:                        ContainerHandle.FIRST_PAGE_NUMBER);
3797:                int overflowThreshold = 50;
3798:
3799:                t_util.t_checkEmptyPage(page);
3800:
3801:                // use default insert, not allowing overflow
3802:                int insertFlag = Page.INSERT_INITIAL | Page.INSERT_DEFAULT;
3803:
3804:                // test 1:
3805:                // create a row that's under the threshold
3806:                T_RawStoreRow r1 = new T_RawStoreRow(1);
3807:                r1.setColumn(0, 200, REC_001);
3808:                // insert the row twice, should fit on 1 page
3809:                RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
3810:                        (byte) insertFlag, overflowThreshold);
3811:                if (rh1 == null)
3812:                    throw T_Fail
3813:                            .testFailMsg("insert of first long row failed.");
3814:                RecordHandle rh2 = t_util.t_insertAtSlot(page, 1, r1,
3815:                        (byte) insertFlag, overflowThreshold);
3816:                if (rh2 == null)
3817:                    throw T_Fail
3818:                            .testFailMsg("insert of second long row failed.");
3819:                t_util.t_checkFetch(page, rh1, r1);
3820:                t_util.t_checkFetch(page, rh2, r1);
3821:                page.unlatch();
3822:                page = null;
3823:                REPORT("test 1: 2 rows under threshold inserted...");
3824:
3825:                // test 2:
3826:                // get a new page
3827:                page = t_util.t_addPage(c);
3828:                // create a row that's over the threshold
3829:                T_RawStoreRow r2 = new T_RawStoreRow(1);
3830:                r2.setColumn(0, 2000, REC_001);
3831:                // insert the row twice, should fail both inserts
3832:                rh1 = t_util.t_insertAtSlot(page, 0, r2, (byte) insertFlag,
3833:                        overflowThreshold);
3834:                if (rh1 != null) {
3835:                    throw T_Fail
3836:                            .testFailMsg("insert of 1st over threshold row should failed.");
3837:                }
3838:                rh2 = t_util.t_insertAtSlot(page, 0, r2, (byte) insertFlag,
3839:                        overflowThreshold);
3840:                if (rh2 != null)
3841:                    throw T_Fail
3842:                            .testFailMsg("insert of 2nd over threshold row should failed.");
3843:                page.unlatch();
3844:                page = null;
3845:                REPORT("test 2: 2 rows over threshold not inserted...");
3846:
3847:                // test 3:
3848:                // get a new page
3849:                page = t_util.t_addPage(c);
3850:                // create a row with 2 columns, each column is under the threshold,
3851:                // and the row is also under the threshold
3852:                T_RawStoreRow r3 = new T_RawStoreRow(2);
3853:                // create a row that's under the threshold
3854:                r3.setColumn(0, 400, REC_001);
3855:                r3.setColumn(1, 400, REC_001);
3856:                // insert the row twice, should fit on 1 page
3857:                rh1 = t_util.t_insertAtSlot(page, 0, r3, (byte) insertFlag,
3858:                        overflowThreshold);
3859:                if (rh1 == null)
3860:                    throw T_Fail
3861:                            .testFailMsg("insert of 1st 2-column row failed.");
3862:                rh2 = t_util.t_insertAtSlot(page, 1, r3, (byte) insertFlag,
3863:                        overflowThreshold);
3864:                if (rh2 == null)
3865:                    throw T_Fail
3866:                            .testFailMsg("insert of 2nd 2-column row failed.");
3867:                page.unlatch();
3868:                page = null;
3869:                REPORT("test 3: 2 rows with 2 columns under the threshold inserted...");
3870:
3871:                // test 4:
3872:                // get a new page
3873:                page = t_util.t_addPage(c);
3874:                // create a row with 2 columns, each column is under the threshold,
3875:                // but the row is over the threshold
3876:                T_RawStoreRow r4 = new T_RawStoreRow(2);
3877:                // create a row that's under the threshold
3878:                r4.setColumn(0, 800, REC_001);
3879:                r4.setColumn(1, 800, REC_001);
3880:                // insert the row twice, should fit on 1 page
3881:                rh1 = t_util.t_insertAtSlot(page, 0, r4, (byte) insertFlag,
3882:                        overflowThreshold);
3883:                if (rh1 != null) {
3884:                    SanityManager.DEBUG_PRINT("bug", "page = " + page);
3885:                    throw T_Fail
3886:                            .testFailMsg("insert of 1st 2-column row (OT) should failed.");
3887:                }
3888:                rh2 = t_util.t_insertAtSlot(page, 0, r4, (byte) insertFlag,
3889:                        overflowThreshold);
3890:                if (rh2 != null)
3891:                    throw T_Fail
3892:                            .testFailMsg("insert of 2nd 2-column row (OT) should failed.");
3893:                page.unlatch();
3894:                page = null;
3895:                REPORT("test 4: 2 rows with 2 columns over the threshold not inserted...");
3896:
3897:                // cleanup after first part of test.
3898:                t_util.t_dropContainer(t, segment, cid); // cleanup
3899:                t_util.t_commit(t);
3900:                t.close();
3901:                PASS("P023");
3902:            }
3903:
3904:            /**
3905:            	Insert small rows and update them so that they overflow a page.
3906:
3907:            	@exception T_Fail Unexpected behaviour from the API
3908:            	@exception StandardException Unexpected exception from the implementation
3909:             */
3910:            protected void P030(long segment) throws StandardException, T_Fail {
3911:
3912:                Transaction t = t_util.t_startTransaction();
3913:
3914:                long cid = t_util.t_addContainer(t, segment, 4096);
3915:
3916:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
3917:                        true);
3918:                Page page = t_util.t_getPage(c,
3919:                        ContainerHandle.FIRST_PAGE_NUMBER);
3920:                t_util.t_checkEmptyPage(page);
3921:
3922:                T_RawStoreRow r0 = new T_RawStoreRow(0);
3923:                T_RawStoreRow r1 = new T_RawStoreRow((String) null);
3924:                T_RawStoreRow r2 = new T_RawStoreRow("0123456789");
3925:
3926:                t_util.t_insertAtSlot(page, 0, r0);
3927:                t_util.t_insertAtSlot(page, 1, r1);
3928:                t_util.t_insertAtSlot(page, 2, r2);
3929:
3930:                t_util.t_checkRecordCount(page, 3, 3);
3931:                page.unlatch();
3932:                page = null;
3933:
3934:                // check there is only one page
3935:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3936:                    throw T_Fail
3937:                            .testFailMsg("an extra page has appeared in the container");
3938:                t_util.t_commit(t);
3939:
3940:                //
3941:                // Update the row at slot 1 so that it fills most of the page
3942:                //
3943:                c = t_util.t_openContainer(t, segment, cid, true);
3944:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3945:
3946:                t_util.t_checkStringLengthFetch(page, 1, -1);
3947:                t_util.t_checkStringLengthFetch(page, 2, 10);
3948:
3949:                t_util.t_checkFieldCount(page, 0, 0);
3950:                t_util.t_checkFieldCount(page, 1, 1);
3951:                t_util.t_checkFieldCount(page, 2, 1);
3952:
3953:                T_RawStoreRow r1u = new T_RawStoreRow(String
3954:                        .valueOf(new char[1937]));
3955:                page.updateAtSlot(1, r1u.getRow(), (FormatableBitSet) null);
3956:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
3957:                t_util.t_checkStringLengthFetch(page, 2, 10); // on page 1
3958:                t_util.t_checkFieldCount(page, 0, 0);
3959:                t_util.t_checkFieldCount(page, 1, 1);
3960:                t_util.t_checkFieldCount(page, 2, 1);
3961:                page.unlatch();
3962:                // check there is only one page
3963:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3964:                    throw T_Fail
3965:                            .testFailMsg("an extra page has appeared in the container");
3966:                t_util.t_commit(t);
3967:
3968:                //
3969:                // Update the row at slot 2 so that it overflows
3970:                //
3971:                c = t_util.t_openContainer(t, segment, cid, true);
3972:                T_RawStoreRow r2u = new T_RawStoreRow(String
3973:                        .valueOf(new char[1099])); // stored length is twice string lenght + 2
3974:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3975:                page.updateAtSlot(2, r2u.getRow(), (FormatableBitSet) null);
3976:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
3977:                t_util.t_checkStringLengthFetch(page, 2, 1099); // on first overflow page
3978:                t_util.t_checkFieldCount(page, 0, 0);
3979:                t_util.t_checkFieldCount(page, 1, 1);
3980:                t_util.t_checkFieldCount(page, 2, 1);
3981:                page.unlatch();
3982:                // check there is only one page
3983:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3984:                    throw T_Fail
3985:                            .testFailMsg("an extra page has appeared in the container");
3986:                t_util.t_commit(t);
3987:
3988:                c = t_util.t_openContainer(t, segment, cid, true);
3989:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3990:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
3991:                t_util.t_checkStringLengthFetch(page, 2, 1099); // on first overflow page
3992:                t_util.t_checkFieldCount(page, 0, 0);
3993:                t_util.t_checkFieldCount(page, 1, 1);
3994:                t_util.t_checkFieldCount(page, 2, 1);
3995:                // check there is only one page
3996:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
3997:                    throw T_Fail
3998:                            .testFailMsg("an extra page has appeared in the container");
3999:                t_util.t_commit(t);
4000:
4001:                //
4002:                // Update the row at slot 0 so that it overflows onto the same page as the first
4003:                // overflow.
4004:                //
4005:                c = t_util.t_openContainer(t, segment, cid, true);
4006:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
4007:                T_RawStoreRow r0u = new T_RawStoreRow(String
4008:                        .valueOf(new char[423]));
4009:                page.updateAtSlot(0, r0u.getRow(), (FormatableBitSet) null);
4010:                t_util.t_checkStringLengthFetch(page, 0, 423); // on first overflow page
4011:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
4012:                t_util.t_checkStringLengthFetch(page, 2, 1099); // on first overflow page
4013:                t_util.t_checkFieldCount(page, 0, 1);
4014:                t_util.t_checkFieldCount(page, 1, 1);
4015:                t_util.t_checkFieldCount(page, 2, 1);
4016:                page.unlatch();
4017:                // check there is only one page
4018:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
4019:                    throw T_Fail
4020:                            .testFailMsg("an extra page has appeared in the container");
4021:
4022:                t_util.t_commit(t);
4023:
4024:                //
4025:                // Update the row at slot 0 that has already been overflowed
4026:                // but keeping it on the same page
4027:                //
4028:                c = t_util.t_openContainer(t, segment, cid, true);
4029:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
4030:                r0u = new T_RawStoreRow(String.valueOf(new char[399]));
4031:                page.updateAtSlot(0, r0u.getRow(), (FormatableBitSet) null);
4032:                t_util.t_checkStringLengthFetch(page, 0, 399); // on first overflow page
4033:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
4034:                t_util.t_checkStringLengthFetch(page, 2, 1099); // on first overflow page
4035:                t_util.t_checkFieldCount(page, 0, 1);
4036:                t_util.t_checkFieldCount(page, 1, 1);
4037:                t_util.t_checkFieldCount(page, 2, 1);
4038:                page.unlatch();
4039:                // check there is only one page
4040:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
4041:                    throw T_Fail
4042:                            .testFailMsg("an extra page has appeared in the container");
4043:
4044:                //
4045:                // Update the row at slot 0 that has already been overflowed
4046:                // but moving it to a new page
4047:                //
4048:                c = t_util.t_openContainer(t, segment, cid, true);
4049:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
4050:                r0u = new T_RawStoreRow(String.valueOf(new char[1400]));
4051:                page.updateAtSlot(0, r0u.getRow(), (FormatableBitSet) null);
4052:                t_util.t_checkStringLengthFetch(page, 0, 1400); // on second overflow page
4053:                t_util.t_checkStringLengthFetch(page, 1, 1937); // on page 1
4054:                t_util.t_checkStringLengthFetch(page, 2, 1099); // on first overflow page
4055:                t_util.t_checkFieldCount(page, 0, 1);
4056:                t_util.t_checkFieldCount(page, 1, 1);
4057:                t_util.t_checkFieldCount(page, 2, 1);
4058:                page.unlatch();
4059:                // check there is only one page
4060:                if (c.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
4061:                    throw T_Fail
4062:                            .testFailMsg("an extra page has appeared in the container");
4063:
4064:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4065:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4066:                }
4067:
4068:                t_util.t_commit(t);
4069:
4070:                t.close();
4071:
4072:                PASS("P030: segment = " + segment);
4073:            }
4074:
4075:            /**
4076:            	Insert 4-column long rows into 1K pages, each column is less than a page.
4077:
4078:            	@exception T_Fail Unexpected behaviour from the API
4079:            	@exception StandardException Unexpected exception from the implementation
4080:             */
4081:            protected void P031(long segment) throws StandardException, T_Fail {
4082:
4083:                Transaction t = t_util.t_startTransaction();
4084:
4085:                long cid = t_util.t_addContainer(t, segment, 4096);
4086:
4087:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4088:                        true);
4089:                Page page = t_util.t_getPage(c,
4090:                        ContainerHandle.FIRST_PAGE_NUMBER);
4091:                t_util.t_checkEmptyPage(page);
4092:
4093:                T_RawStoreRow r0 = new T_RawStoreRow(4);
4094:                r0.setColumn(0, 256, REC_001);
4095:                r0.setColumn(1, 256, REC_002);
4096:                r0.setColumn(2, 256, REC_003);
4097:                r0.setColumn(3, 256, REC_004);
4098:
4099:                int insertFlag = Page.INSERT_INITIAL;
4100:                insertFlag |= Page.INSERT_OVERFLOW;
4101:
4102:                RecordHandle rh0 = null;
4103:                try {
4104:                    rh0 = t_util.t_insertAtSlot(page, 0, r0, (byte) insertFlag);
4105:                } catch (StandardException se) {
4106:                    throw T_Fail.testFailMsg("insert of long row failed.");
4107:                }
4108:
4109:                if (rh0 == null)
4110:                    throw T_Fail
4111:                            .testFailMsg("insert of first long row failed.");
4112:                else {
4113:                    REPORT("about to check fetch...");
4114:                    DataValueDescriptor column = new SQLChar();
4115:                    t_util.t_checkFetchColFromSlot(page,
4116:                            page.FIRST_SLOT_NUMBER, 0, column, false, REC_001,
4117:                            256);
4118:                    t_util.t_checkFetchColFromSlot(page,
4119:                            page.FIRST_SLOT_NUMBER, 1, column, false, REC_002,
4120:                            256);
4121:                    t_util.t_checkFetchColFromSlot(page,
4122:                            page.FIRST_SLOT_NUMBER, 2, column, false, REC_003,
4123:                            256);
4124:                    t_util.t_checkFetchColFromSlot(page,
4125:                            page.FIRST_SLOT_NUMBER, 3, column, false, REC_004,
4126:                            256);
4127:                }
4128:
4129:                page.unlatch();
4130:
4131:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4132:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4133:                }
4134:
4135:                t_util.t_commit(t);
4136:
4137:                t.close();
4138:
4139:                PASS("P031: segment = " + segment);
4140:            }
4141:
4142:            /**
4143:            	Insert 60-column long rows into 1K pages, each column is less than a page.
4144:
4145:            	@exception T_Fail Unexpected behaviour from the API
4146:            	@exception StandardException Unexpected exception from the implementation
4147:             */
4148:            protected void P032(long segment) throws StandardException, T_Fail {
4149:
4150:                Transaction t = t_util.t_startTransaction();
4151:
4152:                long cid = t_util.t_addContainer(t, segment, 4096);
4153:
4154:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4155:                        true);
4156:                Page page = t_util.t_getPage(c,
4157:                        ContainerHandle.FIRST_PAGE_NUMBER);
4158:                t_util.t_checkEmptyPage(page);
4159:
4160:                int insertFlag = Page.INSERT_INITIAL;
4161:                insertFlag |= Page.INSERT_OVERFLOW;
4162:
4163:                T_RawStoreRow r0 = new T_RawStoreRow(60);
4164:                for (int i = 0; i < 60; i++) {
4165:                    r0.setColumn(i, 1200, REC_001);
4166:                }
4167:
4168:                RecordHandle rh0 = null;
4169:                try {
4170:                    rh0 = t_util.t_insertAtSlot(page, 0, r0, (byte) insertFlag);
4171:                } catch (StandardException se) {
4172:                    throw T_Fail
4173:                            .testFailMsg("insert of first long row failed.");
4174:                }
4175:
4176:                if (rh0 == null)
4177:                    throw T_Fail
4178:                            .testFailMsg("insert of a 60-column (300 bytes per column) row failed.");
4179:                else {
4180:                    REPORT("about to check fetch the first long row inserted...");
4181:                    DataValueDescriptor column = new SQLChar();
4182:                    for (int i = 0; i < 60; i++) {
4183:                        t_util.t_checkFetchColFromSlot(page,
4184:                                page.FIRST_SLOT_NUMBER, i, column, false,
4185:                                REC_001, 1200);
4186:                    }
4187:                }
4188:
4189:                // create a new row with 60 columns, and each column has REC_001 = "McLaren"
4190:                for (int i = 0; i < 60; i++) {
4191:                    r0.setColumn(i, REC_001);
4192:                }
4193:
4194:                RecordHandle rh1 = null;
4195:                try {
4196:                    rh1 = t_util.t_insertAtSlot(page, 1, r0, (byte) insertFlag);
4197:                } catch (StandardException se) {
4198:                    throw T_Fail
4199:                            .testFailMsg("insert of second long row failed.");
4200:                }
4201:
4202:                if (rh1 == null) {
4203:                    throw T_Fail
4204:                            .testFailMsg("insert of a 60-column (~10 bytes per column) row failed.");
4205:                } else {
4206:                    REPORT("about to check fetch the second long row inserted ...");
4207:                    DataValueDescriptor column = new SQLChar();
4208:                    for (int i = 0; i < 60; i++) {
4209:                        t_util.t_checkFetchColFromSlot(page, 1, i, column,
4210:                                false, REC_001);
4211:                    }
4212:                }
4213:
4214:                page.unlatch();
4215:
4216:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4217:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4218:                }
4219:
4220:                t_util.t_commit(t);
4221:
4222:                t.close();
4223:
4224:                PASS("P032: segment = " + segment);
4225:            }
4226:
4227:            /**
4228:            	Insert 100-column long rows into 1K pages, each column is less than a page.
4229:
4230:            	@exception T_Fail Unexpected behaviour from the API
4231:            	@exception StandardException Unexpected exception from the implementation
4232:             */
4233:            protected void P033(long segment) throws StandardException, T_Fail {
4234:
4235:                Transaction t = t_util.t_startTransaction();
4236:
4237:                long cid = t_util.t_addContainer(t, segment, 4096);
4238:
4239:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4240:                        true);
4241:                Page page = t_util.t_getPage(c,
4242:                        ContainerHandle.FIRST_PAGE_NUMBER);
4243:                try {
4244:                    t_util.t_checkEmptyPage(page);
4245:
4246:                    T_RawStoreRow r0 = new T_RawStoreRow(100);
4247:                    for (int i = 0; i < 100; i++) {
4248:                        r0.setColumn(i, REC_007);
4249:                    }
4250:
4251:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
4252:
4253:                    RecordHandle rh0 = null;
4254:                    try {
4255:                        rh0 = t_util.t_insertAtSlot(page, 0, r0,
4256:                                (byte) insertFlag);
4257:                    } catch (StandardException se) {
4258:                        throw T_Fail.testFailMsg("insert of long row failed.");
4259:                    }
4260:
4261:                    if (rh0 == null)
4262:                        throw T_Fail
4263:                                .testFailMsg("insert of first long row failed.");
4264:                    else {
4265:                        REPORT("about to check fetch...");
4266:                        DataValueDescriptor column = new SQLChar();
4267:                        for (int i = 0; i < 100; i++) {
4268:                            t_util.t_checkFetchColFromSlot(page,
4269:                                    page.FIRST_SLOT_NUMBER, i, column, false,
4270:                                    REC_007);
4271:                        }
4272:                    }
4273:
4274:                    page.unlatch();
4275:                    page = null;
4276:                    if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4277:                        t_util.t_dropContainer(t, segment, cid); // cleanup
4278:                    }
4279:
4280:                } finally {
4281:                    if (page != null)
4282:                        page.unlatch();
4283:                    t_util.t_commit(t);
4284:                    t.close();
4285:                }
4286:
4287:                PASS("P033: segment = " + segment);
4288:            }
4289:
4290:            /**
4291:            	Insert 401 column long row with many small columns in the beginning,
4292:            	and one large column at the end into 4K pages.
4293:
4294:            	@exception T_Fail Unexpected behaviour from the API
4295:            	@exception StandardException Unexpected exception from the implementation
4296:             */
4297:            protected void P034(long segment) throws StandardException, T_Fail {
4298:
4299:                Transaction t = t_util.t_startTransaction();
4300:
4301:                long cid = t_util.t_addContainer(t, segment, 4096);
4302:
4303:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4304:                        true);
4305:                Page page = t_util.t_getPage(c,
4306:                        ContainerHandle.FIRST_PAGE_NUMBER);
4307:                try {
4308:                    t_util.t_checkEmptyPage(page);
4309:
4310:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
4311:
4312:                    T_RawStoreRow r1 = new T_RawStoreRow(401);
4313:                    for (int i = 0; i < 400; i++)
4314:                        r1.setColumn(i, REC_001);
4315:                    r1.setColumn(400, 1500, REC_001);
4316:                    RecordHandle rh = t_util.t_insertAtSlot(page, 0, r1,
4317:                            (byte) insertFlag);
4318:                    t_util.t_checkFetch(page, rh, r1);
4319:                    page.unlatch();
4320:                    page = null;
4321:                    if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4322:                        t_util.t_dropContainer(t, segment, cid); // cleanup
4323:                    }
4324:
4325:                } finally {
4326:                    if (page != null)
4327:                        page.unlatch();
4328:
4329:                    t_util.t_commit(t);
4330:                    t.close();
4331:                }
4332:
4333:                PASS("P034: segment = " + segment);
4334:            }
4335:
4336:            /**
4337:            	Insert a single long column long row into a 1K page.
4338:
4339:            	@exception T_Fail Unexpected behaviour from the API
4340:            	@exception StandardException Unexpected exception from the implementation
4341:             */
4342:            protected void P035(long segment) throws StandardException, T_Fail {
4343:
4344:                Transaction t = t_util.t_startTransaction();
4345:
4346:                long cid = t_util.t_addContainer(t, segment, 4096);
4347:
4348:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4349:                        true);
4350:                Page page = t_util.t_getPage(c,
4351:                        ContainerHandle.FIRST_PAGE_NUMBER);
4352:                try {
4353:                    t_util.t_checkEmptyPage(page);
4354:
4355:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
4356:
4357:                    T_RawStoreRow r1 = new T_RawStoreRow(1);
4358:                    // insert a long column
4359:                    r1.setColumn(0, 500, REC_001);
4360:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
4361:                            (byte) insertFlag);
4362:                    t_util.t_checkFetch(page, rh1, r1);
4363:                    REPORT("row 1 inserted...");
4364:
4365:                    // insert a 6 column row, every other column is long
4366:                    T_RawStoreRow r2 = new T_RawStoreRow(6);
4367:                    r2.setColumn(0, 400, REC_001); // this takes 800 bytes
4368:                    r2.setColumn(1, 500, REC_002); // this takes 1000 bytes
4369:                    r2.setColumn(2, 400, REC_001);
4370:                    r2.setColumn(3, 500, REC_002);
4371:                    r2.setColumn(4, 400, REC_001);
4372:                    r2.setColumn(5, 500, REC_002);
4373:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r2,
4374:                            (byte) insertFlag);
4375:                    t_util.t_checkFetch(page, rh2, r2);
4376:                    REPORT("row 2 inserted...");
4377:
4378:                    // insert a long column
4379:                    r1.setColumn(0, 1500, REC_001);
4380:                    RecordHandle rh3 = t_util.t_insertAtSlot(page, 0, r1,
4381:                            (byte) insertFlag);
4382:                    if (rh3 != null)
4383:                        throw T_Fail
4384:                                .testFailMsg("expect the 3rd row to not fit on page");
4385:
4386:                    page.unlatch();
4387:                    page = null;
4388:
4389:                    if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
4390:                        t_util.t_dropContainer(t, segment, cid); // cleanup
4391:                    }
4392:
4393:                } finally {
4394:                    if (page != null)
4395:                        page.unlatch();
4396:
4397:                    t_util.t_commit(t);
4398:                    t.close();
4399:                }
4400:
4401:                PASS("P035: segment = " + segment);
4402:            }
4403:
4404:            /**
4405:            	Test space reclaimation - purging of a long row gets back all
4406:            	the row pieces.
4407:
4408:            	@exception T_Fail Unexpected behaviour from the API
4409:            	@exception StandardException Unexpected exception from the implementation
4410:             */
4411:            protected void P036() throws StandardException, T_Fail {
4412:                long segment = 0;
4413:                Transaction t = t_util.t_startTransaction();
4414:                long cid = t_util.t_addContainer(t, segment, 4096);
4415:
4416:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4417:                        true);
4418:                Page page = t_util.t_getPage(c,
4419:                        ContainerHandle.FIRST_PAGE_NUMBER);
4420:                try {
4421:                    t_util.t_checkEmptyPage(page);
4422:
4423:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
4424:
4425:                    // insert a row with 400 columns from 200 to 400 bytes each and make it
4426:                    // sprawl across many pages.
4427:                    T_RawStoreRow r1 = new T_RawStoreRow(400);
4428:                    for (int i = 0; i < 400; i++)
4429:                        r1.setColumn(i, 100 + i, REC_001);
4430:
4431:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
4432:                            (byte) insertFlag);
4433:                    t_util.t_checkFetch(page, rh1, r1);
4434:
4435:                    Page nextPage = t_util.t_addPage(c);
4436:                    long nextPageNumber = nextPage.getPageNumber();
4437:                    // deallocate it
4438:                    t_util.t_removePage(c, nextPage);
4439:
4440:                    REPORT("P036 - Nextpage is " + nextPageNumber);
4441:                    page.unlatch();
4442:                    page = null;
4443:                    t_util.t_commit(t);
4444:
4445:                    // See what the next page is.
4446:                    c = t_util.t_openContainer(t, segment, cid, true);
4447:
4448:                    // Now purge that first row.
4449:                    page = t_util.t_getPage(c,
4450:                            ContainerHandle.FIRST_PAGE_NUMBER);
4451:
4452:                    t_util.t_checkRecordCount(page, 1, 1);
4453:                    page.purgeAtSlot(0, 1, logDataForPurges);
4454:
4455:                    t_util.t_checkEmptyPage(page);
4456:                    page.unlatch();
4457:                    page = null;
4458:                    t_util.t_commit(t);
4459:
4460:                    // give some time for post commit to finish
4461:                    t_util.t_wait(10); // wait 10 milliseconds.
4462:
4463:                    // reinsert r1, it should use no extra page than last time.
4464:                    c = t_util.t_openContainer(t, segment, cid, true);
4465:                    page = t_util.t_getPage(c,
4466:                            ContainerHandle.FIRST_PAGE_NUMBER);
4467:
4468:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r1,
4469:                            (byte) insertFlag);
4470:                    t_util.t_checkFetch(page, rh2, r1);
4471:                    page.unlatch();
4472:                    page = null;
4473:
4474:                    // now verify that it used up no more page than last time
4475:                    nextPage = t_util.t_addPage(c);
4476:                    long checkNextPageNumber = nextPage.getPageNumber();
4477:                    nextPage.unlatch();
4478:
4479:                    if (nextPageNumber != checkNextPageNumber)
4480:                        throw T_Fail
4481:                                .testFailMsg("fail to reuse row pieces expect next page="
4482:                                        + nextPageNumber
4483:                                        + " but got "
4484:                                        + checkNextPageNumber);
4485:
4486:                    t_util.t_commit(t);
4487:
4488:                    // Purge them and roll them back via savepoint.  These should not
4489:                    // be reclaimed.
4490:                    c = t_util.t_openContainer(t, segment, cid, true);
4491:                    t.setSavePoint(SP1, null);
4492:                    page = t_util.t_getPage(c,
4493:                            ContainerHandle.FIRST_PAGE_NUMBER);
4494:                    t_util.t_checkRecordCount(page, 1, 1);
4495:                    page.purgeAtSlot(0, 1, logDataForPurges);
4496:                    page.unlatch();
4497:                    page = null;
4498:
4499:                    // make sure we cannot get our hands on a page that is freed up by
4500:                    // the purge
4501:                    Page testPage = t_util.t_addPage(c);
4502:                    T_RawStoreRow testRow = new T_RawStoreRow(REC_001);
4503:                    t_util.t_insert(testPage, testRow);
4504:                    testPage.unlatch();
4505:
4506:                    t.rollbackToSavePoint(SP1, null);
4507:
4508:                    testPage = t_util.t_addPage(c);
4509:                    t_util.t_insert(testPage, testRow);
4510:                    testPage.unlatch();
4511:
4512:                    t_util.t_commit(t);
4513:                    t_util.t_wait(10);
4514:
4515:                    c = t_util.t_openContainer(t, segment, cid, true);
4516:
4517:                    testPage = t_util.t_addPage(c);
4518:                    t_util.t_insert(testPage, testRow);
4519:                    testPage.unlatch();
4520:
4521:                    //when container is in unlogged mode, the check is untru,
4522:                    //because rollback to save point would have done nothing.
4523:                    //so purge was not rolled back. The row does not exist any more
4524:                    if ((openMode & ContainerHandle.MODE_UNLOGGED) == 0) {
4525:                        page = t_util.t_getPage(c,
4526:                                ContainerHandle.FIRST_PAGE_NUMBER);
4527:                        if (logDataForPurges) {
4528:                            t_util.t_checkFetch(page, rh2, r1);
4529:                        } else {
4530:                            //when data is not logged for purges ,
4531:                            //in this particular first four columns becomes null becuase
4532:                            //first 4 fileds data are on the 1st page and do not get 
4533:                            //logged during pruge and
4534:                            //the rest of the columns gets the data back because they
4535:                            //are removed page by page.
4536:                            T_RawStoreRow r1_wnl = new T_RawStoreRow(400);
4537:                            for (int i = 0; i < 18; i++)
4538:                                r1_wnl.setColumn(i, 4, REC_NULL);
4539:                            for (int i = 18; i < 400; i++)
4540:                                r1_wnl.setColumn(i, 100 + i, REC_001);
4541:                            t_util.t_checkFetch(page, rh2, r1_wnl);
4542:                        }
4543:                        page.unlatch();
4544:                        page = null;
4545:                    }
4546:
4547:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4548:
4549:                } finally {
4550:                    if (page != null)
4551:                        page.unlatch();
4552:                    t_util.t_commit(t);
4553:                    t.close();
4554:                }
4555:
4556:                PASS("P036");
4557:            }
4558:
4559:            /**
4560:            	Test space reclaimation - purging of a row with serveral long columns
4561:            	get back all the column chains.
4562:
4563:            	@exception T_Fail Unexpected behaviour from the API
4564:            	@exception StandardException Unexpected exception from the implementation
4565:             */
4566:            protected void P037() throws StandardException, T_Fail {
4567:                // Insert the 3 rows in P035, then purge them and reinsert them and
4568:                // make sure it reuses all the pages from last time.
4569:
4570:                long segment = 0;
4571:                Transaction t = t_util.t_startTransaction();
4572:                long cid = t_util.t_addContainer(t, segment, 4096);
4573:
4574:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4575:                        true);
4576:                Page page = t_util.t_getPage(c,
4577:                        ContainerHandle.FIRST_PAGE_NUMBER);
4578:                try {
4579:                    t_util.t_checkEmptyPage(page);
4580:
4581:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
4582:                    T_RawStoreRow r1 = new T_RawStoreRow(1);
4583:                    // insert a long column
4584:                    r1.setColumn(0, 5500, REC_001);
4585:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
4586:                            (byte) insertFlag);
4587:                    t_util.t_checkFetch(page, rh1, r1);
4588:
4589:                    // insert a 6 column row, every other column is long, sizes 
4590:                    // picked so that 2 rows fit, but 3rd row won't fit even if whole
4591:                    // row is overflowed.
4592:                    T_RawStoreRow r2 = new T_RawStoreRow(6);
4593:                    r2.setColumn(0, 660, REC_001); // this takes ~1320 bytes
4594:                    r2.setColumn(1, 5000, REC_002); // this takes ~10000 bytes
4595:                    r2.setColumn(2, 660, REC_001);
4596:                    r2.setColumn(3, 5000, REC_002);
4597:                    r2.setColumn(4, 660, REC_001);
4598:                    r2.setColumn(5, 5000, REC_002);
4599:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r2,
4600:                            (byte) insertFlag);
4601:                    t_util.t_checkFetch(page, rh2, r2);
4602:
4603:                    // insert a long column - this should fail
4604:                    RecordHandle rh3 = t_util.t_insertAtSlot(page, 0, r1,
4605:                            (byte) insertFlag);
4606:                    if (rh3 != null) {
4607:                        throw T_Fail
4608:                                .testFailMsg("expect the 3rd row to not fit on page");
4609:                    }
4610:
4611:                    page.unlatch();
4612:                    page = null;
4613:
4614:                    Page nextPage = t_util.t_addPage(c);
4615:                    long nextPageNumber = nextPage.getPageNumber();
4616:                    // deallocate it
4617:                    t_util.t_removePage(c, nextPage);
4618:
4619:                    REPORT("P037 - Nextpage is " + nextPageNumber);
4620:
4621:                    t_util.t_commit(t);
4622:
4623:                    // now purge them
4624:                    c = t_util.t_openContainer(t, segment, cid, true);
4625:                    page = t_util.t_getPage(c,
4626:                            ContainerHandle.FIRST_PAGE_NUMBER);
4627:
4628:                    t_util.t_checkRecordCount(page, 2, 2);
4629:                    page.purgeAtSlot(0, 2, logDataForPurges);
4630:                    t_util.t_checkEmptyPage(page);
4631:                    page.unlatch();
4632:                    page = null;
4633:
4634:                    t_util.t_commit(t);
4635:
4636:                    // give some time for post commit to finish
4637:                    t_util.t_wait(10); // wait 10 milliseconds.
4638:
4639:                    // reinsert all 3 of them again, exactly the same way.
4640:                    c = t_util.t_openContainer(t, segment, cid, true);
4641:                    page = t_util.t_getPage(c,
4642:                            ContainerHandle.FIRST_PAGE_NUMBER);
4643:
4644:                    rh1 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
4645:                    rh2 = t_util.t_insertAtSlot(page, 0, r2, (byte) insertFlag);
4646:                    rh3 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
4647:                    t_util.t_checkFetch(page, rh1, r1);
4648:                    t_util.t_checkFetch(page, rh2, r2);
4649:                    if (rh3 != null)
4650:                        throw T_Fail
4651:                                .testFailMsg("expect the 3rd row to not fit on page");
4652:                    page.unlatch();
4653:                    page = null;
4654:
4655:                    nextPage = t_util.t_addPage(c);
4656:                    long checkNextPageNumber = nextPage.getPageNumber();
4657:                    nextPage.unlatch();
4658:
4659:                    if (nextPageNumber != checkNextPageNumber)
4660:                        throw T_Fail
4661:                                .testFailMsg("fail to reuse row pieces expect next page="
4662:                                        + nextPageNumber
4663:                                        + " but got "
4664:                                        + checkNextPageNumber);
4665:
4666:                    t_util.t_commit(t);
4667:
4668:                    // Purge them and roll them back via savepoint.  These should not
4669:                    // be reclaimed.
4670:                    c = t_util.t_openContainer(t, segment, cid, true);
4671:
4672:                    t.setSavePoint(SP1, null);
4673:                    page = t_util.t_getPage(c,
4674:                            ContainerHandle.FIRST_PAGE_NUMBER);
4675:
4676:                    t_util.t_checkRecordCount(page, 2, 2);
4677:                    page.purgeAtSlot(0, 2, logDataForPurges);
4678:                    t_util.t_checkEmptyPage(page);
4679:
4680:                    page.unlatch();
4681:                    page = null;
4682:
4683:                    // make sure we cannot get our hands on a page that is freed up by
4684:                    // the purge
4685:                    Page testPage = t_util.t_addPage(c);
4686:                    T_RawStoreRow testRow = new T_RawStoreRow(REC_001);
4687:                    t_util.t_insert(testPage, testRow);
4688:                    testPage.unlatch();
4689:
4690:                    t.rollbackToSavePoint(SP1, null);
4691:
4692:                    testPage = t_util.t_addPage(c);
4693:                    t_util.t_insert(testPage, testRow);
4694:                    testPage.unlatch();
4695:
4696:                    t_util.t_commit(t);
4697:
4698:                    // give some time for post commit to finish
4699:                    t_util.t_wait(10);
4700:
4701:                    // check to make sure post commit did not reclaim those rows.
4702:                    c = t_util.t_openContainer(t, segment, cid, true);
4703:
4704:                    testPage = t_util.t_addPage(c);
4705:                    t_util.t_insert(testPage, testRow);
4706:                    testPage.unlatch();
4707:
4708:                    page = t_util.t_getPage(c,
4709:                            ContainerHandle.FIRST_PAGE_NUMBER);
4710:
4711:                    t_util.t_checkRecordCount(page, 2, 2);
4712:                    t_util.t_checkFetch(page, rh1, r1);
4713:
4714:                    if (logDataForPurges)
4715:                        t_util.t_checkFetch(page, rh2, r2);
4716:                    else {
4717:
4718:                        // During purges when data is not logged when slots are purged
4719:                        // they become null on rollback and some cases like long columns
4720:                        // we remove the wholepage on rollback we get the data back.
4721:                        T_RawStoreRow r2_wnl = new T_RawStoreRow(6);
4722:                        r2_wnl.setColumn(0, 4, REC_NULL);
4723:                        r2_wnl.setColumn(1, 5000, REC_002);
4724:                        r2_wnl.setColumn(2, 4, REC_NULL);
4725:                        r2_wnl.setColumn(3, 5000, REC_002);
4726:                        r2_wnl.setColumn(4, 4, REC_NULL);
4727:                        r2_wnl.setColumn(5, 5000, REC_002);
4728:                        t_util.t_checkFetch(page, rh2, r2_wnl);
4729:                    }
4730:
4731:                    page.unlatch();
4732:                    page = null;
4733:
4734:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4735:
4736:                } finally {
4737:                    if (page != null)
4738:                        page.unlatch();
4739:                    t_util.t_commit(t);
4740:                    t.close();
4741:                }
4742:
4743:                PASS("P037");
4744:
4745:            }
4746:
4747:            /**
4748:            	Test space reclaimation - rollback of an insert (with purge) of a row
4749:            	that overflows and with long column get back all the space in the row
4750:            	and column chain. 
4751:
4752:            	@exception T_Fail Unexpected behaviour from the API
4753:            	@exception StandardException Unexpected exception from the implementation
4754:             */
4755:            protected void P038() throws StandardException, T_Fail {
4756:                long segment = 0;
4757:
4758:                // Insert the 3 rows in P035, then abort the insert.
4759:                // Reinsert them and make sure it reuses all the pages from last time. 
4760:                Transaction t = t_util.t_startTransaction();
4761:                long cid = t_util.t_addContainer(t, segment, 4096);
4762:                t_util.t_commit(t);
4763:
4764:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4765:                        true);
4766:                Page page = t_util.t_getPage(c,
4767:                        ContainerHandle.FIRST_PAGE_NUMBER);
4768:                try {
4769:                    t_util.t_checkEmptyPage(page);
4770:
4771:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW
4772:                            | Page.INSERT_UNDO_WITH_PURGE;
4773:
4774:                    T_RawStoreRow r1 = new T_RawStoreRow(1);
4775:                    // insert a long column
4776:                    r1.setColumn(0, 1500, REC_001);
4777:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
4778:                            (byte) insertFlag);
4779:
4780:                    // insert a 6 column row, every other column is long
4781:                    T_RawStoreRow r2 = new T_RawStoreRow(6);
4782:                    r2.setColumn(0, 400, REC_001); // this takes ~800 bytes
4783:                    r2.setColumn(1, 500, REC_002); // this takes ~1000 bytes
4784:                    r2.setColumn(2, 400, REC_001);
4785:                    r2.setColumn(3, 500, REC_002);
4786:                    r2.setColumn(4, 400, REC_001);
4787:                    r2.setColumn(5, 500, REC_002);
4788:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r2,
4789:                            (byte) insertFlag);
4790:
4791:                    // insert a long column
4792:                    RecordHandle rh3 = t_util.t_insertAtSlot(page, 0, r1,
4793:                            (byte) insertFlag);
4794:                    if (rh3 != null)
4795:                        throw T_Fail
4796:                                .testFailMsg("expect the 3rd row to not fit on page");
4797:                    page = null;
4798:
4799:                    Page nextPage = t_util.t_addPage(c);
4800:                    long nextPageNumber = nextPage.getPageNumber();
4801:                    // deallocate it
4802:                    t_util.t_removePage(c, nextPage);
4803:
4804:                    REPORT("P038 - Nextpage is " + nextPageNumber);
4805:
4806:                    t_util.t_abort(t);
4807:
4808:                    // the abort rolled back the removal of nextPage also, redo the removed
4809:                    c = t_util.t_openContainer(t, segment, cid, true);
4810:                    nextPage = t_util.t_getPage(c, nextPageNumber);
4811:                    t_util.t_removePage(c, nextPage);
4812:                    t_util.t_commit(t);
4813:
4814:                    // reinsert the 3 rows, they should not take up any more space than
4815:                    // last time.
4816:                    c = t_util.t_openContainer(t, segment, cid, true);
4817:                    page = t_util.t_getPage(c,
4818:                            ContainerHandle.FIRST_PAGE_NUMBER);
4819:
4820:                    t_util.t_checkEmptyPage(page);
4821:
4822:                    rh1 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
4823:                    rh2 = t_util.t_insertAtSlot(page, 0, r2, (byte) insertFlag);
4824:                    rh3 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
4825:
4826:                    t_util.t_checkFetch(page, rh1, r1);
4827:                    t_util.t_checkFetch(page, rh2, r2);
4828:                    if (rh3 != null)
4829:                        throw T_Fail
4830:                                .testFailMsg("expect the 3rd row to not fit on page");
4831:
4832:                    page.unlatch();
4833:                    page = null;
4834:
4835:                    nextPage = t_util.t_addPage(c);
4836:                    long checkNextPageNumber = nextPage.getPageNumber();
4837:                    nextPage.unlatch();
4838:
4839:                    if (nextPageNumber != checkNextPageNumber)
4840:                        throw T_Fail
4841:                                .testFailMsg("fail to reuse row pieces expect next page="
4842:                                        + nextPageNumber
4843:                                        + " but got "
4844:                                        + checkNextPageNumber);
4845:
4846:                    t_util.t_dropContainer(t, segment, cid); // cleanup
4847:
4848:                } finally {
4849:                    if (page != null)
4850:                        page.unlatch();
4851:                    t_util.t_commit(t);
4852:                    t.close();
4853:                }
4854:
4855:                PASS("P038");
4856:            }
4857:
4858:            /**
4859:            	Test space reclaimation - shrink a head row piece.
4860:
4861:            	@exception T_Fail Unexpected behaviour from the API
4862:            	@exception StandardException Unexpected exception from the implementation
4863:             */
4864:            protected void P039() throws StandardException, T_Fail {
4865:                // insert 3 2K rows of 3 columns,  size (100, 1500, 400), into an 8K
4866:                // page, then fill up the page with 1K rows.  
4867:                // 
4868:                // 1. Update the first 2K row so that the 2nd and 3rd column gets moved
4869:                // to another page.  See that we can insert at least 1 more 1K row into
4870:                // the page.
4871:                // 
4872:                // 2. Update the second 2K row so that the 2nd column becomes a long
4873:                // column.  See that we can insert at least 1 more 1K row into the
4874:                // page. 
4875:                //
4876:                // 3. Update the third 2K row so that the column size shrinks to (200,
4877:                // 200, 200).  See that we can insert at least 1 more 1K row into the
4878:                // page.
4879:
4880:                long segment = 0;
4881:                Transaction t = t_util.t_startTransaction();
4882:                long cid = t_util.t_addContainer(t, segment, 8 * 1024);
4883:
4884:                T_RawStoreRow bigRow = new T_RawStoreRow(3);
4885:                bigRow.setColumn(0, 50, REC_001); // remember each char takes 2 bytes
4886:                bigRow.setColumn(1, 750, REC_002);
4887:                bigRow.setColumn(2, 200, REC_003);
4888:
4889:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
4890:                        true);
4891:                Page page = t_util.t_getPage(c,
4892:                        ContainerHandle.FIRST_PAGE_NUMBER);
4893:                try {
4894:                    RecordHandle rh1 = t_util.t_insert(page, bigRow);
4895:                    RecordHandle rh2 = t_util.t_insert(page, bigRow);
4896:                    RecordHandle rh3 = t_util.t_insert(page, bigRow);
4897:
4898:                    t_util.t_checkFetch(page, rh1, bigRow);
4899:                    t_util.t_checkFetch(page, rh2, bigRow);
4900:                    t_util.t_checkFetch(page, rh3, bigRow);
4901:
4902:                    // now fill up the page with smaller rows
4903:                    T_RawStoreRow smallRow = new T_RawStoreRow(1);
4904:                    smallRow.setColumn(0, 500, REC_004);
4905:
4906:                    while (page.spaceForInsert()) {
4907:                        if (t_util.t_insert(page, smallRow) == null)
4908:                            break;
4909:                    }
4910:                    REPORT("P039: " + (page.recordCount() - 3)
4911:                            + " small rows have been inserted");
4912:                    page.unlatch();
4913:                    page = null;
4914:
4915:                    t_util.t_commit(t);
4916:
4917:                    // (1) update rh1 so that column 2 and 3 are moved off page
4918:                    bigRow.setColumn(1, 2000, REC_005);
4919:                    c = t_util.t_openContainer(t, segment, cid, true);
4920:
4921:                    page = t_util.t_getPage(c,
4922:                            ContainerHandle.FIRST_PAGE_NUMBER);
4923:                    page.update(rh1, bigRow.getRow(), (FormatableBitSet) null);
4924:                    t_util.t_checkFetch(page, rh1, bigRow);
4925:                    page.unlatch();
4926:                    page = null;
4927:                    t_util.t_commit(t);
4928:
4929:                    t_util.t_wait(10); // wait for post commit to get processed.
4930:
4931:                    c = t_util.t_openContainer(t, segment, cid, true);
4932:                    page = t_util.t_getPage(c,
4933:                            ContainerHandle.FIRST_PAGE_NUMBER);
4934:
4935:                    if (t_util.t_insert(page, smallRow) == null)
4936:                        throw T_Fail
4937:                                .testFailMsg("expect row to have shrunk (1)");
4938:
4939:                    // fill it up again 
4940:                    while (page.spaceForInsert()) {
4941:                        if (t_util.t_insert(page, smallRow) == null)
4942:                            break;
4943:                    }
4944:                    REPORT("P039: " + (page.recordCount() - 3)
4945:                            + " small rows have been inserted");
4946:
4947:                    page.unlatch();
4948:                    page = null;
4949:
4950:                    t_util.t_commit(t);
4951:
4952:                    // (2) update rh2 so that column 2 becomes a long column
4953:                    FormatableBitSet colList = new FormatableBitSet(2);
4954:                    colList.set(1); // update column 1, the second column
4955:                    // use sparse rows
4956:                    T_RawStoreRow partialRow = new T_RawStoreRow(2);
4957:                    partialRow.setColumn(1, 8000, REC_006);
4958:
4959:                    c = t_util.t_openContainer(t, segment, cid, true);
4960:
4961:                    page = t_util.t_getPage(c,
4962:                            ContainerHandle.FIRST_PAGE_NUMBER);
4963:
4964:                    page.update(rh2, partialRow.getRow(), colList);
4965:
4966:                    bigRow.setColumn(1, 8000, REC_006);
4967:                    t_util.t_checkFetch(page, rh2, bigRow);
4968:                    page.unlatch();
4969:                    page = null;
4970:                    t_util.t_commit(t);
4971:
4972:                    t_util.t_wait(10); // wait for post commit to get processed.
4973:
4974:                    c = t_util.t_openContainer(t, segment, cid, true);
4975:                    page = t_util.t_getPage(c,
4976:                            ContainerHandle.FIRST_PAGE_NUMBER);
4977:                    if (t_util.t_insert(page, smallRow) == null)
4978:                        throw T_Fail
4979:                                .testFailMsg("expect row to have shrunk (2)");
4980:
4981:                    // fill it up again 
4982:                    while (page.spaceForInsert()) {
4983:                        if (t_util.t_insert(page, smallRow) == null)
4984:                            break;
4985:                    }
4986:                    REPORT("P039: " + (page.recordCount() - 3)
4987:                            + " small rows have been inserted");
4988:
4989:                    page.unlatch();
4990:                    page = null;
4991:
4992:                    t_util.t_commit(t);
4993:
4994:                    // (3) - update rh3 to have (200, 400, 400) bytes columns
4995:                    bigRow.setColumn(0, 100, REC_001);
4996:                    bigRow.setColumn(1, 200, REC_002);
4997:                    bigRow.setColumn(2, 200, REC_003);
4998:
4999:                    c = t_util.t_openContainer(t, segment, cid, true);
5000:                    page = t_util.t_getPage(c,
5001:                            ContainerHandle.FIRST_PAGE_NUMBER);
5002:                    page.update(rh3, bigRow.getRow(), (FormatableBitSet) null);
5003:                    t_util.t_checkFetch(page, rh3, bigRow);
5004:                    page.unlatch();
5005:                    page = null;
5006:                    t_util.t_commit(t);
5007:
5008:                    t_util.t_wait(10); // wait for post commit to get processed.
5009:
5010:                    c = t_util.t_openContainer(t, segment, cid, true);
5011:                    page = t_util.t_getPage(c,
5012:                            ContainerHandle.FIRST_PAGE_NUMBER);
5013:
5014:                    if (t_util.t_insert(page, smallRow) == null)
5015:                        throw T_Fail
5016:                                .testFailMsg("expect row to have shrunk (3)");
5017:                    page.unlatch();
5018:                    page = null;
5019:
5020:                    t_util.t_dropContainer(t, segment, cid); // cleanup
5021:                } finally {
5022:                    if (page != null)
5023:                        page.unlatch();
5024:                    t_util.t_commit(t);
5025:                    t.close();
5026:                }
5027:
5028:                PASS("P039");
5029:            }
5030:
5031:            /**
5032:            	Test space reclaimation - shrink a non head row piece.
5033:
5034:            	@exception T_Fail Unexpected behaviour from the API
5035:            	@exception StandardException Unexpected exception from the implementation
5036:             */
5037:            protected void P040() throws StandardException, T_Fail {
5038:                // Manufacture a row that has a small head row piece, a large 2nd row
5039:                // piece and a small third row piece.
5040:                // Using the same head page, add a second row that has a small head row
5041:                // piece and a medium sized 2nd row piece, a new overflow page should
5042:                // be allocated.
5043:                // Update the first row to now have a small 2nd row piece.
5044:                // Using the same head page, add a third row that has a small head row
5045:                // piece and a medium sized 2nd row piece, no new overflow page should
5046:                // be allocated.
5047:
5048:                long segment = 0;
5049:                Transaction t = t_util.t_startTransaction();
5050:                long cid = t_util.t_addContainer(t, 0, 4096);
5051:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
5052:                        true);
5053:
5054:                Page page = t_util.t_getPage(c,
5055:                        ContainerHandle.FIRST_PAGE_NUMBER);
5056:                try {
5057:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW
5058:                            | Page.INSERT_UNDO_WITH_PURGE;
5059:
5060:                    T_RawStoreRow row1 = new T_RawStoreRow(3);
5061:                    row1.setColumn(0, 400, REC_001);
5062:                    row1.setColumn(1, 800, REC_002); // this takes ~1600 bytes
5063:                    row1.setColumn(2, 400, REC_003);
5064:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, row1,
5065:                            (byte) insertFlag);
5066:
5067:                    t_util.t_checkFetch(page, rh1, row1);
5068:
5069:                    page.unlatch();
5070:                    page = null;
5071:                    t_util.t_commit(t);
5072:
5073:                    c = t_util.t_openContainer(t, segment, cid, true);
5074:                    Page nextPage = t_util.t_addPage(c);
5075:
5076:                    // remember where next page is
5077:                    long nextPageNumber = nextPage.getPageNumber();
5078:                    t_util.t_removePage(c, nextPage);
5079:                    t_util.t_commit(t);
5080:
5081:                    T_RawStoreRow row2 = new T_RawStoreRow(3);
5082:                    row2.setColumn(0, 1200, REC_001);
5083:                    row2.setColumn(1, 1200, REC_002);
5084:                    row2.setColumn(2, 400, REC_003);
5085:
5086:                    c = t_util.t_openContainer(t, segment, cid, true);
5087:                    page = t_util.t_getPage(c,
5088:                            ContainerHandle.FIRST_PAGE_NUMBER);
5089:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 1, row2,
5090:                            (byte) insertFlag);
5091:
5092:                    t_util.t_checkFetch(page, rh2, row2);
5093:                    page.unlatch();
5094:                    page = null;
5095:
5096:                    // this should have allocated more overflow page
5097:                    nextPage = t_util.t_addPage(c);
5098:                    long checkNextPageNumber = nextPage.getPageNumber();
5099:                    if (checkNextPageNumber == nextPageNumber)
5100:                        throw T_Fail
5101:                                .testFailMsg("expected to allocate more pages");
5102:                    t_util.t_removePage(c, nextPage);
5103:                    t_util.t_commit(t);
5104:
5105:                    // now this is the next free page
5106:                    nextPageNumber = checkNextPageNumber;
5107:
5108:                    // shrink first row 2nd column, and second row 1st column so we
5109:                    // have space on both the first and the second page on the row
5110:                    // chain.
5111:                    // use sparse rows
5112:                    T_RawStoreRow partialRow = new T_RawStoreRow(2);
5113:                    partialRow.setColumn(1, 400, REC_004);
5114:
5115:                    T_RawStoreRow partialRow2 = new T_RawStoreRow(2);
5116:                    partialRow2.setColumn(0, 400, REC_004);
5117:
5118:                    c = t_util.t_openContainer(t, segment, cid, true);
5119:                    page = t_util.t_getPage(c,
5120:                            ContainerHandle.FIRST_PAGE_NUMBER);
5121:
5122:                    FormatableBitSet colList = new FormatableBitSet(2);
5123:                    colList.set(1); // update first row column 1, the second column
5124:                    page.update(rh1, partialRow.getRow(), colList);
5125:
5126:                    colList.clear(1);
5127:                    colList.set(0); // update second row column 0, the first column
5128:                    page.update(rh2, partialRow2.getRow(), colList);
5129:
5130:                    // verify the update worked.
5131:                    row1.setColumn(1, 400, REC_004);
5132:                    row2.setColumn(0, 400, REC_004);
5133:                    t_util.t_checkFetch(page, rh1, row1);
5134:                    t_util.t_checkFetch(page, rh2, row2);
5135:
5136:                    page.unlatch();
5137:                    page = null;
5138:
5139:                    t_util.t_commit(t);
5140:                    t_util.t_wait(10); // give post commit a chance to work
5141:
5142:                    // We think the head row should have 2 200 bytes row.
5143:                    // One of the overflow row piece chain has an overflow page with a
5144:                    // 200 bytes row followed by another overflow page with a 200 bytes
5145:                    // row.
5146:                    // The other overflow row piece should have 1 600 bytes row and no
5147:                    // other overflow page.
5148:                    T_RawStoreRow row3 = new T_RawStoreRow(2);
5149:                    row3.setColumn(0, 400, REC_001);
5150:                    row3.setColumn(1, 800, REC_002);
5151:                    // We think this should select the first overflow chain.
5152:                    c = t_util.t_openContainer(t, segment, cid, true);
5153:                    page = t_util.t_getPage(c,
5154:                            ContainerHandle.FIRST_PAGE_NUMBER);
5155:
5156:                    if (!page.spaceForInsert())
5157:                        throw T_Fail
5158:                                .testFailMsg("No space for insert after shrink row");
5159:
5160:                    RecordHandle rh3 = t_util.t_insertAtSlot(page, 1, row3,
5161:                            (byte) insertFlag);
5162:                    t_util.t_checkFetch(page, rh3, row3);
5163:
5164:                    page.unlatch();
5165:                    page = null;
5166:
5167:                    // this should not allocate more overflow pages
5168:                    nextPage = t_util.t_addPage(c);
5169:                    checkNextPageNumber = nextPage.getPageNumber();
5170:                    if (checkNextPageNumber != nextPageNumber)
5171:                        throw T_Fail
5172:                                .testFailMsg("not expected to allocate more pages "
5173:                                        + nextPageNumber
5174:                                        + ","
5175:                                        + checkNextPageNumber);
5176:
5177:                    t_util.t_dropContainer(t, segment, cid); // cleanup
5178:                } finally {
5179:                    if (page != null)
5180:                        page.unlatch();
5181:
5182:                    t_util.t_commit(t);
5183:                    t.close();
5184:                }
5185:                PASS("P040");
5186:            }
5187:
5188:            /**
5189:            	Test space reclaimation - update a long column to another long column.
5190:
5191:            	@exception T_Fail Unexpected behaviour from the API
5192:            	@exception StandardException Unexpected exception from the implementation
5193:             */
5194:            protected void P041() throws StandardException, T_Fail {
5195:                // Make a row with several long columns, on different row pieces.
5196:                // Update these long columns - to other long columns or to short
5197:                // columns.  Remember what the next page is.
5198:                // Update these long columns to the original long column (in length),
5199:                // we shouldn't be adding any more pages.
5200:
5201:                long segment = 0;
5202:                Transaction t = t_util.t_startTransaction();
5203:                long cid = t_util.t_addContainer(t, segment, 4096);
5204:
5205:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
5206:                        true);
5207:                Page page = t_util.t_getPage(c,
5208:                        ContainerHandle.FIRST_PAGE_NUMBER);
5209:                try {
5210:                    t_util.t_checkEmptyPage(page);
5211:
5212:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
5213:
5214:                    // insert a 6 column row, every other column is long
5215:                    T_RawStoreRow r1 = new T_RawStoreRow(6);
5216:                    r1.setColumn(0, 400, REC_001); // this takes ~800 bytes
5217:                    r1.setColumn(1, 500, REC_002); // this takes ~1000 bytes
5218:                    r1.setColumn(2, 400, REC_001);
5219:                    r1.setColumn(3, 500, REC_002);
5220:                    r1.setColumn(4, 400, REC_001);
5221:                    r1.setColumn(5, 500, REC_002);
5222:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
5223:                            (byte) insertFlag);
5224:                    t_util.t_checkFetch(page, rh1, r1);
5225:
5226:                    // update column 0,1,2 to short columns, columns 3, 4, 5 to other
5227:                    // long columns.
5228:                    T_RawStoreRow r2 = new T_RawStoreRow(6);
5229:                    r2.setColumn(0, 100, REC_003);
5230:                    r2.setColumn(1, 100, REC_004);
5231:                    r2.setColumn(2, 100, REC_003);
5232:                    r2.setColumn(3, 500, REC_005);
5233:                    r2.setColumn(4, 500, REC_006);
5234:                    r2.setColumn(5, 500, REC_005);
5235:
5236:                    page.update(rh1, r2.getRow(), (FormatableBitSet) null);
5237:                    t_util.t_checkFetch(page, rh1, r2);
5238:
5239:                    page.unlatch();
5240:                    page = null;
5241:
5242:                    Page nextpage = t_util.t_addPage(c);
5243:                    long nextPageNumber = nextpage.getPageNumber();
5244:                    t_util.t_removePage(c, nextpage);
5245:
5246:                    t_util.t_commit(t);
5247:                    t_util.t_wait(10); // let post commit work
5248:
5249:                    // now update to original long rows, should not take any more
5250:                    // space.
5251:                    c = t_util.t_openContainer(t, segment, cid, true);
5252:                    page = t_util.t_getPage(c,
5253:                            ContainerHandle.FIRST_PAGE_NUMBER);
5254:                    t_util.t_checkFetch(page, rh1, r2);
5255:
5256:                    t.setSavePoint(SP1, null);
5257:
5258:                    page.update(rh1, r1.getRow(), (FormatableBitSet) null);
5259:                    t_util.t_checkFetch(page, rh1, r1);
5260:                    page.unlatch();
5261:                    page = null;
5262:
5263:                    nextpage = t_util.t_addPage(c);
5264:                    long checkNextPageNumber = nextpage.getPageNumber();
5265:                    nextpage.unlatch();
5266:                    if (checkNextPageNumber != nextPageNumber)
5267:                        throw T_Fail
5268:                                .testFailMsg("expect next page to be unchanged");
5269:
5270:                    // now roll back the update via savepoint.
5271:                    t.rollbackToSavePoint(SP1, null);
5272:
5273:                    t_util.t_commit(t);
5274:                    t_util.t_wait(10); // make sure post commit don't 
5275:                    // reclaim things that are not garbage.
5276:
5277:                    c = t_util.t_openContainer(t, segment, cid, true);
5278:                    page = t_util.t_getPage(c,
5279:                            ContainerHandle.FIRST_PAGE_NUMBER);
5280:                    t_util.t_checkFetch(page, rh1, r2);
5281:                    page.unlatch();
5282:                    page = null;
5283:
5284:                    t_util.t_dropContainer(t, segment, cid); // cleanup
5285:                } finally {
5286:                    if (page != null)
5287:                        page.unlatch();
5288:                    t_util.t_commit(t);
5289:                    t.close();
5290:                }
5291:
5292:                PASS("P041");
5293:
5294:            }
5295:
5296:            /**
5297:            	Test space reclaimation - rollback of an update that create a long
5298:            	column. 
5299:
5300:            	@exception T_Fail Unexpected behaviour from the API
5301:            	@exception StandardException Unexpected exception from the implementation
5302:             */
5303:            protected void P042() throws StandardException, T_Fail {
5304:                // Make a row with a short column.  Remember the next page.
5305:                // Update it to a long column, roll back.  See that the next page goes
5306:                // back to before the update.
5307:                //
5308:                // Update the row so that it overflows to another page and have long
5309:                // column there.  Remember the next page.  Update the long column to
5310:                // another long column.  Rollback the update.  See that the next page
5311:                // goes back to before the update.
5312:                // 
5313:                long segment = 0;
5314:                Transaction t = t_util.t_startTransaction();
5315:                long cid = t_util.t_addContainer(t, segment, 4096);
5316:
5317:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
5318:                        true);
5319:                Page page = t_util.t_getPage(c,
5320:                        ContainerHandle.FIRST_PAGE_NUMBER);
5321:                int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
5322:
5323:                try {
5324:                    T_RawStoreRow smallRow = new T_RawStoreRow(REC_001);
5325:                    RecordHandle rh1 = t_util.t_insert(page, smallRow);
5326:                    t_util.t_commit(t);
5327:
5328:                    c = t_util.t_openContainer(t, segment, cid, true);
5329:                    Page nextPage = t_util.t_addPage(c);
5330:                    long nextPageNumber = nextPage.getPageNumber();
5331:                    // deallocate it
5332:                    t_util.t_removePage(c, nextPage);
5333:                    t_util.t_commit(t);
5334:
5335:                    c = t_util.t_openContainer(t, segment, cid, true);
5336:                    page = t_util.t_getPage(c,
5337:                            ContainerHandle.FIRST_PAGE_NUMBER);
5338:
5339:                    T_RawStoreRow bigRow = new T_RawStoreRow(1);
5340:                    bigRow.setColumn(0, 6400, REC_001);
5341:                    page.update(rh1, bigRow.getRow(), (FormatableBitSet) null);
5342:                    t_util.t_checkFetch(page, rh1, bigRow);
5343:                    page.unlatch();
5344:                    page = null;
5345:
5346:                    Page checkGrow = t_util.t_addPage(c);
5347:                    long checkGrowPageNumber = checkGrow.getPageNumber();
5348:                    if (checkGrowPageNumber == nextPageNumber)
5349:                        throw T_Fail
5350:                                .testFailMsg("expect to have allocated more pages");
5351:                    t_util.t_removePage(c, checkGrow);
5352:
5353:                    t_util.t_abort(t);
5354:
5355:                    t_util.t_wait(10);
5356:                    c = t_util.t_openContainer(t, segment, cid, true);
5357:
5358:                    // the abort rolled back the removePage, remove it again.
5359:                    checkGrow = t_util.t_getPage(c, checkGrowPageNumber);
5360:                    t_util.t_removePage(c, checkGrow);
5361:
5362:                    nextPage = t_util.t_addPage(c);
5363:                    if (nextPage.getPageNumber() != nextPageNumber)
5364:                        throw T_Fail
5365:                                .testFailMsg("rollback of update to long column did not release the long column chain pages");
5366:
5367:                    t_util.t_removePage(c, nextPage);
5368:                    t_util.t_commit(t);
5369:
5370:                    T_RawStoreRow row2 = new T_RawStoreRow(6);
5371:                    row2.setColumn(0, 1600, REC_001); // this takes ~3200 bytes
5372:                    row2.setColumn(1, 2000, REC_002); // this takes ~4000 bytes
5373:                    row2.setColumn(2, 1600, REC_001);
5374:                    row2.setColumn(3, 2000, REC_002);
5375:                    row2.setColumn(4, 1600, REC_001);
5376:                    row2.setColumn(5, 2000, REC_002);
5377:
5378:                    c = t_util.t_openContainer(t, segment, cid, true);
5379:                    page = t_util.t_getPage(c,
5380:                            ContainerHandle.FIRST_PAGE_NUMBER);
5381:
5382:                    t.setSavePoint(SP1, null);
5383:                    page.update(rh1, row2.getRow(), (FormatableBitSet) null);
5384:
5385:                    nextPage = t_util.t_addPage(c);
5386:                    nextPageNumber = nextPage.getPageNumber();
5387:                    t_util.t_removePage(c, nextPage);
5388:
5389:                    t.rollbackToSavePoint(SP1, null); // this should free up some pages
5390:
5391:                    nextPage = t_util.t_getPage(c, nextPageNumber);
5392:                    t_util.t_removePage(c, nextPage);
5393:
5394:                    t_util.t_commit(t);
5395:                    t_util.t_wait(10);
5396:
5397:                    c = t_util.t_openContainer(t, segment, cid, true);
5398:                    Page checkNextPage = t_util.t_addPage(c);
5399:                    if (checkNextPage.getPageNumber() == nextPageNumber)
5400:                        throw T_Fail
5401:                                .testFailMsg("expect some pages to be freed by update rollback");
5402:                    t_util.t_removePage(c, checkNextPage);
5403:                    t_util.t_commit(t);
5404:
5405:                    c = t_util.t_openContainer(t, segment, cid, true);
5406:                    page = t_util.t_getPage(c,
5407:                            ContainerHandle.FIRST_PAGE_NUMBER);
5408:                    t_util.t_checkFetch(page, rh1, smallRow);
5409:
5410:                    // update row so that it has overflow rows and long columns
5411:                    page.update(rh1, row2.getRow(), (FormatableBitSet) null);
5412:
5413:                    // remember the next page
5414:                    nextPage = t_util.t_addPage(c);
5415:                    nextPageNumber = nextPage.getPageNumber();
5416:                    t_util.t_removePage(c, nextPage);
5417:
5418:                    t_util.t_commit(t);
5419:
5420:                    // now update columns 0, 1, 4  to long columns and roll it back. 
5421:                    T_RawStoreRow row3 = new T_RawStoreRow(5);
5422:                    row3.setColumn(0, 4000, REC_003);
5423:                    row3.setColumn(1, 4000, REC_004);
5424:                    row3.setColumn(2, REC_001);
5425:                    row3.setColumn(3, REC_001);
5426:                    row3.setColumn(4, 4000, REC_003);
5427:
5428:                    c = t_util.t_openContainer(t, segment, cid, true);
5429:                    page = t_util.t_getPage(c,
5430:                            ContainerHandle.FIRST_PAGE_NUMBER);
5431:                    page.update(rh1, row3.getRow(), (FormatableBitSet) null);
5432:                    t_util.t_checkFetch(page, rh1, row3);
5433:                    page.unlatch();
5434:                    page = null;
5435:
5436:                    t_util.t_abort(t);
5437:                    t_util.t_wait(10);
5438:
5439:                    c = t_util.t_openContainer(t, segment, cid, true);
5440:                    nextPage = t_util.t_addPage(c);
5441:                    if (nextPage.getPageNumber() != nextPageNumber)
5442:                        throw T_Fail
5443:                                .testFailMsg("expect pages to be freed by update rollback");
5444:                    nextPage.unlatch();
5445:
5446:                    t_util.t_dropContainer(t, segment, cid);
5447:                } finally {
5448:                    if (page != null)
5449:                        page.unlatch();
5450:                    t_util.t_commit(t);
5451:                    t.close();
5452:                }
5453:                PASS("P042");
5454:
5455:            }
5456:
5457:            /**
5458:            	Test space reclaimation - rollback of an update that create a new row
5459:            	piece. 
5460:             */
5461:            protected void P043() {
5462:                // this space cannot be reclaimed.
5463:            }
5464:
5465:            /** 
5466:            	Test that post commit processor does not stubbify a drop table that is
5467:            	rolled back in a savepoint
5468:            	@exception T_Fail Unexpected behaviour from the API
5469:            	@exception StandardException Unexpected exception from the implementation
5470:
5471:             */
5472:            protected void P050() throws StandardException, T_Fail {
5473:                if (!testRollback)
5474:                    return;
5475:
5476:                Transaction t = t_util.t_startTransaction();
5477:                long cid = t_util.t_addContainer(t, 0);
5478:                t_util.t_commit(t);
5479:
5480:                t.setSavePoint(SP1, null);
5481:
5482:                t.dropContainer(new ContainerKey(0, cid));
5483:                t.rollbackToSavePoint(SP1, null);
5484:
5485:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
5486:                t_util.t_addPage(c);
5487:                t_util.t_commit(t);
5488:
5489:                long cid2 = t_util.t_addContainer(t, 0);
5490:                c = t_util.t_openContainer(t, 0, cid2, true);
5491:                t_util.t_addPage(c);
5492:                t_util.t_addPage(c);
5493:                t_util.t_addPage(c);
5494:                t_util.t_addPage(c);
5495:                t_util.t_commit(t);
5496:
5497:                c = t_util.t_openContainer(t, 0, cid, false); // it should not be stubbified...
5498:
5499:                PASS("P050");
5500:
5501:                t_util.t_dropContainer(t, 0, cid); // cleanup - commit it for real
5502:                t_util.t_dropContainer(t, 0, cid2); // cleanup - commit it for real
5503:
5504:                t_util.t_commit(t);
5505:                t.close();
5506:
5507:            }
5508:
5509:            /**
5510:            	Test rollback of Page.insert
5511:            	@exception T_Fail Unexpected behaviour from the API
5512:            	@exception StandardException Unexpected exception from the implementation
5513:
5514:             */
5515:            protected void P051() throws StandardException, T_Fail {
5516:                if (!testRollback)
5517:                    return;
5518:
5519:                Transaction t = t_util.t_startTransaction();
5520:                long cid = t_util.t_addContainer(t, 0);
5521:                t_util.t_commit(t);
5522:
5523:                T_RawStoreRow row = new T_RawStoreRow(REC_001);
5524:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
5525:                Page page = t_util.t_getPage(c,
5526:                        ContainerHandle.FIRST_PAGE_NUMBER);
5527:
5528:                // first insert and check that an abort leaves the row there
5529:                RecordHandle rh1 = t_util.t_insert(page, row);
5530:
5531:                t_util.t_commit(t);
5532:
5533:                c = t_util.t_openContainer(t, 0, cid, true);
5534:
5535:                t_util.t_checkFetch(c, rh1, REC_001);
5536:
5537:                row = new T_RawStoreRow(REC_002);
5538:
5539:                RecordHandle rh2 = t_util.t_insert(c, row);
5540:
5541:                t_util.t_checkFetch(c, rh1, REC_001);
5542:                t_util.t_checkFetch(c, rh2, REC_002);
5543:
5544:                t_util.t_abort(t);
5545:
5546:                c = t_util.t_openContainer(t, 0, cid, true);
5547:                t_util.t_checkFetch(c, rh1, REC_001);
5548:
5549:                page = t_util.t_getPage(c, rh2.getPageNumber());
5550:                if (page.recordExists(rh2, false)) {
5551:                    throw T_Fail.testFailMsg("record insert was not undone");
5552:                }
5553:                page.unlatch();
5554:
5555:                PASS("P051");
5556:
5557:                t_util.t_dropContainer(t, 0, cid); // cleanup
5558:
5559:                t_util.t_commit(t);
5560:                t.close();
5561:            }
5562:
5563:            /**
5564:            	Test rollback of Page.delete
5565:            	@exception T_Fail Unexpected behaviour from the API
5566:            	@exception StandardException Unexpected exception from the implementation
5567:
5568:            	@see Page#delete
5569:
5570:             */
5571:            protected void P052() throws StandardException, T_Fail {
5572:                if (!testRollback)
5573:                    return;
5574:
5575:                Transaction t = t_util.t_startTransaction();
5576:
5577:                long cid = t_util.t_addContainer(t, 0);
5578:                t_util.t_commit(t);
5579:
5580:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
5581:
5582:                // first insert two rows
5583:                T_RawStoreRow row = new T_RawStoreRow(REC_001);
5584:                RecordHandle rh1 = t_util.t_insert(c, row);
5585:                row = new T_RawStoreRow(REC_002);
5586:                RecordHandle rh2 = t_util.t_insert(c, row);
5587:
5588:                t_util.t_commit(t);
5589:
5590:                c = t_util.t_openContainer(t, 0, cid, true);
5591:
5592:                t_util.t_checkFetch(c, rh1, REC_001);
5593:                t_util.t_checkFetch(c, rh2, REC_002);
5594:
5595:                t_util.t_delete(c, rh2);
5596:
5597:                t_util.t_checkFetch(c, rh1, REC_001);
5598:
5599:                t_util.t_abort(t);
5600:
5601:                c = t_util.t_openContainer(t, 0, cid, true);
5602:                t_util.t_checkFetch(c, rh1, REC_001);
5603:                t_util.t_checkFetch(c, rh2, REC_002);
5604:
5605:                PASS("P052");
5606:
5607:                t_util.t_dropContainer(t, 0, cid); // cleanup
5608:
5609:                t_util.t_commit(t);
5610:                t.close();
5611:            }
5612:
5613:            /**
5614:            	Test insertAtSlot that rolls back with a purge
5615:
5616:            	@exception T_Fail Unexpected behaviour from the API
5617:            	@exception StandardException Unexpected exception from the implementation
5618:
5619:             */
5620:            protected void P053() throws StandardException, T_Fail {
5621:                if (!testRollback)
5622:                    return;
5623:                Transaction t = t_util.t_startTransaction();
5624:
5625:                try {
5626:                    long cid = t_util.t_addContainer(t, 0);
5627:                    t_util.t_commit(t);
5628:
5629:                    ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
5630:                    Page page = t_util.t_addPage(c);
5631:
5632:                    T_RawStoreRow row0 = new T_RawStoreRow(REC_001);
5633:                    T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
5634:                    T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
5635:                    T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
5636:                    T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
5637:
5638:                    t_util.t_insertAtSlot(page, 0, row0,
5639:                            Page.INSERT_UNDO_WITH_PURGE);
5640:
5641:                    if (t_util.t_insertAtSlot(page, 1, row1) == null)
5642:                        return;
5643:
5644:                    if (t_util.t_insertAtSlot(page, 2, row2,
5645:                            Page.INSERT_UNDO_WITH_PURGE) == null)
5646:                        return;
5647:
5648:                    if (t_util.t_insertAtSlot(page, 3, row3) == null)
5649:                        return;
5650:
5651:                    if (t_util.t_insertAtSlot(page, 4, row4,
5652:                            Page.INSERT_UNDO_WITH_PURGE) == null)
5653:                        return;
5654:
5655:                    int fillerRows = 0;
5656:                    while (page.spaceForInsert()) {
5657:                        t_util.t_insertAtSlot(page, 4, row4);
5658:                        fillerRows++;
5659:                    }
5660:
5661:                    t_util.t_checkRecordCount(page, fillerRows + 5,
5662:                            fillerRows + 5);
5663:                    t_util.t_abort(t);
5664:
5665:                    c = t_util.t_openContainer(t, 0, cid, true);
5666:                    page = t_util.t_getLastPage(c);
5667:
5668:                    // 2 + fillerRows deleted, 3 purged, 0 nondeleted
5669:                    t_util.t_checkRecordCount(page, 2 + fillerRows, 0);
5670:
5671:                    // since I just purged them, there must be space for re-inserting them
5672:                    t_util.t_insert(page, row0);
5673:                    t_util.t_insert(page, row2);
5674:                    t_util.t_insert(page, row4);
5675:
5676:                    t_util.t_checkRecordCount(page, 5 + fillerRows, 3);
5677:
5678:                    page.unlatch();
5679:                    PASS("P053");
5680:
5681:                    t_util.t_dropContainer(t, 0, cid); // cleanup
5682:                } finally {
5683:                    t_util.t_commit(t);
5684:                    t.close();
5685:                }
5686:            }
5687:
5688:            /**
5689:            	Test internal transaction 
5690:
5691:            	@exception T_Fail Unexpected behaviour from the API
5692:            	@exception StandardException Unexpected exception from the implementation
5693:
5694:             */
5695:            protected void P054() throws StandardException, T_Fail {
5696:                if (!testRollback)
5697:                    return;
5698:
5699:                ContextManager previousCM = contextService
5700:                        .getCurrentContextManager();
5701:
5702:                ContextManager cm1 = contextService.newContextManager();
5703:                contextService.setCurrentContextManager(cm1);
5704:
5705:                Transaction tuser = t_util.t_startTransaction();
5706:                Transaction tinternal = null;
5707:
5708:                try {
5709:
5710:                    long cid1 = t_util.t_addContainer(tuser, 0);
5711:                    ContainerHandle c1 = t_util.t_openContainer(tuser, 0, cid1,
5712:                            true);
5713:                    Page p1 = t_util.t_addPage(c1);
5714:                    t_util.t_commit(tuser);
5715:
5716:                    // insert a row using user transaction 
5717:                    T_RawStoreRow row = new T_RawStoreRow(REC_001);
5718:
5719:                    c1 = t_util.t_openContainer(tuser, 0, cid1, true);
5720:                    p1 = t_util.t_getLastPage(c1);
5721:                    RecordHandle r1 = t_util.t_insert(p1, row);
5722:
5723:                    REPORT("starting internal transaction");
5724:
5725:                    tinternal = t_util.t_startInternalTransaction();
5726:                    long cid2 = t_util.t_addContainer(tinternal, 0);
5727:                    ContainerHandle c2 = t_util.t_openContainer(tinternal, 0,
5728:                            cid2, true);
5729:                    Page p2 = t_util.t_addPage(c2);
5730:                    RecordHandle r2 = t_util.t_insert(p2, row);
5731:
5732:                    // commit internal transaction
5733:                    tinternal.commit();
5734:                    tinternal.abort(); // this will close the container and release
5735:                    // the page
5736:                    tinternal.close();
5737:                    tinternal = null;
5738:
5739:                    REPORT("commit internal transaction");
5740:
5741:                    // abort user transaction
5742:                    t_util.t_abort(tuser);
5743:
5744:                    REPORT("rollback user transaction");
5745:
5746:                    c1 = t_util.t_openContainer(tuser, 0, cid1, true);
5747:
5748:                    p1 = t_util.t_getPage(c1, r1.getPageNumber());
5749:                    if (p1.recordExists(r1, false))
5750:                        throw T_Fail
5751:                                .testFailMsg("user transaction failed to rollback");
5752:
5753:                    c2 = t_util.t_openContainer(tuser, 0, cid2, true);
5754:                    t_util.t_checkFetch(c2, r2, REC_001); // this should be unaffected by the
5755:                    // user transaction rollback
5756:                    p2 = t_util.t_getLastPage(c2);
5757:
5758:                    T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
5759:
5760:                    if (!p2.spaceForInsert()) {
5761:                        REPORT("P054 not run, page cannot accomodate 2 rows");
5762:                        return;
5763:                    }
5764:                    RecordHandle r21 = t_util.t_insert(p2, row2);
5765:
5766:                    // throw an exception, make sure everything is aborted.
5767:                    tinternal = t_util.t_startInternalTransaction();
5768:                    long cid3 = t_util.t_addContainer(tinternal, 0);
5769:                    ContainerHandle c3 = t_util.t_openContainer(tinternal, 0,
5770:                            cid3, true);
5771:                    Page p3 = t_util.t_addPage(c3);
5772:                    RecordHandle r3 = t_util.t_insert(p3, row);
5773:                    try {
5774:                        // this will throw a data statement exception
5775:                        t_util.t_insertAtSlot(p3, 100, row);
5776:                    } catch (StandardException se) {
5777:                        REPORT("cleanup on error");
5778:                        cm1.cleanupOnError(se);
5779:                        REPORT("done cleanup on error");
5780:                    }
5781:
5782:                    tinternal = null;
5783:                    // 	tuser = t_util.t_startTransaction();
5784:                    c2 = t_util.t_openContainer(tuser, 0, cid2, true);
5785:                    t_util.t_checkFetch(c2, r2, REC_001);
5786:
5787:                    p2 = t_util.t_getPage(c2, r21.getPageNumber());
5788:                    if (p2.recordExists(r21, false))
5789:                        throw T_Fail
5790:                                .testFailMsg("expect user transaction to rollback");
5791:
5792:                    // this should fail
5793:                    ContainerKey id3 = new ContainerKey(0, cid3);
5794:                    c3 = tuser
5795:                            .openContainer(id3, ContainerHandle.MODE_READONLY);
5796:                    if (c3 != null)
5797:                        throw T_Fail
5798:                                .testFailMsg("expect internal transaction to rollback");
5799:
5800:                    LockingPolicy nolock = tuser.newLockingPolicy(
5801:                            LockingPolicy.MODE_NONE, 0, false);
5802:
5803:                    RawContainerHandle stub = ((RawTransaction) tuser)
5804:                            .openDroppedContainer(id3, nolock);
5805:
5806:                    if (stub == null)
5807:                        throw T_Fail
5808:                                .testFailMsg("expect container to be dropped");
5809:
5810:                    if (stub.getContainerStatus() != RawContainerHandle.COMMITTED_DROP)
5811:                        throw T_Fail
5812:                                .testFailMsg("expect container to be committed dropped");
5813:
5814:                    // this should fail
5815:                    p3 = stub.getPage(r3.getPageNumber());
5816:
5817:                    if (p3 != null)
5818:                        throw T_Fail
5819:                                .testFailMsg("should not getpage with committed dropped container");
5820:
5821:                    PASS("P054");
5822:
5823:                    t_util.t_dropContainer(tuser, 0, cid2); // cleanup
5824:                    t_util.t_dropContainer(tuser, 0, cid1); // cleanup
5825:
5826:                    if (tinternal != null) {
5827:                        t_util.t_abort(tinternal);
5828:                        tinternal.close();
5829:                    }
5830:
5831:                    if (tuser != null) {
5832:                        t_util.t_commit(tuser);
5833:                        tuser.close();
5834:                    }
5835:                } finally {
5836:
5837:                    contextService.resetCurrentContextManager(cm1);
5838:                }
5839:
5840:            }
5841:
5842:            /**
5843:                Test rollback of partial row update.
5844:                Create a long row with 10 columns on 2 pages (5 columns on each page).
5845:                Update the 1st column on the 2nd page (the 6th column) which causes the
5846:                last column (10th column) to move off the page. Then abort and make sure
5847:                that all the original columns are there and correct.
5848:
5849:                NOTE: stored length is twice string length + 2
5850:
5851:            	@exception T_Fail Unexpected behaviour from the API
5852:            	@exception StandardException Unexpected exception from the implementation
5853:             */
5854:            protected void P055(long segment) throws StandardException, T_Fail {
5855:
5856:                if (!testRollback)
5857:                    return;
5858:
5859:                Transaction t = t_util.t_startTransaction();
5860:
5861:                long cid = t_util.t_addContainer(t, segment, 4096);
5862:
5863:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
5864:                        true);
5865:                Page page = t_util.t_getPage(c,
5866:                        ContainerHandle.FIRST_PAGE_NUMBER);
5867:                t_util.t_checkEmptyPage(page);
5868:
5869:                int colSize = 90;
5870:                T_RawStoreRow r0 = new T_RawStoreRow(10);
5871:                r0.setColumn(0, colSize, REC_001);
5872:                r0.setColumn(1, colSize, REC_002);
5873:                r0.setColumn(2, colSize, REC_003);
5874:                r0.setColumn(3, colSize, REC_004);
5875:                r0.setColumn(4, colSize, REC_005);
5876:                r0.setColumn(5, colSize, REC_009);
5877:                r0.setColumn(6, colSize, REC_010);
5878:                r0.setColumn(7, colSize, REC_011);
5879:                r0.setColumn(8, colSize, REC_012);
5880:                r0.setColumn(9, colSize, REC_013);
5881:
5882:                int insertFlag = Page.INSERT_INITIAL;
5883:                insertFlag |= Page.INSERT_OVERFLOW;
5884:
5885:                RecordHandle rh0 = null;
5886:                try {
5887:                    rh0 = t_util.t_insertAtSlot(page, 0, r0, (byte) insertFlag);
5888:                } catch (StandardException se) {
5889:                    throw T_Fail.testFailMsg("insert of long row failed.");
5890:                }
5891:
5892:                if (rh0 == null)
5893:                    throw T_Fail
5894:                            .testFailMsg("insert of first long row failed.");
5895:                else {
5896:                    REPORT("about to check fetch...");
5897:                    DataValueDescriptor column = new SQLChar();
5898:                    t_util.t_checkFetchColFromSlot(page,
5899:                            page.FIRST_SLOT_NUMBER, 0, column, false, REC_001,
5900:                            colSize);
5901:                    t_util.t_checkFetchColFromSlot(page,
5902:                            page.FIRST_SLOT_NUMBER, 1, column, false, REC_002,
5903:                            colSize);
5904:                    t_util.t_checkFetchColFromSlot(page,
5905:                            page.FIRST_SLOT_NUMBER, 2, column, false, REC_003,
5906:                            colSize);
5907:                    t_util.t_checkFetchColFromSlot(page,
5908:                            page.FIRST_SLOT_NUMBER, 3, column, false, REC_004,
5909:                            colSize);
5910:                    t_util.t_checkFetchColFromSlot(page,
5911:                            page.FIRST_SLOT_NUMBER, 4, column, false, REC_005,
5912:                            colSize);
5913:                    t_util.t_checkFetchColFromSlot(page,
5914:                            page.FIRST_SLOT_NUMBER, 5, column, false, REC_009,
5915:                            colSize);
5916:                    t_util.t_checkFetchColFromSlot(page,
5917:                            page.FIRST_SLOT_NUMBER, 6, column, false, REC_010,
5918:                            colSize);
5919:                    t_util.t_checkFetchColFromSlot(page,
5920:                            page.FIRST_SLOT_NUMBER, 7, column, false, REC_011,
5921:                            colSize);
5922:                    t_util.t_checkFetchColFromSlot(page,
5923:                            page.FIRST_SLOT_NUMBER, 8, column, false, REC_012,
5924:                            colSize);
5925:                    t_util.t_checkFetchColFromSlot(page,
5926:                            page.FIRST_SLOT_NUMBER, 9, column, false, REC_013,
5927:                            colSize);
5928:                }
5929:
5930:                t_util.t_commit(t);
5931:
5932:                // update col 5 (the 6th column, the first column on the 2nd overflow page), which causes
5933:                // the last column (col 9, the 10th column) to move off the page.
5934:
5935:                c = t_util.t_openContainer(t, segment, cid, true);
5936:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
5937:
5938:                T_RawStoreRow updateRow = new T_RawStoreRow(10);
5939:                for (int i = 0; i < 10; i++)
5940:                    updateRow.setColumn(i, (String) null);
5941:                updateRow.setColumn(5, colSize * 2, REC_009);
5942:                FormatableBitSet colList = new FormatableBitSet(10);
5943:                colList.set(5);
5944:                page.updateAtSlot(0, updateRow.getRow(), colList);
5945:
5946:                REPORT("about to check fetch after update ...");
5947:                DataValueDescriptor column = new SQLChar();
5948:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 0,
5949:                        column, false, REC_001, colSize);
5950:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 1,
5951:                        column, false, REC_002, colSize);
5952:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 2,
5953:                        column, false, REC_003, colSize);
5954:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 3,
5955:                        column, false, REC_004, colSize);
5956:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 4,
5957:                        column, false, REC_005, colSize);
5958:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 5,
5959:                        column, false, REC_009, colSize * 2);
5960:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 6,
5961:                        column, false, REC_010, colSize);
5962:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 7,
5963:                        column, false, REC_011, colSize);
5964:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 8,
5965:                        column, false, REC_012, colSize);
5966:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 9,
5967:                        column, false, REC_013, colSize);
5968:                page.unlatch();
5969:
5970:                t_util.t_abort(t);
5971:
5972:                REPORT("about to check fetch after abort ...");
5973:                c = t_util.t_openContainer(t, segment, cid, false);
5974:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
5975:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 0,
5976:                        column, false, REC_001, colSize);
5977:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 1,
5978:                        column, false, REC_002, colSize);
5979:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 2,
5980:                        column, false, REC_003, colSize);
5981:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 3,
5982:                        column, false, REC_004, colSize);
5983:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 4,
5984:                        column, false, REC_005, colSize);
5985:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 5,
5986:                        column, false, REC_009, colSize);
5987:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 6,
5988:                        column, false, REC_010, colSize);
5989:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 7,
5990:                        column, false, REC_011, colSize);
5991:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 8,
5992:                        column, false, REC_012, colSize);
5993:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 9,
5994:                        column, false, REC_013, colSize);
5995:                page.unlatch();
5996:
5997:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
5998:                    t_util.t_dropContainer(t, segment, cid); // cleanup
5999:                }
6000:
6001:                t_util.t_commit(t);
6002:                t.close();
6003:
6004:                PASS("P055: segment = " + segment);
6005:            }
6006:
6007:            /**
6008:                Test rollback of partial row update.
6009:                Create a long row with 15 columns on 3 pages (5 columns on each page).
6010:                Update the 1st column on the 2nd page (the 6th column) which causes the
6011:                last column of that page (10th column) to move off the page. Then abort
6012:                and make sure that all the original columns are there and correct.
6013:
6014:                NOTE: stored length is twice string length + 2
6015:
6016:            	@exception T_Fail Unexpected behaviour from the API
6017:            	@exception StandardException Unexpected exception from the implementation
6018:             */
6019:            protected void P056(long segment) throws StandardException, T_Fail {
6020:
6021:                if (!testRollback)
6022:                    return;
6023:
6024:                Transaction t = t_util.t_startTransaction();
6025:
6026:                long cid = t_util.t_addContainer(t, segment, 4096);
6027:
6028:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6029:                        true);
6030:                Page page = t_util.t_getPage(c,
6031:                        ContainerHandle.FIRST_PAGE_NUMBER);
6032:                t_util.t_checkEmptyPage(page);
6033:
6034:                int colSize = 90;
6035:                T_RawStoreRow r0 = new T_RawStoreRow(15);
6036:                r0.setColumn(0, colSize, REC_001);
6037:                r0.setColumn(1, colSize, REC_002);
6038:                r0.setColumn(2, colSize, REC_003);
6039:                r0.setColumn(3, colSize, REC_004);
6040:                r0.setColumn(4, colSize, REC_005);
6041:                r0.setColumn(5, colSize, REC_009);
6042:                r0.setColumn(6, colSize, REC_010);
6043:                r0.setColumn(7, colSize, REC_011);
6044:                r0.setColumn(8, colSize, REC_012);
6045:                r0.setColumn(9, colSize, REC_013);
6046:                r0.setColumn(10, colSize, REC_014);
6047:                r0.setColumn(11, colSize, REC_015);
6048:                r0.setColumn(12, colSize, REC_016);
6049:                r0.setColumn(13, colSize, REC_017);
6050:                r0.setColumn(14, colSize, REC_018);
6051:
6052:                int insertFlag = Page.INSERT_INITIAL;
6053:                insertFlag |= Page.INSERT_OVERFLOW;
6054:
6055:                RecordHandle rh0 = null;
6056:                try {
6057:                    rh0 = t_util.t_insertAtSlot(page, 0, r0, (byte) insertFlag);
6058:                } catch (StandardException se) {
6059:                    throw T_Fail.testFailMsg("insert of long row failed.");
6060:                }
6061:
6062:                if (rh0 == null)
6063:                    throw T_Fail
6064:                            .testFailMsg("insert of first long row failed.");
6065:                else {
6066:                    REPORT("about to check fetch...");
6067:                    DataValueDescriptor column = new SQLChar();
6068:                    t_util.t_checkFetchColFromSlot(page,
6069:                            page.FIRST_SLOT_NUMBER, 0, column, false, REC_001,
6070:                            colSize);
6071:                    t_util.t_checkFetchColFromSlot(page,
6072:                            page.FIRST_SLOT_NUMBER, 1, column, false, REC_002,
6073:                            colSize);
6074:                    t_util.t_checkFetchColFromSlot(page,
6075:                            page.FIRST_SLOT_NUMBER, 2, column, false, REC_003,
6076:                            colSize);
6077:                    t_util.t_checkFetchColFromSlot(page,
6078:                            page.FIRST_SLOT_NUMBER, 3, column, false, REC_004,
6079:                            colSize);
6080:                    t_util.t_checkFetchColFromSlot(page,
6081:                            page.FIRST_SLOT_NUMBER, 4, column, false, REC_005,
6082:                            colSize);
6083:                    t_util.t_checkFetchColFromSlot(page,
6084:                            page.FIRST_SLOT_NUMBER, 5, column, false, REC_009,
6085:                            colSize);
6086:                    t_util.t_checkFetchColFromSlot(page,
6087:                            page.FIRST_SLOT_NUMBER, 6, column, false, REC_010,
6088:                            colSize);
6089:                    t_util.t_checkFetchColFromSlot(page,
6090:                            page.FIRST_SLOT_NUMBER, 7, column, false, REC_011,
6091:                            colSize);
6092:                    t_util.t_checkFetchColFromSlot(page,
6093:                            page.FIRST_SLOT_NUMBER, 8, column, false, REC_012,
6094:                            colSize);
6095:                    t_util.t_checkFetchColFromSlot(page,
6096:                            page.FIRST_SLOT_NUMBER, 9, column, false, REC_013,
6097:                            colSize);
6098:                    t_util.t_checkFetchColFromSlot(page,
6099:                            page.FIRST_SLOT_NUMBER, 10, column, false, REC_014,
6100:                            colSize);
6101:                    t_util.t_checkFetchColFromSlot(page,
6102:                            page.FIRST_SLOT_NUMBER, 11, column, false, REC_015,
6103:                            colSize);
6104:                    t_util.t_checkFetchColFromSlot(page,
6105:                            page.FIRST_SLOT_NUMBER, 12, column, false, REC_016,
6106:                            colSize);
6107:                    t_util.t_checkFetchColFromSlot(page,
6108:                            page.FIRST_SLOT_NUMBER, 13, column, false, REC_017,
6109:                            colSize);
6110:                    t_util.t_checkFetchColFromSlot(page,
6111:                            page.FIRST_SLOT_NUMBER, 14, column, false, REC_018,
6112:                            colSize);
6113:                }
6114:
6115:                t_util.t_commit(t);
6116:
6117:                // update col 5 (the 6th column, the first column on the 2nd overflow page), which causes
6118:                // the last column (col 9, the 10th column) to move off the page.
6119:
6120:                c = t_util.t_openContainer(t, segment, cid, true);
6121:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6122:
6123:                T_RawStoreRow updateRow = new T_RawStoreRow(15);
6124:                for (int i = 0; i < 15; i++)
6125:                    updateRow.setColumn(i, (String) null);
6126:                updateRow.setColumn(5, colSize * 2, REC_009);
6127:                FormatableBitSet colList = new FormatableBitSet(15);
6128:                colList.set(5);
6129:                page.updateAtSlot(0, updateRow.getRow(), colList);
6130:
6131:                REPORT("about to check fetch after update ...");
6132:                DataValueDescriptor column = new SQLChar();
6133:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 0,
6134:                        column, false, REC_001, colSize);
6135:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 1,
6136:                        column, false, REC_002, colSize);
6137:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 2,
6138:                        column, false, REC_003, colSize);
6139:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 3,
6140:                        column, false, REC_004, colSize);
6141:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 4,
6142:                        column, false, REC_005, colSize);
6143:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 5,
6144:                        column, false, REC_009, colSize * 2);
6145:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 6,
6146:                        column, false, REC_010, colSize);
6147:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 7,
6148:                        column, false, REC_011, colSize);
6149:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 8,
6150:                        column, false, REC_012, colSize);
6151:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 9,
6152:                        column, false, REC_013, colSize);
6153:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6154:                        10, column, false, REC_014, colSize);
6155:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6156:                        11, column, false, REC_015, colSize);
6157:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6158:                        12, column, false, REC_016, colSize);
6159:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6160:                        13, column, false, REC_017, colSize);
6161:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6162:                        14, column, false, REC_018, colSize);
6163:                page.unlatch();
6164:
6165:                t_util.t_abort(t);
6166:
6167:                REPORT("about to check fetch after abort ...");
6168:                c = t_util.t_openContainer(t, segment, cid, false);
6169:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6170:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 0,
6171:                        column, false, REC_001, colSize);
6172:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 1,
6173:                        column, false, REC_002, colSize);
6174:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 2,
6175:                        column, false, REC_003, colSize);
6176:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 3,
6177:                        column, false, REC_004, colSize);
6178:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 4,
6179:                        column, false, REC_005, colSize);
6180:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 5,
6181:                        column, false, REC_009, colSize);
6182:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 6,
6183:                        column, false, REC_010, colSize);
6184:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 7,
6185:                        column, false, REC_011, colSize);
6186:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 8,
6187:                        column, false, REC_012, colSize);
6188:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER, 9,
6189:                        column, false, REC_013, colSize);
6190:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6191:                        10, column, false, REC_014, colSize);
6192:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6193:                        11, column, false, REC_015, colSize);
6194:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6195:                        12, column, false, REC_016, colSize);
6196:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6197:                        13, column, false, REC_017, colSize);
6198:                t_util.t_checkFetchColFromSlot(page, page.FIRST_SLOT_NUMBER,
6199:                        14, column, false, REC_018, colSize);
6200:                page.unlatch();
6201:
6202:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6203:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6204:                }
6205:                t_util.t_commit(t);
6206:                t.close();
6207:
6208:                PASS("P056: segment = " + segment);
6209:            }
6210:
6211:            /**
6212:               Sparse row test.
6213:               Test sparse representation of rows using the FormatableBitSet class.
6214:               Insert, fetch and update a row having gaps.
6215:
6216:            	@exception T_Fail Unexpected behaviour from the API
6217:            	@exception StandardException Unexpected exception from the implementation
6218:             */
6219:            protected void P061() throws StandardException, T_Fail {
6220:                long segment = 0;
6221:                Transaction t = t_util.t_startTransaction();
6222:                long cid = t_util.t_addContainer(t, segment);
6223:
6224:                int numCols = 6;
6225:                T_RawStoreRow row1 = new T_RawStoreRow(numCols);
6226:                row1.setColumn(0, (String) null);
6227:                row1.setColumn(1, REC_001);
6228:                row1.setColumn(2, (String) null);
6229:                row1.setColumn(3, REC_002);
6230:                row1.setColumn(4, (String) null);
6231:                row1.setColumn(5, REC_003);
6232:
6233:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6234:                        true);
6235:                Page page = t_util.t_getPage(c,
6236:                        ContainerHandle.FIRST_PAGE_NUMBER);
6237:                try {
6238:                    RecordHandle rh1 = t_util.t_insert(page, row1);
6239:
6240:                    t_util.t_checkFetchCol(page, rh1, 1, numCols, REC_001);
6241:                    t_util.t_checkFetchCol(page, rh1, 3, numCols, REC_002);
6242:                    t_util.t_checkFetchCol(page, rh1, 5, numCols, REC_003);
6243:
6244:                    t_util.t_checkUpdateCol(page, rh1, 1, numCols, "woody");
6245:                    t_util.t_checkUpdateCol(page, rh1, 3, numCols, "buzz");
6246:                    t_util.t_checkUpdateCol(page, rh1, 5, numCols, "andy");
6247:
6248:                    t_util.t_checkUpdateCol(page, rh1, 2, numCols, "dino");
6249:
6250:                    page.unlatch();
6251:                    page = null;
6252:
6253:                    t_util.t_commit(t);
6254:                } finally {
6255:                    if (page != null)
6256:                        page.unlatch();
6257:                    t_util.t_commit(t);
6258:                    t.close();
6259:                }
6260:
6261:                PASS("P061");
6262:            }
6263:
6264:            /**
6265:               Serializable column test.
6266:               Want to make sure we hit some otherwise dead code in StoredPage, used
6267:               for storing/reading Serializable/Externalizable data to/from a page.
6268:
6269:            	@exception T_Fail Unexpected behaviour from the API
6270:            	@exception StandardException Unexpected exception from the implementation
6271:             */
6272:            protected void P071() throws StandardException, T_Fail {
6273:                /*
6274:                long segment = 0;
6275:                Transaction t = t_util.t_startTransaction();
6276:                long cid = t_util.t_addContainer(t, segment);
6277:
6278:                int numCols = 1;
6279:                T_RawStoreRow row1 = new T_RawStoreRow(numCols);
6280:                row1.setColumn(0,  new T_Serializable(REC_001));
6281:
6282:                ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
6283:                Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6284:                try
6285:                {
6286:                	RecordHandle rh1 = t_util.t_insert(page, row1);
6287:
6288:                	t_util.t_checkFetchSerCol(page, rh1, 0, numCols, new T_Serializable(REC_001));
6289:
6290:                	page.unlatch();
6291:                	page = null;
6292:
6293:                	t_util.t_commit(t);
6294:                }
6295:                finally
6296:                {
6297:                	if (page != null)
6298:                		page.unlatch();
6299:                	t_util.t_commit(t);
6300:                	t.close();
6301:                }
6302:                 */
6303:
6304:                PASS("P071");
6305:            }
6306:
6307:            /*
6308:             ** Update and update partial tests aimed at long rows
6309:             */
6310:
6311:            /**
6312:            	Insert a single row and keep updating it, adding columns
6313:            	not using partial rows.
6314:
6315:            	@exception T_Fail Unexpected behaviour from the API
6316:            	@exception StandardException Unexpected exception from the implementation
6317:             */
6318:            protected void P701(long segment) throws StandardException, T_Fail {
6319:
6320:                Transaction t = t_util.t_startTransaction();
6321:
6322:                long cid = t_util.t_addContainer(t, segment, 4096);
6323:
6324:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6325:                        true);
6326:                Page page = t_util.t_getPage(c,
6327:                        ContainerHandle.FIRST_PAGE_NUMBER);
6328:                t_util.t_checkEmptyPage(page);
6329:
6330:                T_RawStoreRow row = new T_RawStoreRow(0);
6331:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6332:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6333:                t_util.t_checkFetch(page, rh, row);
6334:
6335:                page.unlatch();
6336:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6337:
6338:                for (int i = 0; i < 10; i++) {
6339:
6340:                    REPORT("P701 - iteration " + i);
6341:
6342:                    row = new T_RawStoreRow(i);
6343:
6344:                    for (int j = 0; j < i; j++) {
6345:                        row.setColumn(j, 256, "XX" + j + "YY");
6346:                    }
6347:
6348:                    page.update(rh, row.getRow(), (FormatableBitSet) null);
6349:                    page.unlatch();
6350:                    page = t_util.t_getPage(c,
6351:                            ContainerHandle.FIRST_PAGE_NUMBER);
6352:
6353:                    t_util.t_checkFetch(page, rh, row);
6354:                }
6355:
6356:                page.unlatch();
6357:
6358:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6359:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6360:                }
6361:
6362:                t_util.t_commit(t);
6363:
6364:                t.close();
6365:
6366:                PASS("P701: segment = " + segment);
6367:            }
6368:
6369:            /*
6370:             ** Update and update partial tests aimed at long rows
6371:             */
6372:
6373:            /**
6374:            	Insert a single row and keep updating it, adding columns
6375:            	using partial rows.
6376:
6377:            	@exception T_Fail Unexpected behaviour from the API
6378:            	@exception StandardException Unexpected exception from the implementation
6379:             */
6380:            protected void P702(long segment) throws StandardException, T_Fail {
6381:
6382:                Transaction t = t_util.t_startTransaction();
6383:
6384:                long cid = t_util.t_addContainer(t, segment, 4096);
6385:
6386:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6387:                        true);
6388:                Page page = t_util.t_getPage(c,
6389:                        ContainerHandle.FIRST_PAGE_NUMBER);
6390:                t_util.t_checkEmptyPage(page);
6391:
6392:                T_RawStoreRow row = new T_RawStoreRow(0);
6393:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6394:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6395:                t_util.t_checkFetch(page, rh, row);
6396:
6397:                page.unlatch();
6398:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6399:
6400:                for (int i = 0; i < 10; i++) {
6401:
6402:                    REPORT("P702 - iteration " + i);
6403:
6404:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6405:                    colList.set(i);
6406:
6407:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6408:                    rowU.setColumn(i, 256, "XX" + i + "YY");
6409:
6410:                    page.update(rh, rowU.getRow(), colList);
6411:                    page.unlatch();
6412:
6413:                    T_RawStoreRow rowF = new T_RawStoreRow(i + 1);
6414:
6415:                    for (int j = 0; j <= i; j++) {
6416:                        rowF.setColumn(j, 256, "XX" + j + "YY");
6417:                    }
6418:
6419:                    page = t_util.t_getPage(c,
6420:                            ContainerHandle.FIRST_PAGE_NUMBER);
6421:
6422:                    t_util.t_checkFetch(page, rh, rowF);
6423:                }
6424:                page.unlatch();
6425:
6426:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6427:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6428:                }
6429:
6430:                t_util.t_commit(t);
6431:
6432:                t.close();
6433:
6434:                PASS("P702: segment = " + segment);
6435:            }
6436:
6437:            /**
6438:            	Simple set of partial row updates on a singel page with
6439:            	shrinking and expanding columns.
6440:
6441:            	@exception T_Fail Unexpected behaviour from the API
6442:            	@exception StandardException Unexpected exception from the implementation
6443:             */
6444:
6445:            protected void P703(long segment) throws StandardException, T_Fail {
6446:                Transaction t = t_util.t_startTransaction();
6447:
6448:                long cid = t_util.t_addContainer(t, segment, 4096);
6449:
6450:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6451:                        true);
6452:                Page page = t_util.t_getPage(c,
6453:                        ContainerHandle.FIRST_PAGE_NUMBER);
6454:                t_util.t_checkEmptyPage(page);
6455:
6456:                REPORT("P703 - start ");
6457:                T_RawStoreRow row = new T_RawStoreRow(2);
6458:                row.setColumn(0, REC_001);
6459:                row.setColumn(1, REC_002);
6460:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6461:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6462:                t_util.t_checkFetch(page, rh, row);
6463:                REPORT("P703 - insert Ok ");
6464:
6465:                page.unlatch();
6466:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6467:
6468:                // Perform 10 tests
6469:                // 1  update col0 to grow
6470:                // 2  update col1 to grow
6471:                // 3  update col0 to shrink
6472:                // 4  update col1 to shrink
6473:                // 5  update col0 to null
6474:                // 6  update col1 to null
6475:                // 7  update col0 to non-null
6476:                // 8  update col1 to non-null
6477:                // 9  update no columns
6478:                // 10 update both cols
6479:
6480:                P703Helper(page, rh, 0, REC_006, REC_002);
6481:                REPORT("P703 - case 1 passed");
6482:
6483:                P703Helper(page, rh, 1, REC_007, REC_006);
6484:                REPORT("P703 - case 2 passed");
6485:
6486:                P703Helper(page, rh, 0, REC_003, REC_007);
6487:                REPORT("P703 - case 3 passed");
6488:
6489:                P703Helper(page, rh, 1, REC_004, REC_003);
6490:                REPORT("P703 - case 4 passed");
6491:
6492:                P703Helper(page, rh, 0, null, REC_004);
6493:                REPORT("P703 - case 5 passed");
6494:
6495:                P703Helper(page, rh, 1, null, null);
6496:                REPORT("P703 - case 6 passed");
6497:
6498:                P703Helper(page, rh, 0, REC_002, null);
6499:                REPORT("P703 - case 7 passed");
6500:
6501:                P703Helper(page, rh, 1, REC_001, REC_002);
6502:                REPORT("P703 - case 8 passed");
6503:
6504:                P703Helper(page, rh, -1, REC_002, REC_001);
6505:                REPORT("P703 - case 9 passed");
6506:
6507:                FormatableBitSet colList = new FormatableBitSet(2);
6508:                colList.set(0);
6509:                colList.set(1);
6510:                row.setColumn(0, REC_004);
6511:                row.setColumn(1, REC_003);
6512:                page.update(rh, row.getRow(), colList);
6513:                t_util.t_checkFetch(page, rh, row);
6514:
6515:                REPORT("P703 - case 10 passed");
6516:
6517:                page.unlatch();
6518:
6519:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6520:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6521:                }
6522:
6523:                t.commit();
6524:
6525:                t.close();
6526:
6527:                PASS("P703: segment = " + segment);
6528:            }
6529:
6530:            private void P703Helper(Page page, RecordHandle rh, int colNum,
6531:                    String newVal, String unchangedCol)
6532:                    throws StandardException, T_Fail {
6533:
6534:                FormatableBitSet colList = new FormatableBitSet(2);
6535:                T_RawStoreRow rowU = new T_RawStoreRow(2);
6536:
6537:                // -1 indicates no columns set in bit set
6538:                if (colNum != -1) {
6539:                    colList.grow(colNum + 1);
6540:                    colList.set(colNum);
6541:                    rowU.setColumn(colNum, newVal);
6542:                } else {
6543:                    colNum = 0; // only used for read from now on
6544:                }
6545:                page.update(rh, rowU.getRow(), colList);
6546:
6547:                T_RawStoreRow row = new T_RawStoreRow(2);
6548:                row.setColumn(colNum, newVal);
6549:                row.setColumn(colNum == 0 ? 1 : 0, unchangedCol);
6550:
6551:                t_util.t_checkFetch(page, rh, row);
6552:            }
6553:
6554:            /**
6555:            	Insert a single row with multiple portions.
6556:            	Update fields in the various portions that grow.
6557:
6558:            	@exception T_Fail Unexpected behaviour from the API
6559:            	@exception StandardException Unexpected exception from the implementation
6560:             */
6561:            protected void P704(long segment) throws StandardException, T_Fail {
6562:
6563:                Transaction t = t_util.t_startTransaction();
6564:
6565:                long cid = t_util.t_addContainer(t, segment, 4096);
6566:
6567:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6568:                        true);
6569:                Page page = t_util.t_getPage(c,
6570:                        ContainerHandle.FIRST_PAGE_NUMBER);
6571:                t_util.t_checkEmptyPage(page);
6572:
6573:                // row has 15 cols, each with 200 (ish) bytes (100 null chars)
6574:                // thus we would expect at least 3 pages
6575:                T_RawStoreRow row = new T_RawStoreRow(15);
6576:                for (int i = 0; i < 15; i++) {
6577:                    row.setColumn(i, 100, "XX" + i + "YY");
6578:                }
6579:
6580:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6581:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6582:                t_util.t_checkFetch(page, rh, row);
6583:
6584:                page.unlatch();
6585:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6586:
6587:                // update the each column to grow to be a single page (800 bytes ish)
6588:                for (int i = 0; i < 15; i++) {
6589:
6590:                    REPORT("P704 - col " + i);
6591:
6592:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6593:                    colList.set(i);
6594:
6595:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6596:                    rowU.setColumn(i, 400, "WW" + i + "UU");
6597:
6598:                    page.update(rh, rowU.getRow(), colList);
6599:                    page.unlatch();
6600:
6601:                    row.setColumn(i, 400, "WW" + i + "UU");
6602:
6603:                    page = t_util.t_getPage(c,
6604:                            ContainerHandle.FIRST_PAGE_NUMBER);
6605:
6606:                    t_util.t_checkFetch(page, rh, row);
6607:                }
6608:                page.unlatch();
6609:
6610:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6611:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6612:                }
6613:
6614:                t_util.t_commit(t);
6615:
6616:                t.close();
6617:
6618:                PASS("P704: segment = " + segment);
6619:            }
6620:
6621:            /**
6622:            	Same as 704 but update fields in the reverse order.
6623:
6624:            	@exception T_Fail Unexpected behaviour from the API
6625:            	@exception StandardException Unexpected exception from the implementation
6626:             */
6627:            protected void P705(long segment) throws StandardException, T_Fail {
6628:
6629:                Transaction t = t_util.t_startTransaction();
6630:
6631:                long cid = t_util.t_addContainer(t, segment, 4096);
6632:
6633:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6634:                        true);
6635:                Page page = t_util.t_getPage(c,
6636:                        ContainerHandle.FIRST_PAGE_NUMBER);
6637:                t_util.t_checkEmptyPage(page);
6638:
6639:                // row has 15 cols, each with 200 (ish) bytes (100 null chars)
6640:                // thus we would expect at least 3 pages
6641:                T_RawStoreRow row = new T_RawStoreRow(15);
6642:                for (int i = 0; i < 15; i++) {
6643:                    row.setColumn(i, 100, "XX" + i + "YY");
6644:                }
6645:
6646:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6647:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6648:                t_util.t_checkFetch(page, rh, row);
6649:
6650:                page.unlatch();
6651:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6652:
6653:                // update the each column to grow to be a single page (800 bytes ish)
6654:                for (int i = 14; i >= 0; i--) {
6655:
6656:                    REPORT("P705 - col " + i);
6657:
6658:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6659:                    colList.set(i);
6660:
6661:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6662:                    rowU.setColumn(i, 400, "WW" + i + "UU");
6663:
6664:                    page.update(rh, rowU.getRow(), colList);
6665:                    page.unlatch();
6666:
6667:                    row.setColumn(i, 400, "WW" + i + "UU");
6668:
6669:                    page = t_util.t_getPage(c,
6670:                            ContainerHandle.FIRST_PAGE_NUMBER);
6671:
6672:                    t_util.t_checkFetch(page, rh, row);
6673:                }
6674:                page.unlatch();
6675:
6676:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6677:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6678:                }
6679:
6680:                t_util.t_commit(t);
6681:
6682:                t.close();
6683:
6684:                PASS("P705: segment = " + segment);
6685:            }
6686:
6687:            /**
6688:            	Insert a single row with single or multiple portions.
6689:            	Update every other field with a long col
6690:            	The update each column back to a null
6691:
6692:            	@exception T_Fail Unexpected behaviour from the API
6693:            	@exception StandardException Unexpected exception from the implementation
6694:             */
6695:            protected void P706(long segment, boolean multiPortion)
6696:                    throws StandardException, T_Fail {
6697:
6698:                Transaction t = t_util.t_startTransaction();
6699:
6700:                long cid = t_util.t_addContainer(t, segment, 4096);
6701:
6702:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6703:                        true);
6704:                Page page = t_util.t_getPage(c,
6705:                        ContainerHandle.FIRST_PAGE_NUMBER);
6706:                t_util.t_checkEmptyPage(page);
6707:
6708:                // row has 15 cols, each with 200 (ish) bytes (100 null chars)
6709:                // thus we would expect at least 3 pages
6710:                T_RawStoreRow row = new T_RawStoreRow(15);
6711:                for (int i = 0; i < 15; i++) {
6712:
6713:                    row.setColumn(i, multiPortion ? 100 : 10, "XX" + i + "YY");
6714:                }
6715:
6716:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6717:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6718:                t_util.t_checkFetch(page, rh, row);
6719:
6720:                page.unlatch();
6721:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6722:
6723:                // update  every other column to be a long column
6724:                for (int i = 0; i < 15; i++) {
6725:
6726:                    if ((i % 2) == 0) {
6727:                        continue;
6728:                    }
6729:
6730:                    REPORT("P706 : multiPortion " + multiPortion + " - col "
6731:                            + i);
6732:
6733:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6734:                    colList.set(i);
6735:
6736:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6737:                    rowU.setColumn(i, 3000, "WW" + i + "UU"); // longer than 4096 page length
6738:
6739:                    page.update(rh, rowU.getRow(), colList);
6740:                    page.unlatch();
6741:
6742:                    row.setColumn(i, 3000, "WW" + i + "UU");
6743:
6744:                    page = t_util.t_getPage(c,
6745:                            ContainerHandle.FIRST_PAGE_NUMBER);
6746:
6747:                    t_util.t_checkFetch(page, rh, row);
6748:                }
6749:
6750:                t_util.t_commit(t);
6751:
6752:                // update  every column to a null
6753:                c = t_util.t_openContainer(t, segment, cid, true);
6754:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6755:                for (int i = 0; i < 15; i++) {
6756:
6757:                    REPORT("P706 : update to null " + multiPortion + " - col "
6758:                            + i);
6759:
6760:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6761:                    colList.set(i);
6762:
6763:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6764:                    rowU.setColumn(i, (String) null);
6765:
6766:                    page.update(rh, rowU.getRow(), colList);
6767:                    page.unlatch();
6768:
6769:                    row.setColumn(i, (String) null);
6770:
6771:                    page = t_util.t_getPage(c,
6772:                            ContainerHandle.FIRST_PAGE_NUMBER);
6773:
6774:                    t_util.t_checkFetch(page, rh, row);
6775:                }
6776:                page.unlatch();
6777:
6778:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6779:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6780:                }
6781:
6782:                t_util.t_commit(t);
6783:
6784:                t.close();
6785:
6786:                PASS("P706: multiPortion " + multiPortion + " segment = "
6787:                        + segment);
6788:            }
6789:
6790:            /**
6791:            	Insert a single record that has several chunks
6792:            	and every other column is a long column
6793:            	@exception T_Fail Unexpected behaviour from the API
6794:            	@exception StandardException Unexpected exception from the implementation
6795:             */
6796:            protected void P707(long segment) throws StandardException, T_Fail {
6797:
6798:                Transaction t = t_util.t_startTransaction();
6799:
6800:                long cid = t_util.t_addContainer(t, segment, 4096);
6801:
6802:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6803:                        true);
6804:                Page page = t_util.t_getPage(c,
6805:                        ContainerHandle.FIRST_PAGE_NUMBER);
6806:                t_util.t_checkEmptyPage(page);
6807:
6808:                T_RawStoreRow row = new T_RawStoreRow(20);
6809:                for (int i = 0; i < 20; i++) {
6810:                    if ((i % 2) == 0)
6811:                        row.setColumn(i, 200, "XX" + i + "YY"); // big but first within a page
6812:                    else
6813:                        row.setColumn(i, 4000, "XX" + i + "YY"); // long column
6814:                }
6815:
6816:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6817:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6818:                t_util.t_checkFetch(page, rh, row);
6819:
6820:                page.unlatch();
6821:
6822:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6823:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6824:                }
6825:
6826:                t_util.t_commit(t);
6827:
6828:                t.close();
6829:
6830:                PASS("P707: segment = " + segment);
6831:            }
6832:
6833:            /**
6834:            	Insert a single row with single or multiple portions.
6835:            	Update every other field with a long col
6836:            	rollback.
6837:            	The update each column back to a null & rollback
6838:
6839:            	@exception T_Fail Unexpected behaviour from the API
6840:            	@exception StandardException Unexpected exception from the implementation
6841:             */
6842:            protected void P708(long segment, boolean multiPortion)
6843:                    throws StandardException, T_Fail {
6844:
6845:                Transaction t = t_util.t_startTransaction();
6846:
6847:                long cid = t_util.t_addContainer(t, segment, 4096);
6848:
6849:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
6850:                        true);
6851:                Page page = t_util.t_getPage(c,
6852:                        ContainerHandle.FIRST_PAGE_NUMBER);
6853:                t_util.t_checkEmptyPage(page);
6854:
6855:                // row has 15 cols, each with 200 (ish) bytes (100 null chars)
6856:                // thus we would expect at least 3 pages
6857:                T_RawStoreRow row = new T_RawStoreRow(15);
6858:                for (int i = 0; i < 15; i++) {
6859:
6860:                    row.setColumn(i, multiPortion ? 100 : 10, "XX" + i + "YY");
6861:                }
6862:
6863:                RecordHandle rh = t_util.t_insertAtSlot(page, 0, row,
6864:                        (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
6865:                t_util.t_checkFetch(page, rh, row);
6866:
6867:                page.unlatch();
6868:                t_util.t_commit(t);
6869:                c = t_util.t_openContainer(t, segment, cid, true);
6870:
6871:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6872:
6873:                // update  every other column to be a long column
6874:                for (int i = 0; i < 15; i++) {
6875:
6876:                    if ((i % 2) == 0) {
6877:                        continue;
6878:                    }
6879:
6880:                    REPORT("P708 : multiPortion " + multiPortion + " - col "
6881:                            + i);
6882:
6883:                    FormatableBitSet colList = new FormatableBitSet(i + 1);
6884:                    colList.set(i);
6885:
6886:                    T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
6887:                    rowU.setColumn(i, 3000, "WW" + i + "UU"); // longer than 4096 page length
6888:
6889:                    page.update(rh, rowU.getRow(), colList);
6890:                }
6891:
6892:                t_util.t_abort(t);
6893:
6894:                c = t_util.t_openContainer(t, segment, cid, false);
6895:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6896:                t_util.t_checkFetch(page, rh, row);
6897:                page.unlatch();
6898:
6899:                if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
6900:                    t_util.t_dropContainer(t, segment, cid); // cleanup
6901:                }
6902:
6903:                t_util.t_commit(t);
6904:
6905:                t.close();
6906:
6907:                PASS("P708: multiPortion " + multiPortion + " segment = "
6908:                        + segment);
6909:            }
6910:
6911:            /**
6912:              P709:
6913:              this test exercises purgeAtSlot , rollsback and purges the slot again,
6914:              to make sure not logging the data does not have any impact on repurging
6915:              the rollbacked purges.
6916:              @exception T_Fail Unexpected behaviour from the API
6917:              @exception StandardException Unexpected exception from the implementation
6918:             */
6919:            protected void P709() throws StandardException, T_Fail {
6920:                logDataForPurges = false;
6921:                Transaction t = t_util.t_startTransaction();
6922:                long cid = t_util.t_addContainer(t, 0);
6923:                t_util.t_commit(t);
6924:
6925:                ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
6926:                Page page = t_util.t_getPage(c,
6927:                        ContainerHandle.FIRST_PAGE_NUMBER);
6928:
6929:                // REPORT("insert 5 records");
6930:                T_RawStoreRow row0 = new T_RawStoreRow(REC_001);
6931:                T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
6932:                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
6933:                T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
6934:                T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
6935:
6936:                RecordHandle r0, r1, r2, r3, r4;
6937:                r0 = t_util.t_insertAtSlot(page, 0, row0);
6938:                r1 = t_util.t_insertAtSlot(page, 1, row1);
6939:                r2 = t_util.t_insertAtSlot(page, 2, row2);
6940:                r3 = t_util.t_insertAtSlot(page, 3, row3);
6941:                r4 = t_util.t_insertAtSlot(page, 4, row4);
6942:
6943:                if (r3 != null)
6944:                    page.deleteAtSlot(3, true, (LogicalUndo) null);
6945:
6946:                // REPORT("commit it");
6947:                t_util.t_commit(t);
6948:
6949:                c = t_util.t_openContainer(t, 0, cid, true);
6950:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
6951:
6952:                try {
6953:                    page.purgeAtSlot(-1, 1, logDataForPurges);
6954:                    throw T_Fail
6955:                            .testFailMsg("negative slot number did not cause an exception");
6956:                } catch (StandardException se) {
6957:                } // expected
6958:
6959:                try {
6960:                    page.purgeAtSlot(4, 4, logDataForPurges);
6961:                    throw T_Fail
6962:                            .testFailMsg("purging more rows than is on page did not cause an exception");
6963:                } catch (StandardException se) {
6964:                } // expected
6965:
6966:                // if not all the rows are there, do minimal test
6967:                if (r4 == null) {
6968:                    int rcount = page.recordCount();
6969:                    page.purgeAtSlot(0, 1, logDataForPurges);
6970:                    if (page.recordCount() != rcount - 1)
6971:                        T_Fail.testFailMsg("failed to purge a record, expect "
6972:                                + (rcount - 1) + " got " + page.recordCount());
6973:
6974:                    if (testRollback) {
6975:                        t_util.t_abort(t);
6976:
6977:                        c = t_util.t_openContainer(t, 0, cid, true);
6978:                        page = t_util.t_getPage(c,
6979:                                ContainerHandle.FIRST_PAGE_NUMBER);
6980:                        if (logDataForPurges)
6981:                            t_util.t_checkFetchBySlot(page, 0, REC_001, false,
6982:                                    true);
6983:                        else
6984:                            t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
6985:                                    true);
6986:                        if (page.recordCount() != rcount)
6987:                            T_Fail
6988:                                    .testFailMsg("failed to rollback purge, expect "
6989:                                            + rcount
6990:                                            + " got "
6991:                                            + page.recordCount());
6992:                    } else {
6993:                        t_util.t_commit(t);
6994:                    }
6995:                    PASS("mimimal purging P709");
6996:                    return;
6997:                }
6998:
6999:                // REPORT("purge 2 records from middle");
7000:                page.purgeAtSlot(1, 2, logDataForPurges);
7001:                t_util.t_checkFetchBySlot(page, 0, REC_001, false, true);
7002:                t_util.t_checkFetchBySlot(page, 1, REC_003, true, true);
7003:                t_util.t_checkFetchBySlot(page, 2, REC_004, false, true);
7004:
7005:                if (page.recordCount() != 3)
7006:                    T_Fail
7007:                            .testFailMsg("page expect to have 3 records, recordCount() = "
7008:                                    + page.recordCount());
7009:
7010:                // REPORT("purge all records from the page");
7011:                page.purgeAtSlot(0, 3, logDataForPurges);
7012:                if (page.recordCount() != 0)
7013:                    T_Fail
7014:                            .testFailMsg("page expect to have 0 records, recordCount() = "
7015:                                    + page.recordCount());
7016:
7017:                if (testRollback) {
7018:
7019:                    REPORT("testing rollback");
7020:                    t_util.t_abort(t);
7021:
7022:                    c = t_util.t_openContainer(t, 0, cid, true);
7023:                    page = t_util.t_getPage(c,
7024:                            ContainerHandle.FIRST_PAGE_NUMBER);
7025:
7026:                    if (logDataForPurges) {
7027:                        t_util
7028:                                .t_checkFetchBySlot(page, 0, REC_001, false,
7029:                                        true);
7030:                        t_util
7031:                                .t_checkFetchBySlot(page, 1, REC_001, false,
7032:                                        true);
7033:                        t_util
7034:                                .t_checkFetchBySlot(page, 2, REC_002, false,
7035:                                        true);
7036:                        t_util.t_checkFetchBySlot(page, 3, REC_003, true, true);
7037:                        t_util
7038:                                .t_checkFetchBySlot(page, 4, REC_004, false,
7039:                                        true);
7040:                    } else {
7041:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
7042:                                true);
7043:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
7044:                                true);
7045:                        t_util.t_checkFetchBySlot(page, 2, REC_NULL, false,
7046:                                true);
7047:                        t_util
7048:                                .t_checkFetchBySlot(page, 3, REC_NULL, true,
7049:                                        true);
7050:                        t_util.t_checkFetchBySlot(page, 4, REC_NULL, false,
7051:                                true);
7052:                    }
7053:
7054:                    if (page.recordCount() != 5)
7055:                        T_Fail
7056:                                .testFailMsg("page expect to have 5 records, recordCount() = "
7057:                                        + page.recordCount());
7058:
7059:                    // REPORT("purge 3 records from the end");
7060:                    page.purgeAtSlot(2, 3, logDataForPurges);
7061:                    if (logDataForPurges) {
7062:                        t_util
7063:                                .t_checkFetchBySlot(page, 0, REC_001, false,
7064:                                        true);
7065:                        t_util
7066:                                .t_checkFetchBySlot(page, 1, REC_001, false,
7067:                                        true);
7068:                    } else {
7069:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
7070:                                true);
7071:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
7072:                                true);
7073:                    }
7074:                    if (page.recordCount() != 2)
7075:                        T_Fail
7076:                                .testFailMsg("page expect to have 2 records, recordCount() = "
7077:                                        + page.recordCount());
7078:
7079:                    // REPORT("rollback");
7080:                    t_util.t_abort(t);
7081:
7082:                    c = t_util.t_openContainer(t, 0, cid, true);
7083:                    page = t_util.t_getPage(c,
7084:                            ContainerHandle.FIRST_PAGE_NUMBER);
7085:                    if (logDataForPurges) {
7086:                        t_util
7087:                                .t_checkFetchBySlot(page, 0, REC_001, false,
7088:                                        true);
7089:                        t_util
7090:                                .t_checkFetchBySlot(page, 1, REC_001, false,
7091:                                        true);
7092:                        t_util
7093:                                .t_checkFetchBySlot(page, 2, REC_002, false,
7094:                                        true);
7095:                        t_util.t_checkFetchBySlot(page, 3, REC_003, true, true);
7096:                        t_util
7097:                                .t_checkFetchBySlot(page, 4, REC_004, false,
7098:                                        true);
7099:                    } else {
7100:                        t_util.t_checkFetchBySlot(page, 0, REC_NULL, false,
7101:                                true);
7102:                        t_util.t_checkFetchBySlot(page, 1, REC_NULL, false,
7103:                                true);
7104:                        t_util.t_checkFetchBySlot(page, 2, REC_NULL, false,
7105:                                true);
7106:                        t_util
7107:                                .t_checkFetchBySlot(page, 3, REC_NULL, true,
7108:                                        true);
7109:                        t_util.t_checkFetchBySlot(page, 4, REC_NULL, false,
7110:                                true);
7111:                    }
7112:
7113:                    if (page.recordCount() != 5)
7114:                        T_Fail
7115:                                .testFailMsg("page expect to have 5 records, recordCount() = "
7116:                                        + page.recordCount());
7117:
7118:                    // REPORT("make sure delete record is reconstituted as such");
7119:                    if (page.isDeletedAtSlot(1))
7120:                        T_Fail
7121:                                .testFailMsg("rolled back purged undeleted record cause record to be deleted");
7122:                    if (!page.isDeletedAtSlot(3))
7123:                        T_Fail
7124:                                .testFailMsg("rolled back purged deleted record cause record to be undeleted");
7125:                }
7126:
7127:                REPORT("purging again the purges rolled back earlier");
7128:                //purge again and this time do commit , instead of rollback.
7129:                // REPORT("purge 2 records from middle");
7130:                page.purgeAtSlot(1, 2, logDataForPurges);
7131:                t_util.t_checkFetchBySlot(page, 0, REC_NULL, false, true);
7132:                t_util.t_checkFetchBySlot(page, 1, REC_NULL, true, true);
7133:                t_util.t_checkFetchBySlot(page, 2, REC_NULL, false, true);
7134:
7135:                if (page.recordCount() != 3)
7136:                    T_Fail
7137:                            .testFailMsg("page expect to have 3 records, recordCount() = "
7138:                                    + page.recordCount());
7139:
7140:                // REPORT("purge all records from the page");
7141:                page.purgeAtSlot(0, 3, logDataForPurges);
7142:                if (page.recordCount() != 0)
7143:                    T_Fail
7144:                            .testFailMsg("page expect to have 0 records, recordCount() = "
7145:                                    + page.recordCount());
7146:
7147:                t_util.t_abort(t);
7148:
7149:                c = t_util.t_openContainer(t, 0, cid, true);
7150:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
7151:
7152:                if (page.recordCount() != 5)
7153:                    T_Fail
7154:                            .testFailMsg("page expect to have 5 records, recordCount() = "
7155:                                    + page.recordCount());
7156:
7157:                // REPORT("purge 3 records from the end");
7158:                page.purgeAtSlot(2, 3, logDataForPurges);
7159:                t_util.t_checkFetchBySlot(page, 0, REC_NULL, false, true);
7160:                t_util.t_checkFetchBySlot(page, 1, REC_NULL, false, true);
7161:                if (page.recordCount() != 2)
7162:                    T_Fail
7163:                            .testFailMsg("page expect to have 2 records, recordCount() = "
7164:                                    + page.recordCount());
7165:
7166:                // REPORT("commit");
7167:                t_util.t_commit(t);
7168:
7169:                c = t_util.t_openContainer(t, 0, cid, true);
7170:                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
7171:                t_util.t_checkFetchBySlot(page, 0, REC_NULL, false, true);
7172:                t_util.t_checkFetchBySlot(page, 1, REC_NULL, false, true);
7173:
7174:                if (page.recordCount() != 2)
7175:                    T_Fail
7176:                            .testFailMsg("page expect to have 2 records, recordCount() = "
7177:                                    + page.recordCount());
7178:
7179:                PASS("P709");
7180:
7181:                t_util.t_dropContainer(t, 0, cid); // cleanup
7182:                t_util.t_commit(t);
7183:                t.close();
7184:            }
7185:
7186:            /**
7187:            	Test space reclaimation - purging of a long rows with a rollback and
7188:                purging againg with no data logging for purges
7189:            	@exception T_Fail Unexpected behaviour from the API
7190:            	@exception StandardException Unexpected exception from the implementation
7191:             */
7192:            protected void P710() throws StandardException, T_Fail {
7193:                long segment = 0;
7194:                Transaction t = t_util.t_startTransaction();
7195:                long cid = t_util.t_addContainer(t, segment, 4096);
7196:
7197:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
7198:                        true);
7199:                Page page = t_util.t_getPage(c,
7200:                        ContainerHandle.FIRST_PAGE_NUMBER);
7201:                try {
7202:                    t_util.t_checkEmptyPage(page);
7203:
7204:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
7205:
7206:                    // insert a row with 100 columns from 200 to 400 bytes each and make it
7207:                    // sprawl across many pages.
7208:                    T_RawStoreRow r1 = new T_RawStoreRow(100);
7209:                    for (int i = 0; i < 100; i++)
7210:                        r1.setColumn(i, 100 + i, REC_001);
7211:
7212:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
7213:                            (byte) insertFlag);
7214:                    t_util.t_checkFetch(page, rh1, r1);
7215:
7216:                    Page nextPage = t_util.t_addPage(c);
7217:                    long nextPageNumber = nextPage.getPageNumber();
7218:                    // deallocate it
7219:                    t_util.t_removePage(c, nextPage);
7220:
7221:                    REPORT("P710 - Nextpage is " + nextPageNumber);
7222:                    page.unlatch();
7223:                    page = null;
7224:                    t_util.t_commit(t);
7225:
7226:                    // See what the next page is.
7227:                    c = t_util.t_openContainer(t, segment, cid, true);
7228:
7229:                    // Now purge that first row.
7230:                    page = t_util.t_getPage(c,
7231:                            ContainerHandle.FIRST_PAGE_NUMBER);
7232:
7233:                    t_util.t_checkRecordCount(page, 1, 1);
7234:                    page.purgeAtSlot(0, 1, logDataForPurges);
7235:
7236:                    t_util.t_checkEmptyPage(page);
7237:                    page.unlatch();
7238:                    page = null;
7239:                    t_util.t_commit(t);
7240:
7241:                    // give some time for post commit to finish
7242:                    t_util.t_wait(10); // wait 10 milliseconds.
7243:
7244:                    // reinsert r1, it should use no extra page than last time.
7245:                    c = t_util.t_openContainer(t, segment, cid, true);
7246:                    page = t_util.t_getPage(c,
7247:                            ContainerHandle.FIRST_PAGE_NUMBER);
7248:
7249:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r1,
7250:                            (byte) insertFlag);
7251:                    t_util.t_checkFetch(page, rh2, r1);
7252:                    page.unlatch();
7253:                    page = null;
7254:
7255:                    // now verify that it used up no more page than last time
7256:                    nextPage = t_util.t_addPage(c);
7257:                    long checkNextPageNumber = nextPage.getPageNumber();
7258:                    nextPage.unlatch();
7259:
7260:                    if (nextPageNumber != checkNextPageNumber)
7261:                        throw T_Fail
7262:                                .testFailMsg("fail to reuse row pieces expect next page="
7263:                                        + nextPageNumber
7264:                                        + " but got "
7265:                                        + checkNextPageNumber);
7266:
7267:                    t_util.t_commit(t);
7268:
7269:                    // Purge them and roll them back via savepoint.  These should not
7270:                    // be reclaimed.
7271:                    c = t_util.t_openContainer(t, segment, cid, true);
7272:                    t.setSavePoint(SP1, null);
7273:                    page = t_util.t_getPage(c,
7274:                            ContainerHandle.FIRST_PAGE_NUMBER);
7275:                    t_util.t_checkRecordCount(page, 1, 1);
7276:                    page.purgeAtSlot(0, 1, logDataForPurges);
7277:                    page.unlatch();
7278:                    page = null;
7279:
7280:                    // make sure we cannot get our hands on a page that is freed up by
7281:                    // the purge
7282:                    Page testPage = t_util.t_addPage(c);
7283:                    T_RawStoreRow testRow = new T_RawStoreRow(REC_001);
7284:                    t_util.t_insert(testPage, testRow);
7285:                    testPage.unlatch();
7286:
7287:                    t.rollbackToSavePoint(SP1, null);
7288:
7289:                    testPage = t_util.t_addPage(c);
7290:                    t_util.t_insert(testPage, testRow);
7291:                    testPage.unlatch();
7292:
7293:                    t_util.t_commit(t);
7294:                    t_util.t_wait(10);
7295:
7296:                    c = t_util.t_openContainer(t, segment, cid, true);
7297:
7298:                    testPage = t_util.t_addPage(c);
7299:                    t_util.t_insert(testPage, testRow);
7300:                    testPage.unlatch();
7301:
7302:                    page = t_util.t_getPage(c,
7303:                            ContainerHandle.FIRST_PAGE_NUMBER);
7304:                    t_util.t_checkRecordCount(page, 1, 1);
7305:
7306:                    //repurge again.
7307:                    page.purgeAtSlot(0, 1, logDataForPurges);
7308:                    t_util.t_abort(t);
7309:                    //				t_util.t_checkFetch(page, rh2, r1);			
7310:                    page = null;
7311:                    c = t_util.t_openContainer(t, segment, cid, true);
7312:                    page = t_util.t_getPage(c,
7313:                            ContainerHandle.FIRST_PAGE_NUMBER);
7314:                    t_util.t_checkRecordCount(page, 1, 1);
7315:                    //repurge again and do commit
7316:                    page.purgeAtSlot(0, 1, logDataForPurges);
7317:                    page.unlatch();
7318:                    page = null;
7319:                    t_util.t_commit(t);
7320:                    c = t_util.t_openContainer(t, segment, cid, true);
7321:                    page = t_util.t_getPage(c,
7322:                            ContainerHandle.FIRST_PAGE_NUMBER);
7323:                    t_util.t_checkRecordCount(page, 0, 0);
7324:                    page.unlatch();
7325:                    page = null;
7326:                    t_util.t_dropContainer(t, segment, cid); // cleanup
7327:
7328:                } finally {
7329:                    if (page != null)
7330:                        page.unlatch();
7331:                    t_util.t_commit(t);
7332:                    t.close();
7333:                }
7334:
7335:                PASS("P710");
7336:            }
7337:
7338:            /**
7339:            	Test space reclaimation - purging of a row with serveral long columns
7340:                rollback and repurge them again.
7341:
7342:            	@exception T_Fail Unexpected behaviour from the API
7343:            	@exception StandardException Unexpected exception from the implementation
7344:             */
7345:            protected void P711() throws StandardException, T_Fail {
7346:
7347:                long segment = 0;
7348:                Transaction t = t_util.t_startTransaction();
7349:                long cid = t_util.t_addContainer(t, segment, 4096);
7350:
7351:                ContainerHandle c = t_util.t_openContainer(t, segment, cid,
7352:                        true);
7353:                Page page = t_util.t_getPage(c,
7354:                        ContainerHandle.FIRST_PAGE_NUMBER);
7355:                try {
7356:                    t_util.t_checkEmptyPage(page);
7357:
7358:                    int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
7359:                    T_RawStoreRow r1 = new T_RawStoreRow(1);
7360:                    // insert a long column
7361:                    r1.setColumn(0, 5000, REC_001);
7362:                    RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1,
7363:                            (byte) insertFlag);
7364:                    t_util.t_checkFetch(page, rh1, r1);
7365:
7366:                    // insert a 6 column row, every other column is long
7367:                    T_RawStoreRow r2 = new T_RawStoreRow(6);
7368:                    r2.setColumn(0, 600, REC_001); // this takes ~1200 bytes
7369:                    r2.setColumn(1, 5000, REC_002); // this takes ~10000 bytes
7370:                    r2.setColumn(2, 600, REC_001);
7371:                    r2.setColumn(3, 5000, REC_002);
7372:                    r2.setColumn(4, 600, REC_001);
7373:                    r2.setColumn(5, 5000, REC_002);
7374:                    RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r2,
7375:                            (byte) insertFlag);
7376:                    t_util.t_checkFetch(page, rh2, r2);
7377:
7378:                    // insert a long column - this should fail
7379:                    RecordHandle rh3 = t_util.t_insertAtSlot(page, 0, r1,
7380:                            (byte) insertFlag);
7381:                    if (rh3 != null) {
7382:                        throw T_Fail
7383:                                .testFailMsg("expect the 3rd row to not fit on page");
7384:                    }
7385:                    page.unlatch();
7386:                    page = null;
7387:
7388:                    Page nextPage = t_util.t_addPage(c);
7389:                    long nextPageNumber = nextPage.getPageNumber();
7390:                    // deallocate it
7391:                    t_util.t_removePage(c, nextPage);
7392:
7393:                    REPORT("P711 - Nextpage is " + nextPageNumber);
7394:
7395:                    t_util.t_commit(t);
7396:
7397:                    // now purge them
7398:                    c = t_util.t_openContainer(t, segment, cid, true);
7399:                    page = t_util.t_getPage(c,
7400:                            ContainerHandle.FIRST_PAGE_NUMBER);
7401:
7402:                    t_util.t_checkRecordCount(page, 2, 2);
7403:                    page.purgeAtSlot(0, 2, logDataForPurges);
7404:                    t_util.t_checkEmptyPage(page);
7405:                    page.unlatch();
7406:                    page = null;
7407:
7408:                    t_util.t_abort(t);
7409:
7410:                    // give some time for post commit to finish
7411:                    t_util.t_wait(10); // wait 10 milliseconds.
7412:
7413:                    // Purge them again and roll them back via savepoint.  These should not
7414:                    // be reclaimed.
7415:                    c = t_util.t_openContainer(t, segment, cid, true);
7416:
7417:                    t.setSavePoint(SP1, null);
7418:                    page = t_util.t_getPage(c,
7419:                            ContainerHandle.FIRST_PAGE_NUMBER);
7420:
7421:                    t_util.t_checkRecordCount(page, 2, 2);
7422:                    page.purgeAtSlot(0, 2, logDataForPurges);
7423:                    t_util.t_checkEmptyPage(page);
7424:
7425:                    page.unlatch();
7426:                    page = null;
7427:
7428:                    // make sure we cannot get our hands on a page that is freed up by
7429:                    // the purge
7430:                    Page testPage = t_util.t_addPage(c);
7431:                    T_RawStoreRow testRow = new T_RawStoreRow(REC_001);
7432:                    t_util.t_insert(testPage, testRow);
7433:                    testPage.unlatch();
7434:
7435:                    t.rollbackToSavePoint(SP1, null);
7436:
7437:                    testPage = t_util.t_addPage(c);
7438:                    t_util.t_insert(testPage, testRow);
7439:                    testPage.unlatch();
7440:
7441:                    t_util.t_commit(t);
7442:
7443:                    // give some time for post commit to finish
7444:                    t_util.t_wait(10);
7445:
7446:                    // check to make sure post commit did not reclaim those rows.
7447:                    c = t_util.t_openContainer(t, segment, cid, true);
7448:
7449:                    testPage = t_util.t_addPage(c);
7450:                    t_util.t_insert(testPage, testRow);
7451:                    testPage.unlatch();
7452:
7453:                    page = t_util.t_getPage(c,
7454:                            ContainerHandle.FIRST_PAGE_NUMBER);
7455:
7456:                    t_util.t_checkRecordCount(page, 2, 2);
7457:                    t_util.t_checkFetch(page, rh1, r1);
7458:
7459:                    // During purges when data is not logged when slots are purged
7460:                    // they become null on rollback and some cases like long columns
7461:                    // we remove the wholepage on rollback we get the data back.
7462:                    T_RawStoreRow r2_wnl = new T_RawStoreRow(6);
7463:                    r2_wnl.setColumn(0, 4, REC_NULL);
7464:                    r2_wnl.setColumn(1, 5000, REC_002);
7465:                    r2_wnl.setColumn(2, 4, REC_NULL);
7466:                    r2_wnl.setColumn(3, 5000, REC_002);
7467:                    r2_wnl.setColumn(4, 4, REC_NULL);
7468:                    r2_wnl.setColumn(5, 5000, REC_002);
7469:                    t_util.t_checkFetch(page, rh2, r2_wnl);
7470:
7471:                    page.unlatch();
7472:                    page = null;
7473:
7474:                    t_util.t_dropContainer(t, segment, cid); // cleanup
7475:
7476:                } finally {
7477:                    if (page != null)
7478:                        page.unlatch();
7479:                    t_util.t_commit(t);
7480:                    t.close();
7481:                }
7482:
7483:                PASS("P711");
7484:
7485:            }
7486:
7487:            // test writing out large log records
7488:            protected void L001() throws StandardException, T_Fail {
7489:                Transaction t = t_util.t_startTransaction();
7490:
7491:                // if runing multi threaded, only have 1 thread log these large record
7492:                // or we may get out of memeory error
7493:                int loop = 10;
7494:                int logSize = (threadNumber == 0) ? 50000 : 50;
7495:
7496:                try {
7497:                    for (int i = 0; i < loop; i++) {
7498:                        Loggable l = new T_Undoable(t.getGlobalId(), -1, -1,
7499:                                T_Undoable.REMOVE_NONE, 0, //LWM ignored
7500:                                true, 10, false, i * logSize, false);
7501:                        t.logAndDo(l);
7502:                    }
7503:                    t.commit();
7504:                    t.close();
7505:                    t = null;
7506:
7507:                    t = t_util.t_startTransaction();
7508:                    for (int i = 0; i < loop; i++) {
7509:                        Loggable l = new T_Undoable(t.getGlobalId(), -1, -1,
7510:                                T_Undoable.REMOVE_NONE, 0, //LWM ignored
7511:                                true, 10, false, i * logSize, false);
7512:
7513:                        t.logAndDo(l);
7514:                    }
7515:
7516:                    PASS("L001");
7517:                } finally {
7518:                    t.commit();
7519:                    t.close();
7520:                }
7521:            }
7522:
7523:            /**
7524:            	Test checkpoint
7525:            	@exception T_Fail Unexpected behaviour from the API
7526:            	@exception StandardException Unexpected exception from the implementation
7527:             */
7528:            protected void CP001() throws StandardException, T_Fail {
7529:                if (!testRollback)
7530:                    return;
7531:
7532:                ContextManager previousCM = contextService
7533:                        .getCurrentContextManager();
7534:                Transaction longtran = null;
7535:
7536:                ContextManager cm1 = null;
7537:                Transaction t1 = null;
7538:
7539:                ContextManager cm2 = null;
7540:                Transaction t2 = null;
7541:
7542:                // ContextManager cpm = null; // reserved for the checkpoint transaction
7543:                try {
7544:
7545:                    T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
7546:                    T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
7547:                    T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
7548:                    T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
7549:                    T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
7550:
7551:                    // start a long running transaction that spans multiple checkpoints
7552:                    // make sure it can be rolled back a the end
7553:                    longtran = t_util.t_startTransaction();
7554:
7555:                    long cid = t_util.t_addContainer(longtran, 0);
7556:                    ContainerHandle c = t_util.t_openContainer(longtran, 0,
7557:                            cid, true);
7558:                    RecordHandle r1 = t_util.t_insert(c, row1);
7559:                    RecordHandle r2 = t_util.t_insert(c, row2);
7560:                    t_util.t_commit(longtran);
7561:
7562:                    c = t_util.t_openContainer(longtran, 0, cid, true);
7563:                    Page p2 = t_util.t_getPage(c, r2.getPageNumber());
7564:                    p2.update(r2, row5.getRow(), (FormatableBitSet) null);
7565:                    p2.unlatch();
7566:
7567:                    // a bunch of short running transactions that criss cross the
7568:                    // checkpoints 
7569:
7570:                    cm1 = contextService.newContextManager();
7571:                    contextService.setCurrentContextManager(cm1);
7572:                    t1 = t_util.t_startTransaction();
7573:
7574:                    long cid1 = t_util.t_addContainer(t1, 0);
7575:                    ContainerHandle c1 = t_util.t_openContainer(t1, 0, cid1,
7576:                            true);
7577:                    RecordHandle r3 = t_util.t_insert(c1, row3);
7578:                    RecordHandle r4 = t_util.t_insert(c1, row4);
7579:                    contextService.resetCurrentContextManager(cm1);
7580:
7581:                    cm2 = contextService.newContextManager();
7582:                    contextService.setCurrentContextManager(cm2);
7583:                    t2 = t_util.t_startTransaction();
7584:
7585:                    long cid2 = t_util.t_addContainer(t2, 0);
7586:                    ContainerHandle c2 = t_util.t_openContainer(t2, 0, cid2,
7587:                            true);
7588:                    RecordHandle r5 = t_util.t_insert(c2, row1);
7589:                    t_util.t_commit(t2);
7590:                    c2 = t_util.t_openContainer(t2, 0, cid2, true);
7591:                    Page p5 = t_util.t_getPage(c2, r5.getPageNumber());
7592:                    p5.update(r5, row5.getRow(), (FormatableBitSet) null);
7593:                    p5.unlatch();
7594:
7595:                    //		cpm = contextService.newContextManager();
7596:                    //		contextService.setCurrentContextManager(cpm);
7597:                    factory.checkpoint();
7598:                    contextService.resetCurrentContextManager(cm2);
7599:
7600:                    // make sure checkpoint did not destroy any data
7601:                    contextService.setCurrentContextManager(previousCM);
7602:                    t_util.t_checkFetch(c, r1, REC_001);
7603:                    t_util.t_checkFetch(c, r2, REC_005);
7604:                    contextService.resetCurrentContextManager(previousCM);
7605:
7606:                    contextService.setCurrentContextManager(cm1);
7607:                    t_util.t_checkFetch(c1, r3, REC_003);
7608:                    t_util.t_checkFetch(c1, r4, REC_004);
7609:                    contextService.resetCurrentContextManager(cm1);
7610:
7611:                    contextService.setCurrentContextManager(cm2);
7612:                    t_util.t_checkFetch(c2, r5, REC_005);
7613:
7614:                    // two consecutive checkpoints
7615:                    //		contextService.setCurrentContextManager(cpm);
7616:                    factory.checkpoint();
7617:                    contextService.resetCurrentContextManager(cm2);
7618:
7619:                    // we can insert some more
7620:                    contextService.setCurrentContextManager(previousCM);
7621:                    Page page = t_util.t_addPage(c);
7622:                    RecordHandle r6 = t_util.t_insertAtSlot(page, 0, row1,
7623:                            Page.INSERT_UNDO_WITH_PURGE);
7624:                    page.unlatch();
7625:                    contextService.resetCurrentContextManager(previousCM);
7626:
7627:                    // commit/abort everything except the long running transaction
7628:                    contextService.setCurrentContextManager(cm1);
7629:                    t_util.t_commit(t1);
7630:                    contextService.resetCurrentContextManager(cm1);
7631:
7632:                    contextService.setCurrentContextManager(cm2);
7633:                    t_util.t_abort(t2);
7634:                    contextService.resetCurrentContextManager(cm2);
7635:
7636:                    contextService.setCurrentContextManager(previousCM);
7637:                    t_util.t_checkFetch(c, r1, REC_001);
7638:                    t_util.t_checkFetch(c, r2, REC_005);
7639:                    t_util.t_checkFetch(c, r6, REC_001);
7640:                    contextService.resetCurrentContextManager(previousCM);
7641:
7642:                    contextService.setCurrentContextManager(cm1);
7643:                    c1 = t_util.t_openContainer(t1, 0, cid1, true);
7644:                    t_util.t_checkFetch(c1, r3, REC_003);
7645:                    t_util.t_checkFetch(c1, r4, REC_004);
7646:                    contextService.resetCurrentContextManager(cm1);
7647:
7648:                    contextService.setCurrentContextManager(cm2);
7649:                    c2 = t_util.t_openContainer(t2, 0, cid2, true);
7650:                    t_util.t_checkFetch(c2, r5, REC_001);
7651:
7652:                    // checkpoint again
7653:                    //		contextService.setCurrentContextManager(cpm);
7654:                    factory.checkpoint();
7655:                    contextService.resetCurrentContextManager(cm2);
7656:
7657:                    contextService.setCurrentContextManager(previousCM);
7658:                    t_util.t_abort(longtran);
7659:                    c = t_util.t_openContainer(longtran, 0, cid, true);
7660:                    t_util.t_checkFetch(c, r1, REC_001);
7661:                    t_util.t_checkFetch(c, r2, REC_002);
7662:
7663:                    Page p6 = t_util.t_getPage(c, r6.getPageNumber());
7664:                    t_util.t_checkEmptyPage(p6);
7665:                    p6.unlatch();
7666:
7667:                    t_util.t_dropContainer(longtran, 0, cid); // cleanup
7668:                    contextService.resetCurrentContextManager(previousCM);
7669:
7670:                    contextService.setCurrentContextManager(cm1);
7671:                    t_util.t_checkFetch(c1, r3, REC_003);
7672:                    t_util.t_checkFetch(c1, r4, REC_004);
7673:                    t_util.t_dropContainer(t1, 0, cid1);
7674:                    contextService.resetCurrentContextManager(cm1);
7675:
7676:                    contextService.setCurrentContextManager(cm2);
7677:                    t_util.t_checkFetch(c2, r5, REC_001);
7678:                    t_util.t_dropContainer(t2, 0, cid2);
7679:
7680:                    // checkpoint again
7681:                    //		contextService.setCurrentContextManager(cpm);
7682:                    factory.checkpoint();
7683:                    contextService.resetCurrentContextManager(cm2);
7684:
7685:                    PASS("CP001");
7686:
7687:                } catch (Throwable t) {
7688:                    t.printStackTrace(System.err);
7689:
7690:                    if (cm1 != null)
7691:                        cm1.cleanupOnError(t);
7692:                    if (cm2 != null)
7693:                        cm2.cleanupOnError(t);
7694:                    //		if (cpm != null)
7695:                    //			cpm.cleanupOnError(t);
7696:
7697:                } finally {
7698:
7699:                    if (t2 != null) {
7700:                        contextService.setCurrentContextManager(cm2);
7701:                        t_util.t_commit(t2);
7702:                        t2.close();
7703:                        contextService.resetCurrentContextManager(cm2);
7704:                    }
7705:
7706:                    if (t1 != null) {
7707:                        contextService.setCurrentContextManager(cm1);
7708:                        t_util.t_commit(t1);
7709:                        t1.close();
7710:                        contextService.resetCurrentContextManager(cm1);
7711:                    }
7712:
7713:                    if (longtran != null) {
7714:                        contextService.setCurrentContextManager(previousCM);
7715:                        t_util.t_commit(longtran);
7716:                        longtran.close();
7717:                        contextService.resetCurrentContextManager(previousCM);
7718:                    }
7719:
7720:                    //DJD contextService.setCurrentContextManager(previousCM);
7721:                }
7722:            }
7723:
7724:            /**
7725:            	TC001 - Test the drop on commit mode for temp containers.
7726:
7727:            	@exception T_Fail Unexpected behaviour from the API
7728:            	@exception StandardException Unexpected exception from the implementation
7729:
7730:             */
7731:            protected void TC001() throws T_Fail, StandardException {
7732:
7733:                Transaction t = t_util.t_startTransaction();
7734:
7735:                // open a container with drop on commit and see if it disappears
7736:                long cid = t_util.t_addContainer(t,
7737:                        ContainerHandle.TEMPORARY_SEGMENT);
7738:                t_util.setOpenMode(openMode
7739:                        | ContainerHandle.MODE_DROP_ON_COMMIT);
7740:                ContainerHandle c = t_util.t_openContainer(t,
7741:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7742:                t_util.t_commit(t);
7743:
7744:                ContainerKey id = new ContainerKey(
7745:                        ContainerHandle.TEMPORARY_SEGMENT, cid);
7746:                c = t.openContainer(id, ContainerHandle.MODE_READONLY);
7747:                if (c != null)
7748:                    throw T_Fail.testFailMsg("Temp Container should not exist");
7749:
7750:                // open a container with drop on commit, close it, check it is still there and see if it disappears on a commit
7751:                cid = t_util.t_addContainer(t,
7752:                        ContainerHandle.TEMPORARY_SEGMENT);
7753:                c = t_util.t_openContainer(t,
7754:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7755:                c.close();
7756:                c = t_util.t_openContainer(t,
7757:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7758:                c.close();
7759:                t_util.t_commit(t);
7760:
7761:                id = new ContainerKey(ContainerHandle.TEMPORARY_SEGMENT, cid);
7762:                c = t.openContainer(id, ContainerHandle.MODE_READONLY);
7763:                if (c != null)
7764:                    throw T_Fail.testFailMsg("Temp Container should not exist");
7765:
7766:                // open a container with drop on commit, abort the transaction, and see if it disappears
7767:                cid = t_util.t_addContainer(t,
7768:                        ContainerHandle.TEMPORARY_SEGMENT);
7769:                t_util.setOpenMode(openMode
7770:                        | ContainerHandle.MODE_DROP_ON_COMMIT);
7771:                c = t_util.t_openContainer(t,
7772:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7773:                t_util.t_abort(t);
7774:
7775:                id = new ContainerKey(ContainerHandle.TEMPORARY_SEGMENT, cid);
7776:                c = t.openContainer(id, ContainerHandle.MODE_READONLY);
7777:                if (c != null)
7778:                    throw T_Fail.testFailMsg("Temp Container should not exist");
7779:
7780:                t_util.t_commit(t);
7781:                t.close();
7782:                PASS("TC001");
7783:
7784:            }
7785:
7786:            // code to populate a temp table for some temp tests
7787:            private int[] populateTempTable(ContainerHandle c)
7788:                    throws StandardException, T_Fail {
7789:                Page page = t_util.t_getPage(c,
7790:                        ContainerHandle.FIRST_PAGE_NUMBER);
7791:                t_util.t_checkEmptyPage(page);
7792:
7793:                RecordHandle rh;
7794:                T_RawStoreRow row;
7795:                int[] recordCount = { 0, 0, 0 };
7796:
7797:                for (int i = 0; i < 3;) {
7798:
7799:                    for (;;) {
7800:
7801:                        row = new T_RawStoreRow(REC_001 + i + "X"
7802:                                + recordCount[i]);
7803:                        rh = t_util.t_insert(page, row);
7804:
7805:                        if (rh == null)
7806:                            break;
7807:
7808:                        recordCount[i]++;
7809:                        t_util.t_checkRecordCount(page, recordCount[i],
7810:                                recordCount[i]);
7811:                    }
7812:
7813:                    page.unlatch();
7814:                    page = null;
7815:
7816:                    if (++i < 3) {
7817:                        page = t_util.t_addPage(c);
7818:                        t_util.t_checkEmptyPage(page);
7819:                    }
7820:                }
7821:
7822:                return recordCount;
7823:            }
7824:
7825:            /**
7826:            	A clone of P002 for temporary containers.
7827:            	Insert rows on the first page until the page is full, then add a page
7828:            	and repeat the test (for a total of three pages with full rows).
7829:            	Fetch the rows back by handle methods.
7830:            	Commit or abort the transaction, and see if table is empty.
7831:            	Can be used as follows:
7832:
7833:            	<PRE>
7834:            	mode                   doCommit
7835:
7836:                TRUNCATE_ON_COMMIT     true       Ensure the table has only one empty page after commit
7837:            	TRUNCATE_ON_COMMIT     false      Ensure the table has only one empty page after abort
7838:            	0                      false      Ensure the table has only one empty page after abort
7839:
7840:            	</PRE>
7841:
7842:            	@exception T_Fail Unexpected behaviour from the API
7843:            	@exception StandardException Unexpected exception from the implementation
7844:             */
7845:            protected void TC002(int mode, boolean doCommit)
7846:                    throws StandardException, T_Fail {
7847:
7848:                Transaction t = t_util.t_startTransaction();
7849:
7850:                long cid = t_util.t_addContainer(t,
7851:                        ContainerHandle.TEMPORARY_SEGMENT);
7852:
7853:                REPORT("TC002 container id = " + cid);
7854:
7855:                t_util.setOpenMode(openMode | mode);
7856:
7857:                ContainerHandle c = t_util.t_openContainer(t,
7858:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7859:
7860:                int[] recordCount = populateTempTable(c);
7861:
7862:                for (int i = 0; i < recordCount.length; i++) {
7863:                    REPORT("RecordCount on page " + i + "=" + recordCount[i]);
7864:                }
7865:
7866:                // now check that we read the same number of records back
7867:                // using the handle interface
7868:
7869:                long pageNumber = ContainerHandle.FIRST_PAGE_NUMBER;
7870:                for (int i = 0; i < recordCount.length; i++, pageNumber++) {
7871:                    Page page = t_util.t_getPage(c, pageNumber);
7872:                    t_util.t_checkRecordCount(page, recordCount[i],
7873:                            recordCount[i]);
7874:                    RecordHandle rh = t_util.t_checkFetchFirst(page, REC_001
7875:                            + i + "X" + 0);
7876:                    for (int j = 1; j < recordCount[i]; j++)
7877:                        rh = t_util.t_checkFetchNext(page, rh, REC_001 + i
7878:                                + "X" + j);
7879:
7880:                    try {
7881:                        rh = page.fetchFromSlot(null, recordCount[i],
7882:                                new DataValueDescriptor[0],
7883:                                (FetchDescriptor) null, false);
7884:
7885:                        throw T_Fail
7886:                                .testFailMsg("reading more rows on page than were written");
7887:                    } catch (StandardException se) {
7888:                        // expected exception.
7889:                    }
7890:
7891:                    rh = t_util.t_checkFetchLast(page, REC_001 + i + "X"
7892:                            + (recordCount[i] - 1));
7893:                    for (int j = recordCount[i] - 2; j >= 0; j--)
7894:                        rh = t_util.t_checkFetchPrevious(page, rh, REC_001 + i
7895:                                + "X" + j);
7896:
7897:                    page.unlatch();
7898:                    page = null;
7899:                }
7900:
7901:                c.close();
7902:
7903:                // this commit or abort will truncate the table
7904:                if (doCommit)
7905:                    t_util.t_commit(t);
7906:                else
7907:                    t_util.t_abort(t);
7908:
7909:                t_util.setOpenMode(openMode);
7910:
7911:                c = t_util.t_openContainer(t,
7912:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7913:
7914:                Page page = t_util.t_getPage(c,
7915:                        ContainerHandle.FIRST_PAGE_NUMBER);
7916:
7917:                t_util.t_checkEmptyPage(page);
7918:                page.unlatch();
7919:                page = null;
7920:
7921:                page = c.getPage(ContainerHandle.FIRST_PAGE_NUMBER + 1);
7922:
7923:                if (page != null)
7924:                    throw T_Fail
7925:                            .testFailMsg("truncate of temp container did not succeed");
7926:
7927:                t_util.t_commit(t);
7928:
7929:                t.close();
7930:
7931:                PASS("TC002 " + mode + " " + doCommit);
7932:            }
7933:
7934:            /**
7935:
7936:            	Add a number of rows to a temp table opened in various modes,
7937:            	and drop it before commit/abort.
7938:
7939:            	@exception T_Fail Unexpected behaviour from the API
7940:            	@exception StandardException Unexpected exception from the implementation
7941:             */
7942:            protected void TC003(int mode, boolean doCommit)
7943:                    throws StandardException, T_Fail {
7944:
7945:                Transaction t = t_util.t_startTransaction();
7946:
7947:                long cid = t_util.t_addContainer(t,
7948:                        ContainerHandle.TEMPORARY_SEGMENT);
7949:
7950:                REPORT("TC003 container id = " + cid);
7951:
7952:                t_util.setOpenMode(openMode | mode);
7953:
7954:                ContainerHandle c = t_util.t_openContainer(t,
7955:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
7956:                populateTempTable(c);
7957:
7958:                // table is populated, drop it ...
7959:                t_util.t_dropContainer(t, ContainerHandle.TEMPORARY_SEGMENT,
7960:                        cid);
7961:                // table should have disappeared ...
7962:                ContainerKey id = new ContainerKey(
7963:                        ContainerHandle.TEMPORARY_SEGMENT, cid);
7964:                ContainerHandle ce = t.openContainer(id,
7965:                        ContainerHandle.MODE_READONLY);
7966:                if (ce != null)
7967:                    throw T_Fail
7968:                            .testFailMsg("Dropped Container should not open");
7969:
7970:                if (doCommit)
7971:                    t_util.t_commit(t);
7972:                else
7973:                    t_util.t_abort(t);
7974:
7975:                // table should have disappeared ...
7976:                ContainerHandle cd = t.openContainer(id,
7977:                        ContainerHandle.MODE_READONLY);
7978:                if (cd != null)
7979:                    throw T_Fail
7980:                            .testFailMsg("Dropped Container should not open");
7981:
7982:                t_util.t_commit(t);
7983:
7984:                t.close();
7985:
7986:                PASS("TC003 " + mode + " " + doCommit);
7987:            }
7988:
7989:            /**
7990:            	Open a temp table several times with different modes and ensure the
7991:            	correct behaviour (most severe open wins).
7992:
7993:            	@exception T_Fail Unexpected behaviour from the API
7994:            	@exception StandardException Unexpected exception from the implementation
7995:             */
7996:            protected void TC004all() throws StandardException, T_Fail {
7997:                int[] modes = { 0, ContainerHandle.MODE_DROP_ON_COMMIT,
7998:                        ContainerHandle.MODE_TRUNCATE_ON_COMMIT };
7999:
8000:                for (int m1 = 0; m1 < modes.length; m1++) {
8001:                    for (int m2 = 0; m2 < modes.length; m2++) {
8002:                        for (int m3 = 0; m3 < modes.length; m3++) {
8003:
8004:                            TC004(m1, m2, m3, false, false);
8005:                            TC004(m1, m2, m3, false, true);
8006:                            TC004(m1, m2, m3, true, false);
8007:                            TC004(m1, m2, m3, true, false);
8008:                        }
8009:                    }
8010:
8011:                }
8012:            }
8013:
8014:            /**
8015:            	Open a temp table several time swith different modes and ensure the
8016:            	correct behaviour (most severe open wins).
8017:
8018:            	@exception T_Fail Unexpected behaviour from the API
8019:            	@exception StandardException Unexpected exception from the implementation
8020:             */
8021:            protected void TC004(int mode1, int mode2, int mode3,
8022:                    boolean doCommit, boolean closeThem)
8023:                    throws StandardException, T_Fail {
8024:
8025:                String testInfo = "TC004 mode1 " + mode1 + " mode2 " + mode2
8026:                        + " mode3 " + mode3 + " doCommit " + doCommit
8027:                        + " closeThem " + closeThem;
8028:                REPORT("start " + testInfo);
8029:
8030:                Transaction t = t_util.t_startTransaction();
8031:
8032:                long cid = t_util.t_addContainer(t,
8033:                        ContainerHandle.TEMPORARY_SEGMENT);
8034:
8035:                REPORT("TC004 container id = " + cid);
8036:
8037:                t_util.setOpenMode(openMode | mode1);
8038:                ContainerHandle c1 = t_util.t_openContainer(t,
8039:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
8040:                populateTempTable(c1);
8041:                if (closeThem)
8042:                    c1.close();
8043:
8044:                t_util.setOpenMode(openMode | mode2);
8045:                ContainerHandle c2 = t_util.t_openContainer(t,
8046:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
8047:                if (closeThem)
8048:                    c2.close();
8049:
8050:                t_util.setOpenMode(openMode | mode3);
8051:                ContainerHandle c3 = t_util.t_openContainer(t,
8052:                        ContainerHandle.TEMPORARY_SEGMENT, cid, true);
8053:                if (closeThem)
8054:                    c2.close();
8055:
8056:                if (doCommit)
8057:                    t_util.t_commit(t);
8058:                else
8059:                    t_util.t_abort(t);
8060:
8061:                int fullMode = mode1 | mode2 | mode3;
8062:
8063:                if ((fullMode & ContainerHandle.MODE_DROP_ON_COMMIT) == ContainerHandle.MODE_DROP_ON_COMMIT) {
8064:                    // table should have disappeared ...
8065:                    ContainerKey id = new ContainerKey(
8066:                            ContainerHandle.TEMPORARY_SEGMENT, cid);
8067:                    ContainerHandle cd = t.openContainer(id,
8068:                            ContainerHandle.MODE_READONLY);
8069:                    if (cd != null)
8070:                        throw T_Fail
8071:                                .testFailMsg("Dropped Container should not open");
8072:
8073:                } else if (!doCommit
8074:                        || ((fullMode & ContainerHandle.MODE_TRUNCATE_ON_COMMIT) == ContainerHandle.MODE_TRUNCATE_ON_COMMIT)) {
8075:                    // table should be empty
8076:                    ContainerHandle ce = t_util.t_openContainer(t,
8077:                            ContainerHandle.TEMPORARY_SEGMENT, cid, true);
8078:
8079:                    Page page = t_util.t_getPage(ce,
8080:                            ContainerHandle.FIRST_PAGE_NUMBER);
8081:
8082:                    t_util.t_checkEmptyPage(page);
8083:                    page.unlatch();
8084:                    page = null;
8085:                }
8086:
8087:                t_util.t_commit(t);
8088:
8089:                t.close();
8090:
8091:                PASS(testInfo);
8092:            }
8093:
8094:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.