KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > unitTests > store > T_Recovery


1 /*
2
3    Derby - Class org.apache.derbyTesting.unitTests.store.T_Recovery
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.unitTests.store;
23
24 import org.apache.derbyTesting.unitTests.harness.T_Generic;
25 import org.apache.derbyTesting.unitTests.harness.T_Fail;
26
27 import org.apache.derby.iapi.store.raw.*;
28
29 import org.apache.derby.iapi.reference.SQLState;
30
31 import org.apache.derby.impl.store.raw.log.LogCounter;
32
33 import org.apache.derby.iapi.services.context.ContextService;
34 import org.apache.derby.iapi.services.context.ContextManager;
35 import org.apache.derby.iapi.services.locks.*;
36 import org.apache.derby.iapi.services.property.PropertyUtil;
37 import org.apache.derby.iapi.services.monitor.Monitor;
38 import org.apache.derby.iapi.services.sanity.SanityManager;
39
40 import org.apache.derby.iapi.error.StandardException;
41
42 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
43 import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
44 import org.apache.derby.iapi.store.raw.log.LogInstant;
45
46 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
47
48 import org.apache.derby.iapi.store.access.Qualifier;
49
50 import org.apache.derby.iapi.types.SQLChar;
51
52 import org.apache.derby.iapi.types.DataValueDescriptor;
53
54
55 import org.apache.derby.iapi.services.uuid.UUIDFactory;
56 import org.apache.derby.catalog.UUID;
57 import org.apache.derby.iapi.reference.Property;
58 import org.apache.derby.iapi.reference.Attribute;
59 import org.apache.derby.iapi.services.io.FormatableBitSet;
60
61 import java.io.*;
62 import java.util.Properties JavaDoc;
63
64
65 /**
66     A protocol unit test for recovery.
67
68     To run, create a derby.properties file in a new directory with the
69     contents
70
71     derby.module.test.recovery=org.apache.derbyTesting.unitTests.store.T_Recovery
72
73     Execute
74
75     java -DSetupRecovery=true org.apache.derbyTesting.unitTests.harness.UnitTestMain
76     java -DTestRecovery=true org.apache.derbyTesting.unitTests.harness.UnitTestMain
77 */

78
79 public class T_Recovery extends T_Generic {
80
81     private static final String JavaDoc testService = "RecoveryTest";
82
83     static final String JavaDoc REC_001 = "McLaren";
84     static final String JavaDoc REC_002 = "Ferrari";
85     static final String JavaDoc REC_003 = "Benetton";
86     static final String JavaDoc REC_004 = "Prost";
87     static final String JavaDoc REC_005 = "Tyrell";
88     static final String JavaDoc REC_006 = "Derby, Natscape, Goatscape, the popular names";
89     static final String JavaDoc REC_UNDO = "Lotus";
90     static final String JavaDoc REC_NULL = "NULL";
91
92     static final String JavaDoc SP1 = "savepoint1";
93     static final String JavaDoc SP2 = "savepoint2";
94
95     static final FormatableBitSet BS_COL_0 = new FormatableBitSet(1);
96
97     private RandomAccessFile filein = null;
98     private RandomAccessFile fileout = null;
99
100     private boolean setupRecovery;
101     private boolean testRecovery;
102     private static final String JavaDoc infoPath = "extinout/T_Recovery.info";
103
104
105     private static final String JavaDoc SETUP_RECOVERY = "SetupRecovery";
106     private static final String JavaDoc TEST_RECOVERY = "TestRecovery";
107     private static final String JavaDoc RECOVERY_TESTPATH = "RecoveryTestPath";
108
109
110     RawStoreFactory factory;
111     LockFactory lf;
112     ContextService contextService;
113     UUIDFactory uuidfactory;
114     T_Util t_util;
115
116     public T_Recovery() {
117         super();
118         BS_COL_0.set(0);
119     }
120
121     /*
122     ** Methods required by T_Generic
123     */

124
125     public String JavaDoc getModuleToTestProtocolName() {
126         return RawStoreFactory.MODULE;
127     }
128
129     /**
130     */

131     private void getConfig()
132     {
133     
134         String JavaDoc param = PropertyUtil.getSystemProperty(SETUP_RECOVERY);
135         setupRecovery = Boolean.valueOf(param).booleanValue();
136
137         param = PropertyUtil.getSystemProperty(TEST_RECOVERY);
138         testRecovery = Boolean.valueOf(param).booleanValue();
139     }
140
141
142
143     /**
144         Tests in here come in pairs (Snnn Rnnn), one to set it up, one to test
145         it after recovery. Information that needs to be passed from the setup
146         to the recovery should, ideally, be written out to a database. For
147         now, it is written out as a pair of <key,value> long in the file
148         T_Recovery.info.
149
150         To make sure you don't accidently tramples on someone else's key,
151         encode your test number (nnn) by shifting over 32 bits and then add
152         your key. Multiple invocations which needs paramaters saved should
153         be encoded futher.
154
155         001 < nnn < 200 - no recovery undo
156         200 < nnn < 400 - recovery undo
157
158         @exception T_Fail Unexpected behaviour from the API
159      */

160     public void runTests() throws T_Fail {
161
162         getConfig();
163
164         if (!(setupRecovery ^ testRecovery))
165             throw T_Fail.testFailMsg("One & only one of the SetupRecovery and TestRecovery properties must be set");
166
167         try {
168
169             uuidfactory = Monitor.getMonitor().getUUIDFactory();
170             if (uuidfactory == null) {
171                 throw T_Fail.testFailMsg("UUIDFactory.MODULE not found");
172             }
173
174             // see if we are testing encryption
175
startParams = T_Util.setEncryptionParam(startParams);
176
177             contextService = ContextService.getFactory();
178
179             if (testRecovery)
180             {
181                 if (!Monitor.startPersistentService(testService, startParams))
182                     throw T_Fail.testFailMsg("Monitor didn't know how to restart service: " + testService);
183                 factory = (RawStoreFactory) Monitor.findService(getModuleToTestProtocolName(), testService);
184
185             }
186             else // setup
187
{
188                 // don't automatic boot this service if it gets left around
189
if (startParams == null)
190                     startParams = new Properties JavaDoc();
191                 
192                 startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
193
194                 // do not make T_Recovery test a source, or it won't run on a
195
// syncless configuration
196
//
197
// remove the service directory to ensure a clean run
198
startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString());
199
200                 // keep all log files for diagnostics
201
startParams.put(RawStoreFactory.KEEP_TRANSACTION_LOG, "true");
202
203                 factory = (RawStoreFactory) Monitor.createPersistentService(getModuleToTestProtocolName(),
204                                                                   testService,
205                                                                   startParams);
206             }
207             
208         } catch (StandardException mse) {
209             throw T_Fail.exceptionFail(mse);
210         }
211
212
213         if (factory == null) {
214             throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " service not started.");
215         }
216             
217         lf = factory.getLockFactory();
218             
219         if (lf == null) {
220             throw T_Fail.testFailMsg("LockFactory.MODULE not found");
221         }
222
223         // get a utility helper
224
t_util = new T_Util(factory, lf, contextService);
225
226
227         try {
228
229             if (setupRecovery)
230             {
231                 // dmls
232
S001(); // insert 1 row
233
S002(); // insert a bunch of rows
234
S003(); // update row
235
S004(); // update field
236
S005(); // purge and delete
237
S006(); // page allocation
238
S007(); // page deallocation
239
S008(); // rollback of page deallocation
240
S009(); // deallocation and reuse of page
241
S010(); // allocation/deallocation with overflow pages
242
S011(); // allocate a lot of pages so that > 1
243
// allocation pages are needed
244
S012(); // test page estimation
245

246                 // ddls
247
S020(); // create multiple containers
248
S022();
249                 
250
251                 // committed transactions
252
S100(); // multiple intervening transactions
253
S101(); // transaction with rollback to savepoints
254

255                 // aborted transaction
256
// - these transactions are rollback during runtime -
257

258                 // incomplete transaction
259
// - these transactions are rollback during recovery -
260

261                 S200(); // 1 incomplete transaction
262
S201(); // multiple intervening incomplete transaction
263
S202(); // incomplete transaction with rollback to
264
// savepoint
265
S203(); // incomplete and committed and aborted
266
// transaction with intervening rollback to savepoints
267
S204(); // incomplete and committed and aborted
268
// internal transactions
269

270                 // incomplete transaction with ddls
271
S300(); // incomplete transactions with drop containers
272
S301(); // incomplete transactions with create containers
273
S302(); //purging rows with no data logged
274
S303(); //purging long columns with no data logged
275
S304(); //pruging long rows with no data logged.
276
}
277
278             if (testRecovery || setupRecovery)
279             {
280                 // basic recovery
281
R001();
282                 R002();
283                 R003();
284                 R004();
285                 R005();
286                 R006();
287                 R007();
288                 R008();
289                 R009();
290                 R010();
291                 R011();
292                 R012();
293
294                 R020();
295                 R022();
296
297                 R100();
298                 R101();
299                 R302();
300
301                 // the following tests depends on recovery to roll back the
302
// changes. Only test them after recovery and not during setup
303
if (testRecovery)
304                 {
305
306                     R200();
307                     R201();
308                     R202();
309                     R203();
310                     R204();
311
312                     R300();
313                     R301();
314                     R303();
315                     R304();
316
317                     R999();
318                 }
319             }
320
321             if (setupRecovery)
322             {
323                 S999(); // always run this last, this leaves a 1/2
324
// written log record at the end of the log
325
// and it leaves a page latched
326
}
327
328             if (fileout != null)
329             {
330                 fileout.close();
331                 fileout = null;
332             }
333
334
335             if (filein != null)
336             {
337                 filein.close();
338                 filein = null;
339             }
340
341         } catch (Throwable JavaDoc t) {
342
343             SanityManager.showTrace(t);
344             System.out.println("caught exception t " + t);
345
346             t.printStackTrace();
347
348             // this test should exit the JVM as abruptly as possible.
349
System.exit(0);
350         }
351     }
352
353     private long find(long inkey) throws T_Fail
354     {
355         try
356         {
357             if (filein == null)
358             {
359                 // make sure it does exist
360
File infoFile = new File(infoPath);
361                 if (infoFile.exists())
362                 {
363                     try
364                     {
365                         filein = new RandomAccessFile(infoFile, "r");
366                     }
367                     catch (IOException ioe)
368                     {
369                         System.out.println("Cannot write to temporary file " +
370                                            infoPath +
371                                            ". Please make sure it is correct, if not, please set the property " +
372                                            "RecoveryTestPath=<where temp files should go>");
373                         throw T_Fail.exceptionFail(ioe);
374                     }
375                 }
376                 else
377                     return -1;
378             }
379
380             filein.seek(0);
381
382             long key;
383             while(true)
384             {
385                 key = filein.readLong();
386                 if (key == inkey)
387                 {
388                     long value = filein.readLong();
389                     // System.out.println("found " + key + " " + value);
390
return value;
391                 }
392                 filein.readLong();
393             }
394         }
395         catch (IOException ioe)
396         {
397             // System.out.println("key not found " + inkey);
398
return -1;
399         }
400
401     }
402
403     private long key(int test, int param)
404     {
405         long i = test;
406         return ((i << 32) + param);
407     }
408
409     private void register(long key, long value)
410          throws T_Fail
411     {
412         // System.out.println("registering " + key + " " + value);
413
try
414         {
415             if (fileout == null)
416             {
417                 // make sure it does not exist
418
File infofile = new File(infoPath);
419                 if (infofile.exists())
420                     infofile.delete();
421                 
422                 //if external input output files dir does not exist ,create one
423
File ifdir = new File("extinout");
424                 if(!ifdir.exists())
425                     ifdir.mkdirs();
426                 fileout = new RandomAccessFile(infoPath, "rw");
427             }
428
429             fileout.writeLong(key);
430             fileout.writeLong(value);
431         }
432         catch (IOException ioe)
433         {
434             T_Fail.exceptionFail(ioe);
435         }
436     }
437
438
439     /*
440      * test 1 - insert 1 row
441      */

442     protected void S001() throws T_Fail, StandardException
443     {
444         Transaction t = t_util.t_startTransaction();
445
446         long cid = t_util.t_addContainer(t, 0);
447
448         t_util.t_commit(t);
449
450         ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
451         Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
452         try
453         {
454
455             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
456     
457             RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
458
459             page.unlatch();
460
461             c.close();
462
463             register(key(1, 1), cid);
464         }
465         finally
466         {
467             t_util.t_commit(t);
468             t.close();
469         }
470
471         REPORT("setup S001: " + cid);
472     }
473
474     /* recover test 1 */
475     protected void R001() throws T_Fail, StandardException
476     {
477         long cid = find(key(1, 1));
478         if (cid < 0)
479         {
480             REPORT("R001 not run");
481             return;
482         }
483
484         Transaction t = t_util.t_startTransaction();
485
486         try
487         {
488             ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
489             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
490
491             t_util.t_checkRecordCount(page, 1, 1);
492             t_util.t_checkFieldCount(page, 0, 1);
493         
494             t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
495             page.unlatch();
496
497         }
498         finally
499         {
500             t_util.t_commit(t);
501             t.close();
502         }
503
504         PASS("R001: containerId " + cid);
505
506     }
507
508     /*
509      * test 2 - insert a bunch of rows into one container
510      */

511     protected void S002() throws T_Fail, StandardException
512     {
513         Transaction t = t_util.t_startTransaction();
514
515         long cid = t_util.t_addContainer(t, 0);
516
517         t_util.t_commit(t);
518
519         try
520         {
521             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
522             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
523
524             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
525             T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
526             T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
527             T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
528             T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
529
530             RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
531
532             RecordHandle r2 = t_util.t_insertAtSlot(page, 1, row2);
533
534             RecordHandle r3 = (r2 == null) ? r2 : t_util.t_insertAtSlot(page, 2, row3);
535
536             RecordHandle r4 = (r3 == null) ? r3 : t_util.t_insertAtSlot(page, 3, row4);
537
538             RecordHandle r5 = (r4 == null) ? r4 : t_util.t_insertAtSlot(page, 4, row5);
539
540             REPORT("setup S002: containerId " + cid + " recordCount " + page.recordCount());
541     
542             register(key(2, 1), cid);
543             register(key(2, 2), page.recordCount());
544             page.unlatch();
545             c.close();
546         }
547         finally
548         {
549             t_util.t_commit(t);
550             t.close();
551         }
552     }
553
554     /* recover test 2 */
555     protected void R002() throws T_Fail, StandardException
556     {
557         long cid = find(key(2,1));
558         if (cid < 0)
559         {
560             REPORT("R002 not run");
561             return;
562         }
563
564         int recordCount = (int)find(key(2,2));
565
566         Transaction t = t_util.t_startTransaction();
567
568         try
569         {
570             ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
571             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
572
573
574             t_util.t_checkRecordCount(page, recordCount, recordCount);
575
576             switch(recordCount)
577             {
578             case 5: t_util.t_checkFetchBySlot(page, 4, REC_005, false, false);
579             case 4: t_util.t_checkFetchBySlot(page, 3, REC_004, false, false);
580             case 3: t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
581             case 2: t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
582             case 1: t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
583             }
584             page.unlatch();
585         }
586         finally
587         {
588             t_util.t_commit(t);
589             t.close();
590         }
591
592         PASS("R002: containerId " + cid + " recordCount " + recordCount);
593
594     }
595
596     /*
597      * test 3 - update row
598      */

599     protected void S003() throws T_Fail, StandardException
600     {
601         Transaction t = t_util.t_startTransaction();
602
603         try
604         {
605             long cid = t_util.t_addContainer(t, 0);
606             t_util.t_commit(t);
607
608             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
609             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
610     
611             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
612
613             RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
614
615             t_util.t_checkFetch(page, r1, row1);
616
617         // REPORT("grows the #column in row");
618
T_RawStoreRow upd1 = new T_RawStoreRow(3);
619             upd1.setColumn(0, (String JavaDoc) null);
620             upd1.setColumn(1, REC_003);
621             upd1.setColumn(2, REC_004);
622
623             r1 = page.updateAtSlot(0, upd1.getRow(), (FormatableBitSet) null);
624
625             // REPORT("update that shrinks the #columns in row");
626
T_RawStoreRow row2 = new T_RawStoreRow(3);
627             row2.setColumn(0, REC_001);
628             row2.setColumn(1, REC_002);
629             row2.setColumn(2, REC_003);
630
631             T_RawStoreRow upd2 = new T_RawStoreRow(REC_005);
632
633             RecordHandle r2 = t_util.t_insertAtSlot(page, 1, row2);
634             if (r2 != null) {
635                 r2 = page.updateAtSlot(1, upd2.getRow(), (FormatableBitSet) null);
636             }
637
638             t_util.t_checkFetch(page, r1, upd1);
639             // first row should contain (null, REC_003, REC_004)
640
DataValueDescriptor column = new SQLChar();
641
642         // page, slot, field, column, forUpdate, data
643
t_util.t_checkFetchColFromSlot(page, 0, 0, column, true, null);
644             t_util.t_checkFetchColFromSlot(page, 0, 1, column, true, REC_003);
645             t_util.t_checkFetchColFromSlot(page, 0, 2, column, true, REC_004);
646
647
648             if (r2 != null)
649             {
650                 t_util.t_checkFetch(page, r2, upd2);
651                 // second row should contain (REC_005)
652
t_util.t_checkFetchColFromSlot(page, 1, 0, column, true, REC_005);
653             }
654
655
656             REPORT("setup S003: containerId " + cid + " recordCount " + page.recordCount());
657             register(key(3, 1), cid);
658             register(key(3, 2), page.recordCount());
659
660             page.unlatch();
661         }
662         finally
663         {
664             t_util.t_commit(t);
665             t.close();
666         }
667     }
668
669     /*
670      * recover test 3
671      */

672     protected void R003() throws T_Fail, StandardException
673     {
674         long cid = find(key(3,1));
675         if (cid < 0)
676         {
677             REPORT("R003 not run");
678             return;
679         }
680
681         int recordCount = (int)find(key(3,2));
682
683         Transaction t = t_util.t_startTransaction();
684         try
685         {
686
687             ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
688             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
689
690             t_util.t_checkRecordCount(page, recordCount, recordCount);
691
692
693         // first row should contain (null, REC_003, REC_004)
694

695             t_util.t_checkFieldCount(page, 0, 3);
696
697             DataValueDescriptor column = new SQLChar();
698             t_util.t_checkFetchColFromSlot(page, 0, 0, column, false, null);
699             t_util.t_checkFetchColFromSlot(page, 0, 1, column, false, REC_003);
700             t_util.t_checkFetchColFromSlot(page, 0, 2, column, false, REC_004);
701
702             if (recordCount == 2)
703             {
704                 // second row should contain (REC_005)
705
t_util.t_checkFieldCount(page, 1, 1);
706                 t_util.t_checkFetchColFromSlot(page, 1, 0, column, false, REC_005);
707             }
708
709             page.unlatch();
710         }
711         finally
712         {
713             t_util.t_commit(t);
714             t.close();
715         }
716         PASS("R003: containerId " + cid + " recordCount " + recordCount);
717     }
718
719     /*
720      * test 4 - update field
721      */

722     protected void S004() throws T_Fail, StandardException
723     {
724         Transaction t = t_util.t_startTransaction();
725
726         try
727         {
728
729             long cid = t_util.t_addContainer(t, 0);
730             t_util.t_commit(t);
731
732             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
733             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
734
735             T_RawStoreRow row = new T_RawStoreRow(5);
736             row.setColumn(0, (String JavaDoc) null);
737             row.setColumn(1, REC_004);
738             row.setColumn(2, (String JavaDoc) null);
739             row.setColumn(3, REC_005);
740             row.setColumn(4, REC_005);
741         
742
743             RecordHandle rh = t_util.t_insert(page, row);
744
745             DataValueDescriptor col0 = new SQLChar(null);
746             DataValueDescriptor col1 = new SQLChar(REC_001);
747             DataValueDescriptor col2 = new SQLChar(REC_002);
748             DataValueDescriptor col3 = new SQLChar(null);
749
750             if (page.updateFieldAtSlot(page.FIRST_SLOT_NUMBER, 0, col0, null) == null ||
751                 page.updateFieldAtSlot(page.FIRST_SLOT_NUMBER, 1, col1, null) == null ||
752                 page.updateFieldAtSlot(page.FIRST_SLOT_NUMBER, 2, col2, null) == null ||
753                 page.updateFieldAtSlot(page.FIRST_SLOT_NUMBER, 3, col3, null) == null)
754             {
755                 throw T_Fail.testFailMsg("Failed to update field");
756             }
757
758             page.unlatch();
759             REPORT("setup S004: containerId " + cid);
760
761             register(key(4,1), cid);
762         }
763         finally
764         {
765             t_util.t_commit(t);
766             t.close();
767         }
768     }
769
770     /* recover test 4 */
771     protected void R004() throws T_Fail,StandardException
772     {
773         long cid = find(key(4,1));
774         if (cid < 0)
775         {
776             REPORT("R004 not run");
777             return;
778         }
779
780         Transaction t = t_util.t_startTransaction();
781
782         try
783         {
784             ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
785             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
786
787             // first row should contain (null, REC_001, REC_002, null, REC_005)
788
DataValueDescriptor column = new SQLChar();
789             t_util.t_checkFetchColFromSlot(page, 0, 0, column, false, null);
790             t_util.t_checkFetchColFromSlot(page, 0, 1, column, false, REC_001);
791             t_util.t_checkFetchColFromSlot(page, 0, 2, column, false, REC_002);
792             t_util.t_checkFetchColFromSlot(page, 0, 3, column, false, null);
793             t_util.t_checkFetchColFromSlot(page, 0, 4, column, false, REC_005);
794
795             page.unlatch();
796         }
797         finally
798         {
799             t_util.t_commit(t);
800             t.close();
801         }
802
803         PASS("R004: containerId " + cid );
804
805     }
806
807     /*
808      * test 5 - purge and delete
809      */

810     protected void S005() throws T_Fail, StandardException
811     {
812         Transaction t = t_util.t_startTransaction();
813
814         try
815         {
816
817             long cid = t_util.t_addContainer(t, 0);
818             t_util.t_commit(t);
819
820             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
821             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
822
823             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
824             T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
825             T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
826             T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
827             T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
828
829             long numPurged = 0;
830
831             // row 0
832
RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
833
834             // purge slot 0
835
page.purgeAtSlot(0, 1, true);
836             numPurged++;
837
838             // slot 0
839
RecordHandle r2 = t_util.t_insertAtSlot(page, 0, row2);
840             if (r2 != null) {
841                 page.delete(r2, (LogicalUndo)null);
842             }
843
844             // slot 1
845
RecordHandle r3 = (r2 == null) ? r2 : t_util.t_insertAtSlot(page, 1, row3);
846             if (r3 != null)
847             {
848             
849                 page.delete(r3, (LogicalUndo)null);
850             }
851
852             // slot 2
853
RecordHandle r4 = (r3 == null) ? r3 : t_util.t_insertAtSlot(page, 2, row4);
854
855             // slot 3
856
RecordHandle r5 = (r4 == null) ? r4 : t_util.t_insertAtSlot(page, 3, row5);
857             if (r5 != null)
858             {
859                 // purge slot 1 and 2
860
page.purgeAtSlot(1, 2, true);
861                 numPurged += 2;
862             }
863
864             REPORT("setup S005: containerId " + cid + " recordCount " +
865                    page.recordCount() + " numPurges " + numPurged);
866
867             register(key(5,1), cid);
868             register(key(5,2), page.recordCount());
869             register(key(5,3), numPurged);
870
871             page.unlatch();
872         }
873         finally
874         {
875             t_util.t_commit(t);
876             t.close();
877         }
878     }
879
880     /* recover test 5 */
881     protected void R005() throws T_Fail, StandardException
882     {
883         long cid = find(key(5,1));
884         if (cid < 0)
885         {
886             REPORT("R005 not run");
887             return;
888         }
889         int recordCount = (int)find(key(5,2));
890         int numPurged = (int)find(key(5,3));
891
892         Transaction t = t_util.t_startTransaction();
893         try
894         {
895             ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
896             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
897
898             t_util.t_checkRecordCount(page, recordCount, 1);
899
900             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
901             T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
902             T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
903             T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
904             T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
905
906             if (numPurged == 1)
907             {
908                 // REC_002 (deleted), REC_003 (deleted), REC_004
909
switch(recordCount)
910                 {
911                 case 3:
912                     t_util.t_checkFetchBySlot(page, 2, REC_004, false, false);
913
914                 case 2:
915                     t_util.t_checkFetchBySlot(page, 1, REC_003, true, false);
916
917                 case 1:
918                     t_util.t_checkFetchBySlot(page, 0, REC_002, true, false);
919                 }
920             }
921             else
922             {
923                 // REC_002 (deleted), REC_005
924
switch(recordCount)
925                 {
926                 case 2:
927                     t_util.t_checkFetchBySlot(page, 1, REC_005, false, false);
928
929                 case 1:
930                     t_util.t_checkFetchBySlot(page, 0, REC_002, true, false);
931                     if (!page.isDeletedAtSlot(0))
932                         throw T_Fail.testFailMsg("record should be deleted");
933                 }
934             }
935
936             page.unlatch();
937         }
938         finally
939         {
940             t_util.t_commit(t);
941             t.close();
942         }
943
944         PASS("R005: containerId " + cid + " recordCount " +
945                recordCount + " numPurges " + numPurged);
946     }
947
948     /*
949      * test 6 - page allocation
950      */

951     protected void S006() throws T_Fail, StandardException
952     {
953         Transaction t = t_util.t_startTransaction();
954
955         try
956         {
957             long cid = t_util.t_addContainer(t, 0);
958             t_util.t_commit(t);
959
960             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
961             T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
962             T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
963
964             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
965             Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
966             t_util.t_insertAtSlot(page, 0, row1);
967             long page1_Id = page.getPageNumber();
968             page.unlatch();
969
970             page = t_util.t_addPage(c);
971             t_util.t_insertAtSlot(page, 0, row2);
972             long page2_Id = page.getPageNumber();
973             page.unlatch();
974
975             page = t_util.t_addPage(c);
976             t_util.t_insertAtSlot(page, 0, row3);
977             long page3_Id = page.getPageNumber();
978             page.unlatch();
979
980             if (page1_Id == page2_Id ||
981                 page1_Id == page3_Id ||
982                 page2_Id == page3_Id)
983                 throw T_Fail.testFailMsg("not getting new pages");
984
985             REPORT("setup S006: containerId " + cid);
986
987             register(key(6,1), cid);
988             register(key(6,2), page1_Id);
989             register(key(6,3), page2_Id);
990             register(key(6,4), page3_Id);
991         }
992         finally
993         {
994             t_util.t_commit(t);
995             t.close();
996         }
997     }
998
999     /* recover test 6 */
1000    protected void R006() throws T_Fail, StandardException
1001    {
1002        long cid = find(key(6,1));
1003        if (cid < 0)
1004        {
1005            REPORT("R006 not run");
1006            return;
1007        }
1008
1009        long page1_Id = find(key(6,2));
1010        long page2_Id = find(key(6,3));
1011        long page3_Id = find(key(6,4));
1012
1013        Transaction t = t_util.t_startTransaction();
1014        try
1015        {
1016
1017            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1018            if (page1_Id != c.FIRST_PAGE_NUMBER)
1019                throw T_Fail.testFailMsg("first page != container first page");
1020
1021            Page page = t_util.t_getPage(c, page1_Id);
1022            t_util.t_checkRecordCount(page, 1, 1);
1023            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
1024            page.unlatch();
1025
1026            page = t_util.t_getPage(c, page2_Id);
1027            t_util.t_checkRecordCount(page, 1, 1);
1028            t_util.t_checkFetchBySlot(page, 0, REC_002, false, false);
1029            page.unlatch();
1030
1031            page = t_util.t_getPage(c, page3_Id);
1032            t_util.t_checkRecordCount(page, 1, 1);
1033            t_util.t_checkFetchBySlot(page, 0, REC_003, false, false);
1034            page.unlatch();
1035
1036            page = t_util.t_getLastPage(c);
1037            t_util.t_checkPageNumber(page, page3_Id);
1038            page.unlatch();
1039
1040        }
1041        finally
1042        {
1043            t_util.t_commit(t);
1044            t.close();
1045        }
1046
1047        PASS("R006: containerId " + cid );
1048    }
1049
1050    /*
1051     * test 7 - page deallocation
1052     */

1053    protected void S007() throws T_Fail, StandardException
1054    {
1055        Transaction t = t_util.t_startTransaction();
1056        try
1057        {
1058
1059            long cid = t_util.t_addContainer(t, 0);
1060            t_util.t_commit(t);
1061
1062            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1063
1064            Page page1 = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1065            long p1 = page1.getPageNumber();
1066
1067            Page page2 = t_util.t_addPage(c);
1068            long p2 = page2.getPageNumber();
1069
1070            Page page3 = t_util.t_addPage(c);
1071            long p3 = page3.getPageNumber();
1072
1073            t_util.t_removePage(c, page2);
1074            t_util.t_removePage(c, page3);
1075            t_util.t_removePage(c, page1);
1076
1077            if (page1.isLatched())
1078                throw T_Fail.testFailMsg("page is still latched after remove");
1079
1080            if (page2.isLatched())
1081                throw T_Fail.testFailMsg("page is still latched after remove");
1082
1083            if (page3.isLatched())
1084                throw T_Fail.testFailMsg("page is still latched after remove");
1085
1086            register(key(7,0), cid);
1087            register(key(7,1), p1);
1088            register(key(7,2), p2);
1089            register(key(7,3), p3);
1090
1091            REPORT("setup S007: containerId " + cid);
1092        }
1093        finally
1094        {
1095            t_util.t_commit(t);
1096            t.close();
1097        }
1098    }
1099
1100    /* recover test 7 */
1101    protected void R007() throws T_Fail, StandardException
1102    {
1103        long cid = find(key(7,0));
1104        if (cid < 0)
1105        {
1106            REPORT("R007 not run");
1107            return;
1108        }
1109
1110        long p1 = find(key(7,1));
1111        long p2 = find(key(7,2));
1112        long p3 = find(key(7,3));
1113
1114        Transaction t = t_util.t_startTransaction();
1115        try
1116        {
1117
1118            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1119
1120            Page p = c.getPage(p1);
1121            if (p != null)
1122                throw T_Fail.testFailMsg("got a deallcated page " + p1);
1123
1124            p = c.getPage(p2);
1125            if (p != null)
1126                throw T_Fail.testFailMsg("got a deallcated page " + p2);
1127
1128            p = c.getPage(p3);
1129            if (p != null)
1130                throw T_Fail.testFailMsg("got a deallcated page " + p3);
1131
1132            p = c.getPage(p3+1);
1133            if (p != null)
1134                throw T_Fail.testFailMsg("got a non-existant page " + p3+100);
1135
1136            p = c.getFirstPage();
1137            if (p != null)
1138                throw T_Fail.testFailMsg("got a non-existant first page ");
1139
1140            p = t_util.t_getLastPage(c);
1141            if (p != null)
1142                throw T_Fail.testFailMsg("got a non-existant last page ");
1143
1144            PASS("R007: containerId " + cid);
1145        }
1146        finally
1147        {
1148            t_util.t_commit(t);
1149            t.close();
1150        }
1151    }
1152
1153    /*
1154     * test 8 - page deallocation with rollback
1155     */

1156    protected void S008() throws T_Fail, StandardException
1157    {
1158        Transaction t = t_util.t_startTransaction();
1159        try
1160        {
1161            long cid = t_util.t_addContainer(t, 0);
1162            t_util.t_commit(t);
1163
1164            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1165
1166            Page page1 = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1167            long p1 = page1.getPageNumber();
1168
1169            Page page2 = t_util.t_addPage(c);
1170            long p2 = page2.getPageNumber();
1171
1172            Page page3 = t_util.t_addPage(c);
1173            long p3 = page3.getPageNumber();
1174
1175            Page page4 = t_util.t_addPage(c);
1176            long p4 = page4.getPageNumber();
1177
1178            Page page5 = t_util.t_addPage(c);
1179            long p5 = page5.getPageNumber();
1180
1181            t_util.t_removePage(c, page1);
1182            t_util.t_removePage(c, page3);
1183            t_util.t_removePage(c, page5);
1184            t_util.t_commit(t);
1185
1186            c = t_util.t_openContainer(t, 0, cid, true);
1187            page3 = t_util.t_getPage(c, p2);
1188            page1 = t_util.t_getPage(c, p4);
1189
1190            // page 2 and page 4 are not removed
1191
t_util.t_removePage(c, page2);
1192            t_util.t_removePage(c, page4);
1193
1194            register(key(8,0), cid);
1195            register(key(8,1), p1);
1196            register(key(8,2), p2);
1197            register(key(8,3), p3);
1198            register(key(8,4), p4);
1199            register(key(8,5), p5);
1200
1201            REPORT("setup S008: containerId " + cid);
1202        }
1203        finally
1204        {
1205            t_util.t_abort(t);
1206            t.close();
1207        }
1208
1209    }
1210
1211    /* recover test 8 */
1212    protected void R008() throws T_Fail, StandardException
1213    {
1214        long cid = find(key(8,0));
1215        if (cid < 0)
1216        {
1217            REPORT("R008 not run");
1218            return;
1219        }
1220
1221        long p1 = find(key(8,1));
1222        long p2 = find(key(8,2));
1223        long p3 = find(key(8,3));
1224        long p4 = find(key(8,4));
1225        long p5 = find(key(8,5));
1226
1227        Transaction t = t_util.t_startTransaction();
1228        try
1229        {
1230
1231            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1232
1233        /* page 1, 3, 5 has been removed, page 2, 4 has not */
1234
1235            Page p = c.getPage(p1);
1236            if (p != null)
1237                throw T_Fail.testFailMsg("got a deallcated page " + p1);
1238
1239            p = t_util.t_getPage(c,p2);
1240            p.unlatch();
1241
1242            p = c.getPage(p3);
1243            if (p != null)
1244                throw T_Fail.testFailMsg("got a deallcated page " + p3);
1245
1246            p = t_util.t_getPage(c,p4);
1247            p.unlatch();
1248
1249            p = c.getPage(p5);
1250            if (p != null)
1251                throw T_Fail.testFailMsg("got a deallcated page " + p5);
1252
1253            p = c.getPage(p5+1);
1254            if (p != null)
1255                throw T_Fail.testFailMsg("got a non-existant page " + p5+1);
1256
1257        // make sure get first page skips over p1
1258
p = c.getFirstPage();
1259            if (p == null || p.getPageNumber() != p2)
1260                throw T_Fail.testFailMsg("get first page failed");
1261            p.unlatch();
1262
1263            // make sure get next page skips over p3
1264
p = c.getNextPage(p2);
1265            if (p == null || p.getPageNumber() != p4)
1266                throw T_Fail.testFailMsg("get next page failed");
1267            p.unlatch();
1268
1269            // make sure get next page skips over p5
1270
p = c.getNextPage(p4);
1271            if (p != null)
1272            {
1273                p.unlatch();
1274                throw T_Fail.testFailMsg("get next page failed to terminate");
1275            }
1276
1277            p = t_util.t_getLastPage(c); // make sure it skips over p5
1278
if (p == null || p.getPageNumber() != p4)
1279                throw T_Fail.testFailMsg("getLastPage failed");
1280            p.unlatch();
1281
1282            PASS("R008: containerId " + cid);
1283
1284        }
1285        finally
1286        {
1287            t_util.t_commit(t);
1288            t.close();
1289        }
1290
1291    }
1292
1293    /*
1294     * test 9 - deallocation and reuse pag
1295     */

1296    protected void S009() throws T_Fail, StandardException
1297    {
1298        Transaction t = t_util.t_startTransaction();
1299        try
1300        {
1301            long cid = t_util.t_addContainer(t, 0);
1302            t_util.t_commit(t);
1303
1304
1305            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1306            int numpages = 10;
1307
1308            Page[] origpage = new Page[numpages];
1309            int[] origrid = new int[numpages];
1310            long[] origpnum = new long[numpages];
1311            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
1312
1313            for (int i = 0; i < numpages; i++)
1314            {
1315                if (i == 0)
1316                    origpage[i] = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1317                else
1318                    origpage[i] = t_util.t_addPage(c);
1319
1320                origrid[i] = t_util.t_insert(origpage[i], row1).getId();
1321                origpnum[i] = origpage[i].getPageNumber();
1322
1323                t_util.t_removePage(c, origpage[i]);
1324            }
1325            t_util.t_commit(t);
1326
1327            // check that pages are not reused before transaction is committed
1328
for (int i = 0; i < numpages-1; i++)
1329            {
1330                for (int j = i+1; j < numpages; j++)
1331                {
1332                    if (origpnum[i] == origpnum[j])
1333                        throw T_Fail.testFailMsg("page reused before transaction is committed");
1334                }
1335            }
1336
1337            register(key(9,0), cid);
1338            register(key(9,1), numpages);
1339
1340            for (int i = 0; i < numpages; i++)
1341            {
1342                register(key(9,i+10), origpnum[i]);
1343                register(key(9,i+numpages+10), origrid[i]);
1344            }
1345
1346            // now see if we can reuse them
1347
c = t_util.t_openContainer(t, 0, cid, true);
1348
1349            Page[] newpage = new Page[numpages];
1350            int[] newrid = new int[numpages];
1351            long[] newpnum = new long[numpages];
1352            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
1353
1354            for (int i = 0; i < numpages; i++)
1355            {
1356                newpage[i] = t_util.t_addPage(c);
1357                newpnum[i] = newpage[i].getPageNumber();
1358                newrid[i] = t_util.t_insert(newpage[i], row2).getId();
1359            }
1360
1361            // if any page is reused, make sure the rid is not reused
1362
int reuse = 0;
1363            for (int i = 0; i < numpages; i++)
1364            {
1365                for (int j = 0; j < numpages; j++)
1366                {
1367                    if (origpnum[i] == newpnum[j])
1368                    {
1369                        reuse++;
1370                        if (origrid[i] == newrid[j])
1371                            throw T_Fail.testFailMsg("resued page rid is not preserved");
1372                    
1373                        break; // inner loop
1374
}
1375                }
1376            }
1377
1378            for (int i = 0; i < numpages; i++)
1379            {
1380                register(key(9,i+100), newpnum[i]);
1381                register(key(9,i+numpages+100), newrid[i]);
1382            }
1383
1384            REPORT("setup S009: containerId " + cid + " of " +
1385                   numpages + " original pages," +
1386                   reuse + " pages were reused.");
1387        }
1388        finally
1389        {
1390            t_util.t_commit(t);
1391            t.close();
1392        }
1393    }
1394
1395    /* recover test 9 */
1396    protected void R009() throws T_Fail, StandardException
1397    {
1398        long cid = find(key(9,0));
1399        if (cid < 0)
1400        {
1401            REPORT("R009 not run");
1402            return;
1403        }
1404        int numpages = (int)find(key(9,1));
1405
1406        int[] newrid = new int[numpages];
1407        long[] newpnum = new long[numpages];
1408        Page[] newpage = new Page[numpages];
1409
1410        Transaction t = t_util.t_startTransaction();
1411        try
1412        {
1413
1414            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1415
1416            for (int i = 0; i < numpages; i++)
1417            {
1418                newrid[i] = (int)find(key(9, i+numpages+100));
1419                newpnum[i] = find(key(9,i+100));
1420
1421                newpage[i] = t_util.t_getPage(c, newpnum[i]);
1422                t_util.t_checkRecordCount(newpage[i], 1, 1);
1423                RecordHandle rh = t_util.t_checkFetchFirst(newpage[i], REC_002);
1424                if (rh.getId() != newrid[i])
1425                    throw T_Fail.testFailMsg("recordId not match");
1426            }
1427            REPORT("R009: containerId " + cid);
1428        }
1429        finally
1430        {
1431            t_util.t_commit(t);
1432            t.close();
1433        }
1434    }
1435
1436    /*
1437     * test 10 - allocation/deallocation with overflow page
1438     */

1439    protected void S010() throws T_Fail,StandardException
1440    {
1441        // maufacture a container with the first and last page being overflow
1442
// pages
1443
Transaction t = t_util.t_startTransaction();
1444        try
1445        {
1446            long cid = t_util.t_addContainer(t, 0);
1447            t_util.t_commit(t);
1448
1449            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1450            int numpages = 10;
1451            Page[] page = new Page[numpages];
1452            long[] pnum = new long[numpages];
1453            RecordHandle[] recordHandles = new RecordHandle[numpages];
1454
1455            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
1456            for (int i = 0; i < numpages; i++)
1457            {
1458                if (i == 0)
1459                    page[i] = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1460                else
1461                    page[i] = t_util.t_addPage(c);
1462
1463                pnum[i] = page[i].getPageNumber();
1464
1465                // remove first two and last page as we go, pages are not reused
1466
// until after commit. These pages have no rows in them
1467
if (i < 2 || i == numpages-1)
1468                {
1469                    t_util.t_checkEmptyPage(page[i]);
1470                    t_util.t_removePage(c, page[i]);
1471                }
1472                else
1473                    recordHandles[i] = t_util.t_insert(page[i], row1);
1474
1475            }
1476
1477            t_util.t_commit(t);
1478            c = t_util.t_openContainer(t, 0, cid, true);
1479
1480            Page p = c.getFirstPage();
1481            if (p.getPageNumber() != pnum[2])
1482                throw T_Fail.testFailMsg("first page expected to be page " +
1483                                         pnum[2] + ", got " + p.getPageNumber() +
1484                                         " instead");
1485            p.unlatch();
1486            p = t_util.t_getLastPage(c);
1487            if (p.getPageNumber() != pnum[numpages-2])
1488                throw T_Fail.testFailMsg("last page expected to be page " +
1489                                         pnum[numpages-2] + ", got " + p.getPageNumber() +
1490                                         " instead");
1491            p.unlatch();
1492
1493        // now make rows on the rest of the page overflow
1494
RecordHandle rh;
1495            T_RawStoreRow big = new T_RawStoreRow(String.valueOf(new char[1500]));
1496            REPORT("start reusing pages hopefully");
1497            for (int i = 2; i < numpages-1; i++)
1498            {
1499                T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
1500
1501                p = t_util.t_getPage(c, pnum[i]);
1502                while(p.spaceForInsert(row2.getRow(), (FormatableBitSet) null, 100))
1503                    t_util.t_insert(p, row2);
1504
1505                // now page is filled
1506
rh = p.fetchFromSlot(
1507                        (RecordHandle) null,
1508                        0,
1509                        row2.getRow(),
1510                        (FetchDescriptor) null,
1511                        true);
1512                p.update(rh, big.getRow(), (FormatableBitSet) null);
1513                p.unlatch();
1514            }
1515
1516            register(key(10, 1), cid);
1517            register(key(10, 2), numpages);
1518            for (int i = 0; i < numpages; i++)
1519                register(key(10, 10+i), pnum[i]);
1520            REPORT("setup S010");
1521        }
1522        finally
1523        {
1524            t_util.t_commit(t);
1525            t.close();
1526        }
1527    }
1528
1529    protected void R010() throws T_Fail, StandardException
1530    {
1531        long cid = find(key(10, 1));
1532        if (cid < 0)
1533        {
1534            REPORT("R010 not run");
1535            return;
1536        }
1537        int numpages = (int)find(key(10,2));
1538        long[] pnum = new long[numpages];
1539        for (int i = 0; i < numpages; i++)
1540            pnum[i] = find(key(10, 10+i));
1541
1542        // now check the pages, 0, 1 and last page (...) are all overflowpages
1543
Transaction t = t_util.t_startTransaction();
1544        try
1545        {
1546            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1547            Page p;
1548
1549            p = c.getPage(pnum[0]);
1550            if (p.recordCount() == 0) // it has no overflow rows in it
1551
{
1552                p.unlatch();
1553                throw T_Fail.testFailMsg("first page failed to get any overflow records");
1554            }
1555            p.unlatch();
1556            p = c.getPage(pnum[1]);
1557            if (p.recordCount() == 0) // it has no overflow rows in it
1558
{
1559                p.unlatch();
1560                throw T_Fail.testFailMsg("second page failed to get any overflow records");
1561            }
1562            p.unlatch();
1563            p = c.getPage(pnum[numpages-1]);
1564            if (p.recordCount() == 0) // it has no overflow rows in it
1565
{
1566                p.unlatch();
1567                throw T_Fail.testFailMsg("last page failed to get any overflow records");
1568            }
1569            p.unlatch();
1570
1571        // all other pages have one huge row at the beginning
1572
p = c.getFirstPage();
1573            if (p.getPageNumber() != pnum[2])
1574                throw T_Fail.testFailMsg("first page expected to be page " +
1575                                         pnum[2] + ", got " + p.getPageNumber() +
1576                                         " instead");
1577            long pageNum = p.getPageNumber();
1578            t_util.t_checkStringLengthFetch(p, 0, 1500);
1579
1580            p.unlatch();
1581            int i = 3;
1582            while((p = c.getNextPage(pageNum)) != null)
1583            {
1584                pageNum = p.getPageNumber();
1585                if (pageNum != pnum[i])
1586                    throw T_Fail.testFailMsg("expect page " + pnum[i] +
1587                                             " get page " + pageNum);
1588                t_util.t_checkStringLengthFetch(p, 0, 1500);
1589                p.unlatch();
1590                i++;
1591            }
1592            if (i != numpages-1)
1593                throw T_Fail.testFailMsg("expect last head page to be " +
1594                                         (numpages-2) + " got " + i + " page instead");
1595        }
1596        finally
1597        {
1598            t_util.t_commit(t);
1599            t.close();
1600        }
1601
1602        PASS("R010");
1603    }
1604
1605    /*
1606     * test 11 - allocate a lot of pages so that we need > 1 allocation pages
1607     */

1608    protected void S011() throws T_Fail, StandardException
1609    {
1610        Transaction t = t_util.t_startTransaction();
1611        int iterations = 10000;
1612
1613        try
1614        {
1615            long cid = t_util.t_addContainer(t, 0, 4096);
1616            t_util.t_commit(t);
1617            
1618            T_RawStoreRow row = new T_RawStoreRow(REC_001);
1619            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1620
1621            // allocate iterations pages, this ought to bring the number of pages
1622
// over what 1 allocation page can handle
1623
Page p = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1624            t_util.t_insert(p, row);
1625            p.unlatch();
1626
1627            long pnum = ContainerHandle.FIRST_PAGE_NUMBER;
1628            long lastPageNum = ContainerHandle.INVALID_PAGE_NUMBER;
1629            for (int i = 1; i <= iterations; i++)
1630            {
1631                p = t_util.t_addPage(c);
1632                if (p.getPageNumber() != pnum+1)
1633                    REPORT("S011: skipping " + (pnum+1) + " going to " + p.getPageNumber());
1634                pnum = p.getPageNumber();
1635
1636                t_util.t_insert(p, row);
1637
1638                if (i == iterations)
1639                {
1640                    lastPageNum = p.getPageNumber();
1641                    REPORT("S011: Last page number is " + lastPageNum);
1642                }
1643
1644                p.unlatch();
1645            }
1646            t_util.t_commit(t);
1647
1648            // now scan the pages
1649
c = t_util.t_openContainer(t, 0, cid, true);
1650            p = c.getFirstPage();
1651            if (p == null || p.getPageNumber() !=
1652                ContainerHandle.FIRST_PAGE_NUMBER)
1653                throw T_Fail.testFailMsg("first page not where it is expected");
1654            p.unlatch();
1655
1656            p = t_util.t_getLastPage(c);
1657            if (p == null || p.getPageNumber() != lastPageNum)
1658                throw T_Fail.testFailMsg("last page not where it is expected");
1659            p.unlatch();
1660
1661            register(key(11, 1), cid);
1662            register(key(11, 2), lastPageNum);
1663            register(key(11, 3), iterations);
1664
1665            REPORT("setup S011, container id = " + cid);
1666        }
1667        finally
1668        {
1669            t_util.t_commit(t);
1670            t.close();
1671        }
1672    }
1673
1674    protected void R011() throws T_Fail, StandardException
1675    {
1676        long cid = find(key(11,1));
1677        if (cid < 0)
1678        {
1679            REPORT("R011 not run");
1680            return;
1681        }
1682        else
1683            REPORT("R011 container id = " + cid);
1684
1685        long expectedLastPageNum = find(key(11,2));
1686        int iterations = (int)find(key(11,3));
1687             
1688        Transaction t = t_util.t_startTransaction();
1689        try
1690        {
1691            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1692            Page p = c.getFirstPage();
1693            if (p == null || p.getPageNumber() !=
1694                ContainerHandle.FIRST_PAGE_NUMBER)
1695                throw T_Fail.testFailMsg("first page not where it is expected");
1696            p.unlatch();
1697
1698
1699            long pageNum = ContainerHandle.FIRST_PAGE_NUMBER;
1700            long pnum = pageNum;
1701            int pcount = 1;
1702            while((p = c.getNextPage(pageNum)) != null)
1703            {
1704                t_util.t_checkFetchFirst(p, REC_001);
1705                pageNum = p.getPageNumber();
1706                if (pageNum != pnum+1)
1707                    REPORT("R011: skipping " + (pnum+1) + " going to " + pageNum);
1708                pnum = pageNum;
1709
1710                pcount++;
1711                p.unlatch();
1712            }
1713            if (pcount != (iterations+1))
1714            {
1715                throw T_Fail.testFailMsg(
1716                    "expect to see " + (iterations+1) + " pages, got: " + pcount +
1717                    " last page number is " + pageNum);
1718            }
1719
1720            p = t_util.t_getLastPage(c);
1721            if (p.getPageNumber() != expectedLastPageNum)
1722            {
1723                throw T_Fail.testFailMsg(
1724                    "expect last page num to be " + expectedLastPageNum +
1725                    " , instead got " + p.getPageNumber());
1726            }
1727
1728            REPORT("Last page pagenumber is " + p.getPageNumber() +
1729                   ", it is the last page of " + (iterations+1) + " user pages");
1730            p.unlatch();
1731            
1732
1733            PASS("R011");
1734        }
1735        finally
1736        {
1737            t_util.t_commit(t);
1738            t.close();
1739        }
1740
1741    }
1742
1743    /*
1744     * test 12 - test estimated page count
1745     */

1746    protected void S012() throws T_Fail, StandardException
1747    {
1748        Transaction t = t_util.t_startTransaction();
1749
1750        long cid = t_util.t_addContainer(t, 0, 4096);
1751        t_util.t_commit(t);
1752
1753        try
1754        {
1755            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
1756
1757            if (c.getEstimatedPageCount(0) != 1)
1758                throw T_Fail.testFailMsg("Expect 2 user page, got " + c.getEstimatedPageCount(0));
1759
1760            // allocate 30 pages
1761
Page p = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
1762            T_RawStoreRow row = new T_RawStoreRow(REC_001);
1763
1764            t_util.t_insert(p, row);
1765            p.unlatch();
1766            for (int i = 2; i <= 30; i++)
1767            {
1768                p = t_util.t_addPage(c);
1769                t_util.t_insert(p, row);
1770                p.unlatch();
1771            }
1772
1773            register(key(12, 1), cid);
1774            REPORT("Setup S012");
1775        }
1776        finally
1777        {
1778            t_util.t_commit(t);
1779            t.close();
1780        }
1781    }
1782
1783    protected void R012() throws T_Fail, StandardException
1784    {
1785        long cid = find(key(12,1));
1786        if (cid < 0)
1787        {
1788            REPORT("R012 not run");
1789            return;
1790        }
1791
1792        Transaction t = t_util.t_startTransaction();
1793        try
1794        {
1795            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
1796            if (c.getEstimatedPageCount(0) != 30)
1797                throw T_Fail.testFailMsg("expect 30 pages, got " + c.getEstimatedPageCount(0));
1798
1799            PASS("R012");
1800        }
1801        finally
1802        {
1803            t_util.t_commit(t);
1804            t.close();
1805        }
1806
1807    }
1808
1809    /*
1810     * test 20 - create multiple containers
1811     */

1812    protected void S020() throws T_Fail, StandardException
1813    {
1814        Transaction t = t_util.t_startTransaction();
1815        T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
1816        T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
1817        T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
1818
1819        try
1820        {
1821
1822            long cid1 = t_util.t_addContainer(t, 0);
1823            ContainerHandle c1 = t_util.t_openContainer(t, 0, cid1, true);
1824            Page page = t_util.t_getPage(c1, ContainerHandle.FIRST_PAGE_NUMBER);
1825            t_util.t_insertAtSlot(page, 0, row1);
1826            page.unlatch();
1827        
1828            long cid2 = t_util.t_addContainer(t, 0);
1829            ContainerHandle c2 = t_util.t_openContainer(t, 0, cid2, true);
1830
1831            long cid3 = t_util.t_addContainer(t, 0);
1832            ContainerHandle c3 = t_util.t_openContainer(t, 0, cid3, true);
1833
1834            page = t_util.t_getPage(c2, ContainerHandle.FIRST_PAGE_NUMBER);
1835            // blank first page
1836
page.unlatch();
1837
1838            page = t_util.t_addPage(c2);
1839            t_util.t_insertAtSlot(page, 0, row2);
1840            long pageId = page.getPageNumber();
1841            page.unlatch();
1842
1843            page = t_util.t_getPage(c3, ContainerHandle.FIRST_PAGE_NUMBER);
1844            t_util.t_insertAtSlot(page, 0, row3);
1845            page.unlatch();
1846
1847            REPORT("setup S020: container1 " + cid1 +
1848                   " container2 " + cid2 + " container3 " + cid3 +
1849                   " page " + pageId);
1850
1851            register(key(20, 1), cid1);
1852            register(key(20, 2), cid2);
1853            register(key(20, 3), cid3);
1854            register(key(20, 4), pageId);
1855        }
1856        finally
1857        {
1858            t_util.t_commit(t);
1859            t.close();
1860        }
1861    }
1862
1863    /* recover test 20 */
1864    protected void R020() throws T_Fail, StandardException
1865    {
1866        long cid1 = find(key(20, 1));
1867        if (cid1 < 0)
1868        {
1869            REPORT("R020 not run");
1870            return;
1871        }
1872
1873        long cid2 = find(key(20,2));
1874        long cid3 = find(key(20,3));
1875        long pageId = find(key(20,4));
1876
1877        Transaction t = t_util.t_startTransaction();
1878        try
1879        {
1880
1881            ContainerHandle c = t_util.t_openContainer(t, 0, cid1, false);
1882            Page page = t_util.t_getPage(c, c.FIRST_PAGE_NUMBER);
1883            t_util.t_checkRecordCount(page, 1, 1);
1884            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
1885            page.unlatch();
1886
1887            c = t_util.t_openContainer(t, 0, cid2, false);
1888            page = t_util.t_getPage(c, c.FIRST_PAGE_NUMBER);
1889            t_util.t_checkEmptyPage(page);
1890            page.unlatch();
1891
1892            page = t_util.t_getPage(c, pageId);
1893            t_util.t_checkRecordCount(page, 1, 1);
1894            t_util.t_checkFetchBySlot(page, 0, REC_002, false, false);
1895            page.unlatch();
1896
1897            c = t_util.t_openContainer(t, 0, cid3, false);
1898            page = t_util.t_getPage(c, c.FIRST_PAGE_NUMBER);
1899            t_util.t_checkRecordCount(page, 1, 1);
1900            t_util.t_checkFetchBySlot(page, 0, REC_003, false, false);
1901            page.unlatch();
1902
1903        }
1904        finally
1905        {
1906            t_util.t_commit(t);
1907            t.close();
1908        }
1909
1910        PASS("R020 container1 " + cid1 +
1911               " container2 " + cid2 + " container3 " + cid3 +
1912               " page " + pageId);
1913    }
1914
1915    /*
1916     * test 022 - drop containers
1917     */

1918    protected void S022() throws T_Fail, StandardException
1919    {
1920        Transaction t = t_util.t_startTransaction();
1921        try
1922        {
1923
1924            long cid = t_util.t_addContainer(t, 0);
1925            t_util.t_commit(t);
1926
1927            t_util.t_openContainer(t, 0, cid, true);
1928            t_util.t_dropContainer(t, 0, cid);
1929
1930            t_util.t_abort(t); // this should rollback the drop
1931
t_util.t_openContainer(t, 0, cid, true);
1932
1933            REPORT("rollback of drop container tested");
1934
1935            t.dropContainer(new ContainerKey(0, cid));
1936
1937            t.commit();
1938
1939            REPORT("setup S022: containerId " + cid);
1940
1941            register(key(22, 1), cid);
1942                 
1943        }
1944        finally
1945        {
1946            t_util.t_commit(t);
1947            t.close();
1948        }
1949    }
1950
1951    /*
1952     * recover test 022 - drop container
1953     */

1954    protected void R022() throws T_Fail, StandardException
1955    {
1956        long cid = find(key(22, 1));
1957        if (cid < 0)
1958        {
1959            REPORT("R022 not run");
1960            return;
1961        }
1962
1963        Transaction t = t_util.t_startTransaction();
1964        try
1965        {
1966            ContainerKey id = new ContainerKey(0, cid);
1967            ContainerHandle c1 = t.openContainer(id, ContainerHandle.MODE_READONLY); // this should fail
1968
if (c1 != null)
1969                throw T_Fail.testFailMsg("dropped container should fail to open");
1970        }
1971        finally
1972        {
1973            t_util.t_commit(t);
1974            t.close();
1975        }
1976        PASS("R022 : containerId " + cid);
1977    }
1978
1979    /*
1980     * test 100 - multiple intervening committed transactions
1981     */

1982    protected void S100() throws T_Fail, StandardException
1983    {
1984        T_TWC t1 = t_util.t_startTransactionWithContext();
1985        T_TWC t2 = t_util.t_startTransactionWithContext();
1986        try
1987        {
1988
1989            long cid10 = t_util.t_addContainer(t1,0);
1990            long cid11 = t_util.t_addContainer(t1,0);
1991            t_util.t_commit(t1);
1992
1993            long cid20 = t_util.t_addContainer(t2, 0);
1994            long cid21 = t_util.t_addContainer(t2, 0);
1995            t_util.t_commit(t2);
1996
1997            ContainerHandle c10 = t_util.t_openContainer(t1, 0, cid10, true);
1998            ContainerHandle c11 = t_util.t_openContainer(t1, 0, cid11, true);
1999            ContainerHandle c20 = t_util.t_openContainer(t2, 0, cid20, true);
2000            ContainerHandle c21 = t_util.t_openContainer(t2, 0, cid21, true);
2001
2002            t1.switchTransactionContext();
2003            Page p10 = t_util.t_getPage(c10, ContainerHandle.FIRST_PAGE_NUMBER);
2004            Page p11 = t_util.t_getPage(c11, ContainerHandle.FIRST_PAGE_NUMBER);
2005            t1.resetContext();
2006
2007            t2.switchTransactionContext();
2008            Page p20 = t_util.t_getPage(c20, ContainerHandle.FIRST_PAGE_NUMBER);
2009            Page p21 = t_util.t_getPage(c21, ContainerHandle.FIRST_PAGE_NUMBER);
2010
2011            // for each page, insert, update, updatefield, (some) delete
2012

2013            T_RawStoreRow row1 = new T_RawStoreRow(3);
2014            row1.setColumn(0, REC_001);
2015            row1.setColumn(1, REC_002);
2016            row1.setColumn(2, (String JavaDoc) null);
2017
2018            T_RawStoreRow row2 = new T_RawStoreRow(2);
2019            row2.setColumn(0, REC_003);
2020            row2.setColumn(1, REC_004);
2021
2022
2023            T_RawStoreRow rowP = new T_RawStoreRow(1);
2024            rowP.setColumn(0, REC_005);
2025            t2.resetContext();
2026
2027
2028            t1.switchTransactionContext();
2029            RecordHandle r10 = t_util.t_insertAtSlot(p10, 0, row1);
2030            RecordHandle r11 = t_util.t_insertAtSlot(p11, 0, row1);
2031            t1.resetContext();
2032
2033            t2.switchTransactionContext();
2034            RecordHandle r20 = t_util.t_insertAtSlot(p20, 0, row1);
2035            RecordHandle r21 = t_util.t_insertAtSlot(p21, 0, row1);
2036            t2.resetContext();
2037
2038            t1.switchTransactionContext();
2039            p10.update(r10, row2.getRow(), (FormatableBitSet) null);
2040            p11.update(r11, row2.getRow(), (FormatableBitSet) null);
2041            t1.resetContext();
2042
2043            t2.switchTransactionContext();
2044            p20.update(r20, row2.getRow(), (FormatableBitSet) null);
2045            p21.update(r21, row2.getRow(), (FormatableBitSet) null);
2046            t2.resetContext();
2047        
2048            t1.switchTransactionContext();
2049            p10.update(r10, rowP.getRow(), BS_COL_0);
2050            p11.update(r11, rowP.getRow(), BS_COL_0);
2051            p10.unlatch();
2052            p11.unlatch();
2053            t1.resetContext();
2054
2055
2056
2057            t2.switchTransactionContext();
2058            p20.update(r20, rowP.getRow(), BS_COL_0);
2059            p21.update(r21, rowP.getRow(), BS_COL_0);
2060
2061            p21.delete(r21, (LogicalUndo)null);
2062            p20.unlatch();
2063            p21.unlatch();
2064            t2.resetContext();
2065
2066            REPORT("setup S100: container1 " + cid10 + " container2 " + cid11 +
2067                   " container3 " + cid20 + " container4 " + cid21);
2068
2069            register(key(100, 1), cid10);
2070            register(key(100, 2), cid11);
2071            register(key(100, 3), cid20);
2072            register(key(100, 4), cid21);
2073        }
2074        finally
2075        {
2076            t_util.t_commit(t1);
2077            t_util.t_close(t1);
2078
2079            t_util.t_commit(t2);
2080            t_util.t_close(t2);
2081        }
2082    }
2083
2084    /* recover S100 */
2085    protected void R100 () throws T_Fail, StandardException
2086    {
2087        long[] cid = new long[4];
2088        cid[0] = find(key(100, 1));
2089        if (cid[0] < 0)
2090        {
2091            REPORT("R100 not run");
2092            return;
2093        }
2094            
2095        cid[1] = find(key(100, 2));
2096        cid[2] = find(key(100, 3));
2097        cid[3] = find(key(100, 4));
2098
2099        Transaction t = t_util.t_startTransaction();
2100        try
2101        {
2102            ContainerHandle c;
2103            Page page;
2104
2105            for (int i = 0; i < 4; i++)
2106            {
2107                c = t_util.t_openContainer(t, 0, cid[i], false);
2108                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2109                if (i == 3)
2110                    t_util.t_checkRecordCount(page, 1, 0);
2111                else
2112                    t_util.t_checkRecordCount(page, 1, 1);
2113
2114                t_util.t_checkFieldCount(page, 0, 2);
2115
2116                // each row has REC_005, REC_004
2117
DataValueDescriptor column = new SQLChar();
2118                t_util.t_checkFetchColFromSlot(page, 0, 0, column, false, REC_005);
2119                t_util.t_checkFetchColFromSlot(page, 0, 1, column, false, REC_004);
2120                page.unlatch();
2121            }
2122
2123            PASS("R100 passed: container1 " + cid[0] + " container2 " + cid[1] +
2124                 " container3 " + cid[2] + " container4 " + cid[3]);
2125        }
2126        finally
2127        {
2128            t_util.t_commit(t);
2129            t.close();
2130        }
2131    }
2132
2133    /*
2134     * test 101 - transaction with rollback to savepoint
2135     */

2136    protected void S101() throws T_Fail, StandardException
2137    {
2138        Transaction t = t_util.t_startTransaction();
2139        try
2140        {
2141
2142            long cid = t_util.t_addContainer(t, 0);
2143            t_util.t_commit(t);
2144
2145            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2146            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2147
2148            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2149            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2150            T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
2151            T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
2152            T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
2153        
2154            RecordHandle r0 = t_util.t_insertAtSlot(page, 0, row1);
2155            if (t_util.t_insertAtSlot(page, 1, row2) == null)
2156                return; // test case not interesting
2157

2158            t_util.t_checkRecordCount(page, 2, 2);
2159            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2160            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2161            /////////////////////////////////////////////////////
2162
// At SP1, has 2 records of REC_001 and REC_002 //
2163
/////////////////////////////////////////////////////
2164
t.setSavePoint(SP1, null);
2165
2166            if (t_util.t_insertAtSlot(page, 2, row3) == null)
2167                return; // test case not interesting
2168

2169            page.purgeAtSlot(1, 1, true);
2170
2171            if (t_util.t_insertAtSlot(page, 1, row4) == null)
2172                return;
2173
2174            t_util.t_checkRecordCount(page, 3, 3);
2175            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2176            t_util.t_checkFetchBySlot(page, 1, REC_004, false, false);
2177            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2178            ////////////////////////////////////////////////////////////////
2179
// At SP2, has 3 records of REC_001 and REC_004 and REC_003 //
2180
////////////////////////////////////////////////////////////////
2181
t.setSavePoint(SP2, null);
2182
2183            page.update(r0, row5.getRow(), (FormatableBitSet) null);
2184            page.deleteAtSlot(1, true, (LogicalUndo)null);
2185
2186            t_util.t_checkRecordCount(page, 3, 2);
2187            t_util.t_checkFetchBySlot(page, 0, REC_005, false, false);
2188            t_util.t_checkFetchBySlot(page, 1, REC_004, true, false);
2189            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2190
2191            page.unlatch();
2192            t.rollbackToSavePoint(SP2, null);
2193            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2194
2195            t_util.t_checkRecordCount(page, 3, 3);
2196            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2197            t_util.t_checkFetchBySlot(page, 1, REC_004, false, false);
2198            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2199
2200            // after a rollback to sp, do some more changes
2201

2202            page.update(r0, row5.getRow(), (FormatableBitSet) null);
2203            page.deleteAtSlot(0, true, (LogicalUndo)null);
2204            page.deleteAtSlot(1, true, (LogicalUndo)null);
2205            page.deleteAtSlot(2, true, (LogicalUndo)null);
2206
2207            t_util.t_checkRecordCount(page, 3, 0);
2208            t_util.t_checkFetchBySlot(page, 0, REC_005, true, false);
2209            t_util.t_checkFetchBySlot(page, 1, REC_004, true, false);
2210            t_util.t_checkFetchBySlot(page, 2, REC_003, true, false);
2211
2212            page.unlatch();
2213            t.rollbackToSavePoint(SP1, null);
2214            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2215
2216            // note that an insert, when rolled back, becomes a deleted row but
2217
// will not disappear. A purge row will come back at the same slot
2218
// and with the same record id.
2219
t_util.t_checkRecordCount(page, 4, 2);
2220
2221            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2222            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2223            t_util.t_checkFetchBySlot(page, 2, REC_004, true, false);
2224            t_util.t_checkFetchBySlot(page, 3, REC_003, true, false);
2225
2226            // add one more record to this
2227
if (page.spaceForInsert())
2228                t_util.t_insertAtSlot(page, 3, row5);
2229
2230            REPORT("setup S101: containerId " + cid + " recordCount " + page.recordCount());
2231
2232            register(key(101, 1), cid);
2233            register(key(101, 2), page.recordCount());
2234
2235            page.unlatch();
2236        }
2237        finally
2238        {
2239            t_util.t_commit(t);
2240            t.close();
2241        }
2242    }
2243
2244    /* recover test 101 */
2245    protected void R101() throws T_Fail, StandardException
2246    {
2247        long cid = find(key(101, 1));
2248        if (cid < 0)
2249        {
2250            REPORT("R101 not run");
2251            return;
2252        }
2253        int recordCount = (int)find(key(101, 2));
2254
2255        Transaction t = t_util.t_startTransaction();
2256        try
2257        {
2258
2259            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
2260            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2261
2262            t_util.t_checkRecordCount(page, recordCount, recordCount-2);
2263            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2264            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2265            t_util.t_checkFetchBySlot(page, 2, REC_004, true, false);
2266            if (recordCount == 5)
2267            {
2268                t_util.t_checkFetchBySlot(page, 3, REC_005, false, false);
2269                t_util.t_checkFetchBySlot(page, 4, REC_003, true, false);
2270            }
2271            else
2272                t_util.t_checkFetchBySlot(page, 3, REC_003, true, false);
2273
2274            page.unlatch();
2275        }
2276        finally
2277        {
2278            t_util.t_commit(t);
2279            t.close();
2280        }
2281
2282        PASS("R101: containerId " + cid + " recordCount " + recordCount);
2283    }
2284
2285
2286    /*
2287     * the following tests has recovery undo work, cannot test Rnnn during
2288     * setup because it hasn't been rolled back during setup yet. Test the
2289     * state in Snnn.
2290     */

2291
2292    /*
2293     * test 200 - incomplete transaction
2294     */

2295    protected void S200() throws T_Fail, StandardException
2296    {
2297        T_TWC ctx = t_util.t_startTransactionWithContext();
2298        Transaction t = ctx.tran;
2299        Page page = null;
2300
2301        try
2302        {
2303            long cid = t_util.t_addContainer(t, 0);
2304
2305            t_util.t_commit(t);
2306
2307            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2308
2309            ctx.switchTransactionContext();
2310
2311            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2312
2313            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2314
2315            int rowcount = 0;
2316            while(page.spaceForInsert())
2317            {
2318                if (t_util.t_insertAtSlot(page, 0, row1) != null)
2319                    rowcount++;
2320            }
2321
2322            t_util.t_checkRecordCount(page, rowcount, rowcount);
2323            for (int i = 0; i < rowcount; i++)
2324                t_util.t_checkFetchBySlot(page, i, REC_001, false, false);
2325
2326            REPORT("setup S200: containerId " + cid + " recordCount " + rowcount);
2327            register(key(200, 1), cid);
2328            register(key(200, 2), rowcount);
2329        }
2330        finally
2331        {
2332            if (page != null && page.isLatched())
2333                page.unlatch();
2334            ctx.resetContext();
2335        }
2336        // do not abort it at run time, abort it at recovery time
2337
// t_util.t_abort(t);
2338
// t.close();
2339
}
2340
2341    /* recover test 200 */
2342    protected void R200() throws T_Fail, StandardException
2343    {
2344        long cid = find(key(200, 1));
2345        if (cid < 0)
2346        {
2347            REPORT("R200 not run");
2348            return;
2349        }
2350
2351        int recordCount = (int)find(key(200, 2));
2352
2353        Transaction t = t_util.t_startTransaction();
2354        try
2355        {
2356
2357            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
2358            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2359
2360            // rollback of an insert is a deleted record
2361
t_util.t_checkRecordCount(page, recordCount, 0);
2362            for (int i = 0; i < recordCount; i++)
2363                t_util.t_checkFetchBySlot(page, i, REC_001, true, false);
2364            page.unlatch();
2365
2366            PASS("R200: containerId " + cid + " recordCount " + recordCount);
2367
2368        }
2369        finally
2370        {
2371            t_util.t_commit(t);
2372            t.close();
2373        }
2374    }
2375
2376    /*
2377     * test 201 - multiple intervening incomplete transaction
2378     */

2379    protected void S201() throws T_Fail, StandardException
2380    {
2381        /* this is the same as S100 but left it at an incomplete state */
2382        T_TWC t1 = t_util.t_startTransactionWithContext();
2383        T_TWC t2 = t_util.t_startTransactionWithContext();
2384        Page p10, p11, p20, p21;
2385        p10 = p11 = p20 = p21 = null;
2386
2387        try
2388        {
2389            long cid10 = t_util.t_addContainer(t1,0);
2390            long cid11 = t_util.t_addContainer(t1,0);
2391
2392            long cid20 = t_util.t_addContainer(t2, 0);
2393            long cid21 = t_util.t_addContainer(t2, 0);
2394
2395            t_util.t_commit(t1);
2396            t_util.t_commit(t2);
2397
2398            ContainerHandle c10 = t_util.t_openContainer(t1, 0, cid10, true);
2399            ContainerHandle c11 = t_util.t_openContainer(t1, 0, cid11, true);
2400            ContainerHandle c20 = t_util.t_openContainer(t2, 0, cid20, true);
2401            ContainerHandle c21 = t_util.t_openContainer(t2, 0, cid21, true);
2402
2403            t1.switchTransactionContext();
2404            p10 = t_util.t_getPage(c10, ContainerHandle.FIRST_PAGE_NUMBER);
2405            p11 = t_util.t_getPage(c11, ContainerHandle.FIRST_PAGE_NUMBER);
2406            t1.resetContext();
2407
2408            t2.switchTransactionContext();
2409            p20 = t_util.t_getPage(c20, ContainerHandle.FIRST_PAGE_NUMBER);
2410            p21 = t_util.t_getPage(c21, ContainerHandle.FIRST_PAGE_NUMBER);
2411
2412            // for each page, insert, update, updatefield, (some) delete
2413

2414            T_RawStoreRow row1 = new T_RawStoreRow(3);
2415            row1.setColumn(0, REC_001);
2416            row1.setColumn(1, REC_002);
2417            row1.setColumn(2, (String JavaDoc) null);
2418
2419            T_RawStoreRow row2 = new T_RawStoreRow(2);
2420            row2.setColumn(0, REC_003);
2421            row2.setColumn(1, REC_004);
2422
2423
2424            T_RawStoreRow rowP = new T_RawStoreRow(1);
2425            rowP.setColumn(0, REC_005);
2426            t2.resetContext();
2427
2428            t1.switchTransactionContext();
2429            RecordHandle r10 = t_util.t_insertAtSlot(p10, 0, row1);
2430            RecordHandle r11 = t_util.t_insertAtSlot(p11, 0, row1);
2431            t1.resetContext();
2432
2433            t2.switchTransactionContext();
2434            RecordHandle r20 = t_util.t_insertAtSlot(p20, 0, row1);
2435            RecordHandle r21 = t_util.t_insertAtSlot(p21, 0, row1);
2436            t2.resetContext();
2437
2438            t1.switchTransactionContext();
2439            p10.update(r10, row2.getRow(), (FormatableBitSet) null);
2440            p11.update(r11, row2.getRow(), (FormatableBitSet) null);
2441            t1.resetContext();
2442
2443            t2.switchTransactionContext();
2444            p20.update(r20, row2.getRow(), (FormatableBitSet) null);
2445            p21.update(r21, row2.getRow(), (FormatableBitSet) null);
2446            t2.resetContext();
2447
2448
2449            t1.switchTransactionContext();
2450            p10.update(r10, rowP.getRow(), BS_COL_0);
2451            p11.update(r11, rowP.getRow(), BS_COL_0);
2452            t1.resetContext();
2453
2454            t2.switchTransactionContext();
2455            p20.update(r20, rowP.getRow(), BS_COL_0);
2456            p21.update(r21, rowP.getRow(), BS_COL_0);
2457
2458            p21.delete(r21, (LogicalUndo)null);
2459            t2.resetContext();
2460
2461            REPORT("setup S201: container1 " + cid10 + " container2 " + cid11 +
2462                   " container3 " + cid20 + " container4 " + cid21);
2463
2464            register(key(201, 1), cid10);
2465            register(key(201, 2), cid11);
2466            register(key(201, 3), cid20);
2467            register(key(201, 4), cid21);
2468        }
2469        finally
2470        {
2471            if (p10 != null && p10.isLatched())
2472                p10.unlatch();
2473
2474
2475            if (p11 != null && p11.isLatched())
2476                p11.unlatch();
2477
2478
2479            if (p20 != null && p20.isLatched())
2480                p20.unlatch();
2481
2482            if (p21 != null && p21.isLatched())
2483                p21.unlatch();
2484        }
2485
2486        // let recovery do the abort
2487
}
2488
2489    /* recover test 201 */
2490    protected void R201() throws T_Fail, StandardException
2491    {
2492        long[] cid = new long[4];
2493        cid[0] = find(key(201, 1));
2494        if (cid[0] < 0)
2495        {
2496            REPORT("R201 not run");
2497            return;
2498        }
2499            
2500        cid[1] = find(key(201, 2));
2501        cid[2] = find(key(201, 3));
2502        cid[3] = find(key(201, 4));
2503
2504        Transaction t = t_util.t_startTransaction();
2505        try
2506        {
2507
2508            ContainerHandle c;
2509            Page page;
2510
2511            for (int i = 0; i < 4; i++)
2512            {
2513                c = t_util.t_openContainer(t, 0, cid[i], false);
2514                page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2515                t_util.t_checkRecordCount(page, 1, 0);
2516
2517                // record has the following fields: REC_001, REC_002, null
2518
DataValueDescriptor column = new SQLChar();
2519                t_util.t_checkFetchColFromSlot(page, 0, 0, column, false, REC_001);
2520                t_util.t_checkFetchColFromSlot(page, 0, 1, column, false, REC_002);
2521                t_util.t_checkFetchColFromSlot(page, 0, 2, column, false, null);
2522            }
2523        }
2524        finally
2525        {
2526            t_util.t_commit(t);
2527            t.close();
2528        }
2529        PASS("R201 passed: container1 " + cid[0] + " container2 " + cid[1] +
2530               " container3 " + cid[2] + " container4 " + cid[3]);
2531    }
2532
2533    /*
2534     * test 202 - incomplete transaction with rollback to savepoints
2535     */

2536    protected void S202() throws T_Fail, StandardException
2537    {
2538        /* this is S101 which is left in an incomplete state */
2539        T_TWC ctx = t_util.t_startTransactionWithContext();
2540        Transaction t = ctx.tran;
2541        Page page = null;
2542        ctx.switchTransactionContext();
2543
2544        try
2545        {
2546            long cid = t_util.t_addContainer(t, 0);
2547            t_util.t_commit(t);
2548
2549            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2550            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2551
2552            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2553            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2554            T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
2555            T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
2556            T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
2557
2558            RecordHandle r0 = t_util.t_insertAtSlot(page, 0, row1);
2559            if (t_util.t_insertAtSlot(page, 1, row2) == null)
2560            {
2561                page.unlatch();
2562                t_util.t_abort(t);
2563                t.close();
2564                return; // test case not interesting
2565
}
2566
2567
2568            /////////////////////////////////////////////////////
2569
// At SP1, has 2 records of REC_001 and REC_002 //
2570
/////////////////////////////////////////////////////
2571
t.setSavePoint(SP1, null);
2572
2573            page.update(r0, row5.getRow(), (FormatableBitSet) null);
2574            t_util.t_checkFetchBySlot(page, 0, REC_005, false, false);
2575            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2576
2577            page.unlatch();
2578            t.rollbackToSavePoint(SP1, null);
2579            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2580
2581            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2582            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2583
2584            if (t_util.t_insertAtSlot(page, 2, row3) == null)
2585            {
2586                page.unlatch();
2587                t_util.t_abort(t);
2588                t.close();
2589                return; // test case not interesting
2590
}
2591
2592            page.purgeAtSlot(1, 1, true);
2593
2594            if (t_util.t_insertAtSlot(page, 1, row4) == null)
2595            {
2596                page.unlatch();
2597                t_util.t_abort(t);
2598                t.close();
2599                return; // test case not interesting
2600
}
2601
2602            t_util.t_checkRecordCount(page, 3, 3);
2603            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2604            t_util.t_checkFetchBySlot(page, 1, REC_004, false, false);
2605            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2606            ////////////////////////////////////////////////////////////////
2607
// At SP2, has 3 records of REC_001 and REC_004 and REC_003 //
2608
////////////////////////////////////////////////////////////////
2609
t.setSavePoint(SP2, null);
2610
2611            page.update(r0, row5.getRow(), (FormatableBitSet) null);
2612            page.deleteAtSlot(1, true, (LogicalUndo)null);
2613
2614            t_util.t_checkRecordCount(page, 3, 2);
2615            t_util.t_checkFetchBySlot(page, 0, REC_005, false, false);
2616            t_util.t_checkFetchBySlot(page, 1, REC_004, true, false);
2617            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2618
2619            page.unlatch();
2620            t.rollbackToSavePoint(SP2, null);
2621            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2622
2623            t_util.t_checkRecordCount(page, 3, 3);
2624            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2625            t_util.t_checkFetchBySlot(page, 1, REC_004, false, false);
2626            t_util.t_checkFetchBySlot(page, 2, REC_003, false, false);
2627
2628        // after a rollback to sp, do some more changes
2629

2630            page.update(r0, row5.getRow(), (FormatableBitSet) null);
2631            page.deleteAtSlot(0, true, (LogicalUndo)null);
2632            page.deleteAtSlot(1, true, (LogicalUndo)null);
2633            page.deleteAtSlot(2, true, (LogicalUndo)null);
2634
2635            t_util.t_checkRecordCount(page, 3, 0);
2636            t_util.t_checkFetchBySlot(page, 0, REC_005, true, false);
2637            t_util.t_checkFetchBySlot(page, 1, REC_004, true, false);
2638            t_util.t_checkFetchBySlot(page, 2, REC_003, true, false);
2639
2640            page.unlatch();
2641            t.rollbackToSavePoint(SP1, null);
2642            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2643
2644            // note that an insert, when rolled back, becomes a deleted row but
2645
// will not disappear. A purge row will come back at the same slot
2646
// and with the same record id.
2647
t_util.t_checkRecordCount(page, 4, 2);
2648
2649            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
2650            t_util.t_checkFetchBySlot(page, 1, REC_002, false, false);
2651            t_util.t_checkFetchBySlot(page, 2, REC_004, true, false);
2652            t_util.t_checkFetchBySlot(page, 3, REC_003, true, false);
2653
2654            // add one more record to this
2655
if (page.spaceForInsert())
2656                t_util.t_insertAtSlot(page, 3, row5);
2657
2658            REPORT("setup S202: containerId " + cid + " recordCount " + page.recordCount());
2659
2660            register(key(202, 1), cid);
2661            register(key(202, 2), page.recordCount());
2662
2663        }
2664        finally
2665        {
2666            if (page != null && page.isLatched())
2667                page.unlatch();
2668            ctx.resetContext();
2669        }
2670
2671        // let recovery undo rollback this transaction
2672

2673    }
2674
2675
2676    /* recover test 202 */
2677    protected void R202() throws T_Fail, StandardException
2678    {
2679        long cid = find(key(202, 1));
2680        if (cid < 0)
2681        {
2682            REPORT("R202 not run");
2683            return;
2684        }
2685        int recordCount = (int)find(key(202, 2));
2686
2687        Transaction t = t_util.t_startTransaction();
2688        Page page = null;
2689
2690        try
2691        {
2692            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
2693            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
2694
2695            // rollback will leave the page with only deleted rows
2696
t_util.t_checkRecordCount(page, recordCount, 0);
2697            t_util.t_checkFetchBySlot(page, 0, REC_001, true, true);
2698            t_util.t_checkFetchBySlot(page, 1, REC_002, true, true);
2699            t_util.t_checkFetchBySlot(page, 2, REC_004, true, true);
2700            if (recordCount == 5)
2701            {
2702                t_util.t_checkFetchBySlot(page, 3, REC_005, true, true);
2703                t_util.t_checkFetchBySlot(page, 4, REC_003, true, true);
2704            }
2705            else
2706                t_util.t_checkFetchBySlot(page, 3, REC_003, true, true);
2707
2708        }
2709        finally
2710        {
2711            if (page != null && page.isLatched())
2712                page.unlatch();
2713
2714            t_util.t_commit(t);
2715            t.close();
2716        }
2717        PASS("R202: containerId " + cid + " recordCount " + recordCount);
2718    }
2719
2720    /*
2721     * test 203 - incomplete and committed and aborted
2722     * transaction with intervening rollback to savepoints
2723     */

2724    protected void S203() throws T_Fail, StandardException
2725    {
2726        int numtrans = 5;
2727        int numpages = 2;
2728        int i,j;
2729
2730        T_TWC[] t = new T_TWC[numtrans];
2731        for (i = 0; i < numtrans; i++)
2732            t[i] = t_util.t_startTransactionWithContext();
2733
2734        Page[][] page = null;
2735
2736        try
2737        {
2738            long[] cid = new long[numtrans];
2739            ContainerHandle[] c = new ContainerHandle[numtrans];
2740
2741            for (i = 0; i < numtrans; i++)
2742            {
2743                cid[i] = t_util.t_addContainer(t[i], 0);
2744                t_util.t_commit(t[i]);
2745                c[i] = t_util.t_openContainer(t[i], 0, cid[i], true);
2746            }
2747
2748            page = new Page[numtrans][numpages];
2749            long pagenum[][] = new long[numtrans][numpages];
2750
2751            for (i = 0; i < numtrans; i++)
2752            {
2753                for (j = 0; j < numpages; j++)
2754                {
2755                    t[i].switchTransactionContext();
2756                    page[i][j] = t_util.t_addPage(c[i]);
2757                    pagenum[i][j] = page[i][j].getPageNumber();
2758                    t[i].resetContext();
2759                }
2760            }
2761
2762            // set up numtrans (at least 5) transactions, each with one
2763
// container and numpages pages. Do the following test:
2764
//
2765
// 1) insert 1 row onto each page
2766
// set savepoint SP1 on first transaction (t0)
2767
//
2768
// 2) update every rows
2769
// set savepoint SP1 on all other transactions
2770
//
2771
// 3) update every rows
2772
// set savepoint SP2 on all transactions
2773
//
2774
// 4) update every rows
2775
//
2776
// 5) rollback t0 to SP1
2777
//
2778
// check that only page[0][x] have been rolled back
2779
// past SP2
2780
//
2781
// 6) update every row
2782
// 7) rollback SP2 on all transaction except the first
2783
//
2784
// 8) update every rows
2785
// 9) rollback t0 to SP1
2786
//
2787
// 10) leave transactions in the following state
2788
// t0 - incomplete
2789
// t1 - abort
2790
// t2 - commit
2791
// t3 - incomplete
2792
// t4 - commit
2793
// any other transactions - incomplete
2794

2795
2796            //////////////////////// step 1 ////////////////////////
2797
RecordHandle[][] rh = new RecordHandle[numtrans][numpages];
2798            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
2799            for (i = 0; i < numtrans; i++)
2800                for (j = 0; j < numpages; j++)
2801                {
2802                    t[i].switchTransactionContext();
2803                    rh[i][j] = t_util.t_insert(page[i][j], row1);
2804                    t[i].resetContext();
2805                }
2806
2807            t[0].switchTransactionContext();
2808            t[0].setSavePoint(SP1, null); // sp1
2809
t[0].resetContext();
2810
2811
2812            //////////////////////// step 2 ////////////////////////
2813
T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
2814            for (i = 0; i < numtrans; i++)
2815                for (j = 0; j < numpages; j++)
2816                {
2817                    t[i].switchTransactionContext();
2818                    page[i][j].update(rh[i][j], row2.getRow(), (FormatableBitSet) null);
2819                    t[i].resetContext();
2820                }
2821
2822            for (i = 1; i < numtrans; i++) // sp1
2823
{
2824                t[i].switchTransactionContext();
2825                t[i].setSavePoint(SP1, null);
2826                t[i].resetContext();
2827            }
2828
2829            //////////////////////// step 3 ////////////////////////
2830
T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
2831            for (i = 0; i < numtrans; i++)
2832                for (j = 0; j < numpages; j++)
2833                    page[i][j].update(rh[i][j], row3.getRow(), (FormatableBitSet) null);
2834
2835            for (i = 0; i < numtrans; i++)
2836                t[i].setSavePoint(SP2, null); // sp2
2837

2838        //////////////////////// step 4 ////////////////////////
2839
T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
2840            for (i = 0; i < numtrans; i++)
2841            {
2842                t[i].switchTransactionContext();
2843
2844                for (j = 0; j < numpages; j++)
2845                    page[i][j].update(rh[i][j], row4.getRow(), (FormatableBitSet) null);
2846                t[i].resetContext();
2847            }
2848
2849
2850            //////////////////////// step 5 ////////////////////////
2851
// unlatch relavante pages
2852
t[0].switchTransactionContext();
2853
2854            for (j = 0; j < numpages; j++)
2855                page[0][j].unlatch();
2856
2857            t[0].rollbackToSavePoint(SP1, null); // step 5
2858

2859            // relatch relavante pages
2860
for (j = 0; j < numpages; j++)
2861                page[0][j] = t_util.t_getPage(c[0], pagenum[0][j]);
2862                    
2863            t[0].resetContext();
2864
2865
2866        //////////////////////// check ////////////////////////
2867
for (i = 1; i < numtrans; i++)
2868            {
2869                t[i].switchTransactionContext();
2870                for (j = 0; j < numpages; j++)
2871                    t_util.t_checkFetch(page[i][j], rh[i][j], REC_004);
2872                t[i].resetContext();
2873            }
2874
2875            t[0].switchTransactionContext();
2876            for (j = 0; j < numpages; j++)
2877                t_util.t_checkFetch(page[0][j], rh[0][j], REC_001);
2878
2879            t[0].resetContext();
2880        //////////////////////// step 6 ////////////////////////
2881
T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
2882            for (i = 0; i < numtrans; i++)
2883            {
2884                t[i].switchTransactionContext();
2885                for (j = 0; j < numpages; j++)
2886                    page[i][j].update(rh[i][j], row5.getRow(), (FormatableBitSet) null);
2887                t[i].resetContext();
2888            }
2889
2890            //////////////////////// step 7 ////////////////////////
2891
for (i = 1; i < numtrans; i++)
2892            {
2893                t[i].switchTransactionContext();
2894
2895                for (j = 0; j < numpages; j++)
2896                    page[i][j].unlatch();
2897
2898                t[i].rollbackToSavePoint(SP2, null);
2899
2900                for (j = 0; j < numpages; j++)
2901                    page[i][j] = t_util.t_getPage(c[i],pagenum[i][j]);
2902                t[i].resetContext();
2903            }
2904
2905            //////////////////////// check ////////////////////////
2906
for (i = 1; i < numtrans; i++)
2907            {
2908                t[i].switchTransactionContext();
2909                for (j = 0; j < numpages; j++)
2910                    t_util.t_checkFetch(page[i][j], rh[i][j], REC_003);
2911                t[i].resetContext();
2912            }
2913
2914            t[0].switchTransactionContext();
2915            for (j = 0; j < numpages; j++)
2916                t_util.t_checkFetch(page[0][j], rh[0][j], REC_005);
2917            t[0].resetContext();
2918
2919
2920        //////////////////////// step 8 ////////////////////////
2921
T_RawStoreRow row6 = new T_RawStoreRow(REC_006);
2922            for (i = 0; i < numtrans; i++)
2923            {
2924                t[i].switchTransactionContext();
2925                for (j = 0; j < numpages; j++)
2926                    page[i][j].update(rh[i][j], row6.getRow(), (FormatableBitSet) null); // step 8
2927
t[i].resetContext();
2928            }
2929
2930            //////////////////////// step 9 ////////////////////////
2931
// unlatch relavante pages
2932
t[0].switchTransactionContext();
2933            for (j = 0; j < numpages; j++)
2934                page[0][j].unlatch();
2935
2936            t[0].rollbackToSavePoint(SP1, null);
2937
2938            // relatch relavante pages
2939
for (j = 0; j < numpages; j++)
2940                page[0][j] = t_util.t_getPage(c[0], pagenum[0][j]);
2941
2942            t[0].resetContext();
2943        //////////////////////// check ////////////////////////
2944
for (i = 1; i < numtrans; i++)
2945            {
2946                t[i].switchTransactionContext();
2947
2948                for (j = 0; j < numpages; j++)
2949                {
2950                    t_util.t_checkFetch(page[i][j], rh[i][j], REC_006);
2951                    t_util.t_checkRecordCount(page[i][j], 1, 1);
2952                }
2953                t[i].resetContext();
2954            }
2955
2956            t[0].switchTransactionContext();
2957            for (j = 0; j < numpages; j++)
2958            {
2959                t_util.t_checkFetch(page[0][j], rh[0][j], REC_001);
2960                t_util.t_checkRecordCount(page[0][j], 1, 1);
2961            }
2962            t[0].resetContext();
2963
2964            //////////////////////// step 10 ////////////////////////
2965
// unlatch all pages
2966
for (i = 0; i < numtrans; i++)
2967            {
2968                t[i].switchTransactionContext();
2969                for (j = 0; j < numpages; j++)
2970                    page[i][j].unlatch();
2971                t[i].resetContext();
2972            }
2973
2974            // t[0] incomplete
2975
t_util.t_abort(t[1]);
2976            t_util.t_commit(t[2]);
2977            // t[3] incomplete
2978
t_util.t_commit(t[4]);
2979
2980        // reopen containers 1, 2, and 4, where were closed when the
2981
// transaction terminated.
2982
c[1] = t_util.t_openContainer(t[1], 0, cid[1], false);
2983            c[2] = t_util.t_openContainer(t[2], 0, cid[2], false);
2984            c[4] = t_util.t_openContainer(t[4], 0, cid[4], false);
2985
2986            //////////////////////// check ////////////////////////
2987
for (j = 0; j < numpages; j++)
2988            {
2989                t[0].switchTransactionContext();
2990                t_util.t_checkFetch(c[0], rh[0][j], REC_001);
2991                t[0].resetContext();
2992
2993                // t[1] has been aborted
2994
// rh[1][j] (REC_001) is deleted
2995
t[1].switchTransactionContext();
2996                page[1][j] = t_util.t_getPage(c[1], pagenum[1][j]);
2997                t_util.t_checkRecordCount(page[1][j], 1, 0);
2998                t_util.t_checkFetchBySlot(page[1][j], Page.FIRST_SLOT_NUMBER,
2999                                          REC_001, true, false);
3000                page[1][j].unlatch();
3001                t[1].resetContext();
3002
3003                t[2].switchTransactionContext();
3004                t_util.t_checkFetch(c[2], rh[2][j], REC_006);
3005                t[2].resetContext();
3006
3007                t[3].switchTransactionContext();
3008                t_util.t_checkFetch(c[3], rh[3][j], REC_006);
3009                t[3].resetContext();
3010
3011                t[4].switchTransactionContext();
3012                t_util.t_checkFetch(c[4], rh[4][j], REC_006);
3013                t[4].resetContext();
3014            }
3015
3016
3017            REPORT("setup S203: numtrans " + numtrans + " numpages " + numpages);
3018
3019            for (i = 0; i < numtrans; i++)
3020            {
3021                String JavaDoc str = "container " + i + ":" + cid[i] + " pages: ";
3022                register(key(203, i+10), cid[i]);
3023
3024                for (j = 0; j < numpages; j++)
3025                {
3026                    str += pagenum[i][j] + " ";
3027                    register(key(203, (i+1)*1000+j), pagenum[i][j]);
3028                }
3029                REPORT("\t" + str);
3030            }
3031
3032            register(key(203,1), numtrans);
3033            register(key(203,2), numpages);
3034
3035        }
3036        finally
3037        {
3038            for (i = 0; i < numtrans; i++)
3039            {
3040                for (j =0; j < numpages; j++)
3041                {
3042                    if (page != null && page[i][j] != null
3043                        && page[i][j].isLatched())
3044                        page[i][j].unlatch();
3045                }
3046            }
3047        }
3048
3049        // let recovery rollback incomplete transactions t0 and t3
3050

3051    }
3052
3053
3054    /* recover test 203 */
3055    protected void R203() throws T_Fail, StandardException
3056    {
3057        int numtrans = (int)find(key(203, 1));
3058        int numpages = (int)find(key(203, 2));
3059        int i,j;
3060        if (numtrans < 5 || numpages < 1)
3061        {
3062            REPORT("R203 not run");
3063            return;
3064        }
3065        else
3066        {
3067            REPORT("R203 started, numtrans " + numtrans + " numpages " +
3068                  numpages );
3069        }
3070
3071        Transaction t = t_util.t_startTransaction();
3072
3073        try
3074        {
3075
3076            long[] cid = new long[numtrans];
3077            ContainerHandle[] c = new ContainerHandle[numtrans];
3078
3079            long[][] pagenum = new long[numtrans][numpages];
3080            Page[][] page = new Page[numtrans][numpages];
3081
3082
3083            for (i = 0; i < numtrans; i++)
3084            {
3085
3086                cid[i] = find(key(203, i+10));
3087                c[i] = t_util.t_openContainer(t, 0, cid[i], true);
3088            
3089                for (j = 0; j < numpages; j++)
3090                {
3091                    pagenum[i][j] = find(key(203, (i+1)*1000+j));
3092
3093                    if (SanityManager.DEBUG)
3094                    {
3095                        if (i == 0 && j == (numpages-1))
3096                        {
3097                            SanityManager.DEBUG_SET("TEST_BAD_CHECKSUM");
3098                            Page p = null;
3099                            try {
3100                                p = c[i].getPage(pagenum[i][j]);
3101                            } catch (StandardException se) {
3102
3103                                if (se.getMessageId().equals(SQLState.FILE_IO_GARBLED))
3104                                    REPORT("bad checksum tested");
3105                                else
3106                                    throw se; // not expected
3107
}
3108                            SanityManager.DEBUG_CLEAR("TEST_BAD_CHECKSUM");
3109                            if (p != null)
3110                                throw T_Fail.testFailMsg("failed to generate expected error with bad checksum");
3111                        }
3112                    }
3113
3114                    page[i][j] = t_util.t_getPage(c[i], pagenum[i][j]);
3115                }
3116            }
3117
3118
3119            // transactions were left in the following state
3120
// t0 - incomplete (rolled back)
3121
// t1 - abort
3122
// t2 - commit
3123
// t3 - incomplete (rolled back)
3124
// t4 - commit
3125
// any other transactions - incomplete
3126
//
3127
// all the rolled back transaction should have a deleted REC_001
3128
// all the committed transactions should have a REC_006
3129
//
3130
for (j = 0; j < numpages; j++)
3131            {
3132                t_util.t_checkRecordCount(page[0][j], 1, 0);
3133                t_util.t_checkFetchBySlot(page[0][j], Page.FIRST_SLOT_NUMBER,
3134                                          REC_001, true, true);
3135
3136                t_util.t_checkRecordCount(page[1][j], 1, 0);
3137                t_util.t_checkFetchBySlot(page[1][j], Page.FIRST_SLOT_NUMBER,
3138                                          REC_001, true, true);
3139
3140                t_util.t_checkRecordCount(page[2][j], 1, 1);
3141                t_util.t_checkFetchBySlot(page[2][j], Page.FIRST_SLOT_NUMBER,
3142                                          REC_006, false, true);
3143
3144                t_util.t_checkRecordCount(page[3][j], 1, 0);
3145                t_util.t_checkFetchBySlot(page[3][j], Page.FIRST_SLOT_NUMBER,
3146                                          REC_001, true, true);
3147
3148                t_util.t_checkRecordCount(page[4][j], 1, 1);
3149                t_util.t_checkFetchBySlot(page[4][j], Page.FIRST_SLOT_NUMBER,
3150                                          REC_006, false, true);
3151            }
3152
3153            for (i = 0; i < numtrans; i++)
3154            {
3155                String JavaDoc str = "container " + i + ":" + cid[i] + " pages: ";
3156                for (j = 0; j < numpages; j++)
3157                    str += pagenum[i][j] + " ";
3158                REPORT("\t" + str);
3159            }
3160        }
3161        finally
3162        {
3163            t_util.t_commit(t);
3164            t.close();
3165        }
3166        PASS("R203: numtrans " + numtrans + " numpages " + numpages);
3167    }
3168
3169    /*
3170     * test 204 - incomplete and committed and aborted internal transactions
3171     */

3172    protected void S204() throws T_Fail, StandardException
3173    {
3174        // start 2 user transaction, then 2 internal transaction, then
3175
// another user transaction.
3176
// do some work on all 5 transactions
3177
// roll back one of the internal transaction
3178
// commit the other one
3179
// do some more work on the 2 internal transactions and let
3180
// recovery roll them all back
3181
T_TWC ut1 = t_util.t_startTransactionWithContext();
3182        T_TWC ut2 = t_util.t_startTransactionWithContext();
3183        Page p10, p11, p20, p21, p30;
3184        p10 = p11 = p20 = p21 = p30 = null;
3185
3186        try
3187        {
3188
3189            long cid10 = t_util.t_addContainer(ut1, 0);
3190            long cid11 = t_util.t_addContainer(ut1, 0);
3191            t_util.t_commit(ut1);
3192
3193            long cid20 = t_util.t_addContainer(ut2, 0);
3194            long cid21 = t_util.t_addContainer(ut2, 0);
3195            t_util.t_commit(ut2);
3196
3197            T_RawStoreRow row = new T_RawStoreRow(REC_001);
3198
3199        // all three user transactions have committed.
3200
//
3201
// container used by row row
3202
// cid10 ut1 r10
3203
// cid11 it1 r11 commit r12
3204
// cid20 ut2 r20
3205
// cid21 it2 r21 abort r22
3206
// cid30 ut3 r30
3207
// (ut3 is started after everything is done)
3208
// after recovery, r11 is the only record
3209

3210            ut1.switchTransactionContext();
3211
3212            ContainerHandle c10 = t_util.t_openContainer(ut1, 0, cid10, true);
3213            p10 = t_util.t_addPage(c10);
3214            RecordHandle r10 = t_util.t_insert(p10, row);
3215
3216            Transaction it1 = t_util.t_startInternalTransaction();
3217            ContainerHandle c11 = t_util.t_openContainer(it1, 0, cid11, true);
3218            p11 = t_util.t_addPage(c11);
3219            RecordHandle r11 = t_util.t_insert(p11, row);
3220            ut1.resetContext();
3221
3222            ut2.switchTransactionContext();
3223            ContainerHandle c20 = t_util.t_openContainer(ut2, 0, cid20, true);
3224            p20 = t_util.t_addPage(c20);
3225            RecordHandle r20 = t_util.t_insert(p20, row);
3226
3227            Transaction it2 = t_util.t_startInternalTransaction();
3228            ContainerHandle c21 = t_util.t_openContainer(it2, 0, cid21, true);
3229            p21 = t_util.t_addPage(c21);
3230            RecordHandle r21 = t_util.t_insert(p21, row);
3231            ut2.resetContext();
3232
3233        // r10, r1, r20, r21, r30 inserted by the corresponding transactions
3234

3235        // commit it1 - it uses the same context manager as ut1
3236
ut1.switchTransactionContext();
3237            it1.commit();
3238
3239        // container is left opened and page p11 is left latched
3240
t_util.t_checkFetch(p11, r11, REC_001);
3241
3242            // use it1 to add another row
3243
T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3244            RecordHandle r12 = t_util.t_insert(p11, row2);
3245            t_util.t_checkFetch(p11, r12, REC_002);
3246            ut1.resetContext();
3247
3248            // abort it2 - it uses the same context maanger as ut2
3249
ut2.switchTransactionContext();
3250            it2.abort();
3251            
3252        // need to reopen container
3253
c21 = t_util.t_openContainer(it2, 0, cid21, true);
3254            p21 = t_util.t_getLastPage(c21);
3255            RecordHandle r22 = t_util.t_insert(p21, row2);
3256            ut2.resetContext();
3257
3258            // start ut3 at the end to test
3259
// internal transactions are rolled back first
3260

3261            T_TWC ut3 = t_util.t_startTransactionWithContext();
3262            long cid30 = t_util.t_addContainer(ut3, 0);
3263            t_util.t_commit(ut3);
3264
3265            ContainerHandle c30 = t_util.t_openContainer(ut3, 0, cid30, true);
3266
3267            ut3.switchTransactionContext();
3268            p30 = t_util.t_addPage(c30);
3269            RecordHandle r30 = t_util.t_insert(p30, row);
3270            ut3.resetContext();
3271
3272            register(key(204, 10), cid10);
3273            register(key(204, 11), cid11);
3274            register(key(204, 20), cid20);
3275            register(key(204, 21), cid21);
3276            register(key(204, 30), cid30);
3277
3278            REPORT("setup S204: cid10 " + cid10 +
3279                   ", cid11 " + cid11 +
3280                   ", cid20 " + cid20 +
3281                   ", cid21 " + cid21 +
3282                   ", cid30 " + cid30);
3283
3284        }
3285        finally
3286        {
3287            if (p10 != null && p10.isLatched())
3288                p10.unlatch();
3289
3290            if (p11 != null && p11.isLatched())
3291                p11.unlatch();
3292
3293            if (p20 != null && p20.isLatched())
3294                p20.unlatch();
3295
3296            if (p21 != null && p21.isLatched())
3297                p21.unlatch();
3298
3299            if (p30 != null && p30.isLatched())
3300                p30.unlatch();
3301        }
3302            // let recovery rollback incomplete transactions
3303

3304    }
3305
3306    /*
3307     * test recovery of 204
3308     */

3309    protected void R204() throws T_Fail, StandardException
3310    {
3311        long cid10 = find(key(204, 10));
3312        if (cid10 < 0)
3313        {
3314            REPORT("R204 not run");
3315            return;
3316        }
3317
3318        long cid11 = find(key(204, 11));
3319        long cid20 = find(key(204, 20));
3320        long cid21 = find(key(204, 21));
3321        long cid30 = find(key(204, 30));
3322
3323        Transaction t = t_util.t_startTransaction();
3324        try
3325        {
3326            ContainerHandle c;
3327            Page p;
3328
3329            c = t_util.t_openContainer(t, 0, cid10, false);
3330            p = t_util.t_getLastPage(c);
3331            t_util.t_checkRecordCount(p, 1, 0);
3332            p.unlatch();
3333
3334            c = t_util.t_openContainer(t, 0, cid11, false);
3335            p = t_util.t_getLastPage(c);
3336            t_util.t_checkRecordCount(p, 2, 1); // r11 is the only record that is not rolled back
3337
p.unlatch();
3338
3339            c = t_util.t_openContainer(t, 0, cid20, false);
3340            p = t_util.t_getLastPage(c);
3341            t_util.t_checkRecordCount(p, 1, 0);
3342            p.unlatch();
3343
3344            c = t_util.t_openContainer(t, 0, cid21, false);
3345            p = t_util.t_getLastPage(c);
3346            t_util.t_checkRecordCount(p, 2, 0);
3347            p.unlatch();
3348
3349            c = t_util.t_openContainer(t, 0, cid30, false);
3350            p = t_util.t_getLastPage(c);
3351            t_util.t_checkRecordCount(p, 1, 0);
3352            p.unlatch();
3353        }
3354        finally
3355        {
3356            t_util.t_commit(t);
3357            t.close();
3358        }
3359
3360        PASS("R204 passed: cid10 " + cid10 +
3361               ", cid11 " + cid11 +
3362               ", cid20 " + cid20 +
3363               ", cid21 " + cid21 +
3364               ", cid30 " + cid30);
3365    }
3366
3367    /*
3368     * test 300 - incomplete transaction with drop containers
3369     */

3370    protected void S300() throws T_Fail, StandardException
3371    {
3372        T_TWC ctx = t_util.t_startTransactionWithContext();
3373        Transaction t = ctx.tran;
3374
3375        try
3376        {
3377            long cid = t_util.t_addContainer(t, 0);
3378            t_util.t_commit(t);
3379
3380            t_util.t_openContainer(t, 0, cid, true);
3381            t_util.t_dropContainer(t, 0, cid);
3382
3383            REPORT("setup S300: containerId " + cid);
3384
3385            register(key(300, 1), cid);
3386        }
3387        catch (StandardException se)
3388        {
3389            t_util.t_abort(t);
3390            t.close();
3391            throw se;
3392        }
3393        catch (T_Fail tf)
3394        {
3395            t_util.t_abort(t);
3396            t.close();
3397            throw tf;
3398        }
3399
3400        // let recovery rollback incomplete transaction
3401
}
3402
3403    /*
3404     * test recovery of 300
3405     */

3406    protected void R300() throws T_Fail, StandardException
3407    {
3408        long cid = find(key(300, 1));
3409        if (cid < 0)
3410        {
3411            REPORT("R300 not run");
3412            return;
3413        }
3414
3415        Transaction t = t_util.t_startTransaction();
3416        // recovery should have rolled back the dropped container
3417
t_util.t_openContainer(t, 0, cid, true);
3418
3419        t_util.t_commit(t);
3420        t.close();
3421
3422        PASS("R300 : containerId " + cid);
3423
3424    }
3425
3426    /*
3427     * incomplete transactions with create container
3428     */

3429    protected void S301() throws T_Fail, StandardException
3430    {
3431        T_TWC ctx = t_util.t_startTransactionWithContext();
3432        Transaction t = ctx.tran;
3433        Page page = null;
3434        ctx.switchTransactionContext();
3435
3436        try
3437        {
3438
3439            long cid1 = t_util.t_addContainer(t, 0);
3440            ContainerHandle c1 = t_util.t_openContainer(t, 0, cid1, true);
3441            page = t_util.t_addPage(c1);
3442            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3443            RecordHandle r1 = t_util.t_insert(page, row1);
3444
3445            t.abort();
3446
3447            ContainerKey id1 = new ContainerKey(0, cid1);
3448            c1 = t.openContainer(id1, ContainerHandle.MODE_READONLY);
3449            if (c1 != null)
3450                throw T_Fail.testFailMsg("expect container to be dropped");
3451
3452            LockingPolicy nolock =
3453                t.newLockingPolicy(LockingPolicy.MODE_NONE, 0, false);
3454
3455            RawContainerHandle stub =
3456                ((RawTransaction)t).openDroppedContainer(
3457                    new ContainerKey(0, cid1), nolock);
3458            
3459            /*Not true always after fix for p4#25641(fix for bug:4580)
3460              Checkpoint calls cleans up the stubs that not necessary
3461              for recovery.
3462              if (stub == null)
3463              throw T_Fail.testFailMsg("drop container should still be there");
3464            */

3465            if(stub!=null)
3466                if (stub.getContainerStatus() != RawContainerHandle.COMMITTED_DROP)
3467                    throw T_Fail.testFailMsg("expect container to be committed dropped");
3468
3469            long cid2 = t_util.t_addContainer(t, 0);
3470            ContainerHandle c2 = t_util.t_openContainer(t, 0, cid2, true);
3471            page = t_util.t_addPage(c2);
3472            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3473            RecordHandle r2 = t_util.t_insert(page, row2);
3474
3475            REPORT("setup S301: cid1 " + cid1 + " cid2 " + cid2);
3476            register(key(301, 1), cid1);
3477            register(key(301, 2), cid2);
3478
3479        }
3480        finally
3481        {
3482            if (page != null && page.isLatched())
3483                page.unlatch();
3484            ctx.resetContext();
3485        }
3486        // let recovery rollback incomplete transaction
3487
}
3488
3489    /*
3490     * test recovery of 301
3491     */

3492    protected void R301() throws T_Fail, StandardException
3493    {
3494        long cid1 = find(key(301, 1));
3495        if (cid1 < 0)
3496        {
3497            REPORT("R301 not run");
3498            return;
3499        }
3500
3501        long cid2 = find(key(301, 2));
3502
3503        Transaction t = t_util.t_startTransaction();
3504        try
3505        {
3506            LockingPolicy nolock =
3507                t.newLockingPolicy(LockingPolicy.MODE_NONE, 0, false);
3508
3509            ContainerKey id1 = new ContainerKey(0, cid1);
3510            ContainerHandle c = t.openContainer(id1, ContainerHandle.MODE_READONLY);
3511            if (c != null)
3512                throw T_Fail.testFailMsg("expect container to be dropped");
3513
3514            RawContainerHandle stub = ((RawTransaction)t).openDroppedContainer(
3515                id1, nolock);
3516            /*Not true always after fix for p4#25641(fix for bug:4580)
3517              Checkpoint calls cleans up the stubs that not necessary
3518              for recovery.
3519              if (stub == null)
3520              throw T_Fail.testFailMsg("drop container should still be there");
3521            */

3522            if(stub!=null)
3523                if (stub.getContainerStatus() != RawContainerHandle.COMMITTED_DROP)
3524                    throw T_Fail.testFailMsg("expect container to be committed dropped");
3525
3526            ContainerKey id2 = new ContainerKey(0, cid2);
3527            c = t.openContainer(id2, ContainerHandle.MODE_READONLY);
3528            if (c != null)
3529                throw T_Fail.testFailMsg("expect container to be dropped");
3530
3531            stub = ((RawTransaction)t).openDroppedContainer(
3532                id2, nolock);
3533            /*Not true always after fix for p4#25641(fix for bug:4580)
3534              Checkpoint calls cleans up the stubs that not necessary
3535              for recovery.
3536              if (stub == null)
3537              throw T_Fail.testFailMsg("drop container should still be there");
3538            */

3539            if(stub!=null)
3540                if (stub.getContainerStatus() != RawContainerHandle.COMMITTED_DROP)
3541                    throw T_Fail.testFailMsg("expect container to be committed dropped");
3542
3543        }
3544        finally
3545        {
3546            t_util.t_commit(t);
3547            t.close();
3548        }
3549
3550        PASS("R301 : cid1 " + cid1 + " cid2 " + cid2);
3551
3552    }
3553
3554
3555    
3556    /*
3557     * test 302 - purge and delete with no data logging for purges
3558     */

3559    protected void S302() throws T_Fail, StandardException
3560    {
3561        Transaction t = t_util.t_startTransaction();
3562
3563        try
3564        {
3565
3566            long cid = t_util.t_addContainer(t, 0);
3567            t_util.t_commit(t);
3568
3569            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3570            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3571
3572            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3573            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3574            T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
3575            T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
3576            T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
3577
3578            long numPurged = 0;
3579
3580            // slot 0
3581
RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1);
3582            // slot 1
3583
RecordHandle r2 = t_util.t_insertAtSlot(page, 1, row2);
3584            // slot 2
3585
RecordHandle r3 = (r2 == null) ? r2 : t_util.t_insertAtSlot(page, 2, row3);
3586            // slot 3
3587
RecordHandle r4 = (r3 == null) ? r3 : t_util.t_insertAtSlot(page, 3, row4);
3588            // slot 4
3589
RecordHandle r5 = (r4 == null) ? r4 : t_util.t_insertAtSlot(page, 4, row5);
3590            if (r5 != null)
3591            {
3592                page.delete(r5, (LogicalUndo)null);
3593            }
3594
3595            t_util.t_commit(t);
3596            
3597            c = t_util.t_openContainer(t, 0, cid, true);
3598            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3599            //do some purging now
3600
// purge slot 0
3601
page.purgeAtSlot(0, 1, false);
3602            // purge slot 1 and 2 3
3603
page.purgeAtSlot(0, 3, false);
3604            t_util.t_abort(t);
3605            c = t_util.t_openContainer(t, 0, cid, true);
3606            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3607            //repurge the rows that got rolled back.
3608
page.purgeAtSlot(0, 1, false);
3609            numPurged++;
3610            if (r5 != null)
3611            {
3612                // purge slot 1 and 2
3613
page.purgeAtSlot(0, 2, false);
3614                numPurged += 2;
3615            }
3616
3617            REPORT("setup S302: containerId " + cid + " recordCount " +
3618                   page.recordCount() + " numPurges " + numPurged);
3619
3620            register(key(302,1), cid);
3621            register(key(302,2), page.recordCount());
3622            register(key(302,3), numPurged);
3623
3624            page.unlatch();
3625        }
3626        finally
3627        {
3628            t_util.t_commit(t);
3629            t.close();
3630        }
3631    }
3632
3633    /* recover test 302 */
3634    protected void R302() throws T_Fail, StandardException
3635    {
3636        long cid = find(key(302,1));
3637        if (cid < 0)
3638        {
3639            REPORT("R302 not run");
3640            return;
3641        }
3642        int recordCount = (int)find(key(302,2));
3643        int numPurged = (int)find(key(302,3));
3644
3645        Transaction t = t_util.t_startTransaction();
3646        try
3647        {
3648            ContainerHandle c = t_util.t_openContainer(t, 0, cid, false);
3649            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3650
3651            t_util.t_checkRecordCount(page, recordCount, 1);
3652
3653            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3654            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3655            T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
3656            T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
3657            T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
3658
3659            t_util.t_checkFetchBySlot(page, 1, REC_005, true, false);
3660            if (!page.isDeletedAtSlot(1))
3661                throw T_Fail.testFailMsg("record should be deleted");
3662            //REC_004 should have become a null value because of rollback of purge
3663
t_util.t_checkFetchBySlot(page, 0, "NULL", false, false);
3664            page.unlatch();
3665        }
3666        finally
3667        {
3668            t_util.t_commit(t);
3669            t.close();
3670        }
3671
3672        PASS("R302: containerId " + cid + " recordCount " +
3673               recordCount + " numPurges " + numPurged);
3674    }
3675
3676
3677        
3678    /**
3679        Test space reclaimation - purging of a row with serveral long columns
3680        rollback and repurge them again.
3681
3682        @exception T_Fail Unexpected behaviour from the API
3683        @exception StandardException Unexpected exception from the implementation
3684     */

3685    protected void S303() throws StandardException, T_Fail
3686    {
3687        REPORT("START S303");
3688        long segment = 0;
3689        T_TWC ctx = t_util.t_startTransactionWithContext();
3690        Transaction t = ctx.tran;
3691        ctx.switchTransactionContext();
3692
3693        long cid = t_util.t_addContainer(t, segment, 4096);
3694        ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
3695        Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3696        try
3697        {
3698            t_util.t_checkEmptyPage(page);
3699
3700            int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
3701            T_RawStoreRow r1 = new T_RawStoreRow(1);
3702            // insert a long column
3703
r1.setColumn(0, 5000, REC_001);
3704            RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
3705            t_util.t_checkFetch(page, rh1, r1);
3706
3707            // insert a 6 column row, every other column is long
3708
T_RawStoreRow r2 = new T_RawStoreRow(6);
3709            r2.setColumn(0, 1600, REC_001); // this takes 3200 bytes
3710
r2.setColumn(1, 4000, REC_002); // this takes 8000 bytes
3711
r2.setColumn(2, 1600, REC_001);
3712            r2.setColumn(3, 4000, REC_002);
3713            r2.setColumn(4, 1600, REC_001);
3714            r2.setColumn(5, 4000, REC_002);
3715            RecordHandle rh2 = t_util.t_insertAtSlot(page, 0, r2, (byte)
3716                                                     insertFlag);
3717            
3718            t_util.t_checkFetch(page, rh2, r2);
3719
3720            // insert a long column - this should fail
3721
RecordHandle rh3 = t_util.t_insertAtSlot(page, 0, r1, (byte) insertFlag);
3722            if (rh3 != null)
3723            {
3724                throw T_Fail.testFailMsg("expect the 3rd row to not fit on page");
3725            }
3726            page.unlatch();
3727            page = null;
3728
3729            Page nextPage = t_util.t_addPage(c);
3730            long nextPageNumber = nextPage.getPageNumber();
3731            // deallocate it
3732
t_util.t_removePage(c, nextPage);
3733
3734            REPORT("S303 - Nextpage is " + nextPageNumber);
3735
3736            t_util.t_commit(t);
3737
3738            // now purge them
3739
c = t_util.t_openContainer(t, segment, cid, true);
3740            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3741
3742            t_util.t_checkRecordCount(page, 2, 2);
3743            page.purgeAtSlot(0, 2, false);
3744            t_util.t_checkEmptyPage(page);
3745            page.unlatch();
3746            page = null;
3747
3748            t_util.t_abort(t);
3749
3750            // give some time for post commit to finish
3751
t_util.t_wait(10); // wait 10 milliseconds.
3752

3753
3754            // Purge them again and roll them back via recovery. These should not
3755
// be reclaimed.
3756
c = t_util.t_openContainer(t, segment, cid, true);
3757            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3758            t_util.t_checkRecordCount(page, 2, 2);
3759            int rh1slotnumber = page.getSlotNumber(rh1);
3760            int rh2slotnumber = page.getSlotNumber(rh2);
3761            page.purgeAtSlot(0, 2, false);
3762            t_util.t_checkEmptyPage(page);
3763
3764            page.unlatch();
3765            page = null;
3766
3767            REPORT("S303 - Purged Slots" + rh1slotnumber + "," + rh2slotnumber);
3768
3769            register(key(303,1), cid);
3770            register(key(303,2), rh1slotnumber);
3771            register(key(303,3), rh2slotnumber);
3772            
3773            // let recovery undo rollback this transaction
3774
}
3775        finally
3776        {
3777            if (page != null)
3778                page.unlatch();
3779            ctx.resetContext();
3780        }
3781
3782        PASS("S303");
3783    }
3784
3785    
3786    /* recover test 303:
3787     * repurge the same rows whose purging we rolled back in s303.
3788     */

3789    protected void R303() throws T_Fail, StandardException
3790    {
3791        long cid = find(key(303,1));
3792        if (cid < 0)
3793        {
3794            REPORT("R303 not run");
3795            return;
3796        }
3797
3798        Transaction t = t_util.t_startTransaction();
3799        try
3800        {
3801            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3802            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3803            t_util.t_checkRecordCount(page, 2, 2);
3804            int r1slot = (int)find(key(303,2));
3805            int r2slot = (int)find(key(303,3));
3806            T_RawStoreRow r1 = new T_RawStoreRow(1);
3807            // insert a long column
3808
r1.setColumn(0, 5000, REC_001);
3809            // During purges when data is not logged when slots are purged
3810
// they become null on rollback and some cases like long columns
3811
// we remove the wholepage on rollback we get the data back.
3812
T_RawStoreRow r2_wnl = new T_RawStoreRow(6);
3813            r2_wnl.setColumn(0, 4, REC_NULL);
3814            r2_wnl.setColumn(1, 4000, REC_002);
3815            r2_wnl.setColumn(2, 1600, REC_001);
3816            r2_wnl.setColumn(3, 4000, REC_002);
3817            r2_wnl.setColumn(4, 1600, REC_001);
3818            r2_wnl.setColumn(5, 4000, REC_002);
3819            RecordHandle rh1 = page.getRecordHandleAtSlot(r1slot) ;
3820
3821            t_util.t_checkFetch(page, rh1, r1);
3822            RecordHandle rh2 = page.getRecordHandleAtSlot(r2slot) ;
3823            t_util.t_checkFetch(page, rh2, r2_wnl);
3824
3825            //purge after the recovery.
3826
page.purgeAtSlot(0, 2, false);
3827            
3828            page.unlatch();
3829            page = null;
3830        }
3831        finally
3832        {
3833            t_util.t_commit(t);
3834            t.close();
3835        }
3836
3837        PASS("R303");
3838    }
3839
3840
3841
3842        
3843    /**
3844        Test space reclaimation - purging of a long rows with a rollback and
3845        purging again after recovery in R304
3846        @exception T_Fail Unexpected behaviour from the API
3847        @exception StandardException Unexpected exception from the implementation
3848     */

3849    protected void S304() throws StandardException, T_Fail
3850    {
3851        long segment = 0;
3852        T_TWC ctx = t_util.t_startTransactionWithContext();
3853        Transaction t = ctx.tran;
3854        ctx.switchTransactionContext();
3855
3856        long cid = t_util.t_addContainer(t, segment, 4096);
3857        ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
3858        Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3859        try
3860        {
3861            t_util.t_checkEmptyPage(page);
3862
3863            int insertFlag = Page.INSERT_INITIAL | Page.INSERT_OVERFLOW;
3864
3865            // insert a row with 100 columns from 200 to 400 bytes each and make it
3866
// sprawl across many pages.
3867
T_RawStoreRow r1 = new T_RawStoreRow(100);
3868            for (int i = 0; i < 100; i++)
3869                r1.setColumn(i, 100+i, REC_001);
3870
3871            RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, r1, (byte)insertFlag);
3872            t_util.t_checkFetch(page, rh1, r1);
3873            page.unlatch();
3874            page = null;
3875            t_util.t_commit(t);
3876
3877            c = t_util.t_openContainer(t, segment, cid, true);
3878            // Now purge that long row.
3879
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3880            t_util.t_checkRecordCount(page, 1, 1);
3881            page.purgeAtSlot(0, 1, false);
3882            t_util.t_checkEmptyPage(page);
3883            page.unlatch();
3884            page = null;
3885            // let recovery undo rollback this transaction
3886
register(key(304,1), cid);
3887
3888        }
3889        finally
3890        {
3891            if (page != null)
3892                page.unlatch();
3893            ctx.resetContext();
3894        }
3895
3896        PASS("S304");
3897    }
3898
3899    /* recover test 304:
3900     * repurge the same rows whose purging we rolled back in s304 at recovery.
3901     */

3902    protected void R304() throws T_Fail, StandardException
3903    {
3904        long cid = find(key(304,1));
3905        if (cid < 0)
3906        {
3907            REPORT("R304 not run");
3908            return;
3909        }
3910
3911        Transaction t = t_util.t_startTransaction();
3912        try
3913        {
3914            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3915            Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3916            t_util.t_checkRecordCount(page, 1, 1);
3917
3918            // During purges when data is not logged when slots are purged
3919
// they become null on rollback and some cases like long columns
3920
// we remove the wholepage on rollback we get the data back.
3921
T_RawStoreRow r1_wnl = new T_RawStoreRow(100);
3922            for (int i = 0; i < 18; i++)
3923                r1_wnl.setColumn(i, 4, REC_NULL);
3924            for (int i = 18; i < 100; i++)
3925                r1_wnl.setColumn(i, 100+i, REC_001);
3926            RecordHandle rh1 = page.getRecordHandleAtSlot(0) ;
3927            t_util.t_checkFetch(page, rh1, r1_wnl);
3928
3929            //purge after the recovery.
3930
page.purgeAtSlot(0, 1, false);
3931            page.unlatch();
3932            page = null;
3933        }
3934        finally
3935        {
3936            t_util.t_commit(t);
3937            t.close();
3938        }
3939
3940        PASS("R304");
3941    }
3942
3943
3944    /*
3945     * S999 - last test of the recovery unit test, this leave the end of the
3946     * log in a fuzzy state, do NOT write any more log record after this or
3947     * you will corrupt the database
3948     *
3949     * DO NOT run this test if recovery test is ever run iteratively
3950     */

3951    protected void S999() throws T_Fail, StandardException
3952    {
3953        // only runnable in debug server since trace flags are set by SanityManager
3954
if (!SanityManager.DEBUG)
3955            return;
3956
3957        T_TWC ctx = t_util.t_startTransactionWithContext();
3958        Transaction t = ctx.tran;
3959        ctx.switchTransactionContext();
3960
3961        // LogToFile.TEST_LOG_SWITCH_LOG
3962
SanityManager.DEBUG_SET("TEST_LOG_SWITCH_LOG");
3963
3964        // this will switch the log without writing out a checkpoint log record
3965
factory.checkpoint();
3966        Page page = null;
3967
3968        try
3969        {
3970            long cid = t_util.t_addContainer(t, 0);
3971            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
3972            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3973
3974            T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
3975            RecordHandle rh1 = t_util.t_insertAtSlot(page, 0, row1);
3976            t_util.t_commit(t);
3977
3978            T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
3979            c = t_util.t_openContainer(t, 0, cid, true);
3980            page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
3981
3982            RecordHandle rh2 = t_util.t_insertAtSlot(page, 1, row2);
3983            if (rh2 == null)
3984            {
3985                REPORT("S999 not run, page cannot accomodate 2 rows");
3986                return;
3987            }
3988
3989
3990            t_util.t_checkRecordCount(page, 2, 2);
3991            t_util.t_checkFetch(page, rh1, REC_001);
3992            t_util.t_checkFetch(page, rh2, REC_002);
3993
3994            T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
3995
3996            // LogToFile.TEST_LOG_INCOMPLETE_LOG_WRITE
3997
SanityManager.DEBUG_SET("TEST_LOG_INCOMPLETE_LOG_WRITE");
3998
3999            // let's hope that this page is not written to disk... can't until
4000
// the page is unlatch, and we never unlatch it
4001
RecordHandle rh3 = t_util.t_insert(page, row3); // this is written out incompletely
4002
if (rh3 == null) {
4003                REPORT("S999 not run, page cannot accomodate 3 rows");
4004                return;
4005            }
4006
4007
4008            t_util.t_checkRecordCount(page, 3, 3);
4009            t_util.t_checkFetch(page, rh3, REC_003);
4010
4011            REPORT("setup S999: cid1 " + cid + " page " + page.getPageNumber());
4012            register(key(999, 1), cid);
4013            register(key(999, 2), page.getPageNumber());
4014        }
4015        finally
4016        {
4017            SanityManager.DEBUG_CLEAR("TEST_LOG_SWITCH_LOG");
4018            SanityManager.DEBUG_CLEAR("TEST_LOG_INCOMPLETE_LOG_WRITE");
4019
4020            ctx.resetContext();
4021            // let recovery roll it back
4022
}
4023    }
4024
4025    protected void R999() throws StandardException, T_Fail
4026    {
4027        long cid = find(key(999,1));
4028        if (cid < 0)
4029        {
4030            REPORT("R999 not run");
4031            return;
4032        }
4033
4034        long pageid = find(key(999,2));
4035        Transaction t = t_util.t_startTransaction();
4036        try
4037        {
4038            ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
4039            Page page = t_util.t_getPage(c, pageid);
4040
4041            // there should be 2 rows on the page, 1 undelete and 1 deleted.
4042
// The third row is only partially written out the log and should
4043
// never appear
4044
t_util.t_checkRecordCount(page, 2, 1);
4045            t_util.t_checkFetchBySlot(page, 0, REC_001, false, false);
4046            t_util.t_checkFetchBySlot(page, 1, REC_002, true, false);
4047        }
4048        finally
4049        {
4050            t_util.t_commit(t);
4051            t.close();
4052        }
4053        PASS("R999: cid " + cid + " page " + pageid);
4054
4055    }
4056
4057}
4058
4059
4060
4061
Popular Tags