KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derbyTesting.unitTests.store.T_b2i
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 // impl imports are the preferred way to create unit tests.
25
import org.apache.derbyTesting.unitTests.harness.T_MultiIterations;
26 import org.apache.derbyTesting.unitTests.harness.T_Fail;
27
28 import org.apache.derby.impl.store.access.btree.index.*;
29
30 import org.apache.derby.iapi.types.SQLLongint;
31
32 import org.apache.derby.iapi.reference.Property;
33 import org.apache.derby.iapi.reference.SQLState;
34
35 import org.apache.derby.iapi.services.io.FormatableBitSet;
36 import org.apache.derby.iapi.services.i18n.MessageService;
37
38 import org.apache.derby.iapi.services.monitor.Monitor;
39
40 import org.apache.derby.iapi.services.sanity.SanityManager;
41 import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
42 import org.apache.derby.iapi.services.context.ContextService;
43 import org.apache.derby.iapi.services.context.ContextManager;
44 import org.apache.derby.iapi.services.io.FormatIdUtil;
45
46 import org.apache.derby.iapi.error.StandardException;
47 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
48 import org.apache.derby.iapi.store.access.AccessFactory;
49 import org.apache.derby.iapi.store.access.ConglomerateController;
50 import org.apache.derby.iapi.store.access.Qualifier;
51 import org.apache.derby.iapi.types.RowLocation;
52 import org.apache.derby.iapi.store.access.ScanController;
53 import org.apache.derby.iapi.store.access.ScanInfo;
54 import org.apache.derby.iapi.store.access.TransactionController;
55 import org.apache.derby.iapi.store.access.RowUtil;
56 import org.apache.derby.iapi.store.access.ColumnOrdering;
57
58 import org.apache.derby.iapi.store.raw.ContainerHandle;
59 import org.apache.derby.iapi.store.raw.LockingPolicy;
60 import org.apache.derby.iapi.store.raw.RawStoreFactory;
61
62 import org.apache.derby.iapi.types.DataValueDescriptor;
63
64 import org.apache.derby.impl.store.access.btree.BTree;
65 import org.apache.derby.impl.store.access.conglomerate.TemplateRow;
66 import org.apache.derby.iapi.types.SQLChar;
67
68
69 import java.util.Properties JavaDoc;
70
71
72
73 public class T_b2i extends T_MultiIterations
74 {
75
76     private static final String JavaDoc testService = "b2iTest";
77
78     private Object JavaDoc store_module = null;
79
80     private ContextService contextService = null;
81
82     /* Methods required by T_MultiIterations */
83
84
85     /**
86      * Routine one once per invocation of the test by the driver.
87      * <p>
88      * Do work that should only be done once, no matter how many times
89      * runTests() may be executed.
90      *
91      * @exception T_Fail Thrown on any error.
92      **/

93     protected void setupTest()
94         throws T_Fail
95     {
96         // don't automatic boot this service if it gets left around
97
if (startParams == null) {
98             startParams = new Properties JavaDoc();
99         }
100         startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
101         // remove the service directory to ensure a clean run
102
startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString());
103
104         // see if we are testing encryption
105
startParams = T_Util.setEncryptionParam(startParams);
106
107
108         try {
109             store_module = Monitor.createPersistentService(
110                 getModuleToTestProtocolName(), testService, startParams);
111             
112             contextService = ContextService.getFactory();
113
114         } catch (StandardException mse) {
115             throw T_Fail.exceptionFail(mse);
116         }
117     }
118
119     /*
120     ** Methods required by T_Generic
121     */

122
123     public String JavaDoc getModuleToTestProtocolName() {
124         return AccessFactory.MODULE;
125     }
126
127     /**
128      * Driver routine for the btree secondary index tests.
129      * <p>
130      *
131      * @exception T_Fail Throws T_Fail on any test failure.
132      **/

133     protected void runTestSet() throws T_Fail
134     {
135         AccessFactory store = null;
136         TransactionController tc = null;
137         boolean pass = false;
138
139         out.println("executing b2i test");
140
141         store = (AccessFactory) store_module;
142
143         if (store == null)
144         {
145             throw T_Fail.testFailMsg(
146                     getModuleToTestProtocolName() + " service not started.");
147         }
148
149         ContextManager cm1 = contextService.newContextManager();
150         contextService.setCurrentContextManager(cm1);
151
152         REPORT("(unitTestMain) Testing " + testService);
153
154         try {
155
156             tc = store.getTransaction(cm1);
157
158                 pass = true;
159
160             if (
161                 t_005(tc) &&
162                 t_001(tc) &&
163                 t_003(tc) &&
164                 t_004(tc) &&
165                 t_005(tc) &&
166                 t_006(tc) &&
167                 t_009(tc) &&
168                 t_010(tc) &&
169                 t_011(tc) &&
170                 t_012(tc) &&
171                 t_013(tc) &&
172                 t_014(tc) &&
173                 t_017(tc) &&
174                 t_018(tc) &&
175                 t_019(tc) &&
176                 t_020(tc)
177                 )
178                 
179             {
180                 pass = true;
181
182                 if (SanityManager.DEBUG)
183                 {
184                     pass = false;
185
186                     // The following tests depend on SanityManager functionality
187
// so can not be run in an insane server.
188

189                     if (t_002(tc) &&
190                         t_007(tc) &&
191                         t_008(tc) &&
192                         t_015(tc) &&
193                         t_016(tc)
194                         )
195                         pass = true;
196                 }
197             }
198
199             tc.commit();
200             tc.destroy();
201         }
202         catch (StandardException e)
203         {
204             String JavaDoc msg = e.getMessage();
205             if (msg == null)
206                 msg = e.getClass().getName();
207             REPORT(msg);
208
209             e.printStackTrace(out.getPrintWriter());
210             cm1.cleanupOnError(e);
211
212             pass = false;
213         }
214         catch (Throwable JavaDoc t)
215         {
216             String JavaDoc msg = t.getMessage();
217             if (msg == null)
218                 msg = t.getClass().getName();
219             REPORT(msg);
220
221             t.printStackTrace(out.getPrintWriter());
222             cm1.cleanupOnError(t);
223
224             pass = false;
225         }
226         finally {
227             contextService.resetCurrentContextManager(cm1);
228         }
229
230         if (!pass)
231             throw T_Fail.testFailMsg("");
232     }
233
234     /**
235      * Utility routine to create base table for tests.
236      * <p>
237      * A little utility routine to create base tables for tests. Just
238      * here to make tests a little more readable. It currently just
239      * creates a heap table with "num_cols" SQLLongint columns.
240      *
241      * @return The identifier to be used to open the conglomerate later.
242      *
243      * @param num_cols the number of columns in the base table.
244      *
245      * @exception StandardException Standard exception policy.
246      **/

247
248     void createCongloms(
249     TransactionController tc,
250     int num_cols,
251     boolean unique,
252     boolean varying_first_col,
253     int max_btreerows_per_page,
254     T_CreateConglomRet ret_val)
255         throws StandardException
256     {
257         T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
258         DataValueDescriptor[] base_row = TemplateRow.newU8Row(num_cols);
259
260         if (varying_first_col)
261         {
262             SQLChar string_col = new SQLChar();
263
264             base_row[0] = string_col;
265         }
266
267         long base_conglomid = 0;
268
269         // create the base table
270
base_conglomid =
271             tc.createConglomerate(
272                 "heap", // create a heap conglomerate
273
base_row, // base table template row
274
null, //column sort order - not required for heap
275
null, // default properties
276
TransactionController.IS_DEFAULT);// not temporary
277

278         // Open the base table
279
ConglomerateController base_cc =
280             tc.openConglomerate(
281                 base_conglomid,
282                 false,
283                 TransactionController.OPENMODE_FORUPDATE,
284                 TransactionController.MODE_RECORD,
285                 TransactionController.ISOLATION_SERIALIZABLE);
286
287         // initialize the secondary index row - pointing it at base row
288
RowLocation base_rowloc = base_cc.newRowLocationTemplate();
289         index_row.init(base_row, base_rowloc, num_cols + 1);
290         
291         // create the secondary index
292
Properties JavaDoc properties =
293             createProperties(
294                 null, // no current properties list
295
false, // don't allow duplicates
296
num_cols + 1, // index on all base row cols + row location
297
(unique ? num_cols : num_cols + 1), // non-unique index
298
true, // maintain parent links
299
base_conglomid, // base conglomid
300
num_cols); // row loc in last column
301

302         if (max_btreerows_per_page > 1)
303         {
304             if (BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER != null)
305             {
306                 properties.put(
307                     BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER,
308                     String.valueOf(max_btreerows_per_page));
309             }
310         }
311
312         long index_conglomid =
313             tc.createConglomerate(
314                 "BTREE", // create a btree secondary
315
index_row.getRow(), // index row template
316
null, //column sort order - default
317
properties, // properties
318
TransactionController.IS_DEFAULT); // not temporary
319

320         // return values to caller
321
ret_val.base_conglomid = base_conglomid;
322         ret_val.index_conglomid = index_conglomid;
323         // RESOLVE (mikem - 04/29/98 - why is following line commented out?
324
// ret_val.base_template_row = TemplateRow.newU8Row(num_cols);
325
ret_val.index_template_row = index_row.getRow();
326
327         return;
328     }
329
330     protected static Properties JavaDoc createProperties(
331     Properties JavaDoc input_properties,
332     boolean input_allowduplicates,
333     int input_nkeyfields,
334     int input_nuniquecolumns,
335     boolean input_maintainparentlinks,
336     long input_baseconglomerateid,
337     int input_rowlocationcolumn)
338         throws StandardException
339     {
340         Properties JavaDoc properties =
341             ((input_properties == null) ? new Properties JavaDoc() : input_properties);
342         properties.put(
343             "allowDuplicates", String.valueOf(input_allowduplicates));
344         properties.put(
345             "nKeyFields", String.valueOf(input_nkeyfields));
346         properties.put(
347             "nUniqueColumns", String.valueOf(input_nuniquecolumns));
348         properties.put(
349             "maintainParentLinks", String.valueOf(input_maintainparentlinks));
350         properties.put(
351             "baseConglomerateId", String.valueOf(input_baseconglomerateid));
352         properties.put(
353             "rowLocationColumn", String.valueOf(input_rowlocationcolumn));
354         return(properties);
355     }
356
357     /**
358      * Test a single scan.
359      *
360      * @exception StandardException Standard exception policy.
361      */

362     protected boolean t_scan(
363     TransactionController tc,
364     long conglomid,
365     DataValueDescriptor[] template,
366     DataValueDescriptor[] start_key,
367     int start_op,
368     Qualifier qualifier[][],
369     DataValueDescriptor[] stop_key,
370     int stop_op,
371     int expect_numrows,
372     int expect_key)
373         throws StandardException
374     {
375
376         // open a new scan
377

378         ScanController scan =
379             tc.openScan(
380                 conglomid,
381                 false,
382                 TransactionController.OPENMODE_FORUPDATE,
383                 TransactionController.MODE_RECORD,
384                 TransactionController.ISOLATION_SERIALIZABLE,
385                 (FormatableBitSet) null,
386                 start_key, start_op,
387                 qualifier,
388                 stop_key, stop_op);
389
390         long key = -42;
391         long numrows = 0;
392
393         while (scan.next())
394         {
395             scan.fetch(template);
396
397             key = ((SQLLongint)template[2]).getLong();
398
399             if (key != expect_key)
400             {
401                 return(
402                     FAIL("(t_scan) wrong key, expected (" + expect_key + ")" +
403                      "but got (" + key + ")."));
404             }
405             else
406             {
407                 expect_key++;
408                 numrows++;
409             }
410         }
411
412         ((B2IForwardScan)scan).checkConsistency();
413         
414         scan.close();
415
416         if (numrows != expect_numrows)
417         {
418             return(FAIL("(t_scan) wrong number of rows. Expected " +
419                  expect_numrows + " rows, but got " + numrows + "rows."));
420         }
421
422         return(true);
423     }
424
425     /**
426      * delete a single key, given key value. assumes 3 column table, first
427      * column = 1, second column is a unique key, and 3rd column is a
428      * RecordHandle into the base table.
429      *
430      * @exception StandardException Standard exception policy.
431      */

432     protected boolean t_delete(
433     TransactionController tc,
434     long conglomid,
435     DataValueDescriptor[] search_key,
436     DataValueDescriptor[] template)
437         throws StandardException
438     {
439         SQLLongint column0 = new SQLLongint(-1);
440         SQLLongint column1 = new SQLLongint(-1);
441
442         // open a new scan
443

444         ScanController scan =
445             tc.openScan(conglomid, false,
446                         TransactionController.OPENMODE_FORUPDATE,
447                         TransactionController.MODE_RECORD,
448                         TransactionController.ISOLATION_SERIALIZABLE,
449                         (FormatableBitSet) null,
450                         search_key, ScanController.GE,
451                         null,
452                         search_key, ScanController.GT);
453
454         long expect_key =
455             ((SQLLongint) search_key[1]).getLong();
456
457         int numrows = 0;
458         DataValueDescriptor[] partialRow = new DataValueDescriptor[2];
459         partialRow[0] = column0;
460         partialRow[1] = column1;
461
462         while (scan.next())
463         {
464             numrows++;
465
466             scan.fetch(partialRow);
467
468             if (column0.getLong() != 1)
469                 return(FAIL("(t_delete) column[0] value is not 1"));
470
471             if (column1.getLong() != expect_key)
472                 return(
473                     FAIL("(t_delete) column[1] value is not " + expect_key));
474
475             if (!scan.delete())
476             {
477                 return(FAIL("(t_delete): delete of row failed"));
478             }
479             if (scan.delete())
480             {
481                 return(FAIL("(t_delete): re-delete of row succeeded"));
482             }
483         }
484
485         scan.close();
486
487         // This function expects unique keys, so scan should find single row.
488
if (numrows != 1)
489         {
490             return(FAIL("(t_delete) wrong number of rows. Expected " +
491                    "1 row, but got " + numrows + "rows."));
492         }
493
494         return(true);
495     }
496
497     /**
498      * Test BTreeController.insert()
499      * <p>
500      * Just verify that insert code works for a secondary index. Just call
501      * the interface and make sure the row got there.
502      *
503      * @exception StandardException Standard exception policy.
504      * @exception T_Fail Throws T_Fail on any test failure.
505      **/

506     protected boolean t_001(TransactionController tc)
507         throws StandardException, T_Fail
508     {
509         REPORT("Starting t_001");
510
511         T_CreateConglomRet create_ret = new T_CreateConglomRet();
512
513         createCongloms(tc, 2, false, false, 0, create_ret);
514
515         // Open the base table
516
ConglomerateController base_cc =
517             tc.openConglomerate(
518                 create_ret.base_conglomid,
519                 false,
520                 TransactionController.OPENMODE_FORUPDATE,
521                 TransactionController.MODE_RECORD,
522                 TransactionController.ISOLATION_SERIALIZABLE);
523
524         // Open the secondary index
525
ConglomerateController index_cc =
526             tc.openConglomerate(
527                 create_ret.index_conglomid,
528                 false,
529                 TransactionController.OPENMODE_FORUPDATE,
530                 TransactionController.MODE_RECORD,
531                 TransactionController.ISOLATION_SERIALIZABLE);
532
533         if (!(index_cc instanceof B2IController))
534         {
535             throw T_Fail.testFailMsg("openConglomerate returned wrong type");
536         }
537
538         if (!index_cc.isKeyed())
539         {
540             throw T_Fail.testFailMsg("btree is not keyed.");
541         }
542
543         index_cc.checkConsistency();
544
545         // Create a row and insert into base table, remembering it's location.
546
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
547         T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
548         RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
549
550         index_row1.init(r1, base_rowloc1, 3);
551         ((SQLLongint) r1[0]).setValue(2);
552         ((SQLLongint) r1[1]).setValue(2);
553
554         // Insert the row into the base table and remember its location.
555
base_cc.insertAndFetchLocation(r1, base_rowloc1);
556
557         // Insert the row into the secondary index.
558
if (index_cc.insert(index_row1.getRow()) != 0)
559             throw T_Fail.testFailMsg("insert failed");
560
561         // Make sure we read back the value we wrote from base and index table.
562
DataValueDescriptor[] r2 = TemplateRow.newU8Row(2);
563         T_SecondaryIndexRow index_row2 = new T_SecondaryIndexRow();
564         RowLocation base_rowloc2 = base_cc.newRowLocationTemplate();
565
566         index_row2.init(r2, base_rowloc2, 3);
567
568         // base table check:
569
if (!base_cc.fetch(base_rowloc1, r2, (FormatableBitSet) null))
570         {
571             return(FAIL("(t_001) insert into base table failed"));
572         }
573
574         if (((SQLLongint) r2[0]).getLong() != 2 ||
575             ((SQLLongint) r2[1]).getLong() != 2)
576         {
577             return(FAIL("(t_001) insert into base table failed"));
578         }
579
580         // index check - there should be only one record:
581
ScanController scan =
582             tc.openScan(create_ret.index_conglomid, false,
583                         TransactionController.OPENMODE_FORUPDATE,
584                         TransactionController.MODE_RECORD,
585                         TransactionController.ISOLATION_SERIALIZABLE,
586                         (FormatableBitSet) null,
587                         null, ScanController.NA,
588                         null,
589                         null, ScanController.NA);
590
591         scan.next();
592         scan.fetch(index_row2.getRow());
593
594         // delete the only row in the table, and make sure
595
// isCurrentPositionDeleted() works.
596
if (scan.isCurrentPositionDeleted())
597             throw T_Fail.testFailMsg("current row should not be deleted\n");
598         if (!scan.doesCurrentPositionQualify())
599             throw T_Fail.testFailMsg("current row should still qualify\n");
600         scan.delete();
601         if (!scan.isCurrentPositionDeleted())
602             throw T_Fail.testFailMsg("current row should be deleted\n");
603         if (scan.doesCurrentPositionQualify())
604             throw T_Fail.testFailMsg("deleted row should not qualify\n");
605
606         // just call the debugging code to make sure it doesn't fail.
607
REPORT("Calling scan.tostring(): " + scan);
608
609         if (scan.next() ||
610             ((SQLLongint)(index_row2.getRow()[0])).getLong() != 2 ||
611             ((SQLLongint)(index_row2.getRow()[1])).getLong() != 2)
612         {
613             return(FAIL("(t_001) insert into index failed in base cols"));
614         }
615
616         // test the scaninfo interface.
617

618         ScanInfo scan_info = scan.getScanInfo();
619         Properties JavaDoc prop = scan_info.getAllScanInfo(null);
620
621         if (Integer.parseInt(prop.getProperty(
622            MessageService.getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED)))
623                 != 1)
624         {
625             throw T_Fail.testFailMsg(
626                 "(scanInfo) wrong numPagesVisited. Expected 1, got " +
627                 Integer.parseInt(prop.getProperty(
628                     MessageService.getTextMessage(
629                                 SQLState.STORE_RTS_NUM_PAGES_VISITED))));
630         }
631         if (Integer.parseInt(prop.getProperty(
632             MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED)))
633                 != 1)
634         {
635             throw T_Fail.testFailMsg(
636                 "(scanInfo) wrong numRowsVisited. Expected 1, got " +
637                 Integer.parseInt(prop.getProperty(
638                     MessageService.getTextMessage(
639                                 SQLState.STORE_RTS_NUM_ROWS_VISITED))));
640         }
641         if (Integer.parseInt(prop.getProperty(
642           MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED)))
643                 != 1)
644         {
645             throw T_Fail.testFailMsg(
646                 "(scanInfo) wrong numRowsQualified. Expected 1, got " +
647                 Integer.parseInt(prop.getProperty(
648                     MessageService.getTextMessage(
649                                 SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))));
650         }
651
652
653         int compare_result = base_rowloc1.compare(base_rowloc2);
654         if (compare_result != 0)
655         {
656             return(FAIL("(t_001) insert into index failed in recordhandle.\n" +
657                         "\texpected RecordHandle = " + base_rowloc1 + "\n" +
658                         "\tgot RecordHandle = " + base_rowloc2 +
659                         "\tcompare result = " + compare_result));
660         }
661
662         index_cc.checkConsistency();
663
664         // Close the conglomerates.
665
base_cc.close();
666         index_cc.close();
667
668         try
669         {
670             base_cc.insert(r1);
671             return(FAIL("(t_001) insert on closed conglomerate worked"));
672         }
673         catch (StandardException e)
674         {
675             // e.printStackTrace();
676
}
677
678         try
679         {
680             if (index_cc.insert(r1) != 0)
681                 throw T_Fail.testFailMsg("insert failed");
682             return(FAIL("(t_001) insert on closed conglomerate worked"));
683         }
684         catch (StandardException e)
685         {
686             // e.printStackTrace();
687
}
688
689         tc.commit();
690         REPORT("Ending t_001");
691
692         return true;
693     }
694
695     /**
696      * Test backout during critical times of splits.
697      * <p>
698      * Use trace points to force errors in split at critical points:
699      * leaf_split_abort{1,2,3,4}
700      *
701      * @exception StandardException Standard exception policy.
702      * @exception T_Fail Throws T_Fail on any test failure.
703      **/

704     protected boolean t_002(TransactionController tc)
705         throws StandardException, T_Fail
706     {
707         ScanController scan = null;
708
709         // SanityManager.DEBUG_SET("LockTrace");
710

711         REPORT("Starting t_002");
712
713         T_CreateConglomRet create_ret = new T_CreateConglomRet();
714
715         // Create the btree so that it only allows 2 rows per page.
716
createCongloms(tc, 2, false, false, 2, create_ret);
717
718         // Open the base table
719
ConglomerateController base_cc =
720             tc.openConglomerate(
721                 create_ret.base_conglomid,
722                 false,
723                 TransactionController.OPENMODE_FORUPDATE,
724                 TransactionController.MODE_RECORD,
725                 TransactionController.ISOLATION_SERIALIZABLE);
726
727         // Open the secondary index
728
ConglomerateController index_cc =
729             tc.openConglomerate(
730                 create_ret.index_conglomid,
731                 false,
732                 TransactionController.OPENMODE_FORUPDATE,
733                 TransactionController.MODE_RECORD,
734                 TransactionController.ISOLATION_SERIALIZABLE);
735
736         if (!(index_cc instanceof B2IController))
737         {
738             throw T_Fail.testFailMsg("openConglomerate returned wrong type");
739         }
740
741         index_cc.checkConsistency();
742
743         // Create a row and insert into base table, remembering it's location.
744
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
745         T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
746         RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
747
748         index_row1.init(r1, base_rowloc1, 3);
749
750         // Commit the create of the tables so that the following aborts don't
751
// undo that work.
752
tc.commit();
753
754         // Now try aborts of transactions during splits, using magic
755
// trace flags. This test inserts enough rows to cause a split
756
// and then forces the split to fail at various key points. The
757
// split should be backed out and also the rows before the split.
758
// The test makes sure that there are some inserts before the forced
759
// split abort.
760
String JavaDoc[] debug_strings = {
761             "leaf_split_growRoot1",
762             "leaf_split_growRoot2",
763             "leaf_split_growRoot3",
764             "leaf_split_growRoot4",
765             "leaf_split_growRoot5",
766             "leaf_split_abort1",
767             "leaf_split_abort2",
768             "leaf_split_abort3",
769             "leaf_split_abort4",
770             "branch_split_abort1",
771             "branch_split_abort2",
772             "branch_split_abort3",
773             "branch_split_abort4",
774             "BTreeController_doIns2"
775             };
776
777         for (int errs = 0; errs < debug_strings.length; errs++)
778         {
779             REPORT("Doing abort test: " + debug_strings[errs]);
780
781             // set the debug flag, which will cause an error
782
// RESOLVE (mmm) these tests should be run from the language to
783
// make sure error handling really works.
784

785             if (SanityManager.DEBUG)
786                 SanityManager.DEBUG_SET(debug_strings[errs]);
787             
788             try
789             {
790
791                 // Open the base table
792
base_cc =
793                     tc.openConglomerate(
794                         create_ret.base_conglomid,
795                         false,
796                         TransactionController.OPENMODE_FORUPDATE,
797                         TransactionController.MODE_RECORD,
798                         TransactionController.ISOLATION_SERIALIZABLE);
799
800                 // Open the secondary index
801
index_cc =
802                     tc.openConglomerate(
803                         create_ret.index_conglomid,
804                         false,
805                         TransactionController.OPENMODE_FORUPDATE,
806                         TransactionController.MODE_RECORD,
807                         TransactionController.ISOLATION_SERIALIZABLE);
808
809                 // insert one row that does not cause failure.
810
((SQLLongint)r1[0]).setValue(2);
811                 ((SQLLongint)r1[1]).setValue(10000 + errs);
812
813                 // Insert the row into the base table;remember its location.
814
base_cc.insertAndFetchLocation(r1, base_rowloc1);
815
816                 // Insert the row into the secondary index.
817
if (index_cc.insert(index_row1.getRow()) != 0)
818                     throw T_Fail.testFailMsg("insert failed");
819
820
821                 // set the debug flag, which will cause an error
822
// RESOLVE (mmm) these tests should be run from the
823
// language to make sure error handling really works.
824
if (SanityManager.DEBUG)
825                     SanityManager.DEBUG_SET(debug_strings[errs]);
826
827                 // now insert enough rows to cause failure
828
for (int i = 100; i > 0; i -= 2)
829                 {
830                     ((SQLLongint)r1[0]).setValue(2);
831                     ((SQLLongint)r1[1]).setValue(i);
832
833                     // Insert the row into the base table;remember its location.
834
base_cc.insertAndFetchLocation(r1, base_rowloc1);
835
836                     // Insert the row into the secondary index.
837
if (index_cc.insert(index_row1.getRow()) != 0)
838                     {
839                         throw T_Fail.testFailMsg("insert failed");
840                     }
841                 }
842
843                 throw T_Fail.testFailMsg(
844                     "debug flag (" + debug_strings[errs] +
845                     ")did not cause exception.");
846             }
847             catch (StandardException e)
848             {
849                 ContextService contextFactory = ContextService.getFactory();
850
851                 // Get the context manager.
852
ContextManager cm = contextFactory.getCurrentContextManager();
853
854                 if (SanityManager.DEBUG)
855                     SanityManager.ASSERT(cm != null);
856
857                 cm.cleanupOnError(e);
858                 
859                 // RESOLVE (mikem) - when split abort works come up with
860
// a good sanity check here.
861
//
862
// index check - there should be no records:
863
scan = tc.openScan(create_ret.index_conglomid, false,
864                         TransactionController.OPENMODE_FORUPDATE,
865                         TransactionController.MODE_RECORD,
866                         TransactionController.ISOLATION_SERIALIZABLE,
867                         (FormatableBitSet) null,
868                         null, ScanController.NA,
869                         null,
870                         null, ScanController.NA);
871
872
873                 index_cc =
874                     tc.openConglomerate(
875                         create_ret.index_conglomid,
876                         false,
877                         TransactionController.OPENMODE_FORUPDATE,
878                         TransactionController.MODE_RECORD,
879                         TransactionController.ISOLATION_SERIALIZABLE);
880
881                 index_cc.checkConsistency();
882                 index_cc.close();
883
884                 if (scan.next())
885                 {
886                     throw T_Fail.testFailMsg(
887                             "t_002: there are still rows in table.");
888                 }
889
890
891                 scan.close();
892             }
893
894             // Unset the flag.
895
if (SanityManager.DEBUG)
896                 SanityManager.DEBUG_CLEAR(debug_strings[errs]);
897         }
898
899         // Try a simple abort. The following adds enough rows to cause a
900
// split. The result of the split should be a tree with no rows, but
901
// the splits will not be undone. It is up to the implementation
902
// whether the undo's cause shrinks in the tree. In the initial
903
// implementation it won't.
904
{
905             tc.commit();
906
907             // Open the base table
908
base_cc =
909                 tc.openConglomerate(
910                     create_ret.base_conglomid,
911                     false,
912                     TransactionController.OPENMODE_FORUPDATE,
913                     TransactionController.MODE_RECORD,
914                     TransactionController.ISOLATION_SERIALIZABLE);
915
916             // Open the secondary index
917
index_cc =
918                 tc.openConglomerate(
919                     create_ret.index_conglomid,
920                     false,
921                     TransactionController.OPENMODE_FORUPDATE,
922                     TransactionController.MODE_RECORD,
923                     TransactionController.ISOLATION_SERIALIZABLE);
924
925             // BTree.PROPERTY_MAX_ROWS_PER_PAGE_PARAMETER has been set to 2 so
926
// inserting 3 rows will cause a split at the leaf level.
927
// Make sure that normal abort leaves the committed split.
928
for (int i = 0; i < 3; i++)
929             {
930                 ((SQLLongint)r1[0]).setValue(2);
931                 ((SQLLongint)r1[1]).setValue(i);
932
933                 // Insert the row into the base table;remember its location.
934
base_cc.insertAndFetchLocation(r1, base_rowloc1);
935
936                 // Insert the row into the secondary index.
937
if (index_cc.insert(index_row1.getRow()) != 0)
938                     throw T_Fail.testFailMsg("insert failed");
939             }
940
941             tc.abort();
942
943             // index check - there should be no records left.
944
ScanController empty_scan =
945                 tc.openScan(create_ret.index_conglomid, false,
946                             0,
947                             TransactionController.MODE_RECORD,
948                             TransactionController.ISOLATION_SERIALIZABLE,
949                             (FormatableBitSet) null,
950                             null, ScanController.NA,
951                             null,
952                             null, ScanController.NA);
953
954             if (empty_scan.next())
955             {
956                 throw T_Fail.testFailMsg(
957                     "t_002: there are still rows in table.");
958             }
959         }
960
961         tc.commit();
962         REPORT("Ending t_002");
963
964         return true;
965     }
966
967     private boolean t_003_scan_test_cases(
968     TransactionController tc,
969     long index_conglomid,
970     T_SecondaryIndexRow template
971     )
972         throws StandardException, T_Fail
973     {
974         boolean ret_val = true;
975
976         // run through a predicates as described in the openScan() interface //
977
DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
978         DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
979
980
981         // test predicate x = 5
982
//
983
// result set should be: {5,2,16}, {5,4,17}, {5,6,18}
984
//
985
REPORT("scan (x = 5)");
986         ((SQLLongint)start_key[0]).setValue(5);
987         ((SQLLongint)stop_key[0]).setValue(5);
988         if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
989                    template.getRow(),
990                    start_key, ScanController.GE,
991                    null,
992                    stop_key, ScanController.GT,
993                    3, 16, T_QualifierTest.ORDER_FORWARD))
994         {
995             ret_val = false;
996         }
997                    
998         // +---------------------------------------------------------+
999
// |pred |start|key|stop |key|rows returned |rows locked |
1000
// | |value|op |value|op | |(serialization)|
1001
// +------+-----+---+-----+---+--------------+---------------+
1002
// |x > 5 |{5} |GT |null | |{6,1} .. {9,1}|{5,6} .. {9,1} |
1003
// +-----------------------------------------+---------------+
1004
REPORT("scan (x > 5)");
1005        ((SQLLongint)start_key[0]).setValue(5);
1006        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1007                   template.getRow(),
1008                   start_key, ScanController.GT,
1009                   null,
1010                   null, ScanController.NA,
1011                   3, 19, T_QualifierTest.ORDER_FORWARD))
1012        {
1013            ret_val = false;
1014        }
1015
1016        // +---------------------------------------------------------+
1017
// |pred |start|key|stop |key|rows returned |rows locked |
1018
// | |value|op |value|op | |(serialization)|
1019
// +------+-----+---+-----+---+--------------+---------------+
1020
// |x >= 5|{5} |GE |null | |{5,2} .. {9,1}|{4,6} .. {9,1} |
1021
// +-----------------------------------------+---------------+
1022
REPORT("scan (x >= 5)");
1023        ((SQLLongint)start_key[0]).setValue(5);
1024        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1025                   template.getRow(),
1026                   start_key, ScanController.GE,
1027                   null,
1028                   null, ScanController.NA,
1029                   6, 16, T_QualifierTest.ORDER_FORWARD))
1030        {
1031            ret_val = false;
1032        }
1033
1034        //
1035
// +---------------------------------------------------------+
1036
// |pred |start|key|stop |key|rows returned |rows locked |
1037
// | |value|op |value|op | |(serialization)|
1038
// +------+-----+---+-----+---+--------------+---------------+
1039
// |x <= 5|null | |{5} |GT |{1,1} .. {5,6}|first .. {5,6} |
1040
// +-----------------------------------------+---------------+
1041
REPORT("scan (x <= 5)");
1042        ((SQLLongint)stop_key[0]).setValue(5);
1043        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1044                   template.getRow(),
1045                   null, ScanController.NA,
1046                   null,
1047                   stop_key, ScanController.GT,
1048                   8, 11, T_QualifierTest.ORDER_FORWARD))
1049        {
1050            ret_val = false;
1051        }
1052        //
1053
// +---------------------------------------------------------+
1054
// |pred |start|key|stop |key|rows returned |rows locked |
1055
// | |value|op |value|op | |(serialization)|
1056
// +------+-----+---+-----+---+--------------+---------------+
1057
// |x < 5 |null | |{5} |GE |{1,1} .. {4,6}|first .. {4,6} |
1058
// +-----------------------------------------+---------------+
1059
REPORT("scan (x < 5)");
1060        ((SQLLongint)stop_key[0]).setValue(5);
1061        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1062                   template.getRow(),
1063                   null, ScanController.NA,
1064                   null,
1065                   stop_key, ScanController.GE,
1066                   5, 11, T_QualifierTest.ORDER_FORWARD))
1067        {
1068            ret_val = false;
1069        }
1070
1071        //long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
1072
//long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
1073
//long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
1074
// +------------------------------------------------------------------+
1075
// |pred |start|key|stop |key|rows returned|rows locked |
1076
// | |value|op |value|op | |(serialized) |
1077
// +-----------------+------+--+-----+--+--------------+--------------+
1078
// |x >= 5 and x <= 7|{5}, |GE|{7} |GT|{5,2} .. {7,1}|{4,6} .. {7,1}|
1079
// +------------------------------------------------------------------+
1080
REPORT("scan (x >= 5 and x <= 7)");
1081        ((SQLLongint)start_key[0]).setValue(5);
1082        ((SQLLongint)stop_key[0]).setValue(7);
1083        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1084                   template.getRow(),
1085                   start_key, ScanController.GE,
1086                   null,
1087                   stop_key, ScanController.GT,
1088                   5, 16, T_QualifierTest.ORDER_FORWARD))
1089        {
1090            ret_val = false;
1091        }
1092
1093        // +------------------------------------------------------------------+
1094
// |pred |start|key|stop |key|rows returned|rows locked |
1095
// | |value|op |value|op | |(serialized) |
1096
// +-----------------+------+--+-----+--+--------------+--------------+
1097
// |x = 5 and y > 2 |{5,2} |GT|{5} |GT|{5,4} .. {5,6}|{5,2} .. {9,1}|
1098
// +------------------------------------------------------------------+
1099
REPORT("scan (x = 5 and y > 2)");
1100        start_key = TemplateRow.newU8Row(2);
1101        stop_key = TemplateRow.newU8Row(1);
1102        ((SQLLongint)start_key[0]).setValue(5);
1103        ((SQLLongint)start_key[1]).setValue(2);
1104        ((SQLLongint)stop_key[0]).setValue(5);
1105        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1106                   template.getRow(),
1107                   start_key, ScanController.GT,
1108                   null,
1109                   stop_key, ScanController.GT,
1110                   2, 17, T_QualifierTest.ORDER_FORWARD))
1111        {
1112            ret_val = false;
1113        }
1114
1115        // +------------------------------------------------------------------+
1116
// |pred |start|key|stop |key|rows returned|rows locked |
1117
// | |value|op |value|op | |(serialized) |
1118
// +-----------------+------+--+-----+--+--------------+--------------+
1119
// |x = 5 and y >= 2 | {5,2}|GE| {5} |GT|{5,2} .. {5,6}|{4,6} .. {9,1}|
1120
// +------------------------------------------------------------------+
1121
REPORT("scan (x = 5 and y >= 2)");
1122        start_key = TemplateRow.newU8Row(2);
1123        stop_key = TemplateRow.newU8Row(1);
1124        ((SQLLongint)start_key[0]).setValue(5);
1125        ((SQLLongint)start_key[1]).setValue(2);
1126        ((SQLLongint)stop_key[0]).setValue(5);
1127        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1128                   template.getRow(),
1129                   start_key, ScanController.GE,
1130                   null,
1131                   stop_key, ScanController.GT,
1132                   3, 16, T_QualifierTest.ORDER_FORWARD))
1133        {
1134            ret_val = false;
1135        }
1136
1137        // +------------------------------------------------------------------+
1138
// |pred |start|key|stop |key|rows returned|rows locked |
1139
// | |value|op |value|op | |(serialized) |
1140
// +-----------------+------+--+-----+--+--------------+--------------+
1141
// |x = 5 and y < 5 | {5} |GE|{5,5}|GE|{5,2} .. {5,4}|{4,6} .. {5,4}|
1142
// +------------------------------------------------------------------+
1143
REPORT("scan (x = 5 and y < 5)");
1144        start_key = TemplateRow.newU8Row(1);
1145        stop_key = TemplateRow.newU8Row(2);
1146        ((SQLLongint)start_key[0]).setValue(5);
1147        ((SQLLongint)stop_key[0]).setValue(5);
1148        ((SQLLongint)stop_key[1]).setValue(5);
1149        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1150                   template.getRow(),
1151                   start_key, ScanController.GE,
1152                   null,
1153                   stop_key, ScanController.GE,
1154                   2, 16, T_QualifierTest.ORDER_FORWARD))
1155        {
1156            ret_val = false;
1157        }
1158
1159        // +------------------------------------------------------------------+
1160
// |pred |start|key|stop |key|rows returned|rows locked |
1161
// | |value|op |value|op | |(serialized) |
1162
// +-----------------+------+--+-----+--+--------------+--------------+
1163
// |x = 2 | {2} |GE| {2} |GT|none |{1,1} .. {1,1}|
1164
// +------------------------------------------------------------------+
1165
REPORT("scan (x = 2)");
1166        start_key = TemplateRow.newU8Row(1);
1167        stop_key = TemplateRow.newU8Row(1);
1168        ((SQLLongint)start_key[0]).setValue(2);
1169        ((SQLLongint)stop_key[0]).setValue(2);
1170        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
1171                   template.getRow(),
1172                   start_key, ScanController.GE,
1173                   null,
1174                   stop_key, ScanController.GT,
1175                   0, 0, T_QualifierTest.ORDER_FORWARD))
1176        {
1177            ret_val = false;
1178        }
1179
1180        // +-----------------------------+
1181
// |max on btree - row locked |
1182
// +-----------------------------+
1183
//
1184
REPORT("max on btree, row locked.");
1185        if (!tc.fetchMaxOnBtree(
1186                index_conglomid,
1187                0,
1188                TransactionController.MODE_RECORD,
1189                TransactionController.ISOLATION_SERIALIZABLE,
1190                (FormatableBitSet) null,
1191                template.getRow()))
1192        {
1193            throw T_Fail.testFailMsg("found no max.");
1194        }
1195        else
1196        {
1197            // make sure right max was found.
1198
long key = ((SQLLongint) template.getRow()[2]).getLong();
1199            
1200            if (key != 21)
1201            {
1202                throw T_Fail.testFailMsg("wrong max found.");
1203            }
1204        }
1205
1206        // +-----------------------------+
1207
// |max on btree - table locked |
1208
// +-----------------------------+
1209
//
1210
REPORT("max on btree, table locked.");
1211        if (!tc.fetchMaxOnBtree(
1212                index_conglomid,
1213                0,
1214                TransactionController.MODE_TABLE,
1215                TransactionController.ISOLATION_SERIALIZABLE,
1216                (FormatableBitSet) null,
1217                template.getRow()))
1218        {
1219            throw T_Fail.testFailMsg("found no max.");
1220        }
1221        else
1222        {
1223            // make sure right max was found.
1224
long key = ((SQLLongint) template.getRow()[2]).getLong();
1225            
1226            if (key != 21)
1227            {
1228                throw T_Fail.testFailMsg("wrong max found.");
1229            }
1230        }
1231
1232        // +-----------------------------+
1233
// |max on btree - row locked |
1234
// +-----------------------------+
1235
//
1236
REPORT("max on btree, row locked.");
1237        if (!tc.fetchMaxOnBtree(
1238                index_conglomid,
1239                0,
1240                TransactionController.MODE_RECORD,
1241                TransactionController.ISOLATION_READ_COMMITTED,
1242                (FormatableBitSet) null,
1243                template.getRow()))
1244        {
1245            throw T_Fail.testFailMsg("found no max.");
1246        }
1247        else
1248        {
1249            // make sure right max was found.
1250
long key = ((SQLLongint) template.getRow()[2]).getLong();
1251            
1252            if (key != 21)
1253            {
1254                throw T_Fail.testFailMsg("wrong max found.");
1255            }
1256        }
1257
1258        // +-----------------------------+
1259
// |max on btree - table locked |
1260
// +-----------------------------+
1261
//
1262
REPORT("max on btree, table locked.");
1263        if (!tc.fetchMaxOnBtree(
1264                index_conglomid,
1265                0,
1266                TransactionController.MODE_TABLE,
1267                TransactionController.ISOLATION_READ_COMMITTED,
1268                (FormatableBitSet) null,
1269                template.getRow()))
1270        {
1271            throw T_Fail.testFailMsg("found no max.");
1272        }
1273        else
1274        {
1275            // make sure right max was found.
1276
long key = ((SQLLongint) template.getRow()[2]).getLong();
1277            
1278            if (key != 21)
1279            {
1280                throw T_Fail.testFailMsg("wrong max found.");
1281            }
1282        }
1283
1284        return(ret_val);
1285    }
1286
1287    /**
1288     * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
1289     * BtreeScan.fetch().
1290     *
1291     * @exception StandardException Standard exception policy.
1292     * @exception T_Fail Throws T_Fail on any test failure.
1293     */

1294    protected boolean t_003(TransactionController tc)
1295        throws StandardException, T_Fail
1296    {
1297        T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1298
1299        // base row template - last column is just to make row long so that
1300
// multiple pages are spanned.
1301
DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
1302        base_row[3] = new SQLChar();
1303
1304        String JavaDoc string_1500char = new String JavaDoc();
1305        for (int i = 0; i < 300; i++)
1306            string_1500char += "mikem";
1307
1308        boolean ret_val = true;
1309        long value = -1;
1310        long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
1311        long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
1312        long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
1313
1314        // set of deleted rows to make scans more interesting
1315
long d_col1[] ={ 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12};
1316        long d_col2[] ={ 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1};
1317        long d_col3[] ={91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104};
1318
1319        REPORT("Starting t_003");
1320
1321        // create the base table
1322
long base_conglomid =
1323            tc.createConglomerate(
1324                "heap", // create a heap conglomerate
1325
base_row, // base table template row
1326
null, //column sort order - not required for heap
1327
null, // default properties
1328
TransactionController.IS_DEFAULT); // not temporary
1329

1330        // Open the base table
1331
ConglomerateController base_cc =
1332            tc.openConglomerate(
1333                base_conglomid,
1334                false,
1335                TransactionController.OPENMODE_FORUPDATE,
1336                TransactionController.MODE_RECORD,
1337                TransactionController.ISOLATION_SERIALIZABLE);
1338
1339        // initialize the secondary index row - pointing it at base row
1340
index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
1341
1342        Properties JavaDoc properties =
1343            createProperties(
1344                null, // no current properties list
1345
false, // don't allow duplicates
1346
5, // 4 columns in index row
1347
5, // non-unique index
1348
true, // maintain parent links
1349
base_conglomid, // base conglom id
1350
4); // row loc in last column
1351

1352        long index_conglomid =
1353            tc.createConglomerate(
1354                "BTREE", // create a btree secondary
1355
index_row.getRow(), // row template
1356
null, //column sort order - default
1357
properties, // properties
1358
TransactionController.IS_DEFAULT); // not temporary
1359

1360        // Open the conglomerate.
1361
ConglomerateController index_cc =
1362            tc.openConglomerate(
1363                index_conglomid,
1364                false,
1365                TransactionController.OPENMODE_FORUPDATE,
1366                TransactionController.MODE_RECORD,
1367                TransactionController.ISOLATION_SERIALIZABLE);
1368
1369        // Create a row.
1370
T_SecondaryIndexRow template = new T_SecondaryIndexRow();
1371        RowLocation row_loc = base_cc.newRowLocationTemplate();
1372        template.init(base_row, row_loc, 5);
1373
1374        // insert them in reverse order just to make sure btree is sorting them
1375
for (int i = col1.length - 1; i >= 0; i--)
1376        {
1377            ((SQLLongint)(template.getRow()[0])).setValue(col1[i]);
1378            ((SQLLongint)(template.getRow()[1])).setValue(col2[i]);
1379            ((SQLLongint)(template.getRow()[2])).setValue(col3[i]);
1380            base_row[3] = new SQLChar(string_1500char);
1381
1382            base_cc.insertAndFetchLocation(base_row, row_loc);
1383
1384            // Insert the row.
1385
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
1386
// ")" + template);
1387
if (index_cc.insert(template.getRow()) != 0)
1388                throw T_Fail.testFailMsg("insert failed");
1389        }
1390
1391        index_cc.checkConsistency();
1392
1393        ((B2IController)index_cc).debugConglomerate();
1394
1395        ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
1396
1397        // insert and delete some interesting rows, deleted space management
1398
// may or may not clean these up.
1399
for (int i = d_col1.length - 1; i >= 0; i--)
1400        {
1401            ((SQLLongint)(template.getRow()[0])).setValue(d_col1[i]);
1402            ((SQLLongint)(template.getRow()[1])).setValue(d_col2[i]);
1403            ((SQLLongint)(template.getRow()[2])).setValue(d_col3[i]);
1404            base_row[3] = new SQLChar(string_1500char);
1405
1406            base_cc.insertAndFetchLocation(base_row, row_loc);
1407
1408            // Insert the row.
1409
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
1410
// ")" + template);
1411
if (index_cc.insert(template.getRow()) != 0)
1412                throw T_Fail.testFailMsg("insert failed");
1413
1414            // now delete the row.
1415
base_cc.delete(row_loc);
1416
1417            ScanController delete_scan =
1418                tc.openScan(index_conglomid, false,
1419                            TransactionController.OPENMODE_FORUPDATE,
1420                            TransactionController.MODE_RECORD,
1421                            TransactionController.ISOLATION_SERIALIZABLE,
1422                            (FormatableBitSet) null,
1423                            template.getRow(), ScanController.GE,
1424                            null,
1425                            template.getRow(), ScanController.GT);
1426
1427            if (!delete_scan.next())
1428            {
1429                throw T_Fail.testFailMsg("delete could not find key");
1430            }
1431            else
1432            {
1433                delete_scan.delete();
1434
1435                if (delete_scan.next())
1436                    throw T_Fail.testFailMsg("delete found more than one key");
1437            }
1438
1439            delete_scan.close();
1440        }
1441
1442        ret_val = t_003_scan_test_cases(tc, index_conglomid, template);
1443
1444
1445        // Close the conglomerate.
1446
index_cc.close();
1447
1448        tc.commit();
1449        REPORT("Ending t_003");
1450
1451        return(ret_val);
1452    }
1453
1454    /**
1455     * Test qualifiers.
1456     *
1457     * @exception StandardException Standard exception policy.
1458     * @exception T_Fail Throws T_Fail on any test failure.
1459     */

1460    protected boolean t_004(TransactionController tc)
1461        throws StandardException, T_Fail
1462    {
1463        REPORT("Starting t_004");
1464
1465        T_CreateConglomRet create_ret = new T_CreateConglomRet();
1466
1467        createCongloms(tc, 2, false, false, 0, create_ret);
1468
1469        Properties JavaDoc properties =
1470            createProperties(
1471                null, // no current properties list
1472
false, // don't allow duplicates
1473
4, // 3 columns in index row
1474
4, // non-unique index
1475
true, // maintain parent links
1476
create_ret.base_conglomid, // fake base conglom for now
1477
3); // row loc in last column
1478

1479        T_QualifierTest q_test =
1480            new T_QualifierTest(
1481                "BTREE", // create a btree secondary
1482
properties, // properties
1483
false, // not temporary
1484
out,
1485                T_QualifierTest.ORDER_FORWARD); // ordered
1486

1487        boolean test_result = q_test.t_testqual(tc);
1488
1489        REPORT("Ending t_004");
1490
1491        return(test_result);
1492    }
1493
1494    /**
1495     * Test Branch splits - number of rows necessary to cause splits is raw
1496     * store implementation dependant (currently 5 rows per page in in-memory
1497     * implementation).
1498     *
1499     * @exception StandardException Standard exception policy.
1500     * @exception T_Fail Throws T_Fail on any test failure.
1501     */

1502    protected boolean t_005(TransactionController tc)
1503        throws StandardException, T_Fail
1504    {
1505        boolean ret_val = true;
1506
1507        REPORT("Starting t_005");
1508
1509        T_CreateConglomRet create_ret = new T_CreateConglomRet();
1510
1511        createCongloms(tc, 2, false, false, 0, create_ret);
1512
1513        // Open the base conglomerate.
1514
ConglomerateController base_cc =
1515            tc.openConglomerate(
1516                create_ret.base_conglomid,
1517                false,
1518                TransactionController.OPENMODE_FORUPDATE,
1519                TransactionController.MODE_RECORD,
1520                TransactionController.ISOLATION_SERIALIZABLE);
1521
1522        // Open the index conglomerate.
1523
ConglomerateController index_cc =
1524            tc.openConglomerate(
1525                create_ret.index_conglomid,
1526                false,
1527                TransactionController.OPENMODE_FORUPDATE,
1528                TransactionController.MODE_RECORD,
1529                TransactionController.ISOLATION_SERIALIZABLE);
1530
1531
1532        // Create a row.
1533
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1534        RowLocation rowloc = base_cc.newRowLocationTemplate();
1535        DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1536        index_row.init(base_row, rowloc, 3);
1537
1538        // insert them in reverse order just to make sure btree is sorting them
1539
for (int i = 200; i >= 0; i -= 4)
1540        {
1541            ((SQLLongint)base_row[0]).setValue(1);
1542            ((SQLLongint)base_row[1]).setValue(i);
1543            base_cc.insertAndFetchLocation(base_row, rowloc);
1544
1545            if (index_cc.insert(index_row.getRow()) != 0)
1546                throw T_Fail.testFailMsg("insert failed");
1547        }
1548        for (int i = 199; i >= 0; i -= 4)
1549        {
1550            ((SQLLongint)base_row[0]).setValue(1);
1551            ((SQLLongint)base_row[1]).setValue(i);
1552
1553            base_cc.insertAndFetchLocation(base_row, rowloc);
1554            if (index_cc.insert(index_row.getRow()) != 0)
1555                throw T_Fail.testFailMsg("insert failed");
1556        }
1557
1558        index_cc.checkConsistency();
1559
1560        // Close the conglomerate.
1561
index_cc.close();
1562
1563        tc.commit();
1564
1565        // Search for each of the keys and delete them one at a time.
1566
DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
1567        for (int i = 200; i >= 0; i -= 4)
1568        {
1569            ((SQLLongint)delete_key[0]).setValue(1);
1570            ((SQLLongint)delete_key[1]).setValue(i);
1571
1572            if (!t_delete(
1573                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
1574            {
1575                ret_val = false;
1576            }
1577        }
1578        for (int i = 199; i >= 0; i -= 4)
1579        {
1580            ((SQLLongint)delete_key[0]).setValue(1);
1581            ((SQLLongint)delete_key[1]).setValue(i);
1582
1583            if (!t_delete(
1584                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
1585            {
1586                ret_val = false;
1587            }
1588        }
1589
1590        tc.commit();
1591
1592        // Open the base conglomerate.
1593
base_cc =
1594            tc.openConglomerate(
1595                create_ret.base_conglomid,
1596                false,
1597                TransactionController.OPENMODE_FORUPDATE,
1598                TransactionController.MODE_RECORD,
1599                TransactionController.ISOLATION_SERIALIZABLE);
1600
1601
1602        // Open the conglomerate.
1603
index_cc =
1604            tc.openConglomerate(
1605                create_ret.index_conglomid,
1606                false,
1607                TransactionController.OPENMODE_FORUPDATE,
1608                TransactionController.MODE_RECORD,
1609                TransactionController.ISOLATION_SERIALIZABLE);
1610
1611        // flush and empty cache to make sure rereading stuff works.
1612
RawStoreFactory rawstore =
1613            (RawStoreFactory) Monitor.findServiceModule(
1614                this.store_module, RawStoreFactory.MODULE);
1615
1616        rawstore.idle();
1617
1618        // now make sure that additional splits don't cause delete bits to
1619
// be enabled (one early bug did so).
1620

1621        for (int i = 200; i >= 0; i -= 3)
1622        {
1623            ((SQLLongint)base_row[0]).setValue(1);
1624            ((SQLLongint)base_row[1]).setValue(i);
1625
1626            base_cc.insertAndFetchLocation(base_row, rowloc);
1627            if (index_cc.insert(index_row.getRow()) != 0)
1628                throw T_Fail.testFailMsg("insert failed");
1629        }
1630        for (int i = 200; i >= 0; i -= 3)
1631        {
1632            ((SQLLongint)delete_key[0]).setValue(1);
1633            ((SQLLongint)delete_key[1]).setValue(i);
1634
1635            if (!t_delete(
1636                tc, create_ret.index_conglomid, delete_key, index_row.getRow()))
1637            {
1638                ret_val = false;
1639            }
1640        }
1641
1642        // index check - there should be no records left.
1643
ScanController empty_scan =
1644            tc.openScan(create_ret.index_conglomid, false,
1645                        0,
1646                        TransactionController.MODE_RECORD,
1647                        TransactionController.ISOLATION_SERIALIZABLE,
1648                        (FormatableBitSet) null,
1649                        null, ScanController.NA,
1650                        null,
1651                        null, ScanController.NA);
1652        if (empty_scan.next())
1653            throw T_Fail.testFailMsg("t_005: there are still rows in table.");
1654
1655        index_cc.checkConsistency();
1656
1657        for (int i = 600; i >= 400; i -= 3)
1658        {
1659            ((SQLLongint)base_row[0]).setValue(1);
1660            ((SQLLongint)base_row[1]).setValue(i);
1661
1662            base_cc.insertAndFetchLocation(base_row, rowloc);
1663            if (index_cc.insert(index_row.getRow()) != 0)
1664                throw T_Fail.testFailMsg("insert failed");
1665        }
1666
1667        index_cc.checkConsistency();
1668
1669        tc.abort();
1670
1671        // index check - there should be no records left.
1672
empty_scan =
1673            tc.openScan(create_ret.index_conglomid, false,
1674                        0,
1675                        TransactionController.MODE_RECORD,
1676                        TransactionController.ISOLATION_SERIALIZABLE,
1677                        (FormatableBitSet) null,
1678                        null, ScanController.NA,
1679                        null,
1680                        null, ScanController.NA);
1681        if (empty_scan.next())
1682            throw T_Fail.testFailMsg("t_005: there are still rows in table.");
1683
1684
1685        REPORT("Ending t_005");
1686
1687        return(ret_val);
1688    }
1689    /**
1690     * Test unimplemented interfaces.
1691     *
1692     * The following ScanController interfaces are not supported by the
1693     * btree implementation, because row locations are not returned outside
1694     * the interface. At some point we may package a key as a row location
1695     * but that does not really give any more functionality than using scan
1696     * to find your key:
1697     * ScanController.fetchLocation()
1698     * ScanController.newRowLocationTemplate()
1699     * ScanController.replace()
1700     * ConglomerateController.delete()
1701     * ConglomerateController.fetch()
1702     * ConglomerateController.insertAndFetchLocation()
1703     * ConglomerateController.newRowLocationTemplate()
1704     * ConglomerateController.replace()
1705     *
1706     * @exception StandardException Standard exception policy.
1707     * @exception T_Fail Throws T_Fail on any test failure.
1708     */

1709    protected boolean t_006(TransactionController tc)
1710        throws StandardException, T_Fail
1711    {
1712        REPORT("Starting t_006");
1713
1714        T_CreateConglomRet create_ret = new T_CreateConglomRet();
1715
1716        createCongloms(tc, 2, false, false, 0, create_ret);
1717
1718        // Open the base conglomerate.
1719
ConglomerateController base_cc =
1720            tc.openConglomerate(
1721                create_ret.base_conglomid,
1722                false,
1723                TransactionController.OPENMODE_FORUPDATE,
1724                TransactionController.MODE_RECORD,
1725                TransactionController.ISOLATION_SERIALIZABLE);
1726
1727        // Open the index conglomerate.
1728
ConglomerateController index_cc =
1729            tc.openConglomerate(
1730                create_ret.index_conglomid,
1731                false,
1732                TransactionController.OPENMODE_FORUPDATE,
1733                TransactionController.MODE_RECORD,
1734                TransactionController.ISOLATION_SERIALIZABLE);
1735
1736        // Create a base row template.
1737
DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1738        RowLocation base_rowloc = base_cc.newRowLocationTemplate();
1739
1740        T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
1741        index_row_from_base_row.init(base_row, base_rowloc, 3);
1742        ((SQLLongint)base_row[0]).setValue(1);
1743
1744        // Create a row.
1745
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1746        index_row.init(TemplateRow.newU8Row(2),
1747                        base_cc.newRowLocationTemplate(), 3);
1748
1749        // test: make sure scan position is right after inserts before scan
1750
// no split case. In this case the slot position of the current
1751
// position should change, but the code will keep a record handle
1752
// and not need to reposition by key.
1753
// before keys: 1000, 3000
1754
// last key gotten froms scan : 0
1755
// insert keys:1-900
1756
// next key from scan should be: 5
1757

1758        // insert 1000
1759
((SQLLongint)base_row[1]).setValue(1000);
1760        base_cc.insertAndFetchLocation(base_row, base_rowloc);
1761        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
1762        {
1763            throw T_Fail.testFailMsg("insert failed");
1764        }
1765
1766        // try each of the unsupported interfaces:
1767
try
1768        {
1769            index_cc.delete(null);
1770            return(FAIL("t_006: ConglomerateController.delete() succeeded."));
1771        }
1772        catch (StandardException e)
1773        {
1774        }
1775        try
1776        {
1777            if (!index_cc.fetch(
1778                    null, RowUtil.EMPTY_ROW, (FormatableBitSet) null))
1779            {
1780                return(FAIL("t_006: ConglomerateController.fetch() bad ret."));
1781            }
1782            return(FAIL("t_006: ConglomerateController.fetch() succeeded."));
1783        }
1784        catch (StandardException e)
1785        {
1786        }
1787        try
1788        {
1789            index_cc.insertAndFetchLocation((DataValueDescriptor[]) null, null);
1790            return(FAIL(
1791                "t_006: ConglomerateController.insertAndFetchLocation() succeeded."));
1792        }
1793        catch (StandardException e)
1794        {
1795        }
1796        try
1797        {
1798            RowLocation rowloc = index_cc.newRowLocationTemplate();
1799            return(FAIL(
1800                "t_006: ConglomerateController.newRowLocationTemplate() succeeded."));
1801        }
1802        catch (StandardException e)
1803        {
1804        }
1805        try
1806        {
1807            index_cc.replace(null, null, null);
1808            return(FAIL("t_006: ConglomerateController.replace() succeeded."));
1809        }
1810        catch (StandardException e)
1811        {
1812        }
1813
1814        index_cc.close();
1815
1816        // open a new scan
1817

1818        ScanController scan =
1819            tc.openScan(create_ret.index_conglomid, false,
1820                        0,
1821                        TransactionController.MODE_RECORD,
1822                        TransactionController.ISOLATION_SERIALIZABLE,
1823                        (FormatableBitSet) null,
1824                        null, ScanController.NA,
1825                        null,
1826                        null, ScanController.NA);
1827
1828        int numrows = 0;
1829        while (scan.next())
1830        {
1831            numrows++;
1832
1833            scan.fetch(index_row_from_base_row.getRow());
1834
1835            try
1836            {
1837                scan.fetchLocation(null);
1838                return(FAIL("t_006: scan.fetchLocation() succeeded"));
1839            }
1840            catch (StandardException e)
1841            {
1842            }
1843
1844            try
1845            {
1846                RowLocation rowloc = scan.newRowLocationTemplate();
1847                return(FAIL("t_006: scan.newRowLocationTemplate() succeeded"));
1848            }
1849            catch (StandardException e)
1850            {
1851            }
1852
1853            try
1854            {
1855                scan.replace(index_row_from_base_row.getRow(), (FormatableBitSet) null);
1856                return(FAIL("t_006: scan.replace() succeeded"));
1857            }
1858            catch (StandardException e)
1859            {
1860            }
1861
1862        }
1863
1864        // make sure that scan.next() continues to return false
1865
if (scan.next())
1866            return(FAIL("t_006: scan.next() returned true after false."));
1867
1868        scan.close();
1869
1870        if (numrows != 1)
1871        {
1872            return(FAIL("(t_scan) wrong number of rows. Expected " +
1873                   "1 row, but got " + numrows + "rows."));
1874        }
1875
1876        REPORT("Ending t_006");
1877        return(true);
1878    }
1879
1880    /**
1881     * Test multiple scans in a single page/no split
1882     *
1883     * @exception StandardException Standard exception policy.
1884     * @exception T_Fail Throws T_Fail on any test failure.
1885     */

1886    protected boolean t_007(TransactionController tc)
1887        throws StandardException, T_Fail
1888    {
1889        boolean ret_val = true;
1890
1891        REPORT("Starting t_007");
1892
1893        T_CreateConglomRet create_ret = new T_CreateConglomRet();
1894
1895        createCongloms(tc, 2, false, false, 0, create_ret);
1896
1897        // Open the base conglomerate.
1898
ConglomerateController base_cc =
1899            tc.openConglomerate(
1900                create_ret.base_conglomid,
1901                false,
1902                TransactionController.OPENMODE_FORUPDATE,
1903                TransactionController.MODE_RECORD,
1904                TransactionController.ISOLATION_SERIALIZABLE);
1905
1906        // Open the index conglomerate.
1907
ConglomerateController index_cc =
1908            tc.openConglomerate(
1909                create_ret.index_conglomid,
1910                false,
1911                TransactionController.OPENMODE_FORUPDATE,
1912                TransactionController.MODE_RECORD,
1913                TransactionController.ISOLATION_SERIALIZABLE);
1914
1915        // Create a row.
1916
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
1917        DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
1918        RowLocation row_loc = base_cc.newRowLocationTemplate();
1919        index_row.init(base_row, row_loc, 3);
1920
1921        // Create a row.
1922
((SQLLongint)(index_row.getRow()[0])).setValue(1);
1923
1924        // test: make sure scan position is right after inserts before scan
1925
// no split case. In this case the slot position of the current
1926
// position should change, but the code will keep a record handle
1927
// and not need to reposition by key.
1928
// before keys: 3, 5
1929
// last key gotten froms scan : 0
1930
// insert keys:1, 2
1931
// next key from scan should be: 5
1932

1933        // insert 3
1934
((SQLLongint)(index_row.getRow()[1])).setValue(3);
1935        base_cc.insertAndFetchLocation(base_row, row_loc);
1936        if (index_cc.insert(index_row.getRow()) != 0)
1937            throw T_Fail.testFailMsg("insert failed");
1938
1939        // insert 5
1940
((SQLLongint)(index_row.getRow()[1])).setValue(5);
1941        base_cc.insertAndFetchLocation(base_row, row_loc);
1942        if (index_cc.insert(index_row.getRow()) != 0)
1943            throw T_Fail.testFailMsg("insert failed");
1944
1945        // open a new scan
1946

1947        ScanController scan =
1948            tc.openScan(create_ret.index_conglomid, false,
1949                        0,
1950                        TransactionController.MODE_RECORD,
1951                        TransactionController.ISOLATION_SERIALIZABLE,
1952                        (FormatableBitSet) null,
1953                        null, ScanController.NA,
1954                        null,
1955                        null, ScanController.NA);
1956
1957        if (SanityManager.DEBUG)
1958            SanityManager.ASSERT(scan.next());
1959
1960        scan.fetch(index_row.getRow());
1961        long key = ((SQLLongint)(index_row.getRow()[1])).getLong();
1962
1963        if (SanityManager.DEBUG)
1964            SanityManager.ASSERT(key == 3);
1965
1966        // insert 1
1967
((SQLLongint)(index_row.getRow()[1])).setValue(1);
1968        base_cc.insertAndFetchLocation(base_row, row_loc);
1969        if (index_cc.insert(index_row.getRow()) != 0)
1970            throw T_Fail.testFailMsg("insert failed");
1971
1972        // insert 2
1973
((SQLLongint)(index_row.getRow()[1])).setValue(2);
1974        base_cc.insertAndFetchLocation(base_row, row_loc);
1975        if (index_cc.insert(index_row.getRow()) != 0)
1976            throw T_Fail.testFailMsg("insert failed");
1977
1978        // current position should not have changed
1979
scan.fetch(index_row.getRow());
1980        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
1981
1982        if (SanityManager.DEBUG)
1983            SanityManager.ASSERT(key == 3);
1984
1985        // next position should be 5
1986
if (SanityManager.DEBUG)
1987            SanityManager.ASSERT(scan.next());
1988        scan.fetch(index_row.getRow());
1989        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
1990
1991        if (SanityManager.DEBUG)
1992            SanityManager.ASSERT(key == 5);
1993
1994        index_cc.close();
1995        scan.close();
1996
1997        REPORT("Ending t_007");
1998
1999        return(ret_val);
2000    }
2001    /**
2002     * Test multiple scans in a single table/with splits
2003     *
2004     * @exception StandardException Standard exception policy.
2005     * @exception T_Fail Throws T_Fail on any test failure.
2006     */

2007    protected boolean t_008(TransactionController tc)
2008        throws StandardException, T_Fail
2009    {
2010        boolean ret_val = true;
2011
2012        REPORT("Starting t_008");
2013
2014        T_CreateConglomRet create_ret = new T_CreateConglomRet();
2015
2016        createCongloms(tc, 2, false, false, 0, create_ret);
2017
2018        // Open the base conglomerate.
2019
ConglomerateController base_cc =
2020            tc.openConglomerate(
2021                create_ret.base_conglomid,
2022                false,
2023                TransactionController.OPENMODE_FORUPDATE,
2024                TransactionController.MODE_RECORD,
2025                TransactionController.ISOLATION_SERIALIZABLE);
2026
2027        // Open the index conglomerate.
2028
ConglomerateController index_cc =
2029            tc.openConglomerate(
2030                create_ret.index_conglomid,
2031                false,
2032                TransactionController.OPENMODE_FORUPDATE,
2033                TransactionController.MODE_RECORD,
2034                TransactionController.ISOLATION_SERIALIZABLE);
2035
2036        // Create a base row template.
2037
DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2038        RowLocation base_rowloc = base_cc.newRowLocationTemplate();
2039
2040        T_SecondaryIndexRow index_row_from_base_row = new T_SecondaryIndexRow();
2041        index_row_from_base_row.init(base_row, base_rowloc, 3);
2042        ((SQLLongint)base_row[0]).setValue(1);
2043
2044        // Create a row.
2045
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2046        index_row.init(TemplateRow.newU8Row(2),
2047                        base_cc.newRowLocationTemplate(), 3);
2048
2049        // test: make sure scan position is right after inserts before scan
2050
// no split case. In this case the slot position of the current
2051
// position should change, but the code will keep a record handle
2052
// and not need to reposition by key.
2053
// before keys: 1000, 3000
2054
// last key gotten froms scan : 0
2055
// insert keys:1-900
2056
// next key from scan should be: 5
2057

2058        // insert 1000
2059
((SQLLongint)base_row[1]).setValue(1000);
2060        base_cc.insertAndFetchLocation(base_row, base_rowloc);
2061        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
2062        {
2063            throw T_Fail.testFailMsg("insert failed");
2064        }
2065
2066        // open a new scan
2067

2068        ScanController scan =
2069            tc.openScan(create_ret.index_conglomid, false,
2070                        0,
2071                        TransactionController.MODE_RECORD,
2072                        TransactionController.ISOLATION_SERIALIZABLE,
2073                        (FormatableBitSet) null,
2074                        null, ScanController.NA,
2075                        null,
2076                        null, ScanController.NA);
2077
2078        if (SanityManager.DEBUG)
2079            SanityManager.ASSERT(scan.next());
2080
2081        scan.fetch(index_row.getRow());
2082        long key = ((SQLLongint)(index_row.getRow()[1])).getLong();
2083
2084        if (SanityManager.DEBUG)
2085            SanityManager.ASSERT(key == 1000);
2086
2087        // The following test works best if 5 rows fit on one page
2088

2089        //for (int i = 1; i < 900; i++)
2090
for (int i = 0; i < 6; i++)
2091        {
2092            // insert i
2093
((SQLLongint)base_row[1]).setValue(i);
2094            base_cc.insertAndFetchLocation(base_row, base_rowloc);
2095
2096            if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
2097            {
2098                throw T_Fail.testFailMsg("insert failed");
2099            }
2100
2101            // About every 2nd split page, recheck the position
2102

2103            if (i % 10 == 0)
2104            {
2105                // current position should not have changed
2106
scan.fetch(index_row.getRow());
2107                key = ((SQLLongint)(index_row.getRow()[1])).getLong();
2108                if (SanityManager.DEBUG)
2109                    SanityManager.ASSERT(key == 1000);
2110            }
2111
2112        }
2113
2114        // insert 3000
2115
((SQLLongint)base_row[1]).setValue(3000);
2116        base_cc.insertAndFetchLocation(base_row, base_rowloc);
2117        if (index_cc.insert(index_row_from_base_row.getRow()) != 0)
2118        {
2119            throw T_Fail.testFailMsg("insert failed");
2120        }
2121
2122        // current position should not have changed
2123
scan.fetch(index_row.getRow());
2124        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
2125
2126        if (SanityManager.DEBUG)
2127            SanityManager.ASSERT(key == 1000);
2128
2129        // next position should be 3000
2130
if (SanityManager.DEBUG)
2131            SanityManager.ASSERT(scan.next());
2132        scan.fetch(index_row.getRow());
2133        key = ((SQLLongint)(index_row.getRow()[1])).getLong();
2134
2135        if (SanityManager.DEBUG)
2136            SanityManager.ASSERT(key == 3000);
2137
2138        index_cc.checkConsistency();
2139
2140        index_cc.close();
2141        scan.close();
2142
2143        REPORT("Ending t_008");
2144
2145        return(ret_val);
2146    }
2147
2148    /**
2149     * Test unique/nonunique indexes - both positive and negative cases.
2150     * <p>
2151     *
2152     * @exception StandardException Standard exception policy.
2153     * @exception T_Fail Throws T_Fail on any test failure.
2154     **/

2155    protected boolean t_009(TransactionController tc)
2156        throws StandardException, T_Fail
2157    {
2158        ScanController scan = null;
2159
2160        REPORT("Starting t_009");
2161
2162        // NON-UNIQUE INDEX
2163
T_CreateConglomRet create_ret = new T_CreateConglomRet();
2164
2165        createCongloms(tc, 2, false, false, 2, create_ret);
2166
2167        // Open the base table
2168
ConglomerateController base_cc =
2169            tc.openConglomerate(
2170                create_ret.base_conglomid,
2171                false,
2172                TransactionController.OPENMODE_FORUPDATE,
2173                TransactionController.MODE_RECORD,
2174                TransactionController.ISOLATION_SERIALIZABLE);
2175
2176        // Open the secondary index
2177
ConglomerateController index_cc =
2178            tc.openConglomerate(
2179                create_ret.index_conglomid,
2180                false,
2181                TransactionController.OPENMODE_FORUPDATE,
2182                TransactionController.MODE_RECORD,
2183                TransactionController.ISOLATION_SERIALIZABLE);
2184
2185        // Create a row and insert into base table, remembering it's location.
2186
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
2187        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2188        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2189
2190        index_row1.init(r1, base_rowloc1, 3);
2191
2192        ((SQLLongint)r1[0]).setValue(1);
2193        ((SQLLongint)r1[1]).setValue(1000);
2194
2195        // Insert the row into the base table;remember its location.
2196
base_cc.insertAndFetchLocation(r1, base_rowloc1);
2197
2198        // Insert the row into the secondary index.
2199
if (index_cc.insert(index_row1.getRow()) != 0)
2200            throw T_Fail.testFailMsg("insert failed");
2201
2202        if (index_cc.insert(index_row1.getRow()) !=
2203                ConglomerateController.ROWISDUPLICATE)
2204        {
2205            throw T_Fail.testFailMsg(
2206                "insert of duplicate returned wrong return value:");
2207        }
2208
2209        // Delete the only entry and make sure it can be reinserted in same
2210
// xact.
2211
DataValueDescriptor[] delete_key = TemplateRow.newU8Row(2);
2212        ((SQLLongint)delete_key[0]).setValue(1);
2213        ((SQLLongint)delete_key[1]).setValue(1000);
2214
2215        if (!t_delete(tc, create_ret.index_conglomid,
2216                 delete_key, create_ret.index_template_row))
2217        {
2218            throw T_Fail.testFailMsg(
2219                "t_008: could not delete key.");
2220        }
2221
2222        if (index_cc.insert(index_row1.getRow()) != 0)
2223            throw T_Fail.testFailMsg("insert failed");
2224
2225        tc.commit();
2226
2227        // UNIQUE INDEX
2228
create_ret = new T_CreateConglomRet();
2229
2230        // Create the btree so that it only allows 2 rows per page.
2231
createCongloms(tc, 2, true, false, 2, create_ret);
2232
2233        // Open the base table
2234
base_cc = tc.openConglomerate(
2235                create_ret.base_conglomid,
2236                false,
2237                TransactionController.OPENMODE_FORUPDATE,
2238                TransactionController.MODE_RECORD,
2239                TransactionController.ISOLATION_SERIALIZABLE);
2240
2241        // Open the secondary index
2242
index_cc = tc.openConglomerate(
2243                create_ret.index_conglomid,
2244                false,
2245                TransactionController.OPENMODE_FORUPDATE,
2246                TransactionController.MODE_RECORD,
2247                TransactionController.ISOLATION_SERIALIZABLE);
2248
2249        // Create a row and insert into base table, remembering it's location.
2250
r1 = TemplateRow.newU8Row(2);
2251        index_row1 = new T_SecondaryIndexRow();
2252        base_rowloc1 = base_cc.newRowLocationTemplate();
2253
2254        index_row1.init(r1, base_rowloc1, 3);
2255
2256        ((SQLLongint)r1[0]).setValue(1);
2257        ((SQLLongint)r1[1]).setValue(1000);
2258
2259        // Insert the row into the base table;remember its location.
2260
base_cc.insertAndFetchLocation(r1, base_rowloc1);
2261
2262        // Insert the row into the secondary index.
2263
if (index_cc.insert(index_row1.getRow()) != 0)
2264            throw T_Fail.testFailMsg("insert failed");
2265
2266        // Insert the row into the base table;remember its location.
2267
base_cc.insertAndFetchLocation(r1, base_rowloc1);
2268
2269        // Insert the row into the secondary index.
2270
if (index_cc.insert(index_row1.getRow()) !=
2271                ConglomerateController.ROWISDUPLICATE)
2272        {
2273            throw T_Fail.testFailMsg(
2274                "insert of duplicate returned wrong return value:");
2275        }
2276
2277        // Delete the only entry and make sure it can be reinserted in same
2278
// xact.
2279
delete_key = TemplateRow.newU8Row(2);
2280        ((SQLLongint)delete_key[0]).setValue(1);
2281        ((SQLLongint)delete_key[1]).setValue(1000);
2282
2283        if (!t_delete(tc, create_ret.index_conglomid,
2284                 delete_key, create_ret.index_template_row))
2285        {
2286            throw T_Fail.testFailMsg(
2287                "t_008: could not delete key.");
2288        }
2289
2290
2291        if (index_cc.insert(index_row1.getRow()) != 0)
2292            throw T_Fail.testFailMsg("insert failed");
2293
2294        REPORT("Ending t_009");
2295
2296        return(true);
2297    }
2298
2299    /**
2300     * Test restoreToNull
2301     *
2302     *
2303     * @exception StandardException Standard exception policy.
2304     * @exception T_Fail Throws T_Fail on any test failure.
2305     */

2306    protected boolean t_010(TransactionController tc)
2307        throws StandardException, T_Fail
2308    {
2309        REPORT("Starting t_006");
2310
2311        B2I testbtree = new B2I();
2312
2313        // test restoreToNull()
2314
testbtree.restoreToNull();
2315
2316        if (!(testbtree.isNull()))
2317            throw T_Fail.testFailMsg("bad restoreToNull/isNull");
2318
2319        // test bad container open not working.
2320
try
2321        {
2322
2323            // the following open should fail with a containerNotFound error
2324

2325            // for testing purposes - assume TransactionController can be casted
2326
TransactionManager tm = (TransactionManager) tc;
2327            ConglomerateController cc =
2328                testbtree.open(
2329                    tm, tm.getRawStoreXact(), false, 0, 0,
2330                    (LockingPolicy) null,
2331                    null, null);
2332
2333            throw T_Fail.testFailMsg("bad open succeeded.");
2334        }
2335        catch(StandardException t)
2336        {
2337            // expected path comes here.
2338
}
2339
2340
2341        // create the base table
2342
DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2343        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2344
2345        long base_conglomid = tc.createConglomerate(
2346                                        "heap", // create a heap conglomerate
2347
base_row, // base table template row
2348
null, //column sort order - not required for heap
2349
null, // default properties
2350
TransactionController.IS_DEFAULT);
2351        // Open the base table
2352
ConglomerateController base_cc =
2353            tc.openConglomerate(
2354                base_conglomid,
2355                false,
2356                0,
2357                TransactionController.MODE_RECORD,
2358                TransactionController.ISOLATION_SERIALIZABLE);
2359
2360        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2361
2362        index_row1.init(base_row, base_rowloc1, 3);
2363
2364        // create the secondary index
2365
Properties JavaDoc properties =
2366            createProperties(
2367                null, // no current properties list
2368
false, // don't allow duplicates
2369
3, // index on all base row cols + row location
2370
2, // non-unique index
2371
true, // maintain parent links
2372
-42, // fake base conglom for now
2373
2); // row loc in last column
2374

2375        TransactionManager tm = (TransactionManager) tc;
2376
2377        // test bad property
2378
try
2379        {
2380            testbtree.create(
2381                tm, -1, ContainerHandle.DEFAULT_ASSIGN_ID, index_row1.getRow(),
2382                null, null, TransactionController.IS_TEMPORARY);
2383
2384            throw T_Fail.testFailMsg("bad create succeeded.");
2385        }
2386        catch (StandardException t)
2387        {
2388            // expected path comes here.
2389
}
2390
2391        // try bad properties
2392

2393        // create the secondary index
2394
properties = createProperties(
2395                            null, // no current properties list
2396
false, // don't allow duplicates
2397
3, // index on all base row cols + row location
2398
1, // 1 unique field leaving 1 non key field
2399
// other than the rowlocation - should not be
2400
// allowed.
2401
true, // maintain parent links
2402
-42, // fake base conglom for now
2403
2); // row loc in last column
2404
try
2405        {
2406            long index_conglomid =
2407                tc.createConglomerate(
2408                    "BTREE", // create a btree secondary
2409
index_row1.getRow(), // row template
2410
null, //column sort order - default
2411
properties, // properties
2412
TransactionController.IS_DEFAULT); // not temporary
2413

2414            throw T_Fail.testFailMsg("bad create succeeded.");
2415
2416        }
2417        catch (Throwable JavaDoc t)
2418        {
2419            // expected path comes here
2420
}
2421
2422
2423        REPORT("Ending t_010");
2424        return(true);
2425    }
2426
2427    /**
2428     * Test Special cases of split.
2429     * <p>
2430     * Testing: restartSplitFor() call in LeafControlRow().
2431     *
2432     * The first case is where we split
2433     * down the tree and reach the leaf, pick a split point, and then find
2434     * that there is not enough room to insert row into parent branch page.
2435     *
2436     * The second case is the same as the first except the calling code is
2437     * trying to split a branch page and the parent branch page doesn't have
2438     * room for the row.
2439     *
2440     * @exception StandardException Standard exception policy.
2441     * @exception T_Fail Throws T_Fail on any test failure.
2442     **/

2443    protected boolean t_011(TransactionController tc)
2444        throws StandardException, T_Fail
2445    {
2446        boolean ret_val = true;
2447
2448        REPORT("Starting t_011");
2449
2450        T_CreateConglomRet create_ret = new T_CreateConglomRet();
2451
2452        createCongloms(tc, 2, false, true, 0, create_ret);
2453
2454        // Open the base conglomerate.
2455
ConglomerateController base_cc =
2456            tc.openConglomerate(
2457                create_ret.base_conglomid,
2458                false,
2459                TransactionController.OPENMODE_FORUPDATE,
2460                TransactionController.MODE_RECORD,
2461                TransactionController.ISOLATION_SERIALIZABLE);
2462
2463        // Open the index conglomerate.
2464
ConglomerateController index_cc =
2465            tc.openConglomerate(
2466                create_ret.index_conglomid,
2467                false,
2468                TransactionController.OPENMODE_FORUPDATE,
2469                TransactionController.MODE_RECORD,
2470                TransactionController.ISOLATION_SERIALIZABLE);
2471
2472
2473        // Create a row.
2474
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2475        RowLocation rowloc = base_cc.newRowLocationTemplate();
2476        DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2477        base_row[0] = new SQLChar("aaaaaaaaaa");
2478        index_row.init(base_row, rowloc, 3);
2479
2480        ((SQLChar)base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2481        ((SQLLongint)base_row[1]).setValue(1);
2482        base_cc.insertAndFetchLocation(base_row, rowloc);
2483
2484        // CAUSE LEAF splitFor to loop:
2485
// pick numbers so that split will happen in middle of page. Do this
2486
// by first inserting last row in table and then insert smaller rows,
2487
// then insert rows before it until the table is just ready to split
2488
// the root, and finally insert some shorter rows in such a way as
2489
// they cause a split but the split point is chosen with one of the
2490
// larger rows as the descriminator causing 1st splitfor pass to fail
2491
// and loop back and do a splitFor the larger row.
2492

2493        ((SQLChar)base_row[0]).setValue(T_b2i.repeatString("m", 1000));
2494        {
2495            ((SQLLongint)base_row[1]).setValue(0);
2496            base_cc.insertAndFetchLocation(base_row, rowloc);
2497
2498            if (index_cc.insert(index_row.getRow()) != 0)
2499                throw T_Fail.testFailMsg("insert failed");
2500        }
2501
2502        // insert enough rows to make a 2 level btree where if another row
2503
// with a 1000 byte string would cause a root split.
2504
((SQLChar)base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2505        for (int i = 0; i < 5; i++)
2506        {
2507            ((SQLLongint)base_row[1]).setValue(i);
2508            base_cc.insertAndFetchLocation(base_row, rowloc);
2509
2510            if (index_cc.insert(index_row.getRow()) != 0)
2511                throw T_Fail.testFailMsg("insert failed");
2512        }
2513
2514        // insert a shorter leaf row, such that it will fit in the root, but
2515
// make the split point pick a longer row descriminator which won't
2516
// fit in the root page.
2517
((SQLChar)base_row[0]).setValue(T_b2i.repeatString("z", 500));
2518        for (int i = 10; i > 8; i--)
2519        {
2520            ((SQLLongint)base_row[1]).setValue(i);
2521            base_cc.insertAndFetchLocation(base_row, rowloc);
2522
2523            if (index_cc.insert(index_row.getRow()) != 0)
2524                throw T_Fail.testFailMsg("insert failed");
2525        }
2526
2527        index_cc.checkConsistency();
2528
2529        // Close the conglomerate.
2530
index_cc.close();
2531
2532        tc.dropConglomerate(create_ret.index_conglomid);
2533        tc.dropConglomerate(create_ret.base_conglomid);
2534
2535        tc.abort();
2536
2537        REPORT("Ending t_011");
2538
2539        return(ret_val);
2540    }
2541    /**
2542     * Test Special cases of split.
2543     * <p>
2544     * Testing: restartSplitFor() call in BranchControlRow().
2545     *
2546     * The second case is the same as the first except the calling code is
2547     * trying to split a branch page and the parent branch page doesn't have
2548     * room for the row.
2549     *
2550     * @exception StandardException Standard exception policy.
2551     * @exception T_Fail Throws T_Fail on any test failure.
2552     **/

2553    protected boolean t_012(TransactionController tc)
2554        throws StandardException, T_Fail
2555    {
2556        boolean ret_val = true;
2557
2558        REPORT("Starting t_011");
2559
2560        T_CreateConglomRet create_ret = new T_CreateConglomRet();
2561
2562        createCongloms(tc, 2, false, true, 0, create_ret);
2563
2564        // Open the base conglomerate.
2565
ConglomerateController base_cc =
2566            tc.openConglomerate(
2567                create_ret.base_conglomid,
2568                false,
2569                TransactionController.OPENMODE_FORUPDATE,
2570                TransactionController.MODE_RECORD,
2571                TransactionController.ISOLATION_SERIALIZABLE);
2572
2573        // Open the index conglomerate.
2574
ConglomerateController index_cc =
2575            tc.openConglomerate(
2576                create_ret.index_conglomid,
2577                false,
2578                TransactionController.OPENMODE_FORUPDATE,
2579                TransactionController.MODE_RECORD,
2580                TransactionController.ISOLATION_SERIALIZABLE);
2581
2582
2583        // Create a row.
2584
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
2585        RowLocation rowloc = base_cc.newRowLocationTemplate();
2586        DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2587        base_row[0] = new SQLChar("aaaaaaaaaa");
2588        index_row.init(base_row, rowloc, 3);
2589
2590        ((SQLChar)base_row[0]).setValue(T_b2i.repeatString("a", 1000));
2591        ((SQLLongint)base_row[1]).setValue(1);
2592        base_cc.insertAndFetchLocation(base_row, rowloc);
2593
2594
2595        // CAUSE BRANCH splitFor to loop:
2596
// pick numbers so that split will happen in middle of page. Do this
2597
// by first inserting last row in table and then insert smaller rows,
2598
// then insert rows before it until the table is just ready to split
2599
// the root, and finally insert some shorter rows in such a way as
2600
// they cause a split but the split point is chosen with one of the
2601
// larger rows as the descriminator causing 1st splitfor pass to fail
2602
// and loop back and do a splitFor the larger row.
2603

2604
2605        // insert enough rows so the tree is 3 levels, just ready to go to
2606
// 4 levels.
2607
((SQLChar)base_row[0]).setValue(T_b2i.repeatString("ma", 500));
2608        for (int i = 0; i < 3; i++)
2609        {
2610            ((SQLLongint)base_row[1]).setValue(i);
2611            base_cc.insertAndFetchLocation(base_row, rowloc);
2612
2613            if (index_cc.insert(index_row.getRow()) != 0)
2614                throw T_Fail.testFailMsg("insert failed");
2615        }
2616        ((SQLChar)base_row[0]).setValue(T_b2i.repeatString("m", 1000));
2617        for (int i = 3; i < 23; i++)
2618        {
2619            ((SQLLongint)base_row[1]).setValue(i);
2620            base_cc.insertAndFetchLocation(base_row, rowloc);
2621
2622            if (index_cc.insert(index_row.getRow()) != 0)
2623                throw T_Fail.testFailMsg("insert failed");
2624        }
2625        
2626        ((SQLChar)base_row[0]).setValue(T_b2i.repeatString("a", 600));
2627        for (int i = 123; i > 111; i--)
2628        {
2629            ((SQLLongint)base_row[1]).setValue(i * 2);
2630            base_cc.insertAndFetchLocation(base_row, rowloc);
2631
2632            if (index_cc.insert(index_row.getRow()) != 0)
2633                throw T_Fail.testFailMsg("insert failed");
2634        }
2635        {
2636            ((SQLLongint)base_row[1]).setValue(227);
2637            base_cc.insertAndFetchLocation(base_row, rowloc);
2638
2639            if (index_cc.insert(index_row.getRow()) != 0)
2640                throw T_Fail.testFailMsg("insert failed");
2641        }
2642
2643        // ((B2IController)index_cc).printTree();
2644
tc.commit();
2645
2646        // Close the conglomerate.
2647
index_cc.close();
2648
2649
2650        REPORT("Ending t_012");
2651
2652        return(ret_val);
2653    }
2654
2655    /**
2656     * Test backout during critical times of splits.
2657     * <p>
2658     * Force logical undo of an operation which generated an internal update
2659     * of a btree record:
2660     * case 1:
2661     * o insert into unique btree key1, rowlocation_1
2662     * o delete from btree key1, rowlocation_1
2663     * - this will mark the record logically deleted.
2664     * o insert enough records to move the logically deleted row to another
2665     * page to exercise logical undo of the delete.
2666     * o insert into btree key1, rowlocation_2
2667     * - this internally will generate a logical update field on the
2668     * record.
2669     * o insert enough records to move the logically deleted row to another
2670     * page to exercise logical undo of the delete.
2671     * o abort.
2672     *
2673     * case 2:
2674     * o same as case 1 but don't change the rowlocation_1 value. This
2675     * simulates what the language will generate on an update of a key
2676     * field.
2677     *
2678     *
2679     * @exception StandardException Standard exception policy.
2680     * @exception T_Fail Throws T_Fail on any test failure.
2681     **/

2682    protected boolean t_013(TransactionController tc)
2683        throws StandardException, T_Fail
2684    {
2685        ScanController scan = null;
2686
2687        // SanityManager.DEBUG_SET("LockTrace");
2688

2689        REPORT("Starting t_013");
2690
2691        T_CreateConglomRet create_ret = new T_CreateConglomRet();
2692
2693        // Create the btree so that it only allows 2 rows per page.
2694
createCongloms(tc, 2, true, false, 5, create_ret);
2695
2696        // Open the base table
2697
ConglomerateController base_cc =
2698            tc.openConglomerate(
2699                create_ret.base_conglomid,
2700                false,
2701                TransactionController.OPENMODE_FORUPDATE,
2702                TransactionController.MODE_RECORD,
2703                TransactionController.ISOLATION_SERIALIZABLE);
2704
2705        // Open the secondary index
2706
ConglomerateController index_cc =
2707            tc.openConglomerate(
2708                create_ret.index_conglomid,
2709                false,
2710                TransactionController.OPENMODE_FORUPDATE,
2711                TransactionController.MODE_RECORD,
2712                TransactionController.ISOLATION_SERIALIZABLE);
2713
2714        // Create an index row object for the "delete row"
2715
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
2716        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2717        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2718
2719        index_row1.init(r1, base_rowloc1, 3);
2720
2721        // Create another index row object for the other inserts.
2722
DataValueDescriptor[] r2 = TemplateRow.newU8Row(2);
2723        T_SecondaryIndexRow index_row2 = new T_SecondaryIndexRow();
2724        RowLocation base_rowloc2 = base_cc.newRowLocationTemplate();
2725
2726        index_row2.init(r2, base_rowloc2, 3);
2727
2728        // Commit the create of the tables so that the following aborts don't
2729
// undo that work.
2730
tc.commit();
2731
2732        // CASE 1:
2733
tc.commit();
2734
2735        // Open the base table
2736
base_cc = tc.openConglomerate(
2737                create_ret.base_conglomid,
2738                false,
2739                TransactionController.OPENMODE_FORUPDATE,
2740                TransactionController.MODE_RECORD,
2741                TransactionController.ISOLATION_SERIALIZABLE);
2742
2743        // Open the secondary index
2744
index_cc = tc.openConglomerate(
2745                create_ret.index_conglomid,
2746                false,
2747                TransactionController.OPENMODE_FORUPDATE,
2748                TransactionController.MODE_RECORD,
2749                TransactionController.ISOLATION_SERIALIZABLE);
2750
2751        ((SQLLongint)r1[0]).setValue(1);
2752
2753        // insert row which will be deleted (key = 100, base_rowloc1):
2754
((SQLLongint)r1[1]).setValue(100);
2755        base_cc.insertAndFetchLocation(r1, base_rowloc1);
2756
2757        // Insert the row into the secondary index.
2758
if (index_cc.insert(index_row1.getRow()) != 0)
2759            throw T_Fail.testFailMsg("insert failed");
2760
2761        // insert enough rows so that the logical undo of the insert will
2762
// need to search the tree. The tree has been set to split after
2763
// 5 rows are on a page, so 10 should be plenty.
2764
for (int i = 0; i < 10; i++)
2765        {
2766            ((SQLLongint)r2[1]).setValue(i);
2767
2768            // Insert the row into the base table;remember its location.
2769
base_cc.insertAndFetchLocation(r2, base_rowloc2);
2770
2771            // Insert the row into the secondary index.
2772
if (index_cc.insert(index_row2.getRow()) != 0)
2773                throw T_Fail.testFailMsg("insert failed");
2774        }
2775
2776        // delete row which was inserted (key = 100, base_rowloc1):
2777
if (!t_delete(tc, create_ret.index_conglomid,
2778                index_row1.getRow(), create_ret.index_template_row))
2779        {
2780            throw T_Fail.testFailMsg(
2781                "t_008: could not delete key.");
2782        }
2783        base_cc.delete(base_rowloc1);
2784
2785        // insert enough rows so that the logical undo of the delete will
2786
// need to search the tree. The tree has been set to split after
2787
// 5 rows are on a page, so 10 should be plenty.
2788
for (int i = 10; i < 20; i++)
2789        {
2790            ((SQLLongint)r2[1]).setValue(i);
2791
2792            // Insert the row into the base table;remember its location.
2793
base_cc.insertAndFetchLocation(r2, base_rowloc2);
2794
2795            // Insert the row into the secondary index.
2796
if (index_cc.insert(index_row2.getRow()) != 0)
2797                throw T_Fail.testFailMsg("insert failed");
2798        }
2799
2800        // insert row which will be deleted (key = 100, base_rowloc1):
2801
((SQLLongint)r1[1]).setValue(100);
2802        base_cc.insertAndFetchLocation(r1, base_rowloc1);
2803
2804        // Insert the row into the secondary index.
2805
if (index_cc.insert(index_row1.getRow()) != 0)
2806            throw T_Fail.testFailMsg("insert failed");
2807
2808        // insert enough rows so that the logical undo of the update field will
2809
// need to search the tree. The tree has been set to split after
2810
// 5 rows are on a page, so 10 should be plenty.
2811
for (int i = 20; i < 30; i++)
2812        {
2813            ((SQLLongint)r2[1]).setValue(i);
2814
2815            // Insert the row into the base table;remember its location.
2816
base_cc.insertAndFetchLocation(r2, base_rowloc2);
2817
2818            // Insert the row into the secondary index.
2819
if (index_cc.insert(index_row2.getRow()) != 0)
2820                throw T_Fail.testFailMsg("insert failed");
2821        }
2822
2823        // RESOLVE (mikem) - check that the right row is at key 100.
2824

2825
2826        tc.abort();
2827
2828        // index check - there should be no records left.
2829
ScanController empty_scan =
2830            tc.openScan(create_ret.index_conglomid, false,
2831                        0,
2832                        TransactionController.MODE_RECORD,
2833                        TransactionController.ISOLATION_SERIALIZABLE,
2834                        (FormatableBitSet) null,
2835                        null, ScanController.NA,
2836                        null,
2837                        null, ScanController.NA);
2838
2839        if (empty_scan.next())
2840            throw T_Fail.testFailMsg("t_002: there are still rows in table.");
2841
2842        tc.commit();
2843        REPORT("Ending t_013");
2844
2845        return true;
2846    }
2847
2848    /**
2849     * Test getTableProperties() of BTreeController.
2850     * <p>
2851     *
2852     *
2853     * @exception StandardException Standard exception policy.
2854     * @exception T_Fail Throws T_Fail on any test failure.
2855     **/

2856    protected boolean t_014(TransactionController tc)
2857        throws StandardException, T_Fail
2858    {
2859        ScanController scan = null;
2860
2861        // SanityManager.DEBUG_SET("LockTrace");
2862

2863        REPORT("Starting t_014");
2864
2865
2866        // create the base table
2867
DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
2868        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
2869
2870        long base_conglomid =
2871            tc.createConglomerate(
2872                "heap", // create a heap conglomerate
2873
base_row, // base table template row
2874
null, //column sort order - not required for heap
2875
null, // default properties
2876
TransactionController.IS_DEFAULT);
2877
2878        // Open the base table
2879
ConglomerateController base_cc =
2880            tc.openConglomerate(
2881                base_conglomid,
2882                false,
2883                0,
2884                TransactionController.MODE_RECORD,
2885                TransactionController.ISOLATION_SERIALIZABLE);
2886
2887        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
2888
2889        index_row1.init(base_row, base_rowloc1, 3);
2890
2891        // create the secondary index
2892
Properties JavaDoc properties =
2893            createProperties(
2894                null, // no current properties list
2895
false, // don't allow duplicates
2896
3, // index on all base row cols + row location
2897
2, // non-unique index
2898
true, // maintain parent links
2899
base_conglomid, // fake base conglom for now
2900
2); // row loc in last column
2901

2902        properties.put(Property.PAGE_SIZE_PARAMETER, "8192");
2903        properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, "99");
2904        properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, "42");
2905
2906        TransactionManager tm = (TransactionManager) tc;
2907
2908        // Create a index.
2909
long conglomid =
2910            tc.createConglomerate(
2911                "BTREE", // create a heap conglomerate
2912
index_row1.getRow(), // 1 column template.
2913
null, //column sort order - default
2914
properties, // default properties
2915
TransactionController.IS_DEFAULT); // not temporary
2916

2917        // Open the conglomerate.
2918
ConglomerateController cc =
2919            tc.openConglomerate(
2920                conglomid,
2921                false,
2922                TransactionController.OPENMODE_FORUPDATE,
2923                TransactionController.MODE_RECORD,
2924                TransactionController.ISOLATION_SERIALIZABLE);
2925
2926        // verify that input properties were used.
2927
Properties JavaDoc ret_prop = new Properties JavaDoc();
2928        ret_prop.put(Property.PAGE_SIZE_PARAMETER, "");
2929        ret_prop.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, "");
2930        ret_prop.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, "");
2931
2932        cc.getTableProperties(ret_prop);
2933
2934        if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER).
2935                compareTo("8192") != 0 ||
2936            ret_prop.getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER).
2937                compareTo("0") != 0 ||
2938            ret_prop.getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER).
2939                compareTo("1") != 0)
2940        {
2941            throw T_Fail.testFailMsg(
2942                "(getTableProperties) Did not get expected table propertes." +
2943                "\nGot pageSize = " +
2944                    ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER) +
2945                "\nGot reserved = " +
2946                    ret_prop.getProperty(
2947                        RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER) +
2948                "\nGot minimum record size = " +
2949                    ret_prop.getProperty(
2950                        RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER));
2951        }
2952
2953        tc.commit();
2954
2955        REPORT("Ending t_014");
2956        return(true);
2957    }
2958
2959    /**
2960     * Test latch release during critical time during row level locking.
2961     * <p>
2962     * Use trace points to force errors in split at critical points:
2963     * leaf_split_abort{1,2,3,4}
2964     *
2965     * @exception StandardException Standard exception policy.
2966     * @exception T_Fail Throws T_Fail on any test failure.
2967     **/

2968    protected boolean t_015(TransactionController tc)
2969        throws StandardException, T_Fail
2970    {
2971        ScanController scan = null;
2972
2973        // SanityManager.DEBUG_SET("LockTrace");
2974

2975        REPORT("Starting t_015");
2976
2977        T_CreateConglomRet create_ret = new T_CreateConglomRet();
2978
2979        // Create the btree so that it only allows 2 rows per page.
2980
createCongloms(tc, 2, false, false, 2, create_ret);
2981
2982        // Open the base table
2983
ConglomerateController base_cc =
2984            tc.openConglomerate(
2985                create_ret.base_conglomid,
2986                false,
2987                TransactionController.OPENMODE_FORUPDATE,
2988                TransactionController.MODE_RECORD,
2989                TransactionController.ISOLATION_SERIALIZABLE);
2990
2991        // Open the secondary index
2992
ConglomerateController index_cc =
2993            tc.openConglomerate(
2994                create_ret.index_conglomid,
2995                false,
2996                TransactionController.OPENMODE_FORUPDATE,
2997                TransactionController.MODE_RECORD,
2998                TransactionController.ISOLATION_SERIALIZABLE);
2999
3000        if (!(index_cc instanceof B2IController))
3001        {
3002            throw T_Fail.testFailMsg("openConglomerate returned wrong type");
3003        }
3004
3005        index_cc.checkConsistency();
3006
3007        // Create a row and insert into base table, remembering it's location.
3008
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
3009        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
3010        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
3011
3012        index_row1.init(r1, base_rowloc1, 3);
3013
3014        // Commit the create of the tables so that the following aborts don't
3015
// undo that work.
3016
tc.commit();
3017
3018        // Now load up the table with multiple pages of data.
3019

3020        // Open the base table
3021
base_cc =
3022            tc.openConglomerate(
3023                create_ret.base_conglomid,
3024                false,
3025                TransactionController.OPENMODE_FORUPDATE,
3026                TransactionController.MODE_RECORD,
3027                TransactionController.ISOLATION_SERIALIZABLE);
3028
3029        // Open the secondary index
3030
index_cc =
3031            tc.openConglomerate(
3032                create_ret.index_conglomid,
3033                false,
3034                TransactionController.OPENMODE_FORUPDATE,
3035                TransactionController.MODE_RECORD,
3036                TransactionController.ISOLATION_SERIALIZABLE);
3037
3038        // now insert enough rows to cause failure
3039
for (int i = 100; i > 0; i -= 2)
3040        {
3041            ((SQLLongint)r1[0]).setValue(2);
3042            ((SQLLongint)r1[1]).setValue(i);
3043
3044            // Insert the row into the base table;remember its location.
3045
base_cc.insertAndFetchLocation(r1, base_rowloc1);
3046
3047            // Insert the row into the secondary index.
3048
if (index_cc.insert(index_row1.getRow()) != 0)
3049            {
3050                throw T_Fail.testFailMsg("insert failed");
3051            }
3052        }
3053
3054        // Now try simulated lock wait/latch release paths through the code.
3055
String JavaDoc[] latch_debug_strings = {
3056            "B2iRowLocking3_1_lockScanRow1",
3057            "B2iRowLocking3_2_lockScanRow1",
3058            "B2iRowLocking3_3_lockScanRow1",
3059            "BTreeScan_positionAtStartPosition1",
3060            "BTreeScan_positionAtNextPage1",
3061            // "BTreeScan_reposition1",
3062
"BTreeScan_fetchNextGroup1",
3063        };
3064
3065        for (int errs = 0; errs < latch_debug_strings.length; errs++)
3066        {
3067            REPORT("Doing latch release tests: " + latch_debug_strings[errs]);
3068
3069            // set the debug flag, which will cause a simulated lock wait
3070
// latch release path through the code.
3071
if (SanityManager.DEBUG)
3072                SanityManager.DEBUG_SET(latch_debug_strings[errs]);
3073
3074            // Just scan the rows and make sure you see them all, mostly just
3075
// a test to make sure no errors are thrown by the latch release
3076
// code paths.
3077
scan = tc.openScan(create_ret.index_conglomid, false,
3078                    0,
3079                    TransactionController.MODE_RECORD,
3080                    TransactionController.ISOLATION_SERIALIZABLE,
3081                    (FormatableBitSet) null,
3082                    null, ScanController.NA,
3083                    null,
3084                    null, ScanController.NA);
3085
3086            int row_count = 0;
3087            while (scan.next())
3088            {
3089                row_count++;
3090            }
3091
3092            scan.close();
3093
3094            if (row_count != 50)
3095                throw T_Fail.testFailMsg("wrong scan count = " + row_count);
3096        }
3097
3098        tc.abort();
3099        REPORT("Ending t_015");
3100
3101        return true;
3102    }
3103
3104    /**
3105     * Test deadlocks during critical times of row level locking.
3106     * <p>
3107     * Use trace points to force errors in split at critical points:
3108     * leaf_split_abort{1,2,3,4}
3109     *
3110     * @exception StandardException Standard exception policy.
3111     * @exception T_Fail Throws T_Fail on any test failure.
3112     **/

3113    protected boolean t_016(TransactionController tc)
3114        throws StandardException, T_Fail
3115    {
3116        ScanController scan = null;
3117
3118        // SanityManager.DEBUG_SET("LockTrace");
3119

3120        REPORT("Starting t_016");
3121
3122        T_CreateConglomRet create_ret = new T_CreateConglomRet();
3123
3124        // Create the btree so that it only allows 2 rows per page.
3125
createCongloms(tc, 2, false, false, 2, create_ret);
3126
3127        // Open the base table
3128
ConglomerateController base_cc =
3129            tc.openConglomerate(
3130                create_ret.base_conglomid,
3131                false,
3132                TransactionController.OPENMODE_FORUPDATE,
3133                TransactionController.MODE_RECORD,
3134                TransactionController.ISOLATION_SERIALIZABLE);
3135
3136        // Open the secondary index
3137
ConglomerateController index_cc =
3138            tc.openConglomerate(
3139                create_ret.index_conglomid,
3140                false,
3141                TransactionController.OPENMODE_FORUPDATE,
3142                TransactionController.MODE_RECORD,
3143                TransactionController.ISOLATION_SERIALIZABLE);
3144
3145        if (!(index_cc instanceof B2IController))
3146        {
3147            throw T_Fail.testFailMsg("openConglomerate returned wrong type");
3148        }
3149
3150        index_cc.checkConsistency();
3151
3152        // Create a row and insert into base table, remembering it's location.
3153
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
3154        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
3155        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
3156
3157        index_row1.init(r1, base_rowloc1, 3);
3158
3159        // Commit the create of the tables so that the following aborts don't
3160
// undo that work.
3161
tc.commit();
3162
3163        // Open the base table
3164
base_cc =
3165            tc.openConglomerate(
3166                create_ret.base_conglomid,
3167                false,
3168                TransactionController.OPENMODE_FORUPDATE,
3169                TransactionController.MODE_RECORD,
3170                TransactionController.ISOLATION_SERIALIZABLE);
3171
3172        // Open the secondary index
3173
index_cc =
3174            tc.openConglomerate(
3175                create_ret.index_conglomid,
3176                false,
3177                TransactionController.OPENMODE_FORUPDATE,
3178                TransactionController.MODE_RECORD,
3179                TransactionController.ISOLATION_SERIALIZABLE);
3180
3181        // now insert enough rows to cause failure
3182
for (int i = 100; i > 0; i -= 2)
3183        {
3184            ((SQLLongint)r1[0]).setValue(2);
3185            ((SQLLongint)r1[1]).setValue(i);
3186
3187            // Insert the row into the base table;remember its location.
3188
base_cc.insertAndFetchLocation(r1, base_rowloc1);
3189
3190            // Insert the row into the secondary index.
3191
if (index_cc.insert(index_row1.getRow()) != 0)
3192            {
3193                throw T_Fail.testFailMsg("insert failed");
3194            }
3195        }
3196
3197        tc.abort();
3198
3199        // Now try simulated deadlocks
3200
// RESOLVE (Mikem) - test out aborts and errors during inserts.
3201
String JavaDoc[] deadlock_debug_strings = {
3202            "B2iRowLocking3_1_lockScanRow2",
3203            "B2iRowLocking3_2_lockScanRow2",
3204            "B2iRowLocking3_3_lockScanRow2",
3205            // "BTreeController_doIns2",
3206
"BTreeScan_positionAtStartPosition2",
3207            "BTreeScan_positionAtNextPage2",
3208            // "BTreeScan_reposition2",
3209
"BTreeScan_fetchNextGroup2"
3210        };
3211
3212        for (int errs = 0; errs < deadlock_debug_strings.length; errs++)
3213        {
3214            try
3215            {
3216                REPORT("Doing deadlock tests: " + deadlock_debug_strings[errs]);
3217
3218                // set the debug flag, which will cause a simulated lock wait
3219
// latch release path through the code.
3220
if (SanityManager.DEBUG)
3221                    SanityManager.DEBUG_SET(deadlock_debug_strings[errs]);
3222
3223                // Just scan the rows and make sure you see them all, mostly just
3224
// a test to make sure no errors are thrown by the latch release
3225
// code paths.
3226
scan = tc.openScan(create_ret.index_conglomid, false,
3227                        0,
3228                        TransactionController.MODE_RECORD,
3229                        TransactionController.ISOLATION_SERIALIZABLE,
3230                        (FormatableBitSet) null,
3231                        null, ScanController.NA,
3232                        null,
3233                        null, ScanController.NA);
3234
3235                int row_count = 0;
3236                while (scan.next())
3237                {
3238                    row_count++;
3239                }
3240
3241                scan.close();
3242
3243                throw T_Fail.testFailMsg("expected deadlock");
3244            }
3245            catch (StandardException e)
3246            {
3247                if (!e.getMessageId().equals(SQLState.DEADLOCK))
3248                    throw e;
3249
3250                ContextService contextFactory =
3251                    ContextService.getFactory();
3252
3253                // Get the context manager.
3254
ContextManager cm = contextFactory.getCurrentContextManager();
3255
3256                if (SanityManager.DEBUG)
3257                    SanityManager.ASSERT(cm != null);
3258
3259                cm.cleanupOnError(e);
3260            }
3261        }
3262
3263        tc.commit();
3264        REPORT("Ending t_016");
3265
3266        return true;
3267    }
3268
3269    /**
3270     * Test simple btree insert performance
3271     *
3272     * @exception StandardException Standard exception policy.
3273     * @exception T_Fail Throws T_Fail on any test failure.
3274     */

3275    protected boolean t_perf(TransactionController tc)
3276        throws StandardException, T_Fail
3277    {
3278        boolean ret_val = true;
3279
3280        REPORT("Starting t_005");
3281
3282        T_CreateConglomRet create_ret = new T_CreateConglomRet();
3283
3284        createCongloms(tc, 2, false, false, 0, create_ret);
3285
3286        // Open the base conglomerate.
3287
ConglomerateController base_cc =
3288            tc.openConglomerate(
3289                create_ret.base_conglomid,
3290                false,
3291                TransactionController.OPENMODE_FORUPDATE,
3292                TransactionController.MODE_RECORD,
3293                TransactionController.ISOLATION_SERIALIZABLE);
3294
3295        // Open the index conglomerate.
3296
ConglomerateController index_cc =
3297            tc.openConglomerate(
3298                create_ret.index_conglomid,
3299                false,
3300                TransactionController.OPENMODE_FORUPDATE,
3301                TransactionController.MODE_RECORD,
3302                TransactionController.ISOLATION_SERIALIZABLE);
3303
3304        // Create a row.
3305
T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
3306        RowLocation rowloc = base_cc.newRowLocationTemplate();
3307        DataValueDescriptor[] base_row = TemplateRow.newU8Row(2);
3308        index_row.init(base_row, rowloc, 3);
3309
3310        ((SQLLongint)base_row[0]).setValue(1);
3311        ((SQLLongint)base_row[1]).setValue(1);
3312        base_cc.insertAndFetchLocation(base_row, rowloc);
3313
3314        long startms = System.currentTimeMillis();
3315
3316        // insert them in reverse order just to make sure btree is sorting them
3317
for (int i = 0; i < 2000; i++)
3318        {
3319            ((SQLLongint)base_row[1]).setValue(i);
3320            // base_cc.insertAndFetchLocation(base_row, rowloc);
3321
// ((HeapRowLocation)rowloc).setFrom(0xffffffffffffffffl, 0xfffffff);
3322

3323            if (index_cc.insert(index_row.getRow()) != 0)
3324                throw T_Fail.testFailMsg("insert failed");
3325        }
3326
3327        // ((B2IController)index_cc).printTree();
3328
tc.commit();
3329        long endms = System.currentTimeMillis();
3330        long elapsedms = endms - startms;
3331
3332        System.out.println(" Elapsed (ms) " + elapsedms);
3333        System.out.println(" inserts/second " + (1000 * 1000 / elapsedms));
3334
3335        // Close the conglomerate.
3336
index_cc.close();
3337
3338
3339        REPORT("Ending t_011");
3340
3341        return(ret_val);
3342    }
3343
3344   private boolean t_desc_scan_test_cases(
3345    TransactionController tc,
3346    long index_conglomid,
3347    T_SecondaryIndexRow template
3348    )
3349        throws StandardException, T_Fail
3350    {
3351        boolean ret_val = true;
3352
3353        // run through a predicates as described in the openScan() interface //
3354
DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
3355        DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
3356
3357
3358        // test predicate x = 5
3359
//
3360
// result set should be:{5,6,18}, {5,4,17}, {5,6,16} //descending
3361
//
3362
REPORT("scan (x = 5)");
3363        ((SQLLongint)start_key[0]).setValue(5);
3364        ((SQLLongint)stop_key[0]).setValue(5);
3365        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3366                   template.getRow(),
3367                   start_key, ScanController.GE,
3368                   null,
3369                   stop_key, ScanController.GT,
3370                   3, 18, T_QualifierTest.ORDER_DESC))
3371        {
3372            ret_val = false;
3373        }
3374                   
3375        // +---------------------------------------------------------+
3376
// |pred |start|key|stop |key|rows returned |rows locked |
3377
// | |value|op |value|op | |(serialization)|
3378
// +------+-----+---+-----+---+--------------+---------------+
3379
// |x > 5 |null |na |5 |GE |{9,1} .. {6,1}|{5,6} .. {9,1} |
3380
// +-----------------------------------------+---------------+
3381
REPORT("scan (x > 5)");
3382        ((SQLLongint)stop_key[0]).setValue(5);
3383        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3384                   template.getRow(),
3385                   null, ScanController.NA,
3386                   null,
3387                   stop_key, ScanController.GE,
3388                   3, 21, T_QualifierTest.ORDER_DESC))
3389        {
3390            ret_val = false;
3391        }
3392
3393        // +---------------------------------------------------------+
3394
// |pred |start|key|stop |key|rows returned |rows locked |
3395
// | |value|op |value|op | |(serialization)|
3396
// +------+-----+---+-----+---+--------------+---------------+
3397
// |x >= 5| null|na |5 |GT |{9,1} .. {5,2}|{4,6} .. {9,1} |
3398
// +-----------------------------------------+---------------+
3399
REPORT("scan (x >= 5)");
3400        ((SQLLongint)stop_key[0]).setValue(5);
3401        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3402                   template.getRow(),
3403                   null, ScanController.NA,
3404                   null,
3405                   stop_key, ScanController.GT,
3406                   6, 21, T_QualifierTest.ORDER_DESC))
3407        {
3408            ret_val = false;
3409        }
3410
3411        //
3412
// +---------------------------------------------------------+
3413
// |pred |start|key|stop |key|rows returned |rows locked |
3414
// | |value|op |value|op | |(serialization)|
3415
// +------+-----+---+-----+---+--------------+---------------+
3416
// |x <= 5|5 |GE |null |na |{5,6} .. {1,1}|first .. {5,6} |
3417
// +-----------------------------------------+---------------+
3418
REPORT("scan (x <= 5)");
3419        ((SQLLongint)start_key[0]).setValue(5);
3420        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3421                   template.getRow(),
3422                   start_key, ScanController.GE,
3423                   null,
3424                   null, ScanController.NA,
3425                   8, 18, T_QualifierTest.ORDER_DESC))
3426        {
3427            ret_val = false;
3428        }
3429        //
3430
// +---------------------------------------------------------+
3431
// |pred |start|key|stop |key|rows returned |rows locked |
3432
// | |value|op |value|op | |(serialization)|
3433
// +------+-----+---+-----+---+--------------+---------------+
3434
// |x < 5 |5 | GT|null | |{4,6} .. {1,1}|first .. {4,6} |
3435
// +-----------------------------------------+---------------+
3436
REPORT("scan (x < 5)");
3437        ((SQLLongint)start_key[0]).setValue(5);
3438        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3439                   template.getRow(),
3440                   start_key, ScanController.GT,
3441                   null,
3442                   null, ScanController.NA,
3443                   5, 15, T_QualifierTest.ORDER_DESC))
3444        {
3445            ret_val = false;
3446        }
3447
3448        //long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
3449
//long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
3450
//long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
3451
// +------------------------------------------------------------------+
3452
// |pred |start|key|stop |key|rows returned|rows locked |
3453
// | |value|op |value|op | |(serialized) |
3454
// +-----------------+------+--+-----+--+--------------+--------------+
3455
// |x >= 5 and x <= 7|{7}, |GE|{5} |GT|{5,2} .. {7,1}|{4,6} .. {7,1}|
3456
// +------------------------------------------------------------------+
3457
REPORT("scan (x >= 5 and x <= 7)");
3458        ((SQLLongint)start_key[0]).setValue(7);
3459        ((SQLLongint)stop_key[0]).setValue(5);
3460        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3461                   template.getRow(),
3462                   start_key, ScanController.GE,
3463                   null,
3464                   stop_key, ScanController.GT,
3465                   5, 20, T_QualifierTest.ORDER_DESC))
3466        {
3467            ret_val = false;
3468        }
3469
3470        // +------------------------------------------------------------------+
3471
// |pred |start|key|stop |key|rows returned|rows locked |
3472
// | |value|op |value|op | |(serialized) |
3473
// +-----------------+------+--+-----+--+--------------+--------------+
3474
// |x = 5 and y > 2 |{5} |GE|{5,2 |GE|{5,4} .. {5,6}|{5,2} .. {9,1}|
3475
// +------------------------------------------------------------------+
3476
REPORT("scan (x = 5 and y > 2)");
3477        start_key = TemplateRow.newU8Row(1);
3478        stop_key = TemplateRow.newU8Row(2);
3479        ((SQLLongint)start_key[0]).setValue(5);
3480        ((SQLLongint)stop_key[0]).setValue(5);
3481        ((SQLLongint)stop_key[1]).setValue(2);
3482        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3483                   template.getRow(),
3484                   start_key, ScanController.GE,
3485                   null,
3486                   stop_key, ScanController.GE,
3487                   2, 18, T_QualifierTest.ORDER_DESC))
3488        {
3489            ret_val = false;
3490        }
3491
3492        // +------------------------------------------------------------------+
3493
// |pred |start|key|stop |key|rows returned|rows locked |
3494
// | |value|op |value|op | |(serialized) |
3495
// +-----------------+------+--+-----+--+--------------+--------------+
3496
// |x = 5 and y >= 2 |{5} |GE|{5,2}|GT|{5,2} .. {5,6}|{4,6} .. {9,1}|
3497
// +------------------------------------------------------------------+
3498
REPORT("scan (x = 5 and y >= 2)");
3499        start_key = TemplateRow.newU8Row(1);
3500        stop_key = TemplateRow.newU8Row(2);
3501        ((SQLLongint)start_key[0]).setValue(5);
3502        ((SQLLongint)stop_key[0]).setValue(5);
3503        ((SQLLongint)stop_key[1]).setValue(2);
3504        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3505                   template.getRow(),
3506                   start_key, ScanController.GE,
3507                   null,
3508                   stop_key, ScanController.GT,
3509                   3, 18, T_QualifierTest.ORDER_DESC))
3510        {
3511            ret_val = false;
3512        }
3513
3514        // +------------------------------------------------------------------+
3515
// |pred |start|key|stop |key|rows returned|rows locked |
3516
// | |value|op |value|op | |(serialized) |
3517
// +-----------------+------+--+-----+--+--------------+--------------+
3518
// |x = 5 and y < 5 | {5,5}} |GE|{5}|GT|{5,2} .. {5,4}|{4,6} .. {5,4}|
3519
// +------------------------------------------------------------------+
3520
REPORT("scan (x = 5 and y < 5)");
3521        start_key = TemplateRow.newU8Row(2);
3522        stop_key = TemplateRow.newU8Row(1);
3523        ((SQLLongint)start_key[0]).setValue(5);
3524        ((SQLLongint)start_key[1]).setValue(5);
3525        ((SQLLongint)stop_key[0]).setValue(5);
3526        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3527                   template.getRow(),
3528                   start_key, ScanController.GE,
3529                   null,
3530                   stop_key, ScanController.GT,
3531                   2, 17, T_QualifierTest.ORDER_DESC))
3532        {
3533            ret_val = false;
3534        }
3535
3536        // +------------------------------------------------------------------+
3537
// |pred |start|key|stop |key|rows returned|rows locked |
3538
// | |value|op |value|op | |(serialized) |
3539
// +-----------------+------+--+-----+--+--------------+--------------+
3540
// |x = 2 | {2} |GE| {2} |GT|none |{1,1} .. {1,1}|
3541
// +------------------------------------------------------------------+
3542
REPORT("scan (x = 2)");
3543        start_key = TemplateRow.newU8Row(1);
3544        stop_key = TemplateRow.newU8Row(1);
3545        ((SQLLongint)start_key[0]).setValue(2);
3546        ((SQLLongint)stop_key[0]).setValue(2);
3547        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3548                   template.getRow(),
3549                   start_key, ScanController.GE,
3550                   null,
3551                   stop_key, ScanController.GT,
3552                   0, 0, T_QualifierTest.ORDER_DESC))
3553        {
3554            ret_val = false;
3555        }
3556
3557        // +-----------------------------+
3558
// |minium on btree - row locked |
3559
// +-----------------------------+
3560
//
3561
REPORT("minimum on btree, row locked.");
3562        // the following function actually returns
3563
// the minimum values because the index is in descending order
3564
if (!tc.fetchMaxOnBtree(
3565                index_conglomid,
3566                0,
3567                TransactionController.MODE_RECORD,
3568                TransactionController.ISOLATION_SERIALIZABLE,
3569                (FormatableBitSet) null,
3570                template.getRow()))
3571        {
3572            throw T_Fail.testFailMsg("found no min.");
3573        }
3574        else
3575        {
3576            // make sure right min was found.
3577
long key = ((SQLLongint) template.getRow()[2]).getLong();
3578            
3579            if (key != 11)
3580            {
3581                throw T_Fail.testFailMsg("wrong minimum found.");
3582            }
3583        }
3584
3585        // +-----------------------------+
3586
// |min on btree - table locked |
3587
// +-----------------------------+
3588
//
3589
REPORT("min on btree, table locked.");
3590        if (!tc.fetchMaxOnBtree(
3591                index_conglomid,
3592                0,
3593                TransactionController.MODE_TABLE,
3594                TransactionController.ISOLATION_SERIALIZABLE,
3595                (FormatableBitSet) null,
3596                template.getRow()))
3597        {
3598            throw T_Fail.testFailMsg("found no min.");
3599        }
3600        else
3601        {
3602            // make sure right min was found.
3603
long key = ((SQLLongint) template.getRow()[2]).getLong();
3604            
3605            if (key != 11)
3606            {
3607                throw T_Fail.testFailMsg("wrong min found.");
3608            }
3609        }
3610
3611        // +-----------------------------+
3612
// |min on btree - row locked |
3613
// +-----------------------------+
3614
//
3615
REPORT("min on btree, row locked.");
3616        if (!tc.fetchMaxOnBtree(
3617                index_conglomid,
3618                0,
3619                TransactionController.MODE_RECORD,
3620                TransactionController.ISOLATION_READ_COMMITTED,
3621                (FormatableBitSet) null,
3622                template.getRow()))
3623        {
3624            throw T_Fail.testFailMsg("found no max.");
3625        }
3626        else
3627        {
3628            // make sure right min was found.
3629
long key = ((SQLLongint) template.getRow()[2]).getLong();
3630            
3631            if (key != 11)
3632            {
3633                throw T_Fail.testFailMsg("wrong min found.");
3634            }
3635        }
3636
3637        // +-----------------------------+
3638
// |min on btree - table locked |
3639
// +-----------------------------+
3640
//
3641
REPORT("min on btree, table locked.");
3642        if (!tc.fetchMaxOnBtree(
3643                index_conglomid,
3644                0,
3645                TransactionController.MODE_TABLE,
3646                TransactionController.ISOLATION_READ_COMMITTED,
3647                (FormatableBitSet) null,
3648                template.getRow()))
3649        {
3650            throw T_Fail.testFailMsg("found no min.");
3651        }
3652        else
3653        {
3654            // make sure right min was found.
3655
long key = ((SQLLongint) template.getRow()[2]).getLong();
3656            
3657            if (key != 11)
3658            {
3659                throw T_Fail.testFailMsg("wrong min found.");
3660            }
3661        }
3662
3663        return(ret_val);
3664    }
3665
3666
3667    /**
3668     * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
3669     * BtreeScan.fetch() with descending indexes.
3670     *
3671     * @exception StandardException Standard exception policy.
3672     * @exception T_Fail Throws T_Fail on any test failure.
3673     */

3674    protected boolean t_017(TransactionController tc)
3675        throws StandardException, T_Fail
3676    {
3677        T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
3678
3679        // base row template - last column is just to make row long so that
3680
// multiple pages are spanned.
3681
DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
3682        base_row[3] = new SQLChar();
3683
3684        String JavaDoc string_1500char = new String JavaDoc();
3685        for (int i = 0; i < 300; i++)
3686            string_1500char += "mikem";
3687
3688        boolean ret_val = true;
3689        long value = -1;
3690        long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
3691        long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
3692        long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
3693
3694        // set of deleted rows to make scans more interesting
3695
long d_col1[] ={ 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12};
3696        long d_col2[] ={ 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1};
3697        long d_col3[] ={91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104};
3698
3699        
3700
3701        REPORT("Starting t_017");
3702
3703        // create the base table
3704
long base_conglomid =
3705            tc.createConglomerate(
3706                "heap", // create a heap conglomerate
3707
base_row, // base table template row
3708
null, //column sort order - not required for heap
3709
null, // default properties
3710
TransactionController.IS_DEFAULT); // not temporary
3711

3712        // Open the base table
3713
ConglomerateController base_cc =
3714            tc.openConglomerate(
3715                base_conglomid,
3716                false,
3717                TransactionController.OPENMODE_FORUPDATE,
3718                TransactionController.MODE_RECORD,
3719                TransactionController.ISOLATION_SERIALIZABLE);
3720
3721        // initialize the secondary index row - pointing it at base row
3722
index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
3723
3724        Properties JavaDoc properties =
3725            createProperties(
3726                null, // no current properties list
3727
false, // don't allow duplicates
3728
5, // 4 columns in index row
3729
5, // non-unique index
3730
true, // maintain parent links
3731
base_conglomid, // base conglom id
3732
4); // row loc in last column
3733

3734        // create the index with all the columns in descending order
3735
ColumnOrdering order[] = new ColumnOrdering[5];
3736        order[0] = new T_ColumnOrderingImpl(0, false); // descending
3737
order[1] = new T_ColumnOrderingImpl(1, false); // descending
3738
order[2] = new T_ColumnOrderingImpl(2, false); // descending
3739
order[3] = new T_ColumnOrderingImpl(3, false); // descending
3740
order[4] = new T_ColumnOrderingImpl(4, true); // asccending
3741

3742        long index_conglomid =
3743            tc.createConglomerate(
3744                "BTREE", // create a btree secondary
3745
index_row.getRow(), // row template
3746
order, //column sort order - default
3747
properties, // properties
3748
TransactionController.IS_DEFAULT); // not temporary
3749

3750        // Open the conglomerate.
3751
ConglomerateController index_cc =
3752            tc.openConglomerate(
3753                index_conglomid,
3754                false,
3755                TransactionController.OPENMODE_FORUPDATE,
3756                TransactionController.MODE_RECORD,
3757                TransactionController.ISOLATION_SERIALIZABLE);
3758
3759        // Create a row.
3760
T_SecondaryIndexRow template = new T_SecondaryIndexRow();
3761        RowLocation row_loc = base_cc.newRowLocationTemplate();
3762        template.init(base_row, row_loc, 5);
3763
3764        // insert them in reverse order just to make sure btree is sorting them
3765
for (int i = col1.length - 1; i >= 0; i--)
3766        {
3767            ((SQLLongint)(template.getRow()[0])).setValue(col1[i]);
3768            ((SQLLongint)(template.getRow()[1])).setValue(col2[i]);
3769            ((SQLLongint)(template.getRow()[2])).setValue(col3[i]);
3770            base_row[3] = new SQLChar(string_1500char);
3771
3772            base_cc.insertAndFetchLocation(base_row, row_loc);
3773
3774            // Insert the row.
3775
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
3776
// ")" + template);
3777
if (index_cc.insert(template.getRow()) != 0)
3778                throw T_Fail.testFailMsg("insert failed");
3779        }
3780
3781        index_cc.checkConsistency();
3782
3783        ((B2IController)index_cc).debugConglomerate();
3784
3785        ret_val = t_desc_scan_test_cases(tc, index_conglomid, template);
3786
3787        // insert and delete some interesting rows, deleted space management
3788
// may or may not clean these up.
3789
for (int i = d_col1.length - 1; i >= 0; i--)
3790        {
3791            ((SQLLongint)(template.getRow()[0])).setValue(d_col1[i]);
3792            ((SQLLongint)(template.getRow()[1])).setValue(d_col2[i]);
3793            ((SQLLongint)(template.getRow()[2])).setValue(d_col3[i]);
3794            base_row[3] = new SQLChar(string_1500char);
3795
3796            base_cc.insertAndFetchLocation(base_row, row_loc);
3797
3798            // Insert the row.
3799
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
3800
// ")" + template);
3801
if (index_cc.insert(template.getRow()) != 0)
3802                throw T_Fail.testFailMsg("insert failed");
3803
3804            // now delete the row.
3805
base_cc.delete(row_loc);
3806
3807            ScanController delete_scan =
3808                tc.openScan(index_conglomid, false,
3809                            TransactionController.OPENMODE_FORUPDATE,
3810                            TransactionController.MODE_RECORD,
3811                            TransactionController.ISOLATION_SERIALIZABLE,
3812                            (FormatableBitSet) null,
3813                            template.getRow(), ScanController.GE,
3814                            null,
3815                            template.getRow(), ScanController.GT);
3816
3817            if (!delete_scan.next())
3818            {
3819                throw T_Fail.testFailMsg("delete could not find key");
3820            }
3821            else
3822            {
3823                delete_scan.delete();
3824
3825                if (delete_scan.next())
3826                    throw T_Fail.testFailMsg("delete found more than one key");
3827            }
3828
3829            delete_scan.close();
3830        }
3831
3832        ret_val = t_desc_scan_test_cases(tc, index_conglomid, template);
3833
3834
3835        // Close the conglomerate.
3836
index_cc.close();
3837
3838        tc.commit();
3839        REPORT("Ending t_017");
3840
3841        return(ret_val);
3842    }
3843
3844
3845    /* test cases for ASC DESC ASC DESC column sort order index
3846    SORTED DATA
3847    col1, col2, col3
3848    AS DS AS -- sort order
3849    1, 1, 11
3850    3, 2, 12
3851    4, 6, 15
3852    4, 4, 14
3853    4, 2, 13
3854    5, 6, 18
3855    5, 4, 17
3856    5, 2, 16
3857    6, 1, 19
3858    7, 1, 20
3859    9, 1, 21
3860    */

3861
3862    private boolean t_ascdesc_scan_test_cases(
3863    TransactionController tc,
3864    long index_conglomid,
3865    T_SecondaryIndexRow template
3866    )
3867        throws StandardException, T_Fail
3868    {
3869        boolean ret_val = true;
3870
3871        // run through a predicates as described in the openScan() interface //
3872
DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
3873        DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
3874
3875
3876        // test predicate x = 5
3877
//
3878
// result set should be:{5,6,18}, {5,4,17}, {5,6,16}
3879
//
3880
REPORT("scan (x = 5)");
3881        ((SQLLongint)start_key[0]).setValue(5);
3882        ((SQLLongint)stop_key[0]).setValue(5);
3883        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3884                   template.getRow(),
3885                   start_key, ScanController.GE,
3886                   null,
3887                   stop_key, ScanController.GT,
3888                   3, 18, T_QualifierTest.ORDER_DESC))
3889        {
3890            ret_val = false;
3891        }
3892 
3893
3894        REPORT("scan (x > 5)");
3895        ((SQLLongint)start_key[0]).setValue(5);
3896        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3897                   template.getRow(),
3898                   start_key, ScanController.GT,
3899                   null,
3900                   null, ScanController.NA,
3901                   3, 19, T_QualifierTest.ORDER_FORWARD))
3902        {
3903            ret_val = false;
3904        }
3905
3906        REPORT("scan (x >= 5)");
3907        ((SQLLongint)start_key[0]).setValue(5);
3908        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3909                   template.getRow(),
3910                   start_key, ScanController.GE,
3911                   null,
3912                   null, ScanController.NA,
3913                   6, 16, T_QualifierTest.ORDER_NONE))
3914        {
3915            ret_val = false;
3916        }
3917
3918        REPORT("scan (x <= 5)");
3919        ((SQLLongint)stop_key[0]).setValue(5);
3920        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3921                   template.getRow(),
3922                   null, ScanController.NA,
3923                   null,
3924                   stop_key, ScanController.GT,
3925                   8, 11, T_QualifierTest.ORDER_NONE))
3926        {
3927            ret_val = false;
3928        }
3929  
3930        REPORT("scan (x < 5)");
3931        ((SQLLongint)stop_key[0]).setValue(5);
3932        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3933                   template.getRow(),
3934                   null, ScanController.NA,
3935                   null,
3936                   stop_key, ScanController.GE,
3937                   5, 11, T_QualifierTest.ORDER_NONE))
3938        {
3939            ret_val = false;
3940        }
3941
3942        REPORT("scan (x >= 5 and x <= 7)");
3943        ((SQLLongint)start_key[0]).setValue(5);
3944        ((SQLLongint)stop_key[0]).setValue(7);
3945        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3946                   template.getRow(),
3947                   start_key, ScanController.GE,
3948                   null,
3949                   stop_key, ScanController.GT,
3950                   5, 16, T_QualifierTest.ORDER_NONE))
3951        {
3952            ret_val = false;
3953        }
3954
3955        REPORT("scan (x = 5 and y > 2)");
3956        start_key = TemplateRow.newU8Row(1);
3957        stop_key = TemplateRow.newU8Row(2);
3958        ((SQLLongint)start_key[0]).setValue(5);
3959        ((SQLLongint)stop_key[0]).setValue(5);
3960        ((SQLLongint)stop_key[1]).setValue(2);
3961        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3962                   template.getRow(),
3963                   start_key, ScanController.GE,
3964                   null,
3965                   stop_key, ScanController.GE,
3966                   2, 18, T_QualifierTest.ORDER_DESC))
3967        {
3968            ret_val = false;
3969        }
3970
3971
3972        REPORT("scan (x = 5 and y >= 2)");
3973        start_key = TemplateRow.newU8Row(1);
3974        stop_key = TemplateRow.newU8Row(2);
3975        ((SQLLongint)start_key[0]).setValue(5);
3976        ((SQLLongint)stop_key[0]).setValue(5);
3977        ((SQLLongint)stop_key[1]).setValue(2);
3978        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3979                   template.getRow(),
3980                   start_key, ScanController.GE,
3981                   null,
3982                   stop_key, ScanController.GT,
3983                   3, 18, T_QualifierTest.ORDER_DESC))
3984        {
3985            ret_val = false;
3986        }
3987
3988
3989        REPORT("scan (x = 5 and y < 5)");
3990        start_key = TemplateRow.newU8Row(2);
3991        stop_key = TemplateRow.newU8Row(1);
3992        ((SQLLongint)start_key[0]).setValue(5);
3993        ((SQLLongint)start_key[1]).setValue(5);
3994        ((SQLLongint)stop_key[0]).setValue(5);
3995        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
3996                   template.getRow(),
3997                   start_key, ScanController.GE,
3998                   null,
3999                   stop_key, ScanController.GT,
4000                   2, 17, T_QualifierTest.ORDER_DESC))
4001        {
4002            ret_val = false;
4003        }
4004
4005        REPORT("scan (x = 2)");
4006        start_key = TemplateRow.newU8Row(1);
4007        stop_key = TemplateRow.newU8Row(1);
4008        ((SQLLongint)start_key[0]).setValue(2);
4009        ((SQLLongint)stop_key[0]).setValue(2);
4010        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4011                   template.getRow(),
4012                   start_key, ScanController.GE,
4013                   null,
4014                   stop_key, ScanController.GT,
4015                   0, 0, T_QualifierTest.ORDER_DESC))
4016        {
4017            ret_val = false;
4018        }
4019
4020        // +-----------------------------+---------------
4021
// |last leaf last row on btree - row locked |
4022
// +-----------------------------+---------------
4023
//
4024
REPORT("minimum on btree, row locked.");
4025
4026        if (!tc.fetchMaxOnBtree(
4027                index_conglomid,
4028                0,
4029                TransactionController.MODE_RECORD,
4030                TransactionController.ISOLATION_SERIALIZABLE,
4031                (FormatableBitSet) null,
4032                template.getRow()))
4033        {
4034            throw T_Fail.testFailMsg("found last row in the last leaf.");
4035        }
4036        else
4037        {
4038            // make sure right min was found.
4039
long key = ((SQLLongint) template.getRow()[2]).getLong();
4040            
4041            if (key != 21)
4042            {
4043                throw T_Fail.testFailMsg("wrong last row in the last leaf.");
4044            }
4045        }
4046
4047        // +-----------------------------+--------------
4048
// |last row in the last leaf - table locked |
4049
// +-----------------------------+--------------
4050
//
4051
REPORT("last row in the last leaf, table locked.");
4052        if (!tc.fetchMaxOnBtree(
4053                index_conglomid,
4054                0,
4055                TransactionController.MODE_TABLE,
4056                TransactionController.ISOLATION_SERIALIZABLE,
4057                (FormatableBitSet) null,
4058                template.getRow()))
4059        {
4060            throw T_Fail.testFailMsg("found no min.");
4061        }
4062        else
4063        {
4064            // make sure right last row in the last leaf found.
4065
long key = ((SQLLongint) template.getRow()[2]).getLong();
4066            
4067            if (key != 21)
4068            {
4069                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4070            }
4071        }
4072
4073        // +-----------------------------+-----------
4074
// |last row in the last leaf- row locked |
4075
// +-----------------------------+-----------
4076
//
4077
REPORT("last row in the last leaf, row locked.");
4078        if (!tc.fetchMaxOnBtree(
4079                index_conglomid,
4080                0,
4081                TransactionController.MODE_RECORD,
4082                TransactionController.ISOLATION_READ_COMMITTED,
4083                (FormatableBitSet) null,
4084                template.getRow()))
4085        {
4086            throw T_Fail.testFailMsg("found no max.");
4087        }
4088        else
4089        {
4090            // make sure right last row in the last leaf found.
4091
long key = ((SQLLongint) template.getRow()[2]).getLong();
4092            
4093            if (key != 21)
4094            {
4095                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4096            }
4097        }
4098
4099        // +-----------------------------+-------------
4100
// |last row in the last leaf- table locked |
4101
// +-----------------------------+-------------
4102
//
4103
REPORT("last row in the last leaf, table locked.");
4104        if (!tc.fetchMaxOnBtree(
4105                index_conglomid,
4106                0,
4107                TransactionController.MODE_TABLE,
4108                TransactionController.ISOLATION_READ_COMMITTED,
4109                (FormatableBitSet) null,
4110                template.getRow()))
4111        {
4112            throw T_Fail.testFailMsg("found no last row in the last leaf");
4113        }
4114        else
4115        {
4116            // make sure right min was found.
4117
long key = ((SQLLongint) template.getRow()[2]).getLong();
4118            
4119            if (key != 21)
4120            {
4121                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4122            }
4123        }
4124
4125        return(ret_val);
4126    }
4127
4128
4129 /**
4130     * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
4131     * BtreeScan.fetch() with alternating ascending and descending coulmn
4132     * sort order indexes.
4133     *
4134     * @exception StandardException Standard exception policy.
4135     * @exception T_Fail Throws T_Fail on any test failure.
4136     */

4137    protected boolean t_018(TransactionController tc)
4138        throws StandardException, T_Fail
4139    {
4140        T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
4141
4142        // base row template - last column is just to make row long so that
4143
// multiple pages are spanned.
4144
DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
4145        base_row[3] = new SQLChar();
4146
4147        String JavaDoc string_1500char = new String JavaDoc();
4148        for (int i = 0; i < 300; i++)
4149            string_1500char += "mikem";
4150
4151        boolean ret_val = true;
4152        long value = -1;
4153        long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
4154        long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
4155        long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
4156
4157        // set of deleted rows to make scans more interesting
4158
long d_col1[] ={ 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12};
4159        long d_col2[] ={ 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1};
4160        long d_col3[] ={91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104};
4161
4162        
4163
4164        REPORT("Starting t_018");
4165
4166        // create the base table
4167
long base_conglomid =
4168            tc.createConglomerate(
4169                "heap", // create a heap conglomerate
4170
base_row, // base table template row
4171
null, //column sort order - not required for heap
4172
null, // default properties
4173
TransactionController.IS_DEFAULT); // not temporary
4174

4175        // Open the base table
4176
ConglomerateController base_cc =
4177            tc.openConglomerate(
4178                base_conglomid,
4179                false,
4180                TransactionController.OPENMODE_FORUPDATE,
4181                TransactionController.MODE_RECORD,
4182                TransactionController.ISOLATION_SERIALIZABLE);
4183
4184        // initialize the secondary index row - pointing it at base row
4185
index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
4186
4187        Properties JavaDoc properties =
4188            createProperties(
4189                null, // no current properties list
4190
false, // don't allow duplicates
4191
5, // 4 columns in index row
4192
5, // non-unique index
4193
true, // maintain parent links
4194
base_conglomid, // base conglom id
4195
4); // row loc in last column
4196

4197        // create the index with all the columns in descending order
4198
ColumnOrdering order[] = new ColumnOrdering[5];
4199        order[0] = new T_ColumnOrderingImpl(0, true); // Ascending
4200
order[1] = new T_ColumnOrderingImpl(1, false); // descending
4201
order[2] = new T_ColumnOrderingImpl(2, true); // Ascending
4202
order[3] = new T_ColumnOrderingImpl(3, false); // descending
4203
order[4] = new T_ColumnOrderingImpl(4, true); // asccending
4204

4205        long index_conglomid =
4206            tc.createConglomerate(
4207                "BTREE", // create a btree secondary
4208
index_row.getRow(), // row template
4209
order, //column sort order - default
4210
properties, // properties
4211
TransactionController.IS_DEFAULT); // not temporary
4212

4213        // Open the conglomerate.
4214
ConglomerateController index_cc =
4215            tc.openConglomerate(
4216                index_conglomid,
4217                false,
4218                TransactionController.OPENMODE_FORUPDATE,
4219                TransactionController.MODE_RECORD,
4220                TransactionController.ISOLATION_SERIALIZABLE);
4221
4222        // Create a row.
4223
T_SecondaryIndexRow template = new T_SecondaryIndexRow();
4224        RowLocation row_loc = base_cc.newRowLocationTemplate();
4225        template.init(base_row, row_loc, 5);
4226
4227        // insert them in reverse order just to make sure btree is sorting them
4228
for (int i = col1.length - 1; i >= 0; i--)
4229        {
4230            ((SQLLongint)(template.getRow()[0])).setValue(col1[i]);
4231            ((SQLLongint)(template.getRow()[1])).setValue(col2[i]);
4232            ((SQLLongint)(template.getRow()[2])).setValue(col3[i]);
4233            base_row[3] = new SQLChar(string_1500char);
4234
4235            base_cc.insertAndFetchLocation(base_row, row_loc);
4236
4237            // Insert the row.
4238
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
4239
// ")" + template);
4240
if (index_cc.insert(template.getRow()) != 0)
4241                throw T_Fail.testFailMsg("insert failed");
4242        }
4243
4244        index_cc.checkConsistency();
4245
4246        ((B2IController)index_cc).debugConglomerate();
4247
4248        ret_val = t_ascdesc_scan_test_cases(tc, index_conglomid, template);
4249
4250        // insert and delete some interesting rows, deleted space management
4251
// may or may not clean these up.
4252
for (int i = d_col1.length - 1; i >= 0; i--)
4253        {
4254            ((SQLLongint)(template.getRow()[0])).setValue(d_col1[i]);
4255            ((SQLLongint)(template.getRow()[1])).setValue(d_col2[i]);
4256            ((SQLLongint)(template.getRow()[2])).setValue(d_col3[i]);
4257            base_row[3] = new SQLChar(string_1500char);
4258
4259            base_cc.insertAndFetchLocation(base_row, row_loc);
4260
4261            // Insert the row.
4262
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
4263
// ")" + template);
4264
if (index_cc.insert(template.getRow()) != 0)
4265                throw T_Fail.testFailMsg("insert failed");
4266
4267            // now delete the row.
4268
base_cc.delete(row_loc);
4269
4270            ScanController delete_scan =
4271                tc.openScan(index_conglomid, false,
4272                            TransactionController.OPENMODE_FORUPDATE,
4273                            TransactionController.MODE_RECORD,
4274                            TransactionController.ISOLATION_SERIALIZABLE,
4275                            (FormatableBitSet) null,
4276                            template.getRow(), ScanController.GE,
4277                            null,
4278                            template.getRow(), ScanController.GT);
4279
4280            if (!delete_scan.next())
4281            {
4282                throw T_Fail.testFailMsg("delete could not find key");
4283            }
4284            else
4285            {
4286                delete_scan.delete();
4287
4288                if (delete_scan.next())
4289                    throw T_Fail.testFailMsg("delete found more than one key");
4290            }
4291
4292            delete_scan.close();
4293        }
4294
4295        ret_val = t_ascdesc_scan_test_cases(tc, index_conglomid, template);
4296
4297
4298        // Close the conglomerate.
4299
index_cc.close();
4300
4301        tc.commit();
4302        REPORT("Ending t_018");
4303
4304        return(ret_val);
4305    }
4306
4307
4308
4309    /* test cases for ASC DESC DESC ASC column sort order index
4310    SORTED DATA
4311    col1, col2, col3
4312    DS AS DS -- sort order
4313    9, 1, 21
4314    7, 1, 20
4315    6, 1, 19
4316    5, 2, 16
4317    5, 4, 17
4318    5, 6, 18
4319    4, 2, 13
4320    4, 4, 14
4321    4, 6, 15
4322    3, 1, 12
4323    1, 1, 11
4324    */

4325    private boolean t_ascdesc1_scan_test_cases(
4326    TransactionController tc,
4327    long index_conglomid,
4328    T_SecondaryIndexRow template
4329    )
4330        throws StandardException, T_Fail
4331    {
4332        boolean ret_val = true;
4333
4334        // run through a predicates as described in the openScan() interface //
4335
DataValueDescriptor[] start_key = TemplateRow.newU8Row(1);
4336        DataValueDescriptor[] stop_key = TemplateRow.newU8Row(1);
4337
4338
4339        REPORT("scan (x = 5)");
4340        ((SQLLongint)start_key[0]).setValue(5);
4341        ((SQLLongint)stop_key[0]).setValue(5);
4342        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4343                   template.getRow(),
4344                   start_key, ScanController.GE,
4345                   null,
4346                   stop_key, ScanController.GT,
4347                   3, 16, T_QualifierTest.ORDER_FORWARD))
4348        {
4349            ret_val = false;
4350        }
4351 
4352        REPORT("scan (x > 5)");
4353        ((SQLLongint)stop_key[0]).setValue(5);
4354        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4355                   template.getRow(),
4356                   null, ScanController.NA,
4357                   null,
4358                   stop_key, ScanController.GE,
4359                   3, 21, T_QualifierTest.ORDER_DESC))
4360        {
4361            ret_val = false;
4362        }
4363
4364        REPORT("scan (x >= 5)");
4365        ((SQLLongint)stop_key[0]).setValue(5);
4366        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4367                   template.getRow(),
4368                   null, ScanController.NA,
4369                   null,
4370                   stop_key, ScanController.GT,
4371                   6, 16, T_QualifierTest.ORDER_NONE))
4372        {
4373            ret_val = false;
4374        }
4375
4376  
4377        REPORT("scan (x <= 5)");
4378        ((SQLLongint)start_key[0]).setValue(5);
4379        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4380                   template.getRow(),
4381                   start_key, ScanController.GE,
4382                   null,
4383                   null, ScanController.NA,
4384                   8, 11, T_QualifierTest.ORDER_NONE))
4385        {
4386            ret_val = false;
4387        }
4388  
4389        REPORT("scan (x < 5)");
4390        ((SQLLongint)start_key[0]).setValue(5);
4391        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4392                   template.getRow(),
4393                   start_key, ScanController.GT,
4394                   null,
4395                   null, ScanController.NA,
4396                   5, 11, T_QualifierTest.ORDER_NONE))
4397        {
4398            ret_val = false;
4399        }
4400
4401        REPORT("scan (x >= 5 and x <= 7)");
4402        ((SQLLongint)start_key[0]).setValue(7);
4403        ((SQLLongint)stop_key[0]).setValue(5);
4404        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4405                   template.getRow(),
4406                   start_key, ScanController.GE,
4407                   null,
4408                   stop_key, ScanController.GT,
4409                   5, 16, T_QualifierTest.ORDER_NONE))
4410        {
4411            ret_val = false;
4412        }
4413
4414        REPORT("scan (x = 5 and y > 2)");
4415        start_key = TemplateRow.newU8Row(2);
4416        stop_key = TemplateRow.newU8Row(1);
4417        ((SQLLongint)start_key[0]).setValue(5);
4418        ((SQLLongint)start_key[1]).setValue(2);
4419        ((SQLLongint)stop_key[0]).setValue(5);
4420        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4421                   template.getRow(),
4422                   start_key, ScanController.GT,
4423                   null,
4424                   stop_key, ScanController.GT,
4425                   2, 17, T_QualifierTest.ORDER_FORWARD))
4426        {
4427            ret_val = false;
4428        }
4429
4430        REPORT("scan (x = 5 and y >= 2)");
4431        start_key = TemplateRow.newU8Row(2);
4432        stop_key = TemplateRow.newU8Row(1);
4433        ((SQLLongint)start_key[0]).setValue(5);
4434        ((SQLLongint)start_key[1]).setValue(2);
4435        ((SQLLongint)stop_key[0]).setValue(5);
4436        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4437                   template.getRow(),
4438                   start_key, ScanController.GE,
4439                   null,
4440                   stop_key, ScanController.GT,
4441                   3, 16, T_QualifierTest.ORDER_FORWARD))
4442        {
4443            ret_val = false;
4444        }
4445
4446        REPORT("scan (x = 5 and y < 5)");
4447        start_key = TemplateRow.newU8Row(1);
4448        stop_key = TemplateRow.newU8Row(2);
4449        ((SQLLongint)start_key[0]).setValue(5);
4450        ((SQLLongint)stop_key[0]).setValue(5);
4451        ((SQLLongint)stop_key[1]).setValue(5);
4452
4453        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4454                   template.getRow(),
4455                   start_key, ScanController.GE,
4456                   null,
4457                   stop_key, ScanController.GT,
4458                   2, 16, T_QualifierTest.ORDER_FORWARD))
4459        {
4460            ret_val = false;
4461        }
4462
4463        REPORT("scan (x = 2)");
4464        start_key = TemplateRow.newU8Row(1);
4465        stop_key = TemplateRow.newU8Row(1);
4466        ((SQLLongint)start_key[0]).setValue(2);
4467        ((SQLLongint)stop_key[0]).setValue(2);
4468        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4469                   template.getRow(),
4470                   start_key, ScanController.GE,
4471                   null,
4472                   stop_key, ScanController.GT,
4473                   0, 0, T_QualifierTest.ORDER_DESC))
4474        {
4475            ret_val = false;
4476        }
4477
4478        // values '2' does not exist as such in the data set
4479
REPORT("scan (x > 2)");
4480        stop_key = TemplateRow.newU8Row(1);
4481        ((SQLLongint)stop_key[0]).setValue(2);
4482        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4483                   template.getRow(),
4484                   null, ScanController.NA,
4485                   null,
4486                   stop_key, ScanController.GE,
4487                   10, 12, T_QualifierTest.ORDER_NONE))
4488        {
4489            ret_val = false;
4490        }
4491
4492
4493
4494        // values '2' does not exist as such in the data set
4495
REPORT("scan (x >= 2)");
4496        stop_key = TemplateRow.newU8Row(1);
4497        ((SQLLongint)stop_key[0]).setValue(2);
4498        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4499                   template.getRow(),
4500                   null, ScanController.NA,
4501                   null,
4502                   stop_key, ScanController.GT,
4503                   10, 12, T_QualifierTest.ORDER_NONE))
4504        {
4505            ret_val = false;
4506        }
4507
4508
4509        // values '2' does not exist as such in the data set
4510
REPORT("scan (x < 2)");
4511        start_key = TemplateRow.newU8Row(1);
4512        ((SQLLongint)start_key[0]).setValue(2);
4513        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4514                   template.getRow(),
4515                   start_key, ScanController.GT,
4516                   null,
4517                   null, ScanController.NA,
4518                   1, 11, T_QualifierTest.ORDER_NONE))
4519        {
4520            ret_val = false;
4521        }
4522
4523
4524        // values '2' does not exist as such in the data set
4525
REPORT("scan (x <= 2)");
4526        start_key = TemplateRow.newU8Row(1);
4527        ((SQLLongint)start_key[0]).setValue(2);
4528        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4529                   template.getRow(),
4530                   start_key, ScanController.GE,
4531                   null,
4532                   null, ScanController.NA,
4533                   1, 11, T_QualifierTest.ORDER_NONE))
4534        {
4535            ret_val = false;
4536        }
4537
4538
4539        REPORT("scan (x >= 2 and x <= 7)");
4540        ((SQLLongint)start_key[0]).setValue(7);
4541        ((SQLLongint)stop_key[0]).setValue(2);
4542        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4543                   template.getRow(),
4544                   start_key, ScanController.GE,
4545                   null,
4546                   stop_key, ScanController.GT,
4547                   9, 12, T_QualifierTest.ORDER_NONE))
4548        {
4549            ret_val = false;
4550        }
4551
4552        REPORT("scan (x = 2 and y > 2)");
4553        start_key = TemplateRow.newU8Row(2);
4554        stop_key = TemplateRow.newU8Row(1);
4555        ((SQLLongint)start_key[0]).setValue(2);
4556        ((SQLLongint)start_key[1]).setValue(2);
4557        ((SQLLongint)stop_key[0]).setValue(2);
4558        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4559                   template.getRow(),
4560                   start_key, ScanController.GT,
4561                   null,
4562                   stop_key, ScanController.GT,
4563                   0, 0, T_QualifierTest.ORDER_NONE))
4564        {
4565            ret_val = false;
4566        }
4567
4568        REPORT("scan (x = 2 and y >= 2)");
4569        start_key = TemplateRow.newU8Row(2);
4570        stop_key = TemplateRow.newU8Row(1);
4571        ((SQLLongint)start_key[0]).setValue(2);
4572        ((SQLLongint)start_key[1]).setValue(2);
4573        ((SQLLongint)stop_key[0]).setValue(2);
4574        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4575                   template.getRow(),
4576                   start_key, ScanController.GE,
4577                   null,
4578                   stop_key, ScanController.GT,
4579                   0, 0, T_QualifierTest.ORDER_NONE))
4580        {
4581            ret_val = false;
4582        }
4583
4584        REPORT("scan (x = 4 and y <=2)");
4585        start_key = TemplateRow.newU8Row(1);
4586        stop_key = TemplateRow.newU8Row(2);
4587        ((SQLLongint)start_key[0]).setValue(4);
4588        ((SQLLongint)stop_key[0]).setValue(4);
4589        ((SQLLongint)stop_key[1]).setValue(2);
4590
4591        if (!T_QualifierTest.t_scan(tc, index_conglomid, template.getRow(),
4592                   template.getRow(),
4593                   start_key, ScanController.GE,
4594                   null,
4595                   stop_key, ScanController.GT,
4596                   1, 13, T_QualifierTest.ORDER_DESC))
4597        {
4598            ret_val = false;
4599        }
4600
4601
4602
4603
4604        // +-----------------------------+---------------
4605
// |last leaf last row on btree - row locked |
4606
// +-----------------------------+---------------
4607
//
4608
REPORT("last row in the last leaf, row locked.");
4609
4610        if (!tc.fetchMaxOnBtree(
4611                index_conglomid,
4612                0,
4613                TransactionController.MODE_RECORD,
4614                TransactionController.ISOLATION_SERIALIZABLE,
4615                (FormatableBitSet) null,
4616                template.getRow()))
4617        {
4618            throw T_Fail.testFailMsg("found last row in the last leaf.");
4619        }
4620        else
4621        {
4622            // make sure right min was found.
4623
long key = ((SQLLongint) template.getRow()[2]).getLong();
4624            
4625            if (key != 11)
4626            {
4627                throw T_Fail.testFailMsg("wrong last row in the last leaf.");
4628            }
4629        }
4630
4631        // +-----------------------------+--------------
4632
// |last row in the last leaf - table locked |
4633
// +-----------------------------+--------------
4634
//
4635
REPORT("last row in the last leaf, table locked.");
4636        if (!tc.fetchMaxOnBtree(
4637                index_conglomid,
4638                0,
4639                TransactionController.MODE_TABLE,
4640                TransactionController.ISOLATION_SERIALIZABLE,
4641                (FormatableBitSet) null,
4642                template.getRow()))
4643        {
4644            throw T_Fail.testFailMsg("found no min.");
4645        }
4646        else
4647        {
4648            // make sure right last row in the last leaf found.
4649
long key = ((SQLLongint) template.getRow()[2]).getLong();
4650            
4651            if (key != 11)
4652            {
4653                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4654            }
4655        }
4656
4657        // +-----------------------------+-----------
4658
// |last row in the last leaf- row locked |
4659
// +-----------------------------+-----------
4660
//
4661
REPORT("last row in the last leaf, row locked.");
4662        if (!tc.fetchMaxOnBtree(
4663                index_conglomid,
4664                0,
4665                TransactionController.MODE_RECORD,
4666                TransactionController.ISOLATION_READ_COMMITTED,
4667                (FormatableBitSet) null,
4668                template.getRow()))
4669        {
4670            throw T_Fail.testFailMsg("found no max.");
4671        }
4672        else
4673        {
4674            // make sure right last row in the last leaf found.
4675
long key = ((SQLLongint) template.getRow()[2]).getLong();
4676            
4677            if (key != 11)
4678            {
4679                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4680            }
4681        }
4682
4683        // +-----------------------------+-------------
4684
// |last row in the last leaf- table locked |
4685
// +-----------------------------+-------------
4686
//
4687
REPORT("last row in the last leaf, table locked.");
4688        if (!tc.fetchMaxOnBtree(
4689                index_conglomid,
4690                0,
4691                TransactionController.MODE_TABLE,
4692                TransactionController.ISOLATION_READ_COMMITTED,
4693                (FormatableBitSet) null,
4694                template.getRow()))
4695        {
4696            throw T_Fail.testFailMsg("found no last row in the last leaf");
4697        }
4698        else
4699        {
4700            // make sure right min was found.
4701
long key = ((SQLLongint) template.getRow()[2]).getLong();
4702            
4703            if (key != 11)
4704            {
4705                throw T_Fail.testFailMsg("wrong last row in the last leaf found.");
4706            }
4707        }
4708
4709        return(ret_val);
4710    }
4711
4712
4713 /**
4714     * Test BTree.openScan(), BtreeScan.init(), BtreeScan.next(),
4715     * BtreeScan.fetch() with alternating ascending and descending coulmn
4716     * sort order indexes.
4717     *
4718     * @exception StandardException Standard exception policy.
4719     * @exception T_Fail Throws T_Fail on any test failure.
4720     */

4721    protected boolean t_019(TransactionController tc)
4722        throws StandardException, T_Fail
4723    {
4724        T_SecondaryIndexRow index_row = new T_SecondaryIndexRow();
4725
4726        // base row template - last column is just to make row long so that
4727
// multiple pages are spanned.
4728
DataValueDescriptor[] base_row = TemplateRow.newU8Row(4);
4729        base_row[3] = new SQLChar();
4730
4731        String JavaDoc string_1500char = new String JavaDoc();
4732        for (int i = 0; i < 300; i++)
4733            string_1500char += "mikem";
4734
4735        boolean ret_val = true;
4736        long value = -1;
4737        long col1[] = { 1, 3, 4, 4, 4, 5, 5, 5, 6, 7, 9};
4738        long col2[] = { 1, 1, 2, 4, 6, 2, 4, 6, 1, 1, 1};
4739        long col3[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
4740
4741        // set of deleted rows to make scans more interesting
4742
long d_col1[] ={ 0, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 10, 11, 12};
4743        long d_col2[] ={ 1, 1, 2, 3, 5, 0, 3, 5, 0, 0, 1, 42, 42, 1};
4744        long d_col3[] ={91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104};
4745
4746        
4747
4748        REPORT("Starting t_019");
4749
4750        // create the base table
4751
long base_conglomid =
4752            tc.createConglomerate(
4753                "heap", // create a heap conglomerate
4754
base_row, // base table template row
4755
null, //column sort order - not required for heap
4756
null, // default properties
4757
TransactionController.IS_DEFAULT); // not temporary
4758

4759        // Open the base table
4760
ConglomerateController base_cc =
4761            tc.openConglomerate(
4762                base_conglomid,
4763                false,
4764                TransactionController.OPENMODE_FORUPDATE,
4765                TransactionController.MODE_RECORD,
4766                TransactionController.ISOLATION_SERIALIZABLE);
4767
4768        // initialize the secondary index row - pointing it at base row
4769
index_row.init(base_row, base_cc.newRowLocationTemplate(), 5);
4770
4771        Properties JavaDoc properties =
4772            createProperties(
4773                null, // no current properties list
4774
false, // don't allow duplicates
4775
5, // 4 columns in index row
4776
5, // non-unique index
4777
true, // maintain parent links
4778
base_conglomid, // base conglom id
4779
4); // row loc in last column
4780

4781        // create the index with all the columns in descending order
4782
ColumnOrdering order[] = new ColumnOrdering[5];
4783        order[0] = new T_ColumnOrderingImpl(0, false); // Descending
4784
order[1] = new T_ColumnOrderingImpl(1, true); // Ascending
4785
order[2] = new T_ColumnOrderingImpl(2, true); // Ascending
4786
order[3] = new T_ColumnOrderingImpl(3, false); // descending
4787
order[4] = new T_ColumnOrderingImpl(4, true); // asccending
4788

4789        long index_conglomid =
4790            tc.createConglomerate(
4791                "BTREE", // create a btree secondary
4792
index_row.getRow(), // row template
4793
order, //column sort order - default
4794
properties, // properties
4795
TransactionController.IS_DEFAULT); // not temporary
4796

4797        // Open the conglomerate.
4798
ConglomerateController index_cc =
4799            tc.openConglomerate(
4800                index_conglomid,
4801                false,
4802                TransactionController.OPENMODE_FORUPDATE,
4803                TransactionController.MODE_RECORD,
4804                TransactionController.ISOLATION_SERIALIZABLE);
4805
4806        // Create a row.
4807
T_SecondaryIndexRow template = new T_SecondaryIndexRow();
4808        RowLocation row_loc = base_cc.newRowLocationTemplate();
4809        template.init(base_row, row_loc, 5);
4810
4811        // insert them in reverse order just to make sure btree is sorting them
4812
for (int i = col1.length - 1; i >= 0; i--)
4813        {
4814            ((SQLLongint)(template.getRow()[0])).setValue(col1[i]);
4815            ((SQLLongint)(template.getRow()[1])).setValue(col2[i]);
4816            ((SQLLongint)(template.getRow()[2])).setValue(col3[i]);
4817            base_row[3] = new SQLChar(string_1500char);
4818
4819            base_cc.insertAndFetchLocation(base_row, row_loc);
4820
4821            // Insert the row.
4822
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
4823
// ")" + template);
4824
if (index_cc.insert(template.getRow()) != 0)
4825                throw T_Fail.testFailMsg("insert failed");
4826        }
4827
4828        index_cc.checkConsistency();
4829
4830        ((B2IController)index_cc).debugConglomerate();
4831
4832        ret_val = t_ascdesc1_scan_test_cases(tc, index_conglomid, template);
4833
4834        // insert and delete some interesting rows, deleted space management
4835
// may or may not clean these up.
4836
for (int i = d_col1.length - 1; i >= 0; i--)
4837        {
4838            ((SQLLongint)(template.getRow()[0])).setValue(d_col1[i]);
4839            ((SQLLongint)(template.getRow()[1])).setValue(d_col2[i]);
4840            ((SQLLongint)(template.getRow()[2])).setValue(d_col3[i]);
4841            base_row[3] = new SQLChar(string_1500char);
4842
4843            base_cc.insertAndFetchLocation(base_row, row_loc);
4844
4845            // Insert the row.
4846
// System.out.println("Adding record (" + -(i - (col1.length -1)) +
4847
// ")" + template);
4848
if (index_cc.insert(template.getRow()) != 0)
4849                throw T_Fail.testFailMsg("insert failed");
4850
4851            // now delete the row.
4852
base_cc.delete(row_loc);
4853
4854            ScanController delete_scan =
4855                tc.openScan(index_conglomid, false,
4856                            TransactionController.OPENMODE_FORUPDATE,
4857                            TransactionController.MODE_RECORD,
4858                            TransactionController.ISOLATION_SERIALIZABLE,
4859                            (FormatableBitSet) null,
4860                            template.getRow(), ScanController.GE,
4861                            null,
4862                            template.getRow(), ScanController.GT);
4863
4864            if (!delete_scan.next())
4865            {
4866                throw T_Fail.testFailMsg("delete could not find key");
4867            }
4868            else
4869            {
4870                delete_scan.delete();
4871
4872                if (delete_scan.next())
4873                    throw T_Fail.testFailMsg("delete found more than one key");
4874            }
4875
4876            delete_scan.close();
4877        }
4878
4879        ret_val = t_ascdesc1_scan_test_cases(tc, index_conglomid, template);
4880
4881
4882        // Close the conglomerate.
4883
index_cc.close();
4884
4885        tc.commit();
4886        REPORT("Ending t_019");
4887
4888        return(ret_val);
4889    }
4890
4891    /**
4892     * Test read uncommitted cases on scan.
4893     * <p>
4894     *
4895     * @exception StandardException Standard exception policy.
4896     * @exception T_Fail Throws T_Fail on any test failure.
4897     **/

4898    protected boolean t_020(TransactionController tc)
4899        throws StandardException, T_Fail
4900    {
4901        ScanController scan = null;
4902
4903        REPORT("Starting t_020");
4904
4905        T_CreateConglomRet create_ret = new T_CreateConglomRet();
4906
4907        // Create the btree so that it only allows 2 rows per page.
4908
createCongloms(tc, 2, false, false, 2, create_ret);
4909
4910        // Open the base table
4911
ConglomerateController base_cc =
4912            tc.openConglomerate(
4913                create_ret.base_conglomid,
4914                false,
4915                TransactionController.OPENMODE_FORUPDATE,
4916                TransactionController.MODE_RECORD,
4917                TransactionController.ISOLATION_SERIALIZABLE);
4918
4919        // Open the secondary index
4920
ConglomerateController index_cc =
4921            tc.openConglomerate(
4922                create_ret.index_conglomid,
4923                false,
4924                TransactionController.OPENMODE_FORUPDATE,
4925                TransactionController.MODE_RECORD,
4926                TransactionController.ISOLATION_SERIALIZABLE);
4927
4928        // objects used to insert rows into base and index tables.
4929
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
4930        T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
4931        RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
4932
4933        index_row1.init(r1, base_rowloc1, 3);
4934
4935        // insert one row into the table/index
4936

4937        // Open the base table
4938
base_cc =
4939            tc.openConglomerate(
4940                create_ret.base_conglomid,
4941                false,
4942                TransactionController.OPENMODE_FORUPDATE,
4943                TransactionController.MODE_RECORD,
4944                TransactionController.ISOLATION_SERIALIZABLE);
4945
4946        // Open the secondary index
4947
index_cc =
4948            tc.openConglomerate(
4949                create_ret.index_conglomid,
4950                false,
4951                TransactionController.OPENMODE_FORUPDATE,
4952                TransactionController.MODE_RECORD,
4953                TransactionController.ISOLATION_SERIALIZABLE);
4954
4955        // insert one row that does not cause failure.
4956
((SQLLongint)r1[0]).setValue(2);
4957        ((SQLLongint)r1[1]).setValue(10000);
4958
4959        // Insert the row into the base table;remember its location.
4960
base_cc.insertAndFetchLocation(r1, base_rowloc1);
4961
4962        // Insert the row into the secondary index.
4963
if (index_cc.insert(index_row1.getRow()) != 0)
4964            throw T_Fail.testFailMsg("insert failed");
4965
4966        // Commit the create of the tables so that the following aborts don't
4967
// undo that work.
4968
tc.commit();
4969
4970
4971        // TEST 1 - position a read uncommitted scan on a row which is
4972
// purged by a split trying to get space on the page, and then see
4973
// what happens when the scan trys to continue. This can only happen
4974
// currently if the same transaction deletes the row and while having
4975
// the scan open also does inserts onto the same page. Otherwise the
4976
// btree scan will maintain a "page scan locks" which will prevent
4977
// the row from being purged out from underneath it.
4978

4979
4980        tc.commit();
4981        REPORT("Ending t_020");
4982
4983        return true;
4984    }
4985
4986    public static String JavaDoc repeatString(String JavaDoc data, int repeat) {
4987
4988        String JavaDoc s = data;
4989        for (int i = 1; i < repeat; i++)
4990            s += data;
4991
4992        return s;
4993    }
4994
4995}
4996
4997class T_CreateConglomRet
4998{
4999    public long base_conglomid;
5000    public long index_conglomid;
5001    // public DataValueDescriptor[] base_template_row;
5002
public DataValueDescriptor[] index_template_row;
5003}
5004
Popular Tags