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

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


0001:        /*
0002:
0003:           Derby - Class org.apache.derbyTesting.unitTests.store.T_AccessFactory
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derbyTesting.unitTests.store;
0023:
0024:        import org.apache.derbyTesting.unitTests.harness.T_Generic;
0025:        import org.apache.derbyTesting.unitTests.harness.T_Fail;
0026:
0027:        import org.apache.derby.iapi.store.access.*;
0028:
0029:        import org.apache.derby.iapi.types.SQLLongint;
0030:
0031:        import org.apache.derby.iapi.services.context.ContextManager;
0032:        import org.apache.derby.iapi.services.context.ContextService;
0033:
0034:        import org.apache.derby.iapi.services.io.Storable;
0035:
0036:        import org.apache.derby.iapi.services.monitor.Monitor;
0037:        import org.apache.derby.iapi.services.sanity.SanityManager;
0038:        import org.apache.derby.iapi.services.io.FormatIdUtil;
0039:
0040:        import org.apache.derby.iapi.error.StandardException;
0041:
0042:        import org.apache.derby.iapi.types.DataValueDescriptor;
0043:
0044:        import org.apache.derby.iapi.types.RowLocation;
0045:
0046:        import org.apache.derby.iapi.store.raw.RawStoreFactory;
0047:        import org.apache.derby.iapi.store.raw.Transaction;
0048:        import org.apache.derby.iapi.reference.Property;
0049:        import org.apache.derby.iapi.reference.SQLState;
0050:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0051:        import org.apache.derby.iapi.services.i18n.MessageService;
0052:        import java.io.File;
0053:        import java.io.Serializable;
0054:        import java.util.Hashtable;
0055:        import java.util.Properties;
0056:        import org.apache.derby.iapi.types.SQLInteger;
0057:
0058:        import org.apache.derby.iapi.types.SQLChar;
0059:
0060:        public class T_AccessFactory extends T_Generic {
0061:            private static final String testService = "accessTest";
0062:
0063:            AccessFactory store = null;
0064:
0065:            public T_AccessFactory() {
0066:                super ();
0067:            }
0068:
0069:            /*
0070:             ** Methods of UnitTest.
0071:             */
0072:
0073:            /*
0074:             ** Methods required by T_Generic
0075:             */
0076:
0077:            public String getModuleToTestProtocolName() {
0078:                return AccessFactory.MODULE;
0079:            }
0080:
0081:            /**
0082:            	@exception T_Fail Unexpected behaviour from the API
0083:             */
0084:
0085:            protected void runTests() throws T_Fail {
0086:                TransactionController tc = null;
0087:                boolean pass = false;
0088:
0089:                // Create a AccessFactory to test.
0090:
0091:                // don't automatic boot this service if it gets left around
0092:                if (startParams == null) {
0093:                    startParams = new Properties();
0094:                }
0095:                startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
0096:                // remove the service directory to ensure a clean run
0097:                startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE
0098:                        .toString());
0099:
0100:                // see if we are testing encryption
0101:                startParams = T_Util.setEncryptionParam(startParams);
0102:
0103:                try {
0104:                    store = (AccessFactory) Monitor.createPersistentService(
0105:                            getModuleToTestProtocolName(), testService,
0106:                            startParams);
0107:                } catch (StandardException mse) {
0108:                    throw T_Fail.exceptionFail(mse);
0109:                }
0110:
0111:                if (store == null) {
0112:                    throw T_Fail.testFailMsg(getModuleToTestProtocolName()
0113:                            + " service not started.");
0114:                }
0115:
0116:                REPORT("(unitTestMain) Testing " + testService);
0117:
0118:                try {
0119:
0120:                    ContextManager cm = ContextService.getFactory()
0121:                            .getCurrentContextManager();
0122:
0123:                    tc = store.getAndNameTransaction(cm,
0124:                            AccessFactoryGlobals.USER_TRANS_NAME);
0125:
0126:                    if (dropTest(tc) && holdCursor(tc) && readUncommitted(tc)
0127:                            && updatelocks(tc) && nestedUserTransaction(tc)
0128:                            && positionAtRowLocation(tc) && sortCost(tc)
0129:                            && storeCost(tc) && partialScan(tc) && scanInfo(tc)
0130:                            && insertAndUpdateExample(tc)
0131:                            && insertAndFetchExample(tc) && scanExample(tc)
0132:                            && alterTable(tc) && tempTest(tc)
0133:                            && getTableProperties(tc) && insert_bench(tc)
0134:                            && transactionalProperties(tc) && commitTest(tc)) {
0135:                        pass = true;
0136:                    }
0137:
0138:                    // Make sure commitNoSync gets executed sometimes.
0139:                    tc.commitNoSync(TransactionController.RELEASE_LOCKS);
0140:
0141:                    tc.destroy();
0142:
0143:                    if (!pass)
0144:                        throw T_Fail.testFailMsg("test failed");
0145:
0146:                } catch (StandardException e) {
0147:                    String msg = e.getMessage();
0148:                    if (msg == null)
0149:                        msg = e.getClass().getName();
0150:                    REPORT(msg);
0151:                    e.printStackTrace();
0152:                    throw T_Fail.exceptionFail(e);
0153:                } catch (Throwable t) {
0154:                    t.printStackTrace();
0155:                }
0156:
0157:            }
0158:
0159:            /*
0160:             ** Methods of T_AccessFactory.
0161:             */
0162:
0163:            private void flush_cache() throws StandardException {
0164:                // flush and empty cache to make sure rereading stuff works.
0165:                RawStoreFactory rawstore = (RawStoreFactory) Monitor
0166:                        .findServiceModule(this .store, RawStoreFactory.MODULE);
0167:
0168:                rawstore.checkpoint();
0169:            }
0170:
0171:            protected boolean insertAndFetchExample(TransactionController tc)
0172:                    throws StandardException, T_Fail {
0173:                REPORT("(insertAndFetchExample)");
0174:
0175:                // First a negative test - make sure heap requires a template:
0176:
0177:                try {
0178:                    // Create a heap conglomerate.
0179:                    long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0180:                            null, // ERROR - Heap requires a template!!!
0181:                            null, // column sort order not required for heap
0182:                            null, // default properties
0183:                            TransactionController.IS_DEFAULT); // not temporary
0184:
0185:                    throw T_Fail
0186:                            .testFailMsg("Allowed heap create without template.");
0187:                } catch (Throwable t) {
0188:                    // expected error, just continue.
0189:                }
0190:
0191:                // Create a heap conglomerate.
0192:                T_AccessRow template_row = new T_AccessRow(1);
0193:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0194:                        template_row.getRowArray(), // 1 column template.
0195:                        null, // column sort order not required for heap
0196:                        null, // default properties
0197:                        TransactionController.IS_DEFAULT); // not temporary
0198:
0199:                // Insert and fetch some values.
0200:                if (insertAndFetch(tc, conglomid, 33)
0201:                        && insertAndFetch(tc, conglomid, -1)
0202:                        && insertAndFetch(tc, conglomid, -1000000000)) {
0203:                    return true;
0204:                } else {
0205:                    return false;
0206:                }
0207:            }
0208:
0209:            // Insert a single row with a single column containing
0210:            // the argument integer, and fetch it back, making sure that
0211:            // we read the correct value.
0212:            //
0213:            protected boolean insertAndFetch(TransactionController tc,
0214:                    long conglomid, int value) throws StandardException, T_Fail {
0215:                StaticCompiledOpenConglomInfo static_info = tc
0216:                        .getStaticCompiledConglomInfo(conglomid);
0217:
0218:                DynamicCompiledOpenConglomInfo dynamic_info = tc
0219:                        .getDynamicCompiledConglomInfo(conglomid);
0220:
0221:                String curr_xact_name = tc.getTransactionIdString();
0222:
0223:                REPORT("(insertAndFetch) xact id = " + curr_xact_name);
0224:
0225:                // Open the conglomerate.
0226:                ConglomerateController cc = tc.openCompiledConglomerate(false,
0227:                        TransactionController.OPENMODE_FORUPDATE,
0228:                        TransactionController.MODE_RECORD,
0229:                        TransactionController.ISOLATION_SERIALIZABLE,
0230:                        static_info, dynamic_info);
0231:
0232:                // Create a row.
0233:                T_AccessRow r1 = new T_AccessRow(1);
0234:                SQLInteger c1 = new SQLInteger(value);
0235:                r1.setCol(0, c1);
0236:
0237:                // Get a location template
0238:                RowLocation rowloc = cc.newRowLocationTemplate();
0239:
0240:                // Insert the row and remember its location.
0241:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
0242:
0243:                // quick test to make sure we can hash insert and find row location.
0244:                Hashtable test_rowloc_hash = new Hashtable();
0245:                test_rowloc_hash.put(rowloc, rowloc);
0246:
0247:                RowLocation hash_find = (RowLocation) test_rowloc_hash
0248:                        .get(rowloc);
0249:
0250:                if (!hash_find.equals(rowloc))
0251:                    throw T_Fail
0252:                            .testFailMsg("(insertAndFetch) bad hash lookup 1");
0253:
0254:                hash_find = (RowLocation) test_rowloc_hash.remove(rowloc);
0255:
0256:                if (!hash_find.equals(rowloc))
0257:                    throw T_Fail
0258:                            .testFailMsg("(insertAndFetch) bad hash lookup 2");
0259:
0260:                hash_find = (RowLocation) test_rowloc_hash.remove(rowloc);
0261:
0262:                if (hash_find != null)
0263:                    throw T_Fail
0264:                            .testFailMsg("(insertAndFetch) bad hash lookup 3");
0265:
0266:                // Create a new row of the same type (since the interface expects
0267:                // the callers to be keeping the row types straight), but with
0268:                // a different column value.
0269:                T_AccessRow r2 = new T_AccessRow(1);
0270:                SQLInteger c2 = new SQLInteger(0);
0271:                r2.setCol(0, c2);
0272:
0273:                // Fetch the stored value.
0274:                if (!cc
0275:                        .fetch(rowloc, r2.getRowArray(),
0276:                                (FormatableBitSet) null)) {
0277:                    throw T_Fail
0278:                            .testFailMsg("(insertAndFetch) fetch found no row.");
0279:                }
0280:
0281:                // Fetch using the fetch partial column interface
0282:                SQLInteger c3 = new SQLInteger(0);
0283:                FormatableBitSet singleColumn = new FormatableBitSet(1);
0284:                singleColumn.set(0);
0285:                DataValueDescriptor[] c3row = new DataValueDescriptor[1];
0286:                c3row[0] = c3;
0287:
0288:                if (!cc.fetch(rowloc, c3row, singleColumn)) {
0289:                    throw T_Fail
0290:                            .testFailMsg("(insertAndFetch) fetch found no row.");
0291:                }
0292:
0293:                // Close the conglomerate.
0294:                cc.close();
0295:
0296:                // Make sure we read back the value we wrote.
0297:                if (c2.getInt() != value)
0298:                    throw T_Fail
0299:                            .testFailMsg("(insertAndFetch) Fetched value != inserted value.");
0300:
0301:                if (c3.getInt() != value)
0302:                    throw T_Fail
0303:                            .testFailMsg("(insertAndFetch) Fetched value != inserted value.");
0304:
0305:                return true;
0306:            }
0307:
0308:            protected boolean insertAndUpdateExample(TransactionController tc)
0309:                    throws StandardException, T_Fail {
0310:                // Create a heap conglomerate.
0311:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0312:                        new T_AccessRow(1).getRowArray(), // 1 column template.
0313:                        null, // column sort order not required for heap
0314:                        null, // default properties
0315:                        TransactionController.IS_DEFAULT); // not temporary
0316:
0317:                REPORT("(insertAndUpdateExample)");
0318:
0319:                // Insert and update some values
0320:                if (insertAndUpdate(tc, conglomid, -1, -1003152)
0321:                        && insertAndUpdate(tc, conglomid, 0, 2000000000)
0322:                        && deletetest(tc, conglomid, 1, 2)) {
0323:                    return true;
0324:                }
0325:
0326:                return false;
0327:            }
0328:
0329:            // Insert a single row with a single column containing
0330:            // the first argument integer, delete it, make sure subsequent
0331:            // delete, replace, and replace a single column return false.
0332:            //
0333:            protected boolean deletetest(TransactionController tc,
0334:                    long conglomid, int value1, int value2)
0335:                    throws StandardException, T_Fail {
0336:                boolean ret_val;
0337:
0338:                // Open the conglomerate.
0339:                ConglomerateController cc = tc.openConglomerate(conglomid,
0340:                        false, TransactionController.OPENMODE_FORUPDATE,
0341:                        TransactionController.MODE_RECORD,
0342:                        TransactionController.ISOLATION_SERIALIZABLE);
0343:
0344:                // Create a row.
0345:                T_AccessRow r1 = new T_AccessRow(1);
0346:                r1.setCol(0, new SQLInteger(value1));
0347:
0348:                // Get a location template
0349:                RowLocation rowloc = cc.newRowLocationTemplate();
0350:
0351:                // Insert the row and remember its location.
0352:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
0353:
0354:                // delete it.
0355:                if (!cc.delete(rowloc)) {
0356:                    throw T_Fail
0357:                            .testFailMsg("(deleteTest) delete of row failed");
0358:                }
0359:
0360:                // subsequent replace, update a single column, and delete 
0361:                // should return false 
0362:
0363:                // update single column
0364:                DataValueDescriptor[] update_row = new DataValueDescriptor[1];
0365:                FormatableBitSet update_desc = new FormatableBitSet(1);
0366:                update_desc.set(0);
0367:                if (cc.replace(rowloc, update_row, update_desc)) {
0368:                    throw T_Fail
0369:                            .testFailMsg("(deleteTest) partial column row replace returned true on del row");
0370:                }
0371:
0372:                // update whole row.
0373:                if (cc.replace(rowloc, r1.getRowArray(),
0374:                        (FormatableBitSet) null)) {
0375:                    throw T_Fail
0376:                            .testFailMsg("(deleteTest) update returned true on del row");
0377:                }
0378:                if (cc.delete(rowloc)) {
0379:                    throw T_Fail
0380:                            .testFailMsg("(deleteTest) delete returned true on del row");
0381:                }
0382:
0383:                // Close the conglomerate.
0384:                cc.close();
0385:
0386:                return true;
0387:            }
0388:
0389:            // Insert a single row with a single column containing
0390:            // the first argument integer, update it to the second
0391:            // value, and make sure the update happened.
0392:            //
0393:            protected boolean insertAndUpdate(TransactionController tc,
0394:                    long conglomid, int value1, int value2)
0395:                    throws StandardException, T_Fail {
0396:                // Open the conglomerate.
0397:                ConglomerateController cc = tc.openConglomerate(conglomid,
0398:                        false, TransactionController.OPENMODE_FORUPDATE,
0399:                        TransactionController.MODE_RECORD,
0400:                        TransactionController.ISOLATION_SERIALIZABLE);
0401:
0402:                // Create a row.
0403:                T_AccessRow r1 = new T_AccessRow(1);
0404:                r1.setCol(0, new SQLInteger(value1));
0405:
0406:                // Get a location template
0407:                RowLocation rowloc = cc.newRowLocationTemplate();
0408:
0409:                // Insert the row and remember its location.
0410:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
0411:
0412:                // Update it to the second value
0413:                DataValueDescriptor[] update_row = new DataValueDescriptor[1];
0414:                update_row[0] = new SQLInteger(value2);
0415:
0416:                FormatableBitSet update_desc = new FormatableBitSet(1);
0417:                update_desc.set(0);
0418:
0419:                cc.replace(rowloc, update_row, update_desc);
0420:
0421:                // Create a new row (of the same type, since the interface expects
0422:                // the callers to be keeping the row types straight.
0423:                T_AccessRow r2 = new T_AccessRow(1);
0424:                SQLInteger c2 = new SQLInteger(0);
0425:                r2.setCol(0, c2);
0426:
0427:                // Fetch the stored value.
0428:                if (!cc
0429:                        .fetch(rowloc, r2.getRowArray(),
0430:                                (FormatableBitSet) null)) {
0431:                    throw T_Fail
0432:                            .testFailMsg("(insertAndUpdate) Fetch val not there.");
0433:                }
0434:
0435:                // Close the conglomerate.
0436:                cc.close();
0437:
0438:                // Make sure we read back the value we wrote.
0439:                if (c2.getInt() != value2)
0440:                    throw T_Fail
0441:                            .testFailMsg("(insertAndUpdate) Fetch value != updated value.");
0442:                else
0443:                    return true;
0444:            }
0445:
0446:            protected boolean scanExample(TransactionController tc)
0447:                    throws StandardException, T_Fail {
0448:                tc.commit();
0449:
0450:                if (!tc.isPristine() || !tc.isIdle() || tc.isGlobal())
0451:                    throw T_Fail
0452:                            .testFailMsg("(scanExample) bad xact state after commit.");
0453:
0454:                if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)
0455:                        || (tc
0456:                                .countOpens(TransactionController.OPEN_CONGLOMERATE) > 0)
0457:                        || (tc.countOpens(TransactionController.OPEN_SCAN) > 0)
0458:                        || (tc
0459:                                .countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)
0460:                        || (tc.countOpens(TransactionController.OPEN_SORT) > 0)) {
0461:                    System.out.println("OPENED 0:\n" + tc.debugOpened());
0462:                    return (FAIL("unexpected open count."));
0463:                }
0464:
0465:                // Create a heap conglomerate.
0466:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0467:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
0468:                        null, // column sort order not required for heap
0469:                        null, // default properties
0470:                        TransactionController.IS_DEFAULT); // not temporary
0471:
0472:                REPORT("(scanExample) starting");
0473:
0474:                // Open it.
0475:                ConglomerateController cc = tc.openConglomerate(conglomid,
0476:                        false, TransactionController.OPENMODE_FORUPDATE,
0477:                        TransactionController.MODE_RECORD,
0478:                        TransactionController.ISOLATION_SERIALIZABLE);
0479:
0480:                // Insert some values.
0481:                int values[] = { 11, 22, 33, 44, 55, 66 };
0482:                T_AccessRow row = new T_AccessRow(1);
0483:                for (int i = 0; i < values.length; i++) {
0484:                    row.setCol(0, new SQLInteger(values[i]));
0485:                    if (cc.insert(row.getRowArray()) != 0)
0486:                        throw T_Fail
0487:                                .testFailMsg("(scanExample after insert) insert failed ");
0488:                }
0489:
0490:                // For test coverage call the debugging output routine - can't diff it.
0491:                REPORT("(scanExample) debug output testing: "
0492:                        + tc.debugOpened());
0493:
0494:                // Close the conglomerate.
0495:                cc.close();
0496:
0497:                if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)
0498:                        || (tc
0499:                                .countOpens(TransactionController.OPEN_CONGLOMERATE) > 0)
0500:                        || (tc.countOpens(TransactionController.OPEN_SCAN) > 0)
0501:                        || (tc
0502:                                .countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)
0503:                        || (tc.countOpens(TransactionController.OPEN_SORT) > 0)) {
0504:                    System.out.println("OPENED 1:\n" + tc.debugOpened());
0505:                    return (FAIL("unexpected open count."));
0506:                }
0507:
0508:                REPORT("(scanExample) rows inserted");
0509:
0510:                // Correlates our position in the upcoming scan to the values array.
0511:                int scanindex = 0;
0512:
0513:                // Put a specific column in the row so we can look at it.
0514:                SQLInteger col = new SQLInteger(0);
0515:                row.setCol(0, col);
0516:
0517:                flush_cache();
0518:
0519:                StaticCompiledOpenConglomInfo static_info = tc
0520:                        .getStaticCompiledConglomInfo(conglomid);
0521:
0522:                // Open a scan on the conglomerate.
0523:                ScanController scan1 = tc.openCompiledScan(
0524:                        false, // don't hold
0525:                        0, // not for update
0526:                        TransactionController.MODE_RECORD,
0527:                        TransactionController.ISOLATION_SERIALIZABLE,
0528:                        (FormatableBitSet) null, // all columns, all as objects
0529:                        null, // start position - first row in conglomerate
0530:                        0, // unused if start position is null.
0531:                        null, // qualifier - accept all rows
0532:                        null, // stop position - last row in conglomerate
0533:                        0, // unused if stop position is null.
0534:                        static_info, tc
0535:                                .getDynamicCompiledConglomInfo(conglomid));
0536:
0537:                // check out the RowCountable interface's.
0538:
0539:                if (scan1.getEstimatedRowCount() != 6) {
0540:                    throw T_Fail
0541:                            .testFailMsg("(scanExample) estimated row count not 6:"
0542:                                    + scan1.getEstimatedRowCount());
0543:                }
0544:
0545:                // Test 2 - ASSERT(should be able to set arbitrary row count)
0546:
0547:                scan1.setEstimatedRowCount(5);
0548:
0549:                if (scan1.getEstimatedRowCount() != 5) {
0550:                    throw T_Fail
0551:                            .testFailMsg("(scanExample) estimated row count not 5");
0552:                }
0553:
0554:                // Iterate through and check that the rows are still there.
0555:                while (scan1.next()) {
0556:                    scan1.fetch(row.getRowArray());
0557:
0558:                    // Check we got the value we put in.
0559:                    if (col.getInt() != values[scanindex])
0560:                        throw T_Fail
0561:                                .testFailMsg("(scanExample after insert) Row "
0562:                                        + scanindex + " should have been "
0563:                                        + values[scanindex] + ", was "
0564:                                        + col.getInt());
0565:
0566:                    scanindex++;
0567:                }
0568:
0569:                // make sure another next() call continues to return false.
0570:                if (scan1.next())
0571:                    throw T_Fail
0572:                            .testFailMsg("(scanExample after insert) should continue to return false after reaching end of scan");
0573:
0574:                // see if reopen scan interfaces work
0575:                scan1.reopenScan(null, // start position - first row in conglomerate
0576:                        0, // unused if start position is null.
0577:                        null, // qualifier - accept all rows
0578:                        null, // stop position - last row in conglomerate
0579:                        0); // unused if stop position is null.
0580:
0581:                scan1.next();
0582:                scan1.next();
0583:                scan1.next();
0584:                RowLocation third_row_rowloc = scan1.newRowLocationTemplate();
0585:                scan1.fetchLocation(third_row_rowloc);
0586:
0587:                // see if reopen scan interfaces work
0588:                scan1.reopenScanByRowLocation(third_row_rowloc, null);
0589:
0590:                scanindex = 2;
0591:                while (scan1.next()) {
0592:                    scan1.fetch(row.getRowArray());
0593:
0594:                    // Check we got the value we put in.
0595:                    if (col.getInt() != values[scanindex])
0596:                        throw T_Fail
0597:                                .testFailMsg("(scanExample after insert) Row "
0598:                                        + scanindex + " should have been "
0599:                                        + values[scanindex] + ", was "
0600:                                        + col.getInt());
0601:
0602:                    scanindex++;
0603:                }
0604:
0605:                scan1.close();
0606:
0607:                // Check we saw the right number of rows.
0608:                if (scanindex != values.length)
0609:                    throw T_Fail
0610:                            .testFailMsg("(scanExample after insert) Expected "
0611:                                    + values.length + "rows, got " + scanindex);
0612:
0613:                REPORT("(scanExample) rows present and accounted for");
0614:
0615:                // Open another scan on the conglomerate.
0616:                ScanController scan2 = tc.openScan(
0617:                        conglomid,
0618:                        false, // don't hold
0619:                        TransactionController.OPENMODE_FORUPDATE, // for update
0620:                        TransactionController.MODE_RECORD,
0621:                        TransactionController.ISOLATION_SERIALIZABLE,
0622:                        (FormatableBitSet) null, // all columns, all as objects
0623:                        null, // start position - first row in conglomerate
0624:                        0, // unused if start position is null.
0625:                        null, // qualifier - accept all rows
0626:                        null, // stop position - last row in conglomerate
0627:                        0); // unused if stop position is null.
0628:
0629:                // Iterate with the second scan and fiddle with the values so they
0630:                // look like the new value array.
0631:                int newvalues[] = { 22, 33, 444, 55, 6666 };
0632:                while (scan2.next()) {
0633:                    scan2.fetch(row.getRowArray());
0634:
0635:                    switch (((SQLInteger) row.getCol(0)).getInt()) {
0636:                    case 11:
0637:                        if (!scan2.delete())
0638:                            throw T_Fail
0639:                                    .testFailMsg("(scanExample) delete failed.");
0640:                        break;
0641:                    case 22:
0642:                    case 33:
0643:                    case 55:
0644:                        // leave these alone
0645:                        break;
0646:                    case 44:
0647:                        DataValueDescriptor[] update_row = new DataValueDescriptor[1];
0648:                        update_row[0] = new SQLInteger(444);
0649:
0650:                        FormatableBitSet update_desc = new FormatableBitSet(1);
0651:                        update_desc.set(0);
0652:
0653:                        if (!scan2.replace(update_row, update_desc)) {
0654:                            throw T_Fail
0655:                                    .testFailMsg("(scanExample) partial column row replace failed.");
0656:                        }
0657:                        break;
0658:                    case 66:
0659:                        row.setCol(0, new SQLInteger(6666));
0660:                        if (!scan2.replace(row.getRowArray(),
0661:                                (FormatableBitSet) null))
0662:                            throw T_Fail
0663:                                    .testFailMsg("(scanExample) replace failed.");
0664:                        break;
0665:                    default:
0666:                        throw T_Fail
0667:                                .testFailMsg("(scanExample) Read unexpected value.");
0668:                    }
0669:                }
0670:                scan2.close();
0671:
0672:                REPORT("(scanExample) rows fiddled with");
0673:
0674:                // Open a third scan on the conglomerate.
0675:                ScanController scan3 = tc.openScan(
0676:                        conglomid,
0677:                        false, // don't hold
0678:                        0, // not for update
0679:                        TransactionController.MODE_RECORD,
0680:                        TransactionController.ISOLATION_SERIALIZABLE,
0681:                        (FormatableBitSet) null, // all columns, all as objects
0682:                        null, // start position - first row in conglomerate
0683:                        0, // unused if start position is null.
0684:                        null, // qualifier - accept all rows
0685:                        null, // stop position - last row in conglomerate
0686:                        0); // unused if stop position is null.
0687:
0688:                // Iterate through and inspect the changes.
0689:                scanindex = 0;
0690:                row.setCol(0, col);
0691:                while (scan3.next()) {
0692:                    scan3.fetch(row.getRowArray());
0693:
0694:                    REPORT("(scanExample) scan3 fetched " + col.getInt());
0695:
0696:                    // Check we got the value we put in.
0697:                    if (col.getInt() != newvalues[scanindex])
0698:                        throw T_Fail
0699:                                .testFailMsg("(scanExample after changes) Row "
0700:                                        + scanindex + " should have been "
0701:                                        + newvalues[scanindex] + ", was "
0702:                                        + col.getInt());
0703:
0704:                    scanindex++;
0705:                }
0706:                scan3.close();
0707:
0708:                // Open a third scan on the conglomerate.
0709:                scan3 = tc.openScan(
0710:                        conglomid,
0711:                        false, // don't hold
0712:                        0, // not for update
0713:                        TransactionController.MODE_RECORD,
0714:                        TransactionController.ISOLATION_READ_UNCOMMITTED,
0715:                        (FormatableBitSet) null, // all columns, all as objects
0716:                        null, // start position - first row in conglomerate
0717:                        0, // unused if start position is null.
0718:                        null, // qualifier - accept all rows
0719:                        null, // stop position - last row in conglomerate
0720:                        0); // unused if stop position is null.
0721:
0722:                // Iterate through and inspect the changes.
0723:                scanindex = 0;
0724:                row.setCol(0, col);
0725:                while (scan3.next()) {
0726:                    scan3.fetch(row.getRowArray());
0727:
0728:                    REPORT("(scanExample) scan3 fetched " + col.getInt());
0729:
0730:                    // Check we got the value we put in.
0731:                    if (col.getInt() != newvalues[scanindex])
0732:                        throw T_Fail
0733:                                .testFailMsg("(scanExample after changes) Row "
0734:                                        + scanindex + " should have been "
0735:                                        + newvalues[scanindex] + ", was "
0736:                                        + col.getInt());
0737:
0738:                    scanindex++;
0739:                }
0740:                scan3.close();
0741:
0742:                // Check we saw the right number of rows.
0743:                if (scanindex != newvalues.length)
0744:                    throw T_Fail
0745:                            .testFailMsg("(scanExample after changes) Expected "
0746:                                    + newvalues.length
0747:                                    + "rows, got "
0748:                                    + scanindex);
0749:
0750:                REPORT("(scanExample) fiddled rows present and accounted for");
0751:
0752:                REPORT("(scanExample) testing expected delete errors");
0753:
0754:                // Open 4th scan on conglomerate and test "expected" error returns
0755:                // from replace, partial column replace, delete.
0756:                ScanController scan4 = tc.openScan(
0757:                        conglomid,
0758:                        false, // don't hold
0759:                        TransactionController.OPENMODE_FORUPDATE, // for update
0760:                        TransactionController.MODE_RECORD,
0761:                        TransactionController.ISOLATION_SERIALIZABLE,
0762:                        (FormatableBitSet) null, // all columns, all as objects
0763:                        null, // start position - first row in conglomerate
0764:                        0, // unused if start position is null.
0765:                        null, // qualifier - accept all rows
0766:                        null, // stop position - last row in conglomerate
0767:                        0); // unused if stop position is null.
0768:
0769:                // Iterate with the second scan find the "22" row, delete it and
0770:                // then test that operations on that deleted entry FAIL as expected.
0771:                while (scan4.next()) {
0772:                    scan4.fetch(row.getRowArray());
0773:
0774:                    if (!scan4.doesCurrentPositionQualify()) {
0775:                        throw T_Fail
0776:                                .testFailMsg("(scanExample doesCurrentPositionQualify() errors) Expected requalify of current row to succeed");
0777:                    }
0778:
0779:                    if (((SQLInteger) row.getCol(0)).getInt() == 22) {
0780:                        if (!scan4.delete()) {
0781:                            throw T_Fail
0782:                                    .testFailMsg("(scanExample delete errors) Delete failed.");
0783:                        }
0784:                        break;
0785:                    }
0786:                }
0787:
0788:                if (scan4.doesCurrentPositionQualify()) {
0789:                    throw T_Fail
0790:                            .testFailMsg("(scanExample doesCurrentPositionQualify() errors) Expected qualify of deleted row to FAIL");
0791:                }
0792:
0793:                DataValueDescriptor[] update_row = new DataValueDescriptor[1];
0794:
0795:                FormatableBitSet update_desc = new FormatableBitSet(1);
0796:                update_desc.set(0);
0797:
0798:                if (scan4.replace(update_row, update_desc)) {
0799:                    throw T_Fail
0800:                            .testFailMsg("(scanExample delete errors) Expected partial column replace to FAIL");
0801:                }
0802:                if (scan4.replace(row.getRowArray(), (FormatableBitSet) null)) {
0803:                    throw T_Fail
0804:                            .testFailMsg("(scanExample after changes) Expected replace to FAIL");
0805:                }
0806:                if (scan4.delete()) {
0807:                    throw T_Fail
0808:                            .testFailMsg("(scanExample after changes) Expected delete to FAIL");
0809:                }
0810:
0811:                scan4.close();
0812:
0813:                if ((tc.countOpens(TransactionController.OPEN_TOTAL) > 0)
0814:                        || (tc
0815:                                .countOpens(TransactionController.OPEN_CONGLOMERATE) > 0)
0816:                        || (tc.countOpens(TransactionController.OPEN_SCAN) > 0)
0817:                        || (tc
0818:                                .countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)
0819:                        || (tc.countOpens(TransactionController.OPEN_SORT) > 0)) {
0820:                    System.out.println("OPENED:\n" + tc.debugOpened());
0821:                    return (FAIL("unexpected open count."));
0822:                }
0823:
0824:                REPORT("(scanExample) completed");
0825:                return true;
0826:            }
0827:
0828:            protected boolean dropTest(TransactionController tc)
0829:                    throws StandardException, T_Fail {
0830:                ConglomerateController cc;
0831:
0832:                REPORT("(dropTest) starting");
0833:
0834:                // Test of drop conglomerate with abort by doing the following:
0835:                //     create table
0836:                //     commit
0837:                //     drop table
0838:                //     make sure table is not still there.
0839:                //     abort
0840:                //     make sure table is still there.
0841:
0842:                // Create a heap conglomerate.
0843:                long orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0844:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
0845:                        null, // column sort order not required for heap
0846:                        null, // default properties
0847:                        TransactionController.IS_DEFAULT); // not temporary
0848:
0849:                tc.commit();
0850:
0851:                tc.dropConglomerate(orig_conglomid);
0852:
0853:                // Try and Open it - it should fail.
0854:                try {
0855:                    cc = tc.openConglomerate(orig_conglomid, false,
0856:                            TransactionController.OPENMODE_FORUPDATE,
0857:                            TransactionController.MODE_RECORD,
0858:                            TransactionController.ISOLATION_SERIALIZABLE);
0859:
0860:                    throw T_Fail
0861:                            .testFailMsg("Open conglom on deleted conglom worked.");
0862:                } catch (StandardException e) {
0863:                    if (!e.getMessageId().equals(
0864:                            SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST)) {
0865:                        throw e;
0866:                    }
0867:
0868:                    // normal path through the test - conglomerate does not exist, 
0869:                    // ignore the expected error
0870:                }
0871:
0872:                // Try and Open a random non-existant conglomerate - it should fail.
0873:                try {
0874:                    cc = tc.openConglomerate(42424242, false,
0875:                            TransactionController.OPENMODE_FORUPDATE,
0876:                            TransactionController.MODE_RECORD,
0877:                            TransactionController.ISOLATION_SERIALIZABLE);
0878:
0879:                    throw T_Fail
0880:                            .testFailMsg("Open conglom on deleted conglom worked.");
0881:                } catch (StandardException e) {
0882:                    if (!e.getMessageId().equals(
0883:                            SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST)) {
0884:                        throw e;
0885:                    }
0886:
0887:                    // normal path through the test - conglomerate does not exist, 
0888:                    // ignore the expected error
0889:                }
0890:
0891:                // Try and delete it again - it should fail.
0892:                try {
0893:                    tc.dropConglomerate(orig_conglomid);
0894:
0895:                    throw T_Fail
0896:                            .testFailMsg("Delete conglom on deleted conglom worked.");
0897:                } catch (StandardException e) {
0898:                    // normal path through the test, ignore the expected error
0899:                }
0900:
0901:                // cursory test to make sure conglom directory is not screwed up.
0902:
0903:                // Create a heap conglomerate.
0904:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0905:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
0906:                        null, // column sort order not required for heap
0907:                        null, // default properties
0908:                        TransactionController.IS_DEFAULT); // not temporary
0909:
0910:                cc = tc.openConglomerate(conglomid, false,
0911:                        TransactionController.OPENMODE_FORUPDATE,
0912:                        TransactionController.MODE_RECORD,
0913:                        TransactionController.ISOLATION_SERIALIZABLE);
0914:
0915:                tc.abort();
0916:
0917:                // the original conglomerate should be still around after the abort.
0918:                cc = tc.openConglomerate(orig_conglomid, false,
0919:                        TransactionController.OPENMODE_FORUPDATE,
0920:                        TransactionController.MODE_RECORD,
0921:                        TransactionController.ISOLATION_SERIALIZABLE);
0922:
0923:                cc.close();
0924:
0925:                return true;
0926:            }
0927:
0928:            /**
0929:             * Test the access level getTableProperties() call.
0930:             * <p>
0931:             *
0932:             * @return true if the test succeeded.
0933:             *
0934:             * @param tc The transaction controller to use in the test.
0935:             *
0936:             * @exception  StandardException  Standard exception policy.
0937:             * @exception  T_Fail Unexpected behaviour from the API
0938:             **/
0939:            protected boolean getTableProperties(TransactionController tc)
0940:                    throws StandardException, T_Fail {
0941:                int key_value;
0942:
0943:                Properties prop = new Properties();
0944:
0945:                prop.put(Property.PAGE_SIZE_PARAMETER, "8192");
0946:                prop.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, "99");
0947:                prop.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, "42");
0948:                prop.put(RawStoreFactory.CONTAINER_INITIAL_PAGES, "22");
0949:
0950:                // Create a heap conglomerate.
0951:                T_AccessRow template_row = new T_AccessRow(1);
0952:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0953:                        template_row.getRowArray(), // 1 column template.
0954:                        null, // column sort order not required for heap
0955:                        prop, // default properties
0956:                        TransactionController.IS_DEFAULT); // not temporary
0957:                // Open the conglomerate.
0958:                ConglomerateController cc = tc.openConglomerate(conglomid,
0959:                        false, TransactionController.OPENMODE_FORUPDATE,
0960:                        TransactionController.MODE_RECORD,
0961:                        TransactionController.ISOLATION_SERIALIZABLE);
0962:
0963:                // verify that input properties were used.
0964:                Properties ret_prop = tc.getUserCreateConglomPropList();
0965:
0966:                cc.getTableProperties(ret_prop);
0967:
0968:                if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER)
0969:                        .compareTo("8192") != 0
0970:                        || ret_prop.getProperty(
0971:                                RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
0972:                                .compareTo("99") != 0
0973:                        || ret_prop.getProperty(
0974:                                RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
0975:                                .compareTo("42") != 0
0976:                        || ret_prop.getProperty(
0977:                                RawStoreFactory.CONTAINER_INITIAL_PAGES)
0978:                                .compareTo("22") != 0) {
0979:                    throw T_Fail
0980:                            .testFailMsg("(getTableProperties) Did not get expected table propertes(1)."
0981:                                    + "\nGot pageSize = "
0982:                                    + ret_prop
0983:                                            .getProperty(Property.PAGE_SIZE_PARAMETER)
0984:                                    + "\nGot reserved = "
0985:                                    + ret_prop
0986:                                            .getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
0987:                                    + "\nGot minimum record size = "
0988:                                    + ret_prop
0989:                                            .getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
0990:                                    + "\nGot initial pages = "
0991:                                    + ret_prop
0992:                                            .getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES));
0993:                }
0994:
0995:                ret_prop = cc.getInternalTablePropertySet(null);
0996:
0997:                if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER)
0998:                        .compareTo("8192") != 0
0999:                        || ret_prop.getProperty(
1000:                                RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
1001:                                .compareTo("99") != 0
1002:                        || ret_prop.getProperty(
1003:                                RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
1004:                                .compareTo("42") != 0
1005:                        || ret_prop.getProperty(
1006:                                RawStoreFactory.CONTAINER_INITIAL_PAGES)
1007:                                .compareTo("22") != 0) {
1008:                    throw T_Fail
1009:                            .testFailMsg("(getTableProperties) Did not get expected table propertes(2)."
1010:                                    + "\nGot pageSize = "
1011:                                    + ret_prop
1012:                                            .getProperty(Property.PAGE_SIZE_PARAMETER)
1013:                                    + "\nGot reserved = "
1014:                                    + ret_prop
1015:                                            .getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
1016:                                    + "\nGot minimum record size = "
1017:                                    + ret_prop
1018:                                            .getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
1019:                                    + "\nGot initial pages = "
1020:                                    + ret_prop
1021:                                            .getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES));
1022:                }
1023:
1024:                ret_prop = new Properties();
1025:
1026:                ret_prop = cc.getInternalTablePropertySet(ret_prop);
1027:
1028:                if (ret_prop.getProperty(Property.PAGE_SIZE_PARAMETER)
1029:                        .compareTo("8192") != 0
1030:                        || ret_prop.getProperty(
1031:                                RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
1032:                                .compareTo("99") != 0
1033:                        || ret_prop.getProperty(
1034:                                RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
1035:                                .compareTo("42") != 0
1036:                        || ret_prop.getProperty(
1037:                                RawStoreFactory.CONTAINER_INITIAL_PAGES)
1038:                                .compareTo("22") != 0) {
1039:                    throw T_Fail
1040:                            .testFailMsg("(getTableProperties) Did not get expected table propertes(3)."
1041:                                    + "\nGot pageSize = "
1042:                                    + ret_prop
1043:                                            .getProperty(Property.PAGE_SIZE_PARAMETER)
1044:                                    + "\nGot reserved = "
1045:                                    + ret_prop
1046:                                            .getProperty(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER)
1047:                                    + "\nGot minimum record size = "
1048:                                    + ret_prop
1049:                                            .getProperty(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER)
1050:                                    + "\nGot initial pages = "
1051:                                    + ret_prop
1052:                                            .getProperty(RawStoreFactory.CONTAINER_INITIAL_PAGES));
1053:                }
1054:
1055:                return (true);
1056:            }
1057:
1058:            /**
1059:             * Test the access level alter table interface for adding columns.
1060:             * <p>
1061:             *
1062:             * @return true if the test succeeded.
1063:             *
1064:             * @param tc The transaction controller to use in the test.
1065:             *
1066:             * @exception  StandardException  Standard exception policy.
1067:             * @exception  T_Fail Unexpected behaviour from the API
1068:             **/
1069:            protected boolean alterTable(TransactionController tc)
1070:                    throws StandardException, T_Fail {
1071:                int key_value;
1072:
1073:                REPORT("(alterTable) starting");
1074:
1075:                // Create a heap conglomerate.
1076:                T_AccessRow template_row = new T_AccessRow(1);
1077:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1078:                        template_row.getRowArray(), // 1 column template.
1079:                        null, // column sort order not required for heap
1080:                        null, // default properties
1081:                        TransactionController.IS_DEFAULT); // not temporary
1082:                // Open the conglomerate.
1083:                ConglomerateController cc = tc.openConglomerate(conglomid,
1084:                        false, TransactionController.OPENMODE_FORUPDATE,
1085:                        TransactionController.MODE_RECORD,
1086:                        TransactionController.ISOLATION_SERIALIZABLE);
1087:
1088:                // Create a 1 column row. int column = 1.
1089:                T_AccessRow r1 = new T_AccessRow(1);
1090:                SQLInteger c1 = new SQLInteger(1);
1091:                r1.setCol(0, c1);
1092:
1093:                // Get a location template
1094:                RowLocation rowloc1 = cc.newRowLocationTemplate();
1095:
1096:                // Insert the row and remember its location.
1097:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
1098:
1099:                // create another 1 column row. int column = 2.
1100:                // Get a location template
1101:                r1.setCol(0, new SQLInteger(2));
1102:                RowLocation rowloc2 = cc.newRowLocationTemplate();
1103:
1104:                // Insert the row and remember its location.
1105:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
1106:
1107:                // At this point the table looks like:
1108:                // col1
1109:                // ----
1110:                // 1
1111:                // 2
1112:
1113:                // RESOLVE - currently the store can't catch the following error:
1114:                /*
1115:                // Test that we can't alter while it is open.
1116:                try
1117:                {
1118:                    tc.addColumnToConglomerate(conglomid, 1, c1);
1119:                	throw T_Fail.testFailMsg(
1120:                        "(alterTable) Allowed alter table while table was open.");
1121:                }
1122:                catch (StandardException t)
1123:                {
1124:                    // expected error continue the test.
1125:                }
1126:                 */
1127:
1128:                // Test that we can't add data to columns that don't exist
1129:                // Currently we only error check in debug code.  
1130:                // RESOLVE - should this be a runtime error?
1131:                if (SanityManager.DEBUG) {
1132:                    try {
1133:                        T_AccessRow two_column_row = new T_AccessRow(2);
1134:                        SQLInteger col1 = new SQLInteger(3);
1135:                        SQLInteger col2 = new SQLInteger(3);
1136:                        cc.insert(two_column_row.getRowArray());
1137:                        throw T_Fail
1138:                                .testFailMsg("(alterTable) Allowed insert of bad row.");
1139:                    } catch (StandardException t) {
1140:                        // expected error continue the test.
1141:                    }
1142:                }
1143:
1144:                // Test that we can't fetch data columns that don't exist
1145:
1146:                // Currently we only error check for this in sanity code.
1147:                // RESOLVE - (mikem) should we check for this in released runtime?
1148:                if (SanityManager.DEBUG) {
1149:                    try {
1150:                        T_AccessRow two_column_row = new T_AccessRow(2);
1151:                        if (!cc.fetch(rowloc1, two_column_row.getRowArray(),
1152:                                (FormatableBitSet) null)) {
1153:                            throw T_Fail
1154:                                    .testFailMsg("(alterTable) Allowed fetch of bad row, bad ret val.");
1155:                        }
1156:
1157:                        throw T_Fail
1158:                                .testFailMsg("(alterTable) Allowed fetch of bad row.");
1159:                    } catch (StandardException t) {
1160:                        // expected error continue the test.
1161:                    }
1162:                }
1163:
1164:                // Test that we can't fetch data columns that don't exist
1165:                // Currently we only error check for this in sanity code.
1166:                // RESOLVE - (mikem) should we check for this in released runtime?
1167:                if (SanityManager.DEBUG) {
1168:                    try {
1169:                        DataValueDescriptor[] third_column_row = new DataValueDescriptor[3];
1170:
1171:                        third_column_row[2] = new SQLInteger(3);
1172:
1173:                        FormatableBitSet fetch_desc = new FormatableBitSet(3);
1174:                        fetch_desc.set(2);
1175:
1176:                        if (!cc.fetch(rowloc1, third_column_row, fetch_desc)) {
1177:                            throw T_Fail
1178:                                    .testFailMsg("(alterTable) Allowed fetch of bad row, bad ret val.");
1179:                        }
1180:
1181:                        throw T_Fail
1182:                                .testFailMsg("(alterTable) Allowed fetch of bad row.");
1183:                    } catch (StandardException t) {
1184:                        // expected error continue the test.
1185:                    }
1186:                }
1187:
1188:                // Test that we can't replace data columns that don't exist
1189:
1190:                // Currently we only error check for this in sanity code.
1191:                // RESOLVE - (mikem) should we check for this in released runtime?
1192:                if (SanityManager.DEBUG) {
1193:                    try {
1194:                        T_AccessRow two_column_row = new T_AccessRow(2);
1195:                        SQLInteger col1 = new SQLInteger(3);
1196:                        SQLInteger col2 = new SQLInteger(3);
1197:                        cc.replace(rowloc1, two_column_row.getRowArray(), null);
1198:                        throw T_Fail
1199:                                .testFailMsg("(alterTable) Allowed replace of bad row.");
1200:                    } catch (StandardException t) {
1201:                        // expected error continue the test.
1202:                    }
1203:                }
1204:
1205:                // Test that we can't replace data columns that don't exist
1206:                if (SanityManager.DEBUG) {
1207:                    try {
1208:                        DataValueDescriptor[] second_column_row = new DataValueDescriptor[2];
1209:                        second_column_row[1] = new SQLInteger(3);
1210:
1211:                        FormatableBitSet update_desc = new FormatableBitSet(2);
1212:                        update_desc.set(1);
1213:
1214:                        cc.replace(rowloc1, second_column_row, update_desc);
1215:                        throw T_Fail
1216:                                .testFailMsg("(alterTable) Allowed partial row update of bad column.");
1217:                    } catch (StandardException t) {
1218:                        // expected error continue the test.
1219:                    }
1220:                }
1221:
1222:                // Make sure commitNoSync gets executed sometimes.
1223:                tc.commitNoSync(TransactionController.RELEASE_LOCKS);
1224:
1225:                // now alter the conglomerate, add another int column
1226:                tc.addColumnToConglomerate(conglomid, 1, c1);
1227:
1228:                // Open the table after the close done by commit.
1229:                cc = tc.openConglomerate(conglomid, false,
1230:                        TransactionController.OPENMODE_FORUPDATE,
1231:                        TransactionController.MODE_RECORD,
1232:                        TransactionController.ISOLATION_SERIALIZABLE);
1233:
1234:                T_AccessRow two_column_row = new T_AccessRow(2);
1235:                SQLInteger col1 = new SQLInteger(3);
1236:                SQLInteger col2 = new SQLInteger(3);
1237:
1238:                // fetch the rows and make sure you get null's in new fields.
1239:                if (!cc.fetch(rowloc1, two_column_row.getRowArray(),
1240:                        (FormatableBitSet) null)) {
1241:                    throw T_Fail.testFailMsg("(alterTable) Row not there.");
1242:                }
1243:
1244:                if ((((SQLInteger) two_column_row.getCol(0)).getInt() != 1)
1245:                        || (!two_column_row.getCol(1).isNull())) {
1246:                    throw T_Fail
1247:                            .testFailMsg("(alterTable) Bad column value after alter.");
1248:                }
1249:                if (!cc.fetch(rowloc2, two_column_row.getRowArray(),
1250:                        (FormatableBitSet) null)) {
1251:                    throw T_Fail.testFailMsg("(alterTable) Row not there.");
1252:                }
1253:
1254:                if ((((SQLInteger) two_column_row.getCol(0)).getInt() != 2)
1255:                        || (!two_column_row.getCol(1).isNull())) {
1256:                    throw T_Fail
1257:                            .testFailMsg("(alterTable) Bad column value after alter.");
1258:                }
1259:
1260:                // make sure insert of 2 column row works.
1261:                two_column_row = new T_AccessRow(2);
1262:                two_column_row.setCol(0, new SQLInteger(3));
1263:                two_column_row.setCol(1, new SQLInteger(300));
1264:                cc.insert(two_column_row.getRowArray());
1265:
1266:                // At this point the table looks like:
1267:                // col1 col2
1268:                // ---- ----
1269:                // 1    NA
1270:                // 2    NA
1271:                // 3    300
1272:
1273:                ScanController scan = tc.openScan(
1274:                        conglomid,
1275:                        false, // don't hold
1276:                        TransactionController.OPENMODE_FORUPDATE, // for update
1277:                        TransactionController.MODE_RECORD,
1278:                        TransactionController.ISOLATION_SERIALIZABLE,
1279:                        (FormatableBitSet) null, // all columns, all as objects
1280:                        null, // start position - first row in conglomerate
1281:                        0, // unused if start position is null.
1282:                        null, // qualifier - accept all rows
1283:                        null, // stop position - last row in conglomerate
1284:                        0); // unused if stop position is null.
1285:
1286:                while (scan.next()) {
1287:                    scan.fetch(two_column_row.getRowArray());
1288:
1289:                    key_value = ((SQLInteger) two_column_row.getCol(0))
1290:                            .getInt();
1291:
1292:                    switch (key_value) {
1293:                    case 1: {
1294:                        // Set non-existent column value to 100
1295:                        if (!two_column_row.getCol(1).isNull()) {
1296:                            throw T_Fail
1297:                                    .testFailMsg("(alterTable) Bad column value after alter.");
1298:                        }
1299:
1300:                        // test that replace field works on alter added column
1301:                        // make result row be: (1, 100)
1302:
1303:                        two_column_row.setCol(1, new SQLInteger(100));
1304:
1305:                        scan.replace(two_column_row.getRowArray(),
1306:                                (FormatableBitSet) null);
1307:                        break;
1308:                    }
1309:                    case 2: {
1310:                        if (!two_column_row.getCol(1).isNull()) {
1311:                            throw T_Fail
1312:                                    .testFailMsg("(alterTable) Bad column value after alter.");
1313:                        }
1314:
1315:                        // test that replace row works on alter added column row.
1316:                        // make result row be: (2, 200)
1317:                        two_column_row.setCol(1, new SQLInteger(200));
1318:
1319:                        scan.replace(two_column_row.getRowArray(),
1320:                                (FormatableBitSet) null);
1321:
1322:                        break;
1323:                    }
1324:                    case 3: {
1325:                        break;
1326:                    }
1327:                    default: {
1328:                        throw T_Fail
1329:                                .testFailMsg("(alterTable) bad row value found in table.");
1330:                    }
1331:
1332:                    }
1333:                }
1334:
1335:                // reposition the scan
1336:                scan.reopenScan(null, // start position - first row in conglomerate
1337:                        0, // unused if start position is null.
1338:                        null, // qualifier - accept all rows
1339:                        null, // stop position - last row in conglomerate
1340:                        0); // unused if stop position is null.
1341:
1342:                while (scan.next()) {
1343:                    scan.fetch(two_column_row.getRowArray());
1344:
1345:                    key_value = ((SQLInteger) two_column_row.getCol(0))
1346:                            .getInt();
1347:
1348:                    switch (key_value) {
1349:                    case 1:
1350:                    case 2:
1351:                    case 3: {
1352:                        int second_col_val = ((SQLInteger) two_column_row
1353:                                .getCol(1)).getInt();
1354:
1355:                        if (second_col_val != (key_value * 100)) {
1356:                            throw T_Fail
1357:                                    .testFailMsg("(alterTable) Bad column value after alter."
1358:                                            + "expected: ("
1359:                                            + key_value
1360:                                            + ", "
1361:                                            + key_value
1362:                                            * 100
1363:                                            + ")\n"
1364:                                            + "got     : ("
1365:                                            + key_value
1366:                                            + ", "
1367:                                            + second_col_val + ")\n");
1368:                        }
1369:
1370:                        break;
1371:                    }
1372:                    default: {
1373:                        throw T_Fail
1374:                                .testFailMsg("(alterTable) bad row value found in table.");
1375:                    }
1376:                    }
1377:                }
1378:
1379:                scan.close();
1380:
1381:                tc.commit();
1382:
1383:                REPORT("(alterTable) completed");
1384:
1385:                return true;
1386:            }
1387:
1388:            /**
1389:             * Test the access level ScanInfo interface.
1390:             * <p>
1391:             *
1392:             * @return true if the test succeeded.
1393:             *
1394:             * @param tc The transaction controller to use in the test.
1395:             *
1396:             * @exception  StandardException  Standard exception policy.
1397:             * @exception  T_Fail Unexpected behaviour from the API
1398:             **/
1399:            protected boolean scanInfo(TransactionController tc)
1400:                    throws StandardException, T_Fail {
1401:                int key_value;
1402:
1403:                REPORT("(scanInfo) starting");
1404:
1405:                // Create a heap conglomerate.
1406:                T_AccessRow template_row = new T_AccessRow(2);
1407:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1408:                        template_row.getRowArray(), // 1 column template.
1409:                        null, // column sort order not required for heap
1410:                        null, // default properties
1411:                        TransactionController.IS_DEFAULT); // not temporary
1412:                // Open the conglomerate.
1413:                ConglomerateController cc = tc.openConglomerate(conglomid,
1414:                        false, TransactionController.OPENMODE_FORUPDATE,
1415:                        TransactionController.MODE_RECORD,
1416:                        TransactionController.ISOLATION_SERIALIZABLE);
1417:
1418:                // Create a 1 column row. int column = 1.
1419:                T_AccessRow r1 = new T_AccessRow(2);
1420:                SQLInteger c1 = new SQLInteger(1);
1421:                SQLInteger c2 = new SQLInteger(100);
1422:                r1.setCol(0, c1);
1423:                r1.setCol(1, c2);
1424:
1425:                // Get a location template
1426:                RowLocation rowloc1 = cc.newRowLocationTemplate();
1427:
1428:                // Insert the row and remember its location.
1429:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
1430:
1431:                // create another 2 column row. int column = 2.
1432:                // Get a location template
1433:                r1.setCol(0, new SQLInteger(2));
1434:                r1.setCol(1, new SQLInteger(200));
1435:                RowLocation rowloc2 = cc.newRowLocationTemplate();
1436:
1437:                // Insert the row and remember its location.
1438:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
1439:
1440:                cc.delete(rowloc2);
1441:
1442:                if (tc.isPristine() || tc.isIdle()) {
1443:                    throw T_Fail
1444:                            .testFailMsg("(scanInfo) bad xact state after update xact.");
1445:                }
1446:
1447:                tc.commit();
1448:
1449:                ScanController scan = tc.openScan(
1450:                        conglomid,
1451:                        false, // don't hold
1452:                        0, // for read
1453:                        TransactionController.MODE_TABLE,
1454:                        TransactionController.ISOLATION_SERIALIZABLE,
1455:                        (FormatableBitSet) null, // all columns, all as objects
1456:                        null, // start position - first row in conglomerate
1457:                        0, // unused if start position is null.
1458:                        null, // qualifier - accept all rows
1459:                        null, // stop position - last row in conglomerate
1460:                        0); // unused if stop position is null.
1461:
1462:                if (!scan.isTableLocked()) {
1463:                    throw T_Fail
1464:                            .testFailMsg("(scanInfo) table should be table locked.");
1465:                }
1466:
1467:                while (scan.next()) {
1468:                    scan.fetch(r1.getRowArray());
1469:                }
1470:                ScanInfo scan_info = scan.getScanInfo();
1471:                Properties prop = scan_info.getAllScanInfo(null);
1472:
1473:                if (!tc.isPristine() || tc.isIdle()) {
1474:                    throw T_Fail
1475:                            .testFailMsg("(scanInfo) bad xact state after update xact.");
1476:                }
1477:
1478:                REPORT(("return from full row scan heap.getScanInfo() = " + prop));
1479:
1480:                if (Integer.parseInt(prop.getProperty(MessageService
1481:                        .getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED))) != 1) {
1482:                    throw T_Fail
1483:                            .testFailMsg("(scanInfo) wrong numPagesVisited.  Expected 1, got "
1484:                                    + Integer
1485:                                            .parseInt(prop
1486:                                                    .getProperty(MessageService
1487:                                                            .getTextMessage(SQLState.STORE_RTS_NUM_PAGES_VISITED))));
1488:                }
1489:                if (Integer.parseInt(prop.getProperty(MessageService
1490:                        .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED))) != 2) {
1491:                    throw T_Fail
1492:                            .testFailMsg("(scanInfo) wrong numRowsVisited. Expected 2, got "
1493:                                    + Integer
1494:                                            .parseInt(prop
1495:                                                    .getProperty(MessageService
1496:                                                            .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_VISITED))));
1497:                }
1498:                if (Integer
1499:                        .parseInt(prop
1500:                                .getProperty(MessageService
1501:                                        .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))) != 1) {
1502:                    throw T_Fail
1503:                            .testFailMsg("(scanInfo) wrong numRowsQualified. Expected 1, got "
1504:                                    + Integer
1505:                                            .parseInt(prop
1506:                                                    .getProperty(MessageService
1507:                                                            .getTextMessage(SQLState.STORE_RTS_NUM_ROWS_QUALIFIED))));
1508:                }
1509:
1510:                // Try a partial Row scan
1511:
1512:                // only get the 2nd column.
1513:                FormatableBitSet validColumns = new FormatableBitSet(3);
1514:                validColumns.set(1);
1515:
1516:                scan = tc.openScan(
1517:                        conglomid,
1518:                        false, // don't hold
1519:                        TransactionController.OPENMODE_FORUPDATE, // for update
1520:                        TransactionController.MODE_RECORD,
1521:                        TransactionController.ISOLATION_SERIALIZABLE,
1522:                        validColumns, // only get the second column
1523:                        null, // start position - first row in conglomerate
1524:                        0, // unused if start position is null.
1525:                        null, // qualifier - accept all rows
1526:                        null, // stop position - last row in conglomerate
1527:                        0); // unused if stop position is null.
1528:
1529:                if (scan.isTableLocked()) {
1530:                    throw T_Fail
1531:                            .testFailMsg("(scanInfo) table should be row locked.");
1532:                }
1533:
1534:                scan_info = scan.getScanInfo();
1535:                prop = scan_info.getAllScanInfo(null);
1536:                REPORT(("return from partial scan heap.getScanInfo() = " + prop));
1537:
1538:                // RESOLVE - should test the btree one also.
1539:
1540:                REPORT("(scanInfo) finishing");
1541:
1542:                return true;
1543:            }
1544:
1545:            /**
1546:             * Test partial scans.
1547:             * <p>
1548:             *
1549:             * @return true if the test succeeded.
1550:             *
1551:             * @param tc The transaction controller to use in the test.
1552:             *
1553:             * @exception  StandardException  Standard exception policy.
1554:             * @exception  T_Fail Unexpected behaviour from the API
1555:             **/
1556:            protected boolean partialScan(TransactionController tc)
1557:                    throws StandardException, T_Fail {
1558:                int key_value;
1559:
1560:                REPORT("(partialScan) starting");
1561:
1562:                // Create a heap conglomerate.
1563:                T_AccessRow template_row = new T_AccessRow(2);
1564:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1565:                        template_row.getRowArray(), // 1 column template.
1566:                        null, // column sort order not required for heap
1567:                        null, // default properties
1568:                        TransactionController.IS_DEFAULT); // not temporary
1569:                // Open the conglomerate.
1570:                ConglomerateController cc = tc.openConglomerate(conglomid,
1571:                        false, TransactionController.OPENMODE_FORUPDATE,
1572:                        TransactionController.MODE_RECORD,
1573:                        TransactionController.ISOLATION_SERIALIZABLE);
1574:
1575:                // Create a 1 column row. int column = 1.
1576:                T_AccessRow r1 = new T_AccessRow(2);
1577:                SQLInteger c1 = new SQLInteger(1);
1578:                SQLInteger c2 = new SQLInteger(100);
1579:                r1.setCol(0, c1);
1580:                r1.setCol(1, c2);
1581:
1582:                // Get a location template
1583:                RowLocation rowloc1 = cc.newRowLocationTemplate();
1584:
1585:                // Insert the row and remember its location.
1586:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
1587:
1588:                // create another 2 column row. int column = 2.
1589:                // Get a location template
1590:                r1.setCol(0, new SQLInteger(2));
1591:                r1.setCol(1, new SQLInteger(200));
1592:                RowLocation rowloc2 = cc.newRowLocationTemplate();
1593:
1594:                // Insert the row and remember its location.
1595:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
1596:
1597:                cc.delete(rowloc2);
1598:
1599:                tc.commit();
1600:
1601:                // Try a partial Row scan with no columns.
1602:
1603:                // only get the 2nd column.
1604:                FormatableBitSet validColumns = new FormatableBitSet();
1605:
1606:                ScanController scan = tc.openScan(
1607:                        conglomid,
1608:                        false, // don't hold
1609:                        TransactionController.OPENMODE_FORUPDATE, // for update
1610:                        TransactionController.MODE_RECORD,
1611:                        TransactionController.ISOLATION_SERIALIZABLE,
1612:                        validColumns, // only get the second column
1613:                        null, // start position - first row in conglomerate
1614:                        0, // unused if start position is null.
1615:                        null, // qualifier - accept all rows
1616:                        null, // stop position - last row in conglomerate
1617:                        0); // unused if stop position is null.
1618:
1619:                // should see one row.
1620:
1621:                if (!scan.next()) {
1622:                    throw T_Fail
1623:                            .testFailMsg("(partialScan) did not see first row.");
1624:                }
1625:
1626:                if (scan.next()) {
1627:                    throw T_Fail
1628:                            .testFailMsg("(partialScan) saw more than one row.");
1629:                }
1630:
1631:                // RESOLVE - should test the btree one also.
1632:
1633:                REPORT("(partialScan) finishing");
1634:
1635:                return true;
1636:            }
1637:
1638:            // Simple insert into heap performance test
1639:            protected boolean insert_bench(TransactionController tc)
1640:                    throws StandardException, T_Fail {
1641:                ConglomerateController cc = null;
1642:                ScanController scan = null;
1643:                long conglomid = -1;
1644:                long before, after;
1645:
1646:                // Create a row.
1647:                T_AccessRow r1 = new T_AccessRow(1);
1648:                long iter = 100;
1649:
1650:                for (int numcols = 1; numcols < 101; numcols *= 10) {
1651:                    // Create a heap conglomerate.
1652:                    conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1653:                            new T_AccessRow(numcols).getRowArray(), // 1 SQLInteger() column template.
1654:                            null, // column sort order not required for heap
1655:                            null, // default properties
1656:                            TransactionController.IS_DEFAULT); // not temporary
1657:
1658:                    tc.commit();
1659:
1660:                    // Open the conglomerate.
1661:                    cc = tc.openConglomerate(conglomid, false,
1662:                            TransactionController.OPENMODE_FORUPDATE,
1663:                            TransactionController.MODE_RECORD,
1664:                            TransactionController.ISOLATION_SERIALIZABLE);
1665:
1666:                    for (int i = 0; i < numcols; i++) {
1667:                        r1.setCol(i, new SQLInteger(numcols));
1668:                    }
1669:
1670:                    // time before 
1671:                    before = System.currentTimeMillis();
1672:
1673:                    for (int i = 0; i < iter; i++) {
1674:                        if (cc.insert(r1.getRowArray()) != 0)
1675:                            throw T_Fail
1676:                                    .testFailMsg("(insert_bench) insert failed ");
1677:                    }
1678:
1679:                    // time after 
1680:                    after = System.currentTimeMillis();
1681:
1682:                    REPORT("insert " + iter + " rows of " + numcols
1683:                            + " integer cols = " + (after - before)
1684:                            + " milliseconds.\n");
1685:
1686:                    // time before 
1687:                    before = System.currentTimeMillis();
1688:
1689:                    for (int i = 0; i < iter; i++) {
1690:                        if (cc.insert(r1.getRowArray()) != 0)
1691:                            throw T_Fail
1692:                                    .testFailMsg("(insert_bench) insert failed ");
1693:                    }
1694:
1695:                    // time after 
1696:                    after = System.currentTimeMillis();
1697:
1698:                    REPORT("second insert " + iter + " rows of " + numcols
1699:                            + " integer cols = " + (after - before)
1700:                            + " milliseconds.\n");
1701:
1702:                    // Open a scan on the conglomerate.
1703:                    before = System.currentTimeMillis();
1704:
1705:                    scan = tc.openScan(
1706:                            conglomid,
1707:                            false, // don't hold
1708:                            0, // not for update
1709:                            TransactionController.MODE_RECORD,
1710:                            TransactionController.ISOLATION_SERIALIZABLE,
1711:                            (FormatableBitSet) null, // all columns, all as objects
1712:                            null, // start position - first row in conglomerate
1713:                            0, // unused if start position is null.
1714:                            null, // qualifier - accept all rows
1715:                            null, // stop position - last row in conglomerate
1716:                            0); // unused if stop position is null.
1717:
1718:                    // time before 
1719:                    before = System.currentTimeMillis();
1720:
1721:                    // Iterate through and check that the rows are still there.
1722:                    while (scan.next()) {
1723:                        scan.fetch(r1.getRowArray());
1724:                    }
1725:
1726:                    // time after 
1727:                    after = System.currentTimeMillis();
1728:
1729:                    REPORT("scan " + (2 * iter) + " rows of " + numcols
1730:                            + " integer cols = " + (after - before)
1731:                            + " milliseconds.\n");
1732:
1733:                    // Close the conglomerate.
1734:                    cc.close();
1735:                    tc.commit();
1736:                }
1737:
1738:                return (true);
1739:            }
1740:
1741:            /**
1742:             * Test the access level SortCost interface.
1743:             * <p>
1744:             *
1745:             * @return true if the test succeeded.
1746:             *
1747:             * @param tc The transaction controller to use in the test.
1748:             *
1749:             * @exception  StandardException  Standard exception policy.
1750:             * @exception  T_Fail Unexpected behaviour from the API
1751:             **/
1752:            protected boolean sortCost(TransactionController tc)
1753:                    throws StandardException, T_Fail {
1754:                int key_value;
1755:
1756:                REPORT("(sortCost) starting");
1757:
1758:                // Create a heap conglomerate.
1759:                T_AccessRow template_row = new T_AccessRow(2);
1760:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1761:                        template_row.getRowArray(), // 1 column template.
1762:                        null, // column sort order not required for heap
1763:                        null, // default properties
1764:                        TransactionController.IS_DEFAULT); // not temporary
1765:                // Open the conglomerate.
1766:                ConglomerateController cc = tc.openConglomerate(conglomid,
1767:                        false, TransactionController.OPENMODE_FORUPDATE,
1768:                        TransactionController.MODE_RECORD,
1769:                        TransactionController.ISOLATION_SERIALIZABLE);
1770:
1771:                // Create a 2 column row.
1772:                T_AccessRow r1 = new T_AccessRow(2);
1773:                SQLInteger c1 = new SQLInteger(1);
1774:                SQLInteger c2 = new SQLInteger(100);
1775:                r1.setCol(0, c1);
1776:                r1.setCol(1, c2);
1777:
1778:                // Get a location template
1779:                RowLocation rowloc1 = cc.newRowLocationTemplate();
1780:
1781:                // Insert the row and remember its location.
1782:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
1783:
1784:                cc.close();
1785:
1786:                tc.commit();
1787:
1788:                // flush the cache to get the row count updated.
1789:                flush_cache();
1790:
1791:                // Test 1 - Just call for various types of sorts.  Not sure how 
1792:                // to test the validity.
1793:                SortCostController scc = tc.openSortCostController(null);
1794:
1795:                double estimated_cost = scc.getSortCost(template_row
1796:                        .getRowArray(), null, false, 10000, 100, 100);
1797:
1798:                if (estimated_cost <= 0) {
1799:                    throw T_Fail
1800:                            .testFailMsg("(storeCost) estimated sort cost :"
1801:                                    + estimated_cost);
1802:                }
1803:
1804:                REPORT("(sortCost) finishing");
1805:
1806:                return true;
1807:            }
1808:
1809:            /**
1810:             * Test the access level StoreCost interface.
1811:             * <p>
1812:             *
1813:             * @return true if the test succeeded.
1814:             *
1815:             * @param tc The transaction controller to use in the test.
1816:             *
1817:             * @exception  StandardException  Standard exception policy.
1818:             * @exception  T_Fail Unexpected behaviour from the API
1819:             **/
1820:            protected boolean storeCost(TransactionController tc)
1821:                    throws StandardException, T_Fail {
1822:                int key_value;
1823:
1824:                REPORT("(storeCost) starting");
1825:
1826:                // Create a heap conglomerate.
1827:                T_AccessRow template_row = new T_AccessRow(2);
1828:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
1829:                        template_row.getRowArray(), // 1 column template.
1830:                        null, // column sort order not required for heap
1831:                        null, // default properties
1832:                        TransactionController.IS_DEFAULT); // not temporary
1833:                // Open the conglomerate.
1834:                ConglomerateController cc = tc.openConglomerate(conglomid,
1835:                        false, TransactionController.OPENMODE_FORUPDATE,
1836:                        TransactionController.MODE_RECORD,
1837:                        TransactionController.ISOLATION_SERIALIZABLE);
1838:
1839:                // Create a 2 column row.
1840:                T_AccessRow r1 = new T_AccessRow(2);
1841:                SQLInteger c1 = new SQLInteger(1);
1842:                SQLInteger c2 = new SQLInteger(100);
1843:                r1.setCol(0, c1);
1844:                r1.setCol(1, c2);
1845:
1846:                // Get a location template
1847:                RowLocation rowloc1 = cc.newRowLocationTemplate();
1848:
1849:                // Insert the row and remember its location.
1850:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
1851:
1852:                cc.close();
1853:
1854:                tc.commit();
1855:
1856:                // flush the cache to get the row count updated.
1857:                flush_cache();
1858:
1859:                // Test 1 - ASSERT(initial row count after 1 insert should be 1)
1860:                StoreCostController scc = tc.openStoreCost(conglomid);
1861:
1862:                if (scc.getEstimatedRowCount() != 1) {
1863:                    throw T_Fail
1864:                            .testFailMsg("(storeCost) estimated row count not 1:"
1865:                                    + scc.getEstimatedRowCount());
1866:                }
1867:
1868:                // Test 2 - ASSERT(should be able to set arbitrary row count)
1869:
1870:                scc.setEstimatedRowCount(5);
1871:
1872:                if (scc.getEstimatedRowCount() != 5) {
1873:                    throw T_Fail
1874:                            .testFailMsg("(storeCost) estimated row count not 5");
1875:                }
1876:
1877:                scc.setEstimatedRowCount(1);
1878:
1879:                // Test 3 - ASSERT(should implement getFetchFromRowLocationCost()) 
1880:                //     should figure out some way to determine reasonable number is
1881:                //     returned.
1882:                double fetch_cost = scc.getFetchFromRowLocationCost(
1883:                        (FormatableBitSet) null, 0);
1884:                fetch_cost = scc.getFetchFromRowLocationCost(
1885:                        (FormatableBitSet) new FormatableBitSet(0), 0);
1886:                REPORT("fetch cost (full row) of row loc = " + fetch_cost);
1887:                fetch_cost = scc.getFetchFromRowLocationCost(
1888:                        (FormatableBitSet) new FormatableBitSet(1), 0);
1889:                FormatableBitSet bit_set = new FormatableBitSet(2);
1890:                REPORT("fetch cost (no cols) of row loc = " + fetch_cost);
1891:                bit_set.set(1);
1892:                fetch_cost = scc.getFetchFromRowLocationCost(
1893:                        (FormatableBitSet) new FormatableBitSet(1), 0);
1894:                REPORT("fetch cost (1 col) of row loc = " + fetch_cost);
1895:
1896:                // Test 4 - ASSERT(should implement getFetchFromFullKeyCost()) 
1897:                //     should figure out some way to determine reasonable number is
1898:                //     returned.
1899:                /* - RESOLVE HEAP does not implement this.
1900:                fetch_cost = 
1901:                    scc.getFetchFromFullKeyCost((FormatableBitSet) null, (int[]) null, 0);
1902:                REPORT("fetch full key cost (full row) of row loc = " + fetch_cost);
1903:
1904:                fetch_cost = 
1905:                    scc.getFetchFromFullKeyCost(
1906:                        (FormatableBitSet) new FormatableBitSet(0), (int[]) null, 0);
1907:                REPORT("fetch full key cost (no cols) of row loc = " + fetch_cost);
1908:
1909:                fetch_cost = 
1910:                    scc.getFetchFromFullKeyCost(
1911:                        (FormatableBitSet) new FormatableBitSet(1), (int[]) null, 0);
1912:                REPORT("fetch full key cost (no cols) of row loc = " + fetch_cost);
1913:
1914:                bit_set = new FormatableBitSet(2);
1915:                bit_set.set(1);
1916:                fetch_cost = 
1917:                    scc.getFetchFromFullKeyCost(
1918:                        (FormatableBitSet) new FormatableBitSet(1), (int[]) null, 0);
1919:                REPORT("fetch full key cost (1 col) of row loc = " + fetch_cost);
1920:                 */
1921:
1922:                // Test 5 - ASSERT(should implement getScanCost()) 
1923:                //     should figure out some way to determine reasonable number is
1924:                //     returned.
1925:                StoreCostResult cost_result = new T_StoreCostResult();
1926:
1927:                scc.getScanCost(StoreCostController.STORECOST_SCAN_NORMAL, -1, // row count
1928:                        1, // number of rows fetched at a time from access.
1929:                        false, // forUpdate
1930:                        (FormatableBitSet) null, // validColumns
1931:                        new T_AccessRow(2).getRowArray(), // template
1932:                        null, // start position - first row in conglomerate
1933:                        0, // unused if start position is null.
1934:                        null, // stop position - last row in conglomerate
1935:                        0, // unused if stop position is null.
1936:                        false, // reopen_scan?
1937:                        0, // access_type
1938:                        cost_result); // cost result.
1939:
1940:                REPORT("fetch scan cost (full row) of row loc = " + cost_result);
1941:
1942:                scc.getScanCost(StoreCostController.STORECOST_SCAN_NORMAL, -1, // row count
1943:                        1, // number of rows fetched at a time from access.
1944:                        false, // forUpdate
1945:                        new FormatableBitSet(0), // validColumns
1946:                        new T_AccessRow(2).getRowArray(), // template
1947:                        null, // start position - first row in conglomerate
1948:                        0, // unused if start position is null.
1949:                        null, // stop position - last row in conglomerate
1950:                        0, // unused if stop position is null.
1951:                        false, // reopen_scan?
1952:                        0, // access_type
1953:                        cost_result); // cost result.
1954:
1955:                REPORT("fetch scan cost (no cols) of row loc = " + cost_result);
1956:
1957:                scc.getScanCost(StoreCostController.STORECOST_SCAN_NORMAL, -1, // row count
1958:                        1, // number of rows fetched at a time from access.
1959:                        false, // forUpdate
1960:                        new FormatableBitSet(1), // validColumns
1961:                        new T_AccessRow(2).getRowArray(), // template
1962:                        null, // start position - first row in conglomerate
1963:                        0, // unused if start position is null.
1964:                        null, // stop position - last row in conglomerate
1965:                        0, // unused if stop position is null.
1966:                        false, // reopen_scan?
1967:                        0, // access_type
1968:                        cost_result); // cost result.
1969:
1970:                REPORT("fetch scan cost (no cols) of row loc = " + cost_result);
1971:
1972:                bit_set = new FormatableBitSet(2);
1973:                bit_set.set(1);
1974:                scc.getScanCost(StoreCostController.STORECOST_SCAN_NORMAL, -1, // row count
1975:                        1, // number of rows fetched at a time from access.
1976:                        false, // forUpdate
1977:                        bit_set, // validColumns
1978:                        new T_AccessRow(2).getRowArray(), // template
1979:                        null, // start position - first row in conglomerate
1980:                        0, // unused if start position is null.
1981:                        null, // stop position - last row in conglomerate
1982:                        0, // unused if stop position is null.
1983:                        false, // reopen_scan?
1984:                        0, // access_type
1985:                        cost_result); // cost result.
1986:
1987:                REPORT("fetch scan cost (1 cols) of row loc = " + cost_result);
1988:
1989:                // make sure you can get a row location.
1990:                rowloc1 = scc.newRowLocationTemplate();
1991:
1992:                REPORT("(storeCost) finishing");
1993:
1994:                return true;
1995:            }
1996:
1997:            /**
1998:            	Test transactional properties
1999:
2000:            	@exception StandardException test failure
2001:            	@exception T_Fail test failure
2002:             */
2003:            protected boolean transactionalProperties(TransactionController tc)
2004:                    throws StandardException, T_Fail {
2005:                REPORT("start transactionalProperties");
2006:
2007:                // put a couple of properties in with different values and types
2008:
2009:                tc.setProperty("T_Key_Frog", new SQLLongint(479), false);
2010:                tc.setProperty("T_Key_Tiger", "Roar, ROAR", false);
2011:
2012:                long lvalue = ((SQLLongint) (tc.getProperty("T_Key_Frog")))
2013:                        .getLong();
2014:                if (lvalue != 479)
2015:                    throw T_Fail
2016:                            .testFailMsg("setProperty() - expected 479 - got "
2017:                                    + lvalue);
2018:
2019:                String svalue = (String) tc.getProperty("T_Key_Tiger");
2020:                if (!svalue.equals("Roar, ROAR"))
2021:                    throw T_Fail
2022:                            .testFailMsg("setProperty() - expected 'Roar, ROAR' - got "
2023:                                    + svalue);
2024:
2025:                tc.commit();
2026:
2027:                // should still be accessable after the commit
2028:                lvalue = ((SQLLongint) (tc.getProperty("T_Key_Frog")))
2029:                        .getLong();
2030:                if (lvalue != 479)
2031:                    throw T_Fail
2032:                            .testFailMsg("setProperty() - expected 479 - got "
2033:                                    + lvalue);
2034:
2035:                svalue = (String) tc.getProperty("T_Key_Tiger");
2036:                if (!svalue.equals("Roar, ROAR"))
2037:                    throw T_Fail
2038:                            .testFailMsg("setProperty() - expected 'Roar, ROAR' - got "
2039:                                    + svalue);
2040:
2041:                tc.commit();
2042:
2043:                // see if update works
2044:                tc.setProperty("T_Key_Tiger", "mieow, mieow", false);
2045:                svalue = (String) tc.getProperty("T_Key_Tiger");
2046:                if (!svalue.equals("mieow, mieow"))
2047:                    throw T_Fail
2048:                            .testFailMsg("setProperty() - expected 'mieow, mieow' - got "
2049:                                    + svalue);
2050:
2051:                tc.commit();
2052:                svalue = (String) tc.getProperty("T_Key_Tiger");
2053:                if (!svalue.equals("mieow, mieow"))
2054:                    throw T_Fail
2055:                            .testFailMsg("setProperty() - expected 'mieow, mieow' - got "
2056:                                    + svalue);
2057:
2058:                // see if an update to a different type works
2059:                tc.setProperty("T_Key_Tiger", new SQLLongint(570), false);
2060:                lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger")))
2061:                        .getLong();
2062:
2063:                if (lvalue != 570)
2064:                    throw T_Fail
2065:                            .testFailMsg("setProperty() - expected 570 - got "
2066:                                    + lvalue);
2067:
2068:                tc.commit();
2069:
2070:                lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger")))
2071:                        .getLong();
2072:                if (lvalue != 570)
2073:                    throw T_Fail
2074:                            .testFailMsg("setProperty() - expected 570 - got "
2075:                                    + lvalue);
2076:
2077:                tc.commit();
2078:
2079:                // delete a key
2080:                tc.setProperty("T_Key_Frog", (Serializable) null, false);
2081:                if (tc.getProperty("T_Key_Frog") != null)
2082:                    throw T_Fail.testFailMsg("setProperty() - delete failed");
2083:                tc.commit();
2084:
2085:                if (tc.getProperty("T_Key_Frog") != null)
2086:                    throw T_Fail.testFailMsg("setProperty() - delete failed");
2087:
2088:                tc.commit();
2089:
2090:                // now see if rollback works.
2091:                tc.setProperty("T_Key_Tiger", new SQLLongint(457), false);
2092:
2093:                tc.abort();
2094:                lvalue = ((SQLLongint) (tc.getProperty("T_Key_Tiger")))
2095:                        .getLong();
2096:                if (lvalue != 570)
2097:                    throw T_Fail
2098:                            .testFailMsg("setProperty() - expected 570 - got "
2099:                                    + lvalue);
2100:
2101:                tc.commit();
2102:                PASS("transactionalProperties");
2103:
2104:                return true;
2105:            }
2106:
2107:            // Test temporary conglomerates.
2108:            protected boolean tempTest(TransactionController tc)
2109:                    throws StandardException, T_Fail {
2110:                REPORT("(tempTest) starting");
2111:
2112:                // Create some conglomerates, some temporary, some not.
2113:                long cid5252t = createAConglom(tc, 5252, true); // temporary
2114:                long cid87t = createAConglom(tc, 87, true); // temporary
2115:                long cid999p = createAConglom(tc, 999, false); // permanent
2116:                long cid3t = createAConglom(tc, 3, true); // temporary
2117:
2118:                // Create an index on two of them
2119:                long cid5252ti = createBtree(tc, cid5252t, true);
2120:                long cid999pi = createBtree(tc, cid999p, false);
2121:
2122:                int r;
2123:
2124:                // Make sure we can read them.
2125:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2126:                        cid5252t, 5252)) != 1) {
2127:                    throw T_Fail
2128:                            .testFailMsg("(tempTest) after create checkAConglom(cid5252t) == "
2129:                                    + r);
2130:                }
2131:                if ((r = checkAConglom(tc, getBtreeTemplate(tc, cid5252t),
2132:                        cid5252ti, 5252)) != 1) {
2133:                    throw T_Fail
2134:                            .testFailMsg("(tempTest) after create checkAConglom(cid5252ti) == "
2135:                                    + r);
2136:                }
2137:
2138:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2139:                        cid999p, 999)) != 1) {
2140:                    throw T_Fail
2141:                            .testFailMsg("(tempTest) after create checkAConglom(cid999p) == "
2142:                                    + r);
2143:                }
2144:
2145:                if ((r = checkAConglom(tc, getBtreeTemplate(tc, cid999p),
2146:                        cid999pi, 999)) != 1) {
2147:                    throw T_Fail
2148:                            .testFailMsg("(tempTest) after create checkAConglom(cid999pi) == "
2149:                                    + r);
2150:                }
2151:
2152:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t,
2153:                        3)) != 1) {
2154:                    throw T_Fail
2155:                            .testFailMsg("(tempTest) after create checkAConglom(cid3t) == "
2156:                                    + r);
2157:                }
2158:
2159:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2160:                        cid87t, 87)) != 1) {
2161:                    throw T_Fail
2162:                            .testFailMsg("(tempTest) after create checkAConglom(cid87t) == "
2163:                                    + r);
2164:                }
2165:
2166:                // Drop two of them.
2167:                tc.dropConglomerate(cid999pi);
2168:                tc.dropConglomerate(cid999p);
2169:                tc.dropConglomerate(cid87t);
2170:
2171:                // Try dropping the ones we already dropped - expect exceptions
2172:                try {
2173:                    tc.dropConglomerate(cid999p);
2174:                    throw T_Fail
2175:                            .testFailMsg("(tempTest) drop of dropped cid999p succeeded");
2176:                } catch (StandardException e) {
2177:                    // normal path through the test, ignore the expected error
2178:                }
2179:                try {
2180:                    tc.dropConglomerate(cid999pi);
2181:                    throw T_Fail
2182:                            .testFailMsg("(tempTest) drop of dropped cid999pi succeeded");
2183:                } catch (StandardException e) {
2184:                    // normal path through the test, ignore the expected error
2185:                }
2186:                try {
2187:                    tc.dropConglomerate(cid87t);
2188:                    throw T_Fail
2189:                            .testFailMsg("(tempTest) drop of dropped cid87t succeeded");
2190:                } catch (StandardException e) {
2191:                    // normal path through the test, ignore the expected error
2192:                }
2193:
2194:                // Make sure the correct ones remain
2195:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2196:                        cid5252t, 5252)) != 1) {
2197:                    throw T_Fail
2198:                            .testFailMsg("(tempTest) after drop checkAConglom(cid5252t) == "
2199:                                    + r);
2200:                }
2201:
2202:                if ((r = checkAConglom(tc, getBtreeTemplate(tc, cid5252t),
2203:                        cid5252ti, 5252)) != 1) {
2204:                    throw T_Fail
2205:                            .testFailMsg("(tempTest) after drop checkAConglom(cid5252ti) == "
2206:                                    + r);
2207:                }
2208:
2209:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t,
2210:                        3)) != 1) {
2211:                    throw T_Fail
2212:                            .testFailMsg("(tempTest) after drop checkAConglom(cid3t) == "
2213:                                    + r);
2214:                }
2215:
2216:                // Make sure commitNoSync gets executed sometimes.
2217:                tc.commitNoSync(TransactionController.RELEASE_LOCKS);
2218:
2219:                // After committing the transaction, the congloms
2220:                // should still be there (with their rows).
2221:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2222:                        cid5252t, 5252)) != 1) {
2223:                    throw T_Fail
2224:                            .testFailMsg("(tempTest) after commit checkAConglom(cid5252t) == "
2225:                                    + r);
2226:                }
2227:
2228:                if ((r = checkAConglom(tc, getBtreeTemplate(tc, cid5252t),
2229:                        cid5252ti, 5252)) != 1) {
2230:                    throw T_Fail
2231:                            .testFailMsg("(tempTest) after commit checkAConglom(cid5252ti) == "
2232:                                    + r);
2233:                }
2234:
2235:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t,
2236:                        3)) != 1) {
2237:                    throw T_Fail
2238:                            .testFailMsg("(tempTest) after commit checkAConglom(cid3t) == "
2239:                                    + r);
2240:                }
2241:
2242:                // open cid3t for update to force its truncation on the abort.
2243:                ScanController sc = tc.openScan(
2244:                        cid3t,
2245:                        false, // don't hold
2246:                        TransactionController.OPENMODE_FORUPDATE, // for update
2247:                        TransactionController.MODE_RECORD,
2248:                        TransactionController.ISOLATION_SERIALIZABLE,
2249:                        (FormatableBitSet) null, // all columns, all as objects
2250:                        null, // start position - first row in conglomerate
2251:                        0, // unused if start position is null.
2252:                        null, // qualifier - accept all rows
2253:                        null, // stop position - last row in conglomerate
2254:                        0); // unused if stop position is null.
2255:
2256:                sc.close();
2257:
2258:                tc.abort();
2259:
2260:                // After an abort, the congloms that were opened for update should be there,
2261:                // but truncated
2262:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null,
2263:                        cid5252t, 5252)) != 1) {
2264:                    throw T_Fail
2265:                            .testFailMsg("(tempTest) after abort checkAConglom(cid5252t) == "
2266:                                    + r);
2267:                }
2268:
2269:                // RESOLVE(mikem): track 1825
2270:                // don't want to open temp cantainer with IS_KEPT always.
2271:                // if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t, 3)) != 0) {
2272:                //	throw T_Fail.testFailMsg("(tempTest) after abort checkAConglom(cid3t) == " + r);
2273:                // }
2274:
2275:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid3t,
2276:                        3)) != 1) {
2277:                    throw T_Fail
2278:                            .testFailMsg("(tempTest) after abort checkAConglom(cid3t) == "
2279:                                    + r);
2280:                }
2281:
2282:                // Due to bug STO84, temp btrees are corrupted after aborts,
2283:                // so the following will cause problems:
2284:                /*
2285:                if ((r = checkAConglom(tc, (DataValueDescriptor[]) null, cid5252ti, 5252)) != 0)
2286:                 	throw T_Fail.testFailMsg("(tempTest) after abort checkAConglom(cid5252ti) == " + r);
2287:                 */
2288:
2289:                // Drop index on conglomerate to make sure we can do a drop after truncate.
2290:                tc.dropConglomerate(cid5252ti);
2291:                if (tc.conglomerateExists(cid5252ti))
2292:                    throw T_Fail
2293:                            .testFailMsg("(tempTest) after drop cid5252ti still exists");
2294:
2295:                // Drop one conglomerate to make sure we can do a drop after truncate.
2296:                tc.dropConglomerate(cid5252t);
2297:                if (tc.conglomerateExists(cid5252t))
2298:                    throw T_Fail
2299:                            .testFailMsg("(tempTest) after drop cid5252t still exists");
2300:
2301:                // Leave the last one -  raw store is supposed to delete
2302:                // it when the system reboots
2303:
2304:                // Success!
2305:                REPORT("(tempTest) succeeded");
2306:                return true;
2307:            }
2308:
2309:            private long createAConglom(TransactionController tc,
2310:                    int testValue, boolean temporary) throws StandardException {
2311:                // Create a heap conglomerate.
2312:                long cid = tc.createConglomerate("heap", // create a heap conglomerate
2313:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
2314:                        null, // column sort order not required for heap
2315:                        null, // default properties
2316:                        temporary ? TransactionController.IS_TEMPORARY
2317:                                : TransactionController.IS_DEFAULT);
2318:
2319:                ConglomerateController cc = tc.openConglomerate(cid, false,
2320:                        TransactionController.OPENMODE_FORUPDATE,
2321:                        TransactionController.MODE_RECORD,
2322:                        TransactionController.ISOLATION_SERIALIZABLE);
2323:
2324:                // Create a row.
2325:                T_AccessRow row = new T_AccessRow(1);
2326:                SQLLongint col = new SQLLongint(testValue);
2327:                row.setCol(0, col);
2328:
2329:                // Stuff in the test value so we can recognize this conglom later.
2330:                cc.insert(row.getRowArray());
2331:
2332:                cc.close();
2333:
2334:                return cid;
2335:            }
2336:
2337:            private DataValueDescriptor[] getBtreeTemplate(
2338:                    TransactionController tc, long baseConglomId)
2339:                    throws StandardException {
2340:                // Open a scan on the base conglomerate which will return all rows.
2341:                FormatableBitSet singleColumn = new FormatableBitSet(1);
2342:                singleColumn.set(0);
2343:                ScanController sc = tc.openScan(baseConglomId,
2344:                        false,
2345:                        0, // not for update
2346:                        TransactionController.MODE_RECORD,
2347:                        TransactionController.ISOLATION_SERIALIZABLE,
2348:                        singleColumn, // all columns, all as objects
2349:                        null, 0, null, null, 0);
2350:
2351:                // Create the template for the index. This method "knows" that
2352:                // all rows in the base table have one IntCol
2353:                T_AccessRow template = new T_AccessRow(2);
2354:                SQLLongint col0 = new SQLLongint(0);
2355:                RowLocation col1 = sc.newRowLocationTemplate();
2356:                template.setCol(0, col0);
2357:                template.setCol(1, col1);
2358:
2359:                sc.close();
2360:
2361:                return (template.getRowArray());
2362:            }
2363:
2364:            private long createBtree(TransactionController tc,
2365:                    long baseConglomId, boolean temporary)
2366:                    throws StandardException {
2367:                // Create the properties for the index.
2368:                // This method knows that there is just one column in the base table
2369:                Properties indexProps = new Properties();
2370:                indexProps.put("baseConglomerateId", Long
2371:                        .toString(baseConglomId));
2372:                indexProps.put("nUniqueColumns", "1");
2373:                indexProps.put("rowLocationColumn", "1");
2374:                indexProps.put("nKeyFields", "2");
2375:
2376:                // Open a scan on the base conglomerate which will return all rows.
2377:                FormatableBitSet singleColumn = new FormatableBitSet(1);
2378:                singleColumn.set(0);
2379:                ScanController sc = tc.openScan(baseConglomId,
2380:                        false,
2381:                        0, // not for update
2382:                        TransactionController.MODE_RECORD,
2383:                        TransactionController.ISOLATION_SERIALIZABLE,
2384:                        singleColumn, // just the first column.
2385:                        null, 0, null, null, 0);
2386:
2387:                // Create the template for the index. This method "knows" that
2388:                // all rows in the base table have one IntCol
2389:                T_AccessRow template = new T_AccessRow(2);
2390:                SQLLongint col0 = new SQLLongint(0);
2391:                RowLocation col1 = sc.newRowLocationTemplate();
2392:                template.setCol(0, col0);
2393:                template.setCol(1, col1);
2394:
2395:                DataValueDescriptor[] baseRow = new DataValueDescriptor[1];
2396:                baseRow[0] = col0;
2397:
2398:                // Create a btree secondary index conglomerate.
2399:                long iid = tc.createConglomerate("BTREE", template
2400:                        .getRowArray(), null, indexProps,
2401:                        temporary ? TransactionController.IS_TEMPORARY
2402:                                : TransactionController.IS_DEFAULT);
2403:
2404:                // Open the index so we can stuff in index rows.
2405:                ConglomerateController cc = tc.openConglomerate(iid, false,
2406:                        TransactionController.OPENMODE_FORUPDATE,
2407:                        TransactionController.MODE_RECORD,
2408:                        TransactionController.ISOLATION_SERIALIZABLE);
2409:
2410:                // build the index.
2411:                while (sc.next()) {
2412:                    sc.fetch(baseRow);
2413:                    sc.fetchLocation(col1);
2414:                    cc.insert(template.getRowArray());
2415:                }
2416:
2417:                cc.close();
2418:
2419:                return iid;
2420:            }
2421:
2422:            /**
2423:            Open a scan on the conglomerate for the given conglom id, and verify
2424:            that it has rows with the given test value.  This is a way of
2425:            verifying that we got the right conglomerate.  Returns the number of
2426:            rows that it checked (-1 if the conglomerate doesn't exist).
2427:             **/
2428:            private int checkAConglom(TransactionController tc,
2429:                    DataValueDescriptor[] scratch_template, long conglomId,
2430:                    int testValue) throws StandardException {
2431:                if (!tc.conglomerateExists(conglomId))
2432:                    return -1;
2433:
2434:                ScanController sc = tc.openScan(
2435:                        conglomId,
2436:                        false, // don't hold
2437:                        0, // not for update
2438:                        TransactionController.MODE_RECORD,
2439:                        TransactionController.ISOLATION_SERIALIZABLE,
2440:                        (FormatableBitSet) null, // all columns, all as objects
2441:                        null, // start position - first row in conglomerate
2442:                        0, // unused if start position is null.
2443:                        null, // qualifier - accept all rows
2444:                        null, // stop position - last row in conglomerate
2445:                        0); // unused if stop position is null.
2446:
2447:                // An empty row
2448:                T_AccessRow row = new T_AccessRow(1);
2449:                SQLLongint col = new SQLLongint(0);
2450:                row.setCol(0, col);
2451:
2452:                // Iterate through and check that the rows are still there.
2453:                // Note this part of the test will inten
2454:                int nrows = 0;
2455:                while (sc.next()) {
2456:                    sc.fetch(row.getRowArray());
2457:                    if (((SQLLongint) row.getCol(0)).getLong() != testValue)
2458:                        return -2;
2459:                    nrows++;
2460:                }
2461:
2462:                sc.close();
2463:
2464:                return nrows;
2465:            }
2466:
2467:            protected boolean updatelocks(TransactionController tc)
2468:                    throws StandardException, T_Fail {
2469:                REPORT("(updatelocks starting.)");
2470:
2471:                updatelocks_0(tc, TransactionController.ISOLATION_SERIALIZABLE);
2472:                updatelocks_0(tc,
2473:                        TransactionController.ISOLATION_READ_COMMITTED);
2474:
2475:                REPORT("(updatelocks ending.)");
2476:
2477:                return (true);
2478:            }
2479:
2480:            protected boolean updatelocks_0(TransactionController tc,
2481:                    int isolation_level) throws StandardException, T_Fail {
2482:                // Create a 2 column row.
2483:                T_AccessRow r1 = new T_AccessRow(2);
2484:                SQLInteger c1 = new SQLInteger(1);
2485:                SQLInteger c2 = new SQLInteger(100);
2486:                r1.setCol(0, c1);
2487:                r1.setCol(1, c2);
2488:
2489:                // Create a heap conglomerate.
2490:                long orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2491:                        r1.getRowArray(), null, // column sort order not required for heap
2492:                        null, // default properties
2493:                        TransactionController.IS_DEFAULT); // not temporary
2494:
2495:                // add rows 1 and 2
2496:                ConglomerateController cc = tc.openConglomerate(orig_conglomid,
2497:                        false, TransactionController.OPENMODE_FORUPDATE,
2498:                        TransactionController.MODE_RECORD,
2499:                        TransactionController.ISOLATION_SERIALIZABLE);
2500:
2501:                // insert (1, 100)
2502:                r1.setCol(0, new SQLInteger(1));
2503:                r1.setCol(1, new SQLInteger(100));
2504:                cc.insert(r1.getRowArray());
2505:
2506:                // insert (2, 200)
2507:                r1.setCol(0, new SQLInteger(2));
2508:                r1.setCol(1, new SQLInteger(200));
2509:                cc.insert(r1.getRowArray());
2510:
2511:                // insert (3, 300)
2512:                r1.setCol(0, new SQLInteger(3));
2513:                r1.setCol(1, new SQLInteger(300));
2514:                cc.insert(r1.getRowArray());
2515:
2516:                cc.close();
2517:
2518:                tc.commit();
2519:
2520:                REPORT("(updatelocks ending.)");
2521:
2522:                ScanController sc = tc
2523:                        .openScan(
2524:                                orig_conglomid,
2525:                                false, // don't hold
2526:                                (TransactionController.OPENMODE_FORUPDATE | TransactionController.OPENMODE_USE_UPDATE_LOCKS),
2527:                                TransactionController.MODE_RECORD,
2528:                                TransactionController.ISOLATION_SERIALIZABLE,
2529:                                (FormatableBitSet) null, // all columns, all as objects
2530:                                null, // start position - first row in conglomerate
2531:                                0, // unused if start position is null.
2532:                                null, // qualifier - accept all rows
2533:                                null, // stop position - last row in conglomerate
2534:                                0); // unused if stop position is null.
2535:
2536:                int key_value;
2537:
2538:                boolean found_row_2 = false;
2539:
2540:                while (sc.next()) {
2541:                    sc.fetch(r1.getRowArray());
2542:
2543:                    key_value = ((SQLInteger) r1.getCol(0)).getInt();
2544:
2545:                    switch (key_value) {
2546:                    case 1: {
2547:                        // delete first row
2548:                        sc.delete();
2549:                        break;
2550:                    }
2551:
2552:                    case 2: {
2553:                        // leave second alone - no update, lock will get coverted 
2554:                        // down.
2555:                        found_row_2 = true;
2556:                        break;
2557:                    }
2558:
2559:                    case 3: {
2560:                        // update the third row.
2561:                        T_AccessRow update_row = new T_AccessRow(2);
2562:                        r1.setCol(0, new SQLInteger(30));
2563:                        r1.setCol(1, new SQLInteger(3000));
2564:                        sc.replace(r1.getRowArray(), null);
2565:                        break;
2566:                    }
2567:
2568:                    default: {
2569:                        throw T_Fail
2570:                                .testFailMsg("(updatelock) bad row value found in table.");
2571:                    }
2572:                    }
2573:
2574:                }
2575:
2576:                if (!found_row_2)
2577:                    throw T_Fail
2578:                            .testFailMsg("(updatelock) did not find row in first scan.");
2579:
2580:                // reposition the scan
2581:                sc.reopenScan(null, // start position - first row in conglomerate
2582:                        0, // unused if start position is null.
2583:                        null, // qualifier - accept all rows
2584:                        null, // stop position - last row in conglomerate
2585:                        0); // unused if stop position is null.
2586:
2587:                found_row_2 = false;
2588:
2589:                while (sc.next()) {
2590:                    sc.fetch(r1.getRowArray());
2591:
2592:                    key_value = ((SQLInteger) r1.getCol(0)).getInt();
2593:
2594:                    switch (key_value) {
2595:                    case 2: {
2596:                        // leave second alone - no update, lock will get coverted 
2597:                        // down.
2598:                        found_row_2 = true;
2599:
2600:                        break;
2601:                    }
2602:
2603:                    case 30: {
2604:                        // update the third row.
2605:                        T_AccessRow update_row = new T_AccessRow(2);
2606:                        r1.setCol(0, new SQLInteger(40));
2607:                        r1.setCol(1, new SQLInteger(4000));
2608:                        sc.replace(r1.getRowArray(), null);
2609:                        break;
2610:                    }
2611:
2612:                    default: {
2613:                        throw T_Fail
2614:                                .testFailMsg("(updatelock) bad row value found in table.");
2615:                    }
2616:                    }
2617:
2618:                }
2619:
2620:                if (!found_row_2)
2621:                    throw T_Fail
2622:                            .testFailMsg("(updatelock) did not find row in second scan.");
2623:
2624:                sc.close();
2625:
2626:                tc.commit();
2627:
2628:                // try the scan after the first xact has completed.
2629:
2630:                sc = tc
2631:                        .openScan(
2632:                                orig_conglomid,
2633:                                false, // don't hold
2634:                                (TransactionController.OPENMODE_FORUPDATE | TransactionController.OPENMODE_USE_UPDATE_LOCKS),
2635:                                TransactionController.MODE_RECORD,
2636:                                TransactionController.ISOLATION_SERIALIZABLE,
2637:                                (FormatableBitSet) null, // all columns, all as objects
2638:                                null, // start position - first row in conglomerate
2639:                                0, // unused if start position is null.
2640:                                null, // qualifier - accept all rows
2641:                                null, // stop position - last row in conglomerate
2642:                                0); // unused if stop position is null.
2643:
2644:                found_row_2 = false;
2645:
2646:                while (sc.next()) {
2647:                    sc.fetch(r1.getRowArray());
2648:
2649:                    key_value = ((SQLInteger) r1.getCol(0)).getInt();
2650:
2651:                    switch (key_value) {
2652:                    case 2: {
2653:                        // leave second alone - no update, lock will get coverted 
2654:                        // down.
2655:                        found_row_2 = true;
2656:                        break;
2657:                    }
2658:
2659:                    case 40: {
2660:                        // update the third row.
2661:                        T_AccessRow update_row = new T_AccessRow(2);
2662:                        r1.setCol(0, new SQLInteger(30));
2663:                        r1.setCol(1, new SQLInteger(3000));
2664:                        sc.replace(r1.getRowArray(), null);
2665:                        break;
2666:                    }
2667:
2668:                    default: {
2669:                        throw T_Fail
2670:                                .testFailMsg("(updatelock) bad row value found in table.");
2671:                    }
2672:                    }
2673:
2674:                }
2675:
2676:                if (!found_row_2)
2677:                    throw T_Fail
2678:                            .testFailMsg("(updatelock) did not find row in first scan.");
2679:
2680:                return (true);
2681:            }
2682:
2683:            protected boolean nestedUserTransaction(TransactionController tc)
2684:                    throws StandardException, T_Fail {
2685:
2686:                REPORT("(nestedUserTransaction) starting");
2687:
2688:                // Test of drop conglomerate with abort by doing the following:
2689:                //     create table
2690:                //     commit
2691:                //     drop table
2692:                //     make sure table is not still there.
2693:                //     abort
2694:                //     make sure table is still there.
2695:
2696:                // Create a heap conglomerate.
2697:                long orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2698:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
2699:                        null, // column sort order not required for heap
2700:                        null, // default properties
2701:                        TransactionController.IS_DEFAULT); // not temporary
2702:
2703:                // Create a temporary heap conglomerate.
2704:                long tmp_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2705:                        new T_AccessRow(1).getRowArray(), // 1 SQLInteger() column template.
2706:                        null, // column sort order not required for heap
2707:                        null, // default properties
2708:                        TransactionController.IS_TEMPORARY);
2709:
2710:                TransactionController current_xact = store
2711:                        .getTransaction(ContextService.getFactory()
2712:                                .getCurrentContextManager());
2713:
2714:                // get a nested user transaction
2715:                TransactionController child_tc = tc
2716:                        .startNestedUserTransaction(true);
2717:
2718:                TransactionController current_xact_after_nest = store
2719:                        .getTransaction(ContextService.getFactory()
2720:                                .getCurrentContextManager());
2721:
2722:                if (current_xact_after_nest != current_xact) {
2723:                    throw T_Fail
2724:                            .testFailMsg("(nestedUserTransaction) getTransaction() return changed after startNestedUserTransaction()."
2725:                                    + "current_xact = "
2726:                                    + current_xact
2727:                                    + ";current_xact_after_nest = "
2728:                                    + current_xact_after_nest);
2729:                }
2730:
2731:                if ((tc.getLockObject() != child_tc.getLockObject())
2732:                        || !(tc.getLockObject()
2733:                                .equals(child_tc.getLockObject())))
2734:
2735:                {
2736:                    throw T_Fail
2737:                            .testFailMsg("(nestedUserTransaction) getLockObject should return same object from botht these calls.");
2738:                }
2739:
2740:                // the locks of the nested transaction should not conflict, so this
2741:                // open should work.
2742:                ConglomerateController cc = child_tc.openConglomerate(
2743:                        orig_conglomid, false,
2744:                        TransactionController.OPENMODE_FORUPDATE,
2745:                        TransactionController.MODE_RECORD,
2746:                        TransactionController.ISOLATION_SERIALIZABLE);
2747:
2748:                // Make sure you can access the temporary conglomerate in the 
2749:                // nested transaction.
2750:                ConglomerateController tmp_cc = child_tc.openConglomerate(
2751:                        tmp_conglomid, false,
2752:                        TransactionController.OPENMODE_FORUPDATE,
2753:                        TransactionController.MODE_RECORD,
2754:                        TransactionController.ISOLATION_SERIALIZABLE);
2755:
2756:                cc.close();
2757:                tmp_cc.close();
2758:
2759:                child_tc.commit();
2760:                child_tc.destroy();
2761:
2762:                tc.dropConglomerate(orig_conglomid);
2763:
2764:                // trying to double nest a nested transaction should not work.
2765:                child_tc = tc.startNestedUserTransaction(true);
2766:
2767:                try {
2768:                    child_tc.startNestedUserTransaction(true);
2769:
2770:                    throw T_Fail
2771:                            .testFailMsg("(nestedUserTransaction) double nest xact not allowed.");
2772:                } catch (StandardException se) {
2773:                    // expected exception, fall through.
2774:                }
2775:
2776:                child_tc.commit();
2777:                child_tc.destroy();
2778:
2779:                // make sure internal and ntt's work.  Just add a bunch of data to
2780:                // the table causing page allocation.
2781:                String twok_string = new String("0123456789012345");
2782:
2783:                for (int i = 0; i < 7; i++) {
2784:                    twok_string += twok_string;
2785:                }
2786:
2787:                T_AccessRow big_row = new T_AccessRow(2);
2788:
2789:                big_row.setCol(1, new SQLChar(twok_string));
2790:
2791:                // Create a heap conglomerate.
2792:                orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2793:                        big_row.getRowArray(), null, // column sort order not required for heap
2794:                        null, // default properties
2795:                        TransactionController.IS_DEFAULT); // not temporary
2796:
2797:                child_tc = tc.startNestedUserTransaction(true);
2798:
2799:                // add 20 pages worth of data, causing allocation
2800:
2801:                // the locks of the nested transaction should not conflict, so this
2802:                // open should work.
2803:                cc = child_tc.openConglomerate(orig_conglomid, false,
2804:                        TransactionController.OPENMODE_FORUPDATE,
2805:                        TransactionController.MODE_RECORD,
2806:                        TransactionController.ISOLATION_SERIALIZABLE);
2807:
2808:                child_tc.abort();
2809:                child_tc.destroy();
2810:
2811:                // after the abort the table should not still exist, the parent 
2812:                // xact should have been aborted.
2813:
2814:                try {
2815:                    // the locks of the nested transaction should not conflict, so this
2816:                    // open should work.
2817:                    cc = tc.openConglomerate(orig_conglomid, false,
2818:                            TransactionController.OPENMODE_FORUPDATE,
2819:                            TransactionController.MODE_RECORD,
2820:                            TransactionController.ISOLATION_SERIALIZABLE);
2821:
2822:                    throw T_Fail
2823:                            .testFailMsg("(nestedUserTransaction) conglom should have been aborted.");
2824:                } catch (StandardException se) {
2825:                    // expected exception, fall through.
2826:                }
2827:
2828:                tc.commit();
2829:
2830:                // same test as above, but this time commit parent xact create to
2831:                // make sure it stays around after the child abort.
2832:
2833:                // Create a heap conglomerate.
2834:                orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2835:                        big_row.getRowArray(), null, // column sort order not required for heap
2836:                        null, // default properties
2837:                        TransactionController.IS_DEFAULT); // not temporary
2838:
2839:                tc.commit();
2840:
2841:                child_tc = tc.startNestedUserTransaction(true);
2842:
2843:                // add 20 pages worth of data, causing allocation
2844:
2845:                // the locks of the nested transaction should not conflict, so this
2846:                // open should work.
2847:                cc = child_tc.openConglomerate(orig_conglomid, false,
2848:                        TransactionController.OPENMODE_FORUPDATE,
2849:                        TransactionController.MODE_RECORD,
2850:                        TransactionController.ISOLATION_SERIALIZABLE);
2851:
2852:                /*
2853:                for (int i = 0; i < 40; i++)
2854:                {
2855:                    big_row.setCol(0, new SQLInteger(i));
2856:                	cc.insert(big_row.getRowArray());
2857:                }
2858:                 */
2859:
2860:                child_tc.abort();
2861:                child_tc.destroy();
2862:
2863:                // after the abort the table should not still exist, the parent 
2864:                // xact should have been aborted.
2865:
2866:                try {
2867:                    // the locks of the nested transaction should not conflict, so this
2868:                    // open should work.
2869:                    cc = tc.openConglomerate(orig_conglomid, false,
2870:                            TransactionController.OPENMODE_FORUPDATE,
2871:                            TransactionController.MODE_RECORD,
2872:                            TransactionController.ISOLATION_SERIALIZABLE);
2873:
2874:                    cc.close();
2875:                } catch (StandardException se) {
2876:                    // expected exception, fall through.
2877:
2878:                    throw T_Fail
2879:                            .testFailMsg("(nestedUserTransaction) conglom should have not be aborted.");
2880:                }
2881:
2882:                // start an read only nested user transaction.
2883:                child_tc = tc.startNestedUserTransaction(true);
2884:
2885:                ConglomerateController child_cc = child_tc.openConglomerate(
2886:                        orig_conglomid, false,
2887:                        TransactionController.OPENMODE_FORUPDATE,
2888:                        TransactionController.MODE_RECORD,
2889:                        TransactionController.ISOLATION_SERIALIZABLE);
2890:
2891:                try {
2892:                    // should not be able to do an update in a read only transaction.
2893:                    big_row.setCol(0, new SQLInteger(1042));
2894:                    child_cc.insert(big_row.getRowArray());
2895:
2896:                    throw T_Fail
2897:                            .testFailMsg("(nestedUserTransaction) read only xact does not allow upd.");
2898:
2899:                } catch (StandardException se) {
2900:                    // expected exception, fall through.
2901:                    child_tc.commit();
2902:                    child_tc.destroy();
2903:                }
2904:
2905:                tc.commit();
2906:
2907:                // start an update nested user transaction.
2908:                child_tc = tc.startNestedUserTransaction(false);
2909:
2910:                child_cc = child_tc.openConglomerate(orig_conglomid, false,
2911:                        TransactionController.OPENMODE_FORUPDATE,
2912:                        TransactionController.MODE_RECORD,
2913:                        TransactionController.ISOLATION_SERIALIZABLE);
2914:
2915:                try {
2916:                    // should be able to do an update in a read only transaction.
2917:                    big_row.setCol(0, new SQLInteger(1043));
2918:                    child_cc.insert(big_row.getRowArray());
2919:
2920:                } catch (StandardException se) {
2921:                    throw T_Fail
2922:                            .testFailMsg("(nestedUserTransaction) read only xact does not allow upd.");
2923:                }
2924:
2925:                // expected exception, fall through.
2926:                child_tc.commit();
2927:                child_tc.destroy();
2928:
2929:                tc.commit();
2930:
2931:                cc = tc.openConglomerate(orig_conglomid, false,
2932:                        TransactionController.OPENMODE_FORUPDATE,
2933:                        TransactionController.MODE_TABLE,
2934:                        TransactionController.ISOLATION_SERIALIZABLE);
2935:
2936:                // start an update nested user transaction.
2937:                child_tc = tc.startNestedUserTransaction(false);
2938:
2939:                try {
2940:                    // the following should time out, since locks are not compatible.
2941:                    child_cc = child_tc.openConglomerate(orig_conglomid, false,
2942:                            TransactionController.OPENMODE_FORUPDATE,
2943:                            TransactionController.MODE_RECORD,
2944:                            TransactionController.ISOLATION_SERIALIZABLE);
2945:
2946:                    throw T_Fail
2947:                            .testFailMsg("(nestedUserTransaction) lock should have timed out.");
2948:                } catch (StandardException se) {
2949:                    // expected timeout, fall through.
2950:                }
2951:
2952:                // expected exception, fall through.
2953:                child_tc.commit();
2954:                child_tc.destroy();
2955:
2956:                tc.commit();
2957:
2958:                REPORT("(nestedUserTransaction) finishing");
2959:
2960:                return true;
2961:            }
2962:
2963:            // test various flavors of commit
2964:            protected boolean commitTest(TransactionController tc)
2965:                    throws StandardException, T_Fail {
2966:                REPORT("(commitTest)");
2967:
2968:                // Create a heap conglomerate.
2969:                T_AccessRow template_row = new T_AccessRow(1);
2970:                long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
2971:                        template_row.getRowArray(), // 1 column template.
2972:                        null, // column sort order not required for heap
2973:                        null, // default properties
2974:                        TransactionController.IS_DEFAULT); // not temporary
2975:
2976:                tc.commit();
2977:
2978:                // Open it.
2979:                ConglomerateController cc = tc.openConglomerate(conglomid,
2980:                        false, TransactionController.OPENMODE_FORUPDATE,
2981:                        TransactionController.MODE_RECORD,
2982:                        TransactionController.ISOLATION_SERIALIZABLE);
2983:
2984:                // Create a row.
2985:                T_AccessRow r1 = new T_AccessRow(1);
2986:                SQLInteger c1 = new SQLInteger(0);
2987:                r1.setCol(0, c1);
2988:
2989:                // Get a location template
2990:                RowLocation rowloc = cc.newRowLocationTemplate();
2991:
2992:                // Insert the row and remember its location.
2993:                cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
2994:
2995:                // now commit nosync without releasing the row lock
2996:                tc.commitNoSync(TransactionController.KEEP_LOCKS);
2997:
2998:                // cc should be closed
2999:                try {
3000:                    cc.newRowLocationTemplate();
3001:                    throw T_Fail
3002:                            .testFailMsg("conglomerate controller is not closed after commit");
3003:                } catch (StandardException se) {
3004:                    // expect fail
3005:                }
3006:
3007:                // get another transaction going
3008:                ContextManager cm2 = ContextService.getFactory()
3009:                        .newContextManager();
3010:
3011:                ContextService.getFactory().setCurrentContextManager(cm2);
3012:
3013:                TransactionController tc2 = null;
3014:                ConglomerateController cc2 = null;
3015:                try {
3016:
3017:                    tc2 = store.getTransaction(cm2);
3018:
3019:                    cc2 = tc2.openConglomerate(conglomid, false,
3020:                            TransactionController.OPENMODE_FORUPDATE,
3021:                            TransactionController.MODE_RECORD,
3022:                            TransactionController.ISOLATION_SERIALIZABLE);
3023:
3024:                    // try to lock the row, it should fail
3025:                    // Mikem RESOLVE: this does not get a row lock
3026:                    // cc2.fetch(rowloc, r1.getRowArray(), (FormatableBitSet)null)
3027:
3028:                    cc2.delete(rowloc);
3029:                    throw T_Fail
3030:                            .testFailMsg("expected time out did not happen");
3031:                } catch (StandardException lfe) {
3032:                    if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT))
3033:                        throw lfe;
3034:                } finally {
3035:                    ContextService.getFactory().resetCurrentContextManager(cm2);
3036:                }
3037:
3038:                // see whether anyone is blocked at all
3039:                if (tc.anyoneBlocked()) {
3040:                    throw T_Fail
3041:                            .testFailMsg("No transactions should be blocked");
3042:                }
3043:
3044:                // now really commit the transaction
3045:                tc.commit();
3046:
3047:                ContextService.getFactory().setCurrentContextManager(cm2);
3048:
3049:                try {
3050:                    cc2
3051:                            .fetch(rowloc, r1.getRowArray(),
3052:                                    (FormatableBitSet) null);
3053:                    // get rid of the other transaction 
3054:                    tc2.commitNoSync(TransactionController.RELEASE_LOCKS);
3055:                    tc2.destroy();
3056:                } finally {
3057:                    ContextService.getFactory().resetCurrentContextManager(cm2);
3058:                }
3059:
3060:                REPORT("(commitTest) succeeded");
3061:                return true;
3062:            }
3063:
3064:            private void testOpsBeforeFirstNext(ScanController scan,
3065:                    DataValueDescriptor[] row) throws StandardException, T_Fail {
3066:
3067:                // none of the following operations is allowed before a next() or
3068:                // fetchNext() is called.
3069:                //
3070:                try {
3071:                    scan.delete();
3072:                    throw T_Fail
3073:                            .testFailMsg("(holdCursor) delete() does not work until next() is called.");
3074:                } catch (StandardException lfe) {
3075:                    // expect error
3076:                }
3077:                try {
3078:                    scan.doesCurrentPositionQualify();
3079:                    throw T_Fail
3080:                            .testFailMsg("(holdCursor) doesCurrentPositionQualify() does not work until next() is called.");
3081:                } catch (StandardException lfe) {
3082:                    // expect error
3083:                }
3084:
3085:                try {
3086:                    scan.fetch(row);
3087:                    throw T_Fail
3088:                            .testFailMsg("(holdCursor) fetch() does not work until next() is called.");
3089:                } catch (StandardException lfe) {
3090:                    // expect error
3091:                }
3092:                try {
3093:                    scan.fetchLocation(null);
3094:                    throw T_Fail
3095:                            .testFailMsg("(holdCursor) fetchLocation() does not work until next() is called.");
3096:                } catch (StandardException lfe) {
3097:                    // expect error
3098:                }
3099:                try {
3100:                    scan.isCurrentPositionDeleted();
3101:                    throw T_Fail
3102:                            .testFailMsg("(holdCursor) isCurrentPositionDeleted() does not work until next() is called.");
3103:                } catch (StandardException lfe) {
3104:                    // expect error
3105:                }
3106:                try {
3107:                    scan.replace(row, null);
3108:                    throw T_Fail
3109:                            .testFailMsg("(holdCursor) isCurrentPositionDeleted() does not work until next() is called.");
3110:                } catch (StandardException lfe) {
3111:                    // expect error
3112:                }
3113:            }
3114:
3115:            // test various flavors of commit
3116:            protected boolean holdCursor(TransactionController tc)
3117:                    throws StandardException, T_Fail {
3118:                REPORT("(holdCursor)");
3119:
3120:                // Create a conglomerates and an index on that conglomerate.
3121:                long base_id = createAConglom(tc, 0, false);
3122:
3123:                // Open it.
3124:                ConglomerateController cc = tc.openConglomerate(base_id, false,
3125:                        TransactionController.OPENMODE_FORUPDATE,
3126:                        TransactionController.MODE_RECORD,
3127:                        TransactionController.ISOLATION_SERIALIZABLE);
3128:
3129:                // insert 5 rows
3130:
3131:                T_AccessRow r1 = null;
3132:                SQLLongint c1 = null;
3133:
3134:                for (int i = 1; i < 5; i++) {
3135:                    // Create a row.
3136:                    r1 = new T_AccessRow(1);
3137:                    c1 = new SQLLongint(i);
3138:                    r1.setCol(0, c1);
3139:
3140:                    // Get a location template
3141:                    RowLocation rowloc = cc.newRowLocationTemplate();
3142:
3143:                    // Insert the row and remember its location.
3144:                    cc.insertAndFetchLocation(r1.getRowArray(), rowloc);
3145:                }
3146:
3147:                // Create an index on the base table.
3148:                long index_id = createBtree(tc, base_id, false);
3149:
3150:                tc.commit();
3151:
3152:                cc.close();
3153:
3154:                tc.commit();
3155:
3156:                // HEAP - test that scan is closed on commit of non-held cursor.
3157:
3158:                // Open scan on the base table.
3159:                ScanController base_scan = tc.openScan(
3160:                        base_id,
3161:                        false, // don't hold
3162:                        TransactionController.OPENMODE_FORUPDATE, // for update
3163:                        TransactionController.MODE_RECORD,
3164:                        TransactionController.ISOLATION_SERIALIZABLE,
3165:                        (FormatableBitSet) null, // all columns, all as objects
3166:                        null, // start position - first row in conglomerate
3167:                        0, // unused if start position is null.
3168:                        null, // qualifier - accept all rows
3169:                        null, // stop position - last row in conglomerate
3170:                        0); // unused if stop position is null.
3171:
3172:                // Open scan on the index table.
3173:                ScanController index_scan = tc.openScan(
3174:                        index_id,
3175:                        false, // don't hold
3176:                        TransactionController.OPENMODE_FORUPDATE, // for update
3177:                        TransactionController.MODE_RECORD,
3178:                        TransactionController.ISOLATION_SERIALIZABLE,
3179:                        (FormatableBitSet) null, // all columns, all as objects
3180:                        null, // start position - first row in conglomerate
3181:                        0, // unused if start position is null.
3182:                        null, // qualifier - accept all rows
3183:                        null, // stop position - last row in conglomerate
3184:                        0); // unused if stop position is null.
3185:
3186:                testOpsBeforeFirstNext(base_scan, r1.getRowArray());
3187:                testOpsBeforeFirstNext(index_scan, r1.getRowArray());
3188:
3189:                base_scan.next();
3190:                index_scan.next();
3191:
3192:                base_scan.next();
3193:                index_scan.next();
3194:
3195:                base_scan.next();
3196:                index_scan.next();
3197:
3198:                base_scan.next();
3199:                index_scan.next();
3200:
3201:                base_scan.next();
3202:                index_scan.next();
3203:
3204:                base_scan.next();
3205:                index_scan.next();
3206:
3207:                base_scan.next();
3208:                index_scan.next();
3209:
3210:                // should be able call get and set even after next'ing through the rows.
3211:                long row_count = base_scan.getEstimatedRowCount();
3212:                base_scan.setEstimatedRowCount(10);
3213:                row_count = base_scan.getEstimatedRowCount();
3214:
3215:                // should be able call get and set even after next'ing through the rows.
3216:                row_count = index_scan.getEstimatedRowCount();
3217:                index_scan.setEstimatedRowCount(10);
3218:                row_count = index_scan.getEstimatedRowCount();
3219:
3220:                if (row_count != 10)
3221:                    throw T_Fail
3222:                            .testFailMsg("(holdCursor) some problem with get/set row count.");
3223:
3224:                tc.commit();
3225:
3226:                testOpsBeforeFirstNext(base_scan, r1.getRowArray());
3227:                testOpsBeforeFirstNext(index_scan, r1.getRowArray());
3228:
3229:                // see if commit closed the base_scan.
3230:                if (base_scan.next())
3231:                    throw T_Fail
3232:                            .testFailMsg("(holdCursor) next() should return false, commit should close base_scan.");
3233:
3234:                // see if commit closed the base_scan.
3235:                if (index_scan.next())
3236:                    throw T_Fail
3237:                            .testFailMsg("(holdCursor) next() should return false, commit should close base_scan.");
3238:
3239:                tc.commit();
3240:
3241:                // Open another scan on the conglomerate.
3242:                base_scan = tc.openScan(
3243:                        base_id,
3244:                        true, // hold cursor open across commit
3245:                        TransactionController.OPENMODE_FORUPDATE, // for update
3246:                        TransactionController.MODE_RECORD,
3247:                        TransactionController.ISOLATION_SERIALIZABLE,
3248:                        (FormatableBitSet) null, // all columns, all as objects
3249:                        null, // start position - first row in conglomerate
3250:                        0, // unused if start position is null.
3251:                        null, // qualifier - accept all rows
3252:                        null, // stop position - last row in conglomerate
3253:                        0); // unused if stop position is null.
3254:
3255:                // Open scan on the index table.
3256:                index_scan = tc.openScan(
3257:                        index_id,
3258:                        true, // don't hold
3259:                        TransactionController.OPENMODE_FORUPDATE, // for update
3260:                        TransactionController.MODE_RECORD,
3261:                        TransactionController.ISOLATION_SERIALIZABLE,
3262:                        (FormatableBitSet) null, // all columns, all as objects
3263:                        null, // start position - first row in conglomerate
3264:                        0, // unused if start position is null.
3265:                        null, // qualifier - accept all rows
3266:                        null, // stop position - last row in conglomerate
3267:                        0); // unused if stop position is null.
3268:
3269:                tc.commit();
3270:
3271:                testOpsBeforeFirstNext(base_scan, r1.getRowArray());
3272:                testOpsBeforeFirstNext(index_scan, r1.getRowArray());
3273:
3274:                // try to move scan after commit to 1st row.
3275:                // move cursor to be positioned on 0
3276:                if (!base_scan.next())
3277:                    throw T_Fail
3278:                            .testFailMsg("(holdCursor) next() should not fail, commit should close hold scan.");
3279:                // try to move scan after commit to 1st row.
3280:                // move cursor to be positioned on 0
3281:                if (!index_scan.next())
3282:                    throw T_Fail
3283:                            .testFailMsg("(holdCursor) next() should not fail, commit should close hold scan.");
3284:
3285:                // the 1st next should return the 1st row - ie. 0
3286:
3287:                base_scan.fetch(r1.getRowArray());
3288:                long key_value = ((SQLLongint) r1.getCol(0)).getLong();
3289:
3290:                if (key_value != 0)
3291:                    throw T_Fail.testFailMsg("(holdCursor) 1st row is not 0.");
3292:
3293:                index_scan.fetch(r1.getRowArray());
3294:                key_value = ((SQLLongint) r1.getCol(0)).getLong();
3295:
3296:                if (key_value != 0)
3297:                    throw T_Fail.testFailMsg("(holdCursor) 1st row is not 0.");
3298:
3299:                // move cursor to be positioned on 1
3300:                base_scan.next();
3301:                index_scan.next();
3302:
3303:                tc.commit();
3304:
3305:                testOpsBeforeFirstNext(base_scan, r1.getRowArray());
3306:                testOpsBeforeFirstNext(index_scan, r1.getRowArray());
3307:
3308:                // should be able call get and set even after next'ing through the rows.
3309:                row_count = base_scan.getEstimatedRowCount();
3310:                base_scan.setEstimatedRowCount(5);
3311:                row_count = base_scan.getEstimatedRowCount();
3312:
3313:                // should be able call get and set even after next'ing through the rows.
3314:                row_count = index_scan.getEstimatedRowCount();
3315:                index_scan.setEstimatedRowCount(5);
3316:                row_count = index_scan.getEstimatedRowCount();
3317:
3318:                if (row_count != 5)
3319:                    throw T_Fail
3320:                            .testFailMsg("(holdCursor) some problem with get/set row count.");
3321:
3322:                // try to move to row with key "2"
3323:
3324:                // move cursor to be positioned on 2
3325:                if (!base_scan.next())
3326:                    throw T_Fail
3327:                            .testFailMsg("(holdCursor) next() should not fail, commit should close hold base_scan.");
3328:
3329:                if (!index_scan.next())
3330:                    throw T_Fail
3331:                            .testFailMsg("(holdCursor) next() should not fail, commit should close hold base_scan.");
3332:
3333:                // the 1st next should return the 1st row - ie. 0
3334:                base_scan.fetch(r1.getRowArray());
3335:                key_value = ((SQLLongint) r1.getCol(0)).getLong();
3336:
3337:                if (key_value != 2)
3338:                    throw T_Fail.testFailMsg("(holdCursor) 1st row is not 0.");
3339:
3340:                index_scan.fetch(r1.getRowArray());
3341:                key_value = ((SQLLongint) r1.getCol(0)).getLong();
3342:
3343:                if (key_value != 2)
3344:                    throw T_Fail.testFailMsg("(holdCursor) 1st row is not 0.");
3345:
3346:                // move cursor to be positioned on 3
3347:                base_scan.next();
3348:                base_scan.delete();
3349:
3350:                index_scan.next();
3351:                index_scan.delete();
3352:
3353:                // move cursor to be positioned on 4
3354:                base_scan.next();
3355:                index_scan.next();
3356:
3357:                // move cursor past the end, thus closing it.
3358:                base_scan.next();
3359:                index_scan.next();
3360:
3361:                tc.commit();
3362:
3363:                // should be able call get and set even after next'ing through the rows.
3364:                row_count = base_scan.getEstimatedRowCount();
3365:                base_scan.setEstimatedRowCount(15);
3366:                row_count = base_scan.getEstimatedRowCount();
3367:
3368:                if (row_count != 15)
3369:                    throw T_Fail
3370:                            .testFailMsg("(holdCursor) some problem with get/set row count.");
3371:
3372:                row_count = index_scan.getEstimatedRowCount();
3373:                index_scan.setEstimatedRowCount(15);
3374:                row_count = index_scan.getEstimatedRowCount();
3375:
3376:                if (row_count != 15)
3377:                    throw T_Fail
3378:                            .testFailMsg("(holdCursor) some problem with get/set row count.");
3379:
3380:                testOpsBeforeFirstNext(base_scan, r1.getRowArray());
3381:                testOpsBeforeFirstNext(index_scan, r1.getRowArray());
3382:
3383:                // see what happens committing a closed base_scan and trying next.
3384:
3385:                if (base_scan.next())
3386:                    throw T_Fail
3387:                            .testFailMsg("(holdCursor) next() should fail, the base_scan has been closed by progressing to end.");
3388:                if (index_scan.next())
3389:                    throw T_Fail
3390:                            .testFailMsg("(holdCursor) next() should fail, the base_scan has been closed by progressing to end.");
3391:
3392:                tc.commit();
3393:
3394:                base_scan.close();
3395:                index_scan.close();
3396:
3397:                REPORT("(holdCursor) succeeded");
3398:                return true;
3399:            }
3400:
3401:            // test position at row location, in terms of holdability
3402:            protected boolean positionAtRowLocation(TransactionController tc)
3403:                    throws StandardException, T_Fail {
3404:                REPORT("(positionAtRowLocation)");
3405:
3406:                // Create a conglomerate with one row:
3407:                long base_id = createAConglom(tc, 0, false);
3408:
3409:                // Open it.
3410:                ConglomerateController cc = tc.openConglomerate(base_id, false,
3411:                        TransactionController.OPENMODE_FORUPDATE,
3412:                        TransactionController.MODE_RECORD,
3413:                        TransactionController.ISOLATION_SERIALIZABLE);
3414:
3415:                T_AccessRow accessRow = null;
3416:                for (int i = 1; i < 5; i++) {
3417:                    // Create a row.
3418:                    accessRow = new T_AccessRow(1);
3419:                    SQLLongint c1 = new SQLLongint(i);
3420:                    accessRow.setCol(0, c1);
3421:
3422:                    // Insert the row and remember its location.
3423:                    cc.insert(accessRow.getRowArray());
3424:                }
3425:                tc.commit();
3426:                cc.close();
3427:
3428:                // Open scan on the table:
3429:                ScanController base_scan = tc.openScan(
3430:                        base_id,
3431:                        true, // do hold
3432:                        TransactionController.OPENMODE_FORUPDATE, // for update
3433:                        TransactionController.MODE_RECORD,
3434:                        TransactionController.ISOLATION_SERIALIZABLE,
3435:                        (FormatableBitSet) null, // all columns, all as objects
3436:                        null, // start position - first row in conglomerate
3437:                        0, // unused if start position is null.
3438:                        null, // qualifier - accept all rows
3439:                        null, // stop position - last row in conglomerate
3440:                        0); // unused if stop position is null.
3441:
3442:                // Move to the first row
3443:                base_scan.next();
3444:
3445:                // Get the RowLocation for the first row:
3446:                RowLocation firstRow = base_scan.newRowLocationTemplate();
3447:                base_scan.fetchLocation(firstRow);
3448:                base_scan.fetch(accessRow.getRowArray());
3449:                long key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3450:                if (key_value != 0) {
3451:                    throw T_Fail
3452:                            .testFailMsg("(positionAtRowLocation_err_1) 1st row is not 0 it is:"
3453:                                    + key_value);
3454:                }
3455:
3456:                // Move to some other rows:
3457:                base_scan.next();
3458:                base_scan.fetch(accessRow.getRowArray());
3459:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3460:                if (key_value != 1) {
3461:                    throw T_Fail
3462:                            .testFailMsg("(positionAtRowLocation_err_2) 2nd row is not 1 it is:"
3463:                                    + key_value);
3464:                }
3465:
3466:                base_scan.next();
3467:                base_scan.fetch(accessRow.getRowArray());
3468:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3469:                if (key_value != 2) {
3470:                    throw T_Fail
3471:                            .testFailMsg("(positionAtRowLocation_err_3) 3d row is not 2 it is:"
3472:                                    + key_value);
3473:                }
3474:
3475:                if (!base_scan.positionAtRowLocation(firstRow)) {
3476:                    throw T_Fail
3477:                            .testFailMsg("(positionAtRowLocation_err_4) Failed to position at RowLocation");
3478:                }
3479:                base_scan.fetch(accessRow.getRowArray());
3480:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3481:                if (key_value != 0) {
3482:                    throw T_Fail
3483:                            .testFailMsg("(positionAtRowLocation_err_5) 1st row is not 0 it is:"
3484:                                    + key_value);
3485:                }
3486:
3487:                // Commit and check holdability:
3488:                tc.commit();
3489:                base_scan.next();
3490:                base_scan.fetch(accessRow.getRowArray());
3491:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3492:                if (key_value != 1) {
3493:                    throw T_Fail
3494:                            .testFailMsg("(positionAtRowLocation_err_6) 2nd row is not 1 it is:"
3495:                                    + key_value);
3496:                }
3497:
3498:                base_scan.next();
3499:                base_scan.fetch(accessRow.getRowArray());
3500:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3501:                if (key_value != 2) {
3502:                    throw T_Fail
3503:                            .testFailMsg("(positionAtRowLocation_err_7) 3d row is not 2 it is:"
3504:                                    + key_value);
3505:                }
3506:
3507:                if (!base_scan.positionAtRowLocation(firstRow)) {
3508:                    throw T_Fail
3509:                            .testFailMsg("(positionAtRowLocation_err_8) Failed to position at "
3510:                                    + "RowLocation after commit");
3511:                }
3512:                base_scan.fetch(accessRow.getRowArray());
3513:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3514:                if (key_value != 0) {
3515:                    throw T_Fail
3516:                            .testFailMsg("(positionAtRowLocation_err_9) 1st row is not 0 it is:"
3517:                                    + key_value);
3518:                }
3519:
3520:                base_scan.next();
3521:                base_scan.fetch(accessRow.getRowArray());
3522:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3523:                if (key_value != 1) {
3524:                    throw T_Fail
3525:                            .testFailMsg("(positionAtRowLocation_err_10) 2nd row is not 1 it is:"
3526:                                    + key_value);
3527:                }
3528:
3529:                base_scan.next();
3530:                base_scan.fetch(accessRow.getRowArray());
3531:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3532:                if (key_value != 2) {
3533:                    throw T_Fail
3534:                            .testFailMsg("(positionAtRowLocation_err_10) 3d row is not 2 it is:"
3535:                                    + key_value);
3536:                }
3537:
3538:                // Using reopenScanByRowLocation(..) 
3539:                // instead of positionAtRowLocation(..):
3540:                base_scan.reopenScanByRowLocation(firstRow, null);
3541:                base_scan.next();
3542:                base_scan.fetch(accessRow.getRowArray());
3543:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3544:                if (key_value != 0) {
3545:                    throw T_Fail
3546:                            .testFailMsg("(positionAtRowLocation_err_11) 1st row is not 0 it is:"
3547:                                    + key_value);
3548:                }
3549:
3550:                tc.commit();
3551:
3552:                // Compress the conglomerate
3553:                tc.compressConglomerate(base_id);
3554:                tc.commit();
3555:
3556:                base_scan.next();
3557:                base_scan.fetch(accessRow.getRowArray());
3558:                key_value = ((SQLLongint) accessRow.getCol(0)).getLong();
3559:                if (key_value != 1) {
3560:                    throw T_Fail
3561:                            .testFailMsg("(positionAtRowLocation_err_12) 2nd row is not 1 it is:"
3562:                                    + key_value);
3563:                }
3564:
3565:                // Position at RowLocation should now fail. We cannot guarantee
3566:                // that they are holdable
3567:                if (base_scan.positionAtRowLocation(firstRow)) {
3568:                    throw T_Fail
3569:                            .testFailMsg("(positionAtRowLocation_err_12) Unexpectedly succeeded at "
3570:                                    + "positioning at RowLocation after compress");
3571:                }
3572:
3573:                base_scan.close();
3574:
3575:                REPORT("(positionAtRowLocation) succeeded");
3576:                return true;
3577:            }
3578:
3579:            /**
3580:             * Test critical cases for read uncommitted.
3581:             * <p>
3582:             * test 1 - test heap fetch, delete and replace of row on page which does not exist.  
3583:             * test 2 - test heap fetch, delete and replace of row on page where row does not exist.
3584:             *
3585:             * @exception  StandardException  Standard exception policy.
3586:             **/
3587:            protected boolean readUncommitted(TransactionController tc)
3588:                    throws StandardException, T_Fail {
3589:                REPORT("(readUncommitted)");
3590:
3591:                /*
3592:                 * TEST 1 - test heap fetch of row on page which does not exist.
3593:                 * <p>
3594:                 * Do this by inserting a few pages worth of data and then deleting 
3595:                 * all the rows, while remembering the rowlocation of one of the pages.
3596:                 * You need to at least get to the 2nd page, because the 1st page is
3597:                 * never totally reclaimed and deleted by the system in a heap (it has
3598:                 * some internal catalog information stored internally in row "0").
3599:                 */
3600:
3601:                String twok_string = new String("0123456789012345");
3602:
3603:                for (int i = 0; i < 7; i++) {
3604:                    twok_string += twok_string;
3605:                }
3606:
3607:                T_AccessRow big_row = new T_AccessRow(2);
3608:
3609:                big_row.setCol(1, new SQLChar(twok_string));
3610:
3611:                // Create a heap conglomerate.
3612:                long orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
3613:                        big_row.getRowArray(), null, // column sort order not required for heap
3614:                        null, // default properties
3615:                        TransactionController.IS_DEFAULT); // not temporary
3616:
3617:                ConglomerateController cc = tc.openConglomerate(orig_conglomid,
3618:                        false, TransactionController.OPENMODE_FORUPDATE,
3619:                        TransactionController.MODE_RECORD,
3620:                        TransactionController.ISOLATION_READ_UNCOMMITTED);
3621:
3622:                // add 5 pages worth of data.
3623:
3624:                for (int i = 0; i < 10; i++) {
3625:                    big_row.setCol(0, new SQLInteger(i));
3626:                    cc.insert(big_row.getRowArray());
3627:                }
3628:                cc.close();
3629:
3630:                // Open another scan on the conglomerate.
3631:                ScanController base_scan = tc.openScan(
3632:                        orig_conglomid,
3633:                        true, // hold cursor open across commit
3634:                        TransactionController.OPENMODE_FORUPDATE, // for update
3635:                        TransactionController.MODE_RECORD,
3636:                        TransactionController.ISOLATION_SERIALIZABLE,
3637:                        (FormatableBitSet) null, // all columns, all as objects
3638:                        null, // start position - first row in conglomerate
3639:                        0, // unused if start position is null.
3640:                        null, // qualifier - accept all rows
3641:                        null, // stop position - last row in conglomerate
3642:                        0); // unused if stop position is null.
3643:
3644:                // now delete all the rows and remember the row location of the
3645:                // last row.
3646:
3647:                RowLocation deleted_page_rowloc = base_scan
3648:                        .newRowLocationTemplate();
3649:
3650:                for (int i = 0; i < 10; i++) {
3651:                    base_scan.next();
3652:                    base_scan.fetchLocation(deleted_page_rowloc);
3653:                    base_scan.delete();
3654:
3655:                    tc.commit();
3656:                }
3657:                base_scan.close();
3658:                tc.commit();
3659:
3660:                // at this point the post commit thread should have reclaimed all the 5
3661:                // pages.  Open it, at read uncommitted level.
3662:                cc = tc.openConglomerate(orig_conglomid, false, 0,
3663:                        TransactionController.MODE_RECORD,
3664:                        TransactionController.ISOLATION_READ_UNCOMMITTED);
3665:
3666:                // Test heap fetch of row on page which does not exist.
3667:                if (cc.fetch(deleted_page_rowloc, big_row.getRowArray(), null)) {
3668:                    throw T_Fail
3669:                            .testFailMsg("(readUncommitted) fetch should ret false for reclaimed page.");
3670:                }
3671:
3672:                // Test heap replace of row on page which does not exist.
3673:                FormatableBitSet update_desc = new FormatableBitSet(1);
3674:                if (cc.replace(deleted_page_rowloc, big_row.getRowArray(),
3675:                        update_desc)) {
3676:                    throw T_Fail
3677:                            .testFailMsg("(readUncommitted) delete should ret false for reclaimed page.");
3678:                }
3679:
3680:                // Test heap fetch (overloaded call) of row on page which does not exist.
3681:                if (cc.fetch(deleted_page_rowloc, big_row.getRowArray(), null,
3682:                        true)) {
3683:                    throw T_Fail
3684:                            .testFailMsg("(readUncommitted) fetch should ret false for reclaimed page.");
3685:                }
3686:
3687:                // Test heap delete of row on page which does not exist.
3688:                if (cc.delete(deleted_page_rowloc)) {
3689:                    throw T_Fail
3690:                            .testFailMsg("(readUncommitted) delete should ret false for reclaimed page.");
3691:                }
3692:
3693:                cc.close();
3694:
3695:                /*
3696:                 * TEST 2 - test heap fetch of row on page where row does not exist.
3697:                 * <p>
3698:                 * Do this by inserting enough rows to put 1 row on the 2nd page.
3699:                 * Then delete this one row, which will queue a post commit to reclaim
3700:                 * the row and page.  Then insert one more row on the same page in
3701:                 * the same xact.  Now commit the xact, which will cause post commit
3702:                 * to run which will reclaim the row but not the page.  Then try and
3703:                 * fetch the row which was deleted.
3704:                 */
3705:
3706:                // string column will be 1500 bytes, allowing 2 rows per page to fit.
3707:                SQLChar stringcol = new SQLChar();
3708:                stringcol.setValue(T_AccessFactory.repeatString(
3709:                        "012345678901234", 100));
3710:                big_row.setCol(1, stringcol);
3711:
3712:                // Create a heap conglomerate.
3713:                orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
3714:                        big_row.getRowArray(), null, // column sort order not required for heap
3715:                        null, // default properties
3716:                        TransactionController.IS_DEFAULT); // not temporary
3717:
3718:                cc = tc.openConglomerate(orig_conglomid, false,
3719:                        TransactionController.OPENMODE_FORUPDATE,
3720:                        TransactionController.MODE_RECORD,
3721:                        TransactionController.ISOLATION_READ_UNCOMMITTED);
3722:
3723:                // add 3 rows, should result in 1 row on second page.
3724:
3725:                for (int i = 0; i < 3; i++) {
3726:                    big_row.setCol(0, new SQLInteger(i));
3727:                    cc.insert(big_row.getRowArray());
3728:                }
3729:
3730:                // Open another scan on the conglomerate.
3731:                base_scan = tc.openScan(
3732:                        orig_conglomid,
3733:                        true, // hold cursor open across commit
3734:                        TransactionController.OPENMODE_FORUPDATE, // for update
3735:                        TransactionController.MODE_RECORD,
3736:                        TransactionController.ISOLATION_SERIALIZABLE,
3737:                        (FormatableBitSet) null, // all columns, all as objects
3738:                        null, // start position - first row in conglomerate
3739:                        0, // unused if start position is null.
3740:                        null, // qualifier - accept all rows
3741:                        null, // stop position - last row in conglomerate
3742:                        0); // unused if stop position is null.
3743:
3744:                // now delete all the rows and remember the row location of the
3745:                // last row.
3746:
3747:                RowLocation deleted_row_rowloc = base_scan
3748:                        .newRowLocationTemplate();
3749:
3750:                for (int i = 0; i < 3; i++) {
3751:                    base_scan.next();
3752:                    base_scan.fetchLocation(deleted_row_rowloc);
3753:                    base_scan.delete();
3754:                }
3755:
3756:                // insert another row on page 2 to make sure page does not go away.
3757:                cc.insert(big_row.getRowArray());
3758:
3759:                cc.close();
3760:                base_scan.close();
3761:                tc.commit();
3762:
3763:                // at this point the post commit thread should have reclaimed all the 
3764:                // deleted row on page 2, but not the page.
3765:                //
3766:                // Open it, at read uncommitted level.
3767:                cc = tc.openConglomerate(orig_conglomid, false, 0,
3768:                        TransactionController.MODE_RECORD,
3769:                        TransactionController.ISOLATION_READ_UNCOMMITTED);
3770:
3771:                // the following will be attempting to fetch a row which has been
3772:                // reclaimed by post commit, on an existing page.
3773:
3774:                // test heap fetch of row on page where row does not exist.
3775:                if (cc.fetch(deleted_row_rowloc, big_row.getRowArray(), null)) {
3776:                    throw T_Fail
3777:                            .testFailMsg("(readUncommitted) fetch should ret false for reclaimed row.");
3778:                }
3779:
3780:                // test heap replace of row on page where row does not exist.
3781:                if (cc.replace(deleted_page_rowloc, big_row.getRowArray(),
3782:                        update_desc)) {
3783:                    throw T_Fail
3784:                            .testFailMsg("(readUncommitted) delete should ret false for reclaimed page.");
3785:                }
3786:
3787:                // test heap fetch (overloaded) of row on page where row does not exist.
3788:                if (cc.fetch(deleted_page_rowloc, big_row.getRowArray(), null,
3789:                        true)) {
3790:                    throw T_Fail
3791:                            .testFailMsg("(readUncommitted) fetch should ret false for reclaimed page.");
3792:                }
3793:
3794:                // test heap delete of row on page where row does not exist.
3795:                if (cc.delete(deleted_page_rowloc)) {
3796:                    throw T_Fail
3797:                            .testFailMsg("(readUncommitted) delete should ret false for reclaimed page.");
3798:                }
3799:
3800:                cc.close();
3801:
3802:                /*
3803:                 * TEST 3 - test heap scan fetch of row on page prevents page from 
3804:                 *          disappearing, but handles row being deleted.
3805:                 * <p>
3806:                 * A heap scan will maintain a scan lock on a page even if it is doing
3807:                 * a read uncommitted scan.  This will prevent the row/page from being
3808:                 * reclaimed by post commit while the scan is positioned on the page. 
3809:                 * This presents no other concurrency issues for read uncommitted, it
3810:                 * should be invisible to the user (deletes can still happen and the
3811:                 * read uncommitted scanner will not block anyone).
3812:                 *
3813:                 * You need to at least get to the 2nd page, because the 1st page is
3814:                 * never totally reclaimed and deleted by the system in a heap (it has
3815:                 * some internal catalog information stored internally in row "0").
3816:                 */
3817:
3818:                big_row = new T_AccessRow(2);
3819:
3820:                big_row.setCol(1, new SQLChar(twok_string));
3821:
3822:                // Create a heap conglomerate.
3823:                orig_conglomid = tc.createConglomerate("heap", // create a heap conglomerate
3824:                        big_row.getRowArray(), null, // column sort order not required for heap
3825:                        null, // default properties
3826:                        TransactionController.IS_DEFAULT); // not temporary
3827:
3828:                cc = tc.openConglomerate(orig_conglomid, false,
3829:                        TransactionController.OPENMODE_FORUPDATE,
3830:                        TransactionController.MODE_RECORD,
3831:                        TransactionController.ISOLATION_READ_UNCOMMITTED);
3832:
3833:                // add 5 pages worth of data.
3834:
3835:                for (int i = 0; i < 10; i++) {
3836:                    big_row.setCol(0, new SQLInteger(i));
3837:                    cc.insert(big_row.getRowArray());
3838:                }
3839:                cc.close();
3840:
3841:                // Open scan on the conglomerate, and position it on the second page.
3842:                base_scan = tc.openScan(
3843:                        orig_conglomid,
3844:                        true, // hold cursor open across commit
3845:                        0, // for read
3846:                        TransactionController.MODE_RECORD,
3847:                        TransactionController.ISOLATION_READ_UNCOMMITTED,
3848:                        (FormatableBitSet) null, // all columns, all as objects
3849:                        null, // start position - first row in conglomerate
3850:                        0, // unused if start position is null.
3851:                        null, // qualifier - accept all rows
3852:                        null, // stop position - last row in conglomerate
3853:                        0); // unused if stop position is null.
3854:
3855:                base_scan.next();
3856:                base_scan.next();
3857:                base_scan.next();
3858:
3859:                // test that the row is accessible from all these interfaces, before
3860:                // the page disappears, and then test again after all rows have been
3861:                // deleted from the page.
3862:
3863:                if (!base_scan.doesCurrentPositionQualify())
3864:                    throw T_Fail
3865:                            .testFailMsg("(readUncommitted) doesCurrentPositionQualify() failed.");
3866:
3867:                base_scan.fetch(big_row.getRowArray());
3868:
3869:                base_scan.fetchLocation(deleted_row_rowloc);
3870:
3871:                if (base_scan.isCurrentPositionDeleted())
3872:                    throw T_Fail
3873:                            .testFailMsg("(readUncommitted) isCurrentPositionDeleted() failed.");
3874:
3875:                // Open another scan on the conglomerate.
3876:                ScanController delete_scan = tc.openScan(
3877:                        orig_conglomid,
3878:                        true, // hold cursor open across commit
3879:                        TransactionController.OPENMODE_FORUPDATE, // for update
3880:                        TransactionController.MODE_RECORD,
3881:                        TransactionController.ISOLATION_SERIALIZABLE,
3882:                        (FormatableBitSet) null, // all columns, all as objects
3883:                        null, // start position - first row in conglomerate
3884:                        0, // unused if start position is null.
3885:                        null, // qualifier - accept all rows
3886:                        null, // stop position - last row in conglomerate
3887:                        0); // unused if stop position is null.
3888:
3889:                // now delete all the rows and commit.
3890:
3891:                for (int i = 0; i < 10; i++) {
3892:                    delete_scan.next();
3893:                    delete_scan.fetchLocation(deleted_page_rowloc);
3894:                    delete_scan.delete();
3895:
3896:                }
3897:                delete_scan.close();
3898:
3899:                // Now test that the row is accessible from all these interfaces, after
3900:                // it has been deleted.
3901:
3902:                if (base_scan.doesCurrentPositionQualify())
3903:                    throw T_Fail
3904:                            .testFailMsg("(readUncommitted) doesCurrentPositionQualify() failed.");
3905:
3906:                try {
3907:                    base_scan.fetch(big_row.getRowArray());
3908:                    throw T_Fail
3909:                            .testFailMsg("(readUncommitted) fetch of deleted row should throw exception.");
3910:                } catch (StandardException se) {
3911:                    // expect SQLState.AM_RECORD_NOT_FOUND exception.
3912:
3913:                    if (!se.getMessageId().equals(SQLState.AM_RECORD_NOT_FOUND)) {
3914:                        throw T_Fail
3915:                                .testFailMsg("(readUncommitted) fetch of deleted row should throw SQLState.AM_RECORD_NOT_FOUND.");
3916:                    }
3917:                }
3918:
3919:                base_scan.fetchLocation(deleted_row_rowloc);
3920:
3921:                if (!base_scan.isCurrentPositionDeleted())
3922:                    throw T_Fail
3923:                            .testFailMsg("(readUncommitted) isCurrentPositionDeleted() failed.");
3924:
3925:                base_scan.close();
3926:                tc.commit();
3927:
3928:                REPORT("(readUncommitted) succeeded");
3929:                return true;
3930:            }
3931:
3932:            public static String repeatString(String data, int repeat) {
3933:
3934:                String s = data;
3935:                for (int i = 1; i < repeat; i++)
3936:                    s += data;
3937:
3938:                return s;
3939:            }
3940:
3941:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.