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: }
|