KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > catalog > DataDictionaryImpl


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

21
22 package org.apache.derby.impl.sql.catalog;
23
24 import org.apache.derby.iapi.reference.JDBC30Translation;
25 import org.apache.derby.iapi.reference.Property;
26 import org.apache.derby.iapi.reference.SQLState;
27 import org.apache.derby.iapi.reference.Limits;
28 import org.apache.derby.iapi.sql.conn.Authorizer;
29
30 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
31 import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
32
33 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
34 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
35 import org.apache.derby.iapi.sql.dictionary.FileInfoDescriptor;
36 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
37 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
38 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;
39 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
40 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
41 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
42 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
43 import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;
44 import org.apache.derby.iapi.sql.dictionary.DependencyDescriptor;
45 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
46 import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
47 import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
48 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
49 import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
50 import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;
51 import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor;
52 import org.apache.derby.iapi.sql.dictionary.RoutinePermsDescriptor;
53 import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;
54 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
55 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
56 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
57 import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
58 import org.apache.derby.iapi.sql.dictionary.SubCheckConstraintDescriptor;
59 import org.apache.derby.iapi.sql.dictionary.SubConstraintDescriptor;
60 import org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor;
61 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
62 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
63 import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;
64 import org.apache.derby.iapi.sql.dictionary.SystemColumn;
65
66 import org.apache.derby.iapi.sql.depend.DependencyManager;
67
68 import org.apache.derby.impl.sql.depend.BasicDependencyManager;
69
70 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
71 import org.apache.derby.iapi.sql.execute.ExecutionContext;
72 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
73 import org.apache.derby.iapi.sql.execute.ScanQualifier;
74
75 import org.apache.derby.iapi.types.DataValueFactory;
76 import org.apache.derby.iapi.types.NumberDataValue;
77
78 import org.apache.derby.iapi.types.StringDataValue;
79 import org.apache.derby.iapi.types.TypeId;
80 import org.apache.derby.iapi.types.DataTypeDescriptor;
81 import org.apache.derby.iapi.types.DataValueDescriptor;
82 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
83 import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
84
85 import org.apache.derby.iapi.store.access.AccessFactory;
86 import org.apache.derby.iapi.store.access.ConglomerateController;
87 import org.apache.derby.iapi.types.Orderable;
88 import org.apache.derby.iapi.types.RowLocation;
89 import org.apache.derby.iapi.store.access.RowUtil;
90 import org.apache.derby.iapi.store.access.ScanController;
91 import org.apache.derby.iapi.store.access.TransactionController;
92 import org.apache.derby.iapi.store.access.Qualifier;
93
94 import org.apache.derby.iapi.services.monitor.Monitor;
95 import org.apache.derby.iapi.services.monitor.ModuleControl;
96 import org.apache.derby.iapi.services.monitor.ModuleSupportable;
97
98 import org.apache.derby.iapi.services.context.ContextManager;
99 import org.apache.derby.iapi.services.context.ContextService;
100
101 import org.apache.derby.iapi.error.StandardException;
102
103 // RESOLVE - paulat - remove this import when track 3677 is fixed
104
import org.apache.derby.iapi.services.sanity.AssertFailure;
105
106 import org.apache.derby.iapi.sql.execute.ExecRow;
107 import org.apache.derby.iapi.sql.execute.TupleFilter;
108
109 import org.apache.derby.iapi.services.sanity.SanityManager;
110
111 import org.apache.derby.iapi.services.cache.CacheFactory;
112 import org.apache.derby.iapi.services.cache.CacheManager;
113 import org.apache.derby.iapi.services.cache.Cacheable;
114 import org.apache.derby.iapi.services.cache.CacheableFactory;
115
116 import org.apache.derby.iapi.services.locks.LockFactory;
117 import org.apache.derby.iapi.services.locks.C_LockFactory;
118
119 import org.apache.derby.iapi.services.property.PropertyUtil;
120
121 import org.apache.derby.impl.services.locks.Timeout;
122
123 import org.apache.derby.iapi.services.uuid.UUIDFactory;
124 import org.apache.derby.catalog.AliasInfo;
125 import org.apache.derby.catalog.DefaultInfo;
126 import org.apache.derby.catalog.TypeDescriptor;
127 import org.apache.derby.catalog.UUID;
128 import org.apache.derby.catalog.types.RoutineAliasInfo;
129
130 import org.apache.derby.iapi.services.io.FormatableBitSet;
131 import org.apache.derby.iapi.services.locks.ShExLockable;
132 import org.apache.derby.iapi.services.locks.ShExQual;
133 import org.apache.derby.iapi.util.StringUtil;
134 import org.apache.derby.iapi.util.IdUtil;
135
136 import java.util.Calendar JavaDoc;
137 import java.util.Date JavaDoc;
138 import java.util.GregorianCalendar JavaDoc;
139 import java.util.Hashtable JavaDoc;
140 import java.util.Properties JavaDoc;
141 import java.util.Vector JavaDoc;
142
143 import java.util.List JavaDoc;
144 import java.util.Iterator JavaDoc;
145
146 import java.util.Enumeration JavaDoc;
147 import java.io.InputStream JavaDoc;
148 import java.io.IOException JavaDoc;
149
150 import java.sql.Types JavaDoc;
151
152 /**
153  * This abstract class contains the common code for the "regular" and
154  * limited data dictionaries. The limited configuration puts an upper
155  * limit on the number of tables a user is allowed to create.
156  *
157  * This class provides the entire implementation of DataDictionary,
158  * and ModuleControl, except for the stop()
159  * method, which is to be provided by a non-abstract super-class.
160  * The reason for putting the stop() method in the super-class is to
161  * prevent someone from inadvertently changing this to a non-abstract
162  * class. This class is shipped with both the limited and non-limited
163  * configurations, and we don't want anyone to be able to cheat by
164  * booting this class instead of booting the super-class.
165  */

166
167 public final class DataDictionaryImpl
168     implements DataDictionary, CacheableFactory, ModuleControl, ModuleSupportable,java.security.PrivilegedAction JavaDoc
169 {
170
171     private static final String JavaDoc CFG_SYSTABLES_ID = "SystablesIdentifier";
172     private static final String JavaDoc CFG_SYSTABLES_INDEX1_ID = "SystablesIndex1Identifier";
173     private static final String JavaDoc CFG_SYSTABLES_INDEX2_ID = "SystablesIndex2Identifier";
174     private static final String JavaDoc CFG_SYSCOLUMNS_ID = "SyscolumnsIdentifier";
175     private static final String JavaDoc CFG_SYSCOLUMNS_INDEX1_ID = "SyscolumnsIndex1Identifier";
176     private static final String JavaDoc CFG_SYSCOLUMNS_INDEX2_ID = "SyscolumnsIndex2Identifier";
177     private static final String JavaDoc CFG_SYSCONGLOMERATES_ID = "SysconglomeratesIdentifier";
178     private static final String JavaDoc CFG_SYSCONGLOMERATES_INDEX1_ID = "SysconglomeratesIndex1Identifier";
179     private static final String JavaDoc CFG_SYSCONGLOMERATES_INDEX2_ID = "SysconglomeratesIndex2Identifier";
180     private static final String JavaDoc CFG_SYSCONGLOMERATES_INDEX3_ID = "SysconglomeratesIndex3Identifier";
181     private static final String JavaDoc CFG_SYSSCHEMAS_ID = "SysschemasIdentifier";
182     private static final String JavaDoc CFG_SYSSCHEMAS_INDEX1_ID = "SysschemasIndex1Identifier";
183     private static final String JavaDoc CFG_SYSSCHEMAS_INDEX2_ID = "SysschemasIndex2Identifier";
184
185     private static final int SYSCONGLOMERATES_CORE_NUM = 0;
186     private static final int SYSTABLES_CORE_NUM = 1;
187     private static final int SYSCOLUMNS_CORE_NUM = 2;
188     private static final int SYSSCHEMAS_CORE_NUM = 3;
189     private static final int NUM_CORE = 4;
190     
191     /**
192     * SYSFUN functions. Table of functions that automatically appear
193     * in the SYSFUN schema. These functions are resolved to directly
194     * if no schema name is given, e.g.
195     *
196     * <code>
197     * SELECT COS(angle) FROM ROOM_WALLS
198     * </code>
199     *
200     * Adding a function here is suitable when the function defintion
201     * can have a single return type and fixed parameter types.
202     *
203     * Functions that need to have a return type based upon the
204     * input type(s) are not supported here. Typically those are
205     * added into the parser and methods added into the DataValueDescriptor interface.
206     * Examples are character based functions whose return type
207     * length is based upon the passed in type, e.g. passed a CHAR(10)
208     * returns a CHAR(10).
209     *
210     *
211     * This simple table assumes zero or a single parameter
212     * and RETURNS NULL ON NULL INPUT. The scheme could be expanded
213     * to handle other function options such as other parameters if needed.
214     *[0] = FUNCTION name
215     *[1] = RETURNS type
216     *[2] = Java class
217     *[3] = method name and signature
218     *[4] = parameter type (single parameter) or null for no parameters.
219     *
220     */

221     private static final String JavaDoc[][] SYSFUN_FUNCTIONS = {
222             {"ACOS", "DOUBLE", "java.lang.StrictMath", "acos(double)", "DOUBLE"},
223             {"ASIN", "DOUBLE", "java.lang.StrictMath", "asin(double)", "DOUBLE"},
224             {"ATAN", "DOUBLE", "java.lang.StrictMath", "atan(double)", "DOUBLE"},
225             {"COS", "DOUBLE", "java.lang.StrictMath", "cos(double)", "DOUBLE"},
226             {"SIN", "DOUBLE", "java.lang.StrictMath", "sin(double)", "DOUBLE"},
227             {"TAN", "DOUBLE", "java.lang.StrictMath", "tan(double)", "DOUBLE"},
228             {"PI", "DOUBLE", "org.apache.derby.catalog.SystemProcedures", "PI()", null},
229             {"DEGREES", "DOUBLE", "java.lang.StrictMath", "toDegrees(double)", "DOUBLE"},
230             {"RADIANS", "DOUBLE", "java.lang.StrictMath", "toRadians(double)", "DOUBLE"},
231             {"LN", "DOUBLE", "java.lang.StrictMath", "log(double)", "DOUBLE"},
232             {"LOG", "DOUBLE", "java.lang.StrictMath", "log(double)", "DOUBLE"}, // Same as LN
233
{"LOG10", "DOUBLE", "org.apache.derby.catalog.SystemProcedures", "LOG10(double)", "DOUBLE"},
234             {"EXP", "DOUBLE", "java.lang.StrictMath", "exp(double)", "DOUBLE"},
235             {"CEIL", "DOUBLE", "java.lang.StrictMath", "ceil(double)", "DOUBLE"},
236             {"CEILING", "DOUBLE", "java.lang.StrictMath", "ceil(double)", "DOUBLE"}, // Same as CEIL
237
{"FLOOR", "DOUBLE", "java.lang.StrictMath", "floor(double)", "DOUBLE"},
238     };
239     
240     /**
241      * Runtime definition of the functions from SYSFUN_FUNCTIONS.
242      * Populated dynamically as functions are called.
243      */

244     private static final AliasDescriptor[] SYSFUN_AD =
245         new AliasDescriptor[SYSFUN_FUNCTIONS.length];
246     
247     /**
248      * Dummy parameter name for functions from SYSFUN_FUNCTIONS.
249      */

250     private static final String JavaDoc[] SYSFUN_PNAME = {"P1"};
251     
252     /**
253      * Parameter mode (IN as required) for functions from SYSFUN_FUNCTIONS.
254      */

255     private static final int[] SYSFUN_PMODE = {JDBC30Translation.PARAMETER_MODE_IN};
256
257     // the structure that holds all the core table info
258
private TabInfoImpl[] coreInfo;
259
260     /*
261     ** SchemaDescriptors for system and app schemas. Both
262     ** are canonical. We cache them for fast lookup.
263     */

264     protected SchemaDescriptor systemSchemaDesc;
265     protected SchemaDescriptor sysIBMSchemaDesc;
266     protected SchemaDescriptor declaredGlobalTemporaryTablesSchemaDesc;
267     protected SchemaDescriptor systemDiagSchemaDesc;
268     protected SchemaDescriptor systemUtilSchemaDesc;
269
270     private String JavaDoc systemSchemaName;
271     private String JavaDoc systemDiagSchemaName;
272     private String JavaDoc systemUtilSchemaName;
273     private String JavaDoc sysIBMSchemaName;
274     private String JavaDoc declaredGlobalTemporaryTablesSchemaName;
275     boolean builtinSchemasAreFromLCC;
276
277     protected boolean convertIdToLower;
278     // Convert identifiers to lower case (as in Foundation) or not.
279

280     // This array of non-core table names *MUST* be in the same order
281
// as the non-core table numbers, above.
282
private static final String JavaDoc[] nonCoreNames = {
283                                     "SYSCONSTRAINTS",
284                                     "SYSKEYS",
285                                     "SYSDEPENDS",
286                                     "SYSALIASES",
287                                     "SYSVIEWS",
288                                     "SYSCHECKS",
289                                     "SYSFOREIGNKEYS",
290                                     "SYSSTATEMENTS",
291                                     "SYSFILES",
292                                     "SYSTRIGGERS",
293                                     "SYSSTATISTICS",
294                                     "SYSDUMMY1",
295                                     "SYSTABLEPERMS",
296                                     "SYSCOLPERMS",
297                                     "SYSROUTINEPERMS"
298                                     };
299
300     private static final int NUM_NONCORE = nonCoreNames.length;
301
302     /**
303      * List of all "system" schemas
304      * <p>
305      * This list should contain all schema's used by the system and are
306      * created when the database is created. Users should not be able to
307      * create or drop these schema's and should not be able to create or
308      * drop objects in these schema's. This list is used by code that
309      * needs to check if a particular schema is a "system" schema.
310      **/

311     private static final String JavaDoc[] systemSchemaNames = {
312         SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME,
313         SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,
314         SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME,
315         SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME,
316         SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME,
317         SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME,
318         SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME,
319         SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
320         SchemaDescriptor.STD_SQLJ_SCHEMA_NAME,
321         SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME
322     };
323         
324
325     /** Dictionary version of the on-disk database */
326     private DD_Version dictionaryVersion;
327     /** Dictionary version of the currently running engine */
328     private DD_Version softwareVersion;
329
330     private String JavaDoc authorizationDatabaseOwner;
331     private boolean usesSqlAuthorization;
332
333     /*
334     ** This property and value are written into the database properties
335     ** when the database is created, and are used to determine whether
336     ** the system catalogs need to be upgraded.
337     */

338
339     // the structure that holds all the noncore info
340
private TabInfoImpl[] noncoreInfo;
341
342     // no other system tables have id's in the configuration.
343

344     public DataDescriptorGenerator dataDescriptorGenerator;
345     protected DataValueFactory dvf;
346     protected AccessFactory af;
347     //DataDictionaryContext ddc;
348

349     private ExecutionFactory exFactory;
350     protected UUIDFactory uuidFactory;
351
352     Properties JavaDoc startupParameters;
353     int engineType;
354
355     /* Information about whether or not we are at boot time */
356     protected boolean booting;
357     private TransactionController bootingTC;
358     protected DependencyManager dmgr;
359
360     /* Cache of table descriptors */
361     CacheManager OIDTdCache;
362     CacheManager nameTdCache;
363     private CacheManager spsNameCache;
364     private Hashtable JavaDoc spsIdHash;
365     // private Hashtable spsTextHash;
366
int tdCacheSize;
367     int stmtCacheSize;
368
369     /* Cache of permissions data */
370     CacheManager permissionsCache;
371     int permissionsCacheSize;
372
373     /*
374     ** Lockable object for synchronizing transition from caching to non-caching
375     */

376     ShExLockable cacheCoordinator;
377     public LockFactory lockFactory;
378
379     volatile int cacheMode = DataDictionary.COMPILE_ONLY_MODE;
380
381     /* Number of DDL users */
382     volatile int ddlUsers;
383     /* Number of readers that start in DDL_MODE */
384     volatile int readersInDDLMode;
385
386
387     /**
388         True if the database is read only and requires
389         some form of upgrade, that makes the stored prepared
390         statements invalid.
391         With this case the engine is running at a different
392         version to the underlying stored database. This
393         can happen in 5.1 if the database is read only
394         and a different point release (later than 5.1.25?)
395         to the one that created it, has been booted. (Beetle 5170).
396
397         <P>
398         In 5.2 and newer this will be the case if the engine
399         booting the database is newer than the engine
400         that created it.
401
402     */

403     public boolean readOnlyUpgrade;
404
405     //systemSQLNameNumber is the number used as the last digit during the previous call to getSystemSQLName.
406
//If it is 9 for a given calendarForLastSystemSQLName, we will restart the counter to 0
407
//and increment the calendarForLastSystemSQLName by 10ms.
408
private int systemSQLNameNumber;
409     private GregorianCalendar JavaDoc calendarForLastSystemSQLName = new GregorianCalendar JavaDoc();
410     private long timeForLastSystemSQLName;
411     
412     /**
413      * List of procedures in SYSCS_UTIL schema with PUBLIC access
414      */

415     private static final String JavaDoc[] sysUtilProceduresWithPublicAccess = {
416                                                 "SYSCS_SET_RUNTIMESTATISTICS",
417                                                 "SYSCS_SET_STATISTICS_TIMING",
418                                                 "SYSCS_INPLACE_COMPRESS_TABLE",
419                                                 "SYSCS_COMPRESS_TABLE",
420                                                 };
421     
422     /**
423      * List of functions in SYSCS_UTIL schema with PUBLIC access
424      */

425     private static final String JavaDoc[] sysUtilFunctionsWithPublicAccess = {
426                                                 "SYSCS_GET_RUNTIMESTATISTICS",
427                                                 };
428     
429     /*
430     ** Constructor
431     */

432
433     public DataDictionaryImpl() {
434         
435     }
436
437
438     /**
439       Currently, all this routine does is check to see if the Replication
440       property has been turned on for this database. If so, then this is not
441       the NodeFactory that's wanted--so we return false. The NodeFactory that
442       is wanted is our child class "RepNodeFactory".
443
444       @return true if this database does not want Replication
445                 false otherwise
446       */

447
448     public boolean canSupport(Properties JavaDoc startParams)
449     {
450         return Monitor.isDesiredType( startParams, org.apache.derby.iapi.reference.EngineType.NONE );
451     }
452
453     /**
454      * Start-up method for this instance of the data dictionary.
455      *
456      * @param startParams The start-up parameters
457      *
458      * @exception StandardException Thrown if the module fails to start
459      */

460     public void boot(boolean create, Properties JavaDoc startParams)
461             throws StandardException
462     {
463         softwareVersion = new DD_Version(this, DataDictionary.DD_VERSION_DERBY_10_2);
464
465         /* There is a bootstrapping problem here. We would like to use
466          * a language connection context to find the name of the system and default
467          * schemas. However a language connection context is not available when a
468          * database is being created, as it is when this method is called. So,
469          * this method must look at the params properties to discover the identifier
470          * casing and convert the standard names as necessary, essentially duplicating
471          * logic found in GenericLanguageConnectionContext.
472          */

473         convertIdToLower = false;
474
475         startupParameters = startParams;
476
477         uuidFactory = Monitor.getMonitor().getUUIDFactory();
478
479         engineType = Monitor.getEngineType( startParams );
480
481         // REMIND: actually, we're supposed to get the DataValueFactory
482
// out of the connection context...this is a bit of a shortcut.
483
// We get the DataValueFactory early in order to help bootstrap the system catalogs.
484
LanguageConnectionFactory langConnFactory = (LanguageConnectionFactory) Monitor.bootServiceModule(
485             create, this, LanguageConnectionFactory.MODULE, startParams);
486
487         dvf = langConnFactory.getDataValueFactory();
488         exFactory = (ExecutionFactory) Monitor.bootServiceModule(
489                                                         create, this,
490                                                         ExecutionFactory.MODULE,
491                                                         startParams);
492
493         // initailze the arrays of core and noncore tables
494
initializeCatalogInfo();
495
496         // indicate that we are in the process of booting
497
booting = true;
498
499         // set only if child class hasn't overriden this already
500
if ( dataDescriptorGenerator == null )
501         { dataDescriptorGenerator = new DataDescriptorGenerator( this ); }
502
503         if (!create) {
504
505
506             // SYSTABLES
507

508             coreInfo[SYSTABLES_CORE_NUM].setHeapConglomerate(
509                     getBootParameter(startParams, CFG_SYSTABLES_ID, true));
510
511             coreInfo[SYSTABLES_CORE_NUM].setIndexConglomerate(SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
512                     getBootParameter(startParams, CFG_SYSTABLES_INDEX1_ID, true));
513
514
515             coreInfo[SYSTABLES_CORE_NUM].setIndexConglomerate(
516                     SYSTABLESRowFactory.SYSTABLES_INDEX2_ID,
517                     getBootParameter(startParams, CFG_SYSTABLES_INDEX2_ID, true));
518
519             // SYSCOLUMNS
520

521             coreInfo[SYSCOLUMNS_CORE_NUM].setHeapConglomerate(
522                     getBootParameter(startParams, CFG_SYSCOLUMNS_ID, true));
523
524
525             coreInfo[SYSCOLUMNS_CORE_NUM].setIndexConglomerate(
526                     SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID,
527                     getBootParameter(startParams, CFG_SYSCOLUMNS_INDEX1_ID, true));
528             // 2nd syscolumns index added in Xena, hence may not be there
529
coreInfo[SYSCOLUMNS_CORE_NUM].setIndexConglomerate(
530                     SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX2_ID,
531                     getBootParameter(startParams, CFG_SYSCOLUMNS_INDEX2_ID, false));
532
533             // SYSCONGLOMERATES
534

535             coreInfo[SYSCONGLOMERATES_CORE_NUM].setHeapConglomerate(
536                     getBootParameter(startParams, CFG_SYSCONGLOMERATES_ID, true));
537
538
539             coreInfo[SYSCONGLOMERATES_CORE_NUM].setIndexConglomerate(
540                     SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
541                     getBootParameter(startParams, CFG_SYSCONGLOMERATES_INDEX1_ID, true));
542
543
544             coreInfo[SYSCONGLOMERATES_CORE_NUM].setIndexConglomerate(
545                     SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID,
546                     getBootParameter(startParams, CFG_SYSCONGLOMERATES_INDEX2_ID, true));
547
548             coreInfo[SYSCONGLOMERATES_CORE_NUM].setIndexConglomerate(
549                     SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID,
550                     getBootParameter(startParams, CFG_SYSCONGLOMERATES_INDEX3_ID, true));
551
552
553             // SYSSCHEMAS
554
coreInfo[SYSSCHEMAS_CORE_NUM].setHeapConglomerate(
555                     getBootParameter(startParams, CFG_SYSSCHEMAS_ID, true));
556
557
558             coreInfo[SYSSCHEMAS_CORE_NUM].setIndexConglomerate(
559                     SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID,
560                     getBootParameter(startParams, CFG_SYSSCHEMAS_INDEX1_ID, true));
561
562             coreInfo[SYSSCHEMAS_CORE_NUM].setIndexConglomerate(
563                     SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX2_ID,
564                     getBootParameter(startParams, CFG_SYSSCHEMAS_INDEX2_ID, true));
565
566         }
567
568
569
570         String JavaDoc value = startParams.getProperty(Property.LANG_TD_CACHE_SIZE);
571         tdCacheSize = PropertyUtil.intPropertyValue(Property.LANG_TD_CACHE_SIZE, value,
572                                        0, Integer.MAX_VALUE, Property.LANG_TD_CACHE_SIZE_DEFAULT);
573
574         
575         value = startParams.getProperty(Property.LANG_SPS_CACHE_SIZE);
576         stmtCacheSize = PropertyUtil.intPropertyValue(Property.LANG_SPS_CACHE_SIZE, value,
577                                        0, Integer.MAX_VALUE, Property.LANG_SPS_CACHE_SIZE_DEFAULT);
578
579         value = startParams.getProperty(Property.LANG_PERMISSIONS_CACHE_SIZE);
580         permissionsCacheSize = PropertyUtil.intPropertyValue(Property.LANG_PERMISSIONS_CACHE_SIZE, value,
581                                        0, Integer.MAX_VALUE, Property.LANG_PERMISSIONS_CACHE_SIZE_DEFAULT);
582
583
584         /*
585          * data dictionary contexts are only associated with connections.
586          * we have to look for the basic data dictionary, as there is
587          * no connection, and thus no context stack yet.
588          */

589
590         /*
591          * Get the table descriptor cache.
592          */

593         CacheFactory cf =
594                 (CacheFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
595         OIDTdCache =
596             cf.newCacheManager(this,
597                 "TableDescriptorOIDCache",
598                 tdCacheSize,
599                 tdCacheSize);
600         nameTdCache =
601             cf.newCacheManager(this,
602                 "TableDescriptorNameCache",
603                 tdCacheSize,
604                 tdCacheSize);
605
606         if (stmtCacheSize > 0)
607         {
608             spsNameCache =
609                 cf.newCacheManager(this,
610                     "SPSNameDescriptorCache",
611                     stmtCacheSize,
612                     stmtCacheSize);
613             spsIdHash = new Hashtable JavaDoc(stmtCacheSize);
614             // spsTextHash = new Hashtable(stmtCacheSize);
615
}
616
617
618         /* Get the object to coordinate cache transitions */
619         cacheCoordinator = new ShExLockable();
620
621         /* Get AccessFactory in order to transaction stuff */
622         af = (AccessFactory) Monitor.findServiceModule(this, AccessFactory.MODULE);
623
624         /* Get the lock factory */
625         lockFactory = af.getLockFactory();
626
627         /*
628          * now we need to setup a context stack for the database creation work.
629          * We assume the System boot process has created a context
630          * manager already, but not that contexts we need are there.
631          */

632         ContextService csf = ContextService.getFactory();
633
634         ContextManager cm = csf.getCurrentContextManager();
635         if (SanityManager.DEBUG)
636             SanityManager.ASSERT((cm != null), "Failed to get current ContextManager");
637
638         /* push a datadictionary context onto this stack */
639         pushDataDictionaryContext(cm);
640
641         // RESOLVE other non-StandardException errors.
642
bootingTC = null;
643         try
644         {
645             // Get a transaction controller. This has the side effect of
646
// creating a transaction context if there isn't one already.
647
bootingTC = af.getTransaction(cm);
648
649             /*
650                 We need an execution context so that we can generate rows
651                 REMIND: maybe only for create case?
652              */

653             exFactory.newExecutionContext(cm);
654
655             DataDescriptorGenerator ddg = getDataDescriptorGenerator();
656     
657             if (create) {
658                 String JavaDoc userName = IdUtil.getUserNameFromURLProps(startParams);
659                 authorizationDatabaseOwner = IdUtil.getUserAuthorizationId(userName);
660             
661                 // create any required tables.
662
createDictionaryTables(startParams, bootingTC, ddg);
663                 //create procedures for network server metadata
664
create_SYSIBM_procedures(bootingTC);
665                 //create metadata sps statement required for network server
666
createSystemSps(bootingTC);
667                 // create the SYSCS_UTIL system procedures)
668
create_SYSCS_procedures(bootingTC);
669                 // log the current dictionary version
670
dictionaryVersion = softwareVersion;
671
672                 /* Set properties for current and create time
673                  * DataDictionary versions.
674                  */

675                 bootingTC.setProperty(
676                     DataDictionary.CORE_DATA_DICTIONARY_VERSION,
677                     dictionaryVersion, true);
678
679                 bootingTC.setProperty(
680                     DataDictionary.CREATE_DATA_DICTIONARY_VERSION,
681                     dictionaryVersion, true);
682
683                 // If SqlAuthorization is set as system property during database
684
// creation, set it as database property also, so it gets persisted.
685
if (PropertyUtil.getSystemBoolean(Property.SQL_AUTHORIZATION_PROPERTY))
686                 {
687                     bootingTC.setProperty(Property.SQL_AUTHORIZATION_PROPERTY,"true",true);
688                     usesSqlAuthorization=true;
689                 }
690
691             } else {
692                 // Get the ids for non-core tables
693
loadDictionaryTables(bootingTC, ddg, startParams);
694                 SchemaDescriptor sd = locateSchemaRow(SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
695                                  bootingTC);
696                 authorizationDatabaseOwner = sd.getAuthorizationId();
697                 String JavaDoc sqlAuth = PropertyUtil.getDatabaseProperty(bootingTC,
698                                         Property.SQL_AUTHORIZATION_PROPERTY);
699                 if (Boolean.valueOf(sqlAuth).booleanValue())
700                 {
701                     // SQL authorization requires 10.2 or higher database
702
checkVersion(DataDictionary.DD_VERSION_DERBY_10_2, "sqlAuthorization");
703                     usesSqlAuthorization=true;
704                 }
705             }
706                     
707             if (SanityManager.DEBUG)
708                 SanityManager.ASSERT((authorizationDatabaseOwner != null), "Failed to get Database Owner authorization");
709
710             /* Commit & destroy the create database */
711             bootingTC.commit();
712             cm.getContext(ExecutionContext.CONTEXT_ID).popMe(); // done with ctx
713
} finally {
714
715             if (bootingTC != null) {
716                 bootingTC.destroy(); // gets rid of the transaction context
717
bootingTC = null;
718             }
719             cm.popContext(); // the data dictionary context; check that it is?
720
}
721     
722         setDependencyManager();
723         booting = false;
724     }
725
726     private CacheManager getPermissionsCache() throws StandardException
727     {
728         if( permissionsCache == null)
729         {
730             CacheFactory cf =
731               (CacheFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
732             LanguageConnectionContext lcc = getLCC();
733             TransactionController tc = lcc.getTransactionExecute();
734             permissionsCacheSize = PropertyUtil.getServiceInt( tc,
735                                                                Property.LANG_PERMISSIONS_CACHE_SIZE,
736                                                                40, /* min value */
737                                                                Integer.MAX_VALUE,
738                                                                permissionsCacheSize /* value from boot time. */);
739             permissionsCache = cf.newCacheManager( this,
740                                                    "PermissionsCache",
741                                                    permissionsCacheSize,
742                                                    permissionsCacheSize);
743         }
744         return permissionsCache;
745     } // end of getPermissionsCache
746

747     /**
748      * sets the dependencymanager associated with this dd. subclasses can
749      * override this to install their own funky dependency manager.
750      */

751     protected void setDependencyManager()
752     {
753         dmgr = new BasicDependencyManager();
754     }
755
756     /**
757      * returns the dependencymanager associated with this datadictionary.
758      * @see DataDictionary#getDependencyManager
759      */

760     public DependencyManager getDependencyManager()
761     {
762         return dmgr;
763     }
764
765     /**
766      * Stop this module. In this case, nothing needs to be done.
767      */

768
769     public void stop()
770     {
771     }
772
773     /*
774     ** CacheableFactory interface
775     */

776     public Cacheable newCacheable(CacheManager cm) {
777
778         if (cm == OIDTdCache)
779             return new OIDTDCacheable(this);
780         else if (cm == nameTdCache)
781             return new NameTDCacheable(this);
782         else if( cm == permissionsCache)
783             return new PermissionsCacheable(this);
784         else {
785             return new SPSNameCacheable(this);
786         }
787     }
788
789     /*
790     ** Methods related to ModuleControl
791     */

792
793     /**
794      * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#startReading
795      *
796      * @exception StandardException Thrown on error
797      */

798     public int startReading(LanguageConnectionContext lcc)
799         throws StandardException
800     {
801         int bindCount = lcc.incrementBindCount();
802         int localCacheMode;
803
804         boolean needRetry = false;
805
806         do
807         {
808             if (needRetry)
809             {
810                 // could not get lock while holding the synchronized(this),
811
// so now wait until we can get the lock. Once we get the
812
// lock it is automatically released, hopefully when we
813
// go the the synchronized(this) block we will be able to
814
// get the lock, while holding the synchronized(this)
815
// monitor now.
816

817                 try
818                 {
819                     lockFactory.zeroDurationlockObject(
820                         lcc.getTransactionExecute().getLockObject(),
821                         cacheCoordinator,
822                         ShExQual.SH,
823                         C_LockFactory.WAIT_FOREVER);
824                 }
825                 catch (StandardException e)
826                 {
827                     // DEADLOCK, timeout will not happen with WAIT_FOREVER
828

829                     lcc.decrementBindCount();
830                     throw e;
831                 }
832                 needRetry = false;
833             }
834
835             // "this" is used to synchronize between startReading,doneReading,
836
// and startWriting.
837

838             synchronized(this)
839             {
840                 localCacheMode = getCacheMode();
841
842                 /*
843                 ** Keep track of how deeply nested this bind() operation is.
844                 ** It's possible for nested binding to happen if the user
845                 ** prepares SQL statements from within a static initializer
846                 ** of a class, and calls a method on that class (or uses a
847                 ** field in the class).
848                 **
849                 ** If nested binding is happening, we only want to lock the
850                 ** DataDictionary on the outermost nesting level.
851                 */

852                 if (bindCount == 1)
853                 {
854                     if (localCacheMode == DataDictionary.COMPILE_ONLY_MODE)
855                     {
856                         if (SanityManager.DEBUG)
857                         {
858                             SanityManager.ASSERT(ddlUsers == 0,
859                                 "Cache mode is COMPILE_ONLY and there are DDL users.");
860                         }
861
862                         /*
863                         ** If we deadlock while waiting for a lock,
864                         ** then be sure to restore things as they
865                         ** were.
866                         */

867                         boolean lockGranted = false;
868
869                         try
870                         {
871                             // When the C_LockFactory.NO_WAIT is used this
872
// routine will not throw timeout or deadlock
873
// exceptions. The boolean returned will indicate
874
// if the lock was granted or not. If it would
875
// have had to wait, it just returns immediately
876
// and returns false.
877
//
878
// See if we can get this lock granted without
879
// waiting (while holding the dataDictionary
880
// synchronization).
881

882                             lockGranted =
883                                 lockFactory.lockObject(
884                                     lcc.getTransactionExecute().getLockObject(),
885                                     lcc.getTransactionExecute().getLockObject(),
886                                     cacheCoordinator,
887                                     ShExQual.SH,
888                                     C_LockFactory.NO_WAIT);
889                         }
890                         catch (StandardException e)
891                         {
892                             // neither TIMEOUT or DEADLOCK can happen with
893
// NO_WAIT flag. This must be some other exception.
894

895                             lcc.decrementBindCount();
896                             throw e;
897                         }
898
899                         if (!lockGranted)
900                             needRetry = true;
901                     }
902                     else
903                     {
904                         readersInDDLMode++;
905                     }
906                 }
907             } // end of sync block
908

909         } while (needRetry);
910
911         return localCacheMode;
912     }
913
914     /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#doneReading */
915     public void doneReading(int mode, LanguageConnectionContext lcc)
916         throws StandardException
917     {
918         int bindCount = lcc.decrementBindCount();
919
920         /* This is an arbitrary choice of object to synchronize these methods */
921         synchronized(this)
922         {
923             /*
924             ** Keep track of how deeply nested this bind() operation is.
925             ** It's possible for nested binding to happen if the user
926             ** prepares SQL statements from within a static initializer
927             ** of a class, and calls a method on that class (or uses a
928             ** field in the class).
929             **
930             ** If nested binding is happening, we only want to unlock the
931             ** DataDictionary on the outermost nesting level.
932             */

933             if (bindCount == 0)
934             {
935                 if (mode == DataDictionary.COMPILE_ONLY_MODE)
936                 {
937                     /*
938                     ** Release the share lock that was acquired by the reader when
939                     ** it called startReading().
940                     ** Beetle 4418, during bind, we may even execute something (eg., in a vti
941                     ** constructor) and if a severe error occured, the transaction is rolled
942                     ** back and lock released already, so don't try to unlock if statement context
943                     ** is cleared.
944                     */

945                     if ((lcc.getStatementContext() != null) && lcc.getStatementContext().inUse())
946                     {
947                         int unlockCount = lockFactory.unlock(lcc.getTransactionExecute().getLockObject(),
948                                         lcc.getTransactionExecute().getLockObject(),
949                                         cacheCoordinator,
950                                         ShExQual.SH);
951                         if (SanityManager.DEBUG)
952                         {
953                             if (unlockCount != 1)
954                             {
955                                 SanityManager.THROWASSERT("unlockCount not "+
956                                     "1 as expected, it is "+unlockCount);
957                             }
958                         }
959                     }
960                 }
961                 else
962                 {
963                     readersInDDLMode--;
964
965                     /*
966                     ** We can only switch back to cached (COMPILE_ONLY)
967                     ** mode if there aren't any readers that started in
968                     ** DDL_MODE. Otherwise we could get a reader
969                     ** in DDL_MODE that reads a cached object that
970                     ** was brought in by a reader in COMPILE_ONLY_MODE.
971                     ** If 2nd reader finished and releases it lock
972                     ** on the cache there is nothing to pevent another
973                     ** writer from coming along an deleting the cached
974                     ** object.
975                     */

976                     if (ddlUsers == 0 && readersInDDLMode == 0)
977                     {
978                         clearCaches();
979                         setCacheMode(DataDictionary.COMPILE_ONLY_MODE);
980                     }
981
982                     if (SanityManager.DEBUG)
983                     {
984                         SanityManager.ASSERT(readersInDDLMode >= 0,
985                             "readersInDDLMode is invalid -- should never be < 0");
986                     }
987                 }
988             }
989         }
990     }
991
992     /*
993      * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#startWriting
994      *
995      * @exception StandardException Thrown on error
996      */

997     public void startWriting(LanguageConnectionContext lcc)
998         throws StandardException
999     {
1000
1001        boolean blocked = true;
1002    
1003        /*
1004        ** Don't allow DDL if we're binding a SQL statement.
1005        */

1006        if (lcc.getBindCount() != 0)
1007        {
1008            throw StandardException.newException(SQLState.LANG_DDL_IN_BIND);
1009        }
1010    
1011        /*
1012        ** Check whether we've already done a DDL statement in this
1013        ** transaction. If so, we don't want to re-enter DDL mode, or
1014        ** bump the DDL user count.
1015        */

1016        if ( ! lcc.dataDictionaryInWriteMode())
1017        {
1018            for (int i = 0; blocked; i++)
1019            {
1020                /*
1021                ** If we already tried 5 times and failed, do
1022                ** an unbounded wait for the lock w/o
1023                ** synchronization. Immediately unlock and
1024                ** sleep a random amount of time and start
1025                ** the whole process over again.
1026                */

1027                if (i > 4 &&
1028                    getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)
1029                {
1030                    // Wait until the settable timeout value for the lock,
1031
// and once granted, immediately release the lock. If
1032
// this wait time's out then a TIMEOUT error is sent
1033
// up the stack.
1034

1035                    lockFactory.zeroDurationlockObject(
1036                        lcc.getTransactionExecute().getLockObject(),
1037                        cacheCoordinator,
1038                        ShExQual.EX,
1039                        C_LockFactory.TIMED_WAIT);
1040
1041
1042                    i = 1;
1043                }
1044
1045                if (i > 0)
1046                {
1047                    try
1048                    {
1049                        Thread.sleep(
1050                            (long)((java.lang.Math.random() * 1131) % 20));
1051                    }
1052                    catch (InterruptedException JavaDoc ie)
1053                    {
1054                        throw StandardException.interrupt(ie);
1055                    }
1056                }
1057
1058                synchronized(this)
1059                {
1060                    if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)
1061                    {
1062                        // When the C_LockFactory.NO_WAIT is used this routine
1063
// will not throw timeout or deadlock exceptions. The
1064
// boolean returned will indicate if the lock was
1065
// granted or not. If it would have had to wait, it
1066
// just returns immediately and returns false.
1067
//
1068

1069                        // See if we can get this lock granted without waiting
1070
// (while holding the dataDictionary synchronization).
1071

1072                        boolean lockGranted =
1073                            lockFactory.zeroDurationlockObject(
1074                                lcc.getTransactionExecute().getLockObject(),
1075                                cacheCoordinator,
1076                                ShExQual.EX,
1077                                C_LockFactory.NO_WAIT);
1078
1079                        if (!lockGranted)
1080                            continue;
1081
1082                        /* Switch the caching mode to DDL */
1083                        setCacheMode(DataDictionary.DDL_MODE);
1084    
1085                        /* Clear out all the caches */
1086                        clearCaches();
1087                    }
1088        
1089                    /* Keep track of the number of DDL users */
1090                    ddlUsers++;
1091                } // end synchronized
1092

1093                /*
1094                ** Tell the connection the DD is in DDL mode, so it can take
1095                ** it out of DDL mode when the transaction finishes.
1096                */

1097                lcc.setDataDictionaryWriteMode();
1098                blocked = false;
1099            }
1100
1101        }
1102        else if (SanityManager.DEBUG)
1103        {
1104            SanityManager.ASSERT(getCacheMode() == DataDictionary.DDL_MODE,
1105                "lcc.getDictionaryInWriteMode() but DataDictionary is COMPILE_MODE");
1106        }
1107    }
1108
1109
1110    /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#transactionFinished */
1111    public void transactionFinished() throws StandardException
1112    {
1113        /* This is an arbitrary choice of object to synchronize these methods */
1114        synchronized(this)
1115        {
1116            if (SanityManager.DEBUG)
1117            {
1118                SanityManager.ASSERT(ddlUsers > 0,
1119                    "Number of DDL Users is <= 0 when finishing a transaction");
1120
1121                SanityManager.ASSERT(getCacheMode() == DataDictionary.DDL_MODE,
1122                    "transactionFinished called when not in DDL_MODE");
1123            }
1124
1125            ddlUsers--;
1126
1127            /*
1128            ** We can only switch back to cached (COMPILE_ONLY)
1129            ** mode if there aren't any readers that started in
1130            ** DDL_MODE. Otherwise we could get a reader
1131            ** in DDL_MODE that reads a cached object that
1132            ** was brought in by a reader in COMPILE_ONLY_MODE.
1133            ** If 2nd reader finished and releases it lock
1134            ** on the cache there is nothing to pevent another
1135            ** writer from coming along an deleting the cached
1136            ** object.
1137            */

1138            if (ddlUsers == 0 && readersInDDLMode == 0)
1139            {
1140                clearCaches();
1141                setCacheMode(DataDictionary.COMPILE_ONLY_MODE);
1142            }
1143
1144        }
1145    }
1146
1147    /*
1148    ** SYNCHRONIZATION: no synchronization
1149    ** necessary since integer reads/writes
1150    ** are atomic
1151    */

1152    public int getCacheMode()
1153    {
1154        return cacheMode;
1155    }
1156
1157    /*
1158    ** SYNCHRONIZATION: no synchronization
1159    ** necessary since integer reads/writes
1160    ** are atomic
1161    */

1162    private void setCacheMode(int newMode)
1163    {
1164        cacheMode = newMode;
1165    }
1166
1167    /**
1168     * Get a DataDescriptorGenerator, through which we can create
1169     * objects to be stored in the DataDictionary.
1170     *
1171     * @return A DataDescriptorGenerator
1172     */

1173
1174    public DataDescriptorGenerator getDataDescriptorGenerator()
1175    {
1176        return dataDescriptorGenerator;
1177    }
1178
1179    /**
1180     * Get authorizationID of Database Owner
1181     *
1182     * @return authorizationID
1183     */

1184    public String JavaDoc getAuthorizationDatabaseOwner()
1185    {
1186        return authorizationDatabaseOwner;
1187    }
1188
1189    /**
1190     * @see DataDictionary#usesSqlAuthorization
1191     */

1192    public boolean usesSqlAuthorization()
1193    {
1194        return usesSqlAuthorization;
1195    }
1196
1197    /**
1198     * Get a DataValueFactory, through which we can create
1199     * data value objects.
1200     *
1201     * @return A DataValueFactory
1202     */

1203    public DataValueFactory getDataValueFactory()
1204    {
1205        return dvf;
1206    }
1207
1208    /**
1209     * Get ExecutionFactory associated with this database.
1210     *
1211     * @return The ExecutionFactory
1212     */

1213    public ExecutionFactory getExecutionFactory()
1214    {
1215        return exFactory;
1216    }
1217
1218    /**
1219     * @see DataDictionary#pushDataDictionaryContext
1220     */

1221    public DataDictionaryContext pushDataDictionaryContext(ContextManager contextManager)
1222    {
1223        DataDictionaryContextImpl dataDictionaryContextImpl =
1224            new DataDictionaryContextImpl(contextManager, this);
1225
1226        return dataDictionaryContextImpl;
1227    }
1228
1229
1230    /* We defer getting the builtin schemas (system and default) past boot time so that
1231     * the language connection context will be available.
1232     */

1233    private void getBuiltinSchemaNames() throws StandardException
1234    {
1235        if( builtinSchemasAreFromLCC)
1236            return;
1237        
1238        LanguageConnectionContext lcc = getLCC();
1239        if( null == lcc)
1240        {
1241            systemSchemaName = SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME;
1242            sysIBMSchemaName = SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME;
1243
1244            systemDiagSchemaName =
1245                SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME;
1246            systemUtilSchemaName =
1247                SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME;
1248            declaredGlobalTemporaryTablesSchemaName =
1249                SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME;
1250        }
1251        else
1252        {
1253            systemSchemaName = lcc.getSystemSchemaName();
1254            sysIBMSchemaName = lcc.getSysIBMSchemaName();
1255            systemDiagSchemaName = lcc.getSystemDiagSchemaName();
1256            systemUtilSchemaName = lcc.getSystemUtilSchemaName();
1257            declaredGlobalTemporaryTablesSchemaName =
1258                lcc.getDeclaredGlobalTemporaryTablesSchemaName();
1259
1260            builtinSchemasAreFromLCC = true;
1261        }
1262    }
1263
1264    private void getBuiltinSchemas() throws StandardException
1265    {
1266        if( builtinSchemasAreFromLCC
1267            && null != systemSchemaDesc
1268            && null != sysIBMSchemaDesc
1269            && null != systemDiagSchemaDesc
1270            && null != systemUtilSchemaDesc
1271            && null != declaredGlobalTemporaryTablesSchemaDesc)
1272            return;
1273
1274        getBuiltinSchemaNames();
1275
1276        systemSchemaDesc =
1277            newSystemSchemaDesc(
1278                systemSchemaName, SchemaDescriptor.SYSTEM_SCHEMA_UUID);
1279        sysIBMSchemaDesc =
1280            newSystemSchemaDesc(
1281                sysIBMSchemaName, SchemaDescriptor.SYSIBM_SCHEMA_UUID);
1282        systemDiagSchemaDesc =
1283            newSystemSchemaDesc(
1284                systemDiagSchemaName, SchemaDescriptor.SYSCS_DIAG_SCHEMA_UUID);
1285        systemUtilSchemaDesc =
1286            newSystemSchemaDesc(
1287                systemUtilSchemaName, SchemaDescriptor.SYSCS_UTIL_SCHEMA_UUID);
1288
1289        declaredGlobalTemporaryTablesSchemaDesc =
1290            newDeclaredGlobalTemporaryTablesSchemaDesc(
1291                declaredGlobalTemporaryTablesSchemaName);
1292    }
1293
1294    /**
1295     * Get the descriptor for the system schema. Schema descriptors include
1296     * authorization ids and schema ids.
1297     *
1298     * SQL92 allows a schema to specify a default character set - we will
1299     * not support this.
1300     *
1301     * @return The descriptor for the schema.
1302     *
1303     * @exception StandardException Thrown on failure
1304     */

1305    public SchemaDescriptor getSystemSchemaDescriptor()
1306                        throws StandardException
1307    {
1308        getBuiltinSchemas();
1309        return systemSchemaDesc;
1310    }
1311
1312
1313    /**
1314     * Get the descriptor for the SYSCS_UTIL system schema.
1315     * Schema descriptors include authorization ids and schema ids.
1316     *
1317     * SQL92 allows a schema to specify a default character set - we will
1318     * not support this.
1319     *
1320     * @return The descriptor for the schema.
1321     *
1322     * @exception StandardException Thrown on failure
1323     */

1324    public SchemaDescriptor getSystemUtilSchemaDescriptor()
1325                        throws StandardException
1326    {
1327        getBuiltinSchemas();
1328        return(systemUtilSchemaDesc);
1329    }
1330
1331    /**
1332     * Get the descriptor for the SYSCS_DIAG system schema.
1333     * Schema descriptors include authorization ids and schema ids.
1334     *
1335     * SQL92 allows a schema to specify a default character set - we will
1336     * not support this.
1337     *
1338     * @return The descriptor for the schema.
1339     *
1340     * @exception StandardException Thrown on failure
1341     */

1342    public SchemaDescriptor getSystemDiagSchemaDescriptor()
1343                        throws StandardException
1344    {
1345        getBuiltinSchemas();
1346        return(systemDiagSchemaDesc);
1347    }
1348
1349    /**
1350     * Get the descriptor for the SYSIBM schema. Schema descriptors include
1351     * authorization ids and schema ids.
1352     *
1353     * SQL92 allows a schema to specify a default character set - we will
1354     * not support this.
1355     *
1356     * @return The descriptor for the schema.
1357     *
1358     * @exception StandardException Thrown on failure
1359     */

1360    public SchemaDescriptor getSysIBMSchemaDescriptor()
1361                        throws StandardException
1362    {
1363        getBuiltinSchemas();
1364        return sysIBMSchemaDesc;
1365    }
1366
1367    /**
1368     * Get the descriptor for the declared global temporary table schema which
1369     * is always named "SESSION".
1370     *
1371     * @return The descriptor for the schema.
1372     *
1373     * @exception StandardException Thrown on failure
1374     */

1375    public SchemaDescriptor getDeclaredGlobalTemporaryTablesSchemaDescriptor()
1376        throws StandardException
1377    {
1378        getBuiltinSchemas();
1379        return declaredGlobalTemporaryTablesSchemaDesc;
1380    }
1381    
1382    /**
1383     * Determine whether a string is the name of the system schema.
1384     *
1385     * @param name
1386     * @return true or false
1387     *
1388     * @exception StandardException Thrown on failure
1389     */

1390    public boolean isSystemSchemaName( String JavaDoc name)
1391        throws StandardException
1392    {
1393        getBuiltinSchemaNames();
1394
1395        boolean ret_val = false;
1396
1397        for (int i = systemSchemaNames.length - 1; i >= 0;)
1398        {
1399            if ((ret_val = systemSchemaNames[i--].equals(name)))
1400                break;
1401        }
1402            
1403        return(ret_val);
1404    }
1405
1406    /**
1407     * Get the descriptor for the named schema.
1408     * Schema descriptors include authorization ids and schema ids.
1409     * SQL92 allows a schema to specify a default character set - we will
1410     * not support this. Will check default schema for a match
1411     * before scanning a system table.
1412     *
1413     * @param schemaName The name of the schema we're interested in. Must not be null.
1414     * @param tc TransactionController
1415     *
1416     * @param raiseError whether an exception should be thrown if the schema does not exist.
1417     *
1418     * @return The descriptor for the schema. Can be null (not found) if raiseError is false.
1419     *
1420     * @exception StandardException Thrown on error
1421     */

1422    public SchemaDescriptor getSchemaDescriptor(String JavaDoc schemaName,
1423                                                TransactionController tc,
1424                                                boolean raiseError)
1425        throws StandardException
1426    {
1427        /*
1428        ** Check for APP and SYS schemas before going any
1429        ** further.
1430        */

1431    
1432        if ( tc == null )
1433        {
1434            tc = getTransactionCompile();
1435        }
1436
1437        if (getSystemSchemaDescriptor().getSchemaName().equals(schemaName))
1438        {
1439            return getSystemSchemaDescriptor();
1440        }
1441        else if (getSysIBMSchemaDescriptor().getSchemaName().equals(schemaName))
1442        {
1443            // oh you are really asking SYSIBM, if this db is soft upgraded
1444
// from pre 52, I may have 2 versions for you, one on disk
1445
// (user SYSIBM), one imaginary (builtin). The
1446
// one on disk (real one, if it exists), should always be used.
1447
if (dictionaryVersion.checkVersion(
1448                        DataDictionary.DD_VERSION_CS_5_2, null))
1449            {
1450                return getSysIBMSchemaDescriptor();
1451            }
1452        }
1453
1454        /*
1455        ** Manual lookup
1456        */

1457        SchemaDescriptor sd = locateSchemaRow(schemaName, tc);
1458
1459        //if no schema found and schema name is SESSION, then create an
1460
//in-memory schema descriptor
1461
if (sd == null &&
1462            getDeclaredGlobalTemporaryTablesSchemaDescriptor().getSchemaName().equals(schemaName))
1463        {
1464            return getDeclaredGlobalTemporaryTablesSchemaDescriptor();
1465        }
1466
1467        if (sd == null && raiseError)
1468        {
1469            throw StandardException.newException(
1470                    SQLState.LANG_SCHEMA_DOES_NOT_EXIST, schemaName);
1471        }
1472        else
1473        {
1474            return sd;
1475        }
1476    }
1477        
1478    /**
1479     * Get the target schema by searching for a matching row
1480     * in SYSSCHEMAS by schemaId. Read only scan.
1481     *
1482     * @param schemaId The id of the schema we're interested in.
1483     * If non-null, overrides schemaName
1484     *
1485     * @param tc TransactionController. If null, one
1486     * is gotten off of the language connection context.
1487     *
1488     * @return The row for the schema
1489     *
1490     * @exception StandardException Thrown on error
1491     */

1492    private SchemaDescriptor locateSchemaRow(UUID schemaId,
1493                                TransactionController tc)
1494        throws StandardException
1495    {
1496        DataValueDescriptor UUIDStringOrderable;
1497        TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1498
1499        /* Use UUIDStringOrderable in both start and stop positions for scan */
1500        UUIDStringOrderable = dvf.getCharDataValue(schemaId.toString());
1501
1502        /* Set up the start/stop position for the scan */
1503        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1504        keyRow.setColumn(1, UUIDStringOrderable);
1505
1506        return (SchemaDescriptor)
1507                    getDescriptorViaIndex(
1508                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX2_ID,
1509                        keyRow,
1510                        (ScanQualifier [][]) null,
1511                        ti,
1512                        (TupleDescriptor) null,
1513                        (List) null,
1514                        false);
1515    }
1516        
1517    /**
1518     * Get the target schema by searching for a matching row
1519     * in SYSSCHEMAS by schema name. Read only scan.
1520     *
1521     * @param schemaName The name of the schema we're interested in.
1522     * If schemaId is null, used to qual.
1523     *
1524     * @param tc TransactionController. If null, one
1525     * is gotten off of the language connection context.
1526     *
1527     * @return The row for the schema
1528     *
1529     * @exception StandardException Thrown on error
1530     */

1531    private SchemaDescriptor locateSchemaRow(String JavaDoc schemaName,
1532                                TransactionController tc)
1533        throws StandardException
1534    {
1535        DataValueDescriptor schemaNameOrderable;
1536        TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1537
1538        /* Use aliasNameOrderable in both start
1539         * and stop position for scan.
1540         */

1541        schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
1542
1543        /* Set up the start/stop position for the scan */
1544        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1545        keyRow.setColumn(1, schemaNameOrderable);
1546
1547        return (SchemaDescriptor)
1548                    getDescriptorViaIndex(
1549                        SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID,
1550                        keyRow,
1551                        (ScanQualifier [][]) null,
1552                        ti,
1553                        (TupleDescriptor) null,
1554                        (List) null,
1555                        false);
1556    }
1557
1558    /**
1559     * Get the descriptor for the named schema. If the schemaId
1560     * parameter is NULL, it gets the descriptor for the current (default)
1561     * schema. Schema descriptors include authorization ids and schema ids.
1562     * SQL92 allows a schema to specify a default character set - we will
1563     * not support this. Will check default schema for a match
1564     * before scanning a system table.
1565     *
1566     * @param schemaId The id of the schema we're interested in.
1567     * If the name is NULL, get the descriptor for the
1568     * current schema.
1569     * @param tc TransactionController
1570     *
1571     *
1572     * @return The descriptor for the schema. <I> Warning: <\I> may
1573     * return NULL if schemaName is non-NULL and doesn't exist
1574     * in SYSSCHEMAS
1575     *
1576     * @exception StandardException Thrown on error
1577     */

1578    public SchemaDescriptor getSchemaDescriptor(UUID schemaId,
1579                                    TransactionController tc)
1580        throws StandardException
1581    {
1582        SchemaDescriptor sd = null;
1583        
1584        if ( tc == null )
1585        {
1586            tc = getTransactionCompile();
1587        }
1588
1589        /*
1590        ** Check for APP and SYS schemas before going any
1591        ** further.
1592        */

1593        if (schemaId != null)
1594        {
1595            if (getSystemSchemaDescriptor().getUUID().equals(schemaId))
1596            {
1597                return getSystemSchemaDescriptor();
1598            }
1599            else if (getSysIBMSchemaDescriptor().getUUID().equals(schemaId))
1600            {
1601                return getSysIBMSchemaDescriptor();
1602            }
1603        }
1604
1605        /*
1606        ** If we aren't booting, lets see if we already
1607        ** have the descriptor. If we are in the middle
1608        ** of booting we cannot get the LanguageConnectionContext.
1609        */

1610        if (!booting)
1611        {
1612
1613            LanguageConnectionContext lcc = getLCC();
1614
1615            if (lcc != null)
1616            {
1617                sd = lcc.getDefaultSchema();
1618
1619                if ((sd != null) &&
1620                        ((schemaId == null) ||
1621                            schemaId.equals(sd.getUUID())))
1622                {
1623                    return sd;
1624                }
1625            }
1626        }
1627
1628        return locateSchemaRow(schemaId, tc);
1629    }
1630
1631    /**
1632     * @see DataDictionary#addDescriptor
1633     */

1634    public void addDescriptor(TupleDescriptor td, TupleDescriptor parent,
1635                              int catalogNumber, boolean duplicatesAllowed,
1636                              TransactionController tc)
1637        throws StandardException
1638    {
1639        addDescriptor(td, parent, catalogNumber, duplicatesAllowed, tc, true);
1640    }
1641
1642    /**
1643     * @inheritDoc
1644     */

1645    public void addDescriptor(TupleDescriptor td, TupleDescriptor parent,
1646                              int catalogNumber, boolean duplicatesAllowed,
1647                              TransactionController tc, boolean wait)
1648        throws StandardException
1649    {
1650        TabInfoImpl ti = (catalogNumber < NUM_CORE) ? coreInfo[catalogNumber] :
1651            getNonCoreTI(catalogNumber);
1652
1653        ExecRow row = ti.getCatalogRowFactory().makeRow(td, parent);
1654
1655        int insertRetCode = ti.insertRow(row, tc, wait);
1656
1657        if (!duplicatesAllowed)
1658        {
1659            if (insertRetCode != TabInfoImpl.ROWNOTDUPLICATE)
1660                throw duplicateDescriptorException(td, parent);
1661        }
1662    }
1663
1664    private StandardException
1665        duplicateDescriptorException(TupleDescriptor tuple,
1666                                     TupleDescriptor parent)
1667    {
1668        if (parent != null)
1669            return
1670                StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
1671                                               tuple.getDescriptorType(),
1672                                               tuple.getDescriptorName(),
1673                                               parent.getDescriptorType(),
1674                                               parent.getDescriptorName());
1675
1676        else return
1677                 StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS,
1678                                                tuple.getDescriptorType(),
1679                                                tuple.getDescriptorName());
1680    }
1681
1682    /** array version of addDescriptor.
1683     * @see DataDictionary#addDescriptor
1684     */

1685    public void addDescriptorArray(TupleDescriptor[] td,
1686                                   TupleDescriptor parent,
1687                                   int catalogNumber,
1688                                   boolean allowDuplicates,
1689                                   TransactionController tc)
1690        throws StandardException
1691    {
1692        TabInfoImpl ti = (catalogNumber < NUM_CORE) ? coreInfo[catalogNumber] :
1693            getNonCoreTI(catalogNumber);
1694        CatalogRowFactory crf = ti.getCatalogRowFactory();
1695
1696        ExecRow[] rl = new ExecRow[td.length];
1697
1698        for (int index = 0; index < td.length; index++)
1699        {
1700            ExecRow row = crf.makeRow(td[index], parent);
1701            rl[index] = row;
1702        }
1703
1704        int insertRetCode = ti.insertRowList( rl, tc );
1705        if (!allowDuplicates && insertRetCode != TabInfoImpl.ROWNOTDUPLICATE)
1706        {
1707            throw duplicateDescriptorException(td[insertRetCode], parent);
1708        }
1709    }
1710
1711    /**
1712     * Drop the descriptor for a schema, given the schema's name
1713     *
1714     * @param schemaName The name of the schema to drop
1715     * @param tc TransactionController for the transaction
1716     *
1717     * @exception StandardException Thrown on error
1718     */

1719    public void dropSchemaDescriptor(String JavaDoc schemaName,
1720                            TransactionController tc)
1721        throws StandardException
1722    {
1723        ExecIndexRow keyRow1 = null;
1724        DataValueDescriptor schemaNameOrderable;
1725        TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
1726
1727        if (SanityManager.DEBUG)
1728        {
1729            SchemaDescriptor sd = getSchemaDescriptor(schemaName, getTransactionCompile(), true);
1730            if (!isSchemaEmpty(sd))
1731            {
1732                SanityManager.THROWASSERT("Attempt to drop schema "+schemaName+" that is not empty");
1733            }
1734        }
1735
1736        /* Use schemaNameOrderable in both start
1737         * and stop position for index 1 scan.
1738         */

1739        schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
1740
1741        /* Set up the start/stop position for the scan */
1742        keyRow1 = exFactory.getIndexableRow(1);
1743        keyRow1.setColumn(1, schemaNameOrderable);
1744
1745        ti.deleteRow( tc, keyRow1, SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID );
1746    }
1747
1748    /**
1749     * Get the descriptor for the named table within the given schema.
1750     * If the schema parameter is NULL, it looks for the table in the
1751     * current (default) schema. Table descriptors include object ids,
1752     * object types (table, view, etc.)
1753     *
1754     * @param tableName The name of the table to get the descriptor for
1755     * @param schema The descriptor for the schema the table lives in.
1756     * If null, use the system schema.
1757     *
1758     * @return The descriptor for the table, null if table does not
1759     * exist.
1760     *
1761     * @exception StandardException Thrown on failure
1762     */

1763    public TableDescriptor getTableDescriptor(String JavaDoc tableName,
1764                    SchemaDescriptor schema)
1765            throws StandardException
1766    {
1767        TableDescriptor retval = null;
1768
1769        /*
1770        ** If we didn't get a schema descriptor, we had better
1771        ** have a system table.
1772        */

1773        if (SanityManager.DEBUG)
1774        {
1775            if ((schema == null) && !tableName.startsWith("SYS"))
1776            {
1777                SanityManager.THROWASSERT("null schema for non system table "+tableName);
1778            }
1779        }
1780
1781        SchemaDescriptor sd = (schema == null) ?
1782                getSystemSchemaDescriptor()
1783                : schema;
1784
1785        UUID schemaUUID = sd.getUUID();
1786        
1787        if (SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME.equals(
1788                sd.getSchemaName()))
1789        {
1790            TableDescriptor td =
1791                new TableDescriptor(this, tableName, sd,
1792                        TableDescriptor.VTI_TYPE,
1793                        TableDescriptor.DEFAULT_LOCK_GRANULARITY);
1794            
1795            // ensure a vti class exists
1796
if (getVTIClass(td) != null)
1797                return td;
1798            
1799            // otherwise just standard search
1800
}
1801                
1802        TableKey tableKey = new TableKey(schemaUUID, tableName);
1803
1804        /* Only use the cache if we're in compile-only mode */
1805        if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)
1806        {
1807            NameTDCacheable cacheEntry = (NameTDCacheable) nameTdCache.find(tableKey);
1808            if (cacheEntry != null)
1809            {
1810                retval = cacheEntry.getTableDescriptor();
1811                // bind in previous command might have set refernced cols
1812
retval.setReferencedColumnMap(null);
1813                nameTdCache.release(cacheEntry);
1814            }
1815            return retval;
1816        }
1817
1818        return getTableDescriptorIndex1Scan(tableName, schemaUUID.toString());
1819
1820    }
1821
1822    /**
1823     * Scan systables_index1 (tablename, schemaid) for a match.
1824     *
1825     * @return TableDescriptor The matching descriptor, if any.
1826     *
1827     * @exception StandardException Thrown on failure
1828     */

1829    private TableDescriptor getTableDescriptorIndex1Scan(
1830                                        String JavaDoc tableName,
1831                                        String JavaDoc schemaUUID)
1832                throws StandardException
1833    {
1834        DataValueDescriptor schemaIDOrderable;
1835        DataValueDescriptor tableNameOrderable;
1836        TableDescriptor td;
1837        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
1838
1839        /* Use tableNameOrderable and schemaIdOrderable in both start
1840         * and stop position for scan.
1841         */

1842        tableNameOrderable = dvf.getVarcharDataValue(tableName);
1843        schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
1844
1845        /* Set up the start/stop position for the scan */
1846        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
1847        keyRow.setColumn(1, tableNameOrderable);
1848        keyRow.setColumn(2, schemaIDOrderable);
1849
1850        td = (TableDescriptor)
1851                    getDescriptorViaIndex(
1852                        SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
1853                        keyRow,
1854                        (ScanQualifier [][]) null,
1855                        ti,
1856                        (TupleDescriptor) null,
1857                        (List) null,
1858                        false);
1859
1860        return finishTableDescriptor(td);
1861    }
1862
1863    /**
1864     * This method can get called from the DataDictionary cache.
1865     *
1866     * @param tableKey The TableKey of the table
1867     *
1868     * @return The descriptor for the table, null if the table does
1869     * not exist.
1870     *
1871     * @exception StandardException Thrown on failure
1872     */

1873    TableDescriptor getUncachedTableDescriptor(TableKey tableKey)
1874                throws StandardException
1875    {
1876        return getTableDescriptorIndex1Scan(tableKey.getTableName(),
1877                                            tableKey.getSchemaId().toString());
1878    }
1879
1880    /**
1881     * Get the descriptor for the table with the given UUID.
1882     *
1883     * NOTE: I'm assuming that the object store will define an UUID for
1884     * persistent objects. I'm also assuming that UUIDs are unique across
1885     * schemas, and that the object store will be able to do efficient
1886     * lookups across schemas (i.e. that no schema descriptor parameter
1887     * is needed).
1888     *
1889     * @param tableID The UUID of the table to get the descriptor for
1890     *
1891     * @return The descriptor for the table, null if the table does
1892     * not exist.
1893     *
1894     * @exception StandardException Thrown on failure
1895     */

1896    public TableDescriptor getTableDescriptor(UUID tableID)
1897            throws StandardException
1898    {
1899        OIDTDCacheable cacheEntry;
1900        TableDescriptor retval = null;
1901
1902        /* Only use the cache if we're in compile-only mode */
1903        if (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE)
1904        {
1905            cacheEntry = (OIDTDCacheable) OIDTdCache.find(tableID);
1906            if (cacheEntry != null)
1907            {
1908                retval = cacheEntry.getTableDescriptor();
1909                // bind in previous command might have set refernced cols
1910
retval.setReferencedColumnMap(null);
1911                OIDTdCache.release(cacheEntry);
1912            }
1913
1914            return retval;
1915
1916        }
1917
1918        return getTableDescriptorIndex2Scan(tableID.toString());
1919    }
1920
1921    /**
1922     * This method can get called from the DataDictionary cache.
1923     *
1924     * @param tableID The UUID of the table to get the descriptor for
1925     *
1926     * @return The descriptor for the table, null if the table does
1927     * not exist.
1928     *
1929     * @exception StandardException Thrown on failure
1930     */

1931    protected TableDescriptor getUncachedTableDescriptor(UUID tableID)
1932                throws StandardException
1933    {
1934        return getTableDescriptorIndex2Scan(tableID.toString());
1935    }
1936
1937    /**
1938     * Scan systables_index2 (tableid) for a match.
1939     *
1940     * @return TableDescriptor The matching descriptor, if any.
1941     *
1942     * @exception StandardException Thrown on failure
1943     */

1944    private TableDescriptor getTableDescriptorIndex2Scan(
1945                                        String JavaDoc tableUUID)
1946                throws StandardException
1947    {
1948        DataValueDescriptor tableIDOrderable;
1949        TableDescriptor td;
1950        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
1951
1952        /* Use tableNameOrderable and schemaIdOrderable in both start
1953         * and stop position for scan.
1954         */

1955        tableIDOrderable = dvf.getCharDataValue(tableUUID);
1956
1957        /* Set up the start/stop position for the scan */
1958        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
1959        keyRow.setColumn(1, tableIDOrderable);
1960
1961        td = (TableDescriptor)
1962                    getDescriptorViaIndex(
1963                        SYSTABLESRowFactory.SYSTABLES_INDEX2_ID,
1964                        keyRow,
1965                        (ScanQualifier [][]) null,
1966                        ti,
1967                        (TupleDescriptor) null,
1968                        (List) null,
1969                        false);
1970
1971        return finishTableDescriptor(td);
1972    }
1973
1974    /**
1975     * Finish filling in the TableDescriptor.
1976     * (Build the various lists that hang off the TD.)
1977     *
1978     * @param td The TableDescriptor.
1979     *
1980     * @return The completed TableDescriptor.
1981     *
1982     * @exception StandardException Thrown on failure
1983     */

1984    private TableDescriptor finishTableDescriptor(TableDescriptor td)
1985        throws StandardException
1986    {
1987
1988        if (td != null)
1989        {
1990            synchronized(td)
1991            {
1992                getColumnDescriptorsScan(td);
1993                getConglomerateDescriptorsScan(td);
1994            }
1995        }
1996
1997        return td;
1998    }
1999
2000    /**
2001     * Indicate whether there is anything in the
2002     * particular schema. Checks for tables in the
2003     * the schema, on the assumption that there cannot
2004     * be any other objects in a schema w/o a table.
2005     *
2006     * @param sd descriptor
2007     *
2008     * @return true/false
2009     *
2010     * @exception StandardException on error
2011     */

2012    public boolean isSchemaEmpty(SchemaDescriptor sd)
2013        throws StandardException
2014    {
2015        DataValueDescriptor schemaIdOrderable;
2016        TransactionController tc = getTransactionCompile();
2017
2018        schemaIdOrderable = getValueAsDVD(sd.getUUID());
2019
2020        if (isSchemaReferenced(tc, coreInfo[SYSTABLES_CORE_NUM],
2021                    SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
2022                    SYSTABLESRowFactory.SYSTABLES_INDEX1_SCHEMAID,
2023                    schemaIdOrderable))
2024        {
2025            return false;
2026        }
2027    
2028        if (isSchemaReferenced(tc, getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM),
2029                    SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID,
2030                    2,
2031                    schemaIdOrderable))
2032        {
2033            return false;
2034        }
2035
2036        if (isSchemaReferenced(tc, getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM),
2037                    SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX2_ID,
2038                    2,
2039                    schemaIdOrderable))
2040        {
2041            return false;
2042        }
2043
2044        if (isSchemaReferenced(tc, getNonCoreTI(SYSTRIGGERS_CATALOG_NUM),
2045                    SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX2_ID,
2046                    2,
2047                    schemaIdOrderable))
2048        {
2049            return false;
2050        }
2051
2052        return true;
2053    }
2054
2055    /**
2056     * Is the schema id referenced by the system table in question?
2057     * Currently assumes that the schema id is in an index.
2058     * NOTE: could be generalized a bit, and possibly used
2059     * elsewhere...
2060     *
2061     * @param tc transaction controller
2062     * @param ti table info for the system table
2063     * @param indexId index id
2064     * @param indexCol 1 based index column
2065     * @param schemaIdOrderable the schemaid in a char orderable
2066     *
2067     * @return true if there is a reference to this schema
2068     *
2069     * @exception StandardException on error
2070     */

2071    protected boolean isSchemaReferenced(TransactionController tc,
2072                        TabInfoImpl ti,
2073                        int indexId,
2074                        int indexCol,
2075                        DataValueDescriptor schemaIdOrderable )
2076        throws StandardException
2077    {
2078        ConglomerateController heapCC = null;
2079        ExecIndexRow indexRow1;
2080        ExecIndexRow indexTemplateRow;
2081        ExecRow outRow;
2082        ScanController scanController = null;
2083        boolean foundRow;
2084        FormatableBitSet colToCheck = new FormatableBitSet(indexCol);
2085        CatalogRowFactory rf = ti.getCatalogRowFactory();
2086
2087        if (SanityManager.DEBUG)
2088        {
2089            SanityManager.ASSERT(indexId >= 0, "code needs to be enhanced"+
2090                " to support a table scan to find the index id");
2091        }
2092
2093        colToCheck.set(indexCol - 1);
2094
2095        ScanQualifier[][] qualifier = exFactory.getScanQualifier(1);
2096        qualifier[0][0].setQualifier
2097                (indexCol - 1,
2098                 schemaIdOrderable,
2099                 Orderable.ORDER_OP_EQUALS,
2100                 false,
2101                 false,
2102                 false);
2103
2104        outRow = rf.makeEmptyRow();
2105
2106        try
2107        {
2108            heapCC =
2109                tc.openConglomerate(
2110                    ti.getHeapConglomerate(), false, 0,
2111                    TransactionController.MODE_RECORD,
2112                    TransactionController.ISOLATION_REPEATABLE_READ);
2113    
2114            scanController = tc.openScan(
2115                    ti.getIndexConglomerate(indexId), // conglomerate to open
2116
false, // don't hold open across commit
2117
0, // for read
2118
TransactionController.MODE_RECORD, // row locking
2119
TransactionController.ISOLATION_REPEATABLE_READ,
2120                    colToCheck, // don't get any rows
2121
null, // start position - first row
2122
ScanController.GE, // startSearchOperation
2123
qualifier, // scanQualifier,
2124
null, // stop position - through last row
2125
ScanController.GT); // stopSearchOperation
2126

2127            foundRow = (scanController.next());
2128        }
2129        finally
2130        {
2131            if (scanController != null)
2132            {
2133                scanController.close();
2134            }
2135            if (heapCC != null)
2136            {
2137                heapCC.close();
2138            }
2139        }
2140        
2141        return foundRow;
2142    }
2143
2144    /**
2145     * Drop the table descriptor.
2146     *
2147     * @param td The table descriptor to drop
2148     * @param schema A descriptor for the schema the table
2149     * is a part of. If this parameter is
2150     * NULL, then the table is part of the
2151     * current (default) schema
2152     * @param tc TransactionController for the transaction
2153     *
2154     * @exception StandardException Thrown on error
2155     */

2156    public void dropTableDescriptor(TableDescriptor td, SchemaDescriptor schema,
2157                                    TransactionController tc)
2158        throws StandardException
2159    {
2160        ConglomerateController heapCC;
2161        ExecIndexRow keyRow1 = null;
2162        DataValueDescriptor schemaIDOrderable;
2163        DataValueDescriptor tableNameOrderable;
2164        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
2165
2166        /* Use tableIdOrderable and schemaIdOrderable in both start
2167         * and stop position for index 1 scan.
2168         */

2169        tableNameOrderable = dvf.getVarcharDataValue(td.getName());
2170        schemaIDOrderable = getValueAsDVD(schema.getUUID());
2171
2172        /* Set up the start/stop position for the scan */
2173        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2174        keyRow1.setColumn(1, tableNameOrderable);
2175        keyRow1.setColumn(2, schemaIDOrderable);
2176
2177        ti.deleteRow( tc, keyRow1, SYSTABLESRowFactory.SYSTABLES_INDEX1_ID );
2178    }
2179
2180    /**
2181     * Update the lockGranularity for the specified table.
2182     *
2183     * @param td The TableDescriptor for the table
2184     * @param schema The SchemaDescriptor for the table
2185     * @param lockGranularity The new lockGranularity
2186     * @param tc The TransactionController to use.
2187     *
2188     * @exception StandardException Thrown on error
2189     */

2190    public void updateLockGranularity(TableDescriptor td, SchemaDescriptor schema,
2191                                      char lockGranularity, TransactionController tc)
2192        throws StandardException
2193    {
2194        ConglomerateController heapCC;
2195        ExecIndexRow keyRow1 = null;
2196        ExecRow row;
2197        DataValueDescriptor schemaIDOrderable;
2198        DataValueDescriptor tableNameOrderable;
2199        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
2200        SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti.getCatalogRowFactory();
2201
2202        /* Use tableIdOrderable and schemaIdOrderable in both start
2203         * and stop position for index 1 scan.
2204         */

2205        tableNameOrderable = dvf.getVarcharDataValue(td.getName());
2206        schemaIDOrderable = getValueAsDVD(schema.getUUID());
2207
2208        /* Set up the start/stop position for the scan */
2209        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2210        keyRow1.setColumn(1, tableNameOrderable);
2211        keyRow1.setColumn(2, schemaIDOrderable);
2212
2213        // build the row to be stuffed into SYSTABLES.
2214
row = rf.makeRow(td, schema);
2215        // update row in catalog (no indexes)
2216
boolean[] bArray = new boolean[2];
2217        for (int index = 0; index < 2; index++)
2218        {
2219            bArray[index] = false;
2220        }
2221        ti.updateRow(keyRow1, row,
2222                     SYSTABLESRowFactory.SYSTABLES_INDEX1_ID,
2223                     bArray,
2224                     (int[])null,
2225                     tc);
2226    }
2227
2228    /**
2229     * Drop all table descriptors for a schema.
2230     *
2231     * @param schema A descriptor for the schema to drop the tables
2232     * from.
2233     *
2234     * @return Nothing.
2235     *
2236     * @exception StandardException Thrown on failure
2237     */

2238    /*
2239    public void dropAllTableDescriptors(SchemaDescriptor schema)
2240                        throws StandardException
2241    {
2242        if (SanityManager.DEBUG) SanityManager.NOTREACHED();
2243    }
2244    */

2245
2246    /**
2247     * Get a ColumnDescriptor given its Default ID.
2248     *
2249     * @param uuid The UUID of the default
2250     *
2251     * @return The ColumnDescriptor for the column.
2252     *
2253     * @exception StandardException Thrown on failure
2254     */

2255    public ColumnDescriptor getColumnDescriptorByDefaultId(UUID uuid)
2256                throws StandardException
2257    {
2258        DataValueDescriptor UUIDStringOrderable;
2259        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2260
2261        /* Use UUIDStringOrderable in both start and stop positions for scan */
2262        UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
2263
2264        /* Set up the start/stop position for the scan */
2265        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2266        keyRow.setColumn(1, UUIDStringOrderable);
2267
2268        return (ColumnDescriptor)
2269                    getDescriptorViaIndex(
2270                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX2_ID,
2271                        keyRow,
2272                        (ScanQualifier [][]) null,
2273                        ti,
2274                        (DefaultDescriptor) null,
2275                        (List) null,
2276                        false);
2277    }
2278
2279
2280    /**
2281     * Populate the ColumnDescriptorList for the specified TableDescriptor.
2282     *
2283     * MT synchronization: it is assumed that the caller has synchronized
2284     * on the CDL in the given TD.
2285     *
2286     * @param td The TableDescriptor.
2287     *
2288     * @exception StandardException Thrown on failure
2289     */

2290    private void getColumnDescriptorsScan(TableDescriptor td)
2291            throws StandardException
2292    {
2293        getColumnDescriptorsScan(
2294                        td.getUUID(),
2295                        td.getColumnDescriptorList(),
2296                        td);
2297    }
2298
2299    /**
2300     * Populate the ColumnDescriptorList for the specified TableDescriptor.
2301     *
2302     * MT synchronization: it is assumed that the caller has synchronized
2303     * on the CDL in the given TD.
2304     *
2305     * @param uuid The referencing UUID
2306     * @param cdl The column descriptor list
2307     * @param td The parent tuple descriptor
2308     *
2309     * @exception StandardException Thrown on failure
2310     */

2311     private void getColumnDescriptorsScan(
2312                                            UUID uuid,
2313                                            ColumnDescriptorList cdl,
2314                                            TupleDescriptor td)
2315            throws StandardException
2316    {
2317        ColumnDescriptor cd;
2318        ColumnDescriptorList cdlCopy = new ColumnDescriptorList();
2319        DataValueDescriptor refIDOrderable = null;
2320        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2321
2322        /* Use refIDOrderable in both start and stop position for scan. */
2323        refIDOrderable = getValueAsDVD(uuid);
2324
2325        /* Set up the start/stop position for the scan */
2326        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2327        keyRow.setColumn(1, refIDOrderable);
2328
2329        getDescriptorViaIndex(
2330                        SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID,
2331                        keyRow,
2332                        (ScanQualifier [][]) null,
2333                        ti,
2334                        td,
2335                        (ColumnDescriptorList) cdl,
2336                        false);
2337
2338        /* The TableDescriptor's column descriptor list must be ordered by
2339         * columnNumber. (It is probably not ordered correctly at this point due
2340         * to the index on syscolumns being on (tableId, columnName).) The
2341         * cheapest way to reorder the list appears to be to copy it (above), and then
2342         * walk the copy and put the elements back into the original in the
2343         * expected locations.
2344         */

2345        int cdlSize = cdl.size();
2346        for (int index = 0; index < cdlSize; index++)
2347        {
2348            cdlCopy.add( cdl.get(index));
2349        }
2350        for (int index = 0; index < cdlSize; index++)
2351        {
2352            cd = (ColumnDescriptor) cdlCopy.elementAt(index);
2353            cdl.set(cd.getPosition() - 1, cd);
2354        }
2355    }
2356
2357    /**
2358     * Given a column name and a table ID, drops the column descriptor
2359     * from the table.
2360     *
2361     * @param tableID The UUID of the table to drop the column from
2362     * @param columnName The name of the column to drop
2363     * @param tc TransactionController for the transaction
2364     *
2365     * @exception StandardException Thrown on error
2366     */

2367    public void dropColumnDescriptor(UUID tableID,
2368                String JavaDoc columnName, TransactionController tc)
2369        throws StandardException
2370    {
2371        DataValueDescriptor columnNameOrderable;
2372        DataValueDescriptor tableIdOrderable;
2373
2374        /* Use tableIDOrderable and columnNameOrderable in both start
2375         * and stop position for scan.
2376         */

2377        tableIdOrderable = getValueAsDVD(tableID);
2378        columnNameOrderable = dvf.getVarcharDataValue(columnName);
2379
2380        /* Set up the start/stop position for the scan */
2381        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
2382        keyRow.setColumn(1, tableIdOrderable);
2383        keyRow.setColumn(2, columnNameOrderable);
2384
2385        dropColumnDescriptorCore( tc, keyRow);
2386    }
2387
2388    /**
2389     * Drops all column descriptors from the given table. Useful for
2390     * DROP TABLE.
2391     *
2392     * @param tableID The UUID of the table from which to drop
2393     * all the column descriptors
2394     * @param tc TransactionController for the transaction
2395     *
2396     * @exception StandardException Thrown on error
2397     */

2398    public void dropAllColumnDescriptors(UUID tableID, TransactionController tc)
2399        throws StandardException
2400    {
2401        DataValueDescriptor tableIdOrderable;
2402
2403        /* Use tableIDOrderable in both start and stop position for scan. */
2404        tableIdOrderable = getValueAsDVD(tableID);
2405
2406        /* Set up the start/stop position for the scan */
2407        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2408        keyRow.setColumn(1, tableIdOrderable);
2409
2410        dropColumnDescriptorCore(tc, keyRow);
2411    }
2412
2413    /**
2414     * Drops all table and column permission descriptors for the given table.
2415     *
2416     * @param tableID The UUID of the table from which to drop
2417     * all the permission descriptors
2418     * @param tc TransactionController for the transaction
2419     *
2420     * @exception StandardException Thrown on error
2421     */

2422    public void dropAllTableAndColPermDescriptors(UUID tableID, TransactionController tc)
2423        throws StandardException
2424    {
2425        DataValueDescriptor tableIdOrderable;
2426
2427        // In Derby authorization mode, permission catalogs may not be present
2428
if (!usesSqlAuthorization)
2429            return;
2430
2431        /* Use tableIDOrderable in both start and stop position for scan. */
2432        tableIdOrderable = getValueAsDVD(tableID);
2433
2434        /* Set up the start/stop position for the scan */
2435        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2436        keyRow.setColumn(1, tableIdOrderable);
2437
2438        dropTablePermDescriptor(tc, keyRow);
2439        dropColumnPermDescriptor(tc, keyRow);
2440    }
2441
2442    /**
2443     * Need to update SYSCOLPERMS for a given table because a new column has
2444     * been added to that table. SYSCOLPERMS has a column called "COLUMNS"
2445     * which is a bit map for all the columns in a given user table. Since
2446     * ALTER TABLE .. ADD COLUMN .. has added one more column, we need to
2447     * expand "COLUMNS" for that new column
2448     *
2449     * Currently, this code gets called during execution phase of
2450     * ALTER TABLE .. ADD COLUMN ..
2451     *
2452     * @param tableID The UUID of the table to which a column has been added
2453     * @param tc TransactionController for the transaction
2454     *
2455     * @exception StandardException Thrown on error
2456     */

2457    public void updateSYSCOLPERMSforAddColumnToUserTable(UUID tableID, TransactionController tc)
2458    throws StandardException
2459    {
2460        // In Derby authorization mode, permission catalogs may not be present
2461
if (!usesSqlAuthorization)
2462            return;
2463
2464        /* This method has 2 steps to it. First get all the ColPermsDescriptor
2465        for given tableid. And next step is to go back to SYSCOLPERMS to find
2466        unique row corresponding to each of ColPermsDescriptor and update the
2467        "COLUMNS" column in SYSCOLPERMS. The reason for this 2 step process is
2468        that SYSCOLPERMS has a non-unique row on "TABLEID" column and hence
2469        we can't get a unique handle on each of the affected row in SYSCOLPERMS
2470        using just the "TABLEID" column */

2471
2472        // First get all the ColPermsDescriptor for the given tableid from
2473
//SYSCOLPERMS using getDescriptorViaIndex().
2474
List permissionDescriptorsList;//all ColPermsDescriptor for given tableid
2475
DataValueDescriptor tableIDOrderable = getValueAsDVD(tableID);
2476        TabInfoImpl ti = getNonCoreTI(SYSCOLPERMS_CATALOG_NUM);
2477        SYSCOLPERMSRowFactory rf = (SYSCOLPERMSRowFactory) ti.getCatalogRowFactory();
2478        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2479        keyRow.setColumn(1, tableIDOrderable);
2480        permissionDescriptorsList = newSList();
2481        getDescriptorViaIndex(
2482            SYSCOLPERMSRowFactory.TABLEID_INDEX_NUM,
2483            keyRow,
2484            (ScanQualifier [][]) null,
2485            ti,
2486            (TupleDescriptor) null,
2487            permissionDescriptorsList,
2488            false);
2489
2490        /* Next, using each of the ColPermDescriptor's uuid, get the unique row
2491        in SYSCOLPERMS and expand the "COLUMNS" column in SYSCOLPERMS to
2492        accomodate the newly added column to the tableid*/

2493        ColPermsDescriptor colPermsDescriptor;
2494        ExecRow curRow;
2495        ExecIndexRow uuidKey;
2496        // Not updating any indexes on SYSCOLPERMS
2497
boolean[] bArray = new boolean[SYSCOLPERMSRowFactory.TOTAL_NUM_OF_INDEXES];
2498        int[] colsToUpdate = {SYSCOLPERMSRowFactory.COLUMNS_COL_NUM};
2499        for (Iterator JavaDoc iterator = permissionDescriptorsList.iterator(); iterator.hasNext(); )
2500        {
2501            colPermsDescriptor = (ColPermsDescriptor) iterator.next();
2502            removePermEntryInCache(colPermsDescriptor);
2503            uuidKey = rf.buildIndexKeyRow(rf.COLPERMSID_INDEX_NUM, colPermsDescriptor);
2504            curRow=ti.getRow(tc, uuidKey, rf.COLPERMSID_INDEX_NUM);
2505            FormatableBitSet columns = (FormatableBitSet) curRow.getColumn(
2506                      SYSCOLPERMSRowFactory.COLUMNS_COL_NUM).getObject();
2507            int currentLength = columns.getLength();
2508            columns.grow(currentLength+1);
2509            curRow.setColumn(SYSCOLPERMSRowFactory.COLUMNS_COL_NUM,
2510                      dvf.getDataValue((Object JavaDoc) columns));
2511            ti.updateRow(keyRow, curRow,
2512                    SYSCOLPERMSRowFactory.TABLEID_INDEX_NUM,
2513                     bArray,
2514                     colsToUpdate,
2515                     tc);
2516        }
2517    }
2518
2519    
2520    /**
2521     * Remove PermissionsDescriptor from permissions cache if present
2522     */

2523    private void removePermEntryInCache(PermissionsDescriptor perm)
2524        throws StandardException
2525    {
2526        // Remove cached permissions entry if present
2527
Cacheable cacheEntry = getPermissionsCache().findCached( perm);
2528        if (cacheEntry != null)
2529            getPermissionsCache().remove(cacheEntry);
2530    }
2531
2532    /**
2533     * Drops all routine permission descriptors for the given routine.
2534     *
2535     * @param routineID The UUID of the routine from which to drop
2536     * all the permission descriptors
2537     * @param tc TransactionController for the transaction
2538     *
2539     * @exception StandardException Thrown on error
2540     */

2541    public void dropAllRoutinePermDescriptors(UUID routineID, TransactionController tc)
2542        throws StandardException
2543    {
2544        TabInfoImpl ti = getNonCoreTI(SYSROUTINEPERMS_CATALOG_NUM);
2545        SYSROUTINEPERMSRowFactory rf = (SYSROUTINEPERMSRowFactory) ti.getCatalogRowFactory();
2546        DataValueDescriptor routineIdOrderable;
2547        ExecRow curRow;
2548        PermissionsDescriptor perm;
2549
2550        // In Derby authorization mode, permission catalogs may not be present
2551
if (!usesSqlAuthorization)
2552            return;
2553
2554        /* Use tableIDOrderable in both start and stop position for scan. */
2555        routineIdOrderable = getValueAsDVD(routineID);
2556
2557        /* Set up the start/stop position for the scan */
2558        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2559        keyRow.setColumn(1, routineIdOrderable);
2560
2561        while ((curRow=ti.getRow(tc, keyRow, rf.ALIASID_INDEX_NUM)) != null)
2562        {
2563            perm = (PermissionsDescriptor)rf.buildDescriptor(curRow, (TupleDescriptor) null, this);
2564            removePermEntryInCache(perm);
2565
2566            // Build new key based on UUID and drop the entry as we want to drop
2567
// only this row
2568
ExecIndexRow uuidKey;
2569            uuidKey = rf.buildIndexKeyRow(rf.ROUTINEPERMSID_INDEX_NUM, perm);
2570            ti.deleteRow(tc, uuidKey, rf.ROUTINEPERMSID_INDEX_NUM);
2571        }
2572    }
2573
2574    /**
2575     * Delete the appropriate rows from syscolumns when
2576     * dropping 1 or more columns.
2577     *
2578     * @param tc The TransactionController
2579     * @param keyRow Start/stop position.
2580     *
2581     * @exception StandardException Thrown on failure
2582     */

2583    private void dropColumnDescriptorCore(
2584                    TransactionController tc,
2585                    ExecIndexRow keyRow)
2586            throws StandardException
2587    {
2588        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2589
2590        ti.deleteRow( tc, keyRow, SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID );
2591    }
2592
2593    /**
2594     * Delete the appropriate rows from systableperms when
2595     * dropping a table
2596     *
2597     * @param tc The TransactionController
2598     * @param keyRow Start/stop position.
2599     *
2600     * @exception StandardException Thrown on failure
2601     */

2602    private void dropTablePermDescriptor(
2603                    TransactionController tc,
2604                    ExecIndexRow keyRow)
2605            throws StandardException
2606    {
2607        ExecRow curRow;
2608        PermissionsDescriptor perm;
2609        TabInfoImpl ti = getNonCoreTI(SYSTABLEPERMS_CATALOG_NUM);
2610        SYSTABLEPERMSRowFactory rf = (SYSTABLEPERMSRowFactory) ti.getCatalogRowFactory();
2611
2612        while ((curRow=ti.getRow(tc, keyRow, rf.TABLEID_INDEX_NUM)) != null)
2613        {
2614            perm = (PermissionsDescriptor)rf.buildDescriptor(curRow, (TupleDescriptor) null, this);
2615            removePermEntryInCache(perm);
2616
2617            // Build key on UUID and drop the entry as we want to drop only this row
2618
ExecIndexRow uuidKey;
2619            uuidKey = rf.buildIndexKeyRow(rf.TABLEPERMSID_INDEX_NUM, perm);
2620            ti.deleteRow(tc, uuidKey, rf.TABLEPERMSID_INDEX_NUM);
2621        }
2622    }
2623
2624    /**
2625     * Delete the appropriate rows from syscolperms when
2626     * dropping a table
2627     *
2628     * @param tc The TransactionController
2629     * @param keyRow Start/stop position.
2630     *
2631     * @exception StandardException Thrown on failure
2632     */

2633    private void dropColumnPermDescriptor(
2634                    TransactionController tc,
2635                    ExecIndexRow keyRow)
2636            throws StandardException
2637    {
2638        ExecRow curRow;
2639        PermissionsDescriptor perm;
2640        TabInfoImpl ti = getNonCoreTI(SYSCOLPERMS_CATALOG_NUM);
2641        SYSCOLPERMSRowFactory rf = (SYSCOLPERMSRowFactory) ti.getCatalogRowFactory();
2642
2643        while ((curRow=ti.getRow(tc, keyRow, rf.TABLEID_INDEX_NUM)) != null)
2644        {
2645            perm = (PermissionsDescriptor)rf.buildDescriptor(curRow, (TupleDescriptor) null, this);
2646            removePermEntryInCache(perm);
2647
2648            // Build key on UUID and drop the entry as we want to drop only this row
2649
ExecIndexRow uuidKey;
2650            uuidKey = rf.buildIndexKeyRow(rf.COLPERMSID_INDEX_NUM, perm);
2651            ti.deleteRow(tc, uuidKey, rf.COLPERMSID_INDEX_NUM);
2652        }
2653    }
2654
2655    /**
2656     * Update the column descriptor in question. Updates
2657     * every row in the base conglomerate.
2658     *
2659     * @param cd The ColumnDescriptor
2660     * @param formerUUID The UUID for this column in SYSCOLUMNS,
2661     * may differ from what is in cd if this
2662     * is the column that is being set.
2663     * @param formerName The name for this column in SYSCOLUMNS
2664     * may differ from what is in cd if this
2665     * is the column that is being set.
2666     * @param colsToSet Array of ints of columns to be modified,
2667     * 1 based. May be null (all cols).
2668     * @param tc The TransactionController to use
2669     * @param wait If true, then the caller wants to wait for locks. False will be
2670     * when we using a nested user xaction - we want to timeout right away if the parent
2671     * holds the lock. (bug 4821)
2672     *
2673     * @exception StandardException Thrown on failure
2674     */

2675    private void updateColumnDescriptor(ColumnDescriptor cd,
2676                                        UUID formerUUID,
2677                                        String JavaDoc formerName,
2678                                        int[] colsToSet,
2679                                        TransactionController tc,
2680                                        boolean wait)
2681        throws StandardException
2682    {
2683        ExecIndexRow keyRow1 = null;
2684        ExecRow row;
2685        DataValueDescriptor refIDOrderable;
2686        DataValueDescriptor columnNameOrderable;
2687        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
2688        SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti.getCatalogRowFactory();
2689
2690        /* Use objectID/columnName in both start
2691         * and stop position for index 1 scan.
2692         */

2693        refIDOrderable = getValueAsDVD(formerUUID);
2694        columnNameOrderable = dvf.getVarcharDataValue(formerName);
2695
2696        /* Set up the start/stop position for the scan */
2697        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(2);
2698        keyRow1.setColumn(1, refIDOrderable);
2699        keyRow1.setColumn(2, columnNameOrderable);
2700
2701        // build the row to be stuffed into SYSCOLUMNS.
2702
row = rf.makeRow(cd, null);
2703
2704        /*
2705        ** Figure out if the index in syscolumns needs
2706        ** to be updated.
2707        */

2708        if (SanityManager.DEBUG)
2709        {
2710            SanityManager.ASSERT(rf.getNumIndexes() == 2,
2711                    "There are more indexes on syscolumns than expected, the code herein needs to change");
2712        }
2713
2714        boolean[] bArray = new boolean[rf.getNumIndexes()];
2715
2716        /*
2717        ** Do we need to update indexes?
2718        */

2719        if (colsToSet == null)
2720        {
2721            bArray[0] = true;
2722            bArray[1] = true;
2723        }
2724        else
2725        {
2726            /*
2727            ** Check the specific columns for indexed
2728            ** columns.
2729            */

2730            for (int i = 0; i < colsToSet.length; i++)
2731            {
2732                if ((colsToSet[i] == rf.SYSCOLUMNS_COLUMNNAME) ||
2733                    (colsToSet[i] == rf.SYSCOLUMNS_REFERENCEID))
2734                {
2735                    bArray[0] = true;
2736                    break;
2737                }
2738                else if (colsToSet[i] == rf.SYSCOLUMNS_COLUMNDEFAULTID)
2739                {
2740                    bArray[1] = true;
2741                    break;
2742                }
2743            }
2744        }
2745
2746        ti.updateRow(keyRow1, row,
2747                     SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID,
2748                     bArray,
2749                     colsToSet,
2750                     tc,
2751                     wait);
2752    }
2753
2754    /**
2755     * Gets the viewDescriptor for the view with the given UUID.
2756     *
2757     * @param uuid The UUID for the view
2758     *
2759     * @return A descriptor for the view
2760     *
2761     * @exception StandardException Thrown on error
2762     */

2763    public ViewDescriptor getViewDescriptor(UUID uuid)
2764        throws StandardException
2765    {
2766        return getViewDescriptor(getTableDescriptor(uuid));
2767    }
2768
2769    /**
2770     * Gets the viewDescriptor for the view given the TableDescriptor.
2771     *
2772     * @param td The TableDescriptor for the view.
2773     *
2774     * @return A descriptor for the view
2775     *
2776     * @exception StandardException Thrown on error
2777     */

2778    public ViewDescriptor getViewDescriptor(TableDescriptor td)
2779        throws StandardException
2780    {
2781        TableDescriptor tdi = (TableDescriptor) td;
2782
2783        /* See if the view info is cached */
2784        if (tdi.getViewDescriptor() != null)
2785        {
2786            return tdi.getViewDescriptor();
2787        }
2788
2789        synchronized(tdi)
2790        {
2791            /* See if we were waiting on someone who just filled it in */
2792            if (tdi.getViewDescriptor() != null)
2793            {
2794                return tdi.getViewDescriptor();
2795            }
2796
2797            tdi.setViewDescriptor((ViewDescriptor) getViewDescriptorScan(tdi));
2798        }
2799        return tdi.getViewDescriptor();
2800    }
2801
2802    /**
2803     * Get the information for the view from sys.sysviews.
2804     *
2805     * @param tdi The TableDescriptor for the view.
2806     *
2807     * @return ViewDescriptor The ViewDescriptor for the view.
2808     *
2809     * @exception StandardException Thrown on error
2810     */

2811    private ViewDescriptor getViewDescriptorScan(TableDescriptor tdi)
2812        throws StandardException
2813    {
2814        ViewDescriptor vd;
2815        DataValueDescriptor viewIdOrderable;
2816        TabInfoImpl ti = getNonCoreTI(SYSVIEWS_CATALOG_NUM);
2817        UUID viewID = tdi.getUUID();
2818
2819        /* Use viewIdOrderable in both start
2820         * and stop position for scan.
2821         */

2822        viewIdOrderable = dvf.getCharDataValue(viewID.toString());
2823
2824        /* Set up the start/stop position for the scan */
2825        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2826        keyRow.setColumn(1, viewIdOrderable);
2827
2828        vd = (ViewDescriptor)
2829                    getDescriptorViaIndex(
2830                        SYSVIEWSRowFactory.SYSVIEWS_INDEX1_ID,
2831                        keyRow,
2832                        (ScanQualifier [][]) null,
2833                        ti,
2834                        (TupleDescriptor) null,
2835                        (List) null,
2836                        false);
2837
2838        if (vd != null)
2839        {
2840            vd.setViewName(tdi.getName());
2841        }
2842        return vd;
2843    }
2844
2845    /**
2846     * Drops the view descriptor from the data dictionary.
2847     *
2848     * @param vd A descriptor for the view to be dropped
2849     * @param tc TransactionController to use
2850     *
2851     * @exception StandardException Thrown on error
2852     */

2853    public void dropViewDescriptor(ViewDescriptor vd,
2854                                   TransactionController tc)
2855        throws StandardException
2856    {
2857        DataValueDescriptor viewIdOrderable;
2858        TabInfoImpl ti = getNonCoreTI(SYSVIEWS_CATALOG_NUM);
2859
2860        /* Use aliasNameOrderable in both start
2861         * and stop position for scan.
2862         */

2863        viewIdOrderable = getValueAsDVD(vd.getUUID());
2864
2865        /* Set up the start/stop position for the scan */
2866        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
2867        keyRow.setColumn(1, viewIdOrderable);
2868
2869        ti.deleteRow( tc, keyRow, SYSVIEWSRowFactory.SYSVIEWS_INDEX1_ID );
2870
2871    }
2872
2873    /**
2874     * Scan sysfiles_index2 (id) for a match.
2875     * @return TableDescriptor The matching descriptor, or null.
2876     * @exception StandardException Thrown on failure
2877     */

2878    private FileInfoDescriptor
2879    getFileInfoDescriptorIndex2Scan(UUID id)
2880                throws StandardException
2881    {
2882        DataValueDescriptor idOrderable;
2883        TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2884        idOrderable = dvf.getCharDataValue(id.toString());
2885
2886        /* Set up the start/stop position for the scan */
2887        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
2888        keyRow.setColumn(1, idOrderable);
2889
2890        return (FileInfoDescriptor)
2891                    getDescriptorViaIndex(
2892                        SYSFILESRowFactory.SYSFILES_INDEX2_ID,
2893                        keyRow,
2894                        (ScanQualifier [][]) null,
2895                        ti,
2896                        (TupleDescriptor) null,
2897                        (List) null,
2898                        false);
2899    }
2900
2901    /**
2902     * @see DataDictionary#getFileInfoDescriptor
2903     * @exception StandardException Thrown on failure
2904     */

2905    public FileInfoDescriptor getFileInfoDescriptor(UUID id)
2906                throws StandardException
2907    {
2908        return getFileInfoDescriptorIndex2Scan(id);
2909    }
2910
2911
2912    /**
2913     * Scan sysfiles_index1 (schemaid,name) for a match.
2914     * @return The matching descriptor or null.
2915     * @exception StandardException Thrown on failure
2916     */

2917    private FileInfoDescriptor getFileInfoDescriptorIndex1Scan(
2918                                        UUID schemaId,
2919                                        String JavaDoc name)
2920                throws StandardException
2921    {
2922        DataValueDescriptor schemaIDOrderable;
2923        DataValueDescriptor nameOrderable;
2924        TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2925
2926        nameOrderable = dvf.getVarcharDataValue(name);
2927        schemaIDOrderable = dvf.getCharDataValue(schemaId.toString());
2928
2929        /* Set up the start/stop position for the scan */
2930        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
2931        keyRow.setColumn(1, nameOrderable);
2932        keyRow.setColumn(2, schemaIDOrderable);
2933        FileInfoDescriptor r = (FileInfoDescriptor)
2934                    getDescriptorViaIndex(
2935                        SYSFILESRowFactory.SYSFILES_INDEX1_ID,
2936                        keyRow,
2937                        (ScanQualifier [][]) null,
2938                        ti,
2939                        (TupleDescriptor) null,
2940                        (List) null,
2941                        false);
2942        return r;
2943    }
2944
2945    /**
2946     * @see DataDictionary#getFileInfoDescriptor
2947     * @exception StandardException Thrown on failure
2948     */

2949    public FileInfoDescriptor getFileInfoDescriptor(SchemaDescriptor sd, String JavaDoc name)
2950                throws StandardException
2951    {
2952        return getFileInfoDescriptorIndex1Scan(sd.getUUID(),name);
2953    }
2954
2955    /**
2956     * @see DataDictionary#dropFileInfoDescriptor
2957     * @exception StandardException Thrown on error
2958     */

2959    public void dropFileInfoDescriptor(FileInfoDescriptor fid)
2960                        throws StandardException
2961    {
2962        ConglomerateController heapCC;
2963        ExecIndexRow keyRow1 = null;
2964        DataValueDescriptor idOrderable;
2965        TabInfoImpl ti = getNonCoreTI(SYSFILES_CATALOG_NUM);
2966        TransactionController tc = getTransactionExecute();
2967        
2968        /* Use tableIdOrderable and schemaIdOrderable in both start
2969         * and stop position for index 1 scan.
2970         */

2971        idOrderable = getValueAsDVD(fid.getUUID());
2972
2973        /* Set up the start/stop position for the scan */
2974        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
2975        keyRow1.setColumn(1, idOrderable);
2976        ti.deleteRow( tc, keyRow1, SYSFILESRowFactory.SYSFILES_INDEX2_ID );
2977    }
2978
2979    /**
2980     * Get a SPSDescriptor given its UUID.
2981     *
2982     * @param uuid The UUID
2983     *
2984     * @return The SPSDescriptor for the constraint.
2985     *
2986     * @exception StandardException Thrown on failure
2987     */

2988    public SPSDescriptor getSPSDescriptor(UUID uuid)
2989                throws StandardException
2990    {
2991        SPSDescriptor sps;
2992
2993        /* Make sure that non-core info is initialized */
2994        getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
2995
2996        /* Only use the cache if we're in compile-only mode */
2997        if ((spsNameCache != null) &&
2998            (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE))
2999        {
3000            sps = (SPSDescriptor)spsIdHash.get(uuid);
3001            if (sps != null)
3002            {
3003                //System.out.println("found in hash table ");
3004
// System.out.println("stmt text " + sps.getText());
3005

3006                return sps;
3007            }
3008    
3009            sps = getSPSDescriptorIndex2Scan(uuid.toString());
3010            TableKey stmtKey = new TableKey(sps.getSchemaDescriptor().getUUID(), sps.getName());
3011            try
3012            {
3013                SPSNameCacheable cacheEntry = (SPSNameCacheable)spsNameCache.create(stmtKey, sps);
3014                spsNameCache.release(cacheEntry);
3015            } catch (StandardException se)
3016            {
3017                /*
3018                ** If the error is that the item is already
3019                ** in the cache, then that is ok.
3020                */

3021                if (SQLState.OBJECT_EXISTS_IN_CACHE.equals(se.getMessageId()))
3022                {
3023                    return sps;
3024                }
3025                else
3026                {
3027                    throw se;
3028                }
3029            }
3030            
3031        }
3032        else
3033        {
3034            sps = getSPSDescriptorIndex2Scan(uuid.toString());
3035        }
3036
3037        return sps;
3038    }
3039
3040    /**
3041        Add an entry to the hashtables for lookup from the cache.
3042     */

3043    void spsCacheEntryAdded(SPSDescriptor spsd)
3044    {
3045        spsIdHash.put(spsd.getUUID(), spsd);
3046        // spsTextHash.put(spsd.getText(), spsd);
3047
}
3048
3049    void spsCacheEntryRemoved(SPSDescriptor spsd) {
3050        spsIdHash.remove(spsd.getUUID());
3051        // spsTextHash.remove(spsd.getText());
3052
}
3053
3054    //public SPSDescriptor getSPSBySQLText(String text) {
3055

3056    // return (SPSDescriptor) spsTextHash.get(text);
3057
//}
3058

3059    /**
3060     * This method can get called from the DataDictionary cache.
3061     *
3062     * @param stmtKey The TableKey of the sps
3063     *
3064     * @return The descriptor for the sps, null if the sps does
3065     * not exist.
3066     *
3067     * @exception StandardException Thrown on failure
3068     */

3069    public SPSDescriptor getUncachedSPSDescriptor(TableKey stmtKey)
3070                throws StandardException
3071    {
3072        return getSPSDescriptorIndex1Scan(stmtKey.getTableName(),
3073                                            stmtKey.getSchemaId().toString());
3074    }
3075
3076    /**
3077     * This method can get called from the DataDictionary cache.
3078     *
3079     * @param stmtId The UUID of the stmt to get the descriptor for
3080     *
3081     * @return The descriptor for the stmt, null if the table does
3082     * not exist.
3083     *
3084     * @exception StandardException Thrown on failure
3085     */

3086    protected SPSDescriptor getUncachedSPSDescriptor(UUID stmtId)
3087                throws StandardException
3088    {
3089        return getSPSDescriptorIndex2Scan(stmtId.toString());
3090    }
3091
3092    /**
3093     * Scan sysstatements_index2 (stmtid) for a match.
3094     * Note that we do not do a lookup of parameter info.
3095     *
3096     * @return SPSDescriptor The matching descriptor, if any.
3097     *
3098     * @exception StandardException Thrown on failure
3099     */

3100    private SPSDescriptor getSPSDescriptorIndex2Scan(
3101                                        String JavaDoc stmtUUID)
3102                throws StandardException
3103    {
3104        DataValueDescriptor stmtIDOrderable;
3105        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3106
3107        /* Use stmtIdOrderable in both start
3108         * and stop position for scan.
3109         */

3110        stmtIDOrderable = dvf.getCharDataValue(stmtUUID);
3111
3112        /* Set up the start/stop position for the scan */
3113        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
3114        keyRow.setColumn(1, stmtIDOrderable);
3115
3116        SPSDescriptor spsd = (SPSDescriptor)
3117                    getDescriptorViaIndex(
3118                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID,
3119                        keyRow,
3120                        (ScanQualifier [][]) null,
3121                        ti,
3122                        (TupleDescriptor) null,
3123                        (List) null,
3124                        false);
3125
3126        return spsd;
3127    }
3128
3129    /**
3130     * Get a SPSDescriptor given its name.
3131     * Currently no cacheing. With caching
3132     * we need to be very careful about invalidation.
3133     * No caching means invalidations block on
3134     * existing SPSD instances (since they were read in
3135     *
3136     * @param stmtName the statement name
3137     * @param sd The SchemaDescriptor
3138     *
3139     * @return The SPSDescriptor for the constraint.
3140     *
3141     * @exception StandardException Thrown on failure
3142     */

3143    public SPSDescriptor getSPSDescriptor(String JavaDoc stmtName, SchemaDescriptor sd)
3144        throws StandardException
3145    {
3146        SPSDescriptor sps = null;
3147        TableKey stmtKey;
3148        UUID schemaUUID;
3149
3150        /*
3151        ** If we didn't get a schema descriptor, we had better
3152        ** have a system table.
3153        */

3154        if (SanityManager.DEBUG)
3155        {
3156            if (sd == null)
3157            {
3158                SanityManager.THROWASSERT("null schema for statement "+stmtName);
3159            }
3160        }
3161
3162        schemaUUID = sd.getUUID();
3163        stmtKey = new TableKey(schemaUUID, stmtName);
3164
3165        /* Only use the cache if we're in compile-only mode */
3166        if ((spsNameCache != null) &&
3167            (getCacheMode() == DataDictionary.COMPILE_ONLY_MODE))
3168        {
3169            SPSNameCacheable cacheEntry = (SPSNameCacheable) spsNameCache.find(stmtKey);
3170            if (cacheEntry != null)
3171            {
3172                sps = cacheEntry.getSPSDescriptor();
3173                spsNameCache.release(cacheEntry);
3174            }
3175            //System.out.println("found in cache " + stmtName);
3176
//System.out.println("stmt text " + sps.getText());
3177
return sps;
3178        }
3179
3180        return getSPSDescriptorIndex1Scan(stmtName, schemaUUID.toString());
3181    }
3182
3183    /**
3184     * Scan sysschemas_index1 (stmtname, schemaid) for a match.
3185     *
3186     * @return SPSDescriptor The matching descriptor, if any.
3187     *
3188     * @exception StandardException Thrown on failure
3189     */

3190    private SPSDescriptor getSPSDescriptorIndex1Scan(
3191                                        String JavaDoc stmtName,
3192                                        String JavaDoc schemaUUID)
3193                throws StandardException
3194    {
3195        DataValueDescriptor schemaIDOrderable;
3196        DataValueDescriptor stmtNameOrderable;
3197        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3198
3199        /* Use stmtNameOrderable and schemaIdOrderable in both start
3200         * and stop position for scan.
3201         */

3202        stmtNameOrderable = dvf.getVarcharDataValue(stmtName);
3203        schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
3204
3205        /* Set up the start/stop position for the scan */
3206        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
3207        keyRow.setColumn(1, stmtNameOrderable);
3208        keyRow.setColumn(2, schemaIDOrderable);
3209
3210        SPSDescriptor spsd = (SPSDescriptor)
3211                    getDescriptorViaIndex(
3212                        SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX2_ID,
3213                        keyRow,
3214                        (ScanQualifier [][]) null,
3215                        ti,
3216                        (TupleDescriptor) null,
3217                        (List) null,
3218                        false);
3219    
3220        /*
3221        ** Set up the parameter defaults. We are only
3222        ** doing this when we look up by name because
3223        ** this is the only time we cache, and it can
3224        ** be foolish to look up the parameter defaults
3225        ** for someone that doesn't need them.
3226        */

3227        if (spsd != null)
3228        {
3229            Vector JavaDoc v = new Vector JavaDoc();
3230            spsd.setParams(getSPSParams(spsd, v));
3231            Object JavaDoc[] defaults = new Object JavaDoc[v.size()];
3232            v.copyInto(defaults);
3233            spsd.setParameterDefaults(defaults);
3234        }
3235
3236        return spsd;
3237    }
3238
3239    /**
3240     * Adds the given SPSDescriptor to the data dictionary,
3241     * associated with the given table and constraint type.
3242     *
3243     * @param descriptor The descriptor to add
3244     * @param tc The transaction controller
3245     *
3246     * @exception StandardException Thrown on error
3247     */

3248    public void addSPSDescriptor
3249    (
3250        SPSDescriptor descriptor,
3251        TransactionController tc,
3252        boolean wait
3253    ) throws StandardException
3254    {
3255        ExecRow row;
3256        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3257        SYSSTATEMENTSRowFactory rf = (SYSSTATEMENTSRowFactory) ti.getCatalogRowFactory();
3258        int insertRetCode;
3259
3260        /*
3261        ** We must make sure the descriptor is locked
3262        ** while we are writing it out. Otherwise,
3263        ** the descriptor could be invalidated while
3264        ** we are writing.
3265        */

3266        synchronized(descriptor)
3267        {
3268            // build the row to be stuffed into SYSSTATEMENTS. this will stuff an
3269
// UUID into the descriptor
3270
boolean compileMe = descriptor.initiallyCompilable();
3271            row = rf.makeSYSSTATEMENTSrow(compileMe, descriptor);
3272    
3273            // insert row into catalog and all its indices
3274
insertRetCode = ti.insertRow(row, tc, wait);
3275        }
3276
3277        // Throw an exception duplicate table descriptor
3278
if (insertRetCode != TabInfoImpl.ROWNOTDUPLICATE)
3279        {
3280            throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
3281                                                 descriptor.getDescriptorType(),
3282                                                 descriptor.getDescriptorName(),
3283                                                 descriptor.getSchemaDescriptor().getDescriptorType(),
3284                                                 descriptor.getSchemaDescriptor().getSchemaName());
3285        }
3286
3287        addSPSParams(descriptor, tc, wait);
3288    }
3289
3290    /**
3291     * Add a column in SYS.SYSCOLUMNS for each parameter in the
3292     * parameter list.
3293     */

3294    private void addSPSParams(SPSDescriptor spsd, TransactionController tc, boolean wait)
3295            throws StandardException
3296    {
3297        UUID uuid = spsd.getUUID();
3298        DataTypeDescriptor[] params = spsd.getParams();
3299        Object JavaDoc[] parameterDefaults = spsd.getParameterDefaults();
3300
3301        if (params == null)
3302            return;
3303
3304        /* Create the columns */
3305        int pdlSize = params.length;
3306        for (int index = 0; index < pdlSize; index++)
3307        {
3308            int parameterId = index + 1;
3309
3310            //RESOLVEAUTOINCREMENT
3311
ColumnDescriptor cd =
3312                new ColumnDescriptor(
3313                    "PARAM" + parameterId,
3314                    parameterId, // position
3315
params[index],
3316                    ((parameterDefaults == null) || // default
3317
(index >= parameterDefaults.length)) ?
3318                        (DataValueDescriptor)null :
3319                        (DataValueDescriptor)parameterDefaults[index],
3320                    (DefaultInfo) null,
3321                    uuid,
3322                    (UUID) null, 0, 0);
3323                                        
3324            addDescriptor(cd, null, SYSCOLUMNS_CATALOG_NUM,
3325                          false, // no chance of duplicates here
3326
tc, wait);
3327        }
3328    }
3329
3330    /**
3331     * Get all the parameter descriptors for an SPS.
3332     * Look up the params in SYSCOLUMNS and turn them
3333     * into parameter descriptors.
3334     *
3335     * @param spsd sps descriptor
3336     * @param defaults vector for storing column defaults
3337     *
3338     * @return array of data type descriptors
3339     *
3340     * @exception StandardException Thrown on error
3341     */

3342    public DataTypeDescriptor[] getSPSParams(SPSDescriptor spsd, Vector JavaDoc defaults)
3343        throws StandardException
3344    {
3345        ColumnDescriptorList cdl = new ColumnDescriptorList();
3346        getColumnDescriptorsScan(spsd.getUUID(), cdl, spsd);
3347
3348        int cdlSize = cdl.size();
3349        DataTypeDescriptor[] params = new DataTypeDescriptor[cdlSize];
3350        for (int index = 0; index < cdlSize; index++)
3351        {
3352            ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
3353            params[index] = cd.getType();
3354            if (defaults != null)
3355            {
3356                defaults.addElement(cd.getDefaultValue());
3357            }
3358        }
3359
3360        return params;
3361    }
3362
3363    /**
3364     * Updates SYS.SYSSTATEMENTS with the info from the
3365     * SPSD.
3366     *
3367     * @param spsd The descriptor to add
3368     * @param tc The transaction controller
3369     * @param updateParamDescriptors If true, will update the
3370     * parameter descriptors in SYS.SYSCOLUMNS.
3371     * @param wait If true, then the caller wants to wait for locks. False will be
3372     * @param firstCompilation true, if Statement is getting compiled for first
3373     * time and SPS was created with NOCOMPILE option.
3374     *
3375     * when we using a nested user xaction - we want to timeout right away if the parent
3376     * holds the lock. (bug 4821)
3377     *
3378     * @exception StandardException Thrown on error
3379     */

3380    public void updateSPS(
3381            SPSDescriptor spsd,
3382            TransactionController tc,
3383            boolean recompile,
3384            boolean updateParamDescriptors,
3385            boolean wait,
3386            boolean firstCompilation)
3387                        throws StandardException
3388    {
3389        ExecIndexRow keyRow1 = null;
3390        ExecRow row;
3391        DataValueDescriptor idOrderable;
3392        DataValueDescriptor columnNameOrderable;
3393        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3394        SYSSTATEMENTSRowFactory rf = (SYSSTATEMENTSRowFactory) ti.getCatalogRowFactory();
3395        int[] updCols;
3396        if (recompile)
3397        {
3398            if(firstCompilation)
3399            {
3400                updCols = new int[] {SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID,
3401                                     SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED,
3402                                     SYSSTATEMENTSRowFactory.SYSSTATEMENTS_USINGTEXT,
3403                                     SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE,
3404                                     SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INITIALLY_COMPILABLE};
3405            }else
3406            {
3407
3408                updCols = new int[] {SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID,
3409                                         SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED,
3410                                         SYSSTATEMENTSRowFactory.SYSSTATEMENTS_USINGTEXT,
3411                                         SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE };
3412            }
3413        }
3414        else
3415        {
3416            updCols = new int[] {SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID} ;
3417        }
3418            
3419        idOrderable = getValueAsDVD(spsd.getUUID());
3420
3421        /* Set up the start/stop position for the scan */
3422        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
3423        keyRow1.setColumn(1, idOrderable);
3424
3425        row = rf.makeSYSSTATEMENTSrow(false, // don't compile
3426
spsd);
3427
3428        /*
3429        ** Not updating any indexes
3430        */

3431        boolean[] bArray = new boolean[2];
3432
3433        /*
3434        ** Partial update
3435        */

3436        ti.updateRow(keyRow1, row,
3437                     SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID,
3438                     bArray,
3439                     updCols,
3440                     tc,
3441                     wait);
3442
3443
3444        /*
3445        ** If we don't need to update the parameter
3446        ** descriptors, we are done.
3447        */

3448        if (!updateParamDescriptors)
3449        {
3450            return;
3451        }
3452
3453        /*
3454        ** Set the defaults and datatypes for the parameters, if
3455        ** there are parameters.
3456        */

3457        DataTypeDescriptor[] params = spsd.getParams();
3458        if (params == null)
3459        {
3460            return;
3461        }
3462
3463        if(firstCompilation)
3464        {
3465            /*beetle:5119, reason for doing add here instead of update
3466             *is with NOCOMPILE option of create statement/boot time SPS,
3467             *SPS statement is not compiled to find out the parameter info.
3468             *Because of the parameter info was not inserted at SPSDescriptor
3469             *creation time. As this is the first time we are compiling paramter
3470             *infor should be inserted instead of the update.
3471             */

3472            addSPSParams(spsd, tc, wait);
3473        }
3474        else
3475        {
3476            Object JavaDoc[] parameterDefaults = spsd.getParameterDefaults();
3477
3478            /*
3479            ** Update each column with the new defaults and with
3480            ** the new datatypes. It is possible that someone has
3481            ** done a drop/create on the underlying table and
3482            ** changed the type of a column, which has changed
3483            ** the type of a parameter to our statement.
3484            */

3485            int[] columnsToSet = new int[2];
3486            columnsToSet[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDATATYPE;
3487            columnsToSet[1] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDEFAULT;
3488
3489            UUID uuid = spsd.getUUID();
3490
3491            for (int index = 0; index < params.length; index++)
3492            {
3493                int parameterId = index + 1;
3494
3495            //RESOLVEAUTOINCREMENT
3496
ColumnDescriptor cd = new ColumnDescriptor("PARAM" + parameterId,
3497                                          parameterId, // position
3498
params[index],
3499                                          ((parameterDefaults == null) || // default
3500
(index >= parameterDefaults.length)) ?
3501                                          (DataValueDescriptor)null :
3502                                          (DataValueDescriptor)parameterDefaults[index],
3503                                          (DefaultInfo) null,
3504                                          uuid,
3505                                          (UUID) null,
3506                                          0, 0);
3507                                        
3508                updateColumnDescriptor(cd,
3509                                       cd.getReferencingUUID(),
3510                                       cd.getColumnName(),
3511                                       columnsToSet,
3512                                       tc,
3513                                       wait);
3514            }
3515        }
3516    }
3517
3518    /**
3519     * @see DataDictionary#invalidateAllSPSPlans
3520     * @exception StandardException Thrown on error
3521     */

3522    public void invalidateAllSPSPlans() throws StandardException
3523    {
3524        LanguageConnectionContext lcc = (LanguageConnectionContext)
3525            ContextService.getContext(LanguageConnectionContext.CONTEXT_ID);
3526        startWriting(lcc);
3527
3528        for (java.util.Iterator JavaDoc li = getAllSPSDescriptors().iterator(); li.hasNext(); )
3529        {
3530            SPSDescriptor spsd = (SPSDescriptor) li.next();
3531            spsd.makeInvalid(DependencyManager.USER_RECOMPILE_REQUEST, lcc);
3532        }
3533    }
3534
3535
3536    /**
3537     * Mark all SPS plans in the data dictionary invalid. This does
3538     * not invalidate cached plans. This function is for use by
3539     * the boot-up code.
3540     * @exception StandardException Thrown on error
3541     */

3542    void clearSPSPlans() throws StandardException
3543    {
3544        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3545        faultInTabInfo(ti);
3546
3547        TransactionController tc = getTransactionExecute();
3548
3549        FormatableBitSet columnToReadSet = new FormatableBitSet(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT);
3550        FormatableBitSet columnToUpdateSet = new FormatableBitSet(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT);
3551        columnToUpdateSet.set(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID -1);
3552        columnToUpdateSet.set(SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE -1);
3553
3554        DataValueDescriptor[] replaceRow =
3555            new DataValueDescriptor[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COLUMN_COUNT];
3556
3557        /* Set up a couple of row templates for fetching CHARS */
3558
3559        replaceRow[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID - 1] =
3560            dvf.getDataValue(false);
3561        replaceRow[SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE - 1] =
3562            dvf.getDataValue((Object JavaDoc) null);
3563
3564        /* Scan the entire heap */
3565        ScanController sc =
3566            tc.openScan(
3567                ti.getHeapConglomerate(),
3568                false,
3569                TransactionController.OPENMODE_FORUPDATE,
3570                TransactionController.MODE_TABLE,
3571                TransactionController.ISOLATION_REPEATABLE_READ,
3572                columnToReadSet,
3573                (DataValueDescriptor[]) null,
3574                ScanController.NA,
3575                (Qualifier[][]) null,
3576                (DataValueDescriptor[]) null,
3577                ScanController.NA);
3578
3579        while (sc.fetchNext((DataValueDescriptor[]) null))
3580        {
3581            /* Replace the column in the table */
3582            sc.replace(replaceRow, columnToUpdateSet);
3583        }
3584
3585        sc.close();
3586    }
3587
3588    /**
3589     * Drops the given SPSDescriptor.
3590     *
3591     * @param descriptor The descriptor to drop
3592     * @param tc The TransactionController.
3593     *
3594     * @exception StandardException Thrown on failure
3595     */

3596    public void dropSPSDescriptor(SPSDescriptor descriptor,
3597            TransactionController tc)
3598                        throws StandardException
3599    {
3600        dropSPSDescriptor(descriptor.getUUID(), tc);
3601    }
3602
3603    /**
3604     * Drops the given SPSDescriptor.
3605     *
3606     * @param uuid the statement uuid
3607     * @param tc The TransactionController.
3608     *
3609     * @exception StandardException Thrown on failure
3610     */

3611    public void dropSPSDescriptor
3612    (
3613        UUID uuid,
3614        TransactionController tc
3615    ) throws StandardException
3616    {
3617        DataValueDescriptor stmtIdOrderable;
3618        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3619
3620        stmtIdOrderable = getValueAsDVD(uuid);
3621
3622        /* Set up the start/stop position for the scan */
3623        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
3624        keyRow.setColumn(1, stmtIdOrderable);
3625
3626        ti.deleteRow( tc, keyRow, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID );
3627
3628        /* drop all columns in SYSCOLUMNS */
3629        dropAllColumnDescriptors(uuid, tc);
3630    }
3631
3632    /**
3633     * Get every statement in this database.
3634     * Return the SPSDescriptors in an list.
3635     *
3636     * @return the list of descriptors
3637     *
3638     * @exception StandardException Thrown on failure
3639     */

3640    public List getAllSPSDescriptors()
3641        throws StandardException
3642    {
3643        TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
3644
3645        List list = newSList();
3646
3647        getDescriptorViaHeap(
3648                        (ScanQualifier[][]) null,
3649                        ti,
3650                        (TupleDescriptor) null,
3651                        list);
3652
3653        return list;
3654
3655    }
3656
3657    /**
3658     * Get every constraint in this database.
3659     * Note that this list of ConstraintDescriptors is
3660     * not going to be the same objects that are typically
3661     * cached off of the table descriptors, so this will
3662     * most likely instantiate some duplicate objects.
3663     *
3664     * @return the list of descriptors
3665     *
3666     * @exception StandardException Thrown on failure
3667     */

3668    private ConstraintDescriptorList getAllConstraintDescriptors()
3669        throws StandardException
3670    {
3671        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3672
3673        ConstraintDescriptorList list = new ConstraintDescriptorList();
3674
3675        getConstraintDescriptorViaHeap(
3676                        (ScanQualifier[][]) null,
3677                        ti,
3678                        (TupleDescriptor) null,
3679                        list);
3680        return list;
3681    }
3682
3683    /**
3684     * Get every trigger in this database.
3685     * Note that this list of TriggerDescriptors is
3686     * not going to be the same objects that are typically
3687     * cached off of the table descriptors, so this will
3688     * most likely instantiate some duplicate objects.
3689     *
3690     * @return the list of descriptors
3691     *
3692     * @exception StandardException Thrown on failure
3693     */

3694    private GenericDescriptorList getAllTriggerDescriptors()
3695        throws StandardException
3696    {
3697        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3698
3699        GenericDescriptorList list = new GenericDescriptorList();
3700
3701        getDescriptorViaHeap(
3702                        (ScanQualifier[][]) null,
3703                        ti,
3704                        (TupleDescriptor) null,
3705                        list);
3706        return list;
3707    }
3708
3709    /**
3710     * Get a TriggerDescriptor given its UUID.
3711     *
3712     * @param uuid The UUID
3713     *
3714     * @return The TriggerDescriptor for the constraint.
3715     *
3716     * @exception StandardException Thrown on failure
3717     */

3718    public TriggerDescriptor getTriggerDescriptor(UUID uuid)
3719                throws StandardException
3720    {
3721        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3722        DataValueDescriptor triggerIdOrderable = dvf.getCharDataValue(uuid.toString());
3723
3724        /* Set up the start/stop position for the scan */
3725        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
3726        keyRow.setColumn(1, triggerIdOrderable);
3727
3728        return (TriggerDescriptor)
3729                    getDescriptorViaIndex(
3730                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID,
3731                        keyRow,
3732                        (ScanQualifier [][]) null,
3733                        ti,
3734                        (TupleDescriptor) null,
3735                        (List) null,
3736                        false);
3737    }
3738
3739    /**
3740     * Get the stored prepared statement descriptor given
3741     * a sps name.
3742     *
3743     * @param name The sps name.
3744     * @param sd The schema descriptor.
3745     *
3746     * @return The TriggerDescriptor for the constraint.
3747     *
3748     * @exception StandardException Thrown on failure
3749     */

3750    public TriggerDescriptor getTriggerDescriptor(String JavaDoc name, SchemaDescriptor sd)
3751                throws StandardException
3752    {
3753        DataValueDescriptor schemaIDOrderable;
3754        DataValueDescriptor triggerNameOrderable;
3755        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3756
3757        /* Use triggerNameOrderable and schemaIdOrderable in both start
3758         * and stop position for scan.
3759         */

3760        triggerNameOrderable = dvf.getVarcharDataValue(name);
3761        schemaIDOrderable = dvf.getCharDataValue(sd.getUUID().toString());
3762
3763        /* Set up the start/stop position for the scan */
3764        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
3765        keyRow.setColumn(1, triggerNameOrderable);
3766        keyRow.setColumn(2, schemaIDOrderable);
3767
3768        return (TriggerDescriptor)
3769                    getDescriptorViaIndex(
3770                        SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX2_ID,
3771                        keyRow,
3772                        (ScanQualifier [][]) null,
3773                        ti,
3774                        (TupleDescriptor) null,
3775                        (List) null,
3776                        false);
3777    }
3778
3779    /**
3780     * Load up the trigger descriptor list for this table
3781     * descriptor and return it. If the descriptor list
3782     * is already loaded up, it is retuned without further
3783     * ado.
3784     *
3785     * @param td The table descriptor.
3786     *
3787     * @return The ConstraintDescriptorList for the table
3788     *
3789     * @exception StandardException Thrown on failure
3790     */

3791    public GenericDescriptorList getTriggerDescriptors(TableDescriptor td)
3792        throws StandardException
3793    {
3794        GenericDescriptorList gdl;
3795
3796        if (td == null)
3797        {
3798            return getAllTriggerDescriptors();
3799        }
3800
3801        /* Build the TableDescriptor's TDL if it is currently empty */
3802        gdl = td.getTriggerDescriptorList();
3803
3804        /*
3805        ** Synchronize the building of the TDL. The TDL itself is created
3806        ** empty when the TD is created, so there is no need to synchronize
3807        ** the getting of the TDL.
3808        */

3809        synchronized(gdl)
3810        {
3811            if (!gdl.getScanned())
3812            {
3813                getTriggerDescriptorsScan(td, false);
3814            }
3815        }
3816
3817        return gdl;
3818    }
3819
3820    /**
3821     * Populate the GenericDescriptorList for the specified TableDescriptor.
3822     *
3823     * MT synchronization: it is assumed that the caller has synchronized
3824     * on the CDL in the given TD.
3825     *
3826     * @param td The TableDescriptor.
3827     * @param forUpdate Whether or not to open scan for update
3828     *
3829     * @exception StandardException Thrown on failure
3830     */

3831     private void getTriggerDescriptorsScan(TableDescriptor td, boolean forUpdate)
3832            throws StandardException
3833    {
3834        GenericDescriptorList gdl = (td).getTriggerDescriptorList();
3835        DataValueDescriptor tableIDOrderable = null;
3836        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3837
3838        /* Use tableIDOrderable in both start and stop positions for scan */
3839        tableIDOrderable = getValueAsDVD(td.getUUID());
3840
3841        /* Set up the start/stop position for the scan */
3842        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
3843
3844        keyRow.setColumn(1, tableIDOrderable);
3845
3846        getDescriptorViaIndex(
3847                    SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX3_ID,
3848                    keyRow,
3849                    (ScanQualifier [][]) null,
3850                    ti,
3851                    (TupleDescriptor) null,
3852                    gdl,
3853                    forUpdate);
3854        gdl.setScanned(true);
3855    }
3856
3857    /**
3858     * Drops the given TriggerDescriptor. WARNING: does
3859     * not drop its SPSes!!!
3860     *
3861     * @param descriptor The descriptor to drop
3862     * @param tc The TransactionController.
3863     *
3864     * @exception StandardException Thrown on failure
3865     */

3866    public void dropTriggerDescriptor
3867    (
3868        TriggerDescriptor descriptor,
3869        TransactionController tc
3870    ) throws StandardException
3871    {
3872        DataValueDescriptor idOrderable;
3873        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3874
3875        idOrderable = getValueAsDVD(descriptor.getUUID());
3876
3877        /* Set up the start/stop position for the scan */
3878        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
3879        keyRow.setColumn(1, idOrderable);
3880
3881        ti.deleteRow(tc, keyRow, SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID);
3882    }
3883
3884    /**
3885     * Update the trigger descriptor in question. Updates
3886     * every row in the base conglomerate that matches the uuid.
3887     *
3888     * @param triggerd The Trigger descriptor
3889     * @param formerUUID The UUID for this column in SYSTRIGGERS,
3890     * may differ from what is in triggerd if this
3891     * is the column that is being set.
3892     * @param colsToSet Array of ints of columns to be modified,
3893     * 1 based. May be null (all cols).
3894     * @param tc The TransactionController to use
3895     *
3896     * @exception StandardException Thrown on failure
3897     */

3898    public void updateTriggerDescriptor
3899    (
3900        TriggerDescriptor triggerd,
3901        UUID formerUUID,
3902        int[] colsToSet,
3903        TransactionController tc
3904    ) throws StandardException
3905    {
3906        ExecIndexRow keyRow1 = null;
3907        ExecRow row;
3908        DataValueDescriptor IDOrderable;
3909        DataValueDescriptor columnNameOrderable;
3910        TabInfoImpl ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
3911        SYSTRIGGERSRowFactory rf = (SYSTRIGGERSRowFactory) ti.getCatalogRowFactory();
3912
3913        /* Use objectID in both start
3914         * and stop position for index 1 scan.
3915         */

3916        IDOrderable = getValueAsDVD(formerUUID);
3917
3918        /* Set up the start/stop position for the scan */
3919        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
3920        keyRow1.setColumn(1, IDOrderable);
3921
3922        // build the row to be stuffed into SYSTRIGGERS.
3923
row = rf.makeRow(triggerd, null);
3924
3925        /*
3926        ** Figure out if the index in systriggers needs
3927        ** to be updated.
3928        */

3929        if (SanityManager.DEBUG)
3930        {
3931            SanityManager.ASSERT(rf.getNumIndexes() == 3,
3932                    "There are more indexes on systriggers than expected, the code herein needs to change");
3933        }
3934
3935        boolean[] bArray = new boolean[3];
3936
3937        /*
3938        ** Do we need to update indexes?
3939        */

3940        if (colsToSet == null)
3941        {
3942            bArray[0] = true;
3943            bArray[1] = true;
3944            bArray[2] = true;
3945        }
3946        else
3947        {
3948            /*
3949            ** Check the specific columns for indexed
3950            ** columns.
3951            */

3952            for (int i = 0; i < colsToSet.length; i++)
3953            {
3954                switch (colsToSet[i])
3955                {
3956                    case SYSTRIGGERSRowFactory.SYSTRIGGERS_TRIGGERID:
3957                        bArray[0] = true;
3958                        break;
3959
3960                    case SYSTRIGGERSRowFactory.SYSTRIGGERS_TRIGGERNAME:
3961                    case SYSTRIGGERSRowFactory.SYSTRIGGERS_SCHEMAID:
3962                        bArray[1] = true;
3963                        break;
3964                    
3965                    case SYSTRIGGERSRowFactory.SYSTRIGGERS_TABLEID:
3966                        bArray[2] = true;
3967                        break;
3968                }
3969            }
3970        }
3971
3972        ti.updateRow(keyRow1, row,
3973                     SYSTRIGGERSRowFactory.SYSTRIGGERS_INDEX1_ID,
3974                     bArray,
3975                     colsToSet,
3976                     tc);
3977    }
3978
3979
3980    /**
3981     * Get a ConstraintDescriptor given its UUID. Please
3982     * use getConstraintDescriptorById() is you have the
3983     * constraints table descriptor, it is much faster.
3984     *
3985     * @param uuid The UUID
3986     *
3987     *
3988     * @return The ConstraintDescriptor for the constraint.
3989     *
3990     * @exception StandardException Thrown on failure
3991     */

3992    public ConstraintDescriptor getConstraintDescriptor(UUID uuid)
3993                throws StandardException
3994    {
3995        DataValueDescriptor UUIDStringOrderable;
3996        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
3997
3998        /* Use UUIDStringOrderable in both start and stop positions for scan */
3999        UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
4000
4001        /* Set up the start/stop position for the scan */
4002        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
4003        keyRow.setColumn(1, UUIDStringOrderable);
4004
4005        return getConstraintDescriptorViaIndex(
4006                    SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
4007                    keyRow,
4008                    ti,
4009                    (TableDescriptor) null,
4010                    (ConstraintDescriptorList) null,
4011                    false);
4012    }
4013
4014    /**
4015     * Get a ConstraintDescriptor given its name and schema ID.
4016     * Please use getConstraintDescriptorByName() if you have the
4017     * constraint's table descriptor, it is much faster.
4018     *
4019     * @param constraintName Constraint name.
4020     * @param schemaID The schema UUID
4021     *
4022     * @return The ConstraintDescriptor for the constraint.
4023     *
4024     * @exception StandardException Thrown on failure
4025     */

4026    public ConstraintDescriptor getConstraintDescriptor
4027    (
4028        String JavaDoc constraintName,
4029        UUID schemaID
4030    )
4031        throws StandardException
4032    {
4033        DataValueDescriptor UUIDStringOrderable;
4034        DataValueDescriptor constraintNameOrderable;
4035        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4036
4037        /* Construct keys for both start and stop positions for scan */
4038        constraintNameOrderable = dvf.getVarcharDataValue(constraintName);
4039        UUIDStringOrderable = dvf.getCharDataValue(schemaID.toString());
4040
4041        /* Set up the start/stop position for the scan */
4042        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
4043        keyRow.setColumn(1, constraintNameOrderable);
4044        keyRow.setColumn(2, UUIDStringOrderable);
4045
4046        return getConstraintDescriptorViaIndex(
4047                    SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID,
4048                    keyRow,
4049                    ti,
4050                    (TableDescriptor) null,
4051                    (ConstraintDescriptorList) null,
4052                    false);
4053    }
4054
4055    /** get all the statistiscs descriptors for a given table.
4056     * @param td Table Descriptor for which I need statistics
4057     */

4058    public List getStatisticsDescriptors(TableDescriptor td)
4059        throws StandardException
4060    {
4061        TabInfoImpl ti = getNonCoreTI(SYSSTATISTICS_CATALOG_NUM);
4062        List statDescriptorList = newSList();
4063        DataValueDescriptor UUIDStringOrderable;
4064
4065        /* set up the start/stop position for the scan */
4066        UUIDStringOrderable = dvf.getCharDataValue(td.getUUID().toString());
4067        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
4068        keyRow.setColumn(1, UUIDStringOrderable);
4069        
4070        getDescriptorViaIndex(SYSSTATISTICSRowFactory.SYSSTATISTICS_INDEX1_ID,
4071                              keyRow,
4072                              (ScanQualifier [][])null,
4073                              ti,
4074                              (TupleDescriptor)null,
4075                              statDescriptorList, false);
4076
4077        return statDescriptorList;
4078    }
4079    
4080    /**
4081     * Load up the constraint descriptor list for this table
4082     * descriptor and return it. If the descriptor list
4083     * is already loaded up, it is retuned without further
4084     * ado. If no table descriptor is passed in, then all
4085     * constraint descriptors are retrieved. Note that in
4086     * this case, the constraint descriptor objects may be
4087     * duplicates of constraint descriptors that are hung
4088     * off of the table descriptor cache.
4089     *
4090     * @param td The table descriptor. If null,
4091     * all constraint descriptors are returned.
4092     *
4093     *
4094     * @return The ConstraintDescriptorList for the table
4095     *
4096     * @exception StandardException Thrown on failure
4097     */

4098    public ConstraintDescriptorList getConstraintDescriptors(TableDescriptor td)
4099        throws StandardException
4100    {
4101        ConstraintDescriptorList cdl;
4102
4103        if (td == null)
4104        {
4105            return getAllConstraintDescriptors();
4106        }
4107
4108        /* RESOLVE - need to look at multi-user aspects of hanging constraint
4109         * descriptor list off of table descriptor when we restore the cache.
4110         */

4111
4112        /* Build the TableDescriptor's CDL if it is currently empty */
4113        cdl = td.getConstraintDescriptorList();
4114
4115        /*
4116        ** Synchronize the building of the CDL. The CDL itself is created
4117        ** empty when the TD is created, so there is no need to synchronize
4118        ** the getting of the CDL.
4119        */

4120        synchronized(cdl)
4121        {
4122            if (! cdl.getScanned())
4123            {
4124                getConstraintDescriptorsScan(td, false);
4125            }
4126        }
4127
4128        return cdl;
4129    }
4130
4131    /**
4132     * Convert a constraint descriptor list into a list
4133     * of active constraints, that is, constraints which
4134     * must be enforced. For the Core product, these
4135     * are just the constraints on the original list.
4136     * However, during REFRESH we may have deferred some
4137     * constraints until statement end. This method returns
4138     * the corresponding list of constraints which AREN'T
4139     * deferred.
4140     *
4141     * @param cdl The constraint descriptor list to wrap with
4142     * an Active constraint descriptor list.
4143     *
4144     * @return The corresponding Active ConstraintDescriptorList
4145     *
4146     * @exception StandardException Thrown on failure
4147     */

4148    public ConstraintDescriptorList getActiveConstraintDescriptors(ConstraintDescriptorList cdl)
4149        throws StandardException
4150    { return cdl; }
4151
4152    /**
4153     * Reports whether an individual constraint must be
4154     * enforced. For the Core product, this routine always
4155     * returns true.
4156     *
4157     * However, during REFRESH we may have deferred some
4158     * constraints until statement end. This method returns
4159     * false if the constraint deferred
4160     *
4161     * @param constraint the constraint to check
4162     *
4163     *
4164     * @return The corresponding Active ConstraintDescriptorList
4165     *
4166     * @exception StandardException Thrown on failure
4167     */

4168    public boolean activeConstraint( ConstraintDescriptor constraint )
4169        throws StandardException
4170    { return true; }
4171
4172    /**
4173     * Get the constraint descriptor given a table and the UUID String
4174     * of the backing index.
4175     *
4176     * @param td The table descriptor.
4177     * @param uuid the UUID for the backing index.
4178     *
4179     * @return The ConstraintDescriptor for the constraint.
4180     *
4181     * @exception StandardException Thrown on failure
4182     */

4183    public ConstraintDescriptor getConstraintDescriptor(TableDescriptor td,
4184                                                        UUID uuid)
4185                throws StandardException
4186    {
4187        return getConstraintDescriptors(td).getConstraintDescriptor(uuid);
4188    }
4189
4190
4191    /**
4192     * Get the constraint descriptor given a table and the UUID String
4193     * of the constraint
4194     *
4195     * @param td The table descriptor.
4196     * @param uuid The UUID for the constraint
4197     *
4198     * @return The ConstraintDescriptor for the constraint.
4199     *
4200     * @exception StandardException Thrown on failure
4201     */

4202    public ConstraintDescriptor getConstraintDescriptorById
4203    (
4204        TableDescriptor td,
4205        UUID uuid
4206    )
4207        throws StandardException
4208    {
4209        return getConstraintDescriptors(td).getConstraintDescriptorById(uuid);
4210    }
4211
4212    /**
4213     * Get the constraint descriptor given a TableDescriptor and the constraint name.
4214     *
4215     * @param td The table descriptor.
4216     * @param sd The schema descriptor for the constraint
4217     * @param constraintName The constraint name.
4218     * @param forUpdate Whether or not access is for update
4219     *
4220     * @return The ConstraintDescriptor for the constraint.
4221     *
4222     * @exception StandardException Thrown on failure
4223     */

4224    public ConstraintDescriptor getConstraintDescriptorByName(TableDescriptor td,
4225                                                              SchemaDescriptor sd,
4226                                                              String JavaDoc constraintName,
4227                                                              boolean forUpdate)
4228                throws StandardException
4229    {
4230        /* If forUpdate, then we need to actually read from the table. */
4231        if (forUpdate)
4232        {
4233            td.emptyConstraintDescriptorList();
4234            getConstraintDescriptorsScan(td, true);
4235        }
4236        return getConstraintDescriptors(td).getConstraintDescriptorByName(sd, constraintName);
4237    }
4238
4239    /**
4240     * Populate the ConstraintDescriptorList for the specified TableDescriptor.
4241     *
4242     * MT synchronization: it is assumed that the caller has synchronized
4243     * on the CDL in the given TD.
4244     *
4245     * @param td The TableDescriptor.
4246     * @param forUpdate Whether or not to open scan for update
4247     *
4248     * @exception StandardException Thrown on failure
4249     */

4250     private void getConstraintDescriptorsScan(TableDescriptor td, boolean forUpdate)
4251            throws StandardException
4252    {
4253        ConstraintDescriptorList cdl = td.getConstraintDescriptorList();
4254        DataValueDescriptor tableIDOrderable = null;
4255        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4256
4257        /* Use tableIDOrderable in both start and stop positions for scan */
4258        tableIDOrderable = getValueAsDVD(td.getUUID());
4259
4260        /* Set up the start/stop position for the scan */
4261        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
4262
4263        keyRow.setColumn(1, tableIDOrderable);
4264
4265        getConstraintDescriptorViaIndex(
4266                    SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX3_ID,
4267                    keyRow,
4268                    ti,
4269                    td,
4270                    cdl,
4271                    forUpdate);
4272        cdl.setScanned(true);
4273    }
4274
4275    /**
4276     * Return a (single or list of) ConstraintDescriptor(s) from
4277     * SYSCONSTRAINTS where the access is from the index to the heap.
4278     *
4279     * @param indexId The id of the index (0 to # of indexes on table) to use
4280     * @param keyRow The supplied ExecIndexRow for search
4281     * @param ti The TabInfoImpl to use
4282     * @param td The TableDescriptor, if supplied.
4283     * @param dList The list to build, if supplied. If null, then caller expects
4284     * a single descriptor
4285     * @param forUpdate Whether or not to open scan for update
4286     *
4287     * @return The last matching descriptor
4288     *
4289     * @exception StandardException Thrown on error
4290     */

4291    protected ConstraintDescriptor getConstraintDescriptorViaIndex(
4292                        int indexId,
4293                        ExecIndexRow keyRow,
4294                        TabInfoImpl ti,
4295                        TableDescriptor td,
4296                        ConstraintDescriptorList dList,
4297                        boolean forUpdate)
4298            throws StandardException
4299    {
4300        SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
4301        ConglomerateController heapCC;
4302        ConstraintDescriptor cd = null;
4303        ExecIndexRow indexRow1;
4304        ExecIndexRow indexTemplateRow;
4305        ExecRow outRow;
4306        RowLocation baseRowLocation;
4307        ScanController scanController;
4308        TransactionController tc;
4309
4310        // Get the current transaction controller
4311
tc = getTransactionCompile();
4312
4313        outRow = rf.makeEmptyRow();
4314
4315        heapCC =
4316            tc.openConglomerate(
4317                ti.getHeapConglomerate(), false, 0,
4318                TransactionController.MODE_RECORD,
4319                TransactionController.ISOLATION_REPEATABLE_READ);
4320
4321
4322        /* Scan the index and go to the data pages for qualifying rows to
4323         * build the column descriptor.
4324         */

4325        scanController = tc.openScan(
4326                ti.getIndexConglomerate(indexId), // conglomerate to open
4327
false, // don't hold open across commit
4328
(forUpdate) ? TransactionController.OPENMODE_FORUPDATE : 0,
4329                TransactionController.MODE_RECORD,
4330                TransactionController.ISOLATION_REPEATABLE_READ,
4331                (FormatableBitSet) null, // all fields as objects
4332
keyRow.getRowArray(), // start position - exact key match.
4333
ScanController.GE, // startSearchOperation
4334
null, //scanQualifier,
4335
keyRow.getRowArray(), // stop position - exact key match.
4336
ScanController.GT); // stopSearchOperation
4337

4338        while (scanController.next())
4339        {
4340            SubConstraintDescriptor subCD = null;
4341
4342            // create an index row template
4343
indexRow1 = getIndexRowFromHeapRow(
4344                                    ti.getIndexRowGenerator(indexId),
4345                                    heapCC.newRowLocationTemplate(),
4346                                    outRow);
4347
4348            scanController.fetch(indexRow1.getRowArray());
4349
4350            baseRowLocation = (RowLocation) indexRow1.getColumn(
4351                                                indexRow1.nColumns());
4352
4353            boolean base_row_exists =
4354                heapCC.fetch(
4355                    baseRowLocation, outRow.getRowArray(), (FormatableBitSet) null);
4356
4357            if (SanityManager.DEBUG)
4358            {
4359                // it can not be possible for heap row to disappear while
4360
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
4361
SanityManager.ASSERT(base_row_exists, "base row doesn't exist");
4362            }
4363
4364            switch (rf.getConstraintType(outRow))
4365            {
4366                case DataDictionary.PRIMARYKEY_CONSTRAINT:
4367                case DataDictionary.FOREIGNKEY_CONSTRAINT:
4368                case DataDictionary.UNIQUE_CONSTRAINT:
4369                    subCD = getSubKeyConstraint(
4370                                rf.getConstraintId(outRow), rf.getConstraintType(outRow));
4371                    break;
4372
4373                case DataDictionary.CHECK_CONSTRAINT:
4374                    subCD = getSubCheckConstraint(
4375                                rf.getConstraintId(outRow));
4376                    break;
4377
4378                default:
4379                    if (SanityManager.DEBUG)
4380                    {
4381                        SanityManager.THROWASSERT("unexpected value "+
4382                                "from rf.getConstraintType(outRow)" +
4383                                rf.getConstraintType(outRow));
4384                    }
4385            }
4386
4387            if (SanityManager.DEBUG)
4388            {
4389                SanityManager.ASSERT(subCD != null,
4390                                     "subCD is expected to be non-null");
4391            }
4392
4393            /* Cache the TD in the SCD so that
4394             * the row factory doesn't need to go
4395             * out to disk to get it.
4396             */

4397            subCD.setTableDescriptor(td);
4398
4399            cd = (ConstraintDescriptor) rf.buildDescriptor(
4400                                                outRow,
4401                                                subCD,
4402                                                this);
4403
4404            /* If dList is null, then caller only wants a single descriptor - we're done
4405             * else just add the current descriptor to the list.
4406             */

4407            if (dList == null)
4408            {
4409                break;
4410            }
4411            else
4412            {
4413                dList.add(cd);
4414            }
4415        }
4416        scanController.close();
4417        heapCC.close();
4418        return cd;
4419    }
4420
4421    /**
4422     * Return a (single or list of) catalog row descriptor(s) from
4423     * SYSCONSTRAINTS through a heap scan
4424     *
4425     * @param scanQualifiers qualifiers
4426     * @param ti The TabInfoImpl to use
4427     * @param parentTupleDescriptor The parentDescriptor, if applicable.
4428     * @param list The list to build, if supplied.
4429     * If null, then caller expects a single descriptor
4430     *
4431     * @return The last matching descriptor
4432     *
4433     * @exception StandardException Thrown on error
4434     */

4435    protected TupleDescriptor getConstraintDescriptorViaHeap(
4436                        ScanQualifier [][] scanQualifiers,
4437                        TabInfoImpl ti,
4438                        TupleDescriptor parentTupleDescriptor,
4439                        List list)
4440            throws StandardException
4441    {
4442        SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
4443        ConglomerateController heapCC;
4444        ExecRow outRow;
4445        ExecRow templateRow;
4446        ScanController scanController;
4447        TransactionController tc;
4448        ConstraintDescriptor cd = null;
4449
4450        // Get the current transaction controller
4451
tc = getTransactionCompile();
4452
4453        outRow = rf.makeEmptyRow();
4454
4455        /*
4456        ** Table scan
4457        */

4458        scanController = tc.openScan(
4459                ti.getHeapConglomerate(), // conglomerate to open
4460
false, // don't hold open across commit
4461
0, // for read
4462
TransactionController.MODE_TABLE,
4463                TransactionController.ISOLATION_REPEATABLE_READ,
4464                (FormatableBitSet) null, // all fields as objects
4465
(DataValueDescriptor[]) null, // start position - first row
4466
0, // startSearchOperation - none
4467
scanQualifiers, // scanQualifier,
4468
(DataValueDescriptor[]) null, // stop position -through last row
4469
0); // stopSearchOperation - none
4470

4471        try
4472        {
4473            while (scanController.fetchNext(outRow.getRowArray()))
4474            {
4475                SubConstraintDescriptor subCD = null;
4476    
4477                switch (rf.getConstraintType(outRow))
4478                {
4479                    case DataDictionary.PRIMARYKEY_CONSTRAINT:
4480                    case DataDictionary.FOREIGNKEY_CONSTRAINT:
4481                    case DataDictionary.UNIQUE_CONSTRAINT:
4482                        subCD = getSubKeyConstraint(
4483                                    rf.getConstraintId(outRow), rf.getConstraintType(outRow));
4484                        break;
4485    
4486                    case DataDictionary.CHECK_CONSTRAINT:
4487                        subCD = getSubCheckConstraint(
4488                                    rf.getConstraintId(outRow));
4489                        break;
4490    
4491                    default:
4492                        if (SanityManager.DEBUG)
4493                        {
4494                            SanityManager.THROWASSERT("unexpected value from "+
4495                                    " rf.getConstraintType(outRow) "
4496                                    + rf.getConstraintType(outRow));
4497                        }
4498                }
4499    
4500                if (SanityManager.DEBUG)
4501                {
4502                    SanityManager.ASSERT(subCD != null,
4503                                         "subCD is expected to be non-null");
4504                }
4505                cd = (ConstraintDescriptor) rf.buildDescriptor(
4506                                                    outRow,
4507                                                    subCD,
4508                                                    this);
4509    
4510                /* If dList is null, then caller only wants a single descriptor - we're done
4511                 * else just add the current descriptor to the list.
4512                 */

4513                if (list == null)
4514                {
4515                    break;
4516                }
4517                else
4518                {
4519                    list.add(cd);
4520                }
4521            }
4522        }
4523        finally
4524        {
4525            scanController.close();
4526        }
4527        return cd;
4528    }
4529
4530    /**
4531     * Return a table descriptor corresponding to the TABLEID
4532     * field in SYSCONSTRAINTS where CONSTRAINTID matches
4533     * the constraintId passsed in.
4534     *
4535     * @param constraintId The id of the constraint
4536     *
4537     * @return the corresponding table descriptor
4538     *
4539     * @exception StandardException Thrown on error
4540     */

4541    public TableDescriptor getConstraintTableDescriptor(UUID constraintId)
4542            throws StandardException
4543    {
4544        List slist = getConstraints(constraintId,
4545                                            SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
4546                                            SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_TABLEID);
4547
4548        if (slist.size() == 0)
4549        {
4550            return null;
4551        }
4552    
4553        // get the table descriptor
4554
return getTableDescriptor((UUID)slist.get(0));
4555    }
4556
4557    /**
4558     * Return a list of foreign keys constraints referencing
4559     * this constraint. Returns both enabled and disabled
4560     * foreign keys.
4561     *
4562     * @param constraintId The id of the referenced constraint
4563     *
4564     * @return list of constraints, empty of there are none
4565     *
4566     * @exception StandardException Thrown on error
4567     */

4568    public ConstraintDescriptorList getForeignKeys(UUID constraintId)
4569            throws StandardException
4570    {
4571        TabInfoImpl ti = getNonCoreTI(SYSFOREIGNKEYS_CATALOG_NUM);
4572        List fkList = newSList();
4573
4574        // Use constraintIDOrderable in both start and stop positions for scan
4575
DataValueDescriptor constraintIDOrderable = getValueAsDVD(constraintId);
4576
4577        /* Set up the start/stop position for the scan */
4578        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
4579        keyRow.setColumn(1, constraintIDOrderable);
4580
4581        getDescriptorViaIndex(
4582                        SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX2_ID,
4583                        keyRow,
4584                        (ScanQualifier [][]) null,
4585                        ti,
4586                        (TupleDescriptor) null,
4587                        fkList,
4588                        false);
4589
4590        SubKeyConstraintDescriptor cd;
4591        TableDescriptor td;
4592        ConstraintDescriptorList cdl = new ConstraintDescriptorList();
4593        ConstraintDescriptorList tmpCdl;
4594
4595        for (Iterator JavaDoc iterator = fkList.iterator(); iterator.hasNext(); )
4596        {
4597            cd = (SubKeyConstraintDescriptor) iterator.next();
4598            td = getConstraintTableDescriptor(cd.getUUID());
4599            cdl.add(getConstraintDescriptors(td).getConstraintDescriptorById(cd.getUUID()));
4600        }
4601
4602        return cdl;
4603    }
4604
4605    /**
4606     * Return an List which of the relevant column matching
4607     * the indexed criteria. If nothing matches, returns an
4608     * empty List (never returns null).
4609     *
4610     * @param uuid The id of the constraint
4611     * @param indexId The index id in SYS.SYSCONSTRAINTS
4612     * @param columnNum The column to retrieve
4613     *
4614     * @return a list of UUIDs in an List.
4615     *
4616     * @exception StandardException Thrown on error
4617     */

4618    public List getConstraints(UUID uuid, int indexId, int columnNum)
4619            throws StandardException
4620    {
4621        ExecIndexRow indexRow1;
4622        ExecIndexRow indexTemplateRow;
4623        ExecRow outRow;
4624        RowLocation baseRowLocation;
4625        ConglomerateController heapCC = null;
4626        ScanController scanController = null;
4627        TransactionController tc;
4628        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4629        SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
4630        TableDescriptor td = null;
4631        List slist = newSList();
4632
4633        if (SanityManager.DEBUG)
4634        {
4635            SanityManager.ASSERT(indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID ||
4636                                 indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX3_ID,
4637                                    "bad index id, must be one of the indexes on a uuid");
4638            SanityManager.ASSERT(columnNum > 0 &&
4639                                 columnNum <= SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT,
4640                                    "invalid column number for column to be retrieved");
4641        }
4642
4643        try
4644        {
4645            /* Use tableIDOrderable in both start and stop positions for scan */
4646            DataValueDescriptor orderable = getValueAsDVD(uuid);
4647    
4648            /* Set up the start/stop position for the scan */
4649            ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
4650            keyRow.setColumn(1, orderable);
4651
4652            // Get the current transaction controller
4653
tc = getTransactionCompile();
4654    
4655            outRow = rf.makeEmptyRow();
4656    
4657            heapCC =
4658                tc.openConglomerate(
4659                    ti.getHeapConglomerate(), false, 0,
4660                    TransactionController.MODE_RECORD,
4661                    TransactionController.ISOLATION_REPEATABLE_READ);
4662
4663            // create an index row template
4664
indexRow1 = getIndexRowFromHeapRow(
4665                                ti.getIndexRowGenerator(indexId),
4666                                heapCC.newRowLocationTemplate(),
4667                                outRow);
4668    
4669            // just interested in one column
4670
DataValueDescriptor[] rowTemplate =
4671              new DataValueDescriptor[SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT];
4672            FormatableBitSet columnToGetSet =
4673              new FormatableBitSet(SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT);
4674            columnToGetSet.set(columnNum - 1);
4675
4676            rowTemplate[columnNum - 1] =
4677                dvf.getNullChar((StringDataValue) null);
4678    
4679            // Scan the index and go to the data pages for qualifying rows
4680
scanController = tc.openScan(
4681                    ti.getIndexConglomerate(indexId),// conglomerate to open
4682
false, // don't hold open across commit
4683
0, // for read
4684
TransactionController.MODE_RECORD,
4685                    TransactionController.ISOLATION_REPEATABLE_READ,// RESOLVE: should be level 2
4686
(FormatableBitSet) null, // all fields as objects
4687
keyRow.getRowArray(), // start position - exact key match.
4688
ScanController.GE, // startSearchOperation
4689
null, // scanQualifier (none)
4690
keyRow.getRowArray(), // stop position - exact key match.
4691
ScanController.GT); // stopSearchOperation
4692

4693            while (scanController.fetchNext(indexRow1.getRowArray()))
4694            {
4695                baseRowLocation = (RowLocation)
4696                    indexRow1.getColumn(indexRow1.nColumns());
4697    
4698                // get the row and grab the uuid
4699
boolean base_row_exists =
4700                    heapCC.fetch(
4701                        baseRowLocation, rowTemplate, columnToGetSet);
4702
4703                if (SanityManager.DEBUG)
4704                {
4705                    // it can not be possible for heap row to disappear while
4706
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
4707
SanityManager.ASSERT(base_row_exists, "base row not found");
4708                }
4709
4710                slist.add(uuidFactory.recreateUUID(
4711                    (String JavaDoc)((DataValueDescriptor)rowTemplate[columnNum - 1]).getObject()));
4712            }
4713        }
4714        finally
4715        {
4716            if (heapCC != null)
4717            {
4718                heapCC.close();
4719            }
4720            if (scanController != null)
4721            {
4722                scanController.close();
4723            }
4724        }
4725        return slist;
4726    }
4727
4728    /**
4729     * Adds the given ConstraintDescriptor to the data dictionary,
4730     * associated with the given table and constraint type.
4731     *
4732     * @param descriptor The descriptor to add
4733     * @param tc The transaction controller
4734     *
4735     * @exception StandardException Thrown on error
4736     */

4737    public void addConstraintDescriptor(
4738            ConstraintDescriptor descriptor,
4739            TransactionController tc)
4740        throws StandardException
4741    {
4742        ExecRow row = null;
4743        int type = descriptor.getConstraintType();
4744        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4745        SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
4746        int insertRetCode;
4747
4748        if (SanityManager.DEBUG)
4749        {
4750            if (!(type == DataDictionary.PRIMARYKEY_CONSTRAINT ||
4751                                 type == DataDictionary.FOREIGNKEY_CONSTRAINT ||
4752                                 type == DataDictionary.UNIQUE_CONSTRAINT ||
4753                                 type == DataDictionary.CHECK_CONSTRAINT))
4754            {
4755                SanityManager.THROWASSERT("constraint type (" + type +
4756                    ") is unexpected value");
4757            }
4758        }
4759
4760        addDescriptor(descriptor, descriptor.getSchemaDescriptor(),
4761                      SYSCONSTRAINTS_CATALOG_NUM, false,
4762                      tc);
4763
4764        switch (type)
4765        {
4766            case DataDictionary.PRIMARYKEY_CONSTRAINT:
4767            case DataDictionary.FOREIGNKEY_CONSTRAINT:
4768            case DataDictionary.UNIQUE_CONSTRAINT:
4769                if (SanityManager.DEBUG)
4770                {
4771                    if (!(descriptor instanceof KeyConstraintDescriptor))
4772                    {
4773                        SanityManager.THROWASSERT(
4774                            "descriptor expected to be instanceof KeyConstraintDescriptor, " +
4775                            "not, " + descriptor.getClass().getName());
4776                    }
4777                }
4778
4779                addSubKeyConstraint((KeyConstraintDescriptor) descriptor, tc);
4780                break;
4781
4782            case DataDictionary.CHECK_CONSTRAINT:
4783                if (SanityManager.DEBUG)
4784                {
4785                    if (!(descriptor instanceof CheckConstraintDescriptor))
4786                    {
4787                        SanityManager.THROWASSERT("descriptor expected "+
4788                            "to be instanceof CheckConstraintDescriptorImpl, " +
4789                            "not, " + descriptor.getClass().getName());
4790                    }
4791                }
4792
4793                addDescriptor(descriptor, null, SYSCHECKS_CATALOG_NUM, true, tc);
4794                break;
4795        }
4796    }
4797
4798    /**
4799     * Update the constraint descriptor in question. Updates
4800     * every row in the base conglomerate.
4801     *
4802     * @param cd The Constraintescriptor
4803     * @param formerUUID The UUID for this column in SYSCONSTRAINTS,
4804     * may differ from what is in cd if this
4805     * is the column that is being set.
4806     * @param colsToSet Array of ints of columns to be modified,
4807     * 1 based. May be null (all cols).
4808     * @param tc The TransactionController to use
4809     *
4810     * @exception StandardException Thrown on failure
4811     */

4812    public void updateConstraintDescriptor(ConstraintDescriptor cd,
4813                                        UUID formerUUID,
4814                                        int[] colsToSet,
4815                                        TransactionController tc)
4816        throws StandardException
4817    {
4818        ExecIndexRow keyRow1 = null;
4819        ExecRow row;
4820        DataValueDescriptor IDOrderable;
4821        DataValueDescriptor columnNameOrderable;
4822        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4823        SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
4824
4825        /* Use objectID/columnName in both start
4826         * and stop position for index 1 scan.
4827         */

4828        IDOrderable = getValueAsDVD(formerUUID);
4829
4830        /* Set up the start/stop position for the scan */
4831        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
4832        keyRow1.setColumn(1, IDOrderable);
4833
4834        // build the row to be stuffed into SYSCONSTRAINTS.
4835
row = rf.makeRow(cd, null);
4836
4837        /*
4838        ** Figure out if the index in sysconstraints needs
4839        ** to be updated.
4840        */

4841        if (SanityManager.DEBUG)
4842        {
4843            SanityManager.ASSERT(rf.getNumIndexes() == 3,
4844                    "There are more indexes on sysconstraints than expected, the code herein needs to change");
4845        }
4846
4847        boolean[] bArray = new boolean[3];
4848
4849        /*
4850        ** Do we need to update indexes?
4851        */

4852        if (colsToSet == null)
4853        {
4854            bArray[0] = true;
4855            bArray[1] = true;
4856            bArray[2] = true;
4857        }
4858        else
4859        {
4860            /*
4861            ** Check the specific columns for indexed
4862            ** columns.
4863            */

4864            for (int i = 0; i < colsToSet.length; i++)
4865            {
4866                switch (colsToSet[i])
4867                {
4868                    case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_CONSTRAINTID:
4869                        bArray[0] = true;
4870                        break;
4871
4872                    case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_CONSTRAINTNAME:
4873                    case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_SCHEMAID:
4874                        bArray[1] = true;
4875                        break;
4876                    
4877                    case SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_TABLEID:
4878                        bArray[2] = true;
4879                        break;
4880                }
4881            }
4882        }
4883
4884        ti.updateRow(keyRow1, row,
4885                     SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID,
4886                     bArray,
4887                     colsToSet,
4888                     tc);
4889    }
4890
4891    /**
4892     * Drops the given ConstraintDescriptor that is associated
4893     * with the given table and constraint type from the data dictionary.
4894     *
4895     * @param table The table from which to drop the
4896     * constraint descriptor
4897     * @param descriptor The descriptor to drop
4898     * @param tc The TransactionController
4899     *
4900     * @exception StandardException Thrown on error
4901     */

4902    public void dropConstraintDescriptor(TableDescriptor table,
4903            ConstraintDescriptor descriptor,
4904            TransactionController tc)
4905        throws StandardException
4906    {
4907        ExecIndexRow keyRow = null;
4908        DataValueDescriptor schemaIDOrderable;
4909        DataValueDescriptor constraintNameOrderable;
4910        TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
4911
4912        switch (descriptor.getConstraintType())
4913        {
4914            case DataDictionary.PRIMARYKEY_CONSTRAINT:
4915            case DataDictionary.FOREIGNKEY_CONSTRAINT:
4916            case DataDictionary.UNIQUE_CONSTRAINT:
4917                dropSubKeyConstraint(
4918                            descriptor,
4919                            tc);
4920                break;
4921
4922            case DataDictionary.CHECK_CONSTRAINT:
4923                dropSubCheckConstraint(
4924                            descriptor.getUUID(),
4925                            tc);
4926                break;
4927        }
4928
4929        /* Use constraintNameOrderable and schemaIdOrderable in both start
4930         * and stop position for index 2 scan.
4931         */

4932        constraintNameOrderable = dvf.getVarcharDataValue(descriptor.getConstraintName());
4933        schemaIDOrderable = getValueAsDVD(descriptor.getSchemaDescriptor().getUUID());
4934
4935        /* Set up the start/stop position for the scan */
4936        keyRow = (ExecIndexRow) exFactory.getIndexableRow(2);
4937        keyRow.setColumn(1, constraintNameOrderable);
4938        keyRow.setColumn(2, schemaIDOrderable);
4939
4940        ti.deleteRow( tc, keyRow, SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX2_ID );
4941    }
4942
4943    /**
4944     * Drops all ConstraintDescriptors from the data dictionary
4945     * that are associated with the given table,
4946     *
4947     * @param table The table from which to drop all
4948     * constraint descriptors
4949     * @param tc The TransactionController
4950     *
4951     * @exception StandardException Thrown on error
4952     */

4953    public void dropAllConstraintDescriptors(TableDescriptor table,
4954                                             TransactionController tc)
4955        throws StandardException
4956    {
4957        ConstraintDescriptorList cdl = getConstraintDescriptors(table);
4958
4959        // Walk the table's CDL and drop each ConstraintDescriptor.
4960
for (Iterator JavaDoc iterator = cdl.iterator(); iterator.hasNext(); )
4961        {
4962            ConstraintDescriptor cd = (ConstraintDescriptor) iterator.next();
4963            dropConstraintDescriptor(table, cd, tc);
4964        }
4965
4966        /*
4967        ** Null out the table's constraint descriptor list. NOTE: This is
4968        ** not really necessary at the time of this writing (11/3/97), because
4969        ** we do not cache data dictionary objects while DDL is going on,
4970        ** but in the future it might be necessary.
4971        */

4972        table.setConstraintDescriptorList(null);
4973    }
4974
4975    /**
4976     * Get a SubKeyConstraintDescriptor from syskeys or sysforeignkeys for
4977     * the specified constraint id. For primary foreign and and unique
4978     * key constraints.
4979     *
4980     * @param constraintId The UUID for the constraint.
4981     * @param type The type of the constraint
4982     * (e.g. DataDictionary.FOREIGNKEY_CONSTRAINT)
4983     *
4984     * @return SubKeyConstraintDescriptor The Sub descriptor for the constraint.
4985     *
4986     * @exception StandardException Thrown on failure
4987     */

4988    public SubKeyConstraintDescriptor getSubKeyConstraint(UUID constraintId, int type)
4989        throws StandardException
4990    {
4991        DataValueDescriptor constraintIDOrderable = null;
4992        TabInfoImpl ti;
4993        int indexNum;
4994        int baseNum;
4995
4996        if (type == DataDictionary.FOREIGNKEY_CONSTRAINT)
4997        {
4998            baseNum = SYSFOREIGNKEYS_CATALOG_NUM;
4999            indexNum = SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX1_ID;
5000        }
5001        else
5002        {
5003            baseNum = SYSKEYS_CATALOG_NUM;
5004            indexNum = SYSKEYSRowFactory.SYSKEYS_INDEX1_ID;
5005        }
5006        ti = getNonCoreTI(baseNum);
5007
5008        /* Use constraintIDOrderable in both start and stop positions for scan */
5009        constraintIDOrderable = getValueAsDVD(constraintId);
5010
5011        /* Set up the start/stop position for the scan */
5012        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
5013        keyRow.setColumn(1, constraintIDOrderable);
5014
5015        return (SubKeyConstraintDescriptor)
5016                    getDescriptorViaIndex(
5017                        indexNum,
5018                        keyRow,
5019                        (ScanQualifier [][]) null,
5020                        ti,
5021                        (TupleDescriptor) null,
5022                        (List) null,
5023                        false);
5024    }
5025
5026    /**
5027     * Add the matching row to syskeys when adding a unique or primary key constraint
5028     *
5029     * @param descriptor The KeyConstraintDescriptor for the constraint.
5030     * @param tc The TransactionController
5031     *
5032     * @exception StandardException Thrown on failure
5033     */

5034    private void addSubKeyConstraint(KeyConstraintDescriptor descriptor,
5035                                     TransactionController tc)
5036        throws StandardException
5037    {
5038        ExecRow row;
5039        TabInfoImpl ti;
5040
5041        /*
5042        ** Foreign keys get a row in SYSFOREIGNKEYS, and
5043        ** all others get a row in SYSKEYS.
5044        */

5045        if (descriptor.getConstraintType()
5046                == DataDictionary.FOREIGNKEY_CONSTRAINT)
5047        {
5048            ForeignKeyConstraintDescriptor fkDescriptor =
5049                    (ForeignKeyConstraintDescriptor)descriptor;
5050
5051            if (SanityManager.DEBUG)
5052            {
5053                if (!(descriptor instanceof ForeignKeyConstraintDescriptor))
5054                {
5055                    SanityManager.THROWASSERT("descriptor not an fk descriptor, is "+
5056                        descriptor.getClass().getName());
5057                }
5058            }
5059            
5060            ti = getNonCoreTI(SYSFOREIGNKEYS_CATALOG_NUM);
5061            SYSFOREIGNKEYSRowFactory fkkeysRF = (SYSFOREIGNKEYSRowFactory)ti.getCatalogRowFactory();
5062
5063            row = fkkeysRF.makeRow(fkDescriptor, null);
5064
5065            /*
5066            ** Now we need to bump the reference count of the
5067            ** contraint that this FK references
5068            */

5069            ReferencedKeyConstraintDescriptor refDescriptor =
5070                            fkDescriptor.getReferencedConstraint();
5071
5072            refDescriptor.incrementReferenceCount();
5073
5074            int[] colsToSet = new int[1];
5075            colsToSet[0] = SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_REFERENCECOUNT;
5076
5077            updateConstraintDescriptor(refDescriptor,
5078                                            refDescriptor.getUUID(),
5079                                            colsToSet,
5080                                            tc);
5081        }
5082        else
5083        {
5084            ti = getNonCoreTI(SYSKEYS_CATALOG_NUM);
5085            SYSKEYSRowFactory keysRF = (SYSKEYSRowFactory) ti.getCatalogRowFactory();
5086
5087            // build the row to be stuffed into SYSKEYS
5088
row = keysRF.makeRow(descriptor, null);
5089        }
5090
5091        // insert row into catalog and all its indices
5092
ti.insertRow(row, tc, true);
5093    }
5094
5095    /**
5096     * Drop the matching row from syskeys when dropping a primary key
5097     * or unique constraint.
5098     *
5099     * @param constraint the constraint
5100     * @param tc The TransactionController
5101     *
5102     * @exception StandardException Thrown on failure
5103     */

5104    private void dropSubKeyConstraint(ConstraintDescriptor constraint, TransactionController tc)
5105        throws StandardException
5106    {
5107        ExecIndexRow keyRow1 = null;
5108        DataValueDescriptor constraintIdOrderable;
5109        TabInfoImpl ti;
5110        int baseNum;
5111        int indexNum;
5112
5113        if (constraint.getConstraintType()
5114                == DataDictionary.FOREIGNKEY_CONSTRAINT)
5115        {
5116            baseNum = SYSFOREIGNKEYS_CATALOG_NUM;
5117            indexNum = SYSFOREIGNKEYSRowFactory.SYSFOREIGNKEYS_INDEX1_ID;
5118
5119            /*
5120            ** If we have a foreign key, we need to decrement the
5121            ** reference count of the contraint that this FK references.
5122            ** We need to do this *before* we drop the foreign key
5123            ** because of the way FK.getReferencedConstraint() works.
5124            */

5125            if (constraint.getConstraintType()
5126                    == DataDictionary.FOREIGNKEY_CONSTRAINT)
5127            {
5128                ReferencedKeyConstraintDescriptor refDescriptor =
5129                        (ReferencedKeyConstraintDescriptor)
5130                                getConstraintDescriptor(
5131                                    ((ForeignKeyConstraintDescriptor)constraint).
5132                                            getReferencedConstraintId());
5133
5134                if (refDescriptor != null)
5135                {
5136                    refDescriptor.decrementReferenceCount();
5137    
5138                    int[] colsToSet = new int[1];
5139                    colsToSet[0] = SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_REFERENCECOUNT;
5140        
5141                    updateConstraintDescriptor(refDescriptor,
5142                                                refDescriptor.getUUID(),
5143                                                colsToSet,
5144                                                tc);
5145                }
5146            }
5147        }
5148        else
5149        {
5150            baseNum = SYSKEYS_CATALOG_NUM;
5151            indexNum = SYSKEYSRowFactory.SYSKEYS_INDEX1_ID;
5152        }
5153
5154        ti = getNonCoreTI(baseNum);
5155
5156        /* Use constraintIdOrderable in both start
5157         * and stop position for index 1 scan.
5158         */

5159        constraintIdOrderable = getValueAsDVD(constraint.getUUID());
5160
5161        /* Set up the start/stop position for the scan */
5162        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5163        keyRow1.setColumn(1, constraintIdOrderable);
5164
5165        ti.deleteRow( tc, keyRow1, indexNum);
5166    }
5167
5168    /**
5169     * Get a SubCheckConstraintDescriptor from syschecks for
5170     * the specified constraint id. (Useful for check constraints.)
5171     *
5172     * @param constraintId The UUID for the constraint.
5173     *
5174     * @return SubCheckConstraintDescriptor The Sub descriptor for the constraint.
5175     *
5176     * @exception StandardException Thrown on failure
5177     */

5178    private SubCheckConstraintDescriptor getSubCheckConstraint(UUID constraintId)
5179        throws StandardException
5180    {
5181        DataValueDescriptor constraintIDOrderable = null;
5182        TabInfoImpl ti = getNonCoreTI(SYSCHECKS_CATALOG_NUM);
5183        SYSCHECKSRowFactory rf = (SYSCHECKSRowFactory) ti.getCatalogRowFactory();
5184
5185        /* Use constraintIDOrderable in both start and stop positions for scan */
5186        constraintIDOrderable = getValueAsDVD(constraintId);
5187
5188        /* Set up the start/stop position for the scan */
5189        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
5190        keyRow.setColumn(1, constraintIDOrderable);
5191
5192        return (SubCheckConstraintDescriptor)
5193                    getDescriptorViaIndex(
5194                        SYSCHECKSRowFactory.SYSCHECKS_INDEX1_ID,
5195                        keyRow,
5196                        (ScanQualifier [][]) null,
5197                        ti,
5198                        (TupleDescriptor) null,
5199                        (List) null,
5200                        false);
5201    }
5202
5203    /**
5204     * Drop the matching row from syschecks when dropping a check constraint.
5205     *
5206     * @param constraintId The constraint id.
5207     * @param tc The TransactionController
5208     *
5209     * @exception StandardException Thrown on failure
5210     */

5211    private void dropSubCheckConstraint(UUID constraintId, TransactionController tc)
5212        throws StandardException
5213    {
5214        ExecIndexRow checkRow1 = null;
5215        DataValueDescriptor constraintIdOrderable;
5216        TabInfoImpl ti = getNonCoreTI(SYSCHECKS_CATALOG_NUM);
5217
5218        /* Use constraintIdOrderable in both start
5219         * and stop position for index 1 scan.
5220         */

5221        constraintIdOrderable = getValueAsDVD(constraintId);
5222
5223        /* Set up the start/stop position for the scan */
5224        checkRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5225        checkRow1.setColumn(1, constraintIdOrderable);
5226
5227        ti.deleteRow( tc, checkRow1, SYSCHECKSRowFactory.SYSCHECKS_INDEX1_ID );
5228    }
5229
5230    /**
5231     * Get all of the ConglomerateDescriptors in the database and
5232     * hash them by conglomerate number.
5233     * This is useful as a performance optimization for the locking VTIs.
5234     * NOTE: This method will scan SYS.SYSCONGLOMERATES at READ UNCOMMITTED.
5235     *
5236     * @param tc TransactionController for the transaction
5237     *
5238     * @return A Hashtable with all of the ConglomerateDescriptors
5239     * in the database hashed by conglomerate number.
5240     *
5241     * @exception StandardException Thrown on failure
5242     */

5243    public Hashtable JavaDoc hashAllConglomerateDescriptorsByNumber(TransactionController tc)
5244        throws StandardException
5245    {
5246        Hashtable JavaDoc ht = new Hashtable JavaDoc();
5247        ConglomerateDescriptor cd = null;
5248        ScanController scanController;
5249        ExecRow outRow;
5250        // ExecIndexRow keyRow = null;
5251
TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5252        SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti.getCatalogRowFactory();
5253
5254        outRow = rf.makeEmptyRow();
5255        scanController = tc.openScan(
5256                ti.getHeapConglomerate(), // conglomerate to open
5257
false, // don't hold open across commit
5258
0, // for read
5259
TransactionController.MODE_RECORD, // scans whole table.
5260
TransactionController.ISOLATION_READ_UNCOMMITTED,
5261                (FormatableBitSet) null, // all fields as objects
5262
(DataValueDescriptor[]) null, //keyRow.getRowArray(), // start position - first row
5263
ScanController.GE, // startSearchOperation
5264
(ScanQualifier [][]) null,
5265                (DataValueDescriptor[]) null, //keyRow.getRowArray(), // stop position - through last row
5266
ScanController.GT); // stopSearchOperation
5267

5268        // it is important for read uncommitted scans to use fetchNext() rather
5269
// than fetch, so that the fetch happens while latch is held, otherwise
5270
// the next() might position the scan on a row, but the subsequent
5271
// fetch() may find the row deleted or purged from the table.
5272
while (scanController.fetchNext(outRow.getRowArray()))
5273        {
5274            cd = (ConglomerateDescriptor) rf.buildDescriptor(
5275                                                outRow,
5276                                                (TupleDescriptor) null,
5277                                                this );
5278            Long JavaDoc hashKey = new Long JavaDoc(cd.getConglomerateNumber());
5279            ht.put(hashKey, cd);
5280        }
5281
5282        scanController.close();
5283
5284        return ht;
5285    }
5286
5287    /**
5288     * Get all of the TableDescriptors in the database and hash them by TableId
5289     * This is useful as a performance optimization for the locking VTIs.
5290     * NOTE: This method will scan SYS.SYSTABLES at READ UNCOMMITTED.
5291     *
5292     * @param tc TransactionController for the transaction
5293     *
5294     * @return A Hashtable with all of the Table descriptors in the database
5295     * hashed by TableId
5296     *
5297     *
5298     * @exception StandardException Thrown on failure
5299     */

5300    public Hashtable JavaDoc hashAllTableDescriptorsByTableId(TransactionController tc)
5301        throws StandardException
5302    {
5303        Hashtable JavaDoc ht = new Hashtable JavaDoc();
5304        ScanController scanController;
5305        ExecRow outRow;
5306        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
5307        SYSTABLESRowFactory
5308                    rf = (SYSTABLESRowFactory) ti.getCatalogRowFactory();
5309
5310        outRow = rf.makeEmptyRow();
5311
5312        scanController = tc.openScan(
5313                ti.getHeapConglomerate(), // sys.systable
5314
false, // don't hold open across commit
5315
0, // for read
5316
TransactionController.MODE_RECORD,// scans whole table.
5317
TransactionController.ISOLATION_READ_UNCOMMITTED,
5318                (FormatableBitSet) null, // all fields as objects
5319
(DataValueDescriptor[])null, // start position - first row
5320
ScanController.GE, // startSearchOperation
5321
(ScanQualifier[][])null, //scanQualifier,
5322
(DataValueDescriptor[])null, //stop position-through last row
5323
ScanController.GT); // stopSearchOperation
5324

5325        // it is important for read uncommitted scans to use fetchNext() rather
5326
// than fetch, so that the fetch happens while latch is held, otherwise
5327
// the next() might position the scan on a row, but the subsequent
5328
// fetch() may find the row deleted or purged from the table.
5329
while(scanController.fetchNext(outRow.getRowArray()))
5330        {
5331            TableDescriptor td = (TableDescriptor)
5332                rf.buildDescriptor(outRow, (TupleDescriptor)null,
5333                                   this);
5334            ht.put(td.getUUID(), td);
5335        }
5336        scanController.close();
5337        return ht;
5338    }
5339
5340    /**
5341     * Get a ConglomerateDescriptor given its UUID. If it is an index
5342     * conglomerate shared by at least another duplicate index, this returns
5343     * one of the ConglomerateDescriptors for those indexes.
5344     *
5345     * @param uuid The UUID
5346     *
5347     *
5348     * @return A ConglomerateDescriptor for the conglomerate.
5349     *
5350     * @exception StandardException Thrown on failure
5351     */

5352    public ConglomerateDescriptor getConglomerateDescriptor(UUID uuid)
5353                throws StandardException
5354    {
5355        ConglomerateDescriptor[] cds = getConglomerateDescriptors(uuid);
5356        if (cds.length == 0)
5357            return null;
5358        return cds[0];
5359    }
5360
5361    /**
5362     * Get an array of ConglomerateDescriptors given the UUID. If it is a
5363     * heap conglomerate or an index conglomerate not shared by a duplicate
5364     * index, the size of the return array is 1.
5365     *
5366     * @param uuid The UUID
5367     *
5368     *
5369     * @return An array of ConglomerateDescriptors for the conglomerate.
5370     * returns size 0 array if no such conglomerate.
5371     *
5372     * @exception StandardException Thrown on failure
5373     */

5374    public ConglomerateDescriptor[] getConglomerateDescriptors(UUID uuid)
5375                throws StandardException
5376    {
5377        DataValueDescriptor UUIDStringOrderable;
5378        SYSCONGLOMERATESRowFactory rf;
5379        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5380
5381        /* Use UUIDStringOrderable in both start and stop positions for scan */
5382        UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
5383
5384        /* Set up the start/stop position for the scan */
5385        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5386        keyRow.setColumn(1, UUIDStringOrderable);
5387
5388        List cdl = newSList();
5389
5390        getDescriptorViaIndex(
5391                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
5392                        keyRow,
5393                        (ScanQualifier [][]) null,
5394                        ti,
5395                        (TupleDescriptor) null,
5396                        cdl,
5397                        false);
5398
5399        ConglomerateDescriptor[] cda = new ConglomerateDescriptor[cdl.size()];
5400        cdl.toArray(cda);
5401        return cda;
5402
5403    }
5404
5405    /**
5406     * Get a ConglomerateDescriptor given its conglomerate number. If it is an
5407     * index conglomerate shared by at least another duplicate index, this
5408     * returns one of the ConglomerateDescriptors for those indexes.
5409     *
5410     * @param conglomerateNumber The conglomerate number.
5411     *
5412     *
5413     * @return A ConglomerateDescriptor for the conglomerate. Returns NULL if
5414     * no such conglomerate.
5415     *
5416     * @exception StandardException Thrown on failure
5417     */

5418    public ConglomerateDescriptor getConglomerateDescriptor(
5419                                    long conglomerateNumber)
5420                                    throws StandardException
5421    {
5422        ConglomerateDescriptor[] cds = getConglomerateDescriptors(conglomerateNumber);
5423        if (cds.length == 0)
5424            return null;
5425        return cds[0];
5426    }
5427
5428    /**
5429     * Get an array of conglomerate descriptors for the given conglomerate
5430     * number. If it is a heap conglomerate or an index conglomerate not
5431     * shared by a duplicate index, the size of the return array is 1.
5432     *
5433     * @param conglomerateNumber The number for the conglomerate
5434     * we're interested in
5435     *
5436     * @return An array of ConglomerateDescriptors that share the requested
5437     * conglomerate. Returns size 0 array if no such conglomerate.
5438     *
5439     * @exception StandardException Thrown on failure
5440     */

5441    public ConglomerateDescriptor[] getConglomerateDescriptors(
5442                                    long conglomerateNumber)
5443                                    throws StandardException
5444    {
5445        ScanController scanController;
5446        TransactionController tc;
5447        ExecRow outRow;
5448        DataValueDescriptor conglomNumberOrderable = null;
5449        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5450        SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti.getCatalogRowFactory();
5451
5452        conglomNumberOrderable =
5453                dvf.getDataValue(conglomerateNumber);
5454
5455        ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
5456        scanQualifier[0][0].setQualifier(
5457                rf.SYSCONGLOMERATES_CONGLOMERATENUMBER - 1, /* column number */
5458                conglomNumberOrderable,
5459                Orderable.ORDER_OP_EQUALS,
5460                false,
5461                false,
5462                false);
5463
5464        ConglomerateDescriptorList cdl = new ConglomerateDescriptorList();
5465        getDescriptorViaHeap(scanQualifier,
5466                                 ti,
5467                                 null,
5468                                 cdl);
5469
5470        int size = cdl.size();
5471        ConglomerateDescriptor[] cda = new ConglomerateDescriptor[size];
5472        for (int index = 0; index < size; index++)
5473            cda[index] = (ConglomerateDescriptor) cdl.get(index);
5474
5475        return cda;
5476    }
5477    
5478
5479    /**
5480     * Populate the ConglomerateDescriptorList for the
5481     * specified TableDescriptor by scanning sysconglomerates.
5482     *
5483     * MT synchronization: it is assumed that the caller has synchronized
5484     * on the CDL in the given TD.
5485     *
5486     * @param td The TableDescriptor.
5487     *
5488     * @exception StandardException Thrown on failure
5489     */

5490    private void getConglomerateDescriptorsScan(TableDescriptor td)
5491            throws StandardException
5492    {
5493        ConglomerateDescriptorList cdl = td.getConglomerateDescriptorList();
5494
5495        ExecIndexRow keyRow3 = null;
5496        DataValueDescriptor tableIDOrderable;
5497        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5498
5499        /* Use tableIDOrderable in both start and stop positions for scan */
5500        tableIDOrderable = getValueAsDVD(td.getUUID());
5501
5502        /* Set up the start/stop position for the scan */
5503        keyRow3 = (ExecIndexRow) exFactory.getIndexableRow(1);
5504        keyRow3.setColumn(1, tableIDOrderable);
5505
5506        getDescriptorViaIndex(
5507            SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID,
5508                keyRow3,
5509                (ScanQualifier [][]) null,
5510                ti,
5511                (TupleDescriptor) null,
5512                cdl,
5513                false);
5514    }
5515
5516    /**
5517     * Gets a conglomerate descriptor for the named index in the given schema,
5518     * getting an exclusive row lock on the matching row in
5519     * sys.sysconglomerates (for DDL concurrency) if requested.
5520     *
5521     * @param indexName The name of the index we're looking for
5522     * @param sd The schema descriptor
5523     * @param forUpdate Whether or not to get an exclusive row
5524     * lock on the row in sys.sysconglomerates.
5525     *
5526     * @return A ConglomerateDescriptor describing the requested
5527     * conglomerate. Returns NULL if no such conglomerate.
5528     *
5529     * @exception StandardException Thrown on failure
5530     */

5531    public ConglomerateDescriptor getConglomerateDescriptor(
5532                        String JavaDoc indexName,
5533                        SchemaDescriptor sd,
5534                        boolean forUpdate)
5535                        throws StandardException
5536    {
5537        ExecIndexRow keyRow2 = null;
5538        DataValueDescriptor nameOrderable;
5539        DataValueDescriptor schemaIDOrderable = null;
5540        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5541
5542        nameOrderable = dvf.getVarcharDataValue(indexName);
5543        schemaIDOrderable = getValueAsDVD(sd.getUUID());
5544
5545        /* Set up the start/stop position for the scan */
5546        keyRow2 = exFactory.getIndexableRow(2);
5547        keyRow2.setColumn(1, nameOrderable);
5548        keyRow2.setColumn(2, schemaIDOrderable);
5549
5550        return (ConglomerateDescriptor)
5551                    getDescriptorViaIndex(
5552                        SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID,
5553                        keyRow2,
5554                        (ScanQualifier [][]) null,
5555                        ti,
5556                        (TupleDescriptor) null,
5557                        (List) null,
5558                        forUpdate);
5559    }
5560                                    
5561    /**
5562     * Drops a conglomerate descriptor
5563     *
5564     * @param conglomerate The ConglomerateDescriptor for the conglomerate
5565     * @param tc TransactionController for the transaction
5566     *
5567     * @exception StandardException Thrown on failure
5568     */

5569    public void dropConglomerateDescriptor(
5570                        ConglomerateDescriptor conglomerate,
5571                        TransactionController tc)
5572                        throws StandardException
5573    {
5574        ExecIndexRow keyRow2 = null;
5575        DataValueDescriptor nameOrderable;
5576        DataValueDescriptor schemaIDOrderable = null;
5577        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5578
5579        nameOrderable = dvf.getVarcharDataValue(conglomerate.getConglomerateName());
5580        schemaIDOrderable = getValueAsDVD(conglomerate.getSchemaID());
5581
5582        /* Set up the start/stop position for the scan */
5583        keyRow2 = (ExecIndexRow) exFactory.getIndexableRow(2);
5584        keyRow2.setColumn(1, nameOrderable);
5585        keyRow2.setColumn(2, schemaIDOrderable);
5586
5587        ti.deleteRow( tc, keyRow2, SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX2_ID );
5588
5589    }
5590 
5591    /**
5592     * Drops all conglomerates associated with a table.
5593     *
5594     * @param td The TableDescriptor of the table
5595     * @param tc TransactionController for the transaction
5596     *
5597     * @exception StandardException Thrown on failure
5598     */

5599
5600    public void dropAllConglomerateDescriptors(
5601                        TableDescriptor td,
5602                        TransactionController tc)
5603                    throws StandardException
5604    {
5605        ExecIndexRow keyRow3 = null;
5606        DataValueDescriptor tableIDOrderable;
5607        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5608
5609        /* Use tableIDOrderable in both start
5610         * and stop position for index 3 scan.
5611         */

5612        tableIDOrderable = getValueAsDVD(td.getUUID());
5613
5614        /* Set up the start/stop position for the scan */
5615        keyRow3 = (ExecIndexRow) exFactory.getIndexableRow(1);
5616        keyRow3.setColumn(1, tableIDOrderable);
5617
5618
5619        ti.deleteRow( tc, keyRow3, SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX3_ID );
5620    }
5621
5622    /**
5623     * Update the conglomerateNumber for a ConglomerateDescriptor.
5624     * This is useful, in 1.3, when doing a bulkInsert into an
5625     * empty table where we insert into a new conglomerate.
5626     * (This will go away in 1.4.)
5627     *
5628     * @param cd The ConglomerateDescriptor
5629     * @param conglomerateNumber The new conglomerate number
5630     * @param tc The TransactionController to use
5631     *
5632     * @exception StandardException Thrown on failure
5633     */

5634    public void updateConglomerateDescriptor(ConglomerateDescriptor cd,
5635                                             long conglomerateNumber,
5636                                             TransactionController tc)
5637        throws StandardException
5638    {
5639        ConglomerateDescriptor[] cds = new ConglomerateDescriptor[1];
5640        cds[0] = cd;
5641        updateConglomerateDescriptor(cds, conglomerateNumber, tc);
5642    }
5643
5644    /**
5645     * Update all system schemas to have new authorizationId. This is needed
5646     * while upgrading pre-10.2 databases to 10.2 or later versions. From 10.2,
5647     * all system schemas would be owned by database owner's authorizationId.
5648     *
5649     * @param aid AuthorizationID of Database Owner
5650     * @param tc TransactionController to use
5651     *
5652     * @exception StandardException Thrown on failure
5653     */

5654    public void updateSystemSchemaAuthorization(String JavaDoc aid,
5655                                                TransactionController tc)
5656        throws StandardException
5657    {
5658        updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME, aid, tc);
5659        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME, aid, tc);
5660
5661        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME, aid, tc);
5662        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME, aid, tc);
5663        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME, aid, tc);
5664        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME, aid, tc);
5665        updateSchemaAuth(SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME, aid, tc);
5666
5667        updateSchemaAuth(SchemaDescriptor.STD_SQLJ_SCHEMA_NAME, aid, tc);
5668        updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME, aid, tc);
5669        updateSchemaAuth(SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME, aid, tc);
5670    }
5671
5672    /**
5673     * Update authorizationId of specified schemaName
5674     *
5675     * @param schemaName Schema Name of system schema
5676     * @param authorizationId authorizationId of new schema owner
5677     * @param tc The TransactionController to use
5678     *
5679     * @exception StandardException Thrown on failure
5680     */

5681    public void updateSchemaAuth(String JavaDoc schemaName,
5682                                 String JavaDoc authorizationId,
5683                                 TransactionController tc)
5684        throws StandardException
5685    {
5686        ExecIndexRow keyRow;
5687        DataValueDescriptor schemaNameOrderable;
5688        TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
5689
5690        /* Use schemaNameOrderable in both start
5691         * and stop position for index 1 scan.
5692         */

5693        schemaNameOrderable = dvf.getVarcharDataValue(schemaName);
5694
5695        /* Set up the start/stop position for the scan */
5696        keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
5697        keyRow.setColumn(1, schemaNameOrderable);
5698
5699        SYSSCHEMASRowFactory rf = (SYSSCHEMASRowFactory) ti.getCatalogRowFactory();
5700        ExecRow row = rf.makeEmptyRow();
5701
5702        row.setColumn(SYSSCHEMASRowFactory.SYSSCHEMAS_SCHEMAAID,
5703                      dvf.getVarcharDataValue(authorizationId));
5704
5705        boolean[] bArray = {false, false};
5706
5707        int[] colsToUpdate = {SYSSCHEMASRowFactory.SYSSCHEMAS_SCHEMAAID};
5708
5709        ti.updateRow(keyRow, row,
5710                     SYSSCHEMASRowFactory.SYSSCHEMAS_INDEX1_ID,
5711                     bArray,
5712                     colsToUpdate,
5713                     tc);
5714    }
5715
5716    /**
5717     * Update the conglomerateNumber for an array of ConglomerateDescriptors.
5718     * In case of more than one ConglomerateDescriptor, each descriptor
5719     * should be updated separately, conglomerate id is not same for all
5720     * the descriptors. Even when indexes are sharing the same
5721     * conglomerate(conglomerate number), conglomerate ids are unique.
5722     *
5723     * This is useful, in 1.3, when doing a bulkInsert into an
5724     * empty table where we insert into a new conglomerate.
5725     * (This will go away in 1.4.)
5726     *
5727     * @param cds The array of ConglomerateDescriptors
5728     * @param conglomerateNumber The new conglomerate number
5729     * @param tc The TransactionController to use
5730     *
5731     * @exception StandardException Thrown on failure
5732     */

5733    public void updateConglomerateDescriptor(ConglomerateDescriptor[] cds,
5734                                             long conglomerateNumber,
5735                                             TransactionController tc)
5736        throws StandardException
5737    {
5738        ExecIndexRow keyRow1 = null;
5739        ExecRow row;
5740        DataValueDescriptor conglomIDOrderable;
5741        TabInfoImpl ti = coreInfo[SYSCONGLOMERATES_CORE_NUM];
5742        SYSCONGLOMERATESRowFactory rf = (SYSCONGLOMERATESRowFactory) ti.getCatalogRowFactory();
5743        boolean[] bArray = {false, false, false};
5744
5745        for (int i = 0; i < cds.length; i++)
5746        {
5747            /* Use conglomIDOrderable in both start
5748             * and stop position for index 1 scan.
5749             */

5750            conglomIDOrderable = getValueAsDVD(cds[i].getUUID());
5751
5752            /* Set up the start/stop position for the scan */
5753            keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5754            keyRow1.setColumn(1, conglomIDOrderable);
5755
5756            cds[i].setConglomerateNumber(conglomerateNumber);
5757            // build the row to be stuffed into SYSCONGLOMERATES.
5758
row = rf.makeRow(cds[i], null);
5759
5760            // update row in catalog (no indexes)
5761
ti.updateRow(keyRow1, row,
5762                         SYSCONGLOMERATESRowFactory.SYSCONGLOMERATES_INDEX1_ID,
5763                         bArray,
5764                         (int[])null,
5765                         tc);
5766        }
5767
5768    }
5769
5770    
5771    /**
5772     * Gets a list of the dependency descriptors for the given dependent's id.
5773     *
5774     * @param dependentID The ID of the dependent we're interested in
5775     *
5776     * @return List Returns a list of DependencyDescriptors.
5777     * Returns an empty List if no stored dependencies for the
5778     * dependent's ID.
5779     *
5780     * @exception StandardException Thrown on failure
5781     */

5782    public List getDependentsDescriptorList(String JavaDoc dependentID)
5783        throws StandardException
5784    {
5785        List ddlList = newSList();
5786        DataValueDescriptor dependentIDOrderable;
5787        TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5788
5789        /* Use dependentIDOrderable in both start and stop positions for scan */
5790        dependentIDOrderable = dvf.getCharDataValue(dependentID);
5791
5792        /* Set up the start/stop position for the scan */
5793        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5794        keyRow.setColumn(1, dependentIDOrderable);
5795
5796        getDescriptorViaIndex(
5797            SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID,
5798            keyRow,
5799            (ScanQualifier [][]) null,
5800            ti,
5801            (TupleDescriptor) null,
5802            ddlList,
5803            false);
5804                
5805        return ddlList;
5806    }
5807
5808    /**
5809     * Gets a list of the dependency descriptors for the given provider's id.
5810     *
5811     * @param providerID The ID of the provider we're interested in
5812     *
5813     * @return List Returns a list of DependencyDescriptors.
5814     * Returns an empty List if no stored dependencies for the
5815     * provider's ID.
5816     *
5817     * @exception StandardException Thrown on failure
5818     */

5819    public List getProvidersDescriptorList(String JavaDoc providerID)
5820        throws StandardException
5821    {
5822        List ddlList = newSList();
5823        DataValueDescriptor providerIDOrderable;
5824        TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5825
5826        /* Use providerIDOrderable in both start and stop positions for scan */
5827        providerIDOrderable = dvf.getCharDataValue(providerID);
5828
5829        /* Set up the start/stop position for the scan */
5830        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
5831        keyRow.setColumn(1, providerIDOrderable);
5832
5833        getDescriptorViaIndex(
5834            SYSDEPENDSRowFactory.SYSDEPENDS_INDEX2_ID,
5835            keyRow,
5836            (ScanQualifier [][]) null,
5837            ti,
5838            (TupleDescriptor) null,
5839            ddlList,
5840            false);
5841
5842
5843
5844        return ddlList;
5845    }
5846
5847    /**
5848     * Build and return an List with DependencyDescriptors for
5849     * all of the stored dependencies.
5850     * This is useful for consistency checking.
5851     *
5852     * @return List List of all DependencyDescriptors.
5853     *
5854     * @exception StandardException Thrown on failure
5855     */

5856    public List getAllDependencyDescriptorsList()
5857                throws StandardException
5858    {
5859        ScanController scanController;
5860        TransactionController tc;
5861        ExecRow outRow;
5862        ExecRow templateRow;
5863        List ddl = newSList();
5864        TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5865        SYSDEPENDSRowFactory rf = (SYSDEPENDSRowFactory) ti.getCatalogRowFactory();
5866
5867
5868        // Get the current transaction controller
5869
tc = getTransactionCompile();
5870
5871        outRow = rf.makeEmptyRow();
5872
5873        scanController = tc.openScan(
5874            ti.getHeapConglomerate(), // conglomerate to open
5875
false, // don't hold open across commit
5876
0, // for read
5877
TransactionController.MODE_TABLE, // scans entire table.
5878
TransactionController.ISOLATION_REPEATABLE_READ,
5879            (FormatableBitSet) null, // all fields as objects
5880
null, // start position - first row
5881
ScanController.GE, // startSearchOperation
5882
null,
5883            null, // stop position - through last row
5884
ScanController.GT); // stopSearchOperation
5885

5886        while (scanController.fetchNext(outRow.getRowArray()))
5887        {
5888            DependencyDescriptor dependencyDescriptor;
5889
5890            dependencyDescriptor = (DependencyDescriptor)
5891                     rf.buildDescriptor(outRow,
5892                                                (TupleDescriptor) null,
5893                                                this);
5894
5895            ddl.add(dependencyDescriptor);
5896        }
5897
5898        scanController.close();
5899
5900        return ddl;
5901    }
5902
5903    /**
5904     * Drop a single dependency from the data dictionary.
5905     *
5906     * @param dd The DependencyDescriptor.
5907     * @param tc TransactionController for the transaction
5908     *
5909     * @exception StandardException Thrown on failure
5910     */

5911    public void dropStoredDependency(DependencyDescriptor dd,
5912                                    TransactionController tc )
5913                throws StandardException
5914    {
5915        ExecIndexRow keyRow1 = null;
5916        UUID dependentID = dd.getUUID();
5917        UUID providerID = dd.getProviderID();
5918        DataValueDescriptor dependentIDOrderable = getValueAsDVD(dependentID);
5919        TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5920
5921        /* Use dependentIDOrderable in both start
5922         * and stop position for index 1 scan.
5923         */

5924        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5925        keyRow1.setColumn(1, dependentIDOrderable);
5926
5927        // only drop the rows which have this providerID
5928
TupleFilter filter = new DropDependencyFilter( providerID );
5929
5930        ti.deleteRows( tc,
5931                       keyRow1, // start row
5932
ScanController.GE,
5933                       null, //qualifier
5934
filter, // filter on base row
5935
keyRow1, // stop row
5936
ScanController.GT,
5937                       SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID );
5938
5939    }
5940
5941
5942    /**
5943     * Remove all of the stored dependencies for a given dependent's ID
5944     * from the data dictionary.
5945     *
5946     * @param dependentsUUID Dependent's uuid
5947     * @param tc TransactionController for the transaction
5948     *
5949     * @exception StandardException Thrown on failure
5950     */

5951    public void dropDependentsStoredDependencies(UUID dependentsUUID,
5952                                       TransactionController tc)
5953                throws StandardException
5954    {
5955         dropDependentsStoredDependencies(dependentsUUID, tc, true);
5956    }
5957                
5958    /**
5959     * @inheritDoc
5960     */

5961    public void dropDependentsStoredDependencies(UUID dependentsUUID,
5962                                       TransactionController tc,
5963                                       boolean wait)
5964                throws StandardException
5965    {
5966        ExecIndexRow keyRow1 = null;
5967        DataValueDescriptor dependentIDOrderable;
5968        TabInfoImpl ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
5969
5970        /* Use dependentIDOrderable in both start
5971         * and stop position for index 1 scan.
5972         */

5973        dependentIDOrderable = getValueAsDVD(dependentsUUID);
5974
5975        /* Set up the start/stop position for the scan */
5976        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
5977        keyRow1.setColumn(1, dependentIDOrderable);
5978
5979        ti.deleteRow( tc, keyRow1, SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID,
5980                wait );
5981
5982    }
5983
5984    /**
5985     * Get the UUID Factory. (No need to make the UUIDFactory a module.)
5986     *
5987     * @return UUIDFactory The UUID Factory for this DataDictionary.
5988     */

5989    public UUIDFactory getUUIDFactory()
5990    {
5991        return uuidFactory;
5992    }
5993
5994    /**
5995     * Get a AliasDescriptor given its UUID.
5996     *
5997     * @param uuid The UUID
5998     *
5999     *
6000     * @return The AliasDescriptor for the alias.
6001     *
6002     * @exception StandardException Thrown on failure
6003     */

6004    public AliasDescriptor getAliasDescriptor(UUID uuid)
6005                throws StandardException
6006    {
6007        DataValueDescriptor UUIDStringOrderable;
6008        SYSALIASESRowFactory rf;
6009        TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
6010
6011        rf = (SYSALIASESRowFactory) ti.getCatalogRowFactory();
6012
6013        /* Use UUIDStringOrderable in both start and stop positions for scan */
6014        UUIDStringOrderable = dvf.getCharDataValue(uuid.toString());
6015
6016        /* Set up the start/stop position for the scan */
6017        ExecIndexRow keyRow = exFactory.getIndexableRow(1);
6018        keyRow.setColumn(1, UUIDStringOrderable);
6019
6020        return (AliasDescriptor)
6021                    getDescriptorViaIndex(
6022                        SYSALIASESRowFactory.SYSALIASES_INDEX2_ID,
6023                        keyRow,
6024                        (ScanQualifier [][]) null,
6025                        ti,
6026                        (TupleDescriptor) null,
6027                        (List) null,
6028                        false);
6029    }
6030
6031    /**
6032     * Get a AliasDescriptor by alias name and name space.
6033     * NOTE: caller responsible for handling no match.
6034     *
6035       @param schemaId schema identifier
6036     * @param aliasName The alias name.
6037     * @param nameSpace The alias type.
6038     *
6039     * @return AliasDescriptor AliasDescriptor for the alias name and name space
6040     *
6041     * @exception StandardException Thrown on failure
6042     */

6043    public AliasDescriptor getAliasDescriptor(String JavaDoc schemaId, String JavaDoc aliasName, char nameSpace)
6044            throws StandardException
6045    {
6046        DataValueDescriptor aliasNameOrderable;
6047        DataValueDescriptor nameSpaceOrderable;
6048        TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
6049        SYSALIASESRowFactory rf = (SYSALIASESRowFactory) ti.getCatalogRowFactory();
6050
6051        /* Use aliasNameOrderable and aliasTypeOrderable in both start
6052         * and stop position for scan.
6053         */

6054        aliasNameOrderable = dvf.getVarcharDataValue(aliasName);
6055        char[] charArray = new char[1];
6056        charArray[0] = nameSpace;
6057        nameSpaceOrderable = dvf.getCharDataValue(new String JavaDoc(charArray));
6058
6059        /* Set up the start/stop position for the scan */
6060        ExecIndexRow keyRow = exFactory.getIndexableRow(3);
6061        keyRow.setColumn(1, dvf.getCharDataValue(schemaId));
6062        keyRow.setColumn(2, aliasNameOrderable);
6063        keyRow.setColumn(3, nameSpaceOrderable);
6064
6065        return (AliasDescriptor)
6066                    getDescriptorViaIndex(
6067                        SYSALIASESRowFactory.SYSALIASES_INDEX1_ID,
6068                        keyRow,
6069                        (ScanQualifier [][]) null,
6070                        ti,
6071                        (TupleDescriptor) null,
6072                        (List) null,
6073                        false);
6074    }
6075
6076    /**
6077        Get the list of routines matching the schema and routine name.
6078        While we only support a single alias for a given name,namespace just
6079        return a list of zero or one item.
6080        If the schema is SYSFUN then do not use the system catalogs,
6081        but instead look up the routines from the in-meomry table driven
6082        by the contents of SYSFUN_FUNCTIONS.
6083     */

6084    public java.util.List JavaDoc getRoutineList(String JavaDoc schemaID, String JavaDoc routineName, char nameSpace)
6085        throws StandardException {
6086
6087        java.util.List JavaDoc list = new java.util.ArrayList JavaDoc();
6088        
6089        // Special in-memory table lookup for SYSFUN
6090
if (schemaID.equals(SchemaDescriptor.SYSFUN_SCHEMA_UUID)
6091                && nameSpace == AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR)
6092        {
6093            for (int f = 0; f < DataDictionaryImpl.SYSFUN_FUNCTIONS.length; f++)
6094            {
6095                String JavaDoc[] details = DataDictionaryImpl.SYSFUN_FUNCTIONS[f];
6096                String JavaDoc name = details[0];
6097                if (!name.equals(routineName))
6098                    continue;
6099                
6100                AliasDescriptor ad = DataDictionaryImpl.SYSFUN_AD[f];
6101                if (ad == null)
6102                {
6103                    // details[1] Return type
6104
TypeDescriptor rt =
6105                        DataTypeDescriptor.getBuiltInDataTypeDescriptor(details[1]);
6106
6107                    // details[4] - zero or single argument type
6108
String JavaDoc paramType = details[4];
6109                    TypeDescriptor[] pt;
6110                    String JavaDoc[] paramNames;
6111                    int[] paramModes;
6112                    int paramCount;
6113                    if (paramType != null)
6114                    {
6115                        paramNames = DataDictionaryImpl.SYSFUN_PNAME;
6116                        paramCount = 1;
6117                        paramModes = DataDictionaryImpl.SYSFUN_PMODE;
6118                        pt = new TypeDescriptor[1];
6119                        pt[0] =
6120                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(paramType);
6121                    }
6122                    else
6123                    {
6124                        // no parameters
6125
paramNames = null;
6126                        pt = null;
6127                        paramCount = 0;
6128                        paramModes = null;
6129                    }
6130                    
6131                    // details[3] = java method
6132
RoutineAliasInfo ai = new RoutineAliasInfo(details[3],
6133                            paramCount, paramNames,
6134                            pt, paramModes, 0,
6135                            RoutineAliasInfo.PS_JAVA, RoutineAliasInfo.NO_SQL,
6136                            false, rt);
6137
6138                    // details[2] = class name
6139
ad = new AliasDescriptor(this, uuidFactory.createUUID(), name,
6140                            uuidFactory.recreateUUID(schemaID),
6141                            details[2], AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR,
6142                            AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR,
6143                            true, ai, null);
6144
6145                    DataDictionaryImpl.SYSFUN_AD[f] = ad;
6146                }
6147                list.add(ad);
6148            }
6149            return list;
6150        }
6151        
6152        AliasDescriptor ad = getAliasDescriptor(schemaID, routineName, nameSpace);
6153        if (ad != null) {
6154            list.add(ad);
6155        }
6156        return list;
6157    }
6158
6159    /**
6160     * Drop a AliasDescriptor from the DataDictionary
6161     *
6162     * @param ad The AliasDescriptor to drop
6163     * @param tc The TransactionController
6164     *
6165     * @exception StandardException Thrown on failure
6166     */

6167
6168    public void dropAliasDescriptor(AliasDescriptor ad,
6169                                    TransactionController tc)
6170            throws StandardException
6171    {
6172        ExecIndexRow keyRow1 = null;
6173        DataValueDescriptor aliasNameOrderable;
6174        DataValueDescriptor nameSpaceOrderable;
6175        TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
6176
6177        /* Use aliasNameOrderable and nameSpaceOrderable in both start
6178         * and stop position for index 1 scan.
6179         */

6180        aliasNameOrderable = dvf.getVarcharDataValue(ad.getDescriptorName());
6181        char[] charArray = new char[1];
6182        charArray[0] = ad.getNameSpace();
6183        nameSpaceOrderable = dvf.getCharDataValue(new String JavaDoc(charArray));
6184
6185        /* Set up the start/stop position for the scan */
6186        keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(3);
6187        keyRow1.setColumn(1, dvf.getCharDataValue(ad.getSchemaUUID().toString()));
6188        keyRow1.setColumn(2, aliasNameOrderable);
6189        keyRow1.setColumn(3, nameSpaceOrderable);
6190
6191        ti.deleteRow( tc, keyRow1, SYSALIASESRowFactory.SYSALIASES_INDEX1_ID );
6192
6193    }
6194
6195    //
6196
// class implementation
6197
//
6198

6199    /**
6200     * Initialize system catalogs. This is where we perform upgrade. It is our
6201     * pious hope that we won't ever have to upgrade the core catalogs, other than
6202     * to add fields inside Formatable columns in these catalogs.
6203     *
6204     * If we do have to upgrade the core catalogs, then we may need to move the
6205     * loadCatalog calls into the upgrade machinery. It's do-able, just not pretty.
6206     *
6207     *
6208     * @param tc TransactionController
6209     * @param ddg DataDescriptorGenerator
6210     *
6211     * @exception StandardException Thrown on error
6212     */

6213    protected void loadDictionaryTables(TransactionController tc,
6214                                        DataDescriptorGenerator ddg,
6215                                        Properties JavaDoc startParams)
6216        throws StandardException
6217    {
6218        // load the core catalogs first
6219
loadCatalogs(ddg, coreInfo);
6220
6221        dictionaryVersion = (DD_Version)tc.getProperty(
6222                                            DataDictionary.CORE_DATA_DICTIONARY_VERSION);
6223
6224        softwareVersion.upgradeIfNeeded(dictionaryVersion, tc, startParams);
6225    }
6226
6227    /**
6228     * Initialize indices for an array of catalogs
6229     *
6230     * @param ddg DataDescriptorGenerator
6231     *
6232     *
6233     * @exception StandardException Thrown on error
6234     */

6235    public void loadCatalogs(DataDescriptorGenerator ddg, TabInfoImpl[] catalogArray)
6236        throws StandardException
6237    {
6238        int ictr;
6239        int numIndexes;
6240        int indexCtr;
6241        TabInfoImpl catalog;
6242        int catalogCount = catalogArray.length;
6243
6244        /* Initialize the various variables associated with index scans of these catalogs */
6245        for (ictr = 0; ictr < catalogCount; ictr++)
6246        {
6247            // NOTE: This only works for core catalogs, which are initialized
6248
// up front.
6249
catalog = catalogArray[ictr];
6250
6251            numIndexes = catalog.getNumberOfIndexes();
6252
6253            if (numIndexes > 0)
6254            {
6255                for (indexCtr = 0; indexCtr < numIndexes; indexCtr++)
6256                {
6257                    initSystemIndexVariables(ddg, catalog, indexCtr);
6258                }
6259            }
6260        }
6261
6262    }
6263
6264    /*
6265    ** Methods related to create
6266    */

6267
6268    /**
6269        Create all the required dictionary tables. Any classes that extend this class
6270        and need to create new tables shoudl override this method, and then
6271        call this method as the first action in the new method, e.g.
6272        <PRE>
6273        protected Configuration createDictionaryTables(Configuration cfg, TransactionController tc,
6274                DataDescriptorGenerator ddg)
6275                throws StandardException
6276        {
6277            super.createDictionaryTables(params, tc, ddg);
6278
6279            ...
6280        }
6281        </PRE>
6282
6283        @exception StandardException Standard Cloudscape error policy
6284    */

6285    protected void createDictionaryTables(Properties JavaDoc params, TransactionController tc,
6286            DataDescriptorGenerator ddg)
6287                    throws StandardException
6288    {
6289        /*
6290        ** Create a new schema descriptor -- with no args
6291        ** creates the system schema descriptor in which
6292        ** all tables reside (SYS)
6293        */

6294        systemSchemaDesc =
6295          newSystemSchemaDesc(
6296              convertIdToLower ?
6297                  StringUtil.SQLToLowerCase(SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME) :
6298                  SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME,
6299                  SchemaDescriptor.SYSTEM_SCHEMA_UUID);
6300
6301        /* Create the core tables and generate the UUIDs for their
6302         * heaps (before creating the indexes).
6303         * RESOLVE - This loop will eventually drive all of the
6304         * work for creating the core tables.
6305         */

6306        for (int coreCtr = 0; coreCtr < NUM_CORE; coreCtr++)
6307        {
6308            TabInfoImpl ti = coreInfo[coreCtr];
6309
6310            Properties JavaDoc heapProperties = ti.getCreateHeapProperties();
6311
6312            ti.setHeapConglomerate(
6313                createConglomerate(
6314                            ti.getTableName(),
6315                            tc,
6316                            ti.getCatalogRowFactory().makeEmptyRow(),
6317                            heapProperties
6318                            )
6319                );
6320
6321            // bootstrap indexes on core tables before bootstraping the tables themselves
6322
if (coreInfo[coreCtr].getNumberOfIndexes() > 0)
6323            {
6324                bootStrapSystemIndexes(systemSchemaDesc, tc, ddg, ti);
6325            }
6326        }
6327
6328        // bootstrap the core tables into the data dictionary
6329
for ( int ictr = 0; ictr < NUM_CORE; ictr++ )
6330        {
6331            /* RESOLVE - need to do something with COLUMNTYPE in following table creating code */
6332            TabInfoImpl ti = coreInfo[ictr];
6333
6334            addSystemTableToDictionary(ti, systemSchemaDesc, tc, ddg);
6335        }
6336
6337        // Add the bootstrap information to the configuration
6338
params.put(CFG_SYSTABLES_ID,
6339                   Long.toString(
6340                        coreInfo[SYSTABLES_CORE_NUM].getHeapConglomerate()));
6341        params.put(CFG_SYSTABLES_INDEX1_ID,
6342                   Long.toString(
6343                        coreInfo[SYSTABLES_CORE_NUM].getIndexConglomerate(
6344                            ((SYSTABLESRowFactory) coreInfo[SYSTABLES_CORE_NUM].
6345                                getCatalogRowFactory()).SYSTABLES_INDEX1_ID)));
6346        params.put(CFG_SYSTABLES_INDEX2_ID,
6347                   Long.toString(
6348                        coreInfo[SYSTABLES_CORE_NUM].getIndexConglomerate(
6349                            ((SYSTABLESRowFactory) coreInfo[SYSTABLES_CORE_NUM].
6350                                getCatalogRowFactory()).SYSTABLES_INDEX2_ID)));
6351
6352        params.put(CFG_SYSCOLUMNS_ID,
6353                   Long.toString(
6354                        coreInfo[SYSCOLUMNS_CORE_NUM].getHeapConglomerate()));
6355        params.put(CFG_SYSCOLUMNS_INDEX1_ID,
6356                    Long.toString(
6357                        coreInfo[SYSCOLUMNS_CORE_NUM].getIndexConglomerate(
6358                            ((SYSCOLUMNSRowFactory) coreInfo[SYSCOLUMNS_CORE_NUM].
6359                                getCatalogRowFactory()).SYSCOLUMNS_INDEX1_ID)));
6360        params.put(CFG_SYSCOLUMNS_INDEX2_ID,
6361                    Long.toString(
6362                        coreInfo[SYSCOLUMNS_CORE_NUM].getIndexConglomerate(
6363                            ((SYSCOLUMNSRowFactory) coreInfo[SYSCOLUMNS_CORE_NUM].
6364                                getCatalogRowFactory()).SYSCOLUMNS_INDEX2_ID)));
6365
6366        params.put(CFG_SYSCONGLOMERATES_ID,
6367                   Long.toString(
6368                        coreInfo[SYSCONGLOMERATES_CORE_NUM].getHeapConglomerate()));
6369        params.put(CFG_SYSCONGLOMERATES_INDEX1_ID,
6370                    Long.toString(
6371                        coreInfo[SYSCONGLOMERATES_CORE_NUM].getIndexConglomerate(
6372                            ((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM].
6373                                getCatalogRowFactory()).SYSCONGLOMERATES_INDEX1_ID)));
6374        params.put(CFG_SYSCONGLOMERATES_INDEX2_ID,
6375                    Long.toString(
6376                        coreInfo[SYSCONGLOMERATES_CORE_NUM].getIndexConglomerate(
6377                            ((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM].
6378                                getCatalogRowFactory()).SYSCONGLOMERATES_INDEX2_ID)));
6379        params.put(CFG_SYSCONGLOMERATES_INDEX3_ID,
6380                    Long.toString(
6381                        coreInfo[SYSCONGLOMERATES_CORE_NUM].getIndexConglomerate(
6382                            ((SYSCONGLOMERATESRowFactory) coreInfo[SYSCONGLOMERATES_CORE_NUM].
6383                                getCatalogRowFactory()).SYSCONGLOMERATES_INDEX3_ID)));
6384
6385        params.put(CFG_SYSSCHEMAS_ID,
6386                   Long.toString(
6387                        coreInfo[SYSSCHEMAS_CORE_NUM].getHeapConglomerate()));
6388        params.put(CFG_SYSSCHEMAS_INDEX1_ID,
6389                    Long.toString(
6390                        coreInfo[SYSSCHEMAS_CORE_NUM].getIndexConglomerate(
6391                            ((SYSSCHEMASRowFactory) coreInfo[SYSSCHEMAS_CORE_NUM].
6392                                getCatalogRowFactory()).SYSSCHEMAS_INDEX1_ID)));
6393        params.put(CFG_SYSSCHEMAS_INDEX2_ID,
6394                    Long.toString(
6395                        coreInfo[SYSSCHEMAS_CORE_NUM].getIndexConglomerate(
6396                            ((SYSSCHEMASRowFactory) coreInfo[SYSSCHEMAS_CORE_NUM].
6397                                getCatalogRowFactory()).SYSSCHEMAS_INDEX2_ID)));
6398
6399        //Add the SYSIBM Schema
6400
sysIBMSchemaDesc =
6401            addSystemSchema(
6402                SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME,
6403                SchemaDescriptor.SYSIBM_SCHEMA_UUID, tc);
6404
6405        /* Create the non-core tables and generate the UUIDs for their
6406         * heaps (before creating the indexes).
6407         * RESOLVE - This loop will eventually drive all of the
6408         * work for creating the non-core tables.
6409         */

6410        for (int noncoreCtr = 0; noncoreCtr < NUM_NONCORE; noncoreCtr++)
6411        {
6412            int catalogNumber = noncoreCtr + NUM_CORE;
6413            boolean isDummy = (catalogNumber == SYSDUMMY1_CATALOG_NUM);
6414
6415            TabInfoImpl ti = getNonCoreTIByNumber(catalogNumber);
6416
6417            makeCatalog(ti, isDummy ? sysIBMSchemaDesc : systemSchemaDesc, tc );
6418
6419            if (isDummy)
6420                populateSYSDUMMY1(tc);
6421
6422            // Clear the table entry for this non-core table,
6423
// to allow it to be garbage-collected. The idea
6424
// is that a running database might never need to
6425
// reference a non-core table after it was created.
6426
clearNoncoreTable(noncoreCtr);
6427        }
6428
6429        //Add ths System Schema
6430
addDescriptor(
6431                systemSchemaDesc, null, SYSSCHEMAS_CATALOG_NUM, false, tc);
6432
6433
6434        // Add the following system Schema's to be compatible with DB2,
6435
// currently Cloudscape does not use them, but by creating them as
6436
// system schema's it will insure applications can't create them,
6437
// drop them, or create objects in them. This set includes:
6438
// SYSCAT
6439
// SYSFUN
6440
// SYSPROC
6441
// SYSSTAT
6442
// NULLID
6443

6444        //Add the SYSCAT Schema
6445
addSystemSchema(
6446            SchemaDescriptor.IBM_SYSTEM_CAT_SCHEMA_NAME,
6447            SchemaDescriptor.SYSCAT_SCHEMA_UUID, tc);
6448
6449        //Add the SYSFUN Schema
6450
addSystemSchema(
6451            SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,
6452            SchemaDescriptor.SYSFUN_SCHEMA_UUID, tc);
6453
6454        //Add the SYSPROC Schema
6455
addSystemSchema(
6456            SchemaDescriptor.IBM_SYSTEM_PROC_SCHEMA_NAME,
6457            SchemaDescriptor.SYSPROC_SCHEMA_UUID, tc);
6458
6459        //Add the SYSSTAT Schema
6460
addSystemSchema(
6461            SchemaDescriptor.IBM_SYSTEM_STAT_SCHEMA_NAME,
6462            SchemaDescriptor.SYSSTAT_SCHEMA_UUID, tc);
6463
6464        //Add the NULLID Schema
6465
addSystemSchema(
6466            SchemaDescriptor.IBM_SYSTEM_NULLID_SCHEMA_NAME,
6467            SchemaDescriptor.NULLID_SCHEMA_UUID, tc);
6468
6469        //Add the SQLJ Schema
6470
addSystemSchema(
6471            SchemaDescriptor.STD_SQLJ_SCHEMA_NAME,
6472            SchemaDescriptor.SQLJ_SCHEMA_UUID, tc);
6473
6474        //Add the SYSCS_DIAG Schema
6475
addSystemSchema(
6476            SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME,
6477            SchemaDescriptor.SYSCS_DIAG_SCHEMA_UUID, tc);
6478
6479        //Add the SYSCS_UTIL Schema
6480
addSystemSchema(
6481            SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME,
6482            SchemaDescriptor.SYSCS_UTIL_SCHEMA_UUID, tc);
6483
6484        //Add the APP schema
6485
SchemaDescriptor appSchemaDesc = new SchemaDescriptor(this,
6486                                        SchemaDescriptor.STD_DEFAULT_SCHEMA_NAME,
6487                                        SchemaDescriptor.DEFAULT_USER_NAME,
6488                                        uuidFactory.recreateUUID( SchemaDescriptor.DEFAULT_SCHEMA_UUID),
6489                                        false);
6490  
6491        addDescriptor(appSchemaDesc, null, SYSSCHEMAS_CATALOG_NUM, false, tc);
6492    }
6493
6494    /**
6495     * Add a system schema to the database.
6496     * <p>
6497     *
6498     * @param schema_name name of the schema to add.
6499     *
6500     * @exception StandardException Standard exception policy.
6501     **/

6502    private SchemaDescriptor addSystemSchema(
6503    String JavaDoc schema_name,
6504    String JavaDoc schema_uuid,
6505    TransactionController tc)
6506        throws StandardException
6507    {
6508        // create the descriptor
6509
SchemaDescriptor schema_desc =
6510            new SchemaDescriptor(
6511                this,
6512                convertIdToLower ? schema_name.toLowerCase() : schema_name,
6513                authorizationDatabaseOwner,
6514                uuidFactory.recreateUUID(schema_uuid),
6515                true);
6516
6517        // add it to the catalog.
6518
addDescriptor(schema_desc, null, SYSSCHEMAS_CATALOG_NUM, false, tc);
6519
6520        return(schema_desc);
6521    }
6522
6523    /** called by the upgrade code (dd_xena etc) to add a new system catalog.
6524     *
6525     * @param tc TransactionController to use.
6526     * @param catalogNumber catalogNumber
6527     */

6528    protected void upgradeMakeCatalog(TransactionController tc, int catalogNumber)
6529        throws StandardException
6530    {
6531        TabInfoImpl ti;
6532        if (catalogNumber >= NUM_CORE)
6533            ti = getNonCoreTIByNumber(catalogNumber);
6534        else
6535            ti = coreInfo[catalogNumber];
6536        
6537        makeCatalog(ti, (catalogNumber == SYSDUMMY1_CATALOG_NUM) ? getSysIBMSchemaDescriptor() :
6538                                getSystemSchemaDescriptor(), tc);
6539    }