Source Code Cross Referenced for DataDictionaryImpl.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » catalog » 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.derby.impl.sql.catalog 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.sql.catalog.DataDictionaryImpl
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.derby.impl.sql.catalog;
0023:
0024:        import org.apache.derby.iapi.reference.JDBC30Translation;
0025:        import org.apache.derby.iapi.reference.Property;
0026:        import org.apache.derby.iapi.reference.SQLState;
0027:        import org.apache.derby.iapi.reference.Limits;
0028:        import org.apache.derby.iapi.sql.conn.Authorizer;
0029:
0030:        import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
0031:        import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
0032:
0033:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
0034:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
0035:        import org.apache.derby.iapi.sql.dictionary.FileInfoDescriptor;
0036:        import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
0037:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
0038:        import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;
0039:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
0040:        import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
0041:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0042:        import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
0043:        import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;
0044:        import org.apache.derby.iapi.sql.dictionary.DependencyDescriptor;
0045:        import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
0046:        import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
0047:        import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
0048:        import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
0049:        import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
0050:        import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;
0051:        import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor;
0052:        import org.apache.derby.iapi.sql.dictionary.RoutinePermsDescriptor;
0053:        import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;
0054:        import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
0055:        import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
0056:        import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
0057:        import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
0058:        import org.apache.derby.iapi.sql.dictionary.SubCheckConstraintDescriptor;
0059:        import org.apache.derby.iapi.sql.dictionary.SubConstraintDescriptor;
0060:        import org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor;
0061:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0062:        import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
0063:        import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;
0064:        import org.apache.derby.iapi.sql.dictionary.SystemColumn;
0065:
0066:        import org.apache.derby.iapi.sql.depend.DependencyManager;
0067:
0068:        import org.apache.derby.impl.sql.depend.BasicDependencyManager;
0069:
0070:        import org.apache.derby.iapi.sql.execute.ExecIndexRow;
0071:        import org.apache.derby.iapi.sql.execute.ExecutionContext;
0072:        import org.apache.derby.iapi.sql.execute.ExecutionFactory;
0073:        import org.apache.derby.iapi.sql.execute.ScanQualifier;
0074:
0075:        import org.apache.derby.iapi.types.DataValueFactory;
0076:        import org.apache.derby.iapi.types.NumberDataValue;
0077:
0078:        import org.apache.derby.iapi.types.StringDataValue;
0079:        import org.apache.derby.iapi.types.TypeId;
0080:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0081:        import org.apache.derby.iapi.types.DataValueDescriptor;
0082:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0083:        import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
0084:
0085:        import org.apache.derby.iapi.store.access.AccessFactory;
0086:        import org.apache.derby.iapi.store.access.ConglomerateController;
0087:        import org.apache.derby.iapi.types.Orderable;
0088:        import org.apache.derby.iapi.types.RowLocation;
0089:        import org.apache.derby.iapi.store.access.RowUtil;
0090:        import org.apache.derby.iapi.store.access.ScanController;
0091:        import org.apache.derby.iapi.store.access.TransactionController;
0092:        import org.apache.derby.iapi.store.access.Qualifier;
0093:
0094:        import org.apache.derby.iapi.services.monitor.Monitor;
0095:        import org.apache.derby.iapi.services.monitor.ModuleControl;
0096:        import org.apache.derby.iapi.services.monitor.ModuleSupportable;
0097:
0098:        import org.apache.derby.iapi.services.context.ContextManager;
0099:        import org.apache.derby.iapi.services.context.ContextService;
0100:
0101:        import org.apache.derby.iapi.error.StandardException;
0102:
0103:        // RESOLVE - paulat - remove this import when track 3677 is fixed
0104:        import org.apache.derby.iapi.services.sanity.AssertFailure;
0105:
0106:        import org.apache.derby.iapi.sql.execute.ExecRow;
0107:        import org.apache.derby.iapi.sql.execute.TupleFilter;
0108:
0109:        import org.apache.derby.iapi.services.sanity.SanityManager;
0110:
0111:        import org.apache.derby.iapi.services.cache.CacheFactory;
0112:        import org.apache.derby.iapi.services.cache.CacheManager;
0113:        import org.apache.derby.iapi.services.cache.Cacheable;
0114:        import org.apache.derby.iapi.services.cache.CacheableFactory;
0115:
0116:        import org.apache.derby.iapi.services.locks.LockFactory;
0117:        import org.apache.derby.iapi.services.locks.C_LockFactory;
0118:
0119:        import org.apache.derby.iapi.services.property.PropertyUtil;
0120:
0121:        import org.apache.derby.impl.services.locks.Timeout;
0122:
0123:        import org.apache.derby.iapi.services.uuid.UUIDFactory;
0124:        import org.apache.derby.catalog.AliasInfo;
0125:        import org.apache.derby.catalog.DefaultInfo;
0126:        import org.apache.derby.catalog.TypeDescriptor;
0127:        import org.apache.derby.catalog.UUID;
0128:        import org.apache.derby.catalog.types.RoutineAliasInfo;
0129:
0130:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0131:        import org.apache.derby.iapi.services.locks.ShExLockable;
0132:        import org.apache.derby.iapi.services.locks.ShExQual;
0133:        import org.apache.derby.iapi.util.StringUtil;
0134:        import org.apache.derby.iapi.util.IdUtil;
0135:
0136:        import java.util.Calendar;
0137:        import java.util.Date;
0138:        import java.util.GregorianCalendar;
0139:        import java.util.Hashtable;
0140:        import java.util.Properties;
0141:        import java.util.Vector;
0142:
0143:        import java.util.List;
0144:        import java.util.Iterator;
0145:
0146:        import java.util.Enumeration;
0147:        import java.io.InputStream;
0148:        import java.io.IOException;
0149:
0150:        import java.sql.Types;
0151:
0152:        /**
0153:         * This abstract class contains the common code for the "regular" and
0154:         * limited data dictionaries.  The limited configuration puts an upper
0155:         * limit on the number of tables a user is allowed to create.
0156:         *
0157:         * This class provides the entire implementation of DataDictionary,
0158:         * and ModuleControl, except for the stop()
0159:         * method, which is to be provided by a non-abstract super-class.
0160:         * The reason for putting the stop() method in the super-class is to
0161:         * prevent someone from inadvertently changing this to a non-abstract
0162:         * class.  This class is shipped with both the limited and non-limited
0163:         * configurations, and we don't want anyone to be able to cheat by
0164:         * booting this class instead of booting the super-class.
0165:         */
0166:
0167:        public final class DataDictionaryImpl implements  DataDictionary,
0168:                CacheableFactory, ModuleControl, ModuleSupportable,
0169:                java.security.PrivilegedAction {
0170:
0171:            private static final String CFG_SYSTABLES_ID = "SystablesIdentifier";
0172:            private static final String CFG_SYSTABLES_INDEX1_ID = "SystablesIndex1Identifier";
0173:            private static final String CFG_SYSTABLES_INDEX2_ID = "SystablesIndex2Identifier";
0174:            private static final String CFG_SYSCOLUMNS_ID = "SyscolumnsIdentifier";
0175:            private static final String CFG_SYSCOLUMNS_INDEX1_ID = "SyscolumnsIndex1Identifier";
0176:            private static final String CFG_SYSCOLUMNS_INDEX2_ID = "SyscolumnsIndex2Identifier";
0177:            private static final String CFG_SYSCONGLOMERATES_ID = "SysconglomeratesIdentifier";
0178:            private static final String CFG_SYSCONGLOMERATES_INDEX1_ID = "SysconglomeratesIndex1Identifier";
0179:            private static final String CFG_SYSCONGLOMERATES_INDEX2_ID = "SysconglomeratesIndex2Identifier";
0180:            private static final String CFG_SYSCONGLOMERATES_INDEX3_ID = "SysconglomeratesIndex3Identifier";
0181:            private static final String CFG_SYSSCHEMAS_ID = "SysschemasIdentifier";
0182:            private static final String CFG_SYSSCHEMAS_INDEX1_ID = "SysschemasIndex1Identifier";
0183:            private static final String CFG_SYSSCHEMAS_INDEX2_ID = "SysschemasIndex2Identifier";
0184:
0185:            private static final int SYSCONGLOMERATES_CORE_NUM = 0;
0186:            private static final int SYSTABLES_CORE_NUM = 1;
0187:            private static final int SYSCOLUMNS_CORE_NUM = 2;
0188:            private static final int SYSSCHEMAS_CORE_NUM = 3;
0189:            private static final int NUM_CORE = 4;
0190:
0191:            /**
0192:             * SYSFUN functions. Table of functions that automatically appear
0193:             * in the SYSFUN schema. These functions are resolved to directly
0194:             * if no schema name is given, e.g.
0195:             * 
0196:             * <code>
0197:             * SELECT COS(angle) FROM ROOM_WALLS
0198:             * </code>
0199:             * 
0200:             * Adding a function here is suitable when the function defintion
0201:             * can have a single return type and fixed parameter types.
0202:             * 
0203:             * Functions that need to have a return type based upon the
0204:             * input type(s) are not supported here. Typically those are
0205:             * added into the parser and methods added into the DataValueDescriptor interface.
0206:             * Examples are character based functions whose return type
0207:             * length is based upon the passed in type, e.g. passed a CHAR(10)
0208:             * returns a CHAR(10).
0209:             * 
0210:             * 
0211:             * This simple table assumes zero or a single parameter
0212:             * and RETURNS NULL ON NULL INPUT. The scheme could be expanded
0213:             * to handle other function options such as other parameters if needed.
0214:             *[0] = FUNCTION name
0215:             *[1] = RETURNS type
0216:             *[2] = Java class
0217:             *[3] = method name and signature
0218:             *[4] = parameter type (single parameter) or null for no parameters.
0219:             *
0220:             */
0221:            private static final String[][] SYSFUN_FUNCTIONS = {
0222:                    { "ACOS", "DOUBLE", "java.lang.StrictMath", "acos(double)",
0223:                            "DOUBLE" },
0224:                    { "ASIN", "DOUBLE", "java.lang.StrictMath", "asin(double)",
0225:                            "DOUBLE" },
0226:                    { "ATAN", "DOUBLE", "java.lang.StrictMath", "atan(double)",
0227:                            "DOUBLE" },
0228:                    { "COS", "DOUBLE", "java.lang.StrictMath", "cos(double)",
0229:                            "DOUBLE" },
0230:                    { "SIN", "DOUBLE", "java.lang.StrictMath", "sin(double)",
0231:                            "DOUBLE" },
0232:                    { "TAN", "DOUBLE", "java.lang.StrictMath", "tan(double)",
0233:                            "DOUBLE" },
0234:                    { "PI", "DOUBLE",
0235:                            "org.apache.derby.catalog.SystemProcedures",
0236:                            "PI()", null },
0237:                    { "DEGREES", "DOUBLE", "java.lang.StrictMath",
0238:                            "toDegrees(double)", "DOUBLE" },
0239:                    { "RADIANS", "DOUBLE", "java.lang.StrictMath",
0240:                            "toRadians(double)", "DOUBLE" },
0241:                    { "LN", "DOUBLE", "java.lang.StrictMath", "log(double)",
0242:                            "DOUBLE" },
0243:                    { "LOG", "DOUBLE", "java.lang.StrictMath", "log(double)",
0244:                            "DOUBLE" }, // Same as LN
0245:                    { "LOG10", "DOUBLE",
0246:                            "org.apache.derby.catalog.SystemProcedures",
0247:                            "LOG10(double)", "DOUBLE" },
0248:                    { "EXP", "DOUBLE", "java.lang.StrictMath", "exp(double)",
0249:                            "DOUBLE" },
0250:                    { "CEIL", "DOUBLE", "java.lang.StrictMath", "ceil(double)",
0251:                            "DOUBLE" },
0252:                    { "CEILING", "DOUBLE", "java.lang.StrictMath",
0253:                            "ceil(double)", "DOUBLE" }, // Same as CEIL
0254:                    { "FLOOR", "DOUBLE", "java.lang.StrictMath",
0255:                            "floor(double)", "DOUBLE" }, };
0256:
0257:            /**
0258:             * Runtime definition of the functions from SYSFUN_FUNCTIONS.
0259:             * Populated dynamically as functions are called.
0260:             */
0261:            private static final AliasDescriptor[] SYSFUN_AD = new AliasDescriptor[SYSFUN_FUNCTIONS.length];
0262:
0263:            /**
0264:             * Dummy parameter name for functions from SYSFUN_FUNCTIONS.
0265:             */
0266:            private static final String[] SYSFUN_PNAME = { "P1" };
0267:
0268:            /**
0269:             * Parameter mode (IN as required) for functions from SYSFUN_FUNCTIONS.
0270:             */
0271:            private static final int[] SYSFUN_PMODE = { JDBC30Translation.PARAMETER_MODE_IN };
0272:
0273:            // the structure that holds all the core table info
0274:            private TabInfoImpl[] coreInfo;
0275:
0276:            /*
0277:             ** SchemaDescriptors for system and app schemas.  Both
0278:             ** are canonical.  We cache them for fast lookup.
0279:             */
0280:            protected SchemaDescriptor systemSchemaDesc;
0281:            protected SchemaDescriptor sysIBMSchemaDesc;
0282:            protected SchemaDescriptor declaredGlobalTemporaryTablesSchemaDesc;
0283:            protected SchemaDescriptor systemDiagSchemaDesc;
0284:            protected SchemaDescriptor systemUtilSchemaDesc;
0285:
0286:            private String systemSchemaName;
0287:            private String systemDiagSchemaName;
0288:            private String systemUtilSchemaName;
0289:            private String sysIBMSchemaName;
0290:            private String declaredGlobalTemporaryTablesSchemaName;
0291:            boolean builtinSchemasAreFromLCC;
0292:
0293:            protected boolean convertIdToLower;
0294:            // Convert identifiers to lower case (as in Foundation) or not.
0295:
0296:            // This array of non-core table names *MUST* be in the same order
0297:            // as the non-core table numbers, above.
0298:            private static final String[] nonCoreNames = { "SYSCONSTRAINTS",
0299:                    "SYSKEYS", "SYSDEPENDS", "SYSALIASES", "SYSVIEWS",
0300:                    "SYSCHECKS", "SYSFOREIGNKEYS", "SYSSTATEMENTS", "SYSFILES",
0301:                    "SYSTRIGGERS", "SYSSTATISTICS", "SYSDUMMY1",
0302:                    "SYSTABLEPERMS", "SYSCOLPERMS", "SYSROUTINEPERMS" };
0303:
0304:            private static final int NUM_NONCORE = nonCoreNames.length;
0305:
0306:            /**
0307:             * List of all "system" schemas
0308:             * <p>
0309:             * This list should contain all schema's used by the system and are
0310:             * created when the database is created.  Users should not be able to
0311:             * create or drop these schema's and should not be able to create or
0312:             * drop objects in these schema's.  This list is used by code that
0313:             * needs to check if a particular schema is a "system" schema.
0314:             **/
0315:            private static final String[] systemSchemaNames = {
0316:                    SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME,
0317:                    SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,
0318:                    SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME,
0319:                    SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME,
0320:                    SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME,
0321:                    SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME,
0322:                    SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME,
0323:                    SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
0324:                    SchemaDescriptor.STD_SQLJ_SCHEMA_NAME,
0325:                    SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME };
0326:
0327:            /** Dictionary version of the on-disk database */
0328:            private DD_Version dictionaryVersion;
0329:            /** Dictionary version of the currently running engine */
0330:            private DD_Version softwareVersion;
0331:
0332:            private String authorizationDatabaseOwner;
0333:            private boolean usesSqlAuthorization;
0334:
0335:            /*
0336:             ** This property and value are written into the database properties
0337:             ** when the database is created, and are used to determine whether
0338:             ** the system catalogs need to be upgraded.
0339:             */
0340:
0341:            // the structure that holds all the noncore info
0342:            private TabInfoImpl[] noncoreInfo;
0343:
0344:            // no other system tables have id's in the configuration.
0345:
0346:            public DataDescriptorGenerator dataDescriptorGenerator;
0347:            protected DataValueFactory dvf;
0348:            protected AccessFactory af;
0349:            //DataDictionaryContext				ddc;
0350:
0351:            private ExecutionFactory exFactory;
0352:            protected UUIDFactory uuidFactory;
0353:
0354:            Properties startupParameters;
0355:            int engineType;
0356:
0357:            /* Information about whether or not we are at boot time */
0358:            protected boolean booting;
0359:            private TransactionController bootingTC;
0360:            protected DependencyManager dmgr;
0361:
0362:            /* Cache of table descriptors */
0363:            CacheManager OIDTdCache;
0364:            CacheManager nameTdCache;
0365:            private CacheManager spsNameCache;
0366:            private Hashtable spsIdHash;
0367:            // private Hashtable       spsTextHash;
0368:            int tdCacheSize;
0369:            int stmtCacheSize;
0370:
0371:            /* Cache of permissions data */
0372:            CacheManager permissionsCache;
0373:            int permissionsCacheSize;
0374:
0375:            /*
0376:             ** Lockable object for synchronizing transition from caching to non-caching
0377:             */
0378:            ShExLockable cacheCoordinator;
0379:            public LockFactory lockFactory;
0380:
0381:            volatile int cacheMode = DataDictionary.COMPILE_ONLY_MODE;
0382:
0383:            /* Number of DDL users */
0384:            volatile int ddlUsers;
0385:            /* Number of readers that start in DDL_MODE */
0386:            volatile int readersInDDLMode;
0387:
0388:            /**
0389:            	True if the database is read only and requires
0390:            	some form of upgrade, that makes the stored prepared
0391:            	statements invalid.
0392:            	With this case the engine is running at a different
0393:            	version to the underlying stored database. This
0394:            	can happen in 5.1 if the database is read only
0395:            	and a different point release (later than 5.1.25?)
0396:            	to the one that created it, has been booted. (Beetle 5170).
0397:
0398:            	<P>
0399:            	In 5.2 and newer this will be the case if the engine
0400:            	booting the database is newer than the engine
0401:            	that created it.
0402:
0403:             */
0404:            public boolean readOnlyUpgrade;
0405:
0406:            //systemSQLNameNumber is the number used as the last digit during the previous call to getSystemSQLName.
0407:            //If it is 9 for a given calendarForLastSystemSQLName, we will restart the counter to 0
0408:            //and increment the calendarForLastSystemSQLName by 10ms.
0409:            private int systemSQLNameNumber;
0410:            private GregorianCalendar calendarForLastSystemSQLName = new GregorianCalendar();
0411:            private long timeForLastSystemSQLName;
0412:
0413:            /**
0414:             * List of procedures in SYSCS_UTIL schema with PUBLIC access
0415:             */
0416:            private static final String[] sysUtilProceduresWithPublicAccess = {
0417:                    "SYSCS_SET_RUNTIMESTATISTICS",
0418:                    "SYSCS_SET_STATISTICS_TIMING",
0419:                    "SYSCS_INPLACE_COMPRESS_TABLE", "SYSCS_COMPRESS_TABLE", };
0420:
0421:            /**
0422:             * List of functions in SYSCS_UTIL schema with PUBLIC access
0423:             */
0424:            private static final String[] sysUtilFunctionsWithPublicAccess = { "SYSCS_GET_RUNTIMESTATISTICS", };
0425:
0426:            /*
0427:             ** Constructor
0428:             */
0429:
0430:            public DataDictionaryImpl() {
0431:
0432:            }
0433:
0434:            /**
0435:              Currently, all this routine does is check to see if the Replication
0436:              property has been turned on for this database. If so, then this is not
0437:              the NodeFactory that's wanted--so we return false. The NodeFactory that
0438:              is wanted is our child class "RepNodeFactory".
0439:
0440:              @return	true		if this database does not want Replication
0441:                        false		otherwise
0442:             */
0443:
0444:            public boolean canSupport(Properties startParams) {
0445:                return Monitor.isDesiredType(startParams,
0446:                        org.apache.derby.iapi.reference.EngineType.NONE);
0447:            }
0448:
0449:            /**
0450:             * Start-up method for this instance of the data dictionary.
0451:             *
0452:             * @param startParams	The start-up parameters
0453:             *
0454:             *	@exception StandardException	Thrown if the module fails to start
0455:             */
0456:            public void boot(boolean create, Properties startParams)
0457:                    throws StandardException {
0458:                softwareVersion = new DD_Version(this ,
0459:                        DataDictionary.DD_VERSION_DERBY_10_2);
0460:
0461:                /* There is a bootstrapping problem here. We would like to use
0462:                 * a language connection context to find the name of the system and default
0463:                 * schemas. However a language connection context is not available when a
0464:                 * database is being created, as it is when this method is called. So,
0465:                 * this method must look at the params properties to discover the identifier
0466:                 * casing and convert the standard names as necessary, essentially duplicating
0467:                 * logic found in GenericLanguageConnectionContext.
0468:                 */
0469:                convertIdToLower = false;
0470:
0471:                startupParameters = startParams;
0472:
0473:                uuidFactory = Monitor.getMonitor().getUUIDFactory();
0474:
0475:                engineType = Monitor.getEngineType(startParams);
0476:
0477:                // REMIND: actually, we're supposed to get the DataValueFactory
0478:                // out of the connection context...this is a bit of a shortcut.
0479:                // We get the DataValueFactory early in order to help bootstrap the system catalogs.
0480:                LanguageConnectionFactory langConnFactory = (LanguageConnectionFactory) Monitor
0481:                        .bootServiceModule(create, this ,
0482:                                LanguageConnectionFactory.MODULE, startParams);
0483:
0484:                dvf = langConnFactory.getDataValueFactory();
0485:                exFactory = (ExecutionFactory) Monitor.bootServiceModule(
0486:                        create, this , ExecutionFactory.MODULE, startParams);
0487:
0488:                // initailze the arrays of core and noncore tables
0489:                initializeCatalogInfo();
0490:
0491:                // indicate that we are in the process of booting
0492:                booting = true;
0493:
0494:                // set only if child class hasn't overriden this already
0495:                if (dataDescriptorGenerator == null) {
0496:                    dataDescriptorGenerator = new DataDescriptorGenerator(this );
0497:                }
0498:
0499:                if (!create) {
0500:
0501:                    // SYSTABLES
0502:
0503:                    coreInfo[SYSTABLES_CORE_NUM]
0504:                            .setHeapConglomerate(getBootParameter(startParams,
0505:                                    CFG_SYSTABLES_ID, true));
0506:
0507:                    coreInfo[SYSTABLES_CORE_NUM].setIndexConglomerate(
0508:                            SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
0509:                            getBootParameter(startParams,
0510:                                    CFG_SYSTABLES_INDEX1_ID, true));
0511:
0512:                    coreInfo[SYSTABLES_CORE_NUM].setIndexConglomerate(
0513:                            SYSTABLESRowFactory.SYSTABLES_INDEX2_ID,
0514:                            getBootParameter(startParams,
0515:                                    CFG_SYSTABLES_INDEX2_ID, true));
0516:
0517:                    // SYSCOLUMNS
0518:
0519:                    coreInfo[SYSCOLUMNS_CORE_NUM]
0520:                            .setHeapConglomerate(getBootParameter(startParams,
0521:                                    CFG_SYSCOLUMNS_ID, true));
0522:
0523:                    coreInfo[SYSCOLUMNS_CORE_NUM].setIndexConglomerate(
0524:                            SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID,
0525:                            getBootParameter(startParams,
0526:                                    CFG_SYSCOLUMNS_INDEX1_ID, true));
0527:                    // 2nd syscolumns index added in Xena, hence may not be there
0528:                    coreInfo[SYSCOLUMNS_CORE_NUM].setIndexConglomerate(
0529:                            SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX2_ID,
0530:                            getBootParameter(startParams,
0531:                                    CFG_SYSCOLUMNS_INDEX2_ID, false));
0532:
0533:                    // SYSCONGLOMERATES
0534:
0535:                    coreInfo[SYSCONGLOMERATES_CORE_NUM]
0536:                            .setHeapConglomerate(getBootParameter(startParams,
0537:                                    CFG_SYSCONGLOMERATES_ID, true));
0538:
0539:                    coreInfo[SYSCONGLOMERATES_CORE_NUM]
0540:                            .setIndexConglomerate(
0541:                                    SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
0542:                                    getBootParameter(startParams,
0543:                                            CFG_SYSCONGLOMERATES_INDEX1_ID,
0544:                                            true));
0545:
0546:                    coreInfo[SYSCONGLOMERATES_CORE_NUM]
0547:                            .setIndexConglomerate(
0548:                                    SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID,
0549:                                    getBootParameter(startParams,
0550:                                            CFG_SYSCONGLOMERATES_INDEX2_ID,
0551:                                            true));
0552:
0553:                    coreInfo[SYSCONGLOMERATES_CORE_NUM]
0554:                            .setIndexConglomerate(
0555:                                    SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID,
0556:                                    getBootParameter(startParams,
0557:                                            CFG_SYSCONGLOMERATES_INDEX3_ID,
0558:                                            true));
0559:
0560:                    // SYSSCHEMAS
0561:                    coreInfo[SYSSCHEMAS_CORE_NUM]
0562:                            .setHeapConglomerate(getBootParameter(startParams,
0563:                                    CFG_SYSSCHEMAS_ID, true));
0564:
0565:                    coreInfo[SYSSCHEMAS_CORE_NUM].setIndexConglomerate(
0566:                            SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID,
0567:                            getBootParameter(startParams,
0568:                                    CFG_SYSSCHEMAS_INDEX1_ID, true));
0569:
0570:                    coreInfo[SYSSCHEMAS_CORE_NUM].setIndexConglomerate(
0571:                            SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX2_ID,
0572:                            getBootParameter(startParams,
0573:                                    CFG_SYSSCHEMAS_INDEX2_ID, true));
0574:
0575:                }
0576:
0577:                String value = startParams
0578:                        .getProperty(Property.LANG_TD_CACHE_SIZE);
0579:                tdCacheSize = PropertyUtil.intPropertyValue(
0580:                        Property.LANG_TD_CACHE_SIZE, value, 0,
0581:                        Integer.MAX_VALUE, Property.LANG_TD_CACHE_SIZE_DEFAULT);
0582:
0583:                value = startParams.getProperty(Property.LANG_SPS_CACHE_SIZE);
0584:                stmtCacheSize = PropertyUtil
0585:                        .intPropertyValue(Property.LANG_SPS_CACHE_SIZE, value,
0586:                                0, Integer.MAX_VALUE,
0587:                                Property.LANG_SPS_CACHE_SIZE_DEFAULT);
0588:
0589:                value = startParams
0590:                        .getProperty(Property.LANG_PERMISSIONS_CACHE_SIZE);
0591:                permissionsCacheSize = PropertyUtil.intPropertyValue(
0592:                        Property.LANG_PERMISSIONS_CACHE_SIZE, value, 0,
0593:                        Integer.MAX_VALUE,
0594:                        Property.LANG_PERMISSIONS_CACHE_SIZE_DEFAULT);
0595:
0596:                /*
0597:                 * data dictionary contexts are only associated with connections.
0598:                 * we have to look for the basic data dictionary, as there is
0599:                 * no connection, and thus no context stack yet.
0600:                 */
0601:
0602:                /*
0603:                 * Get the table descriptor cache.
0604:                 */
0605:                CacheFactory cf = (CacheFactory) Monitor
0606:                        .startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
0607:                OIDTdCache = cf.newCacheManager(this ,
0608:                        "TableDescriptorOIDCache", tdCacheSize, tdCacheSize);
0609:                nameTdCache = cf.newCacheManager(this ,
0610:                        "TableDescriptorNameCache", tdCacheSize, tdCacheSize);
0611:
0612:                if (stmtCacheSize > 0) {
0613:                    spsNameCache = cf.newCacheManager(this ,
0614:                            "SPSNameDescriptorCache", stmtCacheSize,
0615:                            stmtCacheSize);
0616:                    spsIdHash = new Hashtable(stmtCacheSize);
0617:                    // spsTextHash = new Hashtable(stmtCacheSize);
0618:                }
0619:
0620:                /* Get the object to coordinate cache transitions */
0621:                cacheCoordinator = new ShExLockable();
0622:
0623:                /* Get AccessFactory in order to transaction stuff */
0624:                af = (AccessFactory) Monitor.findServiceModule(this ,
0625:                        AccessFactory.MODULE);
0626:
0627:                /* Get the lock factory */
0628:                lockFactory = af.getLockFactory();
0629:
0630:                /*
0631:                 * now we need to setup a context stack for the database creation work.
0632:                 * We assume the System boot process has created a context
0633:                 * manager already, but not that contexts we need are there.
0634:                 */
0635:                ContextService csf = ContextService.getFactory();
0636:
0637:                ContextManager cm = csf.getCurrentContextManager();
0638:                if (SanityManager.DEBUG)
0639:                    SanityManager.ASSERT((cm != null),
0640:                            "Failed to get current ContextManager");
0641:
0642:                /* push a datadictionary context onto this stack */
0643:                pushDataDictionaryContext(cm);
0644:
0645:                // RESOLVE other non-StandardException errors.
0646:                bootingTC = null;
0647:                try {
0648:                    // Get a transaction controller. This has the side effect of
0649:                    // creating a transaction context if there isn't one already.
0650:                    bootingTC = af.getTransaction(cm);
0651:
0652:                    /*
0653:                    	We need an execution context so that we can generate rows
0654:                    	REMIND: maybe only for create case?
0655:                     */
0656:                    exFactory.newExecutionContext(cm);
0657:
0658:                    DataDescriptorGenerator ddg = getDataDescriptorGenerator();
0659:
0660:                    if (create) {
0661:                        String userName = IdUtil
0662:                                .getUserNameFromURLProps(startParams);
0663:                        authorizationDatabaseOwner = IdUtil
0664:                                .getUserAuthorizationId(userName);
0665:
0666:                        // create any required tables.
0667:                        createDictionaryTables(startParams, bootingTC, ddg);
0668:                        //create procedures for network server metadata
0669:                        create_SYSIBM_procedures(bootingTC);
0670:                        //create metadata sps statement required for network server
0671:                        createSystemSps(bootingTC);
0672:                        // create the SYSCS_UTIL system procedures)
0673:                        create_SYSCS_procedures(bootingTC);
0674:                        // log the current dictionary version
0675:                        dictionaryVersion = softwareVersion;
0676:
0677:                        /* Set properties for current and create time 
0678:                         * DataDictionary versions.
0679:                         */
0680:                        bootingTC.setProperty(
0681:                                DataDictionary.CORE_DATA_DICTIONARY_VERSION,
0682:                                dictionaryVersion, true);
0683:
0684:                        bootingTC.setProperty(
0685:                                DataDictionary.CREATE_DATA_DICTIONARY_VERSION,
0686:                                dictionaryVersion, true);
0687:
0688:                        // If SqlAuthorization is set as system property during database
0689:                        // creation, set it as database property also, so it gets persisted.
0690:                        if (PropertyUtil
0691:                                .getSystemBoolean(Property.SQL_AUTHORIZATION_PROPERTY)) {
0692:                            bootingTC.setProperty(
0693:                                    Property.SQL_AUTHORIZATION_PROPERTY,
0694:                                    "true", true);
0695:                            usesSqlAuthorization = true;
0696:                        }
0697:
0698:                    } else {
0699:                        // Get the ids for non-core tables
0700:                        loadDictionaryTables(bootingTC, ddg, startParams);
0701:                        SchemaDescriptor sd = locateSchemaRow(
0702:                                SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
0703:                                bootingTC);
0704:                        authorizationDatabaseOwner = sd.getAuthorizationId();
0705:                        String sqlAuth = PropertyUtil.getDatabaseProperty(
0706:                                bootingTC, Property.SQL_AUTHORIZATION_PROPERTY);
0707:                        if (Boolean.valueOf(sqlAuth).booleanValue()) {
0708:                            // SQL authorization requires 10.2 or higher database
0709:                            checkVersion(DataDictionary.DD_VERSION_DERBY_10_2,
0710:                                    "sqlAuthorization");
0711:                            usesSqlAuthorization = true;
0712:                        }
0713:                    }
0714:
0715:                    if (SanityManager.DEBUG)
0716:                        SanityManager.ASSERT(
0717:                                (authorizationDatabaseOwner != null),
0718:                                "Failed to get Database Owner authorization");
0719:
0720:                    /* Commit & destroy the create database */
0721:                    bootingTC.commit();
0722:                    cm.getContext(ExecutionContext.CONTEXT_ID).popMe(); // done with ctx
0723:                } finally {
0724:
0725:                    if (bootingTC != null) {
0726:                        bootingTC.destroy(); // gets rid of the transaction context
0727:                        bootingTC = null;
0728:                    }
0729:                    cm.popContext(); // the data dictionary context; check that it is?
0730:                }
0731:
0732:                setDependencyManager();
0733:                booting = false;
0734:            }
0735:
0736:            private CacheManager getPermissionsCache() throws StandardException {
0737:                if (permissionsCache == null) {
0738:                    CacheFactory cf = (CacheFactory) Monitor
0739:                            .startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
0740:                    LanguageConnectionContext lcc = getLCC();
0741:                    TransactionController tc = lcc.getTransactionExecute();
0742:                    permissionsCacheSize = PropertyUtil
0743:                            .getServiceInt(tc,
0744:                                    Property.LANG_PERMISSIONS_CACHE_SIZE, 40, /* min value */
0745:                                    Integer.MAX_VALUE, permissionsCacheSize /* value from boot time. */);
0746:                    permissionsCache = cf.newCacheManager(this ,
0747:                            "PermissionsCache", permissionsCacheSize,
0748:                            permissionsCacheSize);
0749:                }
0750:                return permissionsCache;
0751:            } // end of getPermissionsCache
0752:
0753:            /** 
0754:             * sets the dependencymanager associated with this dd. subclasses can
0755:             * override this to install their own funky dependency manager.
0756:             */
0757:            protected void setDependencyManager() {
0758:                dmgr = new BasicDependencyManager();
0759:            }
0760:
0761:            /**
0762:             * returns the dependencymanager associated with this datadictionary.
0763:             * @see DataDictionary#getDependencyManager
0764:             */
0765:            public DependencyManager getDependencyManager() {
0766:                return dmgr;
0767:            }
0768:
0769:            /**
0770:             * Stop this module.  In this case, nothing needs to be done.
0771:             */
0772:
0773:            public void stop() {
0774:            }
0775:
0776:            /*
0777:             ** CacheableFactory interface
0778:             */
0779:            public Cacheable newCacheable(CacheManager cm) {
0780:
0781:                if (cm == OIDTdCache)
0782:                    return new OIDTDCacheable(this );
0783:                else if (cm == nameTdCache)
0784:                    return new NameTDCacheable(this );
0785:                else if (cm == permissionsCache)
0786:                    return new PermissionsCacheable(this );
0787:                else {
0788:                    return new SPSNameCacheable(this );
0789:                }
0790:            }
0791:
0792:            /*
0793:             ** Methods related to ModuleControl
0794:             */
0795:
0796:            /**
0797:             * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#startReading
0798:             *
0799:             * @exception StandardException		Thrown on error
0800:             */
0801:            public int startReading(LanguageConnectionContext lcc)
0802:                    throws StandardException {
0803:                int bindCount = lcc.incrementBindCount();
0804:                int localCacheMode;
0805:
0806:                boolean needRetry = false;
0807:
0808:                do {
0809:                    if (needRetry) {
0810:                        // could not get lock while holding the synchronized(this),
0811:                        // so now wait until we can get the lock.  Once we get the
0812:                        // lock it is automatically released, hopefully when we 
0813:                        // go the the synchronized(this) block we will be able to
0814:                        // get the lock, while holding the synchronized(this)
0815:                        // monitor now.
0816:
0817:                        try {
0818:                            lockFactory.zeroDurationlockObject(lcc
0819:                                    .getTransactionExecute().getLockObject(),
0820:                                    cacheCoordinator, ShExQual.SH,
0821:                                    C_LockFactory.WAIT_FOREVER);
0822:                        } catch (StandardException e) {
0823:                            // DEADLOCK, timeout will not happen with WAIT_FOREVER
0824:
0825:                            lcc.decrementBindCount();
0826:                            throw e;
0827:                        }
0828:                        needRetry = false;
0829:                    }
0830:
0831:                    // "this" is used to synchronize between startReading,doneReading, 
0832:                    //  and startWriting.
0833:
0834:                    synchronized (this ) {
0835:                        localCacheMode = getCacheMode();
0836:
0837:                        /*
0838:                         ** Keep track of how deeply nested this bind() operation is.
0839:                         ** It's possible for nested binding to happen if the user
0840:                         ** prepares SQL statements from within a static initializer
0841:                         ** of a class, and calls a method on that class (or uses a
0842:                         ** field in the class).
0843:                         **
0844:                         ** If nested binding is happening, we only want to lock the
0845:                         ** DataDictionary on the outermost nesting level.
0846:                         */
0847:                        if (bindCount == 1) {
0848:                            if (localCacheMode == DataDictionary.COMPILE_ONLY_MODE) {
0849:                                if (SanityManager.DEBUG) {
0850:                                    SanityManager
0851:                                            .ASSERT(ddlUsers == 0,
0852:                                                    "Cache mode is COMPILE_ONLY and there are DDL users.");
0853:                                }
0854:
0855:                                /*
0856:                                 ** If we deadlock while waiting for a lock,
0857:                                 ** then be sure to restore things as they
0858:                                 ** were.
0859:                                 */
0860:                                boolean lockGranted = false;
0861:
0862:                                try {
0863:                                    // When the C_LockFactory.NO_WAIT is used this 
0864:                                    // routine will not throw timeout or deadlock 
0865:                                    // exceptions.  The boolean returned will indicate 
0866:                                    // if the lock was granted or not.  If it would 
0867:                                    // have had to wait, it just returns immediately 
0868:                                    // and returns false.
0869:                                    // 
0870:                                    // See if we can get this lock granted without 
0871:                                    // waiting (while holding the dataDictionary 
0872:                                    // synchronization).
0873:
0874:                                    lockGranted = lockFactory.lockObject(lcc
0875:                                            .getTransactionExecute()
0876:                                            .getLockObject(), lcc
0877:                                            .getTransactionExecute()
0878:                                            .getLockObject(), cacheCoordinator,
0879:                                            ShExQual.SH, C_LockFactory.NO_WAIT);
0880:                                } catch (StandardException e) {
0881:                                    // neither TIMEOUT or DEADLOCK can happen with 
0882:                                    // NO_WAIT flag.  This must be some other exception.
0883:
0884:                                    lcc.decrementBindCount();
0885:                                    throw e;
0886:                                }
0887:
0888:                                if (!lockGranted)
0889:                                    needRetry = true;
0890:                            } else {
0891:                                readersInDDLMode++;
0892:                            }
0893:                        }
0894:                    } // end of sync block
0895:
0896:                } while (needRetry);
0897:
0898:                return localCacheMode;
0899:            }
0900:
0901:            /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#doneReading */
0902:            public void doneReading(int mode, LanguageConnectionContext lcc)
0903:                    throws StandardException {
0904:                int bindCount = lcc.decrementBindCount();
0905:
0906:                /* This is an arbitrary choice of object to synchronize these methods */
0907:                synchronized (this ) {
0908:                    /*
0909:                     ** Keep track of how deeply nested this bind() operation is.
0910:                     ** It's possible for nested binding to happen if the user
0911:                     ** prepares SQL statements from within a static initializer
0912:                     ** of a class, and calls a method on that class (or uses a
0913:                     ** field in the class).
0914:                     **
0915:                     ** If nested binding is happening, we only want to unlock the
0916:                     ** DataDictionary on the outermost nesting level.
0917:                     */
0918:                    if (bindCount == 0) {
0919:                        if (mode == DataDictionary.COMPILE_ONLY_MODE) {
0920:                            /*
0921:                             ** Release the share lock that was acquired by the reader when
0922:                             ** it called startReading().
0923:                             ** Beetle 4418, during bind, we may even execute something (eg., in a vti
0924:                             ** constructor) and if a severe error occured, the transaction is rolled
0925:                             ** back and lock released already, so don't try to unlock if statement context
0926:                             ** is cleared.
0927:                             */
0928:                            if ((lcc.getStatementContext() != null)
0929:                                    && lcc.getStatementContext().inUse()) {
0930:                                int unlockCount = lockFactory.unlock(lcc
0931:                                        .getTransactionExecute()
0932:                                        .getLockObject(), lcc
0933:                                        .getTransactionExecute()
0934:                                        .getLockObject(), cacheCoordinator,
0935:                                        ShExQual.SH);
0936:                                if (SanityManager.DEBUG) {
0937:                                    if (unlockCount != 1) {
0938:                                        SanityManager
0939:                                                .THROWASSERT("unlockCount not "
0940:                                                        + "1 as expected, it is "
0941:                                                        + unlockCount);
0942:                                    }
0943:                                }
0944:                            }
0945:                        } else {
0946:                            readersInDDLMode--;
0947:
0948:                            /*
0949:                             ** We can only switch back to cached (COMPILE_ONLY)
0950:                             ** mode if there aren't any readers that started in
0951:                             ** DDL_MODE.  Otherwise we could get a reader
0952:                             ** in DDL_MODE that reads a cached object that
0953:                             ** was brought in by a reader in COMPILE_ONLY_MODE.
0954:                             ** If 2nd reader finished and releases it lock
0955:                             ** on the cache there is nothing to pevent another
0956:                             ** writer from coming along an deleting the cached
0957:                             ** object.
0958:                             */
0959:                            if (ddlUsers == 0 && readersInDDLMode == 0) {
0960:                                clearCaches();
0961:                                setCacheMode(DataDictionary.COMPILE_ONLY_MODE);
0962:                            }
0963:
0964:                            if (SanityManager.DEBUG) {
0965:                                SanityManager
0966:                                        .ASSERT(readersInDDLMode >= 0,
0967:                                                "readersInDDLMode is invalid -- should never be < 0");
0968:                            }
0969:                        }
0970:                    }
0971:                }
0972:            }
0973:
0974:            /*
0975:             * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#startWriting
0976:             *
0977:             * @exception StandardException		Thrown on error
0978:             */
0979:            public void startWriting(LanguageConnectionContext lcc)
0980:                    throws StandardException {
0981:
0982:                boolean blocked = true;
0983:
0984:                /*
0985:                 ** Don't allow DDL if we're binding a SQL statement.
0986:                 */
0987:                if (lcc.getBindCount() != 0) {
0988:                    throw StandardException
0989:                            .newException(SQLState.LANG_DDL_IN_BIND);
0990:                }
0991:
0992:                /*
0993:                 ** Check whether we've already done a DDL statement in this
0994:                 ** transaction.  If so, we don't want to re-enter DDL mode, or
0995:                 ** bump the DDL user count.
0996:                 */
0997:                if (!lcc.dataDictionaryInWriteMode()) {
0998:                    for (int i = 0; blocked; i++) {
0999:                        /*
1000:                         ** If we already tried 5 times and failed, do
1001:                         ** an unbounded wait for the lock w/o
1002:                         ** synchronization.  Immediately unlock and
1003:                         ** sleep a random amount of time and start
1004:                         ** the whole process over again.
1005:                         */
1006:                        if (i > 4
1007:                                && getCacheMode() == DataDictionary.COMPILE_ONLY_MODE) {
1008:                            // Wait until the settable timeout value for the lock,
1009:                            // and once granted, immediately release the lock.  If
1010:                            // this wait time's out then a TIMEOUT error is sent
1011:                            // up the stack.
1012:
1013:                            lockFactory.zeroDurationlockObject(lcc
1014:                                    .getTransactionExecute().getLockObject(),
1015:                                    cacheCoordinator, ShExQual.EX,
1016:                                    C_LockFactory.TIMED_WAIT);
1017:
1018:                            i = 1;
1019:                        }
1020:
1021:                        if (i > 0) {
1022:                            try {
1023:                                Thread
1024:                                        .sleep((long) ((java.lang.Math.random() * 1131) % 20));
1025:                            } catch (InterruptedException ie) {
1026:                                throw StandardException.interrupt(ie);
1027:                            }
1028:                        }
1029:
1030:                        synchronized (this ) {
1031:                            if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE) {
1032:                                // When the C_LockFactory.NO_WAIT is used this routine 
1033:                                // will not throw timeout or deadlock exceptions.  The 
1034:                                // boolean returned will indicate if the lock was 
1035:                                // granted or not.  If it would have had to wait, it 
1036:                                // just returns immediately and returns false.
1037:                                // 
1038:
1039:                                // See if we can get this lock granted without waiting
1040:                                // (while holding the dataDictionary synchronization).
1041:
1042:                                boolean lockGranted = lockFactory
1043:                                        .zeroDurationlockObject(lcc
1044:                                                .getTransactionExecute()
1045:                                                .getLockObject(),
1046:                                                cacheCoordinator, ShExQual.EX,
1047:                                                C_LockFactory.NO_WAIT);
1048:
1049:                                if (!lockGranted)
1050:                                    continue;
1051:
1052:                                /* Switch the caching mode to DDL */
1053:                                setCacheMode(DataDictionary.DDL_MODE);
1054:
1055:                                /* Clear out all the caches */
1056:                                clearCaches();
1057:                            }
1058:
1059:                            /* Keep track of the number of DDL users */
1060:                            ddlUsers++;
1061:                        } // end synchronized	
1062:
1063:                        /*
1064:                         ** Tell the connection the DD is in DDL mode, so it can take
1065:                         ** it out of DDL mode when the transaction finishes.
1066:                         */
1067:                        lcc.setDataDictionaryWriteMode();
1068:                        blocked = false;
1069:                    }
1070:
1071:                } else if (SanityManager.DEBUG) {
1072:                    SanityManager
1073:                            .ASSERT(getCacheMode() == DataDictionary.DDL_MODE,
1074:                                    "lcc.getDictionaryInWriteMode() but DataDictionary is COMPILE_MODE");
1075:                }
1076:            }
1077:
1078:            /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#transactionFinished */
1079:            public void transactionFinished() throws StandardException {
1080:                /* This is an arbitrary choice of object to synchronize these methods */
1081:                synchronized (this ) {
1082:                    if (SanityManager.DEBUG) {
1083:                        SanityManager
1084:                                .ASSERT(ddlUsers > 0,
1085:                                        "Number of DDL Users is <= 0 when finishing a transaction");
1086:
1087:                        SanityManager
1088:                                .ASSERT(
1089:                                        getCacheMode() == DataDictionary.DDL_MODE,
1090:                                        "transactionFinished called when not in DDL_MODE");
1091:                    }
1092:
1093:                    ddlUsers--;
1094:
1095:                    /*
1096:                     ** We can only switch back to cached (COMPILE_ONLY)
1097:                     ** mode if there aren't any readers that started in
1098:                     ** DDL_MODE.  Otherwise we could get a reader
1099:                     ** in DDL_MODE that reads a cached object that
1100:                     ** was brought in by a reader in COMPILE_ONLY_MODE.
1101:                     ** If 2nd reader finished and releases it lock
1102:                     ** on the cache there is nothing to pevent another
1103:                     ** writer from coming along an deleting the cached
1104:                     ** object.
1105:                     */
1106:                    if (ddlUsers == 0 && readersInDDLMode == 0) {
1107:                        clearCaches();
1108:                        setCacheMode(DataDictionary.COMPILE_ONLY_MODE);
1109:                    }
1110:
1111:                }
1112:            }
1113:
1114:            /*
1115:             ** SYNCHRONIZATION: no synchronization
1116:             ** necessary since integer reads/writes
1117:             ** are atomic
1118:             */
1119:            public int getCacheMode() {
1120:                return cacheMode;
1121:            }
1122:
1123:            /*
1124:             ** SYNCHRONIZATION: no synchronization
1125:             ** necessary since integer reads/writes
1126:             ** are atomic
1127:             */
1128:            private void setCacheMode(int newMode) {
1129:                cacheMode = newMode;
1130:            }
1131:
1132:            /**
1133:             * Get a DataDescriptorGenerator, through which we can create
1134:             * objects to be stored in the DataDictionary.
1135:             *
1136:             * @return	A DataDescriptorGenerator
1137:             */
1138:
1139:            public DataDescriptorGenerator getDataDescriptorGenerator() {
1140:                return dataDescriptorGenerator;
1141:            }
1142:
1143:            /**
1144:             * Get authorizationID of Database Owner
1145:             *
1146:             * @return	authorizationID
1147:             */
1148:            public String getAuthorizationDatabaseOwner() {
1149:                return authorizationDatabaseOwner;
1150:            }
1151:
1152:            /**
1153:             * @see DataDictionary#usesSqlAuthorization
1154:             */
1155:            public boolean usesSqlAuthorization() {
1156:                return usesSqlAuthorization;
1157:            }
1158:
1159:            /**
1160:             * Get a DataValueFactory, through which we can create
1161:             * data value objects.
1162:             *
1163:             * @return	A DataValueFactory
1164:             */
1165:            public DataValueFactory getDataValueFactory() {
1166:                return dvf;
1167:            }
1168:
1169:            /**
1170:             * Get ExecutionFactory associated with this database.
1171:             *
1172:             * @return	The ExecutionFactory
1173:             */
1174:            public ExecutionFactory getExecutionFactory() {
1175:                return exFactory;
1176:            }
1177:
1178:            /**
1179:             * @see DataDictionary#pushDataDictionaryContext
1180:             */
1181:            public DataDictionaryContext pushDataDictionaryContext(
1182:                    ContextManager contextManager) {
1183:                DataDictionaryContextImpl dataDictionaryContextImpl = new DataDictionaryContextImpl(
1184:                        contextManager, this );
1185:
1186:                return dataDictionaryContextImpl;
1187:            }
1188:
1189:            /* We defer getting the builtin schemas (system and default) past boot time so that
1190:             * the language connection context will be available.
1191:             */
1192:            private void getBuiltinSchemaNames() throws StandardException {
1193:                if (builtinSchemasAreFromLCC)
1194:                    return;
1195:
1196:                LanguageConnectionContext lcc = getLCC();
1197:                if (null == lcc) {
1198:                    systemSchemaName = SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME;
1199:                    sysIBMSchemaName = SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME;
1200:
1201:                    systemDiagSchemaName = SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME;
1202:                    systemUtilSchemaName = SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME;
1203:                    declaredGlobalTemporaryTablesSchemaName = SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME;
1204:                } else {
1205:                    systemSchemaName = lcc.getSystemSchemaName();
1206:                    sysIBMSchemaName = lcc.getSysIBMSchemaName();
1207:                    systemDiagSchemaName = lcc.getSystemDiagSchemaName();
1208:                    systemUtilSchemaName = lcc.getSystemUtilSchemaName();
1209:                    declaredGlobalTemporaryTablesSchemaName = lcc
1210:                            .getDeclaredGlobalTemporaryTablesSchemaName();
1211:
1212:                    builtinSchemasAreFromLCC = true;
1213:                }
1214:            }
1215:
1216:            private void getBuiltinSchemas() throws StandardException {
1217:                if (builtinSchemasAreFromLCC && null != systemSchemaDesc
1218:                        && null != sysIBMSchemaDesc
1219:                        && null != systemDiagSchemaDesc
1220:                        && null != systemUtilSchemaDesc
1221:                        && null != declaredGlobalTemporaryTablesSchemaDesc)
1222:                    return;
1223:
1224:                getBuiltinSchemaNames();
1225:
1226:                systemSchemaDesc = newSystemSchemaDesc(systemSchemaName,
1227:                        SchemaDescriptor.SYSTEM_SCHEMA_UUID);
1228:                sysIBMSchemaDesc = newSystemSchemaDesc(sysIBMSchemaName,
1229:                        SchemaDescriptor.SYSIBM_SCHEMA_UUID);
1230:                systemDiagSchemaDesc = newSystemSchemaDesc(
1231:                        systemDiagSchemaName,
1232:                        SchemaDescriptor.SYSCS_DIAG_SCHEMA_UUID);
1233:                systemUtilSchemaDesc = newSystemSchemaDesc(
1234:                        systemUtilSchemaName,
1235:                        SchemaDescriptor.SYSCS_UTIL_SCHEMA_UUID);
1236:
1237:                declaredGlobalTemporaryTablesSchemaDesc = newDeclaredGlobalTemporaryTablesSchemaDesc(declaredGlobalTemporaryTablesSchemaName);
1238:            }
1239:
1240:            /**
1241:             * Get the descriptor for the system schema. Schema descriptors include 
1242:             * authorization ids and schema ids.
1243:             *
1244:             * SQL92 allows a schema to specify a default character set - we will
1245:             * not support this.
1246:             *
1247:             * @return	The descriptor for the schema.
1248:             *
1249:             * @exception StandardException		Thrown on failure
1250:             */
1251:            public SchemaDescriptor getSystemSchemaDescriptor()
1252:                    throws StandardException {
1253:                getBuiltinSchemas();
1254:                return systemSchemaDesc;
1255:            }
1256:
1257:            /**
1258:             * Get the descriptor for the SYSCS_UTIL system schema. 
1259:             * Schema descriptors include authorization ids and schema ids.
1260:             *
1261:             * SQL92 allows a schema to specify a default character set - we will
1262:             * not support this.
1263:             *
1264:             * @return	The descriptor for the schema.
1265:             *
1266:             * @exception StandardException		Thrown on failure
1267:             */
1268:            public SchemaDescriptor getSystemUtilSchemaDescriptor()
1269:                    throws StandardException {
1270:                getBuiltinSchemas();
1271:                return (systemUtilSchemaDesc);
1272:            }
1273:
1274:            /**
1275:             * Get the descriptor for the SYSCS_DIAG system schema. 
1276:             * Schema descriptors include authorization ids and schema ids.
1277:             *
1278:             * SQL92 allows a schema to specify a default character set - we will
1279:             * not support this.
1280:             *
1281:             * @return	The descriptor for the schema.
1282:             *
1283:             * @exception StandardException		Thrown on failure
1284:             */
1285:            public SchemaDescriptor getSystemDiagSchemaDescriptor()
1286:                    throws StandardException {
1287:                getBuiltinSchemas();
1288:                return (systemDiagSchemaDesc);
1289:            }
1290:
1291:            /**
1292:             * Get the descriptor for the SYSIBM schema. Schema descriptors include 
1293:             * authorization ids and schema ids.
1294:             *
1295:             * SQL92 allows a schema to specify a default character set - we will
1296:             * not support this.
1297:             *
1298:             * @return	The descriptor for the schema.
1299:             *
1300:             * @exception StandardException		Thrown on failure
1301:             */
1302:            public SchemaDescriptor getSysIBMSchemaDescriptor()
1303:                    throws StandardException {
1304:                getBuiltinSchemas();
1305:                return sysIBMSchemaDesc;
1306:            }
1307:
1308:            /**
1309:             * Get the descriptor for the declared global temporary table schema which 
1310:             * is always named "SESSION".
1311:             *
1312:             * @return	The descriptor for the schema.
1313:             *
1314:             * @exception StandardException		Thrown on failure
1315:             */
1316:            public SchemaDescriptor getDeclaredGlobalTemporaryTablesSchemaDescriptor()
1317:                    throws StandardException {
1318:                getBuiltinSchemas();
1319:                return declaredGlobalTemporaryTablesSchemaDesc;
1320:            }
1321:
1322:            /**
1323:             * Determine whether a string is the name of the system schema.
1324:             *
1325:             * @param name
1326:             * @return	true or false
1327:             *
1328:             * @exception StandardException		Thrown on failure
1329:             */
1330:            public boolean isSystemSchemaName(String name)
1331:                    throws StandardException {
1332:                getBuiltinSchemaNames();
1333:
1334:                boolean ret_val = false;
1335:
1336:                for (int i = systemSchemaNames.length - 1; i >= 0;) {
1337:                    if ((ret_val = systemSchemaNames[i--].equals(name)))
1338:                        break;
1339:                }
1340:
1341:                return (ret_val);
1342:            }
1343:
1344:            /**
1345:             * Get the descriptor for the named schema.
1346:             * Schema descriptors include authorization ids and schema ids.
1347:             * SQL92 allows a schema to specify a default character set - we will
1348:             * not support this.  Will check default schema for a match
1349:             * before scanning a system table.
1350:             * 
1351:             * @param schemaName	The name of the schema we're interested in. Must not be null.
1352:             * @param tc			TransactionController
1353:             *
1354:             * @param raiseError    whether an exception should be thrown if the schema does not exist.
1355:             *
1356:             * @return	The descriptor for the schema. Can be null (not found) if raiseError is false.
1357:             *
1358:             * @exception StandardException		Thrown on error
1359:             */
1360:            public SchemaDescriptor getSchemaDescriptor(String schemaName,
1361:                    TransactionController tc, boolean raiseError)
1362:                    throws StandardException {
1363:                /*
1364:                 ** Check for APP and SYS schemas before going any
1365:                 ** further.
1366:                 */
1367:
1368:                if (tc == null) {
1369:                    tc = getTransactionCompile();
1370:                }
1371:
1372:                if (getSystemSchemaDescriptor().getSchemaName().equals(
1373:                        schemaName)) {
1374:                    return getSystemSchemaDescriptor();
1375:                } else if (getSysIBMSchemaDescriptor().getSchemaName().equals(
1376:                        schemaName)) {
1377:                    // oh you are really asking SYSIBM, if this db is soft upgraded 
1378:                    // from pre 52, I may have 2 versions for you, one on disk 
1379:                    // (user SYSIBM), one imaginary (builtin). The
1380:                    // one on disk (real one, if it exists), should always be used.
1381:                    if (dictionaryVersion.checkVersion(
1382:                            DataDictionary.DD_VERSION_CS_5_2, null)) {
1383:                        return getSysIBMSchemaDescriptor();
1384:                    }
1385:                }
1386:
1387:                /*
1388:                 ** Manual lookup
1389:                 */
1390:                SchemaDescriptor sd = locateSchemaRow(schemaName, tc);
1391:
1392:                //if no schema found and schema name is SESSION, then create an 
1393:                //in-memory schema descriptor
1394:                if (sd == null
1395:                        && getDeclaredGlobalTemporaryTablesSchemaDescriptor()
1396:                                .getSchemaName().equals(schemaName)) {
1397:                    return getDeclaredGlobalTemporaryTablesSchemaDescriptor();
1398:                }
1399:
1400:                if (sd == null && raiseError) {
1401:                    throw StandardException.newException(
1402:                            SQLState.LANG_SCHEMA_DOES_NOT_EXIST, schemaName);
1403:                } else {
1404:                    return sd;
1405:                }
1406:            }
1407:
1408:            /**
1409:             * Get the target schema by searching for a matching row
1410:             * in SYSSCHEMAS by schemaId.  Read only scan.
1411:             * 
1412:             * @param schemaId		The id of the schema we're interested in.
1413:             *						If non-null, overrides schemaName
1414:             * 
1415:             * @param tc			TransactionController.  If null, one
1416:             *						is gotten off of the language connection context.
1417:             *
1418:             * @return	The row for the schema
1419:             *
1420:             * @exception StandardException		Thrown on error
1421:             */
1422:            private SchemaDescriptor locateSchemaRow(UUID schemaId,
1423:                    TransactionController tc) throws StandardException {
1424:                DataValueDescriptor UUIDStringOrderable;
1425:                TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1426:
1427:                /* Use UUIDStringOrderable in both start and stop positions for scan */
1428:                UUIDStringOrderable = dvf.getCharDataValue(schemaId.toString());
1429:
1430:                /* Set up the start/stop position for the scan */
1431:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1432:                keyRow.setColumn(1, UUIDStringOrderable);
1433:
1434:                return (SchemaDescriptor) getDescriptorViaIndex(
1435:                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX2_ID, keyRow,
1436:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
1437:                        (List) null, false);
1438:            }
1439:
1440:            /**
1441:             * Get the target schema by searching for a matching row
1442:             * in SYSSCHEMAS by schema name.  Read only scan.
1443:             * 
1444:             * @param schemaName	The name of the schema we're interested in.
1445:             *						If schemaId is null, used to qual.
1446:             *
1447:             * @param tc			TransactionController.  If null, one
1448:             *						is gotten off of the language connection context.
1449:             *
1450:             * @return	The row for the schema
1451:             *
1452:             * @exception StandardException		Thrown on error
1453:             */
1454:            private SchemaDescriptor locateSchemaRow(String schemaName,
1455:                    TransactionController tc) throws StandardException {
1456:                DataValueDescriptor schemaNameOrderable;
1457:                TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1458:
1459:                /* Use aliasNameOrderable in both start 
1460:                 * and stop position for scan. 
1461:                 */
1462:                schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
1463:
1464:                /* Set up the start/stop position for the scan */
1465:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1466:                keyRow.setColumn(1, schemaNameOrderable);
1467:
1468:                return (SchemaDescriptor) getDescriptorViaIndex(
1469:                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID, keyRow,
1470:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
1471:                        (List) null, false);
1472:            }
1473:
1474:            /**
1475:             * Get the descriptor for the named schema. If the schemaId
1476:             * parameter is NULL, it gets the descriptor for the current (default)
1477:             * schema. Schema descriptors include authorization ids and schema ids.
1478:             * SQL92 allows a schema to specify a default character set - we will
1479:             * not support this.  Will check default schema for a match
1480:             * before scanning a system table.
1481:             * 
1482:             * @param schemaId	The id of the schema we're interested in.
1483:             *			If the name is NULL, get the descriptor for the
1484:             *			current schema.
1485:             * @param tc			TransactionController
1486:             *
1487:             *
1488:             * @return	The descriptor for the schema.  <I> Warning: <\I> may
1489:             * 			return NULL if schemaName is non-NULL and doesn't exist
1490:             *			in SYSSCHEMAS
1491:             *
1492:             * @exception StandardException		Thrown on error
1493:             */
1494:            public SchemaDescriptor getSchemaDescriptor(UUID schemaId,
1495:                    TransactionController tc) throws StandardException {
1496:                SchemaDescriptor sd = null;
1497:
1498:                if (tc == null) {
1499:                    tc = getTransactionCompile();
1500:                }
1501:
1502:                /*
1503:                 ** Check for APP and SYS schemas before going any
1504:                 ** further.
1505:                 */
1506:                if (schemaId != null) {
1507:                    if (getSystemSchemaDescriptor().getUUID().equals(schemaId)) {
1508:                        return getSystemSchemaDescriptor();
1509:                    } else if (getSysIBMSchemaDescriptor().getUUID().equals(
1510:                            schemaId)) {
1511:                        return getSysIBMSchemaDescriptor();
1512:                    }
1513:                }
1514:
1515:                /*
1516:                 ** If we aren't booting, lets see if we already
1517:                 ** have the descriptor.  If we are in the middle
1518:                 ** of booting we cannot get the LanguageConnectionContext.
1519:                 */
1520:                if (!booting) {
1521:
1522:                    LanguageConnectionContext lcc = getLCC();
1523:
1524:                    if (lcc != null) {
1525:                        sd = lcc.getDefaultSchema();
1526:
1527:                        if ((sd != null)
1528:                                && ((schemaId == null) || schemaId.equals(sd
1529:                                        .getUUID()))) {
1530:                            return sd;
1531:                        }
1532:                    }
1533:                }
1534:
1535:                return locateSchemaRow(schemaId, tc);
1536:            }
1537:
1538:            /** 
1539:             * @see DataDictionary#addDescriptor
1540:             */
1541:            public void addDescriptor(TupleDescriptor td,
1542:                    TupleDescriptor parent, int catalogNumber,
1543:                    boolean duplicatesAllowed, TransactionController tc)
1544:                    throws StandardException {
1545:                addDescriptor(td, parent, catalogNumber, duplicatesAllowed, tc,
1546:                        true);
1547:            }
1548:
1549:            /**
1550:             * @inheritDoc
1551:             */
1552:            public void addDescriptor(TupleDescriptor td,
1553:                    TupleDescriptor parent, int catalogNumber,
1554:                    boolean duplicatesAllowed, TransactionController tc,
1555:                    boolean wait) throws StandardException {
1556:                TabInfoImpl ti = (catalogNumber < NUM_CORE) ? coreInfo[catalogNumber]
1557:                        : getNonCoreTI(catalogNumber);
1558:
1559:                ExecRow row = ti.getCatalogRowFactory().makeRow(td, parent);
1560:
1561:                int insertRetCode = ti.insertRow(row, tc, wait);
1562:
1563:                if (!duplicatesAllowed) {
1564:                    if (insertRetCode != TabInfoImpl.ROWNOTDUPLICATE)
1565:                        throw duplicateDescriptorException(td, parent);
1566:                }
1567:            }
1568:
1569:            private StandardException duplicateDescriptorException(
1570:                    TupleDescriptor tuple, TupleDescriptor parent) {
1571:                if (parent != null)
1572:                    return StandardException.newException(
1573:                            SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
1574:                            tuple.getDescriptorType(), tuple
1575:                                    .getDescriptorName(), parent
1576:                                    .getDescriptorType(), parent
1577:                                    .getDescriptorName());
1578:
1579:                else
1580:                    return StandardException.newException(
1581:                            SQLState.LANG_OBJECT_ALREADY_EXISTS, tuple
1582:                                    .getDescriptorType(), tuple
1583:                                    .getDescriptorName());
1584:            }
1585:
1586:            /** array version of addDescriptor.
1587:             * @see DataDictionary#addDescriptor
1588:             */
1589:            public void addDescriptorArray(TupleDescriptor[] td,
1590:                    TupleDescriptor parent, int catalogNumber,
1591:                    boolean allowDuplicates, TransactionController tc)
1592:                    throws StandardException {
1593:                TabInfoImpl ti = (catalogNumber < NUM_CORE) ? coreInfo[catalogNumber]
1594:                        : getNonCoreTI(catalogNumber);
1595:                CatalogRowFactory crf = ti.getCatalogRowFactory();
1596:
1597:                ExecRow[] rl = new ExecRow[td.length];
1598:
1599:                for (int index = 0; index < td.length; index++) {
1600:                    ExecRow row = crf.makeRow(td[index], parent);
1601:                    rl[index] = row;
1602:                }
1603:
1604:                int insertRetCode = ti.insertRowList(rl, tc);
1605:                if (!allowDuplicates
1606:                        && insertRetCode != TabInfoImpl.ROWNOTDUPLICATE) {
1607:                    throw duplicateDescriptorException(td[insertRetCode],
1608:                            parent);
1609:                }
1610:            }
1611:
1612:            /**
1613:             * Drop the descriptor for a schema, given the schema's name
1614:             *
1615:             * @param schemaName	The name of the schema to drop
1616:             * @param tc			TransactionController for the transaction
1617:             *
1618:             * @exception StandardException		Thrown on error
1619:             */
1620:            public void dropSchemaDescriptor(String schemaName,
1621:                    TransactionController tc) throws StandardException {
1622:                ExecIndexRow keyRow1 = null;
1623:                DataValueDescriptor schemaNameOrderable;
1624:                TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1625:
1626:                if (SanityManager.DEBUG) {
1627:                    SchemaDescriptor sd = getSchemaDescriptor(schemaName,
1628:                            getTransactionCompile(), true);
1629:                    if (!isSchemaEmpty(sd)) {
1630:                        SanityManager.THROWASSERT("Attempt to drop schema "
1631:                                + schemaName + " that is not empty");
1632:                    }
1633:                }
1634:
1635:                /* Use schemaNameOrderable in both start 
1636:                 * and stop position for index 1 scan. 
1637:                 */
1638:                schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
1639:
1640:                /* Set up the start/stop position for the scan */
1641:                keyRow1 = exFactory.getIndexableRow(1);
1642:                keyRow1.setColumn(1, schemaNameOrderable);
1643:
1644:                ti.deleteRow(tc, keyRow1,
1645:                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID);
1646:            }
1647:
1648:            /**
1649:             * Get the descriptor for the named table within the given schema.
1650:             * If the schema parameter is NULL, it looks for the table in the
1651:             * current (default) schema. Table descriptors include object ids,
1652:             * object types (table, view, etc.)
1653:             *
1654:             * @param tableName	The name of the table to get the descriptor for
1655:             * @param schema	The descriptor for the schema the table lives in.
1656:             *			If null, use the system schema.
1657:             *
1658:             * @return	The descriptor for the table, null if table does not
1659:             *		exist.
1660:             *
1661:             * @exception StandardException		Thrown on failure
1662:             */
1663:            public TableDescriptor getTableDescriptor(String tableName,
1664:                    SchemaDescriptor schema) throws StandardException {
1665:                TableDescriptor retval = null;
1666:
1667:                /*
1668:                 ** If we didn't get a schema descriptor, we had better
1669:                 ** have a system table.
1670:                 */
1671:                if (SanityManager.DEBUG) {
1672:                    if ((schema == null) && !tableName.startsWith("SYS")) {
1673:                        SanityManager
1674:                                .THROWASSERT("null schema for non system table "
1675:                                        + tableName);
1676:                    }
1677:                }
1678:
1679:                SchemaDescriptor sd = (schema == null) ? getSystemSchemaDescriptor()
1680:                        : schema;
1681:
1682:                UUID schemaUUID = sd.getUUID();
1683:
1684:                if (SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME.equals(sd
1685:                        .getSchemaName())) {
1686:                    TableDescriptor td = new TableDescriptor(this , tableName,
1687:                            sd, TableDescriptor.VTI_TYPE,
1688:                            TableDescriptor.DEFAULT_LOCK_GRANULARITY);
1689:
1690:                    // ensure a vti class exists
1691:                    if (getVTIClass(td) != null)
1692:                        return td;
1693:
1694:                    // otherwise just standard search
1695:                }
1696:
1697:                TableKey tableKey = new TableKey(schemaUUID, tableName);
1698:
1699:                /* Only use the cache if we're in compile-only mode */
1700:                if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE) {
1701:                    NameTDCacheable cacheEntry = (NameTDCacheable) nameTdCache
1702:                            .find(tableKey);
1703:                    if (cacheEntry != null) {
1704:                        retval = cacheEntry.getTableDescriptor();
1705:                        // bind in previous command might have set refernced cols
1706:                        retval.setReferencedColumnMap(null);
1707:                        nameTdCache.release(cacheEntry);
1708:                    }
1709:                    return retval;
1710:                }
1711:
1712:                return getTableDescriptorIndex1Scan(tableName, schemaUUID
1713:                        .toString());
1714:
1715:            }
1716:
1717:            /**
1718:             * Scan systables_index1 (tablename, schemaid) for a match.
1719:             *
1720:             * @return TableDescriptor	The matching descriptor, if any.
1721:             *
1722:             * @exception StandardException		Thrown on failure
1723:             */
1724:            private TableDescriptor getTableDescriptorIndex1Scan(
1725:                    String tableName, String schemaUUID)
1726:                    throws StandardException {
1727:                DataValueDescriptor schemaIDOrderable;
1728:                DataValueDescriptor tableNameOrderable;
1729:                TableDescriptor td;
1730:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
1731:
1732:                /* Use tableNameOrderable and schemaIdOrderable in both start 
1733:                 * and stop position for scan. 
1734:                 */
1735:                tableNameOrderable = dvf.getVarcharDataValue(tableName);
1736:                schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
1737:
1738:                /* Set up the start/stop position for the scan */
1739:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
1740:                keyRow.setColumn(1, tableNameOrderable);
1741:                keyRow.setColumn(2, schemaIDOrderable);
1742:
1743:                td = (TableDescriptor) getDescriptorViaIndex(
1744:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID, keyRow,
1745:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
1746:                        (List) null, false);
1747:
1748:                return finishTableDescriptor(td);
1749:            }
1750:
1751:            /**
1752:             * This method can get called from the DataDictionary cache.
1753:             *
1754:             * @param tableKey	The TableKey of the table
1755:             *
1756:             * @return	The descriptor for the table, null if the table does
1757:             *		not exist.
1758:             *
1759:             * @exception StandardException		Thrown on failure
1760:             */
1761:            TableDescriptor getUncachedTableDescriptor(TableKey tableKey)
1762:                    throws StandardException {
1763:                return getTableDescriptorIndex1Scan(tableKey.getTableName(),
1764:                        tableKey.getSchemaId().toString());
1765:            }
1766:
1767:            /**
1768:             * Get the descriptor for the table with the given UUID.
1769:             *
1770:             * NOTE: I'm assuming that the object store will define an UUID for
1771:             * persistent objects. I'm also assuming that UUIDs are unique across
1772:             * schemas, and that the object store will be able to do efficient
1773:             * lookups across schemas (i.e. that no schema descriptor parameter
1774:             * is needed).
1775:             *
1776:             * @param tableID	The UUID of the table to get the descriptor for
1777:             *
1778:             * @return	The descriptor for the table, null if the table does
1779:             *		not exist.
1780:             *
1781:             * @exception StandardException		Thrown on failure
1782:             */
1783:            public TableDescriptor getTableDescriptor(UUID tableID)
1784:                    throws StandardException {
1785:                OIDTDCacheable cacheEntry;
1786:                TableDescriptor retval = null;
1787:
1788:                /* Only use the cache if we're in compile-only mode */
1789:                if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE) {
1790:                    cacheEntry = (OIDTDCacheable) OIDTdCache.find(tableID);
1791:                    if (cacheEntry != null) {
1792:                        retval = cacheEntry.getTableDescriptor();
1793:                        // bind in previous command might have set refernced cols
1794:                        retval.setReferencedColumnMap(null);
1795:                        OIDTdCache.release(cacheEntry);
1796:                    }
1797:
1798:                    return retval;
1799:
1800:                }
1801:
1802:                return getTableDescriptorIndex2Scan(tableID.toString());
1803:            }
1804:
1805:            /**
1806:             * This method can get called from the DataDictionary cache.
1807:             *
1808:             * @param tableID	The UUID of the table to get the descriptor for
1809:             *
1810:             * @return	The descriptor for the table, null if the table does
1811:             *		not exist.
1812:             *
1813:             * @exception StandardException		Thrown on failure
1814:             */
1815:            protected TableDescriptor getUncachedTableDescriptor(UUID tableID)
1816:                    throws StandardException {
1817:                return getTableDescriptorIndex2Scan(tableID.toString());
1818:            }
1819:
1820:            /**
1821:             * Scan systables_index2 (tableid) for a match.
1822:             *
1823:             * @return TableDescriptor	The matching descriptor, if any.
1824:             *
1825:             * @exception StandardException		Thrown on failure
1826:             */
1827:            private TableDescriptor getTableDescriptorIndex2Scan(
1828:                    String tableUUID) throws StandardException {
1829:                DataValueDescriptor tableIDOrderable;
1830:                TableDescriptor td;
1831:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
1832:
1833:                /* Use tableNameOrderable and schemaIdOrderable in both start 
1834:                 * and stop position for scan. 
1835:                 */
1836:                tableIDOrderable = dvf.getCharDataValue(tableUUID);
1837:
1838:                /* Set up the start/stop position for the scan */
1839:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1840:                keyRow.setColumn(1, tableIDOrderable);
1841:
1842:                td = (TableDescriptor) getDescriptorViaIndex(
1843:                        SYSTABLESRowFactory.SYSTABLES_INDEX2_ID, keyRow,
1844:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
1845:                        (List) null, false);
1846:
1847:                return finishTableDescriptor(td);
1848:            }
1849:
1850:            /**
1851:             * Finish filling in the TableDescriptor.
1852:             * (Build the various lists that hang off the TD.)
1853:             *
1854:             * @param td	The TableDescriptor.
1855:             *
1856:             * @return The completed TableDescriptor.
1857:             *
1858:             * @exception StandardException		Thrown on failure
1859:             */
1860:            private TableDescriptor finishTableDescriptor(TableDescriptor td)
1861:                    throws StandardException {
1862:
1863:                if (td != null) {
1864:                    synchronized (td) {
1865:                        getColumnDescriptorsScan(td);
1866:                        getConglomerateDescriptorsScan(td);
1867:                    }
1868:                }
1869:
1870:                return td;
1871:            }
1872:
1873:            /**
1874:             * Indicate whether there is anything in the 
1875:             * particular schema.  Checks for tables in the
1876:             * the schema, on the assumption that there cannot
1877:             * be any other objects in a schema w/o a table.
1878:             *
1879:             * @param sd descriptor
1880:             *
1881:             * @return true/false
1882:             *
1883:             * @exception StandardException on error
1884:             */
1885:            public boolean isSchemaEmpty(SchemaDescriptor sd)
1886:                    throws StandardException {
1887:                DataValueDescriptor schemaIdOrderable;
1888:                TransactionController tc = getTransactionCompile();
1889:
1890:                schemaIdOrderable = getValueAsDVD(sd.getUUID());
1891:
1892:                if (isSchemaReferenced(tc, coreInfo[SYSTABLES_CORE_NUM],
1893:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
1894:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_SCHEMAID,
1895:                        schemaIdOrderable)) {
1896:                    return false;
1897:                }
1898:
1899:                if (isSchemaReferenced(tc,
1900:                        getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM),
1901:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID, 2,
1902:                        schemaIdOrderable)) {
1903:                    return false;
1904:                }
1905:
1906:                if (isSchemaReferenced(tc,
1907:                        getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM),
1908:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX2_ID, 2,
1909:                        schemaIdOrderable)) {
1910:                    return false;
1911:                }
1912:
1913:                if (isSchemaReferenced(tc,
1914:                        getNonCoreTI(SYSTRIGGERS_CATALOG_NUM),
1915:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX2_ID, 2,
1916:                        schemaIdOrderable)) {
1917:                    return false;
1918:                }
1919:
1920:                return true;
1921:            }
1922:
1923:            /**
1924:             * Is the schema id referenced by the system table in question?
1925:             * Currently assumes that the schema id is in an index.
1926:             * NOTE: could be generalized a bit, and possibly used
1927:             * elsewhere...
1928:             *
1929:             * @param tc	transaction controller
1930:             * @param ti	table info for the system table
1931:             * @param indexId	index id
1932:             * @param indexCol	1 based index column
1933:             * @param schemaIdOrderable	the schemaid in a char orderable
1934:             *
1935:             * @return true if there is a reference to this schema
1936:             *
1937:             * @exception StandardException on error
1938:             */
1939:            protected boolean isSchemaReferenced(TransactionController tc,
1940:                    TabInfoImpl ti, int indexId, int indexCol,
1941:                    DataValueDescriptor schemaIdOrderable)
1942:                    throws StandardException {
1943:                ConglomerateController heapCC = null;
1944:                ExecIndexRow indexRow1;
1945:                ExecIndexRow indexTemplateRow;
1946:                ExecRow outRow;
1947:                ScanController scanController = null;
1948:                boolean foundRow;
1949:                FormatableBitSet colToCheck = new FormatableBitSet(indexCol);
1950:                CatalogRowFactory rf = ti.getCatalogRowFactory();
1951:
1952:                if (SanityManager.DEBUG) {
1953:                    SanityManager
1954:                            .ASSERT(
1955:                                    indexId >= 0,
1956:                                    "code needs to be enhanced"
1957:                                            + " to support a table scan to find the index id");
1958:                }
1959:
1960:                colToCheck.set(indexCol - 1);
1961:
1962:                ScanQualifier[][] qualifier = exFactory.getScanQualifier(1);
1963:                qualifier[0][0].setQualifier(indexCol - 1, schemaIdOrderable,
1964:                        Orderable.ORDER_OP_EQUALS, false, false, false);
1965:
1966:                outRow = rf.makeEmptyRow();
1967:
1968:                try {
1969:                    heapCC = tc.openConglomerate(ti.getHeapConglomerate(),
1970:                            false, 0, TransactionController.MODE_RECORD,
1971:                            TransactionController.ISOLATION_REPEATABLE_READ);
1972:
1973:                    scanController = tc.openScan(
1974:                            ti.getIndexConglomerate(indexId), // conglomerate to open
1975:                            false, // don't hold open across commit
1976:                            0, // for read
1977:                            TransactionController.MODE_RECORD, // row locking
1978:                            TransactionController.ISOLATION_REPEATABLE_READ,
1979:                            colToCheck, // don't get any rows
1980:                            null, // start position - first row
1981:                            ScanController.GE, // startSearchOperation
1982:                            qualifier, // scanQualifier,
1983:                            null, // stop position - through last row
1984:                            ScanController.GT); // stopSearchOperation
1985:
1986:                    foundRow = (scanController.next());
1987:                } finally {
1988:                    if (scanController != null) {
1989:                        scanController.close();
1990:                    }
1991:                    if (heapCC != null) {
1992:                        heapCC.close();
1993:                    }
1994:                }
1995:
1996:                return foundRow;
1997:            }
1998:
1999:            /**
2000:             * Drop the table descriptor.
2001:             *
2002:             * @param td	The table descriptor to drop
2003:             * @param schema		A descriptor for the schema the table
2004:             *						is a part of.  If this parameter is
2005:             *						NULL, then the table is part of the
2006:             *						current (default) schema
2007:             * @param tc			TransactionController for the transaction
2008:             *
2009:             * @exception StandardException		Thrown on error
2010:             */
2011:            public void dropTableDescriptor(TableDescriptor td,
2012:                    SchemaDescriptor schema, TransactionController tc)
2013:                    throws StandardException {
2014:                ConglomerateController heapCC;
2015:                ExecIndexRow keyRow1 = null;
2016:                DataValueDescriptor schemaIDOrderable;
2017:                DataValueDescriptor tableNameOrderable;
2018:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
2019:
2020:                /* Use tableIdOrderable and schemaIdOrderable in both start 
2021:                 * and stop position for index 1 scan. 
2022:                 */
2023:                tableNameOrderable = dvf.getVarcharDataValue(td.getName());
2024:                schemaIDOrderable = getValueAsDVD(schema.getUUID());
2025:
2026:                /* Set up the start/stop position for the scan */
2027:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2028:                keyRow1.setColumn(1, tableNameOrderable);
2029:                keyRow1.setColumn(2, schemaIDOrderable);
2030:
2031:                ti.deleteRow(tc, keyRow1,
2032:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID);
2033:            }
2034:
2035:            /**
2036:             * Update the lockGranularity for the specified table.
2037:             *
2038:             * @param td				The TableDescriptor for the table
2039:             * @param schema			The SchemaDescriptor for the table
2040:             * @param lockGranularity	The new lockGranularity
2041:             * @param tc				The TransactionController to use.
2042:             *
2043:             * @exception StandardException		Thrown on error
2044:             */
2045:            public void updateLockGranularity(TableDescriptor td,
2046:                    SchemaDescriptor schema, char lockGranularity,
2047:                    TransactionController tc) throws StandardException {
2048:                ConglomerateController heapCC;
2049:                ExecIndexRow keyRow1 = null;
2050:                ExecRow row;
2051:                DataValueDescriptor schemaIDOrderable;
2052:                DataValueDescriptor tableNameOrderable;
2053:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
2054:                SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti
2055:                        .getCatalogRowFactory();
2056:
2057:                /* Use tableIdOrderable and schemaIdOrderable in both start 
2058:                 * and stop position for index 1 scan. 
2059:                 */
2060:                tableNameOrderable = dvf.getVarcharDataValue(td.getName());
2061:                schemaIDOrderable = getValueAsDVD(schema.getUUID());
2062:
2063:                /* Set up the start/stop position for the scan */
2064:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2065:                keyRow1.setColumn(1, tableNameOrderable);
2066:                keyRow1.setColumn(2, schemaIDOrderable);
2067:
2068:                // build the row to be stuffed into SYSTABLES. 
2069:                row = rf.makeRow(td, schema);
2070:                // update row in catalog (no indexes)
2071:                boolean[] bArray = new boolean[2];
2072:                for (int index = 0; index < 2; index++) {
2073:                    bArray[index] = false;
2074:                }
2075:                ti.updateRow(keyRow1, row,
2076:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID, bArray,
2077:                        (int[]) null, tc);
2078:            }
2079:
2080:            /**
2081:             * Drop all table descriptors for a schema.
2082:             *
2083:             * @param schema	A descriptor for the schema to drop the tables
2084:             *			from.
2085:             *
2086:             * @return  Nothing.
2087:             *
2088:             * @exception StandardException		Thrown on failure
2089:             */
2090:            /*
2091:            public void dropAllTableDescriptors(SchemaDescriptor schema)
2092:            					throws StandardException
2093:            {
2094:            	if (SanityManager.DEBUG) SanityManager.NOTREACHED();
2095:            }
2096:             */
2097:
2098:            /**
2099:             * Get a ColumnDescriptor given its Default ID.
2100:             *
2101:             * @param uuid	The UUID of the default
2102:             *
2103:             * @return The ColumnDescriptor for the column.
2104:             *
2105:             * @exception StandardException		Thrown on failure
2106:             */
2107:            public ColumnDescriptor getColumnDescriptorByDefaultId(UUID uuid)
2108:                    throws StandardException {
2109:                DataValueDescriptor UUIDStringOrderable;
2110:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2111:
2112:                /* Use UUIDStringOrderable in both start and stop positions for scan */
2113:                UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
2114:
2115:                /* Set up the start/stop position for the scan */
2116:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2117:                keyRow.setColumn(1, UUIDStringOrderable);
2118:
2119:                return (ColumnDescriptor) getDescriptorViaIndex(
2120:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX2_ID, keyRow,
2121:                        (ScanQualifier[][]) null, ti, (DefaultDescriptor) null,
2122:                        (List) null, false);
2123:            }
2124:
2125:            /** 
2126:             * Populate the ColumnDescriptorList for the specified TableDescriptor.
2127:             *
2128:             * MT synchronization: it is assumed that the caller has synchronized
2129:             * on the CDL in the given TD.
2130:             *
2131:             * @param td				The TableDescriptor.
2132:             *
2133:             * @exception StandardException		Thrown on failure
2134:             */
2135:            private void getColumnDescriptorsScan(TableDescriptor td)
2136:                    throws StandardException {
2137:                getColumnDescriptorsScan(td.getUUID(), td
2138:                        .getColumnDescriptorList(), td);
2139:            }
2140:
2141:            /** 
2142:             * Populate the ColumnDescriptorList for the specified TableDescriptor.
2143:             *
2144:             * MT synchronization: it is assumed that the caller has synchronized
2145:             * on the CDL in the given TD.
2146:             *
2147:             * @param uuid				The referencing UUID
2148:             * @param cdl			The column descriptor list
2149:             * @param td				The parent tuple descriptor
2150:             *
2151:             * @exception StandardException		Thrown on failure
2152:             */
2153:            private void getColumnDescriptorsScan(UUID uuid,
2154:                    ColumnDescriptorList cdl, TupleDescriptor td)
2155:                    throws StandardException {
2156:                ColumnDescriptor cd;
2157:                ColumnDescriptorList cdlCopy = new ColumnDescriptorList();
2158:                DataValueDescriptor refIDOrderable = null;
2159:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2160:
2161:                /* Use refIDOrderable in both start and stop position for scan. */
2162:                refIDOrderable = getValueAsDVD(uuid);
2163:
2164:                /* Set up the start/stop position for the scan */
2165:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2166:                keyRow.setColumn(1, refIDOrderable);
2167:
2168:                getDescriptorViaIndex(
2169:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID, keyRow,
2170:                        (ScanQualifier[][]) null, ti, td,
2171:                        (ColumnDescriptorList) cdl, false);
2172:
2173:                /* The TableDescriptor's column descriptor list must be ordered by
2174:                 * columnNumber.  (It is probably not ordered correctly at this point due
2175:                 * to the index on syscolumns being on (tableId, columnName).)  The
2176:                 * cheapest way to reorder the list appears to be to copy it (above), and then
2177:                 * walk the copy and put the elements back into the original in the
2178:                 * expected locations.
2179:                 */
2180:                int cdlSize = cdl.size();
2181:                for (int index = 0; index < cdlSize; index++) {
2182:                    cdlCopy.add(cdl.get(index));
2183:                }
2184:                for (int index = 0; index < cdlSize; index++) {
2185:                    cd = (ColumnDescriptor) cdlCopy.elementAt(index);
2186:                    cdl.set(cd.getPosition() - 1, cd);
2187:                }
2188:            }
2189:
2190:            /**
2191:             * Given a column name and a table ID, drops the column descriptor
2192:             * from the table.
2193:             *
2194:             * @param tableID	The UUID of the table to drop the column from
2195:             * @param columnName	The name of the column to drop
2196:             * @param tc		TransactionController for the transaction
2197:             *
2198:             * @exception StandardException		Thrown on error
2199:             */
2200:            public void dropColumnDescriptor(UUID tableID, String columnName,
2201:                    TransactionController tc) throws StandardException {
2202:                DataValueDescriptor columnNameOrderable;
2203:                DataValueDescriptor tableIdOrderable;
2204:
2205:                /* Use tableIDOrderable and columnNameOrderable in both start 
2206:                 * and stop position for scan. 
2207:                 */
2208:                tableIdOrderable = getValueAsDVD(tableID);
2209:                columnNameOrderable = dvf.getVarcharDataValue(columnName);
2210:
2211:                /* Set up the start/stop position for the scan */
2212:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
2213:                keyRow.setColumn(1, tableIdOrderable);
2214:                keyRow.setColumn(2, columnNameOrderable);
2215:
2216:                dropColumnDescriptorCore(tc, keyRow);
2217:            }
2218:
2219:            /**
2220:             * Drops all column descriptors from the given table.  Useful for
2221:             * DROP TABLE.
2222:             *
2223:             * @param tableID	The UUID of the table from which to drop
2224:             *			all the column descriptors
2225:             * @param tc		TransactionController for the transaction
2226:             *
2227:             * @exception StandardException		Thrown on error
2228:             */
2229:            public void dropAllColumnDescriptors(UUID tableID,
2230:                    TransactionController tc) throws StandardException {
2231:                DataValueDescriptor tableIdOrderable;
2232:
2233:                /* Use tableIDOrderable in both start and stop position for scan. */
2234:                tableIdOrderable = getValueAsDVD(tableID);
2235:
2236:                /* Set up the start/stop position for the scan */
2237:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2238:                keyRow.setColumn(1, tableIdOrderable);
2239:
2240:                dropColumnDescriptorCore(tc, keyRow);
2241:            }
2242:
2243:            /**
2244:             * Drops all table and column permission descriptors for the given table.
2245:             *
2246:             * @param tableID	The UUID of the table from which to drop
2247:             *			all the permission descriptors
2248:             * @param tc		TransactionController for the transaction
2249:             *
2250:             * @exception StandardException		Thrown on error
2251:             */
2252:            public void dropAllTableAndColPermDescriptors(UUID tableID,
2253:                    TransactionController tc) throws StandardException {
2254:                DataValueDescriptor tableIdOrderable;
2255:
2256:                // In Derby authorization mode, permission catalogs may not be present
2257:                if (!usesSqlAuthorization)
2258:                    return;
2259:
2260:                /* Use tableIDOrderable in both start and stop position for scan. */
2261:                tableIdOrderable = getValueAsDVD(tableID);
2262:
2263:                /* Set up the start/stop position for the scan */
2264:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2265:                keyRow.setColumn(1, tableIdOrderable);
2266:
2267:                dropTablePermDescriptor(tc, keyRow);
2268:                dropColumnPermDescriptor(tc, keyRow);
2269:            }
2270:
2271:            /**
2272:             * Need to update SYSCOLPERMS for a given table because a new column has 
2273:             * been added to that table. SYSCOLPERMS has a column called "COLUMNS"
2274:             * which is a bit map for all the columns in a given user table. Since
2275:             * ALTER TABLE .. ADD COLUMN .. has added one more column, we need to
2276:             * expand "COLUMNS" for that new column
2277:             *
2278:             * Currently, this code gets called during execution phase of
2279:             * ALTER TABLE .. ADD COLUMN .. 
2280:             *
2281:             * @param tableID	The UUID of the table to which a column has been added
2282:             * @param tc		TransactionController for the transaction
2283:             *
2284:             * @exception StandardException		Thrown on error
2285:             */
2286:            public void updateSYSCOLPERMSforAddColumnToUserTable(UUID tableID,
2287:                    TransactionController tc) throws StandardException {
2288:                // In Derby authorization mode, permission catalogs may not be present
2289:                if (!usesSqlAuthorization)
2290:                    return;
2291:
2292:                /* This method has 2 steps to it. First get all the ColPermsDescriptor   
2293:                for given tableid. And next step is to go back to SYSCOLPERMS to find
2294:                unique row corresponding to each of ColPermsDescriptor and update the
2295:                "COLUMNS" column in SYSCOLPERMS. The reason for this 2 step process is
2296:                that SYSCOLPERMS has a non-unique row on "TABLEID" column and hence   
2297:                we can't get a unique handle on each of the affected row in SYSCOLPERMS
2298:                using just the "TABLEID" column */
2299:
2300:                // First get all the ColPermsDescriptor for the given tableid from   
2301:                //SYSCOLPERMS using getDescriptorViaIndex(). 
2302:                List permissionDescriptorsList;//all ColPermsDescriptor for given tableid
2303:                DataValueDescriptor tableIDOrderable = getValueAsDVD(tableID);
2304:                TabInfoImpl ti = getNonCoreTI(SYSCOLPERMS_CATALOG_NUM);
2305:                SYSCOLPERMSRowFactory rf = (SYSCOLPERMSRowFactory) ti
2306:                        .getCatalogRowFactory();
2307:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2308:                keyRow.setColumn(1, tableIDOrderable);
2309:                permissionDescriptorsList = newSList();
2310:                getDescriptorViaIndex(SYSCOLPERMSRowFactory.TABLEID_INDEX_NUM,
2311:                        keyRow, (ScanQualifier[][]) null, ti,
2312:                        (TupleDescriptor) null, permissionDescriptorsList,
2313:                        false);
2314:
2315:                /* Next, using each of the ColPermDescriptor's uuid, get the unique row 
2316:                in SYSCOLPERMS and expand the "COLUMNS" column in SYSCOLPERMS to 
2317:                accomodate the newly added column to the tableid*/
2318:                ColPermsDescriptor colPermsDescriptor;
2319:                ExecRow curRow;
2320:                ExecIndexRow uuidKey;
2321:                // Not updating any indexes on SYSCOLPERMS
2322:                boolean[] bArray = new boolean[SYSCOLPERMSRowFactory.TOTAL_NUM_OF_INDEXES];
2323:                int[] colsToUpdate = { SYSCOLPERMSRowFactory.COLUMNS_COL_NUM };
2324:                for (Iterator iterator = permissionDescriptorsList.iterator(); iterator
2325:                        .hasNext();) {
2326:                    colPermsDescriptor = (ColPermsDescriptor) iterator.next();
2327:                    removePermEntryInCache(colPermsDescriptor);
2328:                    uuidKey = rf.buildIndexKeyRow(rf.COLPERMSID_INDEX_NUM,
2329:                            colPermsDescriptor);
2330:                    curRow = ti.getRow(tc, uuidKey, rf.COLPERMSID_INDEX_NUM);
2331:                    FormatableBitSet columns = (FormatableBitSet) curRow
2332:                            .getColumn(SYSCOLPERMSRowFactory.COLUMNS_COL_NUM)
2333:                            .getObject();
2334:                    int currentLength = columns.getLength();
2335:                    columns.grow(currentLength + 1);
2336:                    curRow.setColumn(SYSCOLPERMSRowFactory.COLUMNS_COL_NUM, dvf
2337:                            .getDataValue((Object) columns));
2338:                    ti.updateRow(keyRow, curRow,
2339:                            SYSCOLPERMSRowFactory.TABLEID_INDEX_NUM, bArray,
2340:                            colsToUpdate, tc);
2341:                }
2342:            }
2343:
2344:            /**
2345:             * Remove PermissionsDescriptor from permissions cache if present
2346:             */
2347:            private void removePermEntryInCache(PermissionsDescriptor perm)
2348:                    throws StandardException {
2349:                // Remove cached permissions entry if present
2350:                Cacheable cacheEntry = getPermissionsCache().findCached(perm);
2351:                if (cacheEntry != null)
2352:                    getPermissionsCache().remove(cacheEntry);
2353:            }
2354:
2355:            /**
2356:             * Drops all routine permission descriptors for the given routine.
2357:             *
2358:             * @param routineID	The UUID of the routine from which to drop
2359:             *			all the permission descriptors
2360:             * @param tc		TransactionController for the transaction
2361:             *
2362:             * @exception StandardException		Thrown on error
2363:             */
2364:            public void dropAllRoutinePermDescriptors(UUID routineID,
2365:                    TransactionController tc) throws StandardException {
2366:                TabInfoImpl ti = getNonCoreTI(SYSROUTINEPERMS_CATALOG_NUM);
2367:                SYSROUTINEPERMSRowFactory rf = (SYSROUTINEPERMSRowFactory) ti
2368:                        .getCatalogRowFactory();
2369:                DataValueDescriptor routineIdOrderable;
2370:                ExecRow curRow;
2371:                PermissionsDescriptor perm;
2372:
2373:                // In Derby authorization mode, permission catalogs may not be present
2374:                if (!usesSqlAuthorization)
2375:                    return;
2376:
2377:                /* Use tableIDOrderable in both start and stop position for scan. */
2378:                routineIdOrderable = getValueAsDVD(routineID);
2379:
2380:                /* Set up the start/stop position for the scan */
2381:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2382:                keyRow.setColumn(1, routineIdOrderable);
2383:
2384:                while ((curRow = ti.getRow(tc, keyRow, rf.ALIASID_INDEX_NUM)) != null) {
2385:                    perm = (PermissionsDescriptor) rf.buildDescriptor(curRow,
2386:                            (TupleDescriptor) null, this );
2387:                    removePermEntryInCache(perm);
2388:
2389:                    // Build new key based on UUID and drop the entry as we want to drop
2390:                    // only this row
2391:                    ExecIndexRow uuidKey;
2392:                    uuidKey = rf.buildIndexKeyRow(rf.ROUTINEPERMSID_INDEX_NUM,
2393:                            perm);
2394:                    ti.deleteRow(tc, uuidKey, rf.ROUTINEPERMSID_INDEX_NUM);
2395:                }
2396:            }
2397:
2398:            /**
2399:             * Delete the appropriate rows from syscolumns when
2400:             * dropping 1 or more columns.
2401:             * 
2402:             * @param tc			The TransactionController
2403:             * @param keyRow		Start/stop position.
2404:             *
2405:             * @exception StandardException		Thrown on failure
2406:             */
2407:            private void dropColumnDescriptorCore(TransactionController tc,
2408:                    ExecIndexRow keyRow) throws StandardException {
2409:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2410:
2411:                ti.deleteRow(tc, keyRow,
2412:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID);
2413:            }
2414:
2415:            /**
2416:             * Delete the appropriate rows from systableperms when
2417:             * dropping a table
2418:             * 
2419:             * @param tc			The TransactionController
2420:             * @param keyRow		Start/stop position.
2421:             *
2422:             * @exception StandardException		Thrown on failure
2423:             */
2424:            private void dropTablePermDescriptor(TransactionController tc,
2425:                    ExecIndexRow keyRow) throws StandardException {
2426:                ExecRow curRow;
2427:                PermissionsDescriptor perm;
2428:                TabInfoImpl ti = getNonCoreTI(SYSTABLEPERMS_CATALOG_NUM);
2429:                SYSTABLEPERMSRowFactory rf = (SYSTABLEPERMSRowFactory) ti
2430:                        .getCatalogRowFactory();
2431:
2432:                while ((curRow = ti.getRow(tc, keyRow, rf.TABLEID_INDEX_NUM)) != null) {
2433:                    perm = (PermissionsDescriptor) rf.buildDescriptor(curRow,
2434:                            (TupleDescriptor) null, this );
2435:                    removePermEntryInCache(perm);
2436:
2437:                    // Build key on UUID and drop the entry as we want to drop only this row
2438:                    ExecIndexRow uuidKey;
2439:                    uuidKey = rf.buildIndexKeyRow(rf.TABLEPERMSID_INDEX_NUM,
2440:                            perm);
2441:                    ti.deleteRow(tc, uuidKey, rf.TABLEPERMSID_INDEX_NUM);
2442:                }
2443:            }
2444:
2445:            /**
2446:             * Delete the appropriate rows from syscolperms when
2447:             * dropping a table
2448:             * 
2449:             * @param tc			The TransactionController
2450:             * @param keyRow		Start/stop position.
2451:             *
2452:             * @exception StandardException		Thrown on failure
2453:             */
2454:            private void dropColumnPermDescriptor(TransactionController tc,
2455:                    ExecIndexRow keyRow) throws StandardException {
2456:                ExecRow curRow;
2457:                PermissionsDescriptor perm;
2458:                TabInfoImpl ti = getNonCoreTI(SYSCOLPERMS_CATALOG_NUM);
2459:                SYSCOLPERMSRowFactory rf = (SYSCOLPERMSRowFactory) ti
2460:                        .getCatalogRowFactory();
2461:
2462:                while ((curRow = ti.getRow(tc, keyRow, rf.TABLEID_INDEX_NUM)) != null) {
2463:                    perm = (PermissionsDescriptor) rf.buildDescriptor(curRow,
2464:                            (TupleDescriptor) null, this );
2465:                    removePermEntryInCache(perm);
2466:
2467:                    // Build key on UUID and drop the entry as we want to drop only this row
2468:                    ExecIndexRow uuidKey;
2469:                    uuidKey = rf
2470:                            .buildIndexKeyRow(rf.COLPERMSID_INDEX_NUM, perm);
2471:                    ti.deleteRow(tc, uuidKey, rf.COLPERMSID_INDEX_NUM);
2472:                }
2473:            }
2474:
2475:            /**
2476:             * Update the column descriptor in question.  Updates
2477:             * every row in the base conglomerate.  
2478:             *
2479:             * @param cd					The ColumnDescriptor
2480:             * @param formerUUID			The UUID for this column in SYSCOLUMNS,
2481:             *								may differ from what is in cd if this
2482:             *								is the column that is being set.
2483:             * @param formerName			The name for this column in SYSCOLUMNS
2484:             *								may differ from what is in cd if this
2485:             *								is the column that is being set.
2486:             * @param colsToSet 			Array of ints of columns to be modified,
2487:             *								1 based.  May be null (all cols).
2488:             * @param tc					The TransactionController to use
2489:             * @param wait		If true, then the caller wants to wait for locks. False will be
2490:             * when we using a nested user xaction - we want to timeout right away if the parent
2491:             * holds the lock.  (bug 4821)
2492:             *
2493:             * @exception StandardException		Thrown on failure
2494:             */
2495:            private void updateColumnDescriptor(ColumnDescriptor cd,
2496:                    UUID formerUUID, String formerName, int[] colsToSet,
2497:                    TransactionController tc, boolean wait)
2498:                    throws StandardException {
2499:                ExecIndexRow keyRow1 = null;
2500:                ExecRow row;
2501:                DataValueDescriptor refIDOrderable;
2502:                DataValueDescriptor columnNameOrderable;
2503:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2504:                SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti
2505:                        .getCatalogRowFactory();
2506:
2507:                /* Use objectID/columnName in both start 
2508:                 * and stop position for index 1 scan. 
2509:                 */
2510:                refIDOrderable = getValueAsDVD(formerUUID);
2511:                columnNameOrderable = dvf.getVarcharDataValue(formerName);
2512:
2513:                /* Set up the start/stop position for the scan */
2514:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2515:                keyRow1.setColumn(1, refIDOrderable);
2516:                keyRow1.setColumn(2, columnNameOrderable);
2517:
2518:                // build the row to be stuffed into SYSCOLUMNS. 
2519:                row = rf.makeRow(cd, null);
2520:
2521:                /*
2522:                 ** Figure out if the index in syscolumns needs 
2523:                 ** to be updated. 
2524:                 */
2525:                if (SanityManager.DEBUG) {
2526:                    SanityManager
2527:                            .ASSERT(
2528:                                    rf.getNumIndexes() == 2,
2529:                                    "There are more indexes on syscolumns than expected, the code herein needs to change");
2530:                }
2531:
2532:                boolean[] bArray = new boolean[rf.getNumIndexes()];
2533:
2534:                /*
2535:                 ** Do we need to update indexes?
2536:                 */
2537:                if (colsToSet == null) {
2538:                    bArray[0] = true;
2539:                    bArray[1] = true;
2540:                } else {
2541:                    /*
2542:                     ** Check the specific columns for indexed
2543:                     ** columns.
2544:                     */
2545:                    for (int i = 0; i < colsToSet.length; i++) {
2546:                        if ((colsToSet[i] == rf.SYSCOLUMNS_COLUMNNAME)
2547:                                || (colsToSet[i] == rf.SYSCOLUMNS_REFERENCEID)) {
2548:                            bArray[0] = true;
2549:                            break;
2550:                        } else if (colsToSet[i] == rf.SYSCOLUMNS_COLUMNDEFAULTID) {
2551:                            bArray[1] = true;
2552:                            break;
2553:                        }
2554:                    }
2555:                }
2556:
2557:                ti.updateRow(keyRow1, row,
2558:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID, bArray,
2559:                        colsToSet, tc, wait);
2560:            }
2561:
2562:            /**
2563:             * Gets the viewDescriptor for the view with the given UUID.
2564:             *
2565:             * @param uuid	The UUID for the view
2566:             *
2567:             * @return  A descriptor for the view
2568:             *
2569:             * @exception StandardException		Thrown on error
2570:             */
2571:            public ViewDescriptor getViewDescriptor(UUID uuid)
2572:                    throws StandardException {
2573:                return getViewDescriptor(getTableDescriptor(uuid));
2574:            }
2575:
2576:            /**
2577:             * Gets the viewDescriptor for the view given the TableDescriptor.
2578:             *
2579:             * @param td	The TableDescriptor for the view.
2580:             *
2581:             * @return	A descriptor for the view
2582:             *
2583:             * @exception StandardException		Thrown on error
2584:             */
2585:            public ViewDescriptor getViewDescriptor(TableDescriptor td)
2586:                    throws StandardException {
2587:                TableDescriptor tdi = (TableDescriptor) td;
2588:
2589:                /* See if the view info is cached */
2590:                if (tdi.getViewDescriptor() != null) {
2591:                    return tdi.getViewDescriptor();
2592:                }
2593:
2594:                synchronized (tdi) {
2595:                    /* See if we were waiting on someone who just filled it in */
2596:                    if (tdi.getViewDescriptor() != null) {
2597:                        return tdi.getViewDescriptor();
2598:                    }
2599:
2600:                    tdi
2601:                            .setViewDescriptor((ViewDescriptor) getViewDescriptorScan(tdi));
2602:                }
2603:                return tdi.getViewDescriptor();
2604:            }
2605:
2606:            /**
2607:             * Get the information for the view from sys.sysviews.
2608:             *
2609:             * @param tdi					The TableDescriptor for the view.
2610:             *
2611:             * @return ViewDescriptor	The ViewDescriptor for the view.
2612:             *
2613:             * @exception StandardException		Thrown on error
2614:             */
2615:            private ViewDescriptor getViewDescriptorScan(TableDescriptor tdi)
2616:                    throws StandardException {
2617:                ViewDescriptor vd;
2618:                DataValueDescriptor viewIdOrderable;
2619:                TabInfoImpl ti = getNonCoreTI(SYSVIEWS_CATALOG_NUM);
2620:                UUID viewID = tdi.getUUID();
2621:
2622:                /* Use viewIdOrderable in both start 
2623:                 * and stop position for scan. 
2624:                 */
2625:                viewIdOrderable = dvf.getCharDataValue(viewID.toString());
2626:
2627:                /* Set up the start/stop position for the scan */
2628:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2629:                keyRow.setColumn(1, viewIdOrderable);
2630:
2631:                vd = (ViewDescriptor) getDescriptorViaIndex(
2632:                        SYSVIEWSRowFactory.SYSVIEWS_INDEX1_ID, keyRow,
2633:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
2634:                        (List) null, false);
2635:
2636:                if (vd != null) {
2637:                    vd.setViewName(tdi.getName());
2638:                }
2639:                return vd;
2640:            }
2641:
2642:            /**
2643:             * Drops the view descriptor from the data dictionary.
2644:             *
2645:             * @param vd		A descriptor for the view to be dropped
2646:             * @param tc		TransactionController to use
2647:             *
2648:             * @exception StandardException		Thrown on error
2649:             */
2650:            public void dropViewDescriptor(ViewDescriptor vd,
2651:                    TransactionController tc) throws StandardException {
2652:                DataValueDescriptor viewIdOrderable;
2653:                TabInfoImpl ti = getNonCoreTI(SYSVIEWS_CATALOG_NUM);
2654:
2655:                /* Use aliasNameOrderable in both start 
2656:                 * and stop position for scan. 
2657:                 */
2658:                viewIdOrderable = getValueAsDVD(vd.getUUID());
2659:
2660:                /* Set up the start/stop position for the scan */
2661:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
2662:                        .getIndexableRow(1);
2663:                keyRow.setColumn(1, viewIdOrderable);
2664:
2665:                ti.deleteRow(tc, keyRow, SYSVIEWSRowFactory.SYSVIEWS_INDEX1_ID);
2666:
2667:            }
2668:
2669:            /**
2670:             * Scan sysfiles_index2 (id) for a match.
2671:             * @return TableDescriptor	The matching descriptor, or null.
2672:             * @exception StandardException		Thrown on failure
2673:             */
2674:            private FileInfoDescriptor getFileInfoDescriptorIndex2Scan(UUID id)
2675:                    throws StandardException {
2676:                DataValueDescriptor idOrderable;
2677:                TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2678:                idOrderable = dvf.getCharDataValue(id.toString());
2679:
2680:                /* Set up the start/stop position for the scan */
2681:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2682:                keyRow.setColumn(1, idOrderable);
2683:
2684:                return (FileInfoDescriptor) getDescriptorViaIndex(
2685:                        SYSFILESRowFactory.SYSFILES_INDEX2_ID, keyRow,
2686:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
2687:                        (List) null, false);
2688:            }
2689:
2690:            /**
2691:             * @see DataDictionary#getFileInfoDescriptor
2692:             * @exception StandardException		Thrown on failure
2693:             */
2694:            public FileInfoDescriptor getFileInfoDescriptor(UUID id)
2695:                    throws StandardException {
2696:                return getFileInfoDescriptorIndex2Scan(id);
2697:            }
2698:
2699:            /**
2700:             * Scan sysfiles_index1 (schemaid,name) for a match.
2701:             * @return The matching descriptor or null.
2702:             * @exception StandardException		Thrown on failure
2703:             */
2704:            private FileInfoDescriptor getFileInfoDescriptorIndex1Scan(
2705:                    UUID schemaId, String name) throws StandardException {
2706:                DataValueDescriptor schemaIDOrderable;
2707:                DataValueDescriptor nameOrderable;
2708:                TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2709:
2710:                nameOrderable = dvf.getVarcharDataValue(name);
2711:                schemaIDOrderable = dvf.getCharDataValue(schemaId.toString());
2712:
2713:                /* Set up the start/stop position for the scan */
2714:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
2715:                keyRow.setColumn(1, nameOrderable);
2716:                keyRow.setColumn(2, schemaIDOrderable);
2717:                FileInfoDescriptor r = (FileInfoDescriptor) getDescriptorViaIndex(
2718:                        SYSFILESRowFactory.SYSFILES_INDEX1_ID, keyRow,
2719:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
2720:                        (List) null, false);
2721:                return r;
2722:            }
2723:
2724:            /**
2725:             * @see DataDictionary#getFileInfoDescriptor
2726:             * @exception StandardException		Thrown on failure
2727:             */
2728:            public FileInfoDescriptor getFileInfoDescriptor(
2729:                    SchemaDescriptor sd, String name) throws StandardException {
2730:                return getFileInfoDescriptorIndex1Scan(sd.getUUID(), name);
2731:            }
2732:
2733:            /**
2734:             * @see DataDictionary#dropFileInfoDescriptor
2735:             * @exception StandardException		Thrown on error
2736:             */
2737:            public void dropFileInfoDescriptor(FileInfoDescriptor fid)
2738:                    throws StandardException {
2739:                ConglomerateController heapCC;
2740:                ExecIndexRow keyRow1 = null;
2741:                DataValueDescriptor idOrderable;
2742:                TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2743:                TransactionController tc = getTransactionExecute();
2744:
2745:                /* Use tableIdOrderable and schemaIdOrderable in both start 
2746:                 * and stop position for index 1 scan. 
2747:                 */
2748:                idOrderable = getValueAsDVD(fid.getUUID());
2749:
2750:                /* Set up the start/stop position for the scan */
2751:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
2752:                keyRow1.setColumn(1, idOrderable);
2753:                ti
2754:                        .deleteRow(tc, keyRow1,
2755:                                SYSFILESRowFactory.SYSFILES_INDEX2_ID);
2756:            }
2757:
2758:            /**
2759:             * Get a SPSDescriptor given its UUID.
2760:             *
2761:             * @param uuid	The UUID
2762:             *
2763:             * @return The SPSDescriptor for the constraint.
2764:             *
2765:             * @exception StandardException		Thrown on failure
2766:             */
2767:            public SPSDescriptor getSPSDescriptor(UUID uuid)
2768:                    throws StandardException {
2769:                SPSDescriptor sps;
2770:
2771:                /* Make sure that non-core info is initialized */
2772:                getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
2773:
2774:                /* Only use the cache if we're in compile-only mode */
2775:                if ((spsNameCache != null)
2776:                        && (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)) {
2777:                    sps = (SPSDescriptor) spsIdHash.get(uuid);
2778:                    if (sps != null) {
2779:                        //System.out.println("found in hash table ");
2780:                        // System.out.println("stmt text " + sps.getText());
2781:
2782:                        return sps;
2783:                    }
2784:
2785:                    sps = getSPSDescriptorIndex2Scan(uuid.toString());
2786:                    TableKey stmtKey = new TableKey(sps.getSchemaDescriptor()
2787:                            .getUUID(), sps.getName());
2788:                    try {
2789:                        SPSNameCacheable cacheEntry = (SPSNameCacheable) spsNameCache
2790:                                .create(stmtKey, sps);
2791:                        spsNameCache.release(cacheEntry);
2792:                    } catch (StandardException se) {
2793:                        /*
2794:                         ** If the error is that the item is already
2795:                         ** in the cache, then that is ok.
2796:                         */
2797:                        if (SQLState.OBJECT_EXISTS_IN_CACHE.equals(se
2798:                                .getMessageId())) {
2799:                            return sps;
2800:                        } else {
2801:                            throw se;
2802:                        }
2803:                    }
2804:
2805:                } else {
2806:                    sps = getSPSDescriptorIndex2Scan(uuid.toString());
2807:                }
2808:
2809:                return sps;
2810:            }
2811:
2812:            /**
2813:            	Add an entry to the hashtables for lookup from the cache.
2814:             */
2815:            void spsCacheEntryAdded(SPSDescriptor spsd) {
2816:                spsIdHash.put(spsd.getUUID(), spsd);
2817:                // spsTextHash.put(spsd.getText(), spsd);
2818:            }
2819:
2820:            void spsCacheEntryRemoved(SPSDescriptor spsd) {
2821:                spsIdHash.remove(spsd.getUUID());
2822:                // spsTextHash.remove(spsd.getText());
2823:            }
2824:
2825:            //public SPSDescriptor getSPSBySQLText(String text) {
2826:
2827:            //	return (SPSDescriptor) spsTextHash.get(text);
2828:            //}
2829:
2830:            /**
2831:             * This method can get called from the DataDictionary cache.
2832:             *
2833:             * @param stmtKey	The TableKey of the sps
2834:             *
2835:             * @return	The descriptor for the sps, null if the sps does
2836:             *		not exist.
2837:             *
2838:             * @exception StandardException		Thrown on failure
2839:             */
2840:            public SPSDescriptor getUncachedSPSDescriptor(TableKey stmtKey)
2841:                    throws StandardException {
2842:                return getSPSDescriptorIndex1Scan(stmtKey.getTableName(),
2843:                        stmtKey.getSchemaId().toString());
2844:            }
2845:
2846:            /**
2847:             * This method can get called from the DataDictionary cache.
2848:             *
2849:             * @param stmtId	The UUID of the stmt to get the descriptor for
2850:             *
2851:             * @return	The descriptor for the stmt, null if the table does
2852:             *		not exist.
2853:             *
2854:             * @exception StandardException		Thrown on failure
2855:             */
2856:            protected SPSDescriptor getUncachedSPSDescriptor(UUID stmtId)
2857:                    throws StandardException {
2858:                return getSPSDescriptorIndex2Scan(stmtId.toString());
2859:            }
2860:
2861:            /**
2862:             * Scan sysstatements_index2 (stmtid) for a match.
2863:             * Note that we do not do a lookup of parameter info.
2864:             *
2865:             * @return SPSDescriptor	The matching descriptor, if any.
2866:             *
2867:             * @exception StandardException		Thrown on failure
2868:             */
2869:            private SPSDescriptor getSPSDescriptorIndex2Scan(String stmtUUID)
2870:                    throws StandardException {
2871:                DataValueDescriptor stmtIDOrderable;
2872:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
2873:
2874:                /* Use stmtIdOrderable in both start 
2875:                 * and stop position for scan. 
2876:                 */
2877:                stmtIDOrderable = dvf.getCharDataValue(stmtUUID);
2878:
2879:                /* Set up the start/stop position for the scan */
2880:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2881:                keyRow.setColumn(1, stmtIDOrderable);
2882:
2883:                SPSDescriptor spsd = (SPSDescriptor) getDescriptorViaIndex(
2884:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID,
2885:                        keyRow, (ScanQualifier[][]) null, ti,
2886:                        (TupleDescriptor) null, (List) null, false);
2887:
2888:                return spsd;
2889:            }
2890:
2891:            /**
2892:             * Get a SPSDescriptor given its name.
2893:             * Currently no cacheing.  With caching
2894:             * we need to be very careful about invalidation.
2895:             * No caching means invalidations block on
2896:             * existing SPSD instances (since they were read in
2897:             *
2898:             * @param stmtName	the statement name
2899:             * @param sd	The SchemaDescriptor
2900:             *
2901:             * @return The SPSDescriptor for the constraint.
2902:             *
2903:             * @exception StandardException		Thrown on failure
2904:             */
2905:            public SPSDescriptor getSPSDescriptor(String stmtName,
2906:                    SchemaDescriptor sd) throws StandardException {
2907:                SPSDescriptor sps = null;
2908:                TableKey stmtKey;
2909:                UUID schemaUUID;
2910:
2911:                /*
2912:                 ** If we didn't get a schema descriptor, we had better
2913:                 ** have a system table.
2914:                 */
2915:                if (SanityManager.DEBUG) {
2916:                    if (sd == null) {
2917:                        SanityManager.THROWASSERT("null schema for statement "
2918:                                + stmtName);
2919:                    }
2920:                }
2921:
2922:                schemaUUID = sd.getUUID();
2923:                stmtKey = new TableKey(schemaUUID, stmtName);
2924:
2925:                /* Only use the cache if we're in compile-only mode */
2926:                if ((spsNameCache != null)
2927:                        && (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)) {
2928:                    SPSNameCacheable cacheEntry = (SPSNameCacheable) spsNameCache
2929:                            .find(stmtKey);
2930:                    if (cacheEntry != null) {
2931:                        sps = cacheEntry.getSPSDescriptor();
2932:                        spsNameCache.release(cacheEntry);
2933:                    }
2934:                    //System.out.println("found in cache " + stmtName);
2935:                    //System.out.println("stmt text " + sps.getText());
2936:                    return sps;
2937:                }
2938:
2939:                return getSPSDescriptorIndex1Scan(stmtName, schemaUUID
2940:                        .toString());
2941:            }
2942:
2943:            /**
2944:             * Scan sysschemas_index1 (stmtname, schemaid) for a match.
2945:             *
2946:             * @return SPSDescriptor	The matching descriptor, if any.
2947:             *
2948:             * @exception StandardException		Thrown on failure
2949:             */
2950:            private SPSDescriptor getSPSDescriptorIndex1Scan(String stmtName,
2951:                    String schemaUUID) throws StandardException {
2952:                DataValueDescriptor schemaIDOrderable;
2953:                DataValueDescriptor stmtNameOrderable;
2954:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
2955:
2956:                /* Use stmtNameOrderable and schemaIdOrderable in both start 
2957:                 * and stop position for scan. 
2958:                 */
2959:                stmtNameOrderable = dvf.getVarcharDataValue(stmtName);
2960:                schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
2961:
2962:                /* Set up the start/stop position for the scan */
2963:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
2964:                keyRow.setColumn(1, stmtNameOrderable);
2965:                keyRow.setColumn(2, schemaIDOrderable);
2966:
2967:                SPSDescriptor spsd = (SPSDescriptor) getDescriptorViaIndex(
2968:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX2_ID,
2969:                        keyRow, (ScanQualifier[][]) null, ti,
2970:                        (TupleDescriptor) null, (List) null, false);
2971:
2972:                /*
2973:                 ** Set up the parameter defaults.  We are only
2974:                 ** doing this when we look up by name because
2975:                 ** this is the only time we cache, and it can
2976:                 ** be foolish to look up the parameter defaults
2977:                 ** for someone that doesn't need them.
2978:                 */
2979:                if (spsd != null) {
2980:                    Vector v = new Vector();
2981:                    spsd.setParams(getSPSParams(spsd, v));
2982:                    Object[] defaults = new Object[v.size()];
2983:                    v.copyInto(defaults);
2984:                    spsd.setParameterDefaults(defaults);
2985:                }
2986:
2987:                return spsd;
2988:            }
2989:
2990:            /**
2991:             * Adds the given SPSDescriptor to the data dictionary,
2992:             * associated with the given table and constraint type.
2993:             *
2994:             * @param descriptor	The descriptor to add
2995:             * @param tc			The transaction controller
2996:             *
2997:             * @exception StandardException		Thrown on error
2998:             */
2999:            public void addSPSDescriptor(SPSDescriptor descriptor,
3000:                    TransactionController tc, boolean wait)
3001:                    throws StandardException {
3002:                ExecRow row;
3003:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3004:                SYSSTATEMENTSRowFactory rf = (SYSSTATEMENTSRowFactory) ti
3005:                        .getCatalogRowFactory();
3006:                int insertRetCode;
3007:
3008:                /*
3009:                 ** We must make sure the descriptor is locked
3010:                 ** while we are writing it out.  Otherwise,
3011:                 ** the descriptor could be invalidated while
3012:                 ** we are writing.
3013:                 */
3014:                synchronized (descriptor) {
3015:                    // build the row to be stuffed into SYSSTATEMENTS. this will stuff an
3016:                    // UUID into the descriptor
3017:                    boolean compileMe = descriptor.initiallyCompilable();
3018:                    row = rf.makeSYSSTATEMENTSrow(compileMe, descriptor);
3019:
3020:                    // insert row into catalog and all its indices
3021:                    insertRetCode = ti.insertRow(row, tc, wait);
3022:                }
3023:
3024:                // Throw an exception duplicate table descriptor
3025:                if (insertRetCode != TabInfoImpl.ROWNOTDUPLICATE) {
3026:                    throw StandardException.newException(
3027:                            SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
3028:                            descriptor.getDescriptorType(), descriptor
3029:                                    .getDescriptorName(), descriptor
3030:                                    .getSchemaDescriptor().getDescriptorType(),
3031:                            descriptor.getSchemaDescriptor().getSchemaName());
3032:                }
3033:
3034:                addSPSParams(descriptor, tc, wait);
3035:            }
3036:
3037:            /**
3038:             * Add a column in SYS.SYSCOLUMNS for each parameter in the
3039:             * parameter list.
3040:             */
3041:            private void addSPSParams(SPSDescriptor spsd,
3042:                    TransactionController tc, boolean wait)
3043:                    throws StandardException {
3044:                UUID uuid = spsd.getUUID();
3045:                DataTypeDescriptor[] params = spsd.getParams();
3046:                Object[] parameterDefaults = spsd.getParameterDefaults();
3047:
3048:                if (params == null)
3049:                    return;
3050:
3051:                /* Create the columns */
3052:                int pdlSize = params.length;
3053:                for (int index = 0; index < pdlSize; index++) {
3054:                    int parameterId = index + 1;
3055:
3056:                    //RESOLVEAUTOINCREMENT
3057:                    ColumnDescriptor cd = new ColumnDescriptor(
3058:                            "PARAM" + parameterId,
3059:                            parameterId, // position
3060:                            params[index],
3061:                            ((parameterDefaults == null) || // default
3062:                            (index >= parameterDefaults.length)) ? (DataValueDescriptor) null
3063:                                    : (DataValueDescriptor) parameterDefaults[index],
3064:                            (DefaultInfo) null, uuid, (UUID) null, 0, 0);
3065:
3066:                    addDescriptor(cd, null, SYSCOLUMNS_CATALOG_NUM, false, // no chance of duplicates here
3067:                            tc, wait);
3068:                }
3069:            }
3070:
3071:            /**
3072:             * Get all the parameter descriptors for an SPS.
3073:             * Look up the params in SYSCOLUMNS and turn them
3074:             * into parameter descriptors.  
3075:             *
3076:             * @param spsd	sps descriptor
3077:             * @param defaults	vector for storing column defaults
3078:             *
3079:             * @return array of data type descriptors
3080:             *
3081:             * @exception StandardException		Thrown on error
3082:             */
3083:            public DataTypeDescriptor[] getSPSParams(SPSDescriptor spsd,
3084:                    Vector defaults) throws StandardException {
3085:                ColumnDescriptorList cdl = new ColumnDescriptorList();
3086:                getColumnDescriptorsScan(spsd.getUUID(), cdl, spsd);
3087:
3088:                int cdlSize = cdl.size();
3089:                DataTypeDescriptor[] params = new DataTypeDescriptor[cdlSize];
3090:                for (int index = 0; index < cdlSize; index++) {
3091:                    ColumnDescriptor cd = (ColumnDescriptor) cdl
3092:                            .elementAt(index);
3093:                    params[index] = cd.getType();
3094:                    if (defaults != null) {
3095:                        defaults.addElement(cd.getDefaultValue());
3096:                    }
3097:                }
3098:
3099:                return params;
3100:            }
3101:
3102:            /**
3103:             * Updates SYS.SYSSTATEMENTS with the info from the
3104:             * SPSD. 
3105:             *
3106:             * @param spsd	The descriptor to add
3107:             * @param tc			The transaction controller
3108:             * @param updateParamDescriptors If true, will update the
3109:             *						parameter descriptors in SYS.SYSCOLUMNS.
3110:             * @param wait		If true, then the caller wants to wait for locks. False will be
3111:             * @param firstCompilation  true, if Statement is getting compiled for first
3112:             *                          time and SPS was created with NOCOMPILE option.
3113:             *
3114:             * when we using a nested user xaction - we want to timeout right away if the parent
3115:             * holds the lock.  (bug 4821)
3116:             *
3117:             * @exception StandardException		Thrown on error
3118:             */
3119:            public void updateSPS(SPSDescriptor spsd, TransactionController tc,
3120:                    boolean recompile, boolean updateParamDescriptors,
3121:                    boolean wait, boolean firstCompilation)
3122:                    throws StandardException {
3123:                ExecIndexRow keyRow1 = null;
3124:                ExecRow row;
3125:                DataValueDescriptor idOrderable;
3126:                DataValueDescriptor columnNameOrderable;
3127:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3128:                SYSSTATEMENTSRowFactory rf = (SYSSTATEMENTSRowFactory) ti
3129:                        .getCatalogRowFactory();
3130:                int[] updCols;
3131:                if (recompile) {
3132:                    if (firstCompilation) {
3133:                        updCols = new int[] {
3134:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID,
3135:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED,
3136:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_USINGTEXT,
3137:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE,
3138:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INITIALLY_COMPILABLE };
3139:                    } else {
3140:
3141:                        updCols = new int[] {
3142:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID,
3143:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED,
3144:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_USINGTEXT,
3145:                                SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE };
3146:                    }
3147:                } else {
3148:                    updCols = new int[] { SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID };
3149:                }
3150:
3151:                idOrderable = getValueAsDVD(spsd.getUUID());
3152:
3153:                /* Set up the start/stop position for the scan */
3154:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
3155:                keyRow1.setColumn(1, idOrderable);
3156:
3157:                row = rf.makeSYSSTATEMENTSrow(false, // don't compile
3158:                        spsd);
3159:
3160:                /*
3161:                 ** Not updating any indexes
3162:                 */
3163:                boolean[] bArray = new boolean[2];
3164:
3165:                /*
3166:                 ** Partial update
3167:                 */
3168:                ti.updateRow(keyRow1, row,
3169:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID,
3170:                        bArray, updCols, tc, wait);
3171:
3172:                /*
3173:                 ** If we don't need to update the parameter
3174:                 ** descriptors, we are done.
3175:                 */
3176:                if (!updateParamDescriptors) {
3177:                    return;
3178:                }
3179:
3180:                /*
3181:                 ** Set the defaults and datatypes for the parameters, if
3182:                 ** there are parameters.
3183:                 */
3184:                DataTypeDescriptor[] params = spsd.getParams();
3185:                if (params == null) {
3186:                    return;
3187:                }
3188:
3189:                if (firstCompilation) {
3190:                    /*beetle:5119, reason for doing add here instead of update
3191:                     *is with NOCOMPILE option of create statement/boot time SPS,
3192:                     *SPS statement is not compiled to find out the parameter info.
3193:                     *Because of the parameter info was not inserted at SPSDescriptor 
3194:                     *creation time. As this is the first time we are compiling paramter
3195:                     *infor should be inserted instead of the update.
3196:                     */
3197:                    addSPSParams(spsd, tc, wait);
3198:                } else {
3199:                    Object[] parameterDefaults = spsd.getParameterDefaults();
3200:
3201:                    /* 
3202:                     ** Update each column with the new defaults and with
3203:                     ** the new datatypes.  It is possible that someone has
3204:                     ** done a drop/create on the underlying table and 
3205:                     ** changed the type of a column, which has changed
3206:                     ** the type of a parameter to our statement.
3207:                     */
3208:                    int[] columnsToSet = new int[2];
3209:                    columnsToSet[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDATATYPE;
3210:                    columnsToSet[1] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDEFAULT;
3211:
3212:                    UUID uuid = spsd.getUUID();
3213:
3214:                    for (int index = 0; index < params.length; index++) {
3215:                        int parameterId = index + 1;
3216:
3217:                        //RESOLVEAUTOINCREMENT
3218:                        ColumnDescriptor cd = new ColumnDescriptor(
3219:                                "PARAM" + parameterId,
3220:                                parameterId, // position
3221:                                params[index],
3222:                                ((parameterDefaults == null) || // default
3223:                                (index >= parameterDefaults.length)) ? (DataValueDescriptor) null
3224:                                        : (DataValueDescriptor) parameterDefaults[index],
3225:                                (DefaultInfo) null, uuid, (UUID) null, 0, 0);
3226:
3227:                        updateColumnDescriptor(cd, cd.getReferencingUUID(), cd
3228:                                .getColumnName(), columnsToSet, tc, wait);
3229:                    }
3230:                }
3231:            }
3232:
3233:            /**
3234:             * @see DataDictionary#invalidateAllSPSPlans
3235:             * @exception StandardException		Thrown on error
3236:             */
3237:            public void invalidateAllSPSPlans() throws StandardException {
3238:                LanguageConnectionContext lcc = (LanguageConnectionContext) ContextService
3239:                        .getContext(LanguageConnectionContext.CONTEXT_ID);
3240:                startWriting(lcc);
3241:
3242:                for (java.util.Iterator li = getAllSPSDescriptors().iterator(); li
3243:                        .hasNext();) {
3244:                    SPSDescriptor spsd = (SPSDescriptor) li.next();
3245:                    spsd.makeInvalid(DependencyManager.USER_RECOMPILE_REQUEST,
3246:                            lcc);
3247:                }
3248:            }
3249:
3250:            /**
3251:             * Mark all SPS plans in the data dictionary invalid. This does
3252:             * not invalidate cached plans. This function is for use by
3253:             * the boot-up code.
3254:             * @exception StandardException		Thrown on error
3255:             */
3256:            void clearSPSPlans() throws StandardException {
3257:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3258:                faultInTabInfo(ti);
3259:
3260:                TransactionController tc = getTransactionExecute();
3261:
3262:                FormatableBitSet columnToReadSet = new FormatableBitSet(
3263:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT);
3264:                FormatableBitSet columnToUpdateSet = new FormatableBitSet(
3265:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT);
3266:                columnToUpdateSet
3267:                        .set(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID - 1);
3268:                columnToUpdateSet
3269:                        .set(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE - 1);
3270:
3271:                DataValueDescriptor[] replaceRow = new DataValueDescriptor[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT];
3272:
3273:                /* Set up a couple of row templates for fetching CHARS */
3274:
3275:                replaceRow[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID - 1] = dvf
3276:                        .getDataValue(false);
3277:                replaceRow[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE - 1] = dvf
3278:                        .getDataValue((Object) null);
3279:
3280:                /* Scan the entire heap */
3281:                ScanController sc = tc.openScan(ti.getHeapConglomerate(),
3282:                        false, TransactionController.OPENMODE_FORUPDATE,
3283:                        TransactionController.MODE_TABLE,
3284:                        TransactionController.ISOLATION_REPEATABLE_READ,
3285:                        columnToReadSet, (DataValueDescriptor[]) null,
3286:                        ScanController.NA, (Qualifier[][]) null,
3287:                        (DataValueDescriptor[]) null, ScanController.NA);
3288:
3289:                while (sc.fetchNext((DataValueDescriptor[]) null)) {
3290:                    /* Replace the column in the table */
3291:                    sc.replace(replaceRow, columnToUpdateSet);
3292:                }
3293:
3294:                sc.close();
3295:            }
3296:
3297:            /**
3298:             * Drops the given SPSDescriptor.
3299:             *
3300:             * @param descriptor	The descriptor to drop
3301:             * @param tc	The TransactionController.
3302:             *
3303:             * @exception StandardException		Thrown on failure
3304:             */
3305:            public void dropSPSDescriptor(SPSDescriptor descriptor,
3306:                    TransactionController tc) throws StandardException {
3307:                dropSPSDescriptor(descriptor.getUUID(), tc);
3308:            }
3309:
3310:            /**
3311:             * Drops the given SPSDescriptor. 
3312:             *
3313:             * @param uuid	the statement uuid
3314:             * @param tc	The TransactionController.
3315:             *
3316:             * @exception StandardException		Thrown on failure
3317:             */
3318:            public void dropSPSDescriptor(UUID uuid, TransactionController tc)
3319:                    throws StandardException {
3320:                DataValueDescriptor stmtIdOrderable;
3321:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3322:
3323:                stmtIdOrderable = getValueAsDVD(uuid);
3324:
3325:                /* Set up the start/stop position for the scan */
3326:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
3327:                        .getIndexableRow(1);
3328:                keyRow.setColumn(1, stmtIdOrderable);
3329:
3330:                ti.deleteRow(tc, keyRow,
3331:                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID);
3332:
3333:                /* drop all columns in SYSCOLUMNS */
3334:                dropAllColumnDescriptors(uuid, tc);
3335:            }
3336:
3337:            /**
3338:             * Get every statement in this database.
3339:             * Return the SPSDescriptors in an list.
3340:             *
3341:             * @return the list of descriptors
3342:             *
3343:             * @exception StandardException		Thrown on failure
3344:             */
3345:            public List getAllSPSDescriptors() throws StandardException {
3346:                TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3347:
3348:                List list = newSList();
3349:
3350:                getDescriptorViaHeap((ScanQualifier[][]) null, ti,
3351:                        (TupleDescriptor) null, list);
3352:
3353:                return list;
3354:
3355:            }
3356:
3357:            /**
3358:             * Get every constraint in this database.
3359:             * Note that this list of ConstraintDescriptors is
3360:             * not going to be the same objects that are typically
3361:             * cached off of the table descriptors, so this will
3362:             * most likely instantiate some duplicate objects.
3363:             *
3364:             * @return the list of descriptors
3365:             *
3366:             * @exception StandardException		Thrown on failure
3367:             */
3368:            private ConstraintDescriptorList getAllConstraintDescriptors()
3369:                    throws StandardException {
3370:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3371:
3372:                ConstraintDescriptorList list = new ConstraintDescriptorList();
3373:
3374:                getConstraintDescriptorViaHeap((ScanQualifier[][]) null, ti,
3375:                        (TupleDescriptor) null, list);
3376:                return list;
3377:            }
3378:
3379:            /**
3380:             * Get every trigger in this database.
3381:             * Note that this list of TriggerDescriptors is
3382:             * not going to be the same objects that are typically
3383:             * cached off of the table descriptors, so this will
3384:             * most likely instantiate some duplicate objects.
3385:             *
3386:             * @return the list of descriptors
3387:             *
3388:             * @exception StandardException		Thrown on failure
3389:             */
3390:            private GenericDescriptorList getAllTriggerDescriptors()
3391:                    throws StandardException {
3392:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3393:
3394:                GenericDescriptorList list = new GenericDescriptorList();
3395:
3396:                getDescriptorViaHeap((ScanQualifier[][]) null, ti,
3397:                        (TupleDescriptor) null, list);
3398:                return list;
3399:            }
3400:
3401:            /**
3402:             * Get a TriggerDescriptor given its UUID.
3403:             *
3404:             * @param uuid	The UUID
3405:             *
3406:             * @return The TriggerDescriptor for the constraint.
3407:             *
3408:             * @exception StandardException		Thrown on failure
3409:             */
3410:            public TriggerDescriptor getTriggerDescriptor(UUID uuid)
3411:                    throws StandardException {
3412:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3413:                DataValueDescriptor triggerIdOrderable = dvf
3414:                        .getCharDataValue(uuid.toString());
3415:
3416:                /* Set up the start/stop position for the scan */
3417:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
3418:                keyRow.setColumn(1, triggerIdOrderable);
3419:
3420:                return (TriggerDescriptor) getDescriptorViaIndex(
3421:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID, keyRow,
3422:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
3423:                        (List) null, false);
3424:            }
3425:
3426:            /** 
3427:             * Get the stored prepared statement descriptor given 
3428:             * a sps name.
3429:             *
3430:             * @param name	The sps name.
3431:             * @param sd	The schema descriptor.
3432:             *
3433:             * @return The TriggerDescriptor for the constraint.
3434:             *
3435:             * @exception StandardException		Thrown on failure
3436:             */
3437:            public TriggerDescriptor getTriggerDescriptor(String name,
3438:                    SchemaDescriptor sd) throws StandardException {
3439:                DataValueDescriptor schemaIDOrderable;
3440:                DataValueDescriptor triggerNameOrderable;
3441:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3442:
3443:                /* Use triggerNameOrderable and schemaIdOrderable in both start 
3444:                 * and stop position for scan. 
3445:                 */
3446:                triggerNameOrderable = dvf.getVarcharDataValue(name);
3447:                schemaIDOrderable = dvf.getCharDataValue(sd.getUUID()
3448:                        .toString());
3449:
3450:                /* Set up the start/stop position for the scan */
3451:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
3452:                keyRow.setColumn(1, triggerNameOrderable);
3453:                keyRow.setColumn(2, schemaIDOrderable);
3454:
3455:                return (TriggerDescriptor) getDescriptorViaIndex(
3456:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX2_ID, keyRow,
3457:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
3458:                        (List) null, false);
3459:            }
3460:
3461:            /**
3462:             * Load up the trigger descriptor list for this table
3463:             * descriptor and return it.  If the descriptor list
3464:             * is already loaded up, it is retuned without further
3465:             * ado.
3466:             *
3467:             * @param td			The table descriptor.
3468:             *
3469:             * @return The ConstraintDescriptorList for the table
3470:             *
3471:             * @exception StandardException		Thrown on failure
3472:             */
3473:            public GenericDescriptorList getTriggerDescriptors(
3474:                    TableDescriptor td) throws StandardException {
3475:                GenericDescriptorList gdl;
3476:
3477:                if (td == null) {
3478:                    return getAllTriggerDescriptors();
3479:                }
3480:
3481:                /* Build the TableDescriptor's TDL if it is currently empty */
3482:                gdl = td.getTriggerDescriptorList();
3483:
3484:                /*
3485:                 ** Synchronize the building of the TDL.  The TDL itself is created
3486:                 ** empty when the TD is created, so there is no need to synchronize
3487:                 ** the getting of the TDL.
3488:                 */
3489:                synchronized (gdl) {
3490:                    if (!gdl.getScanned()) {
3491:                        getTriggerDescriptorsScan(td, false);
3492:                    }
3493:                }
3494:
3495:                return gdl;
3496:            }
3497:
3498:            /** 
3499:             * Populate the GenericDescriptorList for the specified TableDescriptor.
3500:             *
3501:             * MT synchronization: it is assumed that the caller has synchronized
3502:             * on the CDL in the given TD.
3503:             *
3504:             * @param td				The TableDescriptor.
3505:             * @param forUpdate			Whether or not to open scan for update
3506:             *
3507:             * @exception StandardException		Thrown on failure
3508:             */
3509:            private void getTriggerDescriptorsScan(TableDescriptor td,
3510:                    boolean forUpdate) throws StandardException {
3511:                GenericDescriptorList gdl = (td).getTriggerDescriptorList();
3512:                DataValueDescriptor tableIDOrderable = null;
3513:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3514:
3515:                /* Use tableIDOrderable in both start and stop positions for scan */
3516:                tableIDOrderable = getValueAsDVD(td.getUUID());
3517:
3518:                /* Set up the start/stop position for the scan */
3519:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
3520:                        .getIndexableRow(1);
3521:
3522:                keyRow.setColumn(1, tableIDOrderable);
3523:
3524:                getDescriptorViaIndex(
3525:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX3_ID, keyRow,
3526:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
3527:                        gdl, forUpdate);
3528:                gdl.setScanned(true);
3529:            }
3530:
3531:            /**
3532:             * Drops the given TriggerDescriptor.  WARNING: does
3533:             * not drop its SPSes!!!
3534:             *
3535:             * @param descriptor	The descriptor to drop
3536:             * @param tc	The TransactionController.
3537:             *
3538:             * @exception StandardException		Thrown on failure
3539:             */
3540:            public void dropTriggerDescriptor(TriggerDescriptor descriptor,
3541:                    TransactionController tc) throws StandardException {
3542:                DataValueDescriptor idOrderable;
3543:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3544:
3545:                idOrderable = getValueAsDVD(descriptor.getUUID());
3546:
3547:                /* Set up the start/stop position for the scan */
3548:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
3549:                        .getIndexableRow(1);
3550:                keyRow.setColumn(1, idOrderable);
3551:
3552:                ti.deleteRow(tc, keyRow,
3553:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID);
3554:            }
3555:
3556:            /**
3557:             * Update the trigger descriptor in question.  Updates
3558:             * every row in the base conglomerate that matches the uuid.
3559:             *
3560:             * @param triggerd				The Trigger descriptor
3561:             * @param formerUUID			The UUID for this column in SYSTRIGGERS,
3562:             *								may differ from what is in triggerd if this
3563:             *								is the column that is being set.
3564:             * @param colsToSet 			Array of ints of columns to be modified,
3565:             *								1 based.  May be null (all cols).
3566:             * @param tc					The TransactionController to use
3567:             *
3568:             * @exception StandardException		Thrown on failure
3569:             */
3570:            public void updateTriggerDescriptor(TriggerDescriptor triggerd,
3571:                    UUID formerUUID, int[] colsToSet, TransactionController tc)
3572:                    throws StandardException {
3573:                ExecIndexRow keyRow1 = null;
3574:                ExecRow row;
3575:                DataValueDescriptor IDOrderable;
3576:                DataValueDescriptor columnNameOrderable;
3577:                TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3578:                SYSTRIGGERSRowFactory rf = (SYSTRIGGERSRowFactory) ti
3579:                        .getCatalogRowFactory();
3580:
3581:                /* Use objectID in both start 
3582:                 * and stop position for index 1 scan. 
3583:                 */
3584:                IDOrderable = getValueAsDVD(formerUUID);
3585:
3586:                /* Set up the start/stop position for the scan */
3587:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
3588:                keyRow1.setColumn(1, IDOrderable);
3589:
3590:                // build the row to be stuffed into SYSTRIGGERS. 
3591:                row = rf.makeRow(triggerd, null);
3592:
3593:                /*
3594:                 ** Figure out if the index in systriggers needs 
3595:                 ** to be updated. 
3596:                 */
3597:                if (SanityManager.DEBUG) {
3598:                    SanityManager
3599:                            .ASSERT(
3600:                                    rf.getNumIndexes() == 3,
3601:                                    "There are more indexes on systriggers than expected, the code herein needs to change");
3602:                }
3603:
3604:                boolean[] bArray = new boolean[3];
3605:
3606:                /*
3607:                 ** Do we need to update indexes?
3608:                 */
3609:                if (colsToSet == null) {
3610:                    bArray[0] = true;
3611:                    bArray[1] = true;
3612:                    bArray[2] = true;
3613:                } else {
3614:                    /*
3615:                     ** Check the specific columns for indexed
3616:                     ** columns.
3617:                     */
3618:                    for (int i = 0; i < colsToSet.length; i++) {
3619:                        switch (colsToSet[i]) {
3620:                        case SYSTRIGGERSRowFactory.SYSTRIGGERS_TRIGGERID:
3621:                            bArray[0] = true;
3622:                            break;
3623:
3624:                        case SYSTRIGGERSRowFactory.SYSTRIGGERS_TRIGGERNAME:
3625:                        case SYSTRIGGERSRowFactory.SYSTRIGGERS_SCHEMAID:
3626:                            bArray[1] = true;
3627:                            break;
3628:
3629:                        case SYSTRIGGERSRowFactory.SYSTRIGGERS_TABLEID:
3630:                            bArray[2] = true;
3631:                            break;
3632:                        }
3633:                    }
3634:                }
3635:
3636:                ti.updateRow(keyRow1, row,
3637:                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID, bArray,
3638:                        colsToSet, tc);
3639:            }
3640:
3641:            /**
3642:             * Get a ConstraintDescriptor given its UUID.  Please
3643:             * use getConstraintDescriptorById() is you have the
3644:             * constraints table descriptor, it is much faster.
3645:             *
3646:             * @param uuid	The UUID
3647:             *
3648:             *
3649:             * @return The ConstraintDescriptor for the constraint.
3650:             *
3651:             * @exception StandardException		Thrown on failure
3652:             */
3653:            public ConstraintDescriptor getConstraintDescriptor(UUID uuid)
3654:                    throws StandardException {
3655:                DataValueDescriptor UUIDStringOrderable;
3656:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3657:
3658:                /* Use UUIDStringOrderable in both start and stop positions for scan */
3659:                UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
3660:
3661:                /* Set up the start/stop position for the scan */
3662:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
3663:                keyRow.setColumn(1, UUIDStringOrderable);
3664:
3665:                return getConstraintDescriptorViaIndex(
3666:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
3667:                        keyRow, ti, (TableDescriptor) null,
3668:                        (ConstraintDescriptorList) null, false);
3669:            }
3670:
3671:            /**
3672:             * Get a ConstraintDescriptor given its name and schema ID.
3673:             * Please use getConstraintDescriptorByName() if you have the
3674:             * constraint's table descriptor, it is much faster.
3675:             *
3676:             * @param constraintName	Constraint name.
3677:             * @param schemaID			The schema UUID
3678:             *
3679:             * @return The ConstraintDescriptor for the constraint.
3680:             *
3681:             * @exception StandardException		Thrown on failure
3682:             */
3683:            public ConstraintDescriptor getConstraintDescriptor(
3684:                    String constraintName, UUID schemaID)
3685:                    throws StandardException {
3686:                DataValueDescriptor UUIDStringOrderable;
3687:                DataValueDescriptor constraintNameOrderable;
3688:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3689:
3690:                /* Construct keys for both start and stop positions for scan */
3691:                constraintNameOrderable = dvf
3692:                        .getVarcharDataValue(constraintName);
3693:                UUIDStringOrderable = dvf.getCharDataValue(schemaID.toString());
3694:
3695:                /* Set up the start/stop position for the scan */
3696:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
3697:                keyRow.setColumn(1, constraintNameOrderable);
3698:                keyRow.setColumn(2, UUIDStringOrderable);
3699:
3700:                return getConstraintDescriptorViaIndex(
3701:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID,
3702:                        keyRow, ti, (TableDescriptor) null,
3703:                        (ConstraintDescriptorList) null, false);
3704:            }
3705:
3706:            /** get all the statistiscs descriptors for a given table.
3707:             * @param  td	Table Descriptor for which I need statistics
3708:             */
3709:            public List getStatisticsDescriptors(TableDescriptor td)
3710:                    throws StandardException {
3711:                TabInfoImpl ti = getNonCoreTI(SYSSTATISTICS_CATALOG_NUM);
3712:                List statDescriptorList = newSList();
3713:                DataValueDescriptor UUIDStringOrderable;
3714:
3715:                /* set up the start/stop position for the scan */
3716:                UUIDStringOrderable = dvf.getCharDataValue(td.getUUID()
3717:                        .toString());
3718:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
3719:                keyRow.setColumn(1, UUIDStringOrderable);
3720:
3721:                getDescriptorViaIndex(
3722:                        SYSSTATISTICSRowFactory.SYSSTATISTICS_INDEX1_ID,
3723:                        keyRow, (ScanQualifier[][]) null, ti,
3724:                        (TupleDescriptor) null, statDescriptorList, false);
3725:
3726:                return statDescriptorList;
3727:            }
3728:
3729:            /**
3730:             * Load up the constraint descriptor list for this table
3731:             * descriptor and return it.  If the descriptor list
3732:             * is already loaded up, it is retuned without further
3733:             * ado.  If no table descriptor is passed in, then all
3734:             * constraint descriptors are retrieved.  Note that in 
3735:             * this case, the constraint descriptor objects may be
3736:             * duplicates of constraint descriptors that are hung
3737:             * off of the table descriptor cache.
3738:             *
3739:             * @param td			The table descriptor.  If null,
3740:             *						all constraint descriptors are returned.
3741:             *
3742:             *
3743:             * @return The ConstraintDescriptorList for the table
3744:             *
3745:             * @exception StandardException		Thrown on failure
3746:             */
3747:            public ConstraintDescriptorList getConstraintDescriptors(
3748:                    TableDescriptor td) throws StandardException {
3749:                ConstraintDescriptorList cdl;
3750:
3751:                if (td == null) {
3752:                    return getAllConstraintDescriptors();
3753:                }
3754:
3755:                /* RESOLVE - need to look at multi-user aspects of hanging constraint
3756:                 * descriptor list off of table descriptor when we restore the cache.
3757:                 */
3758:
3759:                /* Build the TableDescriptor's CDL if it is currently empty */
3760:                cdl = td.getConstraintDescriptorList();
3761:
3762:                /*
3763:                 ** Synchronize the building of the CDL.  The CDL itself is created
3764:                 ** empty when the TD is created, so there is no need to synchronize
3765:                 ** the getting of the CDL.
3766:                 */
3767:                synchronized (cdl) {
3768:                    if (!cdl.getScanned()) {
3769:                        getConstraintDescriptorsScan(td, false);
3770:                    }
3771:                }
3772:
3773:                return cdl;
3774:            }
3775:
3776:            /**
3777:             * Convert a constraint descriptor list into a list
3778:             * of active constraints, that is, constraints which
3779:             * must be enforced. For the Core product, these
3780:             * are just the constraints on the original list.
3781:             * However, during REFRESH we may have deferred some
3782:             * constraints until statement end. This method returns
3783:             * the corresponding list of constraints which AREN'T
3784:             * deferred.
3785:             *
3786:             * @param cdl	The constraint descriptor list to wrap with
3787:             *				an Active constraint descriptor list.
3788:             *
3789:             * @return The corresponding Active ConstraintDescriptorList
3790:             *
3791:             * @exception StandardException		Thrown on failure
3792:             */
3793:            public ConstraintDescriptorList getActiveConstraintDescriptors(
3794:                    ConstraintDescriptorList cdl) throws StandardException {
3795:                return cdl;
3796:            }
3797:
3798:            /**
3799:             * Reports whether an individual constraint must be
3800:             * enforced. For the Core product, this routine always
3801:             * returns true.
3802:             *
3803:             * However, during REFRESH we may have deferred some
3804:             * constraints until statement end. This method returns
3805:             * false if the constraint deferred
3806:             *
3807:             * @param constraint	the constraint to check
3808:             *
3809:             *
3810:             * @return The corresponding Active ConstraintDescriptorList
3811:             *
3812:             * @exception StandardException		Thrown on failure
3813:             */
3814:            public boolean activeConstraint(ConstraintDescriptor constraint)
3815:                    throws StandardException {
3816:                return true;
3817:            }
3818:
3819:            /** 
3820:             * Get the constraint descriptor given a table and the UUID String
3821:             * of the backing index.
3822:             *
3823:             * @param td			The table descriptor.
3824:             * @param uuid			the UUID for the backing index.
3825:             *
3826:             * @return The ConstraintDescriptor for the constraint.
3827:             *
3828:             * @exception StandardException		Thrown on failure
3829:             */
3830:            public ConstraintDescriptor getConstraintDescriptor(
3831:                    TableDescriptor td, UUID uuid) throws StandardException {
3832:                return getConstraintDescriptors(td).getConstraintDescriptor(
3833:                        uuid);
3834:            }
3835:
3836:            /**
3837:             * Get the constraint descriptor given a table and the UUID String
3838:             * of the constraint
3839:             *
3840:             * @param td			The table descriptor.
3841:             * @param uuid			The UUID for the constraint
3842:             *
3843:             * @return The ConstraintDescriptor for the constraint.
3844:             *
3845:             * @exception StandardException		Thrown on failure
3846:             */
3847:            public ConstraintDescriptor getConstraintDescriptorById(
3848:                    TableDescriptor td, UUID uuid) throws StandardException {
3849:                return getConstraintDescriptors(td)
3850:                        .getConstraintDescriptorById(uuid);
3851:            }
3852:
3853:            /** 
3854:             * Get the constraint descriptor given a TableDescriptor and the constraint name.
3855:             *
3856:             * @param td				The table descriptor.
3857:             * @param sd				The schema descriptor for the constraint
3858:             * @param constraintName	The constraint name.
3859:             * @param forUpdate			Whether or not access is for update
3860:             *
3861:             * @return The ConstraintDescriptor for the constraint.
3862:             *
3863:             * @exception StandardException		Thrown on failure
3864:             */
3865:            public ConstraintDescriptor getConstraintDescriptorByName(
3866:                    TableDescriptor td, SchemaDescriptor sd,
3867:                    String constraintName, boolean forUpdate)
3868:                    throws StandardException {
3869:                /* If forUpdate, then we need to actually read from the table. */
3870:                if (forUpdate) {
3871:                    td.emptyConstraintDescriptorList();
3872:                    getConstraintDescriptorsScan(td, true);
3873:                }
3874:                return getConstraintDescriptors(td)
3875:                        .getConstraintDescriptorByName(sd, constraintName);
3876:            }
3877:
3878:            /** 
3879:             * Populate the ConstraintDescriptorList for the specified TableDescriptor.
3880:             *
3881:             * MT synchronization: it is assumed that the caller has synchronized
3882:             * on the CDL in the given TD.
3883:             *
3884:             * @param td				The TableDescriptor.
3885:             * @param forUpdate			Whether or not to open scan for update
3886:             *
3887:             * @exception StandardException		Thrown on failure
3888:             */
3889:            private void getConstraintDescriptorsScan(TableDescriptor td,
3890:                    boolean forUpdate) throws StandardException {
3891:                ConstraintDescriptorList cdl = td.getConstraintDescriptorList();
3892:                DataValueDescriptor tableIDOrderable = null;
3893:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3894:
3895:                /* Use tableIDOrderable in both start and stop positions for scan */
3896:                tableIDOrderable = getValueAsDVD(td.getUUID());
3897:
3898:                /* Set up the start/stop position for the scan */
3899:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
3900:                        .getIndexableRow(1);
3901:
3902:                keyRow.setColumn(1, tableIDOrderable);
3903:
3904:                getConstraintDescriptorViaIndex(
3905:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX3_ID,
3906:                        keyRow, ti, td, cdl, forUpdate);
3907:                cdl.setScanned(true);
3908:            }
3909:
3910:            /**
3911:             * Return a (single or list of) ConstraintDescriptor(s) from
3912:             * SYSCONSTRAINTS where the access is from the index to the heap.
3913:             *
3914:             * @param indexId	The id of the index (0 to # of indexes on table) to use
3915:             * @param keyRow	The supplied ExecIndexRow for search
3916:             * @param ti		The TabInfoImpl to use
3917:             * @param td		The TableDescriptor, if supplied.
3918:             * @param dList		The list to build, if supplied.  If null, then caller expects
3919:             *					a single descriptor
3920:             * @param forUpdate			Whether or not to open scan for update
3921:             *
3922:             * @return	The last matching descriptor
3923:             *
3924:             * @exception StandardException		Thrown on error
3925:             */
3926:            protected ConstraintDescriptor getConstraintDescriptorViaIndex(
3927:                    int indexId, ExecIndexRow keyRow, TabInfoImpl ti,
3928:                    TableDescriptor td, ConstraintDescriptorList dList,
3929:                    boolean forUpdate) throws StandardException {
3930:                SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti
3931:                        .getCatalogRowFactory();
3932:                ConglomerateController heapCC;
3933:                ConstraintDescriptor cd = null;
3934:                ExecIndexRow indexRow1;
3935:                ExecIndexRow indexTemplateRow;
3936:                ExecRow outRow;
3937:                RowLocation baseRowLocation;
3938:                ScanController scanController;
3939:                TransactionController tc;
3940:
3941:                // Get the current transaction controller
3942:                tc = getTransactionCompile();
3943:
3944:                outRow = rf.makeEmptyRow();
3945:
3946:                heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false,
3947:                        0, TransactionController.MODE_RECORD,
3948:                        TransactionController.ISOLATION_REPEATABLE_READ);
3949:
3950:                /* Scan the index and go to the data pages for qualifying rows to
3951:                 * build the column descriptor.
3952:                 */
3953:                scanController = tc.openScan(
3954:                        ti.getIndexConglomerate(indexId), // conglomerate to open
3955:                        false, // don't hold open across commit
3956:                        (forUpdate) ? TransactionController.OPENMODE_FORUPDATE
3957:                                : 0, TransactionController.MODE_RECORD,
3958:                        TransactionController.ISOLATION_REPEATABLE_READ,
3959:                        (FormatableBitSet) null, // all fields as objects
3960:                        keyRow.getRowArray(), // start position - exact key match.
3961:                        ScanController.GE, // startSearchOperation
3962:                        null, //scanQualifier,
3963:                        keyRow.getRowArray(), // stop position - exact key match.
3964:                        ScanController.GT); // stopSearchOperation
3965:
3966:                while (scanController.next()) {
3967:                    SubConstraintDescriptor subCD = null;
3968:
3969:                    // create an index row template
3970:                    indexRow1 = getIndexRowFromHeapRow(ti
3971:                            .getIndexRowGenerator(indexId), heapCC
3972:                            .newRowLocationTemplate(), outRow);
3973:
3974:                    scanController.fetch(indexRow1.getRowArray());
3975:
3976:                    baseRowLocation = (RowLocation) indexRow1
3977:                            .getColumn(indexRow1.nColumns());
3978:
3979:                    boolean base_row_exists = heapCC.fetch(baseRowLocation,
3980:                            outRow.getRowArray(), (FormatableBitSet) null);
3981:
3982:                    if (SanityManager.DEBUG) {
3983:                        // it can not be possible for heap row to disappear while 
3984:                        // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
3985:                        SanityManager.ASSERT(base_row_exists,
3986:                                "base row doesn't exist");
3987:                    }
3988:
3989:                    switch (rf.getConstraintType(outRow)) {
3990:                    case DataDictionary.PRIMARYKEY_CONSTRAINT:
3991:                    case DataDictionary.FOREIGNKEY_CONSTRAINT:
3992:                    case DataDictionary.UNIQUE_CONSTRAINT:
3993:                        subCD = getSubKeyConstraint(rf.getConstraintId(outRow),
3994:                                rf.getConstraintType(outRow));
3995:                        break;
3996:
3997:                    case DataDictionary.CHECK_CONSTRAINT:
3998:                        subCD = getSubCheckConstraint(rf
3999:                                .getConstraintId(outRow));
4000:                        break;
4001:
4002:                    default:
4003:                        if (SanityManager.DEBUG) {
4004:                            SanityManager.THROWASSERT("unexpected value "
4005:                                    + "from rf.getConstraintType(outRow)"
4006:                                    + rf.getConstraintType(outRow));
4007:                        }
4008:                    }
4009:
4010:                    if (SanityManager.DEBUG) {
4011:                        SanityManager.ASSERT(subCD != null,
4012:                                "subCD is expected to be non-null");
4013:                    }
4014:
4015:                    /* Cache the TD in the SCD so that
4016:                     * the row factory doesn't need to go
4017:                     * out to disk to get it.
4018:                     */
4019:                    subCD.setTableDescriptor(td);
4020:
4021:                    cd = (ConstraintDescriptor) rf.buildDescriptor(outRow,
4022:                            subCD, this );
4023:
4024:                    /* If dList is null, then caller only wants a single descriptor - we're done
4025:                     * else just add the current descriptor to the list.
4026:                     */
4027:                    if (dList == null) {
4028:                        break;
4029:                    } else {
4030:                        dList.add(cd);
4031:                    }
4032:                }
4033:                scanController.close();
4034:                heapCC.close();
4035:                return cd;
4036:            }
4037:
4038:            /**
4039:             * Return a (single or list of) catalog row descriptor(s) from
4040:             * SYSCONSTRAINTS through a heap scan 
4041:             *
4042:             * @param scanQualifiers			qualifiers
4043:             * @param ti						The TabInfoImpl to use
4044:             * @param parentTupleDescriptor		The parentDescriptor, if applicable.
4045:             * @param list						The list to build, if supplied.  
4046:             *									If null, then caller expects a single descriptor
4047:             *
4048:             * @return	The last matching descriptor
4049:             *
4050:             * @exception StandardException		Thrown on error
4051:             */
4052:            protected TupleDescriptor getConstraintDescriptorViaHeap(
4053:                    ScanQualifier[][] scanQualifiers, TabInfoImpl ti,
4054:                    TupleDescriptor parentTupleDescriptor, List list)
4055:                    throws StandardException {
4056:                SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti
4057:                        .getCatalogRowFactory();
4058:                ConglomerateController heapCC;
4059:                ExecRow outRow;
4060:                ExecRow templateRow;
4061:                ScanController scanController;
4062:                TransactionController tc;
4063:                ConstraintDescriptor cd = null;
4064:
4065:                // Get the current transaction controller
4066:                tc = getTransactionCompile();
4067:
4068:                outRow = rf.makeEmptyRow();
4069:
4070:                /*
4071:                 ** Table scan
4072:                 */
4073:                scanController = tc.openScan(
4074:                        ti.getHeapConglomerate(), // conglomerate to open
4075:                        false, // don't hold open across commit
4076:                        0, // for read
4077:                        TransactionController.MODE_TABLE,
4078:                        TransactionController.ISOLATION_REPEATABLE_READ,
4079:                        (FormatableBitSet) null, // all fields as objects
4080:                        (DataValueDescriptor[]) null, // start position - first row
4081:                        0, // startSearchOperation - none
4082:                        scanQualifiers, // scanQualifier,
4083:                        (DataValueDescriptor[]) null, // stop position -through last row
4084:                        0); // stopSearchOperation - none
4085:
4086:                try {
4087:                    while (scanController.fetchNext(outRow.getRowArray())) {
4088:                        SubConstraintDescriptor subCD = null;
4089:
4090:                        switch (rf.getConstraintType(outRow)) {
4091:                        case DataDictionary.PRIMARYKEY_CONSTRAINT:
4092:                        case DataDictionary.FOREIGNKEY_CONSTRAINT:
4093:                        case DataDictionary.UNIQUE_CONSTRAINT:
4094:                            subCD = getSubKeyConstraint(rf
4095:                                    .getConstraintId(outRow), rf
4096:                                    .getConstraintType(outRow));
4097:                            break;
4098:
4099:                        case DataDictionary.CHECK_CONSTRAINT:
4100:                            subCD = getSubCheckConstraint(rf
4101:                                    .getConstraintId(outRow));
4102:                            break;
4103:
4104:                        default:
4105:                            if (SanityManager.DEBUG) {
4106:                                SanityManager
4107:                                        .THROWASSERT("unexpected value from "
4108:                                                + " rf.getConstraintType(outRow) "
4109:                                                + rf.getConstraintType(outRow));
4110:                            }
4111:                        }
4112:
4113:                        if (SanityManager.DEBUG) {
4114:                            SanityManager.ASSERT(subCD != null,
4115:                                    "subCD is expected to be non-null");
4116:                        }
4117:                        cd = (ConstraintDescriptor) rf.buildDescriptor(outRow,
4118:                                subCD, this );
4119:
4120:                        /* If dList is null, then caller only wants a single descriptor - we're done
4121:                         * else just add the current descriptor to the list.
4122:                         */
4123:                        if (list == null) {
4124:                            break;
4125:                        } else {
4126:                            list.add(cd);
4127:                        }
4128:                    }
4129:                } finally {
4130:                    scanController.close();
4131:                }
4132:                return cd;
4133:            }
4134:
4135:            /**
4136:             * Return a table descriptor corresponding to the TABLEID
4137:             * field in SYSCONSTRAINTS where CONSTRAINTID matches
4138:             * the constraintId passsed in.
4139:             *
4140:             * @param constraintId	The id of the constraint
4141:             *
4142:             * @return	the corresponding table descriptor
4143:             *
4144:             * @exception StandardException		Thrown on error
4145:             */
4146:            public TableDescriptor getConstraintTableDescriptor(
4147:                    UUID constraintId) throws StandardException {
4148:                List slist = getConstraints(constraintId,
4149:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
4150:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_TABLEID);
4151:
4152:                if (slist.size() == 0) {
4153:                    return null;
4154:                }
4155:
4156:                // get the table descriptor	
4157:                return getTableDescriptor((UUID) slist.get(0));
4158:            }
4159:
4160:            /**
4161:             * Return a list of foreign keys constraints referencing
4162:             * this constraint.  Returns both enabled and disabled
4163:             * foreign keys.  
4164:             *
4165:             * @param constraintId	The id of the referenced constraint
4166:             *
4167:             * @return	list of constraints, empty of there are none
4168:             *
4169:             * @exception StandardException		Thrown on error
4170:             */
4171:            public ConstraintDescriptorList getForeignKeys(UUID constraintId)
4172:                    throws StandardException {
4173:                TabInfoImpl ti = getNonCoreTI(SYSFOREIGNKEYS_CATALOG_NUM);
4174:                List fkList = newSList();
4175:
4176:                // Use constraintIDOrderable in both start and stop positions for scan
4177:                DataValueDescriptor constraintIDOrderable = getValueAsDVD(constraintId);
4178:
4179:                /* Set up the start/stop position for the scan */
4180:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
4181:                        .getIndexableRow(1);
4182:                keyRow.setColumn(1, constraintIDOrderable);
4183:
4184:                getDescriptorViaIndex(
4185:                        SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX2_ID,
4186:                        keyRow, (ScanQualifier[][]) null, ti,
4187:                        (TupleDescriptor) null, fkList, false);
4188:
4189:                SubKeyConstraintDescriptor cd;
4190:                TableDescriptor td;
4191:                ConstraintDescriptorList cdl = new ConstraintDescriptorList();
4192:                ConstraintDescriptorList tmpCdl;
4193:
4194:                for (Iterator iterator = fkList.iterator(); iterator.hasNext();) {
4195:                    cd = (SubKeyConstraintDescriptor) iterator.next();
4196:                    td = getConstraintTableDescriptor(cd.getUUID());
4197:                    cdl.add(getConstraintDescriptors(td)
4198:                            .getConstraintDescriptorById(cd.getUUID()));
4199:                }
4200:
4201:                return cdl;
4202:            }
4203:
4204:            /**
4205:             * Return an List which of the relevant column matching
4206:             * the indexed criteria.  If nothing matches, returns an
4207:             * empty List (never returns null).
4208:             *
4209:             * @param uuid	The id of the constraint
4210:             * @param indexId		The index id in SYS.SYSCONSTRAINTS
4211:             * @param columnNum		The column to retrieve
4212:             *
4213:             * @return a list of UUIDs in an List.
4214:             *
4215:             * @exception StandardException		Thrown on error
4216:             */
4217:            public List getConstraints(UUID uuid, int indexId, int columnNum)
4218:                    throws StandardException {
4219:                ExecIndexRow indexRow1;
4220:                ExecIndexRow indexTemplateRow;
4221:                ExecRow outRow;
4222:                RowLocation baseRowLocation;
4223:                ConglomerateController heapCC = null;
4224:                ScanController scanController = null;
4225:                TransactionController tc;
4226:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4227:                SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti
4228:                        .getCatalogRowFactory();
4229:                TableDescriptor td = null;
4230:                List slist = newSList();
4231:
4232:                if (SanityManager.DEBUG) {
4233:                    SanityManager
4234:                            .ASSERT(
4235:                                    indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID
4236:                                            || indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX3_ID,
4237:                                    "bad index id, must be one of the indexes on a uuid");
4238:                    SanityManager
4239:                            .ASSERT(
4240:                                    columnNum > 0
4241:                                            && columnNum <= SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT,
4242:                                    "invalid column number for column to be retrieved");
4243:                }
4244:
4245:                try {
4246:                    /* Use tableIDOrderable in both start and stop positions for scan */
4247:                    DataValueDescriptor orderable = getValueAsDVD(uuid);
4248:
4249:                    /* Set up the start/stop position for the scan */
4250:                    ExecIndexRow keyRow = (ExecIndexRow) exFactory
4251:                            .getIndexableRow(1);
4252:                    keyRow.setColumn(1, orderable);
4253:
4254:                    // Get the current transaction controller
4255:                    tc = getTransactionCompile();
4256:
4257:                    outRow = rf.makeEmptyRow();
4258:
4259:                    heapCC = tc.openConglomerate(ti.getHeapConglomerate(),
4260:                            false, 0, TransactionController.MODE_RECORD,
4261:                            TransactionController.ISOLATION_REPEATABLE_READ);
4262:
4263:                    // create an index row template
4264:                    indexRow1 = getIndexRowFromHeapRow(ti
4265:                            .getIndexRowGenerator(indexId), heapCC
4266:                            .newRowLocationTemplate(), outRow);
4267:
4268:                    // just interested in one column
4269:                    DataValueDescriptor[] rowTemplate = new DataValueDescriptor[SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT];
4270:                    FormatableBitSet columnToGetSet = new FormatableBitSet(
4271:                            SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT);
4272:                    columnToGetSet.set(columnNum - 1);
4273:
4274:                    rowTemplate[columnNum - 1] = dvf
4275:                            .getNullChar((StringDataValue) null);
4276:
4277:                    // Scan the index and go to the data pages for qualifying rows 
4278:                    scanController = tc.openScan(
4279:                            ti.getIndexConglomerate(indexId),// conglomerate to open
4280:                            false, // don't hold open across commit
4281:                            0, // for read
4282:                            TransactionController.MODE_RECORD,
4283:                            TransactionController.ISOLATION_REPEATABLE_READ,// RESOLVE: should be level 2
4284:                            (FormatableBitSet) null, // all fields as objects
4285:                            keyRow.getRowArray(), // start position - exact key match.
4286:                            ScanController.GE, // startSearchOperation
4287:                            null, // scanQualifier (none)
4288:                            keyRow.getRowArray(), // stop position - exact key match.
4289:                            ScanController.GT); // stopSearchOperation
4290:
4291:                    while (scanController.fetchNext(indexRow1.getRowArray())) {
4292:                        baseRowLocation = (RowLocation) indexRow1
4293:                                .getColumn(indexRow1.nColumns());
4294:
4295:                        // get the row and grab the uuid
4296:                        boolean base_row_exists = heapCC.fetch(baseRowLocation,
4297:                                rowTemplate, columnToGetSet);
4298:
4299:                        if (SanityManager.DEBUG) {
4300:                            // it can not be possible for heap row to disappear while 
4301:                            // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
4302:                            SanityManager.ASSERT(base_row_exists,
4303:                                    "base row not found");
4304:                        }
4305:
4306:                        slist
4307:                                .add(uuidFactory
4308:                                        .recreateUUID((String) ((DataValueDescriptor) rowTemplate[columnNum - 1])
4309:                                                .getObject()));
4310:                    }
4311:                } finally {
4312:                    if (heapCC != null) {
4313:                        heapCC.close();
4314:                    }
4315:                    if (scanController != null) {
4316:                        scanController.close();
4317:                    }
4318:                }
4319:                return slist;
4320:            }
4321:
4322:            /**
4323:             * Adds the given ConstraintDescriptor to the data dictionary,
4324:             * associated with the given table and constraint type.
4325:             *
4326:             * @param descriptor	The descriptor to add
4327:             * @param tc			The transaction controller
4328:             *
4329:             * @exception StandardException		Thrown on error
4330:             */
4331:            public void addConstraintDescriptor(
4332:                    ConstraintDescriptor descriptor, TransactionController tc)
4333:                    throws StandardException {
4334:                ExecRow row = null;
4335:                int type = descriptor.getConstraintType();
4336:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4337:                SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti
4338:                        .getCatalogRowFactory();
4339:                int insertRetCode;
4340:
4341:                if (SanityManager.DEBUG) {
4342:                    if (!(type == DataDictionary.PRIMARYKEY_CONSTRAINT
4343:                            || type == DataDictionary.FOREIGNKEY_CONSTRAINT
4344:                            || type == DataDictionary.UNIQUE_CONSTRAINT || type == DataDictionary.CHECK_CONSTRAINT)) {
4345:                        SanityManager.THROWASSERT("constraint type (" + type
4346:                                + ") is unexpected value");
4347:                    }
4348:                }
4349:
4350:                addDescriptor(descriptor, descriptor.getSchemaDescriptor(),
4351:                        SYSCONSTRAINTS_CATALOG_NUM, false, tc);
4352:
4353:                switch (type) {
4354:                case DataDictionary.PRIMARYKEY_CONSTRAINT:
4355:                case DataDictionary.FOREIGNKEY_CONSTRAINT:
4356:                case DataDictionary.UNIQUE_CONSTRAINT:
4357:                    if (SanityManager.DEBUG) {
4358:                        if (!(descriptor instanceof  KeyConstraintDescriptor)) {
4359:                            SanityManager
4360:                                    .THROWASSERT("descriptor expected to be instanceof KeyConstraintDescriptor, "
4361:                                            + "not, "
4362:                                            + descriptor.getClass().getName());
4363:                        }
4364:                    }
4365:
4366:                    addSubKeyConstraint((KeyConstraintDescriptor) descriptor,
4367:                            tc);
4368:                    break;
4369:
4370:                case DataDictionary.CHECK_CONSTRAINT:
4371:                    if (SanityManager.DEBUG) {
4372:                        if (!(descriptor instanceof  CheckConstraintDescriptor)) {
4373:                            SanityManager
4374:                                    .THROWASSERT("descriptor expected "
4375:                                            + "to be instanceof CheckConstraintDescriptorImpl, "
4376:                                            + "not, "
4377:                                            + descriptor.getClass().getName());
4378:                        }
4379:                    }
4380:
4381:                    addDescriptor(descriptor, null, SYSCHECKS_CATALOG_NUM,
4382:                            true, tc);
4383:                    break;
4384:                }
4385:            }
4386:
4387:            /**
4388:             * Update the constraint descriptor in question.  Updates
4389:             * every row in the base conglomerate.  
4390:             *
4391:             * @param cd					The Constraintescriptor
4392:             * @param formerUUID			The UUID for this column in SYSCONSTRAINTS,
4393:             *								may differ from what is in cd if this
4394:             *								is the column that is being set.
4395:             * @param colsToSet 			Array of ints of columns to be modified,
4396:             *								1 based.  May be null (all cols).
4397:             * @param tc					The TransactionController to use
4398:             *
4399:             * @exception StandardException		Thrown on failure
4400:             */
4401:            public void updateConstraintDescriptor(ConstraintDescriptor cd,
4402:                    UUID formerUUID, int[] colsToSet, TransactionController tc)
4403:                    throws StandardException {
4404:                ExecIndexRow keyRow1 = null;
4405:                ExecRow row;
4406:                DataValueDescriptor IDOrderable;
4407:                DataValueDescriptor columnNameOrderable;
4408:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4409:                SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti
4410:                        .getCatalogRowFactory();
4411:
4412:                /* Use objectID/columnName in both start 
4413:                 * and stop position for index 1 scan. 
4414:                 */
4415:                IDOrderable = getValueAsDVD(formerUUID);
4416:
4417:                /* Set up the start/stop position for the scan */
4418:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
4419:                keyRow1.setColumn(1, IDOrderable);
4420:
4421:                // build the row to be stuffed into SYSCONSTRAINTS. 
4422:                row = rf.makeRow(cd, null);
4423:
4424:                /*
4425:                 ** Figure out if the index in sysconstraints needs 
4426:                 ** to be updated. 
4427:                 */
4428:                if (SanityManager.DEBUG) {
4429:                    SanityManager
4430:                            .ASSERT(
4431:                                    rf.getNumIndexes() == 3,
4432:                                    "There are more indexes on sysconstraints than expected, the code herein needs to change");
4433:                }
4434:
4435:                boolean[] bArray = new boolean[3];
4436:
4437:                /*
4438:                 ** Do we need to update indexes?
4439:                 */
4440:                if (colsToSet == null) {
4441:                    bArray[0] = true;
4442:                    bArray[1] = true;
4443:                    bArray[2] = true;
4444:                } else {
4445:                    /*
4446:                     ** Check the specific columns for indexed
4447:                     ** columns.
4448:                     */
4449:                    for (int i = 0; i < colsToSet.length; i++) {
4450:                        switch (colsToSet[i]) {
4451:                        case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_CONSTRAINTID:
4452:                            bArray[0] = true;
4453:                            break;
4454:
4455:                        case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_CONSTRAINTNAME:
4456:                        case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_SCHEMAID:
4457:                            bArray[1] = true;
4458:                            break;
4459:
4460:                        case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_TABLEID:
4461:                            bArray[2] = true;
4462:                            break;
4463:                        }
4464:                    }
4465:                }
4466:
4467:                ti.updateRow(keyRow1, row,
4468:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
4469:                        bArray, colsToSet, tc);
4470:            }
4471:
4472:            /**
4473:             * Drops the given ConstraintDescriptor that is associated
4474:             * with the given table and constraint type from the data dictionary.
4475:             *
4476:             * @param table	The table from which to drop the
4477:             *			constraint descriptor
4478:             * @param descriptor	The descriptor to drop
4479:             * @param tc			The TransactionController
4480:             *
4481:             * @exception StandardException		Thrown on error
4482:             */
4483:            public void dropConstraintDescriptor(TableDescriptor table,
4484:                    ConstraintDescriptor descriptor, TransactionController tc)
4485:                    throws StandardException {
4486:                ExecIndexRow keyRow = null;
4487:                DataValueDescriptor schemaIDOrderable;
4488:                DataValueDescriptor constraintNameOrderable;
4489:                TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4490:
4491:                switch (descriptor.getConstraintType()) {
4492:                case DataDictionary.PRIMARYKEY_CONSTRAINT:
4493:                case DataDictionary.FOREIGNKEY_CONSTRAINT:
4494:                case DataDictionary.UNIQUE_CONSTRAINT:
4495:                    dropSubKeyConstraint(descriptor, tc);
4496:                    break;
4497:
4498:                case DataDictionary.CHECK_CONSTRAINT:
4499:                    dropSubCheckConstraint(descriptor.getUUID(), tc);
4500:                    break;
4501:                }
4502:
4503:                /* Use constraintNameOrderable and schemaIdOrderable in both start 
4504:                 * and stop position for index 2 scan. 
4505:                 */
4506:                constraintNameOrderable = dvf.getVarcharDataValue(descriptor
4507:                        .getConstraintName());
4508:                schemaIDOrderable = getValueAsDVD(descriptor
4509:                        .getSchemaDescriptor().getUUID());
4510:
4511:                /* Set up the start/stop position for the scan */
4512:                keyRow = (ExecIndexRow) exFactory.getIndexableRow(2);
4513:                keyRow.setColumn(1, constraintNameOrderable);
4514:                keyRow.setColumn(2, schemaIDOrderable);
4515:
4516:                ti.deleteRow(tc, keyRow,
4517:                        SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID);
4518:            }
4519:
4520:            /**
4521:             * Drops all ConstraintDescriptors from the data dictionary
4522:             * that are associated with the given table,
4523:             *
4524:             * @param table	The table from which to drop all
4525:             *			constraint descriptors
4526:             * @param tc	The TransactionController
4527:             *
4528:             * @exception StandardException		Thrown on error
4529:             */
4530:            public void dropAllConstraintDescriptors(TableDescriptor table,
4531:                    TransactionController tc) throws StandardException {
4532:                ConstraintDescriptorList cdl = getConstraintDescriptors(table);
4533:
4534:                // Walk the table's CDL and drop each ConstraintDescriptor.
4535:                for (Iterator iterator = cdl.iterator(); iterator.hasNext();) {
4536:                    ConstraintDescriptor cd = (ConstraintDescriptor) iterator
4537:                            .next();
4538:                    dropConstraintDescriptor(table, cd, tc);
4539:                }
4540:
4541:                /*
4542:                 ** Null out the table's constraint descriptor list.  NOTE: This is
4543:                 ** not really necessary at the time of this writing (11/3/97), because
4544:                 ** we do not cache data dictionary objects while DDL is going on,
4545:                 ** but in the future it might be necessary.
4546:                 */
4547:                table.setConstraintDescriptorList(null);
4548:            }
4549:
4550:            /**
4551:             * Get a SubKeyConstraintDescriptor from syskeys or sysforeignkeys for
4552:             * the specified constraint id.  For primary foreign and and unique
4553:             * key constraints.
4554:             *
4555:             * @param constraintId	The UUID for the constraint.
4556:             * @param type	The type of the constraint 
4557:             *		(e.g. DataDictionary.FOREIGNKEY_CONSTRAINT)
4558:             *
4559:             * @return SubKeyConstraintDescriptor	The Sub descriptor for the constraint.
4560:             *
4561:             * @exception StandardException		Thrown on failure
4562:             */
4563:            public SubKeyConstraintDescriptor getSubKeyConstraint(
4564:                    UUID constraintId, int type) throws StandardException {
4565:                DataValueDescriptor constraintIDOrderable = null;
4566:                TabInfoImpl ti;
4567:                int indexNum;
4568:                int baseNum;
4569:
4570:                if (type == DataDictionary.FOREIGNKEY_CONSTRAINT) {
4571:                    baseNum = SYSFOREIGNKEYS_CATALOG_NUM;
4572:                    indexNum = SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX1_ID;
4573:                } else {
4574:                    baseNum = SYSKEYS_CATALOG_NUM;
4575:                    indexNum = SYSKEYSRowFactory.SYSKEYS_INDEX1_ID;
4576:                }
4577:                ti = getNonCoreTI(baseNum);
4578:
4579:                /* Use constraintIDOrderable in both start and stop positions for scan */
4580:                constraintIDOrderable = getValueAsDVD(constraintId);
4581:
4582:                /* Set up the start/stop position for the scan */
4583:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
4584:                        .getIndexableRow(1);
4585:                keyRow.setColumn(1, constraintIDOrderable);
4586:
4587:                return (SubKeyConstraintDescriptor) getDescriptorViaIndex(
4588:                        indexNum, keyRow, (ScanQualifier[][]) null, ti,
4589:                        (TupleDescriptor) null, (List) null, false);
4590:            }
4591:
4592:            /**
4593:             * Add the matching row to syskeys when adding a unique or primary key constraint
4594:             *
4595:             * @param descriptor	The KeyConstraintDescriptor for the constraint.
4596:             * @param tc			The TransactionController
4597:             *
4598:             * @exception StandardException		Thrown on failure
4599:             */
4600:            private void addSubKeyConstraint(
4601:                    KeyConstraintDescriptor descriptor, TransactionController tc)
4602:                    throws StandardException {
4603:                ExecRow row;
4604:                TabInfoImpl ti;
4605:
4606:                /*
4607:                 ** Foreign keys get a row in SYSFOREIGNKEYS, and
4608:                 ** all others get a row in SYSKEYS.
4609:                 */
4610:                if (descriptor.getConstraintType() == DataDictionary.FOREIGNKEY_CONSTRAINT) {
4611:                    ForeignKeyConstraintDescriptor fkDescriptor = (ForeignKeyConstraintDescriptor) descriptor;
4612:
4613:                    if (SanityManager.DEBUG) {
4614:                        if (!(descriptor instanceof  ForeignKeyConstraintDescriptor)) {
4615:                            SanityManager
4616:                                    .THROWASSERT("descriptor not an fk descriptor, is "
4617:                                            + descriptor.getClass().getName());
4618:                        }
4619:                    }
4620:
4621:                    ti = getNonCoreTI(SYSFOREIGNKEYS_CATALOG_NUM);
4622:                    SYSFOREIGNKEYSRowFactory fkkeysRF = (SYSFOREIGNKEYSRowFactory) ti
4623:                            .getCatalogRowFactory();
4624:
4625:                    row = fkkeysRF.makeRow(fkDescriptor, null);
4626:
4627:                    /*
4628:                     ** Now we need to bump the reference count of the
4629:                     ** contraint that this FK references
4630:                     */
4631:                    ReferencedKeyConstraintDescriptor refDescriptor = fkDescriptor
4632:                            .getReferencedConstraint();
4633:
4634:                    refDescriptor.incrementReferenceCount();
4635:
4636:                    int[] colsToSet = new int[1];
4637:                    colsToSet[0] = SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_REFERENCECOUNT;
4638:
4639:                    updateConstraintDescriptor(refDescriptor, refDescriptor
4640:                            .getUUID(), colsToSet, tc);
4641:                } else {
4642:                    ti = getNonCoreTI(SYSKEYS_CATALOG_NUM);
4643:                    SYSKEYSRowFactory keysRF = (SYSKEYSRowFactory) ti
4644:                            .getCatalogRowFactory();
4645:
4646:                    // build the row to be stuffed into SYSKEYS
4647:                    row = keysRF.makeRow(descriptor, null);
4648:                }
4649:
4650:                // insert row into catalog and all its indices
4651:                ti.insertRow(row, tc, true);
4652:            }
4653:
4654:            /**
4655:             * Drop the matching row from syskeys when dropping a primary key
4656:             * or unique constraint.
4657:             *
4658:             * @param constraint	the constraint
4659:             * @param tc			The TransactionController
4660:             *
4661:             * @exception StandardException		Thrown on failure
4662:             */
4663:            private void dropSubKeyConstraint(ConstraintDescriptor constraint,
4664:                    TransactionController tc) throws StandardException {
4665:                ExecIndexRow keyRow1 = null;
4666:                DataValueDescriptor constraintIdOrderable;
4667:                TabInfoImpl ti;
4668:                int baseNum;
4669:                int indexNum;
4670:
4671:                if (constraint.getConstraintType() == DataDictionary.FOREIGNKEY_CONSTRAINT) {
4672:                    baseNum = SYSFOREIGNKEYS_CATALOG_NUM;
4673:                    indexNum = SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX1_ID;
4674:
4675:                    /*
4676:                     ** If we have a foreign key, we need to decrement the 
4677:                     ** reference count of the contraint that this FK references.
4678:                     ** We need to do this *before* we drop the foreign key
4679:                     ** because of the way FK.getReferencedConstraint() works.	
4680:                     */
4681:                    if (constraint.getConstraintType() == DataDictionary.FOREIGNKEY_CONSTRAINT) {
4682:                        ReferencedKeyConstraintDescriptor refDescriptor = (ReferencedKeyConstraintDescriptor) getConstraintDescriptor(((ForeignKeyConstraintDescriptor) constraint)
4683:                                .getReferencedConstraintId());
4684:
4685:                        if (refDescriptor != null) {
4686:                            refDescriptor.decrementReferenceCount();
4687:
4688:                            int[] colsToSet = new int[1];
4689:                            colsToSet[0] = SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_REFERENCECOUNT;
4690:
4691:                            updateConstraintDescriptor(refDescriptor,
4692:                                    refDescriptor.getUUID(), colsToSet, tc);
4693:                        }
4694:                    }
4695:                } else {
4696:                    baseNum = SYSKEYS_CATALOG_NUM;
4697:                    indexNum = SYSKEYSRowFactory.SYSKEYS_INDEX1_ID;
4698:                }
4699:
4700:                ti = getNonCoreTI(baseNum);
4701:
4702:                /* Use constraintIdOrderable in both start 
4703:                 * and stop position for index 1 scan. 
4704:                 */
4705:                constraintIdOrderable = getValueAsDVD(constraint.getUUID());
4706:
4707:                /* Set up the start/stop position for the scan */
4708:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
4709:                keyRow1.setColumn(1, constraintIdOrderable);
4710:
4711:                ti.deleteRow(tc, keyRow1, indexNum);
4712:            }
4713:
4714:            /**
4715:             * Get a SubCheckConstraintDescriptor from syschecks for
4716:             * the specified constraint id.  (Useful for check constraints.)
4717:             *
4718:             * @param constraintId	The UUID for the constraint.
4719:             *
4720:             * @return SubCheckConstraintDescriptor	The Sub descriptor for the constraint.
4721:             *
4722:             * @exception StandardException		Thrown on failure
4723:             */
4724:            private SubCheckConstraintDescriptor getSubCheckConstraint(
4725:                    UUID constraintId) throws StandardException {
4726:                DataValueDescriptor constraintIDOrderable = null;
4727:                TabInfoImpl ti = getNonCoreTI(SYSCHECKS_CATALOG_NUM);
4728:                SYSCHECKSRowFactory rf = (SYSCHECKSRowFactory) ti
4729:                        .getCatalogRowFactory();
4730:
4731:                /* Use constraintIDOrderable in both start and stop positions for scan */
4732:                constraintIDOrderable = getValueAsDVD(constraintId);
4733:
4734:                /* Set up the start/stop position for the scan */
4735:                ExecIndexRow keyRow = (ExecIndexRow) exFactory
4736:                        .getIndexableRow(1);
4737:                keyRow.setColumn(1, constraintIDOrderable);
4738:
4739:                return (SubCheckConstraintDescriptor) getDescriptorViaIndex(
4740:                        SYSCHECKSRowFactory.SYSCHECKS_INDEX1_ID, keyRow,
4741:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
4742:                        (List) null, false);
4743:            }
4744:
4745:            /**
4746:             * Drop the matching row from syschecks when dropping a check constraint.
4747:             *
4748:             * @param constraintId	The constraint id.
4749:             * @param tc			The TransactionController
4750:             *
4751:             * @exception StandardException		Thrown on failure
4752:             */
4753:            private void dropSubCheckConstraint(UUID constraintId,
4754:                    TransactionController tc) throws StandardException {
4755:                ExecIndexRow checkRow1 = null;
4756:                DataValueDescriptor constraintIdOrderable;
4757:                TabInfoImpl ti = getNonCoreTI(SYSCHECKS_CATALOG_NUM);
4758:
4759:                /* Use constraintIdOrderable in both start 
4760:                 * and stop position for index 1 scan. 
4761:                 */
4762:                constraintIdOrderable = getValueAsDVD(constraintId);
4763:
4764:                /* Set up the start/stop position for the scan */
4765:                checkRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
4766:                checkRow1.setColumn(1, constraintIdOrderable);
4767:
4768:                ti.deleteRow(tc, checkRow1,
4769:                        SYSCHECKSRowFactory.SYSCHECKS_INDEX1_ID);
4770:            }
4771:
4772:            /**
4773:             * Get all of the ConglomerateDescriptors in the database and
4774:             * hash them by conglomerate number.
4775:             * This is useful as a performance optimization for the locking VTIs.
4776:             * NOTE:  This method will scan SYS.SYSCONGLOMERATES at READ UNCOMMITTED.
4777:             *
4778:             * @param tc		TransactionController for the transaction
4779:             *
4780:             * @return	A Hashtable with all of the ConglomerateDescriptors
4781:             *		in the database hashed by conglomerate number.
4782:             *
4783:             * @exception StandardException		Thrown on failure
4784:             */
4785:            public Hashtable hashAllConglomerateDescriptorsByNumber(
4786:                    TransactionController tc) throws StandardException {
4787:                Hashtable ht = new Hashtable();
4788:                ConglomerateDescriptor cd = null;
4789:                ScanController scanController;
4790:                ExecRow outRow;
4791:                // ExecIndexRow			  keyRow = null;
4792:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
4793:                SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti
4794:                        .getCatalogRowFactory();
4795:
4796:                outRow = rf.makeEmptyRow();
4797:                scanController = tc.openScan(
4798:                        ti.getHeapConglomerate(), // conglomerate to open
4799:                        false, // don't hold open across commit
4800:                        0, // for read
4801:                        TransactionController.MODE_RECORD, // scans whole table.
4802:                        TransactionController.ISOLATION_READ_UNCOMMITTED,
4803:                        (FormatableBitSet) null, // all fields as objects
4804:                        (DataValueDescriptor[]) null, //keyRow.getRowArray(),   // start position - first row
4805:                        ScanController.GE, // startSearchOperation
4806:                        (ScanQualifier[][]) null, (DataValueDescriptor[]) null, //keyRow.getRowArray(),   // stop position - through last row
4807:                        ScanController.GT); // stopSearchOperation
4808:
4809:                // it is important for read uncommitted scans to use fetchNext() rather
4810:                // than fetch, so that the fetch happens while latch is held, otherwise
4811:                // the next() might position the scan on a row, but the subsequent
4812:                // fetch() may find the row deleted or purged from the table.
4813:                while (scanController.fetchNext(outRow.getRowArray())) {
4814:                    cd = (ConglomerateDescriptor) rf.buildDescriptor(outRow,
4815:                            (TupleDescriptor) null, this );
4816:                    Long hashKey = new Long(cd.getConglomerateNumber());
4817:                    ht.put(hashKey, cd);
4818:                }
4819:
4820:                scanController.close();
4821:
4822:                return ht;
4823:            }
4824:
4825:            /**
4826:             * Get all of the TableDescriptors in the database and hash them by TableId
4827:             * This is useful as a performance optimization for the locking VTIs.
4828:             * NOTE:  This method will scan SYS.SYSTABLES at READ UNCOMMITTED.
4829:             *
4830:             * @param tc		TransactionController for the transaction
4831:             *
4832:             * @return	A Hashtable with all of the Table descriptors in the database
4833:             *			hashed by TableId
4834:             *
4835:             *
4836:             * @exception StandardException		Thrown on failure
4837:             */
4838:            public Hashtable hashAllTableDescriptorsByTableId(
4839:                    TransactionController tc) throws StandardException {
4840:                Hashtable ht = new Hashtable();
4841:                ScanController scanController;
4842:                ExecRow outRow;
4843:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
4844:                SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti
4845:                        .getCatalogRowFactory();
4846:
4847:                outRow = rf.makeEmptyRow();
4848:
4849:                scanController = tc.openScan(
4850:                        ti.getHeapConglomerate(), // sys.systable
4851:                        false, // don't hold open across commit
4852:                        0, // for read
4853:                        TransactionController.MODE_RECORD,// scans whole table.
4854:                        TransactionController.ISOLATION_READ_UNCOMMITTED,
4855:                        (FormatableBitSet) null, // all fields as objects
4856:                        (DataValueDescriptor[]) null, // start position - first row
4857:                        ScanController.GE, // startSearchOperation
4858:                        (ScanQualifier[][]) null, //scanQualifier,
4859:                        (DataValueDescriptor[]) null, //stop position-through last row
4860:                        ScanController.GT); // stopSearchOperation
4861:
4862:                // it is important for read uncommitted scans to use fetchNext() rather
4863:                // than fetch, so that the fetch happens while latch is held, otherwise
4864:                // the next() might position the scan on a row, but the subsequent
4865:                // fetch() may find the row deleted or purged from the table.
4866:                while (scanController.fetchNext(outRow.getRowArray())) {
4867:                    TableDescriptor td = (TableDescriptor) rf.buildDescriptor(
4868:                            outRow, (TupleDescriptor) null, this );
4869:                    ht.put(td.getUUID(), td);
4870:                }
4871:                scanController.close();
4872:                return ht;
4873:            }
4874:
4875:            /**
4876:             * Get a ConglomerateDescriptor given its UUID.  If it is an index
4877:             * conglomerate shared by at least another duplicate index, this returns
4878:             * one of the ConglomerateDescriptors for those indexes. 
4879:             *
4880:             * @param uuid	The UUID
4881:             *
4882:             *
4883:             * @return A ConglomerateDescriptor for the conglomerate.
4884:             *
4885:             * @exception StandardException		Thrown on failure
4886:             */
4887:            public ConglomerateDescriptor getConglomerateDescriptor(UUID uuid)
4888:                    throws StandardException {
4889:                ConglomerateDescriptor[] cds = getConglomerateDescriptors(uuid);
4890:                if (cds.length == 0)
4891:                    return null;
4892:                return cds[0];
4893:            }
4894:
4895:            /**
4896:             * Get an array of ConglomerateDescriptors given the UUID.  If it is a
4897:             * heap conglomerate or an index conglomerate not shared by a duplicate
4898:             * index, the size of the return array is 1.
4899:             *
4900:             * @param uuid	The UUID
4901:             *
4902:             *
4903:             * @return An array of ConglomerateDescriptors for the conglomerate.
4904:             *				returns size 0 array if no such conglomerate.
4905:             *
4906:             * @exception StandardException		Thrown on failure
4907:             */
4908:            public ConglomerateDescriptor[] getConglomerateDescriptors(UUID uuid)
4909:                    throws StandardException {
4910:                DataValueDescriptor UUIDStringOrderable;
4911:                SYSCONGLOMERATESRowFactory rf;
4912:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
4913:
4914:                /* Use UUIDStringOrderable in both start and stop positions for scan */
4915:                UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
4916:
4917:                /* Set up the start/stop position for the scan */
4918:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
4919:                keyRow.setColumn(1, UUIDStringOrderable);
4920:
4921:                List cdl = newSList();
4922:
4923:                getDescriptorViaIndex(
4924:                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
4925:                        keyRow, (ScanQualifier[][]) null, ti,
4926:                        (TupleDescriptor) null, cdl, false);
4927:
4928:                ConglomerateDescriptor[] cda = new ConglomerateDescriptor[cdl
4929:                        .size()];
4930:                cdl.toArray(cda);
4931:                return cda;
4932:
4933:            }
4934:
4935:            /**
4936:             * Get a ConglomerateDescriptor given its conglomerate number.  If it is an
4937:             * index conglomerate shared by at least another duplicate index, this
4938:             * returns one of the ConglomerateDescriptors for those indexes. 
4939:             *
4940:             * @param conglomerateNumber	The conglomerate number.
4941:             *
4942:             *
4943:             * @return A ConglomerateDescriptor for the conglomerate.  Returns NULL if
4944:             *				no such conglomerate.
4945:             *
4946:             * @exception StandardException		Thrown on failure
4947:             */
4948:            public ConglomerateDescriptor getConglomerateDescriptor(
4949:                    long conglomerateNumber) throws StandardException {
4950:                ConglomerateDescriptor[] cds = getConglomerateDescriptors(conglomerateNumber);
4951:                if (cds.length == 0)
4952:                    return null;
4953:                return cds[0];
4954:            }
4955:
4956:            /**
4957:             * Get an array of conglomerate descriptors for the given conglomerate
4958:             * number.  If it is a heap conglomerate or an index conglomerate not
4959:             * shared by a duplicate index, the size of the return array is 1.
4960:             *
4961:             * @param conglomerateNumber	The number for the conglomerate
4962:             *				we're interested in
4963:             *
4964:             * @return	An array of ConglomerateDescriptors that share the requested
4965:             *		conglomerate. Returns size 0 array if no such conglomerate.
4966:             *
4967:             * @exception StandardException		Thrown on failure
4968:             */
4969:            public ConglomerateDescriptor[] getConglomerateDescriptors(
4970:                    long conglomerateNumber) throws StandardException {
4971:                ScanController scanController;
4972:                TransactionController tc;
4973:                ExecRow outRow;
4974:                DataValueDescriptor conglomNumberOrderable = null;
4975:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
4976:                SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti
4977:                        .getCatalogRowFactory();
4978:
4979:                conglomNumberOrderable = dvf.getDataValue(conglomerateNumber);
4980:
4981:                ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
4982:                scanQualifier[0][0].setQualifier(
4983:                        rf.SYSCONGLOMERATES_CONGLOMERATENUMBER - 1, /* column number */
4984:                        conglomNumberOrderable, Orderable.ORDER_OP_EQUALS,
4985:                        false, false, false);
4986:
4987:                ConglomerateDescriptorList cdl = new ConglomerateDescriptorList();
4988:                getDescriptorViaHeap(scanQualifier, ti, null, cdl);
4989:
4990:                int size = cdl.size();
4991:                ConglomerateDescriptor[] cda = new ConglomerateDescriptor[size];
4992:                for (int index = 0; index < size; index++)
4993:                    cda[index] = (ConglomerateDescriptor) cdl.get(index);
4994:
4995:                return cda;
4996:            }
4997:
4998:            /** 
4999:             * Populate the ConglomerateDescriptorList for the
5000:             * specified TableDescriptor by scanning sysconglomerates.
5001:             *
5002:             * MT synchronization: it is assumed that the caller has synchronized
5003:             * on the CDL in the given TD.
5004:             *
5005:             * @param td			The TableDescriptor.
5006:             *
5007:             * @exception StandardException		Thrown on failure
5008:             */
5009:            private void getConglomerateDescriptorsScan(TableDescriptor td)
5010:                    throws StandardException {
5011:                ConglomerateDescriptorList cdl = td
5012:                        .getConglomerateDescriptorList();
5013:
5014:                ExecIndexRow keyRow3 = null;
5015:                DataValueDescriptor tableIDOrderable;
5016:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5017:
5018:                /* Use tableIDOrderable in both start and stop positions for scan */
5019:                tableIDOrderable = getValueAsDVD(td.getUUID());
5020:
5021:                /* Set up the start/stop position for the scan */
5022:                keyRow3 = (ExecIndexRow) exFactory.getIndexableRow(1);
5023:                keyRow3.setColumn(1, tableIDOrderable);
5024:
5025:                getDescriptorViaIndex(
5026:                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID,
5027:                        keyRow3, (ScanQualifier[][]) null, ti,
5028:                        (TupleDescriptor) null, cdl, false);
5029:            }
5030:
5031:            /**
5032:             * Gets a conglomerate descriptor for the named index in the given schema,
5033:             * getting an exclusive row lock on the matching row in 
5034:             * sys.sysconglomerates (for DDL concurrency) if requested.
5035:             *
5036:             * @param indexName	The name of the index we're looking for
5037:             * @param sd		The schema descriptor
5038:             * @param forUpdate	Whether or not to get an exclusive row 
5039:             *					lock on the row in sys.sysconglomerates.
5040:             *
5041:             * @return	A ConglomerateDescriptor describing the requested
5042:             *		conglomerate. Returns NULL if no such conglomerate.
5043:             *
5044:             * @exception StandardException		Thrown on failure
5045:             */
5046:            public ConglomerateDescriptor getConglomerateDescriptor(
5047:                    String indexName, SchemaDescriptor sd, boolean forUpdate)
5048:                    throws StandardException {
5049:                ExecIndexRow keyRow2 = null;
5050:                DataValueDescriptor nameOrderable;
5051:                DataValueDescriptor schemaIDOrderable = null;
5052:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5053:
5054:                nameOrderable = dvf.getVarcharDataValue(indexName);
5055:                schemaIDOrderable = getValueAsDVD(sd.getUUID());
5056:
5057:                /* Set up the start/stop position for the scan */
5058:                keyRow2 = exFactory.getIndexableRow(2);
5059:                keyRow2.setColumn(1, nameOrderable);
5060:                keyRow2.setColumn(2, schemaIDOrderable);
5061:
5062:                return (ConglomerateDescriptor) getDescriptorViaIndex(
5063:                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID,
5064:                        keyRow2, (ScanQualifier[][]) null, ti,
5065:                        (TupleDescriptor) null, (List) null, forUpdate);
5066:            }
5067:
5068:            /**
5069:             * Drops a conglomerate descriptor
5070:             *
5071:             * @param conglomerate	The ConglomerateDescriptor for the conglomerate
5072:             * @param tc		TransactionController for the transaction
5073:             *
5074:             * @exception StandardException		Thrown on failure
5075:             */
5076:            public void dropConglomerateDescriptor(
5077:                    ConglomerateDescriptor conglomerate,
5078:                    TransactionController tc) throws StandardException {
5079:                ExecIndexRow keyRow2 = null;
5080:                DataValueDescriptor nameOrderable;
5081:                DataValueDescriptor schemaIDOrderable = null;
5082:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5083:
5084:                nameOrderable = dvf.getVarcharDataValue(conglomerate
5085:                        .getConglomerateName());
5086:                schemaIDOrderable = getValueAsDVD(conglomerate.getSchemaID());
5087:
5088:                /* Set up the start/stop position for the scan */
5089:                keyRow2 = (ExecIndexRow) exFactory.getIndexableRow(2);
5090:                keyRow2.setColumn(1, nameOrderable);
5091:                keyRow2.setColumn(2, schemaIDOrderable);
5092:
5093:                ti.deleteRow(tc, keyRow2,
5094:                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID);
5095:
5096:            }
5097:
5098:            /**
5099:             * Drops all conglomerates associated with a table.
5100:             *
5101:             * @param td		The TableDescriptor of the table 
5102:             * @param tc		TransactionController for the transaction
5103:             *
5104:             * @exception StandardException		Thrown on failure
5105:             */
5106:
5107:            public void dropAllConglomerateDescriptors(TableDescriptor td,
5108:                    TransactionController tc) throws StandardException {
5109:                ExecIndexRow keyRow3 = null;
5110:                DataValueDescriptor tableIDOrderable;
5111:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5112:
5113:                /* Use tableIDOrderable in both start 
5114:                 * and stop position for index 3 scan. 
5115:                 */
5116:                tableIDOrderable = getValueAsDVD(td.getUUID());
5117:
5118:                /* Set up the start/stop position for the scan */
5119:                keyRow3 = (ExecIndexRow) exFactory.getIndexableRow(1);
5120:                keyRow3.setColumn(1, tableIDOrderable);
5121:
5122:                ti.deleteRow(tc, keyRow3,
5123:                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID);
5124:            }
5125:
5126:            /**
5127:             * Update the conglomerateNumber for a ConglomerateDescriptor.
5128:             * This is useful, in 1.3, when doing a bulkInsert into an 
5129:             * empty table where we insert into a new conglomerate.
5130:             * (This will go away in 1.4.)
5131:             *
5132:             * @param cd					The ConglomerateDescriptor
5133:             * @param conglomerateNumber	The new conglomerate number
5134:             * @param tc					The TransactionController to use
5135:             *
5136:             * @exception StandardException		Thrown on failure
5137:             */
5138:            public void updateConglomerateDescriptor(ConglomerateDescriptor cd,
5139:                    long conglomerateNumber, TransactionController tc)
5140:                    throws StandardException {
5141:                ConglomerateDescriptor[] cds = new ConglomerateDescriptor[1];
5142:                cds[0] = cd;
5143:                updateConglomerateDescriptor(cds, conglomerateNumber, tc);
5144:            }
5145:
5146:            /**
5147:             * Update all system schemas to have new authorizationId. This is needed
5148:             * while upgrading pre-10.2 databases to 10.2 or later versions. From 10.2,
5149:             * all system schemas would be owned by database owner's authorizationId.
5150:             *
5151:             * @param aid							AuthorizationID of Database Owner
5152:             * @param tc							TransactionController to use
5153:             *
5154:             * @exception StandardException		Thrown on failure
5155:             */
5156:            public void updateSystemSchemaAuthorization(String aid,
5157:                    TransactionController tc) throws StandardException {
5158:                updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME, aid,
5159:                        tc);
5160:                updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME, aid,
5161:                        tc);
5162:
5163:                updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME,
5164:                        aid, tc);
5165:                updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,
5166:                        aid, tc);
5167:                updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME,
5168:                        aid, tc);
5169:                updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME,
5170:                        aid, tc);
5171:                updateSchemaAuth(
5172:                        SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME, aid, tc);
5173:
5174:                updateSchemaAuth(SchemaDescriptor.STD_SQLJ_SCHEMA_NAME, aid, tc);
5175:                updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME,
5176:                        aid, tc);
5177:                updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME,
5178:                        aid, tc);
5179:            }
5180:
5181:            /**
5182:             * Update authorizationId of specified schemaName
5183:             *
5184:             * @param schemaName			Schema Name of system schema
5185:             * @param authorizationId		authorizationId of new schema owner
5186:             * @param tc					The TransactionController to use
5187:             *
5188:             * @exception StandardException		Thrown on failure
5189:             */
5190:            public void updateSchemaAuth(String schemaName,
5191:                    String authorizationId, TransactionController tc)
5192:                    throws StandardException {
5193:                ExecIndexRow keyRow;
5194:                DataValueDescriptor schemaNameOrderable;
5195:                TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
5196:
5197:                /* Use schemaNameOrderable in both start 
5198:                 * and stop position for index 1 scan. 
5199:                 */
5200:                schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
5201:
5202:                /* Set up the start/stop position for the scan */
5203:                keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
5204:                keyRow.setColumn(1, schemaNameOrderable);
5205:
5206:                SYSSCHEMASRowFactory rf = (SYSSCHEMASRowFactory) ti
5207:                        .getCatalogRowFactory();
5208:                ExecRow row = rf.makeEmptyRow();
5209:
5210:                row.setColumn(SYSSCHEMASRowFactory.SYSSCHEMAS_SCHEMAAID, dvf
5211:                        .getVarcharDataValue(authorizationId));
5212:
5213:                boolean[] bArray = { false, false };
5214:
5215:                int[] colsToUpdate = { SYSSCHEMASRowFactory.SYSSCHEMAS_SCHEMAAID };
5216:
5217:                ti.updateRow(keyRow, row,
5218:                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID, bArray,
5219:                        colsToUpdate, tc);
5220:            }
5221:
5222:            /**
5223:             * Update the conglomerateNumber for an array of ConglomerateDescriptors.
5224:             * In case of more than one ConglomerateDescriptor, each descriptor 
5225:             * should be updated separately, conglomerate id is not same for all 
5226:             * the descriptors. Even when indexes are sharing the same 
5227:             * conglomerate(conglomerate number), conglomerate ids are unique.
5228:             *
5229:             * This is useful, in 1.3, when doing a bulkInsert into an 
5230:             * empty table where we insert into a new conglomerate.
5231:             * (This will go away in 1.4.)
5232:             *
5233:             * @param cds					The array of ConglomerateDescriptors
5234:             * @param conglomerateNumber	The new conglomerate number
5235:             * @param tc					The TransactionController to use
5236:             *
5237:             * @exception StandardException		Thrown on failure
5238:             */
5239:            public void updateConglomerateDescriptor(
5240:                    ConglomerateDescriptor[] cds, long conglomerateNumber,
5241:                    TransactionController tc) throws StandardException {
5242:                ExecIndexRow keyRow1 = null;
5243:                ExecRow row;
5244:                DataValueDescriptor conglomIDOrderable;
5245:                TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5246:                SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti
5247:                        .getCatalogRowFactory();
5248:                boolean[] bArray = { false, false, false };
5249:
5250:                for (int i = 0; i < cds.length; i++) {
5251:                    /* Use conglomIDOrderable in both start 
5252:                     * and stop position for index 1 scan. 
5253:                     */
5254:                    conglomIDOrderable = getValueAsDVD(cds[i].getUUID());
5255:
5256:                    /* Set up the start/stop position for the scan */
5257:                    keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5258:                    keyRow1.setColumn(1, conglomIDOrderable);
5259:
5260:                    cds[i].setConglomerateNumber(conglomerateNumber);
5261:                    // build the row to be stuffed into SYSCONGLOMERATES. 
5262:                    row = rf.makeRow(cds[i], null);
5263:
5264:                    // update row in catalog (no indexes)
5265:                    ti
5266:                            .updateRow(
5267:                                    keyRow1,
5268:                                    row,
5269:                                    SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
5270:                                    bArray, (int[]) null, tc);
5271:                }
5272:
5273:            }
5274:
5275:            /**
5276:             * Gets a list of the dependency descriptors for the given dependent's id.
5277:             *
5278:             * @param dependentID		The ID of the dependent we're interested in
5279:             *
5280:             * @return	List			Returns a list of DependencyDescriptors. 
5281:             *							Returns an empty List if no stored dependencies for the
5282:             *							dependent's ID.
5283:             *
5284:             * @exception StandardException		Thrown on failure
5285:             */
5286:            public List getDependentsDescriptorList(String dependentID)
5287:                    throws StandardException {
5288:                List ddlList = newSList();
5289:                DataValueDescriptor dependentIDOrderable;
5290:                TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5291:
5292:                /* Use dependentIDOrderable in both start and stop positions for scan */
5293:                dependentIDOrderable = dvf.getCharDataValue(dependentID);
5294:
5295:                /* Set up the start/stop position for the scan */
5296:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5297:                keyRow.setColumn(1, dependentIDOrderable);
5298:
5299:                getDescriptorViaIndex(
5300:                        SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID, keyRow,
5301:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
5302:                        ddlList, false);
5303:
5304:                return ddlList;
5305:            }
5306:
5307:            /**
5308:             * Gets a list of the dependency descriptors for the given provider's id.
5309:             *
5310:             * @param providerID		The ID of the provider we're interested in
5311:             *
5312:             * @return	List			Returns a list of DependencyDescriptors. 
5313:             *							Returns an empty List if no stored dependencies for the
5314:             *							provider's ID.
5315:             *
5316:             * @exception StandardException		Thrown on failure
5317:             */
5318:            public List getProvidersDescriptorList(String providerID)
5319:                    throws StandardException {
5320:                List ddlList = newSList();
5321:                DataValueDescriptor providerIDOrderable;
5322:                TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5323:
5324:                /* Use providerIDOrderable in both start and stop positions for scan */
5325:                providerIDOrderable = dvf.getCharDataValue(providerID);
5326:
5327:                /* Set up the start/stop position for the scan */
5328:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5329:                keyRow.setColumn(1, providerIDOrderable);
5330:
5331:                getDescriptorViaIndex(
5332:                        SYSDEPENDSRowFactory.SYSDEPENDS_INDEX2_ID, keyRow,
5333:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
5334:                        ddlList, false);
5335:
5336:                return ddlList;
5337:            }
5338:
5339:            /**
5340:             * Build and return an List with DependencyDescriptors for
5341:             * all of the stored dependencies.  
5342:             * This is useful for consistency checking.
5343:             *
5344:             * @return List		List of all DependencyDescriptors.
5345:             *
5346:             * @exception StandardException		Thrown on failure
5347:             */
5348:            public List getAllDependencyDescriptorsList()
5349:                    throws StandardException {
5350:                ScanController scanController;
5351:                TransactionController tc;
5352:                ExecRow outRow;
5353:                ExecRow templateRow;
5354:                List ddl = newSList();
5355:                TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5356:                SYSDEPENDSRowFactory rf = (SYSDEPENDSRowFactory) ti
5357:                        .getCatalogRowFactory();
5358:
5359:                // Get the current transaction controller
5360:                tc = getTransactionCompile();
5361:
5362:                outRow = rf.makeEmptyRow();
5363:
5364:                scanController = tc.openScan(
5365:                        ti.getHeapConglomerate(), // conglomerate to open
5366:                        false, // don't hold open across commit
5367:                        0, // for read
5368:                        TransactionController.MODE_TABLE, // scans entire table.
5369:                        TransactionController.ISOLATION_REPEATABLE_READ,
5370:                        (FormatableBitSet) null, // all fields as objects
5371:                        null, // start position - first row
5372:                        ScanController.GE, // startSearchOperation
5373:                        null, null, // stop position - through last row
5374:                        ScanController.GT); // stopSearchOperation
5375:
5376:                while (scanController.fetchNext(outRow.getRowArray())) {
5377:                    DependencyDescriptor dependencyDescriptor;
5378:
5379:                    dependencyDescriptor = (DependencyDescriptor) rf
5380:                            .buildDescriptor(outRow, (TupleDescriptor) null,
5381:                                    this );
5382:
5383:                    ddl.add(dependencyDescriptor);
5384:                }
5385:
5386:                scanController.close();
5387:
5388:                return ddl;
5389:            }
5390:
5391:            /** 
5392:             * Drop a single dependency from the data dictionary.
5393:             * 
5394:             * @param dd	The DependencyDescriptor.
5395:             * @param tc	TransactionController for the transaction
5396:             *
5397:             * @exception StandardException		Thrown on failure
5398:             */
5399:            public void dropStoredDependency(DependencyDescriptor dd,
5400:                    TransactionController tc) throws StandardException {
5401:                ExecIndexRow keyRow1 = null;
5402:                UUID dependentID = dd.getUUID();
5403:                UUID providerID = dd.getProviderID();
5404:                DataValueDescriptor dependentIDOrderable = getValueAsDVD(dependentID);
5405:                TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5406:
5407:                /* Use dependentIDOrderable in both start 
5408:                 * and stop position for index 1 scan. 
5409:                 */
5410:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5411:                keyRow1.setColumn(1, dependentIDOrderable);
5412:
5413:                // only drop the rows which have this providerID
5414:                TupleFilter filter = new DropDependencyFilter(providerID);
5415:
5416:                ti.deleteRows(tc,
5417:                        keyRow1, // start row
5418:                        ScanController.GE,
5419:                        null, //qualifier
5420:                        filter, // filter on base row
5421:                        keyRow1, // stop row
5422:                        ScanController.GT,
5423:                        SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID);
5424:
5425:            }
5426:
5427:            /** 
5428:             * Remove all of the stored dependencies for a given dependent's ID 
5429:             * from the data dictionary.
5430:             * 
5431:             * @param dependentsUUID	Dependent's uuid
5432:             * @param tc				TransactionController for the transaction
5433:             *
5434:             * @exception StandardException		Thrown on failure
5435:             */
5436:            public void dropDependentsStoredDependencies(UUID dependentsUUID,
5437:                    TransactionController tc) throws StandardException {
5438:                dropDependentsStoredDependencies(dependentsUUID, tc, true);
5439:            }
5440:
5441:            /** 
5442:             * @inheritDoc
5443:             */
5444:            public void dropDependentsStoredDependencies(UUID dependentsUUID,
5445:                    TransactionController tc, boolean wait)
5446:                    throws StandardException {
5447:                ExecIndexRow keyRow1 = null;
5448:                DataValueDescriptor dependentIDOrderable;
5449:                TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5450:
5451:                /* Use dependentIDOrderable in both start 
5452:                 * and stop position for index 1 scan. 
5453:                 */
5454:                dependentIDOrderable = getValueAsDVD(dependentsUUID);
5455:
5456:                /* Set up the start/stop position for the scan */
5457:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5458:                keyRow1.setColumn(1, dependentIDOrderable);
5459:
5460:                ti.deleteRow(tc, keyRow1,
5461:                        SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID, wait);
5462:
5463:            }
5464:
5465:            /**
5466:             * Get the UUID Factory.  (No need to make the UUIDFactory a module.)
5467:             *
5468:             * @return UUIDFactory	The UUID Factory for this DataDictionary.
5469:             */
5470:            public UUIDFactory getUUIDFactory() {
5471:                return uuidFactory;
5472:            }
5473:
5474:            /**
5475:             * Get a AliasDescriptor given its UUID.
5476:             *
5477:             * @param uuid	The UUID
5478:             *
5479:             *
5480:             * @return The AliasDescriptor for the alias.
5481:             *
5482:             * @exception StandardException		Thrown on failure
5483:             */
5484:            public AliasDescriptor getAliasDescriptor(UUID uuid)
5485:                    throws StandardException {
5486:                DataValueDescriptor UUIDStringOrderable;
5487:                SYSALIASESRowFactory rf;
5488:                TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
5489:
5490:                rf = (SYSALIASESRowFactory) ti.getCatalogRowFactory();
5491:
5492:                /* Use UUIDStringOrderable in both start and stop positions for scan */
5493:                UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
5494:
5495:                /* Set up the start/stop position for the scan */
5496:                ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5497:                keyRow.setColumn(1, UUIDStringOrderable);
5498:
5499:                return (AliasDescriptor) getDescriptorViaIndex(
5500:                        SYSALIASESRowFactory.SYSALIASES_INDEX2_ID, keyRow,
5501:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
5502:                        (List) null, false);
5503:            }
5504:
5505:            /**
5506:             * Get a AliasDescriptor by alias name and name space.
5507:             * NOTE: caller responsible for handling no match.
5508:             *
5509:               @param schemaId		schema identifier
5510:             * @param aliasName		The alias name.
5511:             * @param nameSpace		The alias type.
5512:             *
5513:             * @return AliasDescriptor	AliasDescriptor for the alias name and name space
5514:             *
5515:             * @exception StandardException		Thrown on failure
5516:             */
5517:            public AliasDescriptor getAliasDescriptor(String schemaId,
5518:                    String aliasName, char nameSpace) throws StandardException {
5519:                DataValueDescriptor aliasNameOrderable;
5520:                DataValueDescriptor nameSpaceOrderable;
5521:                TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
5522:                SYSALIASESRowFactory rf = (SYSALIASESRowFactory) ti
5523:                        .getCatalogRowFactory();
5524:
5525:                /* Use aliasNameOrderable and aliasTypeOrderable in both start 
5526:                 * and stop position for scan. 
5527:                 */
5528:                aliasNameOrderable = dvf.getVarcharDataValue(aliasName);
5529:                char[] charArray = new char[1];
5530:                charArray[0] = nameSpace;
5531:                nameSpaceOrderable = dvf
5532:                        .getCharDataValue(new String(charArray));
5533:
5534:                /* Set up the start/stop position for the scan */
5535:                ExecIndexRow keyRow = exFactory.getIndexableRow(3);
5536:                keyRow.setColumn(1, dvf.getCharDataValue(schemaId));
5537:                keyRow.setColumn(2, aliasNameOrderable);
5538:                keyRow.setColumn(3, nameSpaceOrderable);
5539:
5540:                return (AliasDescriptor) getDescriptorViaIndex(
5541:                        SYSALIASESRowFactory.SYSALIASES_INDEX1_ID, keyRow,
5542:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
5543:                        (List) null, false);
5544:            }
5545:
5546:            /**
5547:            	Get the list of routines matching the schema and routine name.
5548:            	While we only support a single alias for a given name,namespace just
5549:            	return a list of zero or one item.
5550:            	If the schema is SYSFUN then do not use the system catalogs,
5551:            	but instead look up the routines from the in-meomry table driven
5552:            	by the contents of SYSFUN_FUNCTIONS.
5553:             */
5554:            public java.util.List getRoutineList(String schemaID,
5555:                    String routineName, char nameSpace)
5556:                    throws StandardException {
5557:
5558:                java.util.List list = new java.util.ArrayList();
5559:
5560:                // Special in-memory table lookup for SYSFUN
5561:                if (schemaID.equals(SchemaDescriptor.SYSFUN_SCHEMA_UUID)
5562:                        && nameSpace == AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR) {
5563:                    for (int f = 0; f < DataDictionaryImpl.SYSFUN_FUNCTIONS.length; f++) {
5564:                        String[] details = DataDictionaryImpl.SYSFUN_FUNCTIONS[f];
5565:                        String name = details[0];
5566:                        if (!name.equals(routineName))
5567:                            continue;
5568:
5569:                        AliasDescriptor ad = DataDictionaryImpl.SYSFUN_AD[f];
5570:                        if (ad == null) {
5571:                            // details[1] Return type
5572:                            TypeDescriptor rt = DataTypeDescriptor
5573:                                    .getBuiltInDataTypeDescriptor(details[1]);
5574:
5575:                            // details[4] - zero or single argument type
5576:                            String paramType = details[4];
5577:                            TypeDescriptor[] pt;
5578:                            String[] paramNames;
5579:                            int[] paramModes;
5580:                            int paramCount;
5581:                            if (paramType != null) {
5582:                                paramNames = DataDictionaryImpl.SYSFUN_PNAME;
5583:                                paramCount = 1;
5584:                                paramModes = DataDictionaryImpl.SYSFUN_PMODE;
5585:                                pt = new TypeDescriptor[1];
5586:                                pt[0] = DataTypeDescriptor
5587:                                        .getBuiltInDataTypeDescriptor(paramType);
5588:                            } else {
5589:                                // no parameters
5590:                                paramNames = null;
5591:                                pt = null;
5592:                                paramCount = 0;
5593:                                paramModes = null;
5594:                            }
5595:
5596:                            // details[3] = java method
5597:                            RoutineAliasInfo ai = new RoutineAliasInfo(
5598:                                    details[3], paramCount, paramNames, pt,
5599:                                    paramModes, 0, RoutineAliasInfo.PS_JAVA,
5600:                                    RoutineAliasInfo.NO_SQL, false, rt);
5601:
5602:                            // details[2] = class name
5603:                            ad = new AliasDescriptor(
5604:                                    this ,
5605:                                    uuidFactory.createUUID(),
5606:                                    name,
5607:                                    uuidFactory.recreateUUID(schemaID),
5608:                                    details[2],
5609:                                    AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR,
5610:                                    AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR,
5611:                                    true, ai, null);
5612:
5613:                            DataDictionaryImpl.SYSFUN_AD[f] = ad;
5614:                        }
5615:                        list.add(ad);
5616:                    }
5617:                    return list;
5618:                }
5619:
5620:                AliasDescriptor ad = getAliasDescriptor(schemaID, routineName,
5621:                        nameSpace);
5622:                if (ad != null) {
5623:                    list.add(ad);
5624:                }
5625:                return list;
5626:            }
5627:
5628:            /** 
5629:             * Drop a AliasDescriptor from the DataDictionary
5630:             *
5631:             * @param ad	The AliasDescriptor to drop
5632:             * @param tc	The TransactionController
5633:             *
5634:             * @exception StandardException		Thrown on failure
5635:             */
5636:
5637:            public void dropAliasDescriptor(AliasDescriptor ad,
5638:                    TransactionController tc) throws StandardException {
5639:                ExecIndexRow keyRow1 = null;
5640:                DataValueDescriptor aliasNameOrderable;
5641:                DataValueDescriptor nameSpaceOrderable;
5642:                TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
5643:
5644:                /* Use aliasNameOrderable and nameSpaceOrderable in both start 
5645:                 * and stop position for index 1 scan. 
5646:                 */
5647:                aliasNameOrderable = dvf.getVarcharDataValue(ad
5648:                        .getDescriptorName());
5649:                char[] charArray = new char[1];
5650:                charArray[0] = ad.getNameSpace();
5651:                nameSpaceOrderable = dvf
5652:                        .getCharDataValue(new String(charArray));
5653:
5654:                /* Set up the start/stop position for the scan */
5655:                keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(3);
5656:                keyRow1.setColumn(1, dvf.getCharDataValue(ad.getSchemaUUID()
5657:                        .toString()));
5658:                keyRow1.setColumn(2, aliasNameOrderable);
5659:                keyRow1.setColumn(3, nameSpaceOrderable);
5660:
5661:                ti.deleteRow(tc, keyRow1,
5662:                        SYSALIASESRowFactory.SYSALIASES_INDEX1_ID);
5663:
5664:            }
5665:
5666:            //
5667:            // class implementation
5668:            //
5669:
5670:            /**
5671:             *	Initialize system catalogs. This is where we perform upgrade. It is our
5672:             *	pious hope that we won't ever have to upgrade the core catalogs, other than
5673:             *	to add fields inside Formatable columns in these catalogs.
5674:             *
5675:             *	If we do have to upgrade the core catalogs, then we may need to move the
5676:             *	loadCatalog calls into the upgrade machinery. It's do-able, just not pretty.
5677:             *
5678:             *
5679:             *	@param	tc		TransactionController
5680:             *	@param	ddg		DataDescriptorGenerator
5681:             *
5682:             * 	@exception StandardException		Thrown on error
5683:             */
5684:            protected void loadDictionaryTables(TransactionController tc,
5685:                    DataDescriptorGenerator ddg, Properties startParams)
5686:                    throws StandardException {
5687:                // load the core catalogs first
5688:                loadCatalogs(ddg, coreInfo);
5689:
5690:                dictionaryVersion = (DD_Version) tc
5691:                        .getProperty(DataDictionary.CORE_DATA_DICTIONARY_VERSION);
5692:
5693:                softwareVersion.upgradeIfNeeded(dictionaryVersion, tc,
5694:                        startParams);
5695:            }
5696:
5697:            /**
5698:             * Initialize indices for an array of catalogs
5699:             *
5700:             *	@param	ddg		DataDescriptorGenerator
5701:             *
5702:             *
5703:             * @exception StandardException		Thrown on error
5704:             */
5705:            public void loadCatalogs(DataDescriptorGenerator ddg,
5706:                    TabInfoImpl[] catalogArray) throws StandardException {
5707:                int ictr;
5708:                int numIndexes;
5709:                int indexCtr;
5710:                TabInfoImpl catalog;
5711:                int catalogCount = catalogArray.length;
5712:
5713:                /* Initialize the various variables associated with index scans of these catalogs */
5714:                for (ictr = 0; ictr < catalogCount; ictr++) {
5715:                    // NOTE: This only works for core catalogs, which are initialized
5716:                    // up front.
5717:                    catalog = catalogArray[ictr];
5718:
5719:                    numIndexes = catalog.getNumberOfIndexes();
5720:
5721:                    if (numIndexes > 0) {
5722:                        for (indexCtr = 0; indexCtr < numIndexes; indexCtr++) {
5723:                            initSystemIndexVariables(ddg, catalog, indexCtr);
5724:                        }
5725:                    }
5726:                }
5727:
5728:            }
5729:
5730:            /*
5731:             ** Methods related to create
5732:             */
5733:
5734:            /**
5735:            	Create all the required dictionary tables. Any classes that extend this class
5736:            	and need to create new tables shoudl override this method, and then
5737:            	call this method as the first action in the new method, e.g.
5738:            	<PRE>
5739:            	protected Configuration createDictionaryTables(Configuration cfg, TransactionController tc,
5740:            			DataDescriptorGenerator ddg)
5741:            			throws StandardException
5742:            	{
5743:            		super.createDictionaryTables(params, tc, ddg);
5744:
5745:            		...
5746:            	}
5747:            	</PRE>
5748:
5749:            	@exception StandardException Standard Cloudscape error policy
5750:             */
5751:            protected void createDictionaryTables(Properties params,
5752:                    TransactionController tc, DataDescriptorGenerator ddg)
5753:                    throws StandardException {
5754:                /*
5755:                 ** Create a new schema descriptor -- with no args
5756:                 ** creates the system schema descriptor in which 
5757:                 ** all tables reside (SYS)
5758:                 */
5759:                systemSchemaDesc = newSystemSchemaDesc(
5760:                        convertIdToLower ? StringUtil
5761:                                .SQLToLowerCase(SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME)
5762:                                : SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME,
5763:                        SchemaDescriptor.SYSTEM_SCHEMA_UUID);
5764:
5765:                /* Create the core tables and generate the UUIDs for their
5766:                 * heaps (before creating the indexes).
5767:                 * RESOLVE - This loop will eventually drive all of the
5768:                 * work for creating the core tables.
5769:                 */
5770:                for (int coreCtr = 0; coreCtr < NUM_CORE; coreCtr++) {
5771:                    TabInfoImpl ti = coreInfo[coreCtr];
5772:
5773:                    Properties heapProperties = ti.getCreateHeapProperties();
5774:
5775:                    ti.setHeapConglomerate(createConglomerate(
5776:                            ti.getTableName(), tc, ti.getCatalogRowFactory()
5777:                                    .makeEmptyRow(), heapProperties));
5778:
5779:                    // bootstrap indexes on core tables before bootstraping the tables themselves
5780:                    if (coreInfo[coreCtr].getNumberOfIndexes() > 0) {
5781:                        bootStrapSystemIndexes(systemSchemaDesc, tc, ddg, ti);
5782:                    }
5783:                }
5784:
5785:                // bootstrap the core tables into the data dictionary
5786:                for (int ictr = 0; ictr < NUM_CORE; ictr++) {
5787:                    /* RESOLVE - need to do something with COLUMNTYPE in following table creating code */
5788:                    TabInfoImpl ti = coreInfo[ictr];
5789:
5790:                    addSystemTableToDictionary(ti, systemSchemaDesc, tc, ddg);
5791:                }
5792:
5793:                // Add the bootstrap information to the configuration
5794:                params.put(CFG_SYSTABLES_ID, Long
5795:                        .toString(coreInfo[SYSTABLES_CORE_NUM]
5796:                                .getHeapConglomerate()));
5797:                params
5798:                        .put(
5799:                                CFG_SYSTABLES_INDEX1_ID,
5800:                                Long
5801:                                        .toString(coreInfo[SYSTABLES_CORE_NUM]
5802:                                                .getIndexConglomerate(((SYSTABLESRowFactory) coreInfo[SYSTABLES_CORE_NUM]
5803:                                                        .getCatalogRowFactory()).SYSTABLES_INDEX1_ID)));
5804:                params
5805:                        .put(
5806:                                CFG_SYSTABLES_INDEX2_ID,
5807:                                Long
5808:                                        .toString(coreInfo[SYSTABLES_CORE_NUM]
5809:                                                .getIndexConglomerate(((SYSTABLESRowFactory) coreInfo[SYSTABLES_CORE_NUM]
5810:                                                        .getCatalogRowFactory()).SYSTABLES_INDEX2_ID)));
5811:
5812:                params.put(CFG_SYSCOLUMNS_ID, Long
5813:                        .toString(coreInfo[SYSCOLUMNS_CORE_NUM]
5814:                                .getHeapConglomerate()));
5815:                params
5816:                        .put(
5817:                                CFG_SYSCOLUMNS_INDEX1_ID,
5818:                                Long
5819:                                        .toString(coreInfo[SYSCOLUMNS_CORE_NUM]
5820:                                                .getIndexConglomerate(((SYSCOLUMNSRowFactory) coreInfo[SYSCOLUMNS_CORE_NUM]
5821:                                                        .getCatalogRowFactory()).SYSCOLUMNS_INDEX1_ID)));
5822:                params
5823:                        .put(
5824:                                CFG_SYSCOLUMNS_INDEX2_ID,
5825:                                Long
5826:                                        .toString(coreInfo[SYSCOLUMNS_CORE_NUM]
5827:                                                .getIndexConglomerate(((SYSCOLUMNSRowFactory) coreInfo[SYSCOLUMNS_CORE_NUM]
5828:                                                        .getCatalogRowFactory()).SYSCOLUMNS_INDEX2_ID)));
5829:
5830:                params.put(CFG_SYSCONGLOMERATES_ID, Long
5831:                        .toString(coreInfo[SYSCONGLOMERATES_CORE_NUM]
5832:                                .getHeapConglomerate()));
5833:                params
5834:                        .put(
5835:                                CFG_SYSCONGLOMERATES_INDEX1_ID,
5836:                                Long
5837:                                        .toString(coreInfo[SYSCONGLOMERATES_CORE_NUM]
5838:                                                .getIndexConglomerate(((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM]
5839:                                                        .getCatalogRowFactory()).SYSCONGLOMERATES_INDEX1_ID)));
5840:                params
5841:                        .put(
5842:                                CFG_SYSCONGLOMERATES_INDEX2_ID,
5843:                                Long
5844:                                        .toString(coreInfo[SYSCONGLOMERATES_CORE_NUM]
5845:                                                .getIndexConglomerate(((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM]
5846:                                                        .getCatalogRowFactory()).SYSCONGLOMERATES_INDEX2_ID)));
5847:                params
5848:                        .put(
5849:                                CFG_SYSCONGLOMERATES_INDEX3_ID,
5850:                                Long
5851:                                        .toString(coreInfo[SYSCONGLOMERATES_CORE_NUM]
5852:                                                .getIndexConglomerate(((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM]
5853:                                                        .getCatalogRowFactory()).SYSCONGLOMERATES_INDEX3_ID)));
5854:
5855:                params.put(CFG_SYSSCHEMAS_ID, Long
5856:                        .toString(coreInfo[SYSSCHEMAS_CORE_NUM]
5857:                                .getHeapConglomerate()));
5858:                params
5859:                        .put(
5860:                                CFG_SYSSCHEMAS_INDEX1_ID,
5861:                                Long
5862:                                        .toString(coreInfo[SYSSCHEMAS_CORE_NUM]
5863:                                                .getIndexConglomerate(((SYSSCHEMASRowFactory) coreInfo[SYSSCHEMAS_CORE_NUM]
5864:                                                        .getCatalogRowFactory()).SYSSCHEMAS_INDEX1_ID)));
5865:                params
5866:                        .put(
5867:                                CFG_SYSSCHEMAS_INDEX2_ID,
5868:                                Long
5869:                                        .toString(coreInfo[SYSSCHEMAS_CORE_NUM]
5870:                                                .getIndexConglomerate(((SYSSCHEMASRowFactory) coreInfo[SYSSCHEMAS_CORE_NUM]
5871:                                                        .getCatalogRowFactory()).SYSSCHEMAS_INDEX2_ID)));
5872:
5873:                //Add the SYSIBM Schema
5874:                sysIBMSchemaDesc = addSystemSchema(
5875:                        SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
5876:                        SchemaDescriptor.SYSIBM_SCHEMA_UUID, tc);
5877:
5878:                /* Create the non-core tables and generate the UUIDs for their
5879:                 * heaps (before creating the indexes).
5880:                 * RESOLVE - This loop will eventually drive all of the
5881:                 * work for creating the non-core tables.
5882:                 */
5883:                for (int noncoreCtr = 0; noncoreCtr < NUM_NONCORE; noncoreCtr++) {
5884:                    int catalogNumber = noncoreCtr + NUM_CORE;
5885:                    boolean isDummy = (catalogNumber == SYSDUMMY1_CATALOG_NUM);
5886:
5887:                    TabInfoImpl ti = getNonCoreTIByNumber(catalogNumber);
5888:
5889:                    makeCatalog(ti, isDummy ? sysIBMSchemaDesc
5890:                            : systemSchemaDesc, tc);
5891:
5892:                    if (isDummy)
5893:                        populateSYSDUMMY1(tc);
5894:
5895:                    // Clear the table entry for this non-core table,
5896:                    // to allow it to be garbage-collected. The idea
5897:                    // is that a running database might never need to
5898:                    // reference a non-core table after it was created.
5899:                    clearNoncoreTable(noncoreCtr);
5900:                }
5901:
5902:                //Add ths System Schema
5903:                addDescriptor(systemSchemaDesc, null, SYSSCHEMAS_CATALOG_NUM,
5904:                        false, tc);
5905:
5906:                // Add the following system Schema's to be compatible with DB2, 
5907:                // currently Cloudscape does not use them, but by creating them as
5908:                // system schema's it will insure applications can't create them,
5909:                // drop them, or create objects in them.  This set includes:
5910:                //     SYSCAT
5911:                //     SYSFUN
5912:                //     SYSPROC
5913:                //     SYSSTAT
5914:                //     NULLID
5915:
5916:                //Add the SYSCAT Schema 
5917:                addSystemSchema(SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME,
5918:                        SchemaDescriptor.SYSCAT_SCHEMA_UUID, tc);
5919:
5920:                //Add the SYSFUN Schema
5921:                addSystemSchema(SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,
5922:                        SchemaDescriptor.SYSFUN_SCHEMA_UUID, tc);
5923:
5924:                //Add the SYSPROC Schema
5925:                addSystemSchema(SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME,
5926:                        SchemaDescriptor.SYSPROC_SCHEMA_UUID, tc);
5927:
5928:                //Add the SYSSTAT Schema
5929:                addSystemSchema(SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME,
5930:                        SchemaDescriptor.SYSSTAT_SCHEMA_UUID, tc);
5931:
5932:                //Add the NULLID Schema
5933:                addSystemSchema(SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME,
5934:                        SchemaDescriptor.NULLID_SCHEMA_UUID, tc);
5935:
5936:                //Add the SQLJ Schema
5937:                addSystemSchema(SchemaDescriptor.STD_SQLJ_SCHEMA_NAME,
5938:                        SchemaDescriptor.SQLJ_SCHEMA_UUID, tc);
5939:
5940:                //Add the SYSCS_DIAG Schema
5941:                addSystemSchema(SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME,
5942:                        SchemaDescriptor.SYSCS_DIAG_SCHEMA_UUID, tc);
5943:
5944:                //Add the SYSCS_UTIL Schema
5945:                addSystemSchema(SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME,
5946:                        SchemaDescriptor.SYSCS_UTIL_SCHEMA_UUID, tc);
5947:
5948:                //Add the APP schema
5949:                SchemaDescriptor appSchemaDesc = new SchemaDescriptor(
5950:                        this ,
5951:                        SchemaDescriptor.STD_DEFAULT_SCHEMA_NAME,
5952:                        SchemaDescriptor.DEFAULT_USER_NAME,
5953:                        uuidFactory
5954:                                .recreateUUID(SchemaDescriptor.DEFAULT_SCHEMA_UUID),
5955:                        false);
5956:
5957:                addDescriptor(appSchemaDesc, null, SYSSCHEMAS_CATALOG_NUM,
5958:                        false, tc);
5959:            }
5960:
5961:            /**
5962:             * Add a system schema to the database.
5963:             * <p>
5964:             *
5965:             * @param schema_name   name of the schema to add.
5966:             *
5967:             * @exception  StandardException  Standard exception policy.
5968:             **/
5969:            private SchemaDescriptor addSystemSchema(String schema_name,
5970:                    String schema_uuid, TransactionController tc)
5971:                    throws StandardException {
5972:                // create the descriptor
5973:                SchemaDescriptor schema_desc = new SchemaDescriptor(this ,
5974:                        convertIdToLower ? schema_name.toLowerCase()
5975:                                : schema_name, authorizationDatabaseOwner,
5976:                        uuidFactory.recreateUUID(schema_uuid), true);
5977:
5978:                // add it to the catalog.
5979:                addDescriptor(schema_desc, null, SYSSCHEMAS_CATALOG_NUM, false,
5980:                        tc);
5981:
5982:                return (schema_desc);
5983:            }
5984:
5985:            /** called by the upgrade code (dd_xena etc) to add a new system catalog.
5986:             * 
5987:             * @param 	tc 				TransactionController to use.
5988:             * @param 	catalogNumber	catalogNumber
5989:             */
5990:            protected void upgradeMakeCatalog(TransactionController tc,
5991:                    int catalogNumber) throws StandardException {
5992:                TabInfoImpl ti;
5993:                if (catalogNumber >= NUM_CORE)
5994:                    ti = getNonCoreTIByNumber(catalogNumber);
5995:                else
5996:                    ti = coreInfo[catalogNumber];
5997:
5998:                makeCatalog(
5999:                        ti,
6000:                        (catalogNumber == SYSDUMMY1_CATALOG_NUM) ? getSysIBMSchemaDescriptor()
6001:                                : getSystemSchemaDescriptor(), tc);
6002:            }
6003:
6004:            /**
6005:             *	The dirty work of creating a catalog.
6006:             *
6007:             *	@param	ti			TabInfoImpl describing catalog to create.
6008:             *	@param	sd			Schema to create catalogs in.
6009:             *	@param	tc			Transaction context.
6010:             *
6011:             *	@exception StandardException Standard Cloudscape error policy
6012:             */
6013:            public void makeCatalog(TabInfoImpl ti, SchemaDescriptor sd,
6014:                    TransactionController tc) throws StandardException {
6015:                DataDescriptorGenerator ddg = getDataDescriptorGenerator();
6016:
6017:                Properties heapProperties = ti.getCreateHeapProperties();
6018:                ti.setHeapConglomerate(createConglomerate(ti.getTableName(),
6019:                        tc, ti.getCatalogRowFactory().makeEmptyRow(),
6020:                        heapProperties));
6021:
6022:                // bootstrap indexes on core tables before bootstrapping the tables themselves
6023:                if (ti.getNumberOfIndexes() > 0) {
6024:                    bootStrapSystemIndexes(sd, tc, ddg, ti);
6025:                }
6026:
6027:                addSystemTableToDictionary(ti, sd, tc, ddg);
6028:            }
6029:
6030:            /**
6031:             *	Upgrade an existing catalog by  setting the nullability
6032:             *
6033:             *	@param	columnNumber			The column to change
6034:             *	@param	nullability				true if nullable 
6035:             *	@param	tc						Transaction controller
6036:             *
6037:             *	@exception StandardException Standard Cloudscape error policy
6038:             */
6039:            public void upgrade_setNullability(CatalogRowFactory rowFactory,
6040:                    int columnNumber, boolean nullability,
6041:                    TransactionController tc) throws StandardException {
6042:                SystemColumn theColumn;
6043:                SystemColumn[] columns = rowFactory.buildColumnList();
6044:                SchemaDescriptor sd = getSystemSchemaDescriptor();
6045:                String columnName;
6046:
6047:                TableDescriptor td = getTableDescriptor(rowFactory
6048:                        .getCatalogName(), sd);
6049:
6050:                theColumn = columns[columnNumber - 1]; // from 1 to 0 based
6051:                ColumnDescriptor cd = makeColumnDescriptor(theColumn,
6052:                        columnNumber, td);
6053:                columnName = cd.getColumnName();
6054:                cd.getType().setNullability(nullability);
6055:                int[] columnNameColArray = new int[1];
6056:                columnNameColArray[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDATATYPE;
6057:                updateColumnDescriptor(cd, td.getUUID(), columnName,
6058:                        columnNameColArray, tc, true);
6059:
6060:            }
6061:
6062:            /**
6063:             *	Upgrade an existing catalog by adding columns.
6064:             *
6065:             *	@param	rowFactory				Associated with this catalog.
6066:             *	@param	newColumnIDs			Array of 1-based column ids.
6067:             *	@param	tc						Transaction controller
6068:             *
6069:             *	@exception StandardException Standard Cloudscape error policy
6070:             */
6071:            public void upgrade_addColumns(CatalogRowFactory rowFactory,
6072:                    int[] newColumnIDs, TransactionController tc)
6073:                    throws StandardException {
6074:                int columnID;
6075:                SystemColumn currentColumn;
6076:                ColumnDescriptor cd;
6077:
6078:                SystemColumn[] columns = rowFactory.buildColumnList();
6079:                ExecRow templateRow = rowFactory.makeEmptyRow();
6080:                int columnCount = newColumnIDs.length;
6081:                SchemaDescriptor sd = getSystemSchemaDescriptor();
6082:                TableDescriptor td;
6083:                long conglomID;
6084:
6085:                // Special case when adding a column to systables or syscolumns, 
6086:                // since we can't go to systables/syscolumns to get the 
6087:                // table/column descriptor until after we add and populate the new column.
6088:                if (rowFactory instanceof  SYSTABLESRowFactory) {
6089:                    td = dataDescriptorGenerator.newTableDescriptor(
6090:                            "SYSTABLES", sd, TableDescriptor.BASE_TABLE_TYPE,
6091:                            TableDescriptor.ROW_LOCK_GRANULARITY);
6092:                    td.setUUID(getUUIDForCoreTable("SYSTABLES", sd.getUUID()
6093:                            .toString(), tc));
6094:                    conglomID = coreInfo[SYSTABLES_CORE_NUM]
6095:                            .getHeapConglomerate();
6096:                } else if (rowFactory instanceof  SYSCOLUMNSRowFactory) {
6097:                    td = dataDescriptorGenerator.newTableDescriptor(
6098:                            "SYSCOLUMNS", sd, TableDescriptor.BASE_TABLE_TYPE,
6099:                            TableDescriptor.ROW_LOCK_GRANULARITY);
6100:                    td.setUUID(getUUIDForCoreTable("SYSCOLUMNS", sd.getUUID()
6101:                            .toString(), tc));
6102:                    conglomID = coreInfo[SYSCOLUMNS_CORE_NUM]
6103:                            .getHeapConglomerate();
6104:                } else {
6105:                    td = getTableDescriptor(rowFactory.getCatalogName(), sd);
6106:                    conglomID = td.getHeapConglomerateId();
6107:                }
6108:
6109:                widenConglomerate(templateRow, newColumnIDs, conglomID, tc);
6110:
6111:                ColumnDescriptor[] cdArray = new ColumnDescriptor[columnCount];
6112:                for (int ix = 0; ix < columnCount; ix++) {
6113:                    columnID = newColumnIDs[ix];
6114:                    currentColumn = columns[columnID - 1]; // from 1 to 0 based
6115:
6116:                    cdArray[ix] = makeColumnDescriptor(currentColumn, ix + 1,
6117:                            td);
6118:                }
6119:                addDescriptorArray(cdArray, td, SYSCOLUMNS_CATALOG_NUM, false,
6120:                        tc);
6121:
6122:            }
6123:
6124:            /**
6125:             *	Add invisible columns to an existing system catalog
6126:             *
6127:             *	@param	rowFactory				Associated with this catalog.
6128:             *	@param	newColumnIDs			Array of 1-based column ids.
6129:             *	@param	tc						Transaction controller
6130:             *
6131:             *	@exception StandardException Standard Cloudscape error policy
6132:             */
6133:            public void upgrade_addInvisibleColumns(
6134:                    CatalogRowFactory rowFactory, int[] newColumnIDs,
6135:                    TransactionController tc) throws StandardException {
6136:                ExecRow templateRow = rowFactory.makeEmptyRow();
6137:                SchemaDescriptor sd = getSystemSchemaDescriptor();
6138:                long conglomID = getTableDescriptor(
6139:                        rowFactory.getCatalogName(), sd)
6140:                        .getHeapConglomerateId();
6141:
6142:                widenConglomerate(templateRow, newColumnIDs, conglomID, tc);
6143:            }
6144:
6145:            /**
6146:             *	Adds columns to the conglomerate underlying a system table.
6147:             *
6148:             *	@param	templateRow				Ultimate shape of base row of table
6149:             *	@param	newColumnIDs			Array of 1-based column ids
6150:             *	@param	conglomID				heap id
6151:             *	@param	tc						Transaction controller
6152:             *
6153:             *	@exception StandardException Standard Cloudscape error policy
6154:             */
6155:            private void widenConglomerate(ExecRow templateRow,
6156:                    int[] newColumnIDs, long conglomID, TransactionController tc)
6157:                    throws StandardException {
6158:                int columnCount = newColumnIDs.length;
6159:
6160:                for (int ix = 0; ix < columnCount; ix++) {
6161:                    int columnID = newColumnIDs[ix];
6162:                    int storablePosition = columnID - 1; // from 1 to 0 based
6163:
6164:                    tc.addColumnToConglomerate(conglomID, storablePosition,
6165:                            templateRow.getColumn(columnID));
6166:                }
6167:
6168:            }
6169:
6170:            /**
6171:             *	Code to add an index to a catalog during upgrade.
6172:             *
6173:             *	@param	tc						transaction controller
6174:             *	@param	ti						information on the catalog that's having a new index added
6175:             *	@param	indexNumber				0-based index number
6176:             *	@param	heapConglomerateNumber	what it is
6177:             *
6178:             * @return The conglomerate number of the new index.
6179:             *
6180:             * @exception StandardException		Thrown on failure
6181:             */
6182:            public long upgrade_makeOneIndex(TransactionController tc,
6183:                    TabInfoImpl ti, int indexNumber, long heapConglomerateNumber)
6184:                    throws StandardException {
6185:                SchemaDescriptor sd = getSystemSchemaDescriptor();
6186:                DataDescriptorGenerator ddg = getDataDescriptorGenerator();
6187:                long indexConglomerateNumber;
6188:
6189:                ConglomerateDescriptor conglomerateDescriptor = bootstrapOneIndex(
6190:                        sd, tc, ddg, ti, indexNumber, heapConglomerateNumber);
6191:
6192:                indexConglomerateNumber = conglomerateDescriptor
6193:                        .getConglomerateNumber();
6194:
6195:                addDescriptor(conglomerateDescriptor, sd,
6196:                        SYSCONGLOMERATES_CATALOG_NUM, false, tc);
6197:
6198:                return indexConglomerateNumber;
6199:            }
6200:
6201:            /**
6202:             * Get the UUID for the specified system table.  Prior
6203:             * to Plato, system tables did not have canonical UUIDs, so
6204:             * we need to scan systables to get the UUID when we
6205:             * are updating the core tables.
6206:             *
6207:             * @param tableName		Name of the table
6208:             * @param schemaUUID	UUID of schema
6209:             * @param tc			TransactionController to user
6210:             *
6211:             * @return UUID	The UUID of the core table.
6212:             *
6213:             * @exception StandardException		Thrown on failure
6214:             */
6215:            private UUID getUUIDForCoreTable(String tableName,
6216:                    String schemaUUID, TransactionController tc)
6217:                    throws StandardException {
6218:                ConglomerateController heapCC;
6219:                ExecIndexRow indexRow1;
6220:                ExecRow row;
6221:                DataValueDescriptor schemaIDOrderable;
6222:                DataValueDescriptor tableNameOrderable;
6223:                ScanController scanController;
6224:                TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
6225:                SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti
6226:                        .getCatalogRowFactory();
6227:
6228:                // We only want the 1st column from the heap
6229:                row = exFactory.getValueRow(1);
6230:
6231:                /* Use tableNameOrderable and schemaIdOrderable in both start 
6232:                 * and stop position for scan. 
6233:                 */
6234:                tableNameOrderable = dvf.getVarcharDataValue(tableName);
6235:                schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
6236:
6237:                /* Set up the start/stop position for the scan */
6238:                ExecIndexRow keyRow = exFactory.getIndexableRow(2);
6239:                keyRow.setColumn(1, tableNameOrderable);
6240:                keyRow.setColumn(2, schemaIDOrderable);
6241:
6242:                heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false,
6243:                        0, TransactionController.MODE_RECORD,
6244:                        TransactionController.ISOLATION_REPEATABLE_READ);
6245:
6246:                ExecRow indexTemplateRow = rf.buildEmptyIndexRow(
6247:                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID, heapCC
6248:                                .newRowLocationTemplate());
6249:
6250:                /* Scan the index and go to the data pages for qualifying rows to
6251:                 * build the column descriptor.
6252:                 */
6253:                scanController = tc
6254:                        .openScan(
6255:                                ti
6256:                                        .getIndexConglomerate(SYSTABLESRowFactory.SYSTABLES_INDEX1_ID), // conglomerate to open
6257:                                false, // don't hold open across commit
6258:                                0,
6259:                                TransactionController.MODE_RECORD,
6260:                                TransactionController.ISOLATION_REPEATABLE_READ,
6261:                                (FormatableBitSet) null, // all fields as objects
6262:                                keyRow.getRowArray(), // start position - first row
6263:                                ScanController.GE, // startSearchOperation
6264:                                (ScanQualifier[][]) null, //scanQualifier,
6265:                                keyRow.getRowArray(), // stop position - through last row
6266:                                ScanController.GT); // stopSearchOperation
6267:
6268:                /* OK to fetch into the template row, 
6269:                 * since we won't be doing a next.
6270:                 */
6271:                if (scanController.fetchNext(indexTemplateRow.getRowArray())) {
6272:                    RowLocation baseRowLocation;
6273:
6274:                    baseRowLocation = (RowLocation) indexTemplateRow
6275:                            .getColumn(indexTemplateRow.nColumns());
6276:
6277:                    /* 1st column is TABLEID (UUID - char(36)) */
6278:                    row.setColumn(SYSTABLESRowFactory.SYSTABLES_TABLEID, dvf
6279:                            .getCharDataValue((String) null));
6280:                    FormatableBitSet bi = new FormatableBitSet(1);
6281:                    bi.set(0);
6282:                    boolean base_row_exists = heapCC.fetch(baseRowLocation, row
6283:                            .getRowArray(), (FormatableBitSet) null);
6284:
6285:                    if (SanityManager.DEBUG) {
6286:                        // it can not be possible for heap row to disappear while 
6287:                        // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
6288:                        SanityManager.ASSERT(base_row_exists,
6289:                                "base row not found");
6290:                    }
6291:                }
6292:
6293:                scanController.close();
6294:                heapCC.close();
6295:
6296:                return uuidFactory.recreateUUID(row.getColumn(1).toString());
6297:            }
6298:
6299:            /**
6300:             * Initialize noncore columns to fixed values
6301:             *
6302:             * @param tc					The TransactionController for the transaction to do the
6303:             *								upgrade in.
6304:             * @param isCoreTable			true if it is a core table
6305:             * @param tableNum				the noncore table number
6306:             * @param columnsToUpdateSet	a bit set of columns to update.  ZERO BASED	
6307:             * @param replaceRow			an object array of Orderables for the new values
6308:             *
6309:             * @exception StandardException		Thrown on error
6310:             */
6311:            void upgrade_initSystemTableCols(TransactionController tc,
6312:                    boolean isCoreTable, int tableNum,
6313:                    FormatableBitSet columnsToUpdateSet,
6314:                    DataValueDescriptor[] replaceRow) throws StandardException {
6315:
6316:                TabInfoImpl ti = (isCoreTable) ? coreInfo[tableNum]
6317:                        : getNonCoreTIByNumber(tableNum);
6318:
6319:                if (!isCoreTable)
6320:                    faultInTabInfo(ti);
6321:
6322:                /* Scan the entire heap */
6323:                ScanController sc = tc.openScan(ti.getHeapConglomerate(),
6324:                        false, TransactionController.OPENMODE_FORUPDATE,
6325:                        TransactionController.MODE_TABLE,
6326:                        TransactionController.ISOLATION_REPEATABLE_READ,
6327:                        RowUtil.EMPTY_ROW_BITSET, (DataValueDescriptor[]) null,
6328:                        ScanController.NA, (Qualifier[][]) null,
6329:                        (DataValueDescriptor[]) null, ScanController.NA);
6330:
6331:                while (sc.next()) {
6332:                    /* Replace the column in the table */
6333:                    sc.replace(replaceRow, columnsToUpdateSet);
6334:                }
6335:
6336:                sc.close();
6337:            }
6338:
6339:            /*
6340:             *******************************************************************************
6341:             *
6342:             *	See RepBasicDataDictionary for sample code on how to create a system
6343:             *	table.
6344:             *
6345:             *	What follows here is special code for the core catalogs. These are catalogs
6346:             *	which have to exist before any other system tables are created.
6347:             *
6348:             *	Creating a core catalog consists of two steps: 1) creating all the infrastructure
6349:             *	needed to make generic systemTableCreation work, 2) actually populating the
6350:             *	Data Dictionary and core conglomerates with tuples.
6351:             *
6352:             *******************************************************************************
6353:             */
6354:
6355:            /**
6356:             *	Infrastructure work for indexes on catalogs.
6357:             *
6358:               @exception StandardException Standard Cloudscape error policy
6359:
6360:             */
6361:            private void bootStrapSystemIndexes(SchemaDescriptor sd,
6362:                    TransactionController tc, DataDescriptorGenerator ddg,
6363:                    TabInfoImpl ti) throws StandardException {
6364:                ConglomerateDescriptor[] cgd = new ConglomerateDescriptor[ti
6365:                        .getNumberOfIndexes()];
6366:
6367:                /* Ordering problem with sysconglomerates.  We need to create 
6368:                 * all of the conglomerates first before adding rows to 
6369:                 * sysconglomerates.  (All of the conglomerates for sysconglomerates
6370:                 * must be there before we can add to them.)
6371:                 *
6372:                 */
6373:                for (int indexCtr = 0; indexCtr < ti.getNumberOfIndexes(); indexCtr++) {
6374:                    cgd[indexCtr] = bootstrapOneIndex(sd, tc, ddg, ti,
6375:                            indexCtr, ti.getHeapConglomerate());
6376:                }
6377:
6378:                for (int indexCtr = 0; indexCtr < ti.getNumberOfIndexes(); indexCtr++) {
6379:                    addDescriptor(cgd[indexCtr], sd,
6380:                            SYSCONGLOMERATES_CATALOG_NUM, false, tc);
6381:                }
6382:            }
6383:
6384:            /**
6385:             * @see DataDictionary#computeAutoincRowLocations
6386:             */
6387:            public RowLocation[] computeAutoincRowLocations(
6388:                    TransactionController tc, TableDescriptor td)
6389:                    throws StandardException {
6390:                int size;
6391:                if (!(td.tableHasAutoincrement()))
6392:                    return null;
6393:
6394:                size = td.getNumberOfColumns();
6395:                RowLocation[] rla = new RowLocation[size];
6396:
6397:                for (int i = 0; i < size; i++) {
6398:                    ColumnDescriptor cd = td.getColumnDescriptor(i + 1);
6399:                    if (cd.isAutoincrement())
6400:                        rla[i] = computeRowLocation(tc, td, cd.getColumnName());
6401:                }
6402:                return rla;
6403:            }
6404:
6405:            /**
6406:             * @see DataDictionary#getSetAutoincrementValue
6407:             */
6408:            public NumberDataValue getSetAutoincrementValue(RowLocation rl,
6409:                    TransactionController tc, boolean doUpdate,
6410:                    NumberDataValue newValue, boolean wait)
6411:                    throws StandardException {
6412:
6413:                FormatableBitSet columnToUpdate = new FormatableBitSet(
6414:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
6415:                int columnNum = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
6416:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
6417:                ConglomerateController heapCC = null;
6418:                SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti
6419:                        .getCatalogRowFactory();
6420:                ExecRow row = rf.makeEmptyRow();
6421:
6422:                FormatableBitSet columnToRead = new FormatableBitSet(
6423:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
6424:
6425:                // FormatableBitSet is 0 based.
6426:                columnToRead.set(columnNum - 1); // current value.
6427:                columnToRead.set(columnNum); // start value.
6428:                columnToRead.set(columnNum + 1); // increment value.
6429:
6430:                try {
6431:                    /* if wait is true then we need to do a wait while trying to
6432:                       open/fetch from the conglomerate. note we use wait both to
6433:                       open as well as fetch from the conglomerate.
6434:                     */
6435:                    heapCC = tc
6436:                            .openConglomerate(
6437:                                    ti.getHeapConglomerate(),
6438:                                    false,
6439:                                    (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0
6440:                                            : TransactionController.OPENMODE_LOCK_NOWAIT)),
6441:                                    TransactionController.MODE_RECORD,
6442:                                    TransactionController.ISOLATION_REPEATABLE_READ);
6443:
6444:                    boolean baseRowExists = heapCC.fetch(rl, row.getRowArray(),
6445:                            columnToRead, wait);
6446:
6447:                    columnToUpdate.set(columnNum - 1); // current value.
6448:
6449:                    // while the Row interface is 1 based.
6450:                    NumberDataValue currentAI = (NumberDataValue) row
6451:                            .getColumn(columnNum);
6452:                    long currentAIValue = currentAI.getLong();
6453:                    NumberDataValue increment = (NumberDataValue) row
6454:                            .getColumn(columnNum + 2);
6455:
6456:                    if (doUpdate) {
6457:                        // we increment and store the new value in SYSCOLUMNS
6458:                        currentAI = currentAI.plus(currentAI, increment,
6459:                                currentAI);
6460:                        row.setColumn(columnNum, currentAI);
6461:                        heapCC.replace(rl, row.getRowArray(), columnToUpdate);
6462:                    }
6463:
6464:                    // but we return the "currentAIValue"-- i.e the value before
6465:                    // incrementing it. 
6466:                    if (newValue != null) {
6467:                        // user has passed in an object; set the current value in there and
6468:                        // return it.
6469:                        newValue.setValue(currentAIValue);
6470:                        return newValue;
6471:                    }
6472:
6473:                    else {
6474:                        // reuse the object read from row.
6475:                        currentAI.setValue(currentAIValue);
6476:                        return currentAI;
6477:                    }
6478:                } finally {
6479:                    if (heapCC != null)
6480:                        heapCC.close();
6481:                }
6482:            }
6483:
6484:            private ConglomerateDescriptor bootstrapOneIndex(
6485:                    SchemaDescriptor sd, TransactionController tc,
6486:                    DataDescriptorGenerator ddg, TabInfoImpl ti,
6487:                    int indexNumber, long heapConglomerateNumber)
6488:                    throws StandardException {
6489:                boolean isUnique;
6490:                ConglomerateController cc;
6491:                ExecRow baseRow;
6492:                ExecIndexRow indexableRow;
6493:                int numColumns;
6494:                long conglomId;
6495:                RowLocation rl;
6496:                CatalogRowFactory rf = ti.getCatalogRowFactory();
6497:                IndexRowGenerator irg;
6498:                ConglomerateDescriptor conglomerateDescriptor;
6499:
6500:                initSystemIndexVariables(ddg, ti, indexNumber);
6501:
6502:                irg = ti.getIndexRowGenerator(indexNumber);
6503:
6504:                numColumns = ti.getIndexColumnCount(indexNumber);
6505:
6506:                /* Is the index unique */
6507:                isUnique = ti.isIndexUnique(indexNumber);
6508:
6509:                // create an index row template
6510:                indexableRow = irg.getIndexRowTemplate();
6511:
6512:                baseRow = rf.makeEmptyRow();
6513:
6514:                // Get a RowLocation template
6515:                cc = tc.openConglomerate(heapConglomerateNumber, false, 0,
6516:                        TransactionController.MODE_RECORD,
6517:                        TransactionController.ISOLATION_REPEATABLE_READ);
6518:
6519:                rl = cc.newRowLocationTemplate();
6520:                cc.close();
6521:
6522:                // Get an index row based on the base row
6523:                irg.getIndexRow(baseRow, rl, indexableRow,
6524:                        (FormatableBitSet) null);
6525:
6526:                // Describe the properties of the index to the store using Properties
6527:                // RESOLVE: The following properties assume a BTREE index.
6528:                Properties indexProperties = ti
6529:                        .getCreateIndexProperties(indexNumber);
6530:
6531:                // Tell it the conglomerate id of the base table
6532:                indexProperties.put("baseConglomerateId", Long
6533:                        .toString(heapConglomerateNumber));
6534:
6535:                // All indexes are unique because they contain the RowLocation.
6536:                // The number of uniqueness columns must include the RowLocation
6537:                // if the user did not specify a unique index.
6538:                indexProperties.put("nUniqueColumns", Integer
6539:                        .toString(isUnique ? numColumns : numColumns + 1));
6540:
6541:                // By convention, the row location column is the last column
6542:                indexProperties.put("rowLocationColumn", Integer
6543:                        .toString(numColumns));
6544:
6545:                // For now, all columns are key fields, including the RowLocation
6546:                indexProperties.put("nKeyFields", Integer
6547:                        .toString(numColumns + 1));
6548:
6549:                /* Create and add the conglomerate (index) */
6550:                conglomId = tc.createConglomerate("BTREE", // we're requesting an index conglomerate
6551:                        indexableRow.getRowArray(), null, //default sort order
6552:                        indexProperties, // default properties
6553:                        TransactionController.IS_DEFAULT); // not temporary
6554:
6555:                conglomerateDescriptor = ddg.newConglomerateDescriptor(
6556:                        conglomId, rf.getIndexName(indexNumber), true, irg,
6557:                        false, rf.getCanonicalIndexUUID(indexNumber), rf
6558:                                .getCanonicalTableUUID(), sd.getUUID());
6559:                ti.setIndexConglomerate(conglomerateDescriptor);
6560:
6561:                return conglomerateDescriptor;
6562:            }
6563:
6564:            public void initSystemIndexVariables(DataDescriptorGenerator ddg,
6565:                    TabInfoImpl ti, int indexNumber) throws StandardException {
6566:                int numCols = ti.getIndexColumnCount(indexNumber);
6567:                int[] baseColumnPositions = new int[numCols];
6568:                CatalogRowFactory rf = ti.getCatalogRowFactory();
6569:
6570:                for (int colCtr = 0; colCtr < numCols; colCtr++) {
6571:                    baseColumnPositions[colCtr] = ti.getBaseColumnPosition(
6572:                            indexNumber, colCtr);
6573:                }
6574:
6575:                boolean[] isAscending = new boolean[baseColumnPositions.length];
6576:                for (int i = 0; i < baseColumnPositions.length; i++)
6577:                    isAscending[i] = true;
6578:
6579:                // For now, assume that all index columns are ordered columns
6580:                ti.setIndexRowGenerator(indexNumber, new IndexRowGenerator(
6581:                        "BTREE", ti.isIndexUnique(indexNumber),
6582:                        baseColumnPositions, isAscending,
6583:                        baseColumnPositions.length));
6584:            }
6585:
6586:            /**
6587:             *	Populate SYSDUMMY1 table with a single row.
6588:             *
6589:             * @exception StandardException Standard Cloudscape error policy
6590:             */
6591:            protected void populateSYSDUMMY1(TransactionController tc)
6592:                    throws StandardException {
6593:                TabInfoImpl ti = getNonCoreTI(SYSDUMMY1_CATALOG_NUM);
6594:                ExecRow row = ti.getCatalogRowFactory().makeRow(null, null);
6595:
6596:                int insertRetCode = ti.insertRow(row, tc, true);
6597:            }
6598:
6599:            /**
6600:             * Clear all of the DataDictionary caches.
6601:             *
6602:             * @exception StandardException Standard Cloudscape error policy
6603:             */
6604:            public void clearCaches() throws StandardException {
6605:                nameTdCache.cleanAll();
6606:                nameTdCache.ageOut();
6607:                OIDTdCache.cleanAll();
6608:                OIDTdCache.ageOut();
6609:                if (spsNameCache != null) {
6610:                    //System.out.println("CLEARING SPS CACHE");
6611:                    spsNameCache.cleanAll();
6612:                    spsNameCache.ageOut();
6613:                    spsIdHash.clear();
6614:                    // spsTextHash.clear();
6615:                }
6616:            }
6617:
6618:            /**
6619:            	Add the required entries to the data dictionary for a System table.
6620:             */
6621:
6622:            private void addSystemTableToDictionary(TabInfoImpl ti,
6623:                    SchemaDescriptor sd, TransactionController tc,
6624:                    DataDescriptorGenerator ddg) throws StandardException {
6625:                CatalogRowFactory crf = ti.getCatalogRowFactory();
6626:
6627:                String name = ti.getTableName();
6628:                long conglomId = ti.getHeapConglomerate();
6629:                SystemColumn[] columnList = crf.buildColumnList();
6630:                UUID heapUUID = crf.getCanonicalHeapUUID();
6631:                String heapName = crf.getCanonicalHeapName();
6632:                TableDescriptor td;
6633:                UUID toid;
6634:                ColumnDescriptor cd;
6635:                int columnCount;
6636:                SystemColumn column;
6637:
6638:                // add table to the data dictionary
6639:
6640:                columnCount = columnList.length;
6641:                td = ddg.newTableDescriptor(name, sd,
6642:                        TableDescriptor.SYSTEM_TABLE_TYPE,
6643:                        TableDescriptor.ROW_LOCK_GRANULARITY);
6644:                td.setUUID(crf.getCanonicalTableUUID());
6645:                addDescriptor(td, sd, SYSTABLES_CATALOG_NUM, false, tc);
6646:                toid = td.getUUID();
6647:
6648:                /* Add the conglomerate for the heap */
6649:                ConglomerateDescriptor cgd = ddg.newConglomerateDescriptor(
6650:                        conglomId, heapName, false, null, false, heapUUID,
6651:                        toid, sd.getUUID());
6652:
6653:                addDescriptor(cgd, sd, SYSCONGLOMERATES_CATALOG_NUM, false, tc);
6654:
6655:                /* Create the columns */
6656:                ColumnDescriptor[] cdlArray = new ColumnDescriptor[columnCount];
6657:
6658:                for (int columnNumber = 0; columnNumber < columnCount; columnNumber++) {
6659:                    column = columnList[columnNumber];
6660:
6661:                    if (SanityManager.DEBUG) {
6662:                        if (column == null) {
6663:                            SanityManager.THROWASSERT("column " + columnNumber
6664:                                    + " for table " + ti.getTableName()
6665:                                    + " is null");
6666:                        }
6667:                    }
6668:                    cdlArray[columnNumber] = makeColumnDescriptor(column,
6669:                            columnNumber + 1, td);
6670:                }
6671:                addDescriptorArray(cdlArray, td, SYSCOLUMNS_CATALOG_NUM, false,
6672:                        tc);
6673:
6674:                // now add the columns to the cdl of the table.
6675:                ColumnDescriptorList cdl = td.getColumnDescriptorList();
6676:                for (int i = 0; i < columnCount; i++)
6677:                    cdl.add(cdlArray[i]);
6678:            }
6679:
6680:            /**
6681:             *	Converts a SystemColumn to a ColumnDescriptor.
6682:             *
6683:             *	@param	column	a SystemColumn
6684:             * @param  columnPosition Position of the column in the table, one based.
6685:             *	@param	td		descriptor for table that column lives in
6686:             *
6687:             *	@return	a ColumnDes*criptor
6688:             *
6689:             *	@exception StandardException Standard Cloudscape error policy
6690:             */
6691:            private ColumnDescriptor makeColumnDescriptor(SystemColumn column,
6692:                    int columnPosition, TableDescriptor td)
6693:                    throws StandardException {
6694:                //RESOLVEAUTOINCREMENT
6695:                return new ColumnDescriptor(column.getName(), columnPosition,
6696:                        column.getType(), null, null, td, (UUID) null, // No defaults yet for system columns
6697:                        0, 0);
6698:            }
6699:
6700:            /**
6701:             *	Create a conglomerate for a system table
6702:             *
6703:             *	@param name 		Name of new catalog.
6704:             *	@param tc			Transaction context.
6705:             *	@param rowTemplate	Template for rows for the new table
6706:             *  @param properties	Properties for createConglomerate
6707:             *
6708:             *	@return	Conglomerate id.
6709:
6710:            	@exception StandardException Standard Cloudscape error policy.
6711:             */
6712:            private long createConglomerate(String name,
6713:                    TransactionController tc, ExecRow rowTemplate,
6714:                    Properties properties) throws StandardException {
6715:                long conglomId;
6716:
6717:                conglomId = tc.createConglomerate("heap", // we're requesting a heap conglomerate
6718:                        rowTemplate.getRowArray(), // row template
6719:                        null, // default sort order
6720:                        properties, // default properties
6721:                        TransactionController.IS_DEFAULT); // not temporary
6722:
6723:                return conglomId;
6724:            }
6725:
6726:            /**
6727:             *	Converts a UUID to an DataValueDescriptor.
6728:             *
6729:             *	@return	the UUID converted to an DataValueDescriptor
6730:             *
6731:             * @exception StandardException		Thrown on error
6732:             */
6733:            public DataValueDescriptor getValueAsDVD(UUID uuid)
6734:                    throws StandardException {
6735:                String uuidString = uuid.toString();
6736:                return dvf.getCharDataValue(uuidString);
6737:            }
6738:
6739:            /**
6740:             *	Initialize catalog information. This method is overridden by children.
6741:             * @exception StandardException		Thrown on error
6742:             */
6743:            public void initializeCatalogInfo() throws StandardException {
6744:                initializeCoreInfo();
6745:                initializeNoncoreInfo();
6746:            }
6747:
6748:            /**
6749:             * Initialized the core info array.
6750:             */
6751:            private void initializeCoreInfo() throws StandardException {
6752:                TabInfoImpl[] lcoreInfo = coreInfo = new TabInfoImpl[NUM_CORE];
6753:
6754:                UUIDFactory luuidFactory = uuidFactory;
6755:
6756:                lcoreInfo[SYSTABLES_CORE_NUM] = new TabInfoImpl(
6757:                        new SYSTABLESRowFactory(luuidFactory, exFactory, dvf,
6758:                                convertIdToLower));
6759:                lcoreInfo[SYSCOLUMNS_CORE_NUM] = new TabInfoImpl(
6760:                        new SYSCOLUMNSRowFactory(luuidFactory, exFactory, dvf,
6761:                                convertIdToLower));
6762:                lcoreInfo[SYSCONGLOMERATES_CORE_NUM] = new TabInfoImpl(
6763:                        new SYSCONGLOMERATESRowFactory(luuidFactory, exFactory,
6764:                                dvf, convertIdToLower));
6765:                lcoreInfo[SYSSCHEMAS_CORE_NUM] = new TabInfoImpl(
6766:                        new SYSSCHEMASRowFactory(luuidFactory, exFactory, dvf,
6767:                                convertIdToLower));
6768:            }
6769:
6770:            /**
6771:             * Initialized the noncore info array.
6772:             */
6773:            private void initializeNoncoreInfo() throws StandardException {
6774:                noncoreInfo = new TabInfoImpl[NUM_NONCORE];
6775:            }
6776:
6777:            /**
6778:             * Get the TransactionController to use, when not
6779:             * passed in as a parameter.  (This hides logic about
6780:             * whether or not we're at boot time in a single
6781:             * place.  NOTE:  There's no LCC at boot time.)
6782:             * NOTE: All <get> methods in the DD should call this method.
6783:             *
6784:             * @return TransactionController	The TC to use.
6785:             *
6786:             * @exception StandardException		Thrown on error
6787:             */
6788:            public TransactionController getTransactionCompile()
6789:                    throws StandardException {
6790:                if (bootingTC != null) {
6791:                    if (SanityManager.DEBUG) {
6792:                        SanityManager.ASSERT(booting,
6793:                                "booting is expected to be true");
6794:                    }
6795:                    return bootingTC;
6796:                } else {
6797:                    if (SanityManager.DEBUG) {
6798:                        SanityManager.ASSERT(!booting,
6799:                                "booting is expected to be false");
6800:                    }
6801:                    {
6802:                        LanguageConnectionContext lcc = getLCC();
6803:                        return lcc.getTransactionCompile();
6804:                    }
6805:                }
6806:            }
6807:
6808:            /**
6809:             * Get the TransactionController to use, when not
6810:             * passed in as a parameter.  (This hides logic about
6811:             * whether or not we're at boot time in a single
6812:             * place.  NOTE:  There's no LCC at boot time.)
6813:             * NOTE: All <get> methods in the DD should call this method.
6814:             *
6815:             * @return TransactionController	The TC to use.
6816:             *
6817:             * @exception StandardException		Thrown on error
6818:             */
6819:            public TransactionController getTransactionExecute()
6820:                    throws StandardException {
6821:                if (bootingTC != null) {
6822:                    if (SanityManager.DEBUG) {
6823:                        SanityManager.ASSERT(booting,
6824:                                "booting is expected to be true");
6825:                    }
6826:                    return bootingTC;
6827:                } else {
6828:                    if (SanityManager.DEBUG) {
6829:                        SanityManager.ASSERT(!booting,
6830:                                "booting is expected to be false");
6831:                    }
6832:                    {
6833:                        LanguageConnectionContext lcc = getLCC();
6834:                        return lcc.getTransactionExecute();
6835:                    }
6836:                }
6837:            }
6838:
6839:            /**
6840:             * Return a (single or list of) catalog row descriptor(s) from a
6841:             * system table where the access is from the index to the heap.
6842:             *
6843:             * @param indexId	The id of the index (0 to # of indexes on table) to use
6844:             * @param keyRow	The supplied ExecIndexRow for search
6845:             * @param ti		The TabInfoImpl to use
6846:             * @param parentTupleDescriptor		The parentDescriptor, if applicable.
6847:             * @param list		The list to build, if supplied.  If null, then caller expects
6848:             *					a single descriptor
6849:             * @param forUpdate	Whether or not to open the index for update.
6850:             *
6851:             * @return	The last matching descriptor
6852:             *
6853:             * @exception StandardException		Thrown on error
6854:             */
6855:            private final TupleDescriptor getDescriptorViaIndex(int indexId,
6856:                    ExecIndexRow keyRow, ScanQualifier[][] scanQualifiers,
6857:                    TabInfoImpl ti, TupleDescriptor parentTupleDescriptor,
6858:                    List list, boolean forUpdate) throws StandardException {
6859:                CatalogRowFactory rf = ti.getCatalogRowFactory();
6860:                ConglomerateController heapCC;
6861:                ExecIndexRow indexRow1;
6862:                ExecIndexRow indexTemplateRow;
6863:                ExecRow outRow;
6864:                RowLocation baseRowLocation;
6865:                ScanController scanController;
6866:                TransactionController tc;
6867:                TupleDescriptor td = null;
6868:
6869:                // Get the current transaction controller
6870:                tc = getTransactionCompile();
6871:
6872:                outRow = rf.makeEmptyRow();
6873:
6874:                heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false,
6875:                        0, TransactionController.MODE_RECORD,
6876:                        TransactionController.ISOLATION_REPEATABLE_READ);
6877:
6878:                /* Scan the index and go to the data pages for qualifying rows to
6879:                 * build the column descriptor.
6880:                 */
6881:                scanController = tc.openScan(
6882:                        ti.getIndexConglomerate(indexId), // conglomerate to open
6883:                        false, // don't hold open across commit
6884:                        (forUpdate) ? TransactionController.OPENMODE_FORUPDATE
6885:                                : 0, TransactionController.MODE_RECORD,
6886:                        TransactionController.ISOLATION_REPEATABLE_READ,
6887:                        (FormatableBitSet) null, // all fields as objects
6888:                        keyRow.getRowArray(), // start position - first row
6889:                        ScanController.GE, // startSearchOperation
6890:                        scanQualifiers, //scanQualifier,
6891:                        keyRow.getRowArray(), // stop position - through last row
6892:                        ScanController.GT); // stopSearchOperation
6893:
6894:                while (scanController.next()) {
6895:                    // create an index row template
6896:                    indexRow1 = getIndexRowFromHeapRow(ti
6897:                            .getIndexRowGenerator(indexId), heapCC
6898:                            .newRowLocationTemplate(), outRow);
6899:
6900:                    scanController.fetch(indexRow1.getRowArray());
6901:
6902:                    baseRowLocation = (RowLocation) indexRow1
6903:                            .getColumn(indexRow1.nColumns());
6904:
6905:                    // RESOLVE paulat - remove the try catch block when track 3677 is fixed
6906:                    // just leave the contents of the try block
6907:                    // adding to get more info on track 3677
6908:
6909:                    boolean base_row_exists = false;
6910:                    try {
6911:                        base_row_exists = heapCC.fetch(baseRowLocation, outRow
6912:                                .getRowArray(), (FormatableBitSet) null);
6913:                    } catch (RuntimeException re) {
6914:                        if (SanityManager.DEBUG) {
6915:                            if (re instanceof  AssertFailure) {
6916:                                StringBuffer strbuf = new StringBuffer(
6917:                                        "Error retrieving base row in table "
6918:                                                + ti.getTableName());
6919:                                strbuf
6920:                                        .append(": An ASSERT was thrown when trying to locate a row matching index row "
6921:                                                + indexRow1
6922:                                                + " from index "
6923:                                                + ti.getIndexName(indexId)
6924:                                                + ", conglom number "
6925:                                                + ti
6926:                                                        .getIndexConglomerate(indexId));
6927:                                debugGenerateInfo(strbuf, tc, heapCC, ti,
6928:                                        indexId);
6929:                            }
6930:                        }
6931:                        throw re;
6932:                    } catch (StandardException se) {
6933:                        if (SanityManager.DEBUG) {
6934:                            // only look for a specific error i.e. that of record on page
6935:                            // no longer exists
6936:                            // do not want to catch lock timeout errors here
6937:                            if (se.getSQLState().equals("XSRS9")) {
6938:                                StringBuffer strbuf = new StringBuffer(
6939:                                        "Error retrieving base row in table "
6940:                                                + ti.getTableName());
6941:                                strbuf
6942:                                        .append(": A StandardException was thrown when trying to locate a row matching index row "
6943:                                                + indexRow1
6944:                                                + " from index "
6945:                                                + ti.getIndexName(indexId)
6946:                                                + ", conglom number "
6947:                                                + ti
6948:                                                        .getIndexConglomerate(indexId));
6949:                                debugGenerateInfo(strbuf, tc, heapCC, ti,
6950:                                        indexId);
6951:                            }
6952:                        }
6953:                        throw se;
6954:                    }
6955:
6956:                    if (SanityManager.DEBUG) {
6957:                        // it can not be possible for heap row to disappear while
6958:                        // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
6959:                        if (!base_row_exists) {
6960:                            StringBuffer strbuf = new StringBuffer(
6961:                                    "Error retrieving base row in table "
6962:                                            + ti.getTableName());
6963:                            strbuf
6964:                                    .append(": could not locate a row matching index row "
6965:                                            + indexRow1
6966:                                            + " from index "
6967:                                            + ti.getIndexName(indexId)
6968:                                            + ", conglom number "
6969:                                            + ti.getIndexConglomerate(indexId));
6970:                            debugGenerateInfo(strbuf, tc, heapCC, ti, indexId);
6971:                            // RESOLVE: for now, we are going to kill the VM
6972:                            // to help debug this problem.
6973:                            System.exit(1);
6974:
6975:                            // RESOLVE: not currently reached
6976:                            //SanityManager.THROWASSERT(strbuf.toString());
6977:                        }
6978:                    }
6979:
6980:                    td = rf
6981:                            .buildDescriptor(outRow, parentTupleDescriptor,
6982:                                    this );
6983:
6984:                    /* If list is null, then caller only wants a single descriptor - we're done
6985:                     * else just add the current descriptor to the list.
6986:                     */
6987:                    if (list == null) {
6988:                        break;
6989:                    } else {
6990:                        list.add(td);
6991:                    }
6992:                }
6993:                scanController.close();
6994:                heapCC.close();
6995:                return td;
6996:            }
6997:
6998:            private void debugGenerateInfo(StringBuffer strbuf,
6999:                    TransactionController tc, ConglomerateController heapCC,
7000:                    TabInfoImpl ti, int indexId) {
7001:                if (SanityManager.DEBUG) {
7002:                    try {
7003:                        strbuf.append("\nadditional information: ");
7004:
7005:                        // print the lock table
7006:                        // will get a NullPointerException if lcc doesn't yet exist e.g. at boot time
7007:                        LanguageConnectionContext lcc = (LanguageConnectionContext) ContextService
7008:                                .getContext(LanguageConnectionContext.CONTEXT_ID);
7009:                        if (lcc != null) {
7010:                            long currentTime = System.currentTimeMillis();
7011:                            //EXCLUDE-START-lockdiag-
7012:                            Enumeration lockTable = lockFactory
7013:                                    .makeVirtualLockTable();
7014:                            String lockTableString = Timeout.buildString(
7015:                                    lockTable, currentTime);
7016:                            strbuf.append("lock table at time of failure\n\n");
7017:                            strbuf.append(lockTableString);
7018:                            //EXCLUDE-END-lockdiag-
7019:                        }
7020:
7021:                        // consistency checking etc.
7022:                        ConglomerateController btreeCC = tc
7023:                                .openConglomerate(
7024:                                        ti.getIndexConglomerate(indexId),
7025:                                        false,
7026:                                        0,
7027:                                        TransactionController.MODE_RECORD,
7028:                                        TransactionController.ISOLATION_REPEATABLE_READ);
7029:
7030:                        btreeCC.debugConglomerate();
7031:                        heapCC.debugConglomerate();
7032:                        heapCC.checkConsistency();
7033:                        strbuf.append("\nheapCC.checkConsistency() = true");
7034:                        ConglomerateController indexCC = tc
7035:                                .openConglomerate(
7036:                                        ti.getIndexConglomerate(indexId),
7037:                                        false,
7038:                                        0,
7039:                                        TransactionController.MODE_TABLE,
7040:                                        TransactionController.ISOLATION_REPEATABLE_READ);
7041:                        indexCC.checkConsistency();
7042:                        strbuf.append("\nindexCC.checkConsistency() = true");
7043:
7044:                        System.err.println("ASSERT FAILURE: "
7045:                                + strbuf.toString());
7046:                        System.out.println("ASSERT FAILURE: "
7047:                                + strbuf.toString());
7048:                        SanityManager.DEBUG_PRINT("ASSERT FAILURE", strbuf
7049:                                .toString());
7050:                    } catch (StandardException se) {
7051:                        strbuf
7052:                                .append("\ngot the following error when doing extra consistency checks:\n"
7053:                                        + se.toString());
7054:                    }
7055:                }
7056:            }
7057:
7058:            /**
7059:             * Return a (single or list of) catalog row descriptor(s) from a
7060:             * system table where the access a heap scan
7061:             *
7062:             * @param scanQualifiers			qualifiers
7063:             * @param ti						The TabInfoImpl to use
7064:             * @param parentTupleDescriptor		The parentDescriptor, if applicable.
7065:             * @param list						The list to build, if supplied.  
7066:             *									If null, then caller expects a single descriptor
7067:             *
7068:             * @return	The last matching descriptor
7069:             *
7070:             * @exception StandardException		Thrown on error
7071:             */
7072:            protected TupleDescriptor getDescriptorViaHeap(
7073:                    ScanQualifier[][] scanQualifiers, TabInfoImpl ti,
7074:                    TupleDescriptor parentTupleDescriptor, List list)
7075:                    throws StandardException {
7076:                CatalogRowFactory rf = ti.getCatalogRowFactory();
7077:                ConglomerateController heapCC;
7078:                ExecRow outRow;
7079:                ScanController scanController;
7080:                TransactionController tc;
7081:                TupleDescriptor td = null;
7082:
7083:                // Get the current transaction controller
7084:                tc = getTransactionCompile();
7085:
7086:                outRow = rf.makeEmptyRow();
7087:
7088:                /*
7089:                 ** Table scan
7090:                 */
7091:                scanController = tc.openScan(
7092:                        ti.getHeapConglomerate(), // conglomerate to open
7093:                        false, // don't hold open across commit
7094:                        0, // for read
7095:                        TransactionController.MODE_TABLE,
7096:                        TransactionController.ISOLATION_REPEATABLE_READ,
7097:                        (FormatableBitSet) null, // all fields as objects
7098:                        (DataValueDescriptor[]) null, // start position - first row
7099:                        0, // startSearchOperation - none
7100:                        scanQualifiers, // scanQualifier,
7101:                        (DataValueDescriptor[]) null, // stop position - through last row
7102:                        0); // stopSearchOperation - none
7103:
7104:                while (scanController.fetchNext(outRow.getRowArray())) {
7105:                    td = rf
7106:                            .buildDescriptor(outRow, parentTupleDescriptor,
7107:                                    this );
7108:
7109:                    /* If dList is null, then caller only wants a single descriptor - we're done
7110:                     * else just add the current descriptor to the list.
7111:                     */
7112:                    if (list == null) {
7113:                        break;
7114:                    } else {
7115:                        list.add(td);
7116:                    }
7117:                }
7118:                scanController.close();
7119:                return td;
7120:            }
7121:
7122:            /**
7123:             * Get a TabInfoImpl for a non-core table.
7124:             * (We fault in information about non-core tables as needed.)
7125:             *
7126:             * @param catalogNumber	The index into noncoreTable[].
7127:             *
7128:             * @exception StandardException		Thrown on error
7129:             */
7130:            private TabInfoImpl getNonCoreTI(int catalogNumber)
7131:                    throws StandardException {
7132:                TabInfoImpl ti = getNonCoreTIByNumber(catalogNumber);
7133:
7134:                faultInTabInfo(ti);
7135:
7136:                return ti;
7137:            }
7138:
7139:            /** returns the tabinfo for a non core system catalog. Input is a
7140:             * catalogNumber (defined in DataDictionary). 
7141:             */
7142:            protected TabInfoImpl getNonCoreTIByNumber(int catalogNumber)
7143:                    throws StandardException {
7144:                int nonCoreNum = catalogNumber - NUM_CORE;
7145:
7146:                // Look up the TabInfoImpl in the array. This does not have to be
7147:                // synchronized, because getting a reference is atomic.
7148:
7149:                TabInfoImpl retval = noncoreInfo[nonCoreNum];
7150:
7151:                if (retval == null) {
7152:                    // If we did not find the TabInfoImpl, get the right one and
7153:                    // load it into the array. There is a small chance that
7154:                    // two threads will do this at the same time. The code will
7155:                    // work properly in that case, since storing a reference
7156:                    // is atomic (although we could get extra object instantiation
7157:                    // if two threads come through here at the same time.
7158:                    UUIDFactory luuidFactory = uuidFactory;
7159:
7160:                    switch (catalogNumber) {
7161:                    case SYSCONSTRAINTS_CATALOG_NUM:
7162:                        retval = new TabInfoImpl(new SYSCONSTRAINTSRowFactory(
7163:                                luuidFactory, exFactory, dvf, convertIdToLower));
7164:                        break;
7165:
7166:                    case SYSKEYS_CATALOG_NUM:
7167:                        retval = new TabInfoImpl(new SYSKEYSRowFactory(
7168:                                luuidFactory, exFactory, dvf, convertIdToLower));
7169:                        break;
7170:
7171:                    case SYSDEPENDS_CATALOG_NUM:
7172:                        retval = new TabInfoImpl(new SYSDEPENDSRowFactory(
7173:                                luuidFactory, exFactory, dvf, convertIdToLower));
7174:                        break;
7175:
7176:                    case SYSVIEWS_CATALOG_NUM:
7177:                        retval = new TabInfoImpl(new SYSVIEWSRowFactory(
7178:                                luuidFactory, exFactory, dvf, convertIdToLower));
7179:                        break;
7180:
7181:                    case SYSCHECKS_CATALOG_NUM:
7182:                        retval = new TabInfoImpl(new SYSCHECKSRowFactory(
7183:                                luuidFactory, exFactory, dvf, convertIdToLower));
7184:                        break;
7185:
7186:                    case SYSFOREIGNKEYS_CATALOG_NUM:
7187:                        retval = new TabInfoImpl(new SYSFOREIGNKEYSRowFactory(
7188:                                luuidFactory, exFactory, dvf, convertIdToLower));
7189:                        break;
7190:
7191:                    case SYSSTATEMENTS_CATALOG_NUM:
7192:                        retval = new TabInfoImpl(new SYSSTATEMENTSRowFactory(
7193:                                luuidFactory, exFactory, dvf, convertIdToLower));
7194:                        break;
7195:
7196:                    case SYSFILES_CATALOG_NUM:
7197:                        retval = new TabInfoImpl(new SYSFILESRowFactory(
7198:                                luuidFactory, exFactory, dvf, convertIdToLower));
7199:                        break;
7200:
7201:                    case SYSALIASES_CATALOG_NUM:
7202:                        retval = new TabInfoImpl(new SYSALIASESRowFactory(
7203:                                luuidFactory, exFactory, dvf, convertIdToLower));
7204:                        break;
7205:
7206:                    case SYSTRIGGERS_CATALOG_NUM:
7207:                        retval = new TabInfoImpl(new SYSTRIGGERSRowFactory(
7208:                                luuidFactory, exFactory, dvf, convertIdToLower));
7209:                        break;
7210:
7211:                    case SYSSTATISTICS_CATALOG_NUM:
7212:                        retval = new TabInfoImpl(new SYSSTATISTICSRowFactory(
7213:                                luuidFactory, exFactory, dvf, convertIdToLower));
7214:                        break;
7215:
7216:                    case SYSDUMMY1_CATALOG_NUM:
7217:                        retval = new TabInfoImpl(new SYSDUMMY1RowFactory(
7218:                                luuidFactory, exFactory, dvf, convertIdToLower));
7219:                        break;
7220:
7221:                    case SYSTABLEPERMS_CATALOG_NUM:
7222:                        retval = new TabInfoImpl(new SYSTABLEPERMSRowFactory(
7223:                                luuidFactory, exFactory, dvf, convertIdToLower));
7224:                        break;
7225:
7226:                    case SYSCOLPERMS_CATALOG_NUM:
7227:                        retval = new TabInfoImpl(new SYSCOLPERMSRowFactory(
7228:                                luuidFactory, exFactory, dvf, convertIdToLower));
7229:                        break;
7230:
7231:                    case SYSROUTINEPERMS_CATALOG_NUM:
7232:                        retval = new TabInfoImpl(new SYSROUTINEPERMSRowFactory(
7233:                                luuidFactory, exFactory, dvf, convertIdToLower));
7234:                        break;
7235:                    }
7236:
7237:                    initSystemIndexVariables(retval);
7238:
7239:                    noncoreInfo[nonCoreNum] = retval;
7240:                }
7241:
7242:                return retval;
7243:            }
7244:
7245:            protected void initSystemIndexVariables(TabInfoImpl ti)
7246:                    throws StandardException {
7247:                int numIndexes = ti.getNumberOfIndexes();
7248:
7249:                if (numIndexes > 0) {
7250:                    DataDescriptorGenerator ddg = getDataDescriptorGenerator();
7251:
7252:                    for (int indexCtr = 0; indexCtr < numIndexes; indexCtr++) {
7253:                        initSystemIndexVariables(ddg, ti, indexCtr);
7254:                    }
7255:                }
7256:            }
7257:
7258:            // Expected to be called only during boot time, so no synchronization.
7259:            private void clearNoncoreTable(int nonCoreNum) {
7260:                noncoreInfo[nonCoreNum] = null;
7261:            }
7262:
7263:            /**
7264:             *	Finishes building a TabInfoImpl if it hasn't already been faulted in.
7265:             *	NOP if TabInfoImpl has already been faulted in.
7266:             *
7267:             *	@param	ti	TabInfoImpl to fault in.
7268:             *
7269:             * @exception StandardException		Thrown on error
7270:             */
7271:            public void faultInTabInfo(TabInfoImpl ti) throws StandardException {
7272:                int numIndexes;
7273:
7274:                /* Most of the time, the noncoreInfo will be complete.
7275:                 * It's okay to do an unsynchronized check and return
7276:                 * if it is complete, since it never becomes "un-complete".
7277:                 * If we change the code, for some reason, to allow
7278:                 * it to become "un-complete" after being complete,
7279:                 * then we will have to do a synchronized check here
7280:                 * as well.
7281:                 */
7282:                if (ti.isComplete()) {
7283:                    return;
7284:                }
7285:
7286:                /* The completing of the noncoreInfo entry must be synchronized. 
7287:                 * NOTE: We are assuming that we will not access a different
7288:                 * noncoreInfo in the course of completing of this noncoreInfo,
7289:                 * otherwise a deadlock could occur.
7290:                 */
7291:                synchronized (ti) {
7292:                    /* Now that we can run, the 1st thing that we must do
7293:                     * is to verify that we still need to complete the
7294:                     * object.  (We may have been blocked on another user
7295:                     * doing the same.)
7296:                     */
7297:                    if (ti.isComplete()) {
7298:                        return;
7299:                    }
7300:
7301:                    TableDescriptor td = getTableDescriptor(ti.getTableName(),
7302:                            getSystemSchemaDescriptor());
7303:
7304:                    // It's possible that the system table is not there right
7305:                    // now. This can happen, for example, if we're in the
7306:                    // process of upgrading a source or target to Xena, in 
7307:                    // which case SYSSYNCINSTANTS is dropped and re-created.
7308:                    // Just return in this case, so we don't get a null pointer
7309:                    // exception.
7310:                    if (td == null) {
7311:                        return;
7312:                    }
7313:
7314:                    ConglomerateDescriptor cd = null;
7315:                    ConglomerateDescriptor[] cds = td
7316:                            .getConglomerateDescriptors();
7317:
7318:                    /* Init the heap conglomerate here */
7319:                    for (int index = 0; index < cds.length; index++) {
7320:                        cd = cds[index];
7321:
7322:                        if (!cd.isIndex()) {
7323:                            ti.setHeapConglomerate(cd.getConglomerateNumber());
7324:                            break;
7325:                        }
7326:                    }
7327:
7328:                    if (SanityManager.DEBUG) {
7329:                        if (cd == null) {
7330:                            SanityManager
7331:                                    .THROWASSERT("No heap conglomerate found for "
7332:                                            + ti.getTableName());
7333:                        }
7334:                    }
7335:
7336:                    /* Initialize the index conglomerates */
7337:                    numIndexes = ti.getCatalogRowFactory().getNumIndexes();
7338:                    if (numIndexes == 0) {
7339:                        return;
7340:                    }
7341:
7342:                    /* For each index, we get its id from the CDL */
7343:                    ConglomerateDescriptor icd = null;
7344:                    int indexCount = 0;
7345:
7346:                    for (int index = 0; index < cds.length; index++) {
7347:                        icd = cds[index];
7348:
7349:                        if (icd.isIndex()) {
7350:                            ti.setIndexConglomerate(icd);
7351:                            indexCount++;
7352:                        }
7353:                        continue;
7354:                    }
7355:
7356:                    if (SanityManager.DEBUG) {
7357:                        if (indexCount != ti.getCatalogRowFactory()
7358:                                .getNumIndexes()) {
7359:                            SanityManager
7360:                                    .THROWASSERT("Number of indexes found ("
7361:                                            + indexCount
7362:                                            + ") does not match the number expected ("
7363:                                            + ti.getCatalogRowFactory()
7364:                                                    .getNumIndexes() + ")");
7365:                        }
7366:                    }
7367:                }
7368:            }
7369:
7370:            /**
7371:             * Get an index row based on a row from the heap.
7372:             *
7373:             * @param irg		IndexRowGenerator to use
7374:             * @param rl		RowLocation for heap
7375:             * @param heapRow	Row from the heap
7376:             *
7377:             * @return ExecIndexRow	Index row.
7378:             *
7379:             * @exception StandardException		Thrown on error
7380:             */
7381:            public static ExecIndexRow getIndexRowFromHeapRow(
7382:                    IndexRowGenerator irg, RowLocation rl, ExecRow heapRow)
7383:                    throws StandardException {
7384:                ExecIndexRow indexRow;
7385:
7386:                indexRow = irg.getIndexRowTemplate();
7387:                // Get an index row based on the base row
7388:                irg.getIndexRow(heapRow, rl, indexRow, (FormatableBitSet) null);
7389:
7390:                return indexRow;
7391:            }
7392:
7393:            public int getEngineType() {
7394:                return engineType;
7395:            }
7396:
7397:            /**
7398:             * Get the heap conglomerate number for SYS.SYSCOLUMNS.
7399:             * (Useful for adding new index to the table.)
7400:             *
7401:             * @return The heap conglomerate number for SYS.SYSCOLUMNS.
7402:             */
7403:            public long getSYSCOLUMNSHeapConglomerateNumber() {
7404:                return coreInfo[SYSCOLUMNS_CORE_NUM].getHeapConglomerate();
7405:            }
7406:
7407:            void addSYSCOLUMNSIndex2Property(TransactionController tc,
7408:                    long index2ConglomerateNumber) {
7409:                startupParameters.put(CFG_SYSCOLUMNS_INDEX2_ID, Long
7410:                        .toString(index2ConglomerateNumber));
7411:            }
7412:
7413:            /**
7414:             */
7415:            private long getBootParameter(Properties startParams, String key,
7416:                    boolean required) throws StandardException {
7417:
7418:                String value = startParams.getProperty(key);
7419:                if (value == null) {
7420:                    if (!required) {
7421:                        return -1;
7422:                    }
7423:                    throw StandardException.newException(
7424:                            SQLState.PROPERTY_MISSING, key);
7425:                }
7426:
7427:                try {
7428:                    return Long.parseLong(value);
7429:                } catch (NumberFormatException nfe) {
7430:                    throw StandardException.newException(
7431:                            SQLState.PROPERTY_INVALID_VALUE, key, value);
7432:                }
7433:            }
7434:
7435:            /**
7436:             *	Returns a unique system generated name of the form SQLyymmddhhmmssxxn
7437:             *	  yy - year, mm - month, dd - day of month, hh - hour, mm - minute, ss - second,
7438:             *	  xx - the first 2 digits of millisec because we don't have enough space to keep the exact millisec value,
7439:             *	  n - number between 0-9
7440:             *
7441:             *	  The number at the end is to handle more than one system generated name request came at the same time.
7442:             *	  In that case, the timestamp will remain the same, we will just increment n at the end of the name.
7443:             *
7444:             *	  Following is how we get around the problem of more than 10 system generated name requestes at the same time:
7445:             *	  When the database boots up, we start a counter with value -1 for the last digit in the generated name.
7446:             *	  We also keep the time in millisec to keep track of when the last system name was generated. At the
7447:             *	  boot time, it will be default to 0L. In addition, we have a calendar object for the time in millisec
7448:             *	  That calendar object is used to fetch yy, mm, dd, etc for the string SQLyymmddhhmmssxxn
7449:             *
7450:             *	  When the first request for the system generated name comes, time of last system generated name will be less than
7451:             *	  the current time. We initialize the counter to 0, set the time of last system generated name to the
7452:             *	  current time truncated off to lower 10ms time. The first name request is the only time we know for sure the
7453:             *	  time of last system generated name will be less than the current time. After this first request, the next request
7454:             *	  could be at any time. We go through the following algorithm for every generated name request.
7455:             *
7456:             *	  First check if the current time(truncated off to lower 10ms) is greater than the timestamp for last system generated name
7457:             *
7458:             *	    If yes, then we change the timestamp for system generated name to the current timestamp and reset the counter to 0
7459:             *	    and generate the name using the current timestamp and 0 as the number at the end of the generated name.
7460:             *
7461:             *	    If no, then it means this request for generated name has come at the same time as last one.
7462:             *	    Or it may come at a time less than the last generated name request. This could be because of seasonal time change
7463:             *	    or somebody manually changing the time on the computer. In any case,
7464:             *	    if the counter is less than 10(meaning this is not yet our 11th request for generated name at a given time),
7465:             *	    we use that in the generated name. But if the counter has reached 10(which means, this is the 11th name request
7466:             *	    at the same time), then we increment the system generated name timestamp by 10ms and reset the counter to 0
7467:             *	    (notice, at this point, the timestamp for system generated names is not in sync with the real current time, but we
7468:             *	    need to have this mechanism to get around the problem of more than 10 generated name requests at a same physical time).
7469:             *
7470:             *	@return	system generated unique name
7471:             */
7472:            public String getSystemSQLName() {
7473:                //note that we are using Date class to change the Calendar object time rather than Calendar.setTimeInMills.
7474:                //This is because of java bug 4243802. setTimeInMillis and getTimeInMillis were protected prior to jdk14
7475:                //But since we still support jdk13, we can't rely on these methods being public starting jdk14.
7476:                //Because of that, we are using Date to do all the time manipulations on the Calendar object 
7477:                StringBuffer generatedSystemSQLName = new StringBuffer("SQL");
7478:                synchronized (this ) {
7479:                    //get the current timestamp
7480:                    long timeNow = (System.currentTimeMillis() / 10L) * 10L;
7481:
7482:                    //if the current timestamp is greater than last constraint name generation time, then we reset the counter and
7483:                    //record the new timestamp
7484:                    if (timeNow > timeForLastSystemSQLName) {
7485:                        systemSQLNameNumber = 0;
7486:                        calendarForLastSystemSQLName.setTime(new Date(timeNow));
7487:                        timeForLastSystemSQLName = timeNow;
7488:                    } else {
7489:                        //the request has come at the same time as the last generated name request
7490:                        //or it has come at a time less than the time the last generated name request. This can happen
7491:                        //because of seasonal time change or manual update of computer time.
7492:
7493:                        //get the number that was last used for the last digit of generated name and increment it by 1.
7494:                        systemSQLNameNumber++;
7495:                        if (systemSQLNameNumber == 10) { //we have already generated 10 names at the last system generated timestamp value
7496:                            //so reset the counter
7497:                            systemSQLNameNumber = 0;
7498:                            timeForLastSystemSQLName = timeForLastSystemSQLName + 10L;
7499:                            //increment the timestamp for system generated names by 10ms
7500:                            calendarForLastSystemSQLName.setTime(new Date(
7501:                                    timeForLastSystemSQLName));
7502:                        }
7503:                    }
7504:
7505:                    generatedSystemSQLName
7506:                            .append(twoDigits(calendarForLastSystemSQLName
7507:                                    .get(Calendar.YEAR)));
7508:                    //have to add 1 to the month value returned because the method give 0-January, 1-February and so on and so forth
7509:                    generatedSystemSQLName
7510:                            .append(twoDigits(calendarForLastSystemSQLName
7511:                                    .get(Calendar.MONTH) + 1));
7512:                    generatedSystemSQLName
7513:                            .append(twoDigits(calendarForLastSystemSQLName
7514:                                    .get(Calendar.DAY_OF_MONTH)));
7515:                    generatedSystemSQLName
7516:                            .append(twoDigits(calendarForLastSystemSQLName
7517:                                    .get(Calendar.HOUR)));
7518:                    generatedSystemSQLName
7519:                            .append(twoDigits(calendarForLastSystemSQLName
7520:                                    .get(Calendar.MINUTE)));
7521:                    generatedSystemSQLName
7522:                            .append(twoDigits(calendarForLastSystemSQLName
7523:                                    .get(Calendar.SECOND)));
7524:                    //because we don't have enough space to store the entire millisec value, just store the higher 2 digits.
7525:                    generatedSystemSQLName
7526:                            .append(twoDigits((int) (calendarForLastSystemSQLName
7527:                                    .get(Calendar.MILLISECOND) / 10)));
7528:                    generatedSystemSQLName.append(systemSQLNameNumber);
7529:                }
7530:                return generatedSystemSQLName.toString();
7531:            }
7532:
7533:            private static String twoDigits(int val) {
7534:                String retval;
7535:
7536:                if (val < 10) {
7537:                    retval = "0" + val;
7538:                } else {
7539:                    int retvalLength = Integer.toString(val).length();
7540:                    retval = Integer.toString(val).substring(retvalLength - 2);
7541:                }
7542:
7543:                return retval;
7544:            }
7545:
7546:            /**
7547:             * sets a new value in SYSCOLUMNS for a particular
7548:             * autoincrement column.
7549:             * 
7550:             * @param tc		 Transaction Controller to use.
7551:             * @param columnName Name of the column.
7552:             * @param aiValue	 Value to write to SYSCOLUMNS.
7553:             * @param incrementNeeded whether to increment the value passed in by the
7554:             * user (aiValue) or not before writing it to SYSCOLUMNS.
7555:             */
7556:            public void setAutoincrementValue(TransactionController tc,
7557:                    UUID tableUUID, String columnName, long aiValue,
7558:                    boolean incrementNeeded) throws StandardException {
7559:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
7560:                ExecIndexRow keyRow = null;
7561:
7562:                keyRow = (ExecIndexRow) exFactory.getIndexableRow(2);
7563:                keyRow.setColumn(1, dvf.getCharDataValue(tableUUID.toString()));
7564:                keyRow.setColumn(2, dvf.getCharDataValue(columnName));
7565:
7566:                SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti
7567:                        .getCatalogRowFactory();
7568:                ExecRow row = rf.makeEmptyRow();
7569:
7570:                boolean[] bArray = new boolean[2];
7571:                for (int index = 0; index < 2; index++) {
7572:                    bArray[index] = false;
7573:                }
7574:
7575:                int[] colsToUpdate = new int[1];
7576:
7577:                colsToUpdate[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
7578:
7579:                if (incrementNeeded) {
7580:                    ExecRow readRow = ti.getRow(tc, keyRow,
7581:                            SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID);
7582:                    NumberDataValue increment = (NumberDataValue) readRow
7583:                            .getColumn(SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTINC);
7584:                    aiValue += increment.getLong();
7585:                }
7586:                row.setColumn(
7587:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE, dvf
7588:                                .getDataValue(aiValue));
7589:
7590:                ti.updateRow(keyRow, row,
7591:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID, bArray,
7592:                        colsToUpdate, tc);
7593:                return;
7594:            }
7595:
7596:            /**
7597:             * Computes the RowLocation in SYSCOLUMNS for a particular 
7598:             * autoincrement column.
7599:             * 
7600:             * @param tc			Transaction Controller to use.
7601:             * @param td			Table Descriptor.
7602:             * @param columnName	Name of column which has autoincrement column.
7603:             * 
7604:             * @exception StandardException thrown on failure.
7605:             */
7606:            private RowLocation computeRowLocation(TransactionController tc,
7607:                    TableDescriptor td, String columnName)
7608:                    throws StandardException {
7609:                TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
7610:                ExecIndexRow keyRow = null;
7611:                ExecRow row;
7612:                UUID tableUUID = td.getUUID();
7613:
7614:                keyRow = (ExecIndexRow) exFactory.getIndexableRow(2);
7615:                keyRow.setColumn(1, dvf.getCharDataValue(tableUUID.toString()));
7616:                keyRow.setColumn(2, dvf.getCharDataValue(columnName));
7617:                return ti.getRowLocation(tc, keyRow,
7618:                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID);
7619:            }
7620:
7621:            public RowLocation getRowLocationTemplate(
7622:                    LanguageConnectionContext lcc, TableDescriptor td)
7623:                    throws StandardException {
7624:                RowLocation rl;
7625:                ConglomerateController heapCC = null;
7626:
7627:                TransactionController tc = lcc.getTransactionCompile();
7628:
7629:                long tableId = td.getHeapConglomerateId();
7630:                heapCC = tc.openConglomerate(tableId, false, 0, tc.MODE_RECORD,
7631:                        tc.ISOLATION_READ_COMMITTED);
7632:                try {
7633:                    rl = heapCC.newRowLocationTemplate();
7634:                } finally {
7635:                    heapCC.close();
7636:                }
7637:
7638:                return rl;
7639:            }
7640:
7641:            /**
7642:             * 
7643:             * Add a table descriptor to the "other" cache. The other cache is
7644:             * determined by the type of the object c.
7645:             *
7646:             * @param td	TableDescriptor to add to the other cache.
7647:             * @param c		Cacheable Object which lets us figure out the other cache.
7648:             *
7649:             * @exception	StandardException
7650:             */
7651:            public void addTableDescriptorToOtherCache(TableDescriptor td,
7652:                    Cacheable c) throws StandardException {
7653:                // get the other cache. if the entry we are setting in the cache is of
7654:                // type oidtdcacheable then use the nametdcache 
7655:                CacheManager otherCache = (c instanceof  OIDTDCacheable) ? nameTdCache
7656:                        : OIDTdCache;
7657:                Object key;
7658:                TDCacheable otherCacheEntry = null;
7659:
7660:                if (otherCache == nameTdCache)
7661:                    key = new TableKey(td.getSchemaDescriptor().getUUID(), td
7662:                            .getName());
7663:                else
7664:                    key = td.getUUID();
7665:
7666:                try {
7667:                    // insert the entry into the the other cache.
7668:                    otherCacheEntry = (TDCacheable) otherCache.create(key, td);
7669:                } catch (StandardException se) {
7670:                    // if the object already exists in cache then somebody beat us to it
7671:                    // otherwise throw the error.
7672:                    if (!(se.getMessageId()
7673:                            .equals(SQLState.OBJECT_EXISTS_IN_CACHE)))
7674:                        throw se;
7675:                } finally {
7676:                    if (otherCacheEntry != null)
7677:                        otherCache.release(otherCacheEntry);
7678:                }
7679:            }
7680:
7681:            /** @see DataDictionary#dropStatisticsDescriptors */
7682:            public void dropStatisticsDescriptors(UUID tableUUID,
7683:                    UUID referenceUUID, TransactionController tc)
7684:                    throws StandardException {
7685:                TabInfoImpl ti = getNonCoreTI(SYSSTATISTICS_CATALOG_NUM);
7686:                DataValueDescriptor first, second;
7687:                first = dvf.getCharDataValue(tableUUID.toString());
7688:
7689:                ExecIndexRow keyRow;
7690:                if (referenceUUID != null) {
7691:                    keyRow = exFactory.getIndexableRow(2);
7692:                    second = dvf.getCharDataValue(referenceUUID.toString());
7693:                    keyRow.setColumn(2, second);
7694:                } else {
7695:                    keyRow = exFactory.getIndexableRow(1);
7696:                }
7697:
7698:                keyRow.setColumn(1, first);
7699:
7700:                ti.deleteRow(tc, keyRow,
7701:                        SYSSTATISTICSRowFactory.SYSSTATISTICS_INDEX1_ID);
7702:
7703:            }
7704:
7705:            private static LanguageConnectionContext getLCC() {
7706:                return (LanguageConnectionContext) ContextService
7707:                        .getContextOrNull(LanguageConnectionContext.CONTEXT_ID);
7708:            }
7709:
7710:            private SchemaDescriptor newSystemSchemaDesc(String name,
7711:                    String uuid) {
7712:                return new SchemaDescriptor(this , name,
7713:                        authorizationDatabaseOwner, uuidFactory
7714:                                .recreateUUID(uuid), true);
7715:            }
7716:
7717:            private SchemaDescriptor newDeclaredGlobalTemporaryTablesSchemaDesc(
7718:                    String name) {
7719:                return new SchemaDescriptor(this , name,
7720:                        authorizationDatabaseOwner, (UUID) null, false);
7721:            }
7722:
7723:            /**
7724:            	Check to see if a database has been upgraded to the required
7725:            	level in order to use a language feature. 
7726:
7727:            	@param requiredMajorVersion Data Dictionary major version
7728:            	@param feature Non-null to throw an error, null to return the state of the version match.
7729:
7730:            	@return True if the database has been upgraded to the required level, false otherwise.
7731:             */
7732:            public boolean checkVersion(int requiredMajorVersion, String feature)
7733:                    throws StandardException {
7734:
7735:                if (requiredMajorVersion == DataDictionary.DD_VERSION_CURRENT) {
7736:                    requiredMajorVersion = softwareVersion.majorVersionNumber;
7737:                }
7738:
7739:                return dictionaryVersion.checkVersion(requiredMajorVersion,
7740:                        feature);
7741:            }
7742:
7743:            /**
7744:             ** Create system built-in metadata stored prepared statements.
7745:             */
7746:            void createSystemSps(TransactionController tc)
7747:                    throws StandardException {
7748:                // DatabaseMetadata stored plans
7749:                createSPSSet(tc, false, getSystemSchemaDescriptor().getUUID());
7750:
7751:                // network server stored plans
7752:                createSPSSet(tc, true, getSysIBMSchemaDescriptor().getUUID());
7753:            }
7754:
7755:            /**
7756:            	Create a set of stored prepared statements from a properties file.
7757:            	Key is the statement name, value is the SQL statement.
7758:             */
7759:            protected void createSPSSet(TransactionController tc, boolean net,
7760:                    UUID schemaID) throws StandardException {
7761:                Properties p = getQueryDescriptions(net);
7762:                Enumeration e = p.keys();
7763:                //statement will get compiled on first execution
7764:                //Note: Don't change this to FALSE LCC is not available for compiling
7765:                boolean nocompile = true;
7766:
7767:                while (e.hasMoreElements()) {
7768:                    String spsName = (String) e.nextElement();
7769:                    String spsText = p.getProperty(spsName);
7770:                    SPSDescriptor spsd = new SPSDescriptor(this , spsName,
7771:                            getUUIDFactory().createUUID(), schemaID, schemaID,
7772:                            SPSDescriptor.SPS_TYPE_REGULAR, !nocompile, // it is valid, unless nocompile
7773:                            spsText, //sps text
7774:                            !nocompile);
7775:
7776:                    addSPSDescriptor(spsd, tc, true);
7777:                }
7778:            }
7779:
7780:            /**
7781:             * Generic create procedure routine.
7782:             * <p>
7783:             * Takes the input procedure and inserts it into the appropriate
7784:             * catalog.  
7785:             *
7786:             * Assumes all arguments are "IN" type.
7787:             *
7788:             * @param routine_name  name of the routine in java and the SQL 
7789:             *                      procedure name.
7790:             *
7791:             * @param arg_names     String array of procedure argument names in order.
7792:             *
7793:             * @param arg_types     Internal SQL types of the arguments
7794:             *
7795:             * @param routine_sql_control     
7796:             *                      One of the RoutineAliasInfo constants:
7797:             *                          MODIFIES_SQL_DATA
7798:             *                          READS_SQL_DATA
7799:             *                          CONTAINS_SQL
7800:             *                          NO_SQL
7801:             *
7802:             * @param return_type   null for procedure.  For functions the return type
7803:             *                      of the function.
7804:             *
7805:             * @return UUID 		UUID of system routine that got created.
7806:             *
7807:             * @exception  StandardException  Standard exception policy.
7808:             **/
7809:            private final UUID createSystemProcedureOrFunction(
7810:                    String routine_name, UUID schema_uuid, String[] arg_names,
7811:                    TypeDescriptor[] arg_types, int num_out_param,
7812:                    int num_result_sets, short routine_sql_control,
7813:                    TypeDescriptor return_type, TransactionController tc)
7814:                    throws StandardException {
7815:                int num_args = 0;
7816:                if (arg_names != null)
7817:                    num_args = arg_names.length;
7818:
7819:                if (SanityManager.DEBUG) {
7820:                    if (num_args != 0) {
7821:                        SanityManager.ASSERT(arg_names != null);
7822:                        SanityManager.ASSERT(arg_types != null);
7823:                        SanityManager
7824:                                .ASSERT(arg_names.length == arg_types.length);
7825:                    }
7826:                }
7827:
7828:                // Actual procedures are in this class:
7829:                String procClass = "org.apache.derby.catalog.SystemProcedures";
7830:
7831:                // all args are only "in" arguments
7832:                int[] arg_modes = null;
7833:                if (num_args != 0) {
7834:                    arg_modes = new int[num_args];
7835:                    int num_in_param = num_args - num_out_param;
7836:                    for (int i = 0; i < num_in_param; i++)
7837:                        arg_modes[i] = JDBC30Translation.PARAMETER_MODE_IN;
7838:                    for (int i = 0; i < num_out_param; i++)
7839:                        arg_modes[num_in_param + i] = JDBC30Translation.PARAMETER_MODE_OUT;
7840:                }
7841:
7842:                RoutineAliasInfo routine_alias_info = new RoutineAliasInfo(
7843:                        routine_name, // name of routine
7844:                        num_args, // number of params
7845:                        arg_names, // names of params
7846:                        arg_types, // types of params
7847:                        arg_modes, // all "IN" params
7848:                        num_result_sets, // number of result sets
7849:                        RoutineAliasInfo.PS_JAVA, // link to java routine
7850:                        routine_sql_control, // one of:
7851:                        //  MODIFIES_SQL_DATA
7852:                        //  READS_SQL_DATA
7853:                        //  CONTAINS_SQL
7854:                        //  NO_SQL
7855:                        true, // true - calledOnNullInput
7856:                        return_type);
7857:
7858:                UUID routine_uuid = getUUIDFactory().createUUID();
7859:                AliasDescriptor ads = new AliasDescriptor(
7860:                        this ,
7861:                        routine_uuid,
7862:                        routine_name,
7863:                        schema_uuid,
7864:                        procClass,
7865:                        (return_type == null) ? AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR
7866:                                : AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR,
7867:                        (return_type == null) ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR
7868:                                : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR,
7869:                        false, routine_alias_info, null);
7870:
7871:                addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM,
7872:                        false, tc);
7873:
7874:                return routine_uuid;
7875:            }
7876:
7877:            /**
7878:             * Create system procedures
7879:             * <p>
7880:             * Used to add the system procedures to the database when
7881:             * it is created.  System procedures are currently added to
7882:             * either SYSCS_UTIL or SQLJ schemas.
7883:             * <p>
7884:             *
7885:             * @param tc     transaction controller to use.  Counts on caller to
7886:             *               commit.
7887:             *
7888:             * @exception  StandardException  Standard exception policy.
7889:             **/
7890:            private final void create_SYSCS_procedures(TransactionController tc)
7891:                    throws StandardException {
7892:                /*
7893:                 ** SYSCS_UTIL routines.
7894:                 */
7895:
7896:                UUID routine_uuid = null;
7897:                // used to put procedure into the SYSCS_UTIL schema
7898:                UUID sysUtilUUID = getSystemUtilSchemaDescriptor().getUUID();
7899:
7900:                // void SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(
7901:                //     varchar(128), varchar(Limits.DB2_VARCHAR_MAXWIDTH))
7902:                {
7903:
7904:                    // procedure argument names
7905:                    String[] arg_names = { "KEY", "VALUE" };
7906:
7907:                    // procedure argument types
7908:                    TypeDescriptor[] arg_types = {
7909:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
7910:                                    Types.VARCHAR, 128),
7911:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
7912:                                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH) };
7913:
7914:                    createSystemProcedureOrFunction(
7915:                            "SYSCS_SET_DATABASE_PROPERTY", sysUtilUUID,
7916:                            arg_names, arg_types, 0, 0,
7917:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
7918:                            (TypeDescriptor) null, tc);
7919:                }
7920:
7921:                // void SYSCS_UTIL.SYSCS_COMPRESS_TABLE(varchar(128), varchar(128), SMALLINT)
7922:                {
7923:                    // procedure argument names
7924:                    String[] arg_names = { "SCHEMANAME", "TABLENAME",
7925:                            "SEQUENTIAL" };
7926:
7927:                    // procedure argument types
7928:                    TypeDescriptor[] arg_types = {
7929:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
7930:                                    Types.VARCHAR, 128),
7931:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
7932:                                    Types.VARCHAR, 128),
7933:                            DataTypeDescriptor
7934:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT)
7935:
7936:                    };
7937:
7938:                    routine_uuid = createSystemProcedureOrFunction(
7939:                            "SYSCS_COMPRESS_TABLE", sysUtilUUID, arg_names,
7940:                            arg_types, 0, 0,
7941:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
7942:                            (TypeDescriptor) null, tc);
7943:
7944:                    createRoutinePermPublicDescriptor(routine_uuid, tc);
7945:                }
7946:
7947:                // void SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE()
7948:                {
7949:                    createSystemProcedureOrFunction(
7950:                            "SYSCS_CHECKPOINT_DATABASE", sysUtilUUID, null,
7951:                            null, 0, 0, RoutineAliasInfo.CONTAINS_SQL,
7952:                            (TypeDescriptor) null, tc);
7953:                }
7954:
7955:                // void SYSCS_UTIL.SYSCS_FREEZE_DATABASE()
7956:                {
7957:                    createSystemProcedureOrFunction("SYSCS_FREEZE_DATABASE",
7958:                            sysUtilUUID, null, null, 0, 0,
7959:                            RoutineAliasInfo.CONTAINS_SQL,
7960:                            (TypeDescriptor) null, tc);
7961:                }
7962:
7963:                // void SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE()
7964:                {
7965:                    createSystemProcedureOrFunction("SYSCS_UNFREEZE_DATABASE",
7966:                            sysUtilUUID, null, null, 0, 0,
7967:                            RoutineAliasInfo.CONTAINS_SQL,
7968:                            (TypeDescriptor) null, tc);
7969:                }
7970:
7971:                // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE(varchar Limits.DB2_VARCHAR_MAXWIDTH)
7972:                {
7973:                    // procedure argument names
7974:                    String[] arg_names = { "BACKUPDIR" };
7975:
7976:                    // procedure argument types
7977:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
7978:                            .getBuiltInDataTypeDescriptor(Types.VARCHAR,
7979:                                    Limits.DB2_VARCHAR_MAXWIDTH) };
7980:
7981:                    createSystemProcedureOrFunction("SYSCS_BACKUP_DATABASE",
7982:                            sysUtilUUID, arg_names, arg_types, 0, 0,
7983:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
7984:                            (TypeDescriptor) null, tc);
7985:                }
7986:
7987:                // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE(
7988:                //     varchar Limits.DB2_VARCHAR_MAXWIDTH, smallint)
7989:                {
7990:                    // procedure argument names
7991:                    String[] arg_names = { "BACKUPDIR",
7992:                            "DELETE_ARCHIVED_LOG_FILES" };
7993:
7994:                    // procedure argument types
7995:                    TypeDescriptor[] arg_types = {
7996:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
7997:                                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
7998:                            DataTypeDescriptor
7999:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8000:
8001:                    createSystemProcedureOrFunction(
8002:                            "SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE",
8003:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8004:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8005:                            (TypeDescriptor) null, tc);
8006:                }
8007:
8008:                // void SYSCS_UTIL.SYSCS_DISABLE_LOG_ARCHIVE_MODE(smallint)
8009:                {
8010:                    // procedure argument names
8011:                    String[] arg_names = { "DELETE_ARCHIVED_LOG_FILES" };
8012:
8013:                    // procedure argument types
8014:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
8015:                            .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8016:
8017:                    createSystemProcedureOrFunction(
8018:                            "SYSCS_DISABLE_LOG_ARCHIVE_MODE", sysUtilUUID,
8019:                            arg_names, arg_types, 0, 0,
8020:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8021:                            (TypeDescriptor) null, tc);
8022:                }
8023:
8024:                // void SYSCS_UTIL.SYSCS_SET_RUNTIMESTTISTICS(smallint)
8025:                {
8026:                    // procedure argument names
8027:                    String[] arg_names = { "ENABLE" };
8028:
8029:                    // procedure argument types
8030:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
8031:                            .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8032:
8033:                    routine_uuid = createSystemProcedureOrFunction(
8034:                            "SYSCS_SET_RUNTIMESTATISTICS", sysUtilUUID,
8035:                            arg_names, arg_types, 0, 0,
8036:                            RoutineAliasInfo.CONTAINS_SQL,
8037:                            (TypeDescriptor) null, tc);
8038:
8039:                    createRoutinePermPublicDescriptor(routine_uuid, tc);
8040:                }
8041:
8042:                // void SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(smallint)
8043:                {
8044:                    // procedure argument names
8045:                    String[] arg_names = { "ENABLE" };
8046:
8047:                    // procedure argument types
8048:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
8049:                            .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8050:
8051:                    routine_uuid = createSystemProcedureOrFunction(
8052:                            "SYSCS_SET_STATISTICS_TIMING", sysUtilUUID,
8053:                            arg_names, arg_types, 0, 0,
8054:                            RoutineAliasInfo.CONTAINS_SQL,
8055:                            (TypeDescriptor) null, tc);
8056:
8057:                    createRoutinePermPublicDescriptor(routine_uuid, tc);
8058:                }
8059:
8060:                // SYSCS_UTIL functions
8061:                //
8062:                // TODO (mikem) - 
8063:                // the following need to be functions when that is supported.
8064:                // until then calling them will not work.
8065:
8066:                // VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH) 
8067:                // SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(varchar(128))
8068:
8069:                {
8070:                    // procedure argument names
8071:                    String[] arg_names = { "KEY" };
8072:
8073:                    // procedure argument types
8074:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
8075:                            .getBuiltInDataTypeDescriptor(Types.VARCHAR, 128) };
8076:
8077:                    createSystemProcedureOrFunction(
8078:                            "SYSCS_GET_DATABASE_PROPERTY", sysUtilUUID,
8079:                            arg_names, arg_types, 0, 0,
8080:                            RoutineAliasInfo.READS_SQL_DATA, DataTypeDescriptor
8081:                                    .getBuiltInDataTypeDescriptor(
8082:                                            Types.VARCHAR,
8083:                                            Limits.DB2_VARCHAR_MAXWIDTH), tc);
8084:                }
8085:
8086:                // SMALLINT SYSCS_UTIL.SYSCS_CHECK_TABLE(varchar(128), varchar(128))
8087:                {
8088:                    // procedure argument names
8089:                    String[] arg_names = { "SCHEMANAME", "TABLENAME" };
8090:
8091:                    // procedure argument types
8092:                    TypeDescriptor[] arg_types = {
8093:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8094:                                    Types.VARCHAR, 128),
8095:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8096:                                    Types.VARCHAR, 128) };
8097:
8098:                    createSystemProcedureOrFunction(
8099:                            "SYSCS_CHECK_TABLE",
8100:                            sysUtilUUID,
8101:                            arg_names,
8102:                            arg_types,
8103:                            0,
8104:                            0,
8105:                            RoutineAliasInfo.READS_SQL_DATA,
8106:                            DataTypeDescriptor
8107:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8108:                            tc);
8109:                }
8110:
8111:                // CLOB SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS()
8112:                {
8113:
8114:                    routine_uuid = createSystemProcedureOrFunction(
8115:                            "SYSCS_GET_RUNTIMESTATISTICS",
8116:                            sysUtilUUID,
8117:                            null,
8118:                            null,
8119:                            0,
8120:                            0,
8121:                            RoutineAliasInfo.CONTAINS_SQL,
8122:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8123:                                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
8124:
8125:                            /*
8126:                            TODO - mikem, wants to be a CLOB, but don't know how to do 
8127:                            that yet.  Testing it with varchar for now.
8128:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8129:                                Types.CLOB, Limits.DB2_LOB_MAXWIDTH),
8130:                             */
8131:                            tc);
8132:
8133:                    createRoutinePermPublicDescriptor(routine_uuid, tc);
8134:                }
8135:
8136:                /*
8137:                 ** SQLJ routine.
8138:                 */
8139:
8140:                UUID sqlJUUID = getSchemaDescriptor(
8141:                        SchemaDescriptor.STD_SQLJ_SCHEMA_NAME, tc, true)
8142:                        .getUUID();
8143:
8144:                // SQLJ.INSTALL_JAR(URL VARCHAR(??), JAR VARCHAR(128), DEPLOY INT)
8145:                {
8146:                    String[] arg_names = { "URL", "JAR", "DEPLOY" };
8147:
8148:                    TypeDescriptor[] arg_types = {
8149:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8150:                                    Types.VARCHAR, 256),
8151:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8152:                                    Types.VARCHAR, 128),
8153:                            DataTypeDescriptor
8154:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER) };
8155:
8156:                    createSystemProcedureOrFunction("INSTALL_JAR", sqlJUUID,
8157:                            arg_names, arg_types, 0, 0,
8158:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8159:                            (TypeDescriptor) null, tc);
8160:                }
8161:
8162:                // SQLJ.REPLACE_JAR(URL VARCHAR(??), JAR VARCHAR(128))
8163:                {
8164:                    String[] arg_names = { "URL", "JAR" };
8165:
8166:                    TypeDescriptor[] arg_types = {
8167:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8168:                                    Types.VARCHAR, 256),
8169:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8170:                                    Types.VARCHAR, 128) };
8171:
8172:                    createSystemProcedureOrFunction("REPLACE_JAR", sqlJUUID,
8173:                            arg_names, arg_types, 0, 0,
8174:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8175:                            (TypeDescriptor) null, tc);
8176:                }
8177:
8178:                // SQLJ.REMOVE_JAR(JAR VARCHAR(128), UNDEPLOY INT)
8179:                {
8180:                    String[] arg_names = { "JAR", "UNDEPLOY" };
8181:
8182:                    TypeDescriptor[] arg_types = {
8183:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8184:                                    Types.VARCHAR, 128),
8185:                            DataTypeDescriptor
8186:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER) };
8187:
8188:                    createSystemProcedureOrFunction("REMOVE_JAR", sqlJUUID,
8189:                            arg_names, arg_types, 0, 0,
8190:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8191:                            (TypeDescriptor) null, tc);
8192:                }
8193:
8194:                /*  SYSCS_EXPORT_TABLE (IN SCHEMANAME  VARCHAR(128), 
8195:                 * IN TABLENAME    VARCHAR(128),  IN FILENAME VARCHAR(32672) , 
8196:                 * IN COLUMNDELIMITER CHAR(1),  IN CHARACTERDELIMITER CHAR(1) ,  
8197:                 * IN CODESET VARCHAR(128))
8198:                 */
8199:
8200:                {
8201:                    // procedure argument names
8202:                    String[] arg_names = { "schemaName", "tableName",
8203:                            "fileName", " columnDelimiter",
8204:                            "characterDelimiter", "codeset" };
8205:
8206:                    // procedure argument types
8207:                    TypeDescriptor[] arg_types = {
8208:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8209:                                    Types.VARCHAR, 128),
8210:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8211:                                    Types.VARCHAR, 128),
8212:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8213:                                    Types.VARCHAR, 32672),
8214:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8215:                                    Types.CHAR, 1),
8216:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8217:                                    Types.CHAR, 1),
8218:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8219:                                    Types.VARCHAR, 128) };
8220:
8221:                    createSystemProcedureOrFunction("SYSCS_EXPORT_TABLE",
8222:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8223:                            RoutineAliasInfo.READS_SQL_DATA,
8224:                            (TypeDescriptor) null, tc);
8225:                }
8226:
8227:                /* SYSCS_EXPORT_QUERY (IN SELECTSTATEMENT  VARCHAR(32672), 
8228:                 * IN FILENAME VARCHAR(32672) , 
8229:                 * IN COLUMNDELIMITER CHAR(1),  IN CHARACTERDELIMITER CHAR(1) ,  
8230:                 * IN CODESET VARCHAR(128))
8231:                 */
8232:                {
8233:                    // procedure argument names
8234:                    String[] arg_names = { "selectStatement", "fileName",
8235:                            " columnDelimiter", "characterDelimiter", "codeset" };
8236:
8237:                    // procedure argument types
8238:                    TypeDescriptor[] arg_types = {
8239:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8240:                                    Types.VARCHAR, 32672),
8241:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8242:                                    Types.VARCHAR, 32672),
8243:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8244:                                    Types.CHAR, 1),
8245:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8246:                                    Types.CHAR, 1),
8247:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8248:                                    Types.VARCHAR, 128) };
8249:
8250:                    createSystemProcedureOrFunction("SYSCS_EXPORT_QUERY",
8251:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8252:                            RoutineAliasInfo.READS_SQL_DATA,
8253:                            (TypeDescriptor) null, tc);
8254:                }
8255:
8256:                /*  SYSCS_IMPORT_TABLE(IN SCHEMANAME VARCHAR(128), 
8257:                 *  IN TABLENAME VARCHAR(128),  IN FILENAME VARCHAR(32762), 
8258:                 *  IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER  CHAR(1),  
8259:                 *  IN CODESET VARCHAR(128) , IN  REPLACE SMALLINT)
8260:                 */
8261:                {
8262:                    // procedure argument names
8263:                    String[] arg_names = { "schemaName", "tableName",
8264:                            "fileName", " columnDelimiter",
8265:                            "characterDelimiter", "codeset", "replace" };
8266:
8267:                    // procedure argument types
8268:
8269:                    // procedure argument types
8270:                    TypeDescriptor[] arg_types = {
8271:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8272:                                    Types.VARCHAR, 128),
8273:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8274:                                    Types.VARCHAR, 128),
8275:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8276:                                    Types.VARCHAR, 32672),
8277:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8278:                                    Types.CHAR, 1),
8279:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8280:                                    Types.CHAR, 1),
8281:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8282:                                    Types.VARCHAR, 128),
8283:                            DataTypeDescriptor
8284:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT), };
8285:
8286:                    createSystemProcedureOrFunction("SYSCS_IMPORT_TABLE",
8287:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8288:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8289:                            (TypeDescriptor) null, tc);
8290:                }
8291:
8292:                /*  SYSCS_IMPORT_DATA(IN SCHEMANAME VARCHAR(128), 
8293:                 *  IN TABLENAME VARCHAR(128), IN INSERTCOLUMNLIST VARCHAR(32762), 
8294:                 *  IN COLUMNINDEXES VARCHAR(32762), IN IN FILENAME VARCHAR(32762), 
8295:                 *  IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER  CHAR(1),  
8296:                 *  IN CODESET VARCHAR(128) , IN  REPLACE SMALLINT)
8297:                 */
8298:                {
8299:                    // procedure argument names
8300:                    String[] arg_names = { "schemaName", "tableName",
8301:                            "insertColumnList", "columnIndexes", "fileName",
8302:                            " columnDelimiter", "characterDelimiter",
8303:                            "codeset", "replace" };
8304:
8305:                    // procedure argument types
8306:
8307:                    // procedure argument types
8308:                    TypeDescriptor[] arg_types = {
8309:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8310:                                    Types.VARCHAR, 128),
8311:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8312:                                    Types.VARCHAR, 128),
8313:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8314:                                    Types.VARCHAR, 32672),
8315:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8316:                                    Types.VARCHAR, 32672),
8317:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8318:                                    Types.VARCHAR, 32672),
8319:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8320:                                    Types.CHAR, 1),
8321:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8322:                                    Types.CHAR, 1),
8323:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8324:                                    Types.VARCHAR, 128),
8325:                            DataTypeDescriptor
8326:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT), };
8327:
8328:                    createSystemProcedureOrFunction("SYSCS_IMPORT_DATA",
8329:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8330:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8331:                            (TypeDescriptor) null, tc);
8332:                }
8333:
8334:                /*  
8335:                 * SYSCS_BULK_INSERT(
8336:                 *     IN SCHEMANAME VARCHAR(128), 
8337:                 *     IN TABLENAME  VARCHAR(128),
8338:                 *     IN VTINAME    VARCHAR(32762), 
8339:                 *     IN VTIARG     VARCHAR(32762))
8340:                 */
8341:                {
8342:                    // procedure argument names
8343:                    String[] arg_names = { "schemaName", "tableName",
8344:                            "vtiName", "vtiArg" };
8345:
8346:                    // procedure argument types
8347:                    TypeDescriptor[] arg_types = {
8348:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8349:                                    Types.VARCHAR, 128),
8350:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8351:                                    Types.VARCHAR, 128),
8352:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8353:                                    Types.VARCHAR, 32672),
8354:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8355:                                    Types.VARCHAR, 32672), };
8356:
8357:                    createSystemProcedureOrFunction("SYSCS_BULK_INSERT",
8358:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8359:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8360:                            (TypeDescriptor) null, tc);
8361:                }
8362:
8363:                // add 10.1 specific system procedures
8364:                create_10_1_system_procedures(tc, sysUtilUUID);
8365:                // add 10.2 specific system procedures
8366:                create_10_2_system_procedures(tc, sysUtilUUID);
8367:            }
8368:
8369:            /**
8370:             * Create system procedures in SYSIBM
8371:             * <p>
8372:             * Used to add the system procedures to the database when
8373:             * it is created.  Full upgrade from version 5.1 or earlier also
8374:             * calls this method.
8375:             * <p>
8376:             *
8377:             * @param tc     transaction controller to use.  Counts on caller to
8378:             *               commit.
8379:             *
8380:             * @exception  StandardException  Standard exception policy.
8381:             **/
8382:            protected final void create_SYSIBM_procedures(
8383:                    TransactionController tc) throws StandardException {
8384:                /*
8385:                 ** SYSIBM routines.
8386:                 */
8387:
8388:                // used to put procedure into the SYSIBM schema
8389:                UUID sysIBMUUID = getSysIBMSchemaDescriptor().getUUID();
8390:
8391:                // SYSIBM.SQLCAMESSAGE(
8392:                {
8393:
8394:                    // procedure argument names
8395:                    String[] arg_names = { "SQLCODE", "SQLERRML", "SQLERRMC",
8396:                            "SQLERRP", "SQLERRD0", "SQLERRD1", "SQLERRD2",
8397:                            "SQLERRD3", "SQLERRD4", "SQLERRD5", "SQLWARN",
8398:                            "SQLSTATE", "FILE", "LOCALE", "MESSAGE",
8399:                            "RETURNCODE" };
8400:
8401:                    // procedure argument types
8402:                    TypeDescriptor[] arg_types = {
8403:                            DataTypeDescriptor
8404:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8405:                            DataTypeDescriptor
8406:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8407:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8408:                                    Types.VARCHAR,
8409:                                    Limits.DB2_JCC_MAX_EXCEPTION_PARAM_LENGTH),
8410:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8411:                                    Types.CHAR, 8),
8412:                            DataTypeDescriptor
8413:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8414:                            DataTypeDescriptor
8415:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8416:                            DataTypeDescriptor
8417:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8418:                            DataTypeDescriptor
8419:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8420:                            DataTypeDescriptor
8421:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8422:                            DataTypeDescriptor
8423:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER),
8424:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8425:                                    Types.CHAR, 11),
8426:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8427:                                    Types.CHAR, 5),
8428:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8429:                                    Types.VARCHAR, 50),
8430:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8431:                                    Types.CHAR, 5),
8432:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8433:                                    Types.VARCHAR, 2400),
8434:                            DataTypeDescriptor
8435:                                    .getBuiltInDataTypeDescriptor(Types.INTEGER) };
8436:
8437:                    createSystemProcedureOrFunction("SQLCAMESSAGE", sysIBMUUID,
8438:                            arg_names, arg_types, 2, 0,
8439:                            RoutineAliasInfo.READS_SQL_DATA,
8440:                            (TypeDescriptor) null, tc);
8441:                }
8442:
8443:                // SYSIBM.SQLPROCEDURES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8444:                {
8445:
8446:                    // procedure argument names
8447:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8448:                            "PROCNAME", "OPTIONS" };
8449:
8450:                    // procedure argument types
8451:                    TypeDescriptor[] arg_types = {
8452:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8453:                                    Types.VARCHAR, 128),
8454:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8455:                                    Types.VARCHAR, 128),
8456:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8457:                                    Types.VARCHAR, 128),
8458:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8459:                                    Types.VARCHAR, 4000) };
8460:
8461:                    createSystemProcedureOrFunction("SQLPROCEDURES",
8462:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8463:                            RoutineAliasInfo.READS_SQL_DATA,
8464:                            (TypeDescriptor) null, tc);
8465:                }
8466:
8467:                // SYSIBM.SQLTABLEPRIVILEGES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8468:                {
8469:
8470:                    // procedure argument names
8471:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8472:                            "TABLENAME", "OPTIONS" };
8473:
8474:                    // procedure argument types
8475:                    TypeDescriptor[] arg_types = {
8476:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8477:                                    Types.VARCHAR, 128),
8478:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8479:                                    Types.VARCHAR, 128),
8480:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8481:                                    Types.VARCHAR, 128),
8482:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8483:                                    Types.VARCHAR, 4000) };
8484:
8485:                    createSystemProcedureOrFunction("SQLTABLEPRIVILEGES",
8486:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8487:                            RoutineAliasInfo.READS_SQL_DATA,
8488:                            (TypeDescriptor) null, tc);
8489:                }
8490:
8491:                // SYSIBM.SQLPRIMARYKEYS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8492:                {
8493:
8494:                    // procedure argument names
8495:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8496:                            "TABLENAME", "OPTIONS" };
8497:
8498:                    // procedure argument types
8499:                    TypeDescriptor[] arg_types = {
8500:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8501:                                    Types.VARCHAR, 128),
8502:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8503:                                    Types.VARCHAR, 128),
8504:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8505:                                    Types.VARCHAR, 128),
8506:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8507:                                    Types.VARCHAR, 4000) };
8508:
8509:                    createSystemProcedureOrFunction("SQLPRIMARYKEYS",
8510:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8511:                            RoutineAliasInfo.READS_SQL_DATA,
8512:                            (TypeDescriptor) null, tc);
8513:                }
8514:
8515:                // SYSIBM.SQLTABLES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000), VARCHAR(4000))
8516:                {
8517:
8518:                    // procedure argument names
8519:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8520:                            "TABLENAME", "TABLETYPE", "OPTIONS" };
8521:
8522:                    // procedure argument types
8523:                    TypeDescriptor[] arg_types = {
8524:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8525:                                    Types.VARCHAR, 128),
8526:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8527:                                    Types.VARCHAR, 128),
8528:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8529:                                    Types.VARCHAR, 128),
8530:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8531:                                    Types.VARCHAR, 4000),
8532:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8533:                                    Types.VARCHAR, 4000) };
8534:
8535:                    createSystemProcedureOrFunction("SQLTABLES", sysIBMUUID,
8536:                            arg_names, arg_types, 0, 1,
8537:                            RoutineAliasInfo.READS_SQL_DATA,
8538:                            (TypeDescriptor) null, tc);
8539:                }
8540:
8541:                // SYSIBM.SQLPROCEDURECOLS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8542:                {
8543:
8544:                    // procedure argument names
8545:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8546:                            "PROCNAME", "PARAMNAME", "OPTIONS" };
8547:
8548:                    // procedure argument types
8549:                    TypeDescriptor[] arg_types = {
8550:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8551:                                    Types.VARCHAR, 128),
8552:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8553:                                    Types.VARCHAR, 128),
8554:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8555:                                    Types.VARCHAR, 128),
8556:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8557:                                    Types.VARCHAR, 128),
8558:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8559:                                    Types.VARCHAR, 4000) };
8560:
8561:                    createSystemProcedureOrFunction("SQLPROCEDURECOLS",
8562:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8563:                            RoutineAliasInfo.READS_SQL_DATA,
8564:                            (TypeDescriptor) null, tc);
8565:                }
8566:
8567:                // SYSIBM.SQLCOLUMNS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8568:                {
8569:
8570:                    // procedure argument names
8571:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8572:                            "TABLENAME", "COLUMNNAME", "OPTIONS" };
8573:
8574:                    // procedure argument types
8575:                    TypeDescriptor[] arg_types = {
8576:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8577:                                    Types.VARCHAR, 128),
8578:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8579:                                    Types.VARCHAR, 128),
8580:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8581:                                    Types.VARCHAR, 128),
8582:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8583:                                    Types.VARCHAR, 128),
8584:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8585:                                    Types.VARCHAR, 4000) };
8586:
8587:                    createSystemProcedureOrFunction("SQLCOLUMNS", sysIBMUUID,
8588:                            arg_names, arg_types, 0, 1,
8589:                            RoutineAliasInfo.READS_SQL_DATA,
8590:                            (TypeDescriptor) null, tc);
8591:                }
8592:
8593:                // SYSIBM.SQLCOLPRIVILEGES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8594:                {
8595:
8596:                    // procedure argument names
8597:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8598:                            "TABLENAME", "COLUMNNAME", "OPTIONS" };
8599:
8600:                    // procedure argument types
8601:                    TypeDescriptor[] arg_types = {
8602:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8603:                                    Types.VARCHAR, 128),
8604:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8605:                                    Types.VARCHAR, 128),
8606:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8607:                                    Types.VARCHAR, 128),
8608:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8609:                                    Types.VARCHAR, 128),
8610:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8611:                                    Types.VARCHAR, 4000) };
8612:
8613:                    createSystemProcedureOrFunction("SQLCOLPRIVILEGES",
8614:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8615:                            RoutineAliasInfo.READS_SQL_DATA,
8616:                            (TypeDescriptor) null, tc);
8617:                }
8618:
8619:                // SYSIBM.SQLUDTS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8620:                {
8621:
8622:                    // procedure argument names
8623:                    String[] arg_names = { "CATALOGNAME", "SCHEMAPATTERN",
8624:                            "TYPENAMEPATTERN", "UDTTYPES", "OPTIONS" };
8625:
8626:                    // procedure argument types
8627:                    TypeDescriptor[] arg_types = {
8628:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8629:                                    Types.VARCHAR, 128),
8630:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8631:                                    Types.VARCHAR, 128),
8632:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8633:                                    Types.VARCHAR, 128),
8634:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8635:                                    Types.VARCHAR, 128),
8636:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8637:                                    Types.VARCHAR, 4000) };
8638:
8639:                    createSystemProcedureOrFunction("SQLUDTS", sysIBMUUID,
8640:                            arg_names, arg_types, 0, 1,
8641:                            RoutineAliasInfo.READS_SQL_DATA,
8642:                            (TypeDescriptor) null, tc);
8643:                }
8644:
8645:                // SYSIBM.SQLFOREIGNKEYS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128),
8646:                //						 VARCHAR(128), VARCHAR(128), VARCHAR(4000))
8647:                {
8648:
8649:                    // procedure argument names
8650:                    String[] arg_names = { "PKCATALOGNAME", "PKSCHEMANAME",
8651:                            "PKTABLENAME", "FKCATALOGNAME", "FKSCHEMANAME",
8652:                            "FKTABLENAME", "OPTIONS" };
8653:
8654:                    // procedure argument types
8655:                    TypeDescriptor[] arg_types = {
8656:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8657:                                    Types.VARCHAR, 128),
8658:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8659:                                    Types.VARCHAR, 128),
8660:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8661:                                    Types.VARCHAR, 128),
8662:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8663:                                    Types.VARCHAR, 128),
8664:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8665:                                    Types.VARCHAR, 128),
8666:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8667:                                    Types.VARCHAR, 128),
8668:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8669:                                    Types.VARCHAR, 4000) };
8670:
8671:                    createSystemProcedureOrFunction("SQLFOREIGNKEYS",
8672:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8673:                            RoutineAliasInfo.READS_SQL_DATA,
8674:                            (TypeDescriptor) null, tc);
8675:                }
8676:
8677:                // SYSIBM.SQLSPECIALCOLUMNS(SMALLINT, VARCHAR(128), VARCHAR(128), VARCHAR(128),
8678:                //						 	SMALLINT, SMALLINT, VARCHAR(4000))
8679:                {
8680:
8681:                    // procedure argument names
8682:                    String[] arg_names = { "COLTYPE", "CATALOGNAME",
8683:                            "SCHEMANAME", "TABLENAME", "SCOPE", "NULLABLE",
8684:                            "OPTIONS" };
8685:
8686:                    // procedure argument types
8687:                    TypeDescriptor[] arg_types = {
8688:                            DataTypeDescriptor
8689:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8690:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8691:                                    Types.VARCHAR, 128),
8692:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8693:                                    Types.VARCHAR, 128),
8694:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8695:                                    Types.VARCHAR, 128),
8696:                            DataTypeDescriptor
8697:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8698:                            DataTypeDescriptor
8699:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8700:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8701:                                    Types.VARCHAR, 4000) };
8702:
8703:                    createSystemProcedureOrFunction("SQLSPECIALCOLUMNS",
8704:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8705:                            RoutineAliasInfo.READS_SQL_DATA,
8706:                            (TypeDescriptor) null, tc);
8707:                }
8708:
8709:                // SYSIBM.SQLGETTYPEINFO(SMALLINT, VARCHAR(4000))
8710:                {
8711:
8712:                    // procedure argument names
8713:                    String[] arg_names = { "DATATYPE", "OPTIONS" };
8714:
8715:                    // procedure argument types
8716:                    TypeDescriptor[] arg_types = {
8717:                            DataTypeDescriptor
8718:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8719:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8720:                                    Types.VARCHAR, 4000) };
8721:
8722:                    createSystemProcedureOrFunction("SQLGETTYPEINFO",
8723:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8724:                            RoutineAliasInfo.READS_SQL_DATA,
8725:                            (TypeDescriptor) null, tc);
8726:                }
8727:
8728:                // SYSIBM.SQLSTATISTICS(VARCHAR(128), VARCHAR(128), VARCHAR(128),
8729:                //						 	SMALLINT, SMALLINT, VARCHAR(4000))
8730:                {
8731:
8732:                    // procedure argument names
8733:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8734:                            "TABLENAME", "UNIQUE", "RESERVED", "OPTIONS" };
8735:
8736:                    // procedure argument types
8737:                    TypeDescriptor[] arg_types = {
8738:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8739:                                    Types.VARCHAR, 128),
8740:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8741:                                    Types.VARCHAR, 128),
8742:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8743:                                    Types.VARCHAR, 128),
8744:                            DataTypeDescriptor
8745:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8746:                            DataTypeDescriptor
8747:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8748:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8749:                                    Types.VARCHAR, 4000) };
8750:
8751:                    createSystemProcedureOrFunction("SQLSTATISTICS",
8752:                            sysIBMUUID, arg_names, arg_types, 0, 1,
8753:                            RoutineAliasInfo.READS_SQL_DATA,
8754:                            (TypeDescriptor) null, tc);
8755:                }
8756:
8757:                // void SYSIBM.METADATA()
8758:                {
8759:                    createSystemProcedureOrFunction("METADATA", sysIBMUUID,
8760:                            null, null, 0, 1, RoutineAliasInfo.READS_SQL_DATA,
8761:                            (TypeDescriptor) null, tc);
8762:                }
8763:
8764:            }
8765:
8766:            /**
8767:             * Grant PUBLIC access to specific system routines. Currently, this is 
8768:             * done for some routines in SYSCS_UTIL schema. 
8769:             * 
8770:             * @param tc	TransactionController to use
8771:             * @param authorizationID	authorization ID of the permission grantor
8772:             * @throws StandardException	Standard exception policy.
8773:             */
8774:            public void grantPublicAccessToSystemRoutines(
8775:                    TransactionController tc, String authorizationID)
8776:                    throws StandardException {
8777:
8778:                // Get schema ID for SYSCS_UTIL schema
8779:                String schemaID = getSystemUtilSchemaDescriptor().getUUID()
8780:                        .toString();
8781:
8782:                for (int i = 0; i < sysUtilProceduresWithPublicAccess.length; i++) {
8783:                    grantPublicAccessToSystemRoutine(schemaID,
8784:                            sysUtilProceduresWithPublicAccess[i],
8785:                            AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR, tc,
8786:                            authorizationID);
8787:                }
8788:
8789:                for (int i = 0; i < sysUtilFunctionsWithPublicAccess.length; i++) {
8790:                    grantPublicAccessToSystemRoutine(schemaID,
8791:                            sysUtilFunctionsWithPublicAccess[i],
8792:                            AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR, tc,
8793:                            authorizationID);
8794:                }
8795:            }
8796:
8797:            /**
8798:             * Grant PUBLIC access to a system routine. This method should be used only 
8799:             * for granting access to a system routine (other than routines in SYSFUN 
8800:             * schema). It expects the routine to be present in SYSALIASES catalog. 
8801:             * 
8802:             * @param schemaID	Schema ID
8803:             * @param routineName	Routine Name
8804:             * @param nameSpace	Indicates whether the routine is a function/procedure.
8805:             * @param tc	TransactionController to use
8806:             * @param authorizationID	authorization ID of the permission grantor
8807:             * @throws StandardException	Standard exception policy.
8808:             */
8809:            private void grantPublicAccessToSystemRoutine(String schemaID,
8810:                    String routineName, char nameSpace,
8811:                    TransactionController tc, String authorizationID)
8812:                    throws StandardException {
8813:                // For system routines, a valid alias descriptor will be returned.
8814:                AliasDescriptor ad = getAliasDescriptor(schemaID, routineName,
8815:                        nameSpace);
8816:
8817:                if (SanityManager.DEBUG) {
8818:                    SanityManager
8819:                            .ASSERT((ad != null),
8820:                                    "Failed to get AliasDescriptor"
8821:                                            + " of the routine");
8822:                }
8823:
8824:                UUID routineUUID = ad.getUUID();
8825:                createRoutinePermPublicDescriptor(routineUUID, tc,
8826:                        authorizationID);
8827:            }
8828:
8829:            /**
8830:             * Create RoutinePermDescriptor to grant access to PUBLIC for
8831:             * this system routine. Currently only SYSUTIL routines need access
8832:             * granted to execute them when a database is created/upgraded.
8833:             *
8834:             * @param routineUUID   uuid of the routine
8835:             * @param tc			TransactionController to use
8836:             *
8837:             * @exception  StandardException  Standard exception policy.
8838:             */
8839:            void createRoutinePermPublicDescriptor(UUID routineUUID,
8840:                    TransactionController tc) throws StandardException {
8841:                createRoutinePermPublicDescriptor(routineUUID, tc,
8842:                        authorizationDatabaseOwner);
8843:            }
8844:
8845:            /**
8846:             * Create RoutinePermDescriptor to grant access to PUBLIC for
8847:             * this system routine using the grantor specified in authorizationID.
8848:             * 
8849:             * @param routineUUID	uuid of the routine
8850:             * @param tc	TransactionController to use
8851:             * @param authorizationID	authorization ID of the permission grantor
8852:             * @throws StandardException	Standard exception policy.
8853:             */
8854:            void createRoutinePermPublicDescriptor(UUID routineUUID,
8855:                    TransactionController tc, String authorizationID)
8856:                    throws StandardException {
8857:                RoutinePermsDescriptor routinePermDesc = new RoutinePermsDescriptor(
8858:                        this , "PUBLIC", authorizationID, routineUUID);
8859:
8860:                addDescriptor(routinePermDesc, null,
8861:                        DataDictionary.SYSROUTINEPERMS_CATALOG_NUM, false, tc);
8862:            }
8863:
8864:            /**
8865:             * Create system procedures added in version 10.1.
8866:             * <p>
8867:             * Create 10.1 system procedures, called by either code creating new
8868:             * database, or code doing hard upgrade from previous version.
8869:             * <p>
8870:             *
8871:             * @param sysUtilUUID   uuid of the SYSUTIL schema.
8872:             *
8873:             * @exception  StandardException  Standard exception policy.
8874:             **/
8875:            void create_10_1_system_procedures(TransactionController tc,
8876:                    UUID sysUtilUUID) throws StandardException {
8877:
8878:                UUID routine_uuid = null;
8879:
8880:                // void SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(
8881:                //     IN SCHEMANAME        VARCHAR(128), 
8882:                //     IN TABLENAME         VARCHAR(128),
8883:                //     IN PURGE_ROWS        SMALLINT,
8884:                //     IN DEFRAGMENT_ROWS   SMALLINT,
8885:                //     IN TRUNCATE_END      SMALLINT
8886:                //     )
8887:                {
8888:                    // procedure argument names
8889:                    String[] arg_names = { "SCHEMANAME", "TABLENAME",
8890:                            "PURGE_ROWS", "DEFRAGMENT_ROWS", "TRUNCATE_END" };
8891:
8892:                    // procedure argument types
8893:                    TypeDescriptor[] arg_types = {
8894:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8895:                                    Types.VARCHAR, 128),
8896:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8897:                                    Types.VARCHAR, 128),
8898:                            DataTypeDescriptor
8899:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8900:                            DataTypeDescriptor
8901:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT),
8902:                            DataTypeDescriptor
8903:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8904:
8905:                    routine_uuid = createSystemProcedureOrFunction(
8906:                            "SYSCS_INPLACE_COMPRESS_TABLE", sysUtilUUID,
8907:                            arg_names, arg_types, 0, 0,
8908:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8909:                            (TypeDescriptor) null, tc);
8910:
8911:                    createRoutinePermPublicDescriptor(routine_uuid, tc);
8912:                }
8913:            }
8914:
8915:            /**
8916:             * Create system procedures added in version 10.2.
8917:             * <p>
8918:             * Create 10.2 system procedures, called by either code creating new
8919:             * database, or code doing hard upgrade from previous version.
8920:             * <p>
8921:             *
8922:             * @param sysUtilUUID   uuid of the SYSUTIL schema.
8923:             *
8924:             * @exception  StandardException  Standard exception policy.
8925:             **/
8926:            void create_10_2_system_procedures(TransactionController tc,
8927:                    UUID sysUtilUUID) throws StandardException {
8928:
8929:                // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE_NOWAIT(
8930:                //     IN BACKUPDIR        VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH)
8931:                //     )
8932:
8933:                {
8934:                    // procedure argument names
8935:                    String[] arg_names = { "BACKUPDIR" };
8936:
8937:                    // procedure argument types
8938:                    TypeDescriptor[] arg_types = { DataTypeDescriptor
8939:                            .getBuiltInDataTypeDescriptor(Types.VARCHAR,
8940:                                    Limits.DB2_VARCHAR_MAXWIDTH) };
8941:
8942:                    createSystemProcedureOrFunction(
8943:                            "SYSCS_BACKUP_DATABASE_NOWAIT", sysUtilUUID,
8944:                            arg_names, arg_types, 0, 0,
8945:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8946:                            (TypeDescriptor) null, tc);
8947:                }
8948:
8949:                // void 
8950:                // SYSCS_UTIL.SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE_NOWAIT(
8951:                //   IN BACKUPDIR                 VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH),
8952:                //   IN DELETE_ARCHIVED_LOG_FILES SMALLINT
8953:                //   )
8954:                {
8955:                    // procedure argument names
8956:                    String[] arg_names = { "BACKUPDIR",
8957:                            "DELETE_ARCHIVED_LOG_FILES" };
8958:
8959:                    // procedure argument types
8960:                    TypeDescriptor[] arg_types = {
8961:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8962:                                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
8963:                            DataTypeDescriptor
8964:                                    .getBuiltInDataTypeDescriptor(Types.SMALLINT) };
8965:
8966:                    createSystemProcedureOrFunction(
8967:                            "SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE_NOWAIT",
8968:                            sysUtilUUID, arg_names, arg_types, 0, 0,
8969:                            RoutineAliasInfo.MODIFIES_SQL_DATA,
8970:                            (TypeDescriptor) null, tc);
8971:                }
8972:
8973:                // SYSIBM.SQLFUNCTIONS(VARCHAR(128), VARCHAR(128), VARCHAR(128), 
8974:                // VARCHAR(4000))
8975:                {
8976:
8977:                    // procedure argument names
8978:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
8979:                            "FUNCNAME", "OPTIONS" };
8980:
8981:                    // procedure argument types
8982:                    TypeDescriptor[] arg_types = {
8983:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8984:                                    Types.VARCHAR, 128),
8985:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8986:                                    Types.VARCHAR, 128),
8987:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8988:                                    Types.VARCHAR, 128),
8989:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8990:                                    Types.VARCHAR, 4000) };
8991:
8992:                    createSystemProcedureOrFunction("SQLFUNCTIONS",
8993:                            getSysIBMSchemaDescriptor().getUUID(), arg_names,
8994:                            arg_types, 0, 1, RoutineAliasInfo.READS_SQL_DATA,
8995:                            (TypeDescriptor) null, tc);
8996:                }
8997:
8998:                // SYSIBM.SQLFUNCTIONPARAMS(VARCHAR(128), VARCHAR(128),
8999:                // VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9000:                {
9001:
9002:                    // procedure argument names
9003:                    String[] arg_names = { "CATALOGNAME", "SCHEMANAME",
9004:                            "FUNCNAME", "PARAMNAME", "OPTIONS" };
9005:
9006:                    // procedure argument types
9007:                    TypeDescriptor[] arg_types = {
9008:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9009:                                    Types.VARCHAR, 128),
9010:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9011:                                    Types.VARCHAR, 128),
9012:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9013:                                    Types.VARCHAR, 128),
9014:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9015:                                    Types.VARCHAR, 128),
9016:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9017:                                    Types.VARCHAR, 4000) };
9018:
9019:                    createSystemProcedureOrFunction("SQLFUNCTIONPARAMS",
9020:                            getSysIBMSchemaDescriptor().getUUID(), arg_names,
9021:                            arg_types, 0, 1, RoutineAliasInfo.READS_SQL_DATA,
9022:                            (TypeDescriptor) null, tc);
9023:                }
9024:            }
9025:
9026:            /*
9027:             ** Priv block code to load net work server meta data queries.
9028:             */
9029:
9030:            private String spsSet;
9031:
9032:            private final synchronized Properties getQueryDescriptions(
9033:                    boolean net) {
9034:                spsSet = net ? "metadata_net.properties"
9035:                        : "/org/apache/derby/impl/jdbc/metadata.properties";
9036:                return (Properties) java.security.AccessController
9037:                        .doPrivileged(this );
9038:            }
9039:
9040:            public final Object run() {
9041:                // SECURITY PERMISSION - IP3
9042:                Properties p = new Properties();
9043:                try {
9044:
9045:                    // SECURITY PERMISSION - IP3
9046:                    InputStream is = getClass().getResourceAsStream(spsSet);
9047:                    p.load(is);
9048:                    is.close();
9049:                } catch (IOException ioe) {
9050:                }
9051:                return p;
9052:            }
9053:
9054:            private static List newSList() {
9055:                return java.util.Collections
9056:                        .synchronizedList(new java.util.LinkedList());
9057:            }
9058:
9059:            /**
9060:             * Get one user's privileges on a table
9061:             *
9062:             * @param tableUUID
9063:             * @param authorizationId The user name
9064:             *
9065:             * @return a TablePermsDescriptor or null if the user has no permissions on the table.
9066:             *
9067:             * @exception StandardException
9068:             */
9069:            public TablePermsDescriptor getTablePermissions(UUID tableUUID,
9070:                    String authorizationId) throws StandardException {
9071:                TablePermsDescriptor key = new TablePermsDescriptor(this ,
9072:                        authorizationId, (String) null, tableUUID);
9073:                return (TablePermsDescriptor) getPermissions(key);
9074:            } // end of getTablePermissions
9075:
9076:            /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getTablePermissions */
9077:            public TablePermsDescriptor getTablePermissions(UUID tablePermsUUID)
9078:                    throws StandardException {
9079:                TablePermsDescriptor key = new TablePermsDescriptor(this ,
9080:                        tablePermsUUID);
9081:                return getUncachedTablePermsDescriptor(key);
9082:            }
9083:
9084:            private Object getPermissions(PermissionsDescriptor key)
9085:                    throws StandardException {
9086:                // RESOLVE get a READ COMMITTED (shared) lock on the permission row
9087:                Cacheable entry = getPermissionsCache().find(key);
9088:                if (entry == null)
9089:                    return null;
9090:                Object perms = entry.getIdentity();
9091:                getPermissionsCache().release(entry);
9092:                return perms;
9093:            }
9094:
9095:            /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getColumnPermissions */
9096:            public ColPermsDescriptor getColumnPermissions(UUID colPermsUUID)
9097:                    throws StandardException {
9098:                ColPermsDescriptor key = new ColPermsDescriptor(this ,
9099:                        colPermsUUID);
9100:                return getUncachedColPermsDescriptor(key);
9101:            }
9102:
9103:            /**
9104:             * Get one user's column privileges for a table.
9105:             *
9106:             * @param tableUUID
9107:             * @param privType (as int) Authorizer.SELECT_PRIV, Authorizer.UPDATE_PRIV, or Authorizer.REFERENCES_PRIV
9108:             * @param forGrant
9109:             * @param authorizationId The user name
9110:             *
9111:             * @return a ColPermsDescriptor or null if the user has no separate column
9112:             *         permissions of the specified type on the table. Note that the user may have been granted
9113:             *         permission on all the columns of the table (no column list), in which case this routine
9114:             *         will return null. You must also call getTablePermissions to see if the user has permission
9115:             *         on a set of columns.
9116:             *
9117:             * @exception StandardException
9118:             */
9119:            public ColPermsDescriptor getColumnPermissions(UUID tableUUID,
9120:                    int privType, boolean forGrant, String authorizationId)
9121:                    throws StandardException {
9122:                String privTypeStr = forGrant ? colPrivTypeMapForGrant[privType]
9123:                        : colPrivTypeMap[privType];
9124:                if (SanityManager.DEBUG)
9125:                    SanityManager.ASSERT(privTypeStr != null,
9126:                            "Invalid column privilege type: " + privType);
9127:                ColPermsDescriptor key = new ColPermsDescriptor(this ,
9128:                        authorizationId, (String) null, tableUUID, privTypeStr);
9129:                return (ColPermsDescriptor) getPermissions(key);
9130:            } // end of getColumnPermissions
9131:
9132:            /**
9133:             * Get one user's column privileges for a table. This routine gets called 
9134:             * during revoke privilege processing
9135:             *
9136:             * @param tableUUID
9137:             * @param privTypeStr (as String) Authorizer.SELECT_PRIV, Authorizer.UPDATE_PRIV, or Authorizer.REFERENCES_PRIV
9138:             * @param forGrant
9139:             * @param authorizationId The user name
9140:             *
9141:             * @return a ColPermsDescriptor or null if the user has no separate column
9142:             *         permissions of the specified type on the table. Note that the user may have been granted
9143:             *         permission on all the columns of the table (no column list), in which case this routine
9144:             *         will return null. You must also call getTablePermissions to see if the user has permission
9145:             *         on a set of columns.
9146:             *
9147:             * @exception StandardException
9148:             */
9149:            public ColPermsDescriptor getColumnPermissions(UUID tableUUID,
9150:                    String privTypeStr, boolean forGrant, String authorizationId)
9151:                    throws StandardException {
9152:                ColPermsDescriptor key = new ColPermsDescriptor(this ,
9153:                        authorizationId, (String) null, tableUUID, privTypeStr);
9154:                return (ColPermsDescriptor) getPermissions(key);
9155:
9156:            }
9157:
9158:            private static final String[] colPrivTypeMap;
9159:            private static final String[] colPrivTypeMapForGrant;
9160:            static {
9161:                colPrivTypeMap = new String[Authorizer.PRIV_TYPE_COUNT];
9162:                colPrivTypeMapForGrant = new String[Authorizer.PRIV_TYPE_COUNT];
9163:                colPrivTypeMap[Authorizer.SELECT_PRIV] = "s";
9164:                colPrivTypeMapForGrant[Authorizer.SELECT_PRIV] = "S";
9165:                colPrivTypeMap[Authorizer.UPDATE_PRIV] = "u";
9166:                colPrivTypeMapForGrant[Authorizer.UPDATE_PRIV] = "U";
9167:                colPrivTypeMap[Authorizer.REFERENCES_PRIV] = "r";
9168:                colPrivTypeMapForGrant[Authorizer.REFERENCES_PRIV] = "R";
9169:            }
9170:
9171:            /**
9172:             * Get one user's permissions for a routine (function or procedure).
9173:             *
9174:             * @param routineUUID
9175:             * @param authorizationId The user's name
9176:             *
9177:             * @return The descriptor of the users permissions for the routine.
9178:             *
9179:             * @exception StandardException
9180:             */
9181:            public RoutinePermsDescriptor getRoutinePermissions(
9182:                    UUID routineUUID, String authorizationId)
9183:                    throws StandardException {
9184:                RoutinePermsDescriptor key = new RoutinePermsDescriptor(this ,
9185:                        authorizationId, (String) null, routineUUID);
9186:
9187:                return (RoutinePermsDescriptor) getPermissions(key);
9188:            } // end of getRoutinePermissions
9189:
9190:            /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getRoutinePermissions */
9191:            public RoutinePermsDescriptor getRoutinePermissions(
9192:                    UUID routinePermsUUID) throws StandardException {
9193:                RoutinePermsDescriptor key = new RoutinePermsDescriptor(this ,
9194:                        routinePermsUUID);
9195:                return getUncachedRoutinePermsDescriptor(key);
9196:            }
9197:
9198:            /**
9199:             * Add or remove a permission to/from the permission database.
9200:             *
9201:             * @param add if true then the permission is added, if false the permission is removed
9202:             * @param perm
9203:             * @param grantee
9204:             * @param tc
9205:             *
9206:             * @return True means revoke has removed a privilege from system
9207:             * table and hence the caller of this method should send invalidation 
9208:             * actions to PermssionDescriptor's dependents.
9209:             */
9210:            public boolean addRemovePermissionsDescriptor(boolean add,
9211:                    PermissionsDescriptor perm, String grantee,
9212:                    TransactionController tc) throws StandardException {
9213:                int catalogNumber = perm.getCatalogNumber();
9214:
9215:                // It is possible for grant statements to look like following
9216:                //   grant execute on function f_abs to mamata2, mamata3;
9217:                //   grant all privileges on t11 to mamata2, mamata3;
9218:                // This means that dd.addRemovePermissionsDescriptor will be called
9219:                // twice for TablePermsDescriptor and twice for RoutinePermsDescriptor, 
9220:                // once for each grantee.
9221:                // First it's called for mamta2. When a row is inserted for mamta2 
9222:                // into the correct system table for the permission descriptor, the 
9223:                // permission descriptor's uuid gets populated with the uuid of 
9224:                // the row that just got inserted into the system table for mamta2
9225:                // Now, when dd.addRemovePermissionsDescriptor gets called again for
9226:                // mamta3, the permission descriptor's uuid will still be set to
9227:                // the uuid that was used for mamta2. If we do not reset the
9228:                // uuid to null, we will think that there is a duplicate row getting
9229:                // inserted for the same uuid. In order to get around this, we should 
9230:                // reset the UUID of passed PermissionDescriptor everytime this method 
9231:                // is called. This way, there will be no leftover values from previous
9232:                // call of this method.
9233:                perm.setUUID(null);
9234:                perm.setGrantee(grantee);
9235:                TabInfoImpl ti = getNonCoreTI(catalogNumber);
9236:                PermissionsCatalogRowFactory rf = (PermissionsCatalogRowFactory) ti
9237:                        .getCatalogRowFactory();
9238:                int primaryIndexNumber = rf.getPrimaryKeyIndexNumber();
9239:                ConglomerateController heapCC = tc.openConglomerate(ti
9240:                        .getHeapConglomerate(),
9241:                        false, // do not keep open across commits
9242:                        0, TransactionController.MODE_RECORD,
9243:                        TransactionController.ISOLATION_REPEATABLE_READ);
9244:                RowLocation rl = null;
9245:                try {
9246:                    rl = heapCC.newRowLocationTemplate();
9247:                } finally {
9248:                    heapCC.close();
9249:                    heapCC = null;
9250:                }
9251:                ExecIndexRow key = rf
9252:                        .buildIndexKeyRow(primaryIndexNumber, perm);
9253:                ExecRow existingRow = ti.getRow(tc, key, primaryIndexNumber);
9254:                if (existingRow == null) {
9255:                    if (!add)
9256:                        //we didn't find an entry in system catalog and this is revoke
9257:                        //so that means there is nothing to revoke. Simply return.
9258:                        //No need to reset permission descriptor's uuid because
9259:                        //no row was ever found in system catalog for the given
9260:                        //permission and hence uuid can't be non-null
9261:                        return false;
9262:                    //We didn't find an entry in system catalog and this is grant so 
9263:                    //so that means we have to enter a new row in system catalog for
9264:                    //this grant.
9265:                    ExecRow row = ti.getCatalogRowFactory().makeRow(perm,
9266:                            (TupleDescriptor) null);
9267:                    int insertRetCode = ti.insertRow(row, tc, true /* wait */);
9268:                    if (SanityManager.DEBUG)
9269:                        SanityManager.ASSERT(
9270:                                insertRetCode == TabInfoImpl.ROWNOTDUPLICATE,
9271:                                "Race condition in inserting table privilege.");
9272:                } else {
9273:                    // add/remove these permissions to/from the existing permissions
9274:                    boolean[] colsChanged = new boolean[existingRow.nColumns()];
9275:                    boolean[] indicesToUpdate = new boolean[rf.getNumIndexes()];
9276:                    int changedColCount = 0;
9277:                    if (add)
9278:                        changedColCount = rf.orPermissions(existingRow, perm,
9279:                                colsChanged);
9280:                    else
9281:                        changedColCount = rf.removePermissions(existingRow,
9282:                                perm, colsChanged);
9283:                    if (changedColCount == 0) {
9284:                        //grant/revoke privilege didn't change anything and hence 
9285:                        //just return
9286:                        return false;
9287:                    }
9288:                    if (!add) {
9289:                        //set the uuid of the passed permission descriptor to 
9290:                        //corresponding rows's uuid in permissions system table. The
9291:                        //permission descriptor's uuid is required to have the 
9292:                        //dependency manager send the revoke privilege action to
9293:                        //all the dependent objects on that permission descriptor.
9294:                        rf.setUUIDOfThePassedDescriptor(existingRow, perm);
9295:                    }
9296:                    if (changedColCount < 0) {
9297:                        // No permissions left in the current row
9298:                        ti.deleteRow(tc, key, primaryIndexNumber);
9299:                    } else if (changedColCount > 0) {
9300:                        int[] colsToUpdate = new int[changedColCount];
9301:                        changedColCount = 0;
9302:                        for (int i = 0; i < colsChanged.length; i++) {
9303:                            if (colsChanged[i])
9304:                                colsToUpdate[changedColCount++] = i + 1;
9305:                        }
9306:                        if (SanityManager.DEBUG)
9307:                            SanityManager
9308:                                    .ASSERT(
9309:                                            changedColCount == colsToUpdate.length,
9310:                                            "return value of "
9311:                                                    + rf.getClass().getName()
9312:                                                    + ".orPermissions does not match the number of booleans it set in colsChanged.");
9313:                        ti
9314:                                .updateRow(key, existingRow,
9315:                                        primaryIndexNumber, indicesToUpdate,
9316:                                        colsToUpdate, tc, true /* wait */);
9317:                    }
9318:                }
9319:                // Remove cached permissions data. The cache may hold permissions data for this key even if
9320:                // the row in the permissions table is new. In that case the cache may have an entry indicating no
9321:                // permissions
9322:                removePermEntryInCache(perm);
9323:
9324:                //If we are dealing with grant, then the caller does not need to send 
9325:                //any invalidation actions to anyone and hence return false
9326:                if (add)
9327:                    return false;
9328:                return true;
9329:            } // end of addPermissionsDescriptor
9330:
9331:            /**
9332:             * Get a table permissions descriptor from the system tables, without going through the cache.
9333:             * This method is called to fill the permissions cache.
9334:             *
9335:             * @return a TablePermsDescriptor that describes the table permissions granted to the grantee, null
9336:             *          if no table-level permissions have been granted to him on the table.
9337:             *
9338:             * @exception StandardException
9339:             */
9340:            TablePermsDescriptor getUncachedTablePermsDescriptor(
9341:                    TablePermsDescriptor key) throws StandardException {
9342:                if (key.getObjectID() == null) {
9343:                    //the TABLEPERMSID for SYSTABLEPERMS is not known, so use
9344:                    //table id, grantor and granteee to find TablePermsDescriptor
9345:                    return (TablePermsDescriptor) getUncachedPermissionsDescriptor(
9346:                            SYSTABLEPERMS_CATALOG_NUM,
9347:                            SYSTABLEPERMSRowFactory.GRANTEE_TABLE_GRANTOR_INDEX_NUM,
9348:                            key);
9349:                } else {
9350:                    //we know the TABLEPERMSID for SYSTABLEPERMS, so use that to
9351:                    //find TablePermsDescriptor from the sytem table
9352:                    return (TablePermsDescriptor) getUncachedPermissionsDescriptor(
9353:                            SYSTABLEPERMS_CATALOG_NUM,
9354:                            SYSTABLEPERMSRowFactory.TABLEPERMSID_INDEX_NUM, key);
9355:                }
9356:            } // end of getUncachedTablePermsDescriptor
9357:
9358:            /**
9359:             * Get a column permissions descriptor from the system tables, without going through the cache.
9360:             * This method is called to fill the permissions cache.
9361:             *
9362:             *
9363:             * @return a ColPermsDescriptor that describes the column permissions granted to the grantee, null
9364:             *          if no column permissions have been granted to him on the table.
9365:             *
9366:             * @exception StandardException
9367:             */
9368:            ColPermsDescriptor getUncachedColPermsDescriptor(
9369:                    ColPermsDescriptor key) throws StandardException {
9370:                if (key.getObjectID() == null) {
9371:                    //the COLPERMSID for SYSCOLPERMS is not known, so use tableid,
9372:                    //privilege type, grantor and granteee to find ColPermsDescriptor
9373:                    return (ColPermsDescriptor) getUncachedPermissionsDescriptor(
9374:                            SYSCOLPERMS_CATALOG_NUM,
9375:                            SYSCOLPERMSRowFactory.GRANTEE_TABLE_TYPE_GRANTOR_INDEX_NUM,
9376:                            key);
9377:                } else {
9378:                    //we know the COLPERMSID for SYSCOLPERMS, so use that to
9379:                    //find ColPermsDescriptor from the sytem table
9380:                    return (ColPermsDescriptor) getUncachedPermissionsDescriptor(
9381:                            SYSCOLPERMS_CATALOG_NUM,
9382:                            SYSCOLPERMSRowFactory.COLPERMSID_INDEX_NUM, key);
9383:                }
9384:            } // end of getUncachedColPermsDescriptor
9385:
9386:            private TupleDescriptor getUncachedPermissionsDescriptor(
9387:                    int catalogNumber, int indexNumber,
9388:                    PermissionsDescriptor key) throws StandardException {
9389:                TabInfoImpl ti = getNonCoreTI(catalogNumber);
9390:                PermissionsCatalogRowFactory rowFactory = (PermissionsCatalogRowFactory) ti
9391:                        .getCatalogRowFactory();
9392:                ExecIndexRow keyRow = rowFactory.buildIndexKeyRow(indexNumber,
9393:                        key);
9394:                return getDescriptorViaIndex(indexNumber, keyRow,
9395:                        (ScanQualifier[][]) null, ti, (TupleDescriptor) null,
9396:                        (List) null, false);
9397:            } // end of getUncachedPermissionsDescriptor
9398:
9399:            /**
9400:             * Get a routine permissions descriptor from the system tables, without going through the cache.
9401:             * This method is called to fill the permissions cache.
9402:             *
9403:             * @return a RoutinePermsDescriptor that describes the table permissions granted to the grantee, null
9404:             *          if no table-level permissions have been granted to him on the table.
9405:             *
9406:             * @exception StandardException
9407:             */
9408:            RoutinePermsDescriptor getUncachedRoutinePermsDescriptor(
9409:                    RoutinePermsDescriptor key) throws StandardException {
9410:                if (key.getObjectID() == null) {
9411:                    //the ROUTINEPERMSID for SYSROUTINEPERMS is not known, so use aliasid,
9412:                    //grantor and granteee to find RoutinePermsDescriptor
9413:                    return (RoutinePermsDescriptor) getUncachedPermissionsDescriptor(
9414:                            SYSROUTINEPERMS_CATALOG_NUM,
9415:                            SYSROUTINEPERMSRowFactory.GRANTEE_ALIAS_GRANTOR_INDEX_NUM,
9416:                            key);
9417:                } else {
9418:                    //we know the ROUTINEPERMSID for SYSROUTINEPERMS, so use that to
9419:                    //find RoutinePermsDescriptor from the sytem table
9420:                    return (RoutinePermsDescriptor) getUncachedPermissionsDescriptor(
9421:                            SYSROUTINEPERMS_CATALOG_NUM,
9422:                            SYSROUTINEPERMSRowFactory.ROUTINEPERMSID_INDEX_NUM,
9423:                            key);
9424:
9425:                }
9426:            } // end of getUncachedRoutinePermsDescriptor
9427:
9428:            private String[][] DIAG_VTI_CLASSES = {
9429:                    { "LOCK_TABLE", "org.apache.derby.diag.LockTable" },
9430:                    { "STATEMENT_CACHE", "org.apache.derby.diag.StatementCache" },
9431:                    { "TRANSACTION_TABLE",
9432:                            "org.apache.derby.diag.TransactionTable" },
9433:                    { "ERROR_MESSAGES", "org.apache.derby.diag.ErrorMessages" },
9434:
9435:            };
9436:
9437:            /**
9438:             * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getVTIClass(org.apache.derby.iapi.sql.dictionary.TableDescriptor)
9439:             */
9440:            public String getVTIClass(TableDescriptor td)
9441:                    throws StandardException {
9442:
9443:                if (SanityManager.DEBUG) {
9444:                    if (td.getTableType() != TableDescriptor.VTI_TYPE)
9445:                        SanityManager
9446:                                .THROWASSERT("getVTIClass: Invalid table type "
9447:                                        + td);
9448:                }
9449:
9450:                for (int i = 0; i < DIAG_VTI_CLASSES.length; i++) {
9451:                    String[] entry = DIAG_VTI_CLASSES[i];
9452:                    if (entry[0].equals(td.getDescriptorName()))
9453:                        return entry[1];
9454:                }
9455:
9456:                return null;
9457:            }
9458:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.