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    }
6540
6541    /**
6542     * The dirty work of creating a catalog.
6543     *
6544     * @param ti TabInfoImpl describing catalog to create.
6545     * @param sd Schema to create catalogs in.
6546     * @param tc Transaction context.
6547     *
6548     * @exception StandardException Standard Cloudscape error policy
6549     */

6550    public void makeCatalog( TabInfoImpl ti,
6551                                 SchemaDescriptor sd,
6552                                 TransactionController tc )
6553                    throws StandardException
6554    {
6555        DataDescriptorGenerator ddg = getDataDescriptorGenerator();
6556
6557        Properties JavaDoc heapProperties = ti.getCreateHeapProperties();
6558        ti.setHeapConglomerate(
6559            createConglomerate(
6560                ti.getTableName(),
6561                tc,
6562                ti.getCatalogRowFactory().makeEmptyRow(),
6563                heapProperties
6564                )
6565            );
6566
6567        // bootstrap indexes on core tables before bootstrapping the tables themselves
6568
if (ti.getNumberOfIndexes() > 0)
6569        {
6570            bootStrapSystemIndexes(sd, tc, ddg, ti);
6571        }
6572
6573        addSystemTableToDictionary(ti, sd, tc, ddg);
6574    }
6575    /**
6576      * Upgrade an existing catalog by setting the nullability
6577      *
6578      * @param columnNumber The column to change
6579      * @param nullability true if nullable
6580      * @param tc Transaction controller
6581      *
6582      * @exception StandardException Standard Cloudscape error policy
6583      */

6584    public void upgrade_setNullability(CatalogRowFactory rowFactory,
6585                                       int columnNumber,
6586                                       boolean nullability,
6587                                       TransactionController tc)
6588        throws StandardException
6589    {
6590        SystemColumn theColumn;
6591        SystemColumn[] columns = rowFactory.buildColumnList();
6592        SchemaDescriptor sd = getSystemSchemaDescriptor();
6593        String JavaDoc columnName;
6594
6595        TableDescriptor td = getTableDescriptor(rowFactory.getCatalogName(), sd);
6596
6597        theColumn = columns[columnNumber - 1]; // from 1 to 0 based
6598
ColumnDescriptor cd = makeColumnDescriptor(theColumn, columnNumber, td );
6599        columnName = cd.getColumnName();
6600        cd.getType().setNullability(nullability);
6601        int[] columnNameColArray = new int[1];
6602        columnNameColArray[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMNDATATYPE ;
6603        updateColumnDescriptor(cd,
6604                                td.getUUID(),
6605                                columnName,
6606                                columnNameColArray,
6607                                tc,
6608                                true);
6609
6610    }
6611
6612  
6613    /**
6614      * Upgrade an existing catalog by adding columns.
6615      *
6616      * @param rowFactory Associated with this catalog.
6617      * @param newColumnIDs Array of 1-based column ids.
6618      * @param tc Transaction controller
6619      *
6620      * @exception StandardException Standard Cloudscape error policy
6621      */

6622    public void upgrade_addColumns( CatalogRowFactory rowFactory,
6623                                        int[] newColumnIDs,
6624                                        TransactionController tc )
6625                    throws StandardException
6626    {
6627        int columnID;
6628        SystemColumn currentColumn;
6629        ColumnDescriptor cd;
6630
6631        SystemColumn[] columns = rowFactory.buildColumnList();
6632        ExecRow templateRow = rowFactory.makeEmptyRow();
6633        int columnCount = newColumnIDs.length;
6634        SchemaDescriptor sd = getSystemSchemaDescriptor();
6635        TableDescriptor td;
6636        long conglomID;
6637
6638        // Special case when adding a column to systables or syscolumns,
6639
// since we can't go to systables/syscolumns to get the
6640
// table/column descriptor until after we add and populate the new column.
6641
if (rowFactory instanceof SYSTABLESRowFactory)
6642        {
6643            td = dataDescriptorGenerator.newTableDescriptor(
6644                        "SYSTABLES",
6645                        sd,
6646                        TableDescriptor.BASE_TABLE_TYPE,
6647                        TableDescriptor.ROW_LOCK_GRANULARITY);
6648            td.setUUID(getUUIDForCoreTable("SYSTABLES", sd.getUUID().toString(), tc));
6649            conglomID = coreInfo[SYSTABLES_CORE_NUM].getHeapConglomerate();
6650        }
6651        else if (rowFactory instanceof SYSCOLUMNSRowFactory)
6652        {
6653            td = dataDescriptorGenerator.newTableDescriptor(
6654                        "SYSCOLUMNS",
6655                        sd,
6656                        TableDescriptor.BASE_TABLE_TYPE,
6657                        TableDescriptor.ROW_LOCK_GRANULARITY);
6658            td.setUUID(getUUIDForCoreTable("SYSCOLUMNS", sd.getUUID().toString(), tc));
6659            conglomID = coreInfo[SYSCOLUMNS_CORE_NUM].getHeapConglomerate();
6660        }
6661        else
6662        {
6663            td = getTableDescriptor( rowFactory.getCatalogName(), sd );
6664            conglomID = td.getHeapConglomerateId();
6665        }
6666
6667        widenConglomerate( templateRow, newColumnIDs, conglomID, tc );
6668
6669
6670        ColumnDescriptor[] cdArray = new ColumnDescriptor[columnCount];
6671        for ( int ix = 0; ix < columnCount; ix++ )
6672        {
6673            columnID = newColumnIDs[ix];
6674            currentColumn = columns[ columnID - 1 ]; // from 1 to 0 based
6675

6676            cdArray[ix] = makeColumnDescriptor( currentColumn, ix + 1, td );
6677        }
6678        addDescriptorArray(cdArray, td, SYSCOLUMNS_CATALOG_NUM, false, tc);
6679
6680    }
6681
6682    /**
6683      * Add invisible columns to an existing system catalog
6684      *
6685      * @param rowFactory Associated with this catalog.
6686      * @param newColumnIDs Array of 1-based column ids.
6687      * @param tc Transaction controller
6688      *
6689      * @exception StandardException Standard Cloudscape error policy
6690      */

6691    public void upgrade_addInvisibleColumns
6692    (
6693        CatalogRowFactory rowFactory,
6694        int[] newColumnIDs,
6695        TransactionController tc
6696    )
6697        throws StandardException
6698    {
6699        ExecRow templateRow = rowFactory.makeEmptyRow();
6700        SchemaDescriptor sd = getSystemSchemaDescriptor( );
6701        long conglomID = getTableDescriptor( rowFactory.getCatalogName(), sd ).getHeapConglomerateId();
6702
6703        widenConglomerate( templateRow, newColumnIDs, conglomID, tc );
6704    }
6705
6706
6707    /**
6708      * Adds columns to the conglomerate underlying a system table.
6709      *
6710      * @param templateRow Ultimate shape of base row of table
6711      * @param newColumnIDs Array of 1-based column ids
6712      * @param conglomID heap id
6713      * @param tc Transaction controller
6714      *
6715      * @exception StandardException Standard Cloudscape error policy
6716      */

6717    private void widenConglomerate
6718    (
6719        ExecRow templateRow,
6720        int[] newColumnIDs,
6721        long conglomID,
6722        TransactionController tc
6723    )
6724        throws StandardException
6725    {
6726        int columnCount = newColumnIDs.length;
6727
6728        for ( int ix = 0; ix < columnCount; ix++ )
6729        {
6730            int columnID = newColumnIDs[ix];
6731            int storablePosition = columnID - 1; // from 1 to 0 based
6732

6733            tc.addColumnToConglomerate( conglomID,
6734                                        storablePosition,
6735                                        templateRow.getColumn( columnID) );
6736        }
6737
6738    }
6739
6740
6741    /**
6742      * Code to add an index to a catalog during upgrade.
6743      *
6744      * @param tc transaction controller
6745      * @param ti information on the catalog that's having a new index added
6746      * @param indexNumber 0-based index number
6747      * @param heapConglomerateNumber what it is
6748      *
6749      * @return The conglomerate number of the new index.
6750      *
6751      * @exception StandardException Thrown on failure
6752      */

6753    public long upgrade_makeOneIndex
6754    (
6755        TransactionController tc,
6756        TabInfoImpl ti,
6757        int indexNumber,
6758        long heapConglomerateNumber
6759    )
6760        throws StandardException
6761    {
6762        SchemaDescriptor sd = getSystemSchemaDescriptor( );
6763        DataDescriptorGenerator ddg = getDataDescriptorGenerator();
6764        long indexConglomerateNumber;
6765
6766        ConglomerateDescriptor conglomerateDescriptor = bootstrapOneIndex
6767            ( sd, tc, ddg, ti, indexNumber, heapConglomerateNumber );
6768
6769        indexConglomerateNumber = conglomerateDescriptor.getConglomerateNumber();
6770
6771        addDescriptor(conglomerateDescriptor, sd,
6772                      SYSCONGLOMERATES_CATALOG_NUM, false, tc);
6773                      
6774        return indexConglomerateNumber;
6775    }
6776
6777
6778    /**
6779     * Get the UUID for the specified system table. Prior
6780     * to Plato, system tables did not have canonical UUIDs, so
6781     * we need to scan systables to get the UUID when we
6782     * are updating the core tables.
6783     *
6784     * @param tableName Name of the table
6785     * @param schemaUUID UUID of schema
6786     * @param tc TransactionController to user
6787     *
6788     * @return UUID The UUID of the core table.
6789     *
6790     * @exception StandardException Thrown on failure
6791     */

6792    private UUID getUUIDForCoreTable(String JavaDoc tableName,
6793                                     String JavaDoc schemaUUID,
6794                                     TransactionController tc)
6795                throws StandardException
6796    {
6797        ConglomerateController heapCC;
6798        ExecIndexRow indexRow1;
6799        ExecRow row;
6800        DataValueDescriptor schemaIDOrderable;
6801        DataValueDescriptor tableNameOrderable;
6802        ScanController scanController;
6803        TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
6804        SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti.getCatalogRowFactory();
6805
6806        // We only want the 1st column from the heap
6807
row = exFactory.getValueRow(1);
6808
6809        /* Use tableNameOrderable and schemaIdOrderable in both start
6810         * and stop position for scan.
6811         */

6812        tableNameOrderable = dvf.getVarcharDataValue(tableName);
6813        schemaIDOrderable = dvf.getCharDataValue(schemaUUID);
6814
6815        /* Set up the start/stop position for the scan */
6816        ExecIndexRow keyRow = exFactory.getIndexableRow(2);
6817        keyRow.setColumn(1, tableNameOrderable);
6818        keyRow.setColumn(2, schemaIDOrderable);
6819
6820        heapCC = tc.openConglomerate(
6821                ti.getHeapConglomerate(), false, 0,
6822                TransactionController.MODE_RECORD,
6823                TransactionController.ISOLATION_REPEATABLE_READ);
6824
6825        ExecRow indexTemplateRow = rf.buildEmptyIndexRow( SYSTABLESRowFactory.SYSTABLES_INDEX1_ID, heapCC.newRowLocationTemplate() );
6826
6827        /* Scan the index and go to the data pages for qualifying rows to
6828         * build the column descriptor.
6829         */

6830        scanController = tc.openScan(
6831                ti.getIndexConglomerate(SYSTABLESRowFactory.SYSTABLES_INDEX1_ID), // conglomerate to open
6832
false, // don't hold open across commit
6833
0,
6834                TransactionController.MODE_RECORD,
6835                TransactionController.ISOLATION_REPEATABLE_READ,
6836                (FormatableBitSet) null, // all fields as objects
6837
keyRow.getRowArray(), // start position - first row
6838
ScanController.GE, // startSearchOperation
6839
(ScanQualifier[][]) null, //scanQualifier,
6840
keyRow.getRowArray(), // stop position - through last row
6841
ScanController.GT); // stopSearchOperation
6842

6843        /* OK to fetch into the template row,
6844         * since we won't be doing a next.
6845         */

6846        if (scanController.fetchNext(indexTemplateRow.getRowArray()))
6847        {
6848            RowLocation baseRowLocation;
6849
6850
6851            baseRowLocation = (RowLocation) indexTemplateRow.getColumn(
6852                                                indexTemplateRow.nColumns());
6853    
6854            /* 1st column is TABLEID (UUID - char(36)) */
6855            row.setColumn(SYSTABLESRowFactory.SYSTABLES_TABLEID, dvf.getCharDataValue((String JavaDoc) null));
6856            FormatableBitSet bi = new FormatableBitSet(1);
6857            bi.set(0);
6858            boolean base_row_exists =
6859                heapCC.fetch(
6860                    baseRowLocation, row.getRowArray(), (FormatableBitSet) null);
6861
6862            if (SanityManager.DEBUG)
6863            {
6864                // it can not be possible for heap row to disappear while
6865
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
6866
SanityManager.ASSERT(base_row_exists, "base row not found");
6867            }
6868        }
6869
6870        scanController.close();
6871        heapCC.close();
6872
6873        return uuidFactory.recreateUUID(row.getColumn(1).toString());
6874    }
6875     
6876 
6877    /**
6878     * Initialize noncore columns to fixed values
6879     *
6880     * @param tc The TransactionController for the transaction to do the
6881     * upgrade in.
6882     * @param isCoreTable true if it is a core table
6883     * @param tableNum the noncore table number
6884     * @param columnsToUpdateSet a bit set of columns to update. ZERO BASED
6885     * @param replaceRow an object array of Orderables for the new values
6886     *
6887     * @exception StandardException Thrown on error
6888     */

6889    void upgrade_initSystemTableCols(
6890    TransactionController tc,
6891    boolean isCoreTable,
6892    int tableNum,
6893    FormatableBitSet columnsToUpdateSet,
6894    DataValueDescriptor[] replaceRow
6895    )
6896        throws StandardException
6897    {
6898        
6899        TabInfoImpl ti = (isCoreTable) ? coreInfo[tableNum] :
6900                                        getNonCoreTIByNumber(tableNum);
6901
6902        if (!isCoreTable)
6903            faultInTabInfo(ti);
6904
6905        /* Scan the entire heap */
6906        ScanController sc =
6907            tc.openScan(
6908                ti.getHeapConglomerate(),
6909                false,
6910                TransactionController.OPENMODE_FORUPDATE,
6911                TransactionController.MODE_TABLE,
6912                TransactionController.ISOLATION_REPEATABLE_READ,
6913                RowUtil.EMPTY_ROW_BITSET,
6914                (DataValueDescriptor[]) null,
6915                ScanController.NA,
6916                (Qualifier[][]) null,
6917                (DataValueDescriptor[]) null,
6918                ScanController.NA);
6919
6920        while (sc.next())
6921        {
6922            /* Replace the column in the table */
6923            sc.replace(replaceRow, columnsToUpdateSet);
6924        }
6925
6926        sc.close();
6927    }
6928
6929
6930
6931    /*
6932    *******************************************************************************
6933    *
6934    * See RepBasicDataDictionary for sample code on how to create a system
6935    * table.
6936    *
6937    * What follows here is special code for the core catalogs. These are catalogs
6938    * which have to exist before any other system tables are created.
6939    *
6940    * Creating a core catalog consists of two steps: 1) creating all the infrastructure
6941    * needed to make generic systemTableCreation work, 2) actually populating the
6942    * Data Dictionary and core conglomerates with tuples.
6943    *
6944    *******************************************************************************
6945    */

6946
6947
6948    /**
6949     * Infrastructure work for indexes on catalogs.
6950     *
6951       @exception StandardException Standard Cloudscape error policy
6952
6953     */

6954    private void bootStrapSystemIndexes(
6955                                  SchemaDescriptor sd,
6956                                  TransactionController tc,
6957                                  DataDescriptorGenerator ddg,
6958                                  TabInfoImpl ti)
6959                        throws StandardException
6960    {
6961        ConglomerateDescriptor[] cgd = new ConglomerateDescriptor[ti.getNumberOfIndexes()];
6962
6963        /* Ordering problem with sysconglomerates. We need to create
6964         * all of the conglomerates first before adding rows to
6965         * sysconglomerates. (All of the conglomerates for sysconglomerates
6966         * must be there before we can add to them.)
6967         *
6968         */

6969        for (int indexCtr = 0; indexCtr < ti.getNumberOfIndexes(); indexCtr++)
6970        {
6971            cgd[indexCtr] = bootstrapOneIndex( sd, tc, ddg, ti, indexCtr, ti.getHeapConglomerate() );
6972        }
6973
6974        for (int indexCtr = 0; indexCtr < ti.getNumberOfIndexes(); indexCtr++)
6975        {
6976            addDescriptor(cgd[indexCtr], sd,
6977                          SYSCONGLOMERATES_CATALOG_NUM, false, tc);
6978        }
6979    }
6980
6981    /**
6982     * @see DataDictionary#computeAutoincRowLocations
6983     */

6984    public RowLocation[] computeAutoincRowLocations(TransactionController tc,
6985                                                    TableDescriptor td)
6986                throws StandardException
6987    {
6988        int size;
6989        if (!(td.tableHasAutoincrement()))
6990            return null;
6991
6992        size = td.getNumberOfColumns();
6993        RowLocation[] rla = new RowLocation[size];
6994
6995        for (int i = 0; i < size; i++)
6996        {
6997            ColumnDescriptor cd = td.getColumnDescriptor(i + 1);
6998            if (cd.isAutoincrement())
6999                rla[i] = computeRowLocation(tc, td, cd.getColumnName());
7000        }
7001        return rla;
7002    }
7003    
7004
7005    /**
7006     * @see DataDictionary#getSetAutoincrementValue
7007     */

7008    public NumberDataValue getSetAutoincrementValue(
7009                                            RowLocation rl,
7010                                            TransactionController tc,
7011                                            boolean doUpdate,
7012                                            NumberDataValue newValue,
7013                                            boolean wait)
7014           throws StandardException
7015    {
7016
7017        FormatableBitSet columnToUpdate = new
7018            FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
7019        int columnNum = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
7020        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
7021        ConglomerateController heapCC = null;
7022        SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti.getCatalogRowFactory();
7023        ExecRow row = rf.makeEmptyRow();
7024
7025        FormatableBitSet columnToRead = new
7026            FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
7027        
7028        // FormatableBitSet is 0 based.
7029
columnToRead.set(columnNum - 1); // current value.
7030
columnToRead.set(columnNum); // start value.
7031
columnToRead.set(columnNum + 1); // increment value.
7032

7033        try
7034        {
7035            /* if wait is true then we need to do a wait while trying to
7036               open/fetch from the conglomerate. note we use wait both to
7037               open as well as fetch from the conglomerate.
7038            */

7039            heapCC =
7040                tc.openConglomerate(
7041                    ti.getHeapConglomerate(),
7042                    false,
7043                    (TransactionController.OPENMODE_FORUPDATE |
7044                     ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)),
7045                    TransactionController.MODE_RECORD,
7046                    TransactionController.ISOLATION_REPEATABLE_READ);
7047
7048            boolean baseRowExists =
7049                heapCC.fetch(rl, row.getRowArray(), columnToRead, wait);
7050
7051            columnToUpdate.set(columnNum - 1); // current value.
7052

7053            // while the Row interface is 1 based.
7054
NumberDataValue currentAI = (NumberDataValue)row.getColumn(columnNum);
7055            long currentAIValue = currentAI.getLong();
7056            NumberDataValue increment = (NumberDataValue)row.getColumn(columnNum + 2);
7057            
7058            if (doUpdate)
7059            {
7060                // we increment and store the new value in SYSCOLUMNS
7061
currentAI = currentAI.plus(currentAI, increment, currentAI);
7062                row.setColumn(columnNum, currentAI);
7063                heapCC.replace(rl, row.getRowArray(), columnToUpdate);
7064            }
7065                
7066            // but we return the "currentAIValue"-- i.e the value before
7067
// incrementing it.
7068
if (newValue != null)
7069            {
7070                // user has passed in an object; set the current value in there and
7071
// return it.
7072
newValue.setValue(currentAIValue);
7073                return newValue;
7074            }
7075            
7076            else
7077            {
7078                // reuse the object read from row.
7079
currentAI.setValue(currentAIValue);
7080                return currentAI;
7081            }
7082        }
7083        finally
7084        {
7085            if (heapCC != null)
7086                heapCC.close();
7087        }
7088    }
7089
7090    private ConglomerateDescriptor bootstrapOneIndex
7091    (
7092        SchemaDescriptor sd,
7093        TransactionController tc,
7094        DataDescriptorGenerator ddg,
7095        TabInfoImpl ti,
7096        int indexNumber,
7097        long heapConglomerateNumber
7098    )
7099        throws StandardException
7100    {
7101        boolean isUnique;
7102        ConglomerateController cc;
7103        ExecRow baseRow;
7104        ExecIndexRow indexableRow;
7105        int numColumns;
7106        long conglomId;
7107        RowLocation rl;
7108        CatalogRowFactory rf = ti.getCatalogRowFactory();
7109        IndexRowGenerator irg;
7110        ConglomerateDescriptor conglomerateDescriptor;
7111
7112        initSystemIndexVariables(ddg, ti, indexNumber);
7113
7114        irg = ti.getIndexRowGenerator(indexNumber);
7115
7116        numColumns = ti.getIndexColumnCount(indexNumber);
7117
7118        /* Is the index unique */
7119        isUnique = ti.isIndexUnique(indexNumber);
7120
7121        // create an index row template
7122
indexableRow = irg.getIndexRowTemplate();
7123
7124        baseRow = rf.makeEmptyRow();
7125
7126        // Get a RowLocation template
7127
cc = tc.openConglomerate(
7128            heapConglomerateNumber, false, 0,
7129            TransactionController.MODE_RECORD,
7130            TransactionController.ISOLATION_REPEATABLE_READ);
7131
7132        rl = cc.newRowLocationTemplate();
7133        cc.close();
7134
7135        // Get an index row based on the base row
7136
irg.getIndexRow(baseRow, rl, indexableRow, (FormatableBitSet) null);
7137
7138        // Describe the properties of the index to the store using Properties
7139
// RESOLVE: The following properties assume a BTREE index.
7140
Properties JavaDoc indexProperties = ti.getCreateIndexProperties(indexNumber);
7141
7142        // Tell it the conglomerate id of the base table
7143
indexProperties.put(
7144            "baseConglomerateId",
7145            Long.toString( heapConglomerateNumber ) );
7146
7147        // All indexes are unique because they contain the RowLocation.
7148
// The number of uniqueness columns must include the RowLocation
7149
// if the user did not specify a unique index.
7150
indexProperties.put("nUniqueColumns",
7151                            Integer.toString(
7152                                isUnique ? numColumns : numColumns + 1));
7153
7154        // By convention, the row location column is the last column
7155
indexProperties.put("rowLocationColumn",
7156                            Integer.toString(numColumns));
7157
7158        // For now, all columns are key fields, including the RowLocation
7159
indexProperties.put("nKeyFields",
7160                            Integer.toString(numColumns + 1));
7161
7162        /* Create and add the conglomerate (index) */
7163        conglomId = tc.createConglomerate(
7164            "BTREE", // we're requesting an index conglomerate
7165
indexableRow.getRowArray(),
7166            null, //default sort order
7167
indexProperties, // default properties
7168
TransactionController.IS_DEFAULT); // not temporary
7169

7170        conglomerateDescriptor =
7171            ddg.newConglomerateDescriptor(conglomId,
7172                                          rf.getIndexName(indexNumber),
7173                                          true,
7174                                          irg,
7175                                          false,
7176                                          rf.getCanonicalIndexUUID(indexNumber),
7177                                          rf.getCanonicalTableUUID(),
7178                                          sd.getUUID());
7179        ti.setIndexConglomerate( conglomerateDescriptor );
7180
7181        return conglomerateDescriptor;
7182    }
7183
7184    public void initSystemIndexVariables(DataDescriptorGenerator ddg,
7185                                           TabInfoImpl ti,
7186                                           int indexNumber)
7187        throws StandardException
7188    {
7189        int numCols = ti.getIndexColumnCount(indexNumber);
7190        int[] baseColumnPositions = new int[numCols];
7191        CatalogRowFactory rf = ti.getCatalogRowFactory();
7192
7193        for (int colCtr = 0; colCtr < numCols; colCtr++)
7194        {
7195            baseColumnPositions[colCtr] =
7196                ti.getBaseColumnPosition(indexNumber, colCtr);
7197        }
7198
7199        boolean[] isAscending = new boolean[baseColumnPositions.length];
7200        for (int i = 0; i < baseColumnPositions.length; i++)
7201            isAscending[i] = true;
7202
7203        // For now, assume that all index columns are ordered columns
7204
ti.setIndexRowGenerator(indexNumber,
7205                                new IndexRowGenerator(
7206                                            "BTREE", ti.isIndexUnique(indexNumber),
7207                                            baseColumnPositions,
7208                                            isAscending,
7209                                            baseColumnPositions.length));
7210    }
7211
7212    /**
7213     * Populate SYSDUMMY1 table with a single row.
7214     *
7215     * @exception StandardException Standard Cloudscape error policy
7216     */

7217    protected void populateSYSDUMMY1(
7218                            TransactionController tc)
7219        throws StandardException
7220    {
7221        TabInfoImpl ti = getNonCoreTI(SYSDUMMY1_CATALOG_NUM);
7222        ExecRow row = ti.getCatalogRowFactory().makeRow(null, null);
7223
7224        int insertRetCode = ti.insertRow(row, tc, true);
7225    }
7226
7227    /**
7228     * Clear all of the DataDictionary caches.
7229     *
7230     * @exception StandardException Standard Cloudscape error policy
7231     */

7232    public void clearCaches() throws StandardException
7233    {
7234        nameTdCache.cleanAll();
7235        nameTdCache.ageOut();
7236        OIDTdCache.cleanAll();
7237        OIDTdCache.ageOut();
7238        if (spsNameCache != null)
7239        {
7240            //System.out.println("CLEARING SPS CACHE");
7241
spsNameCache.cleanAll();
7242            spsNameCache.ageOut();
7243            spsIdHash.clear();
7244            // spsTextHash.clear();
7245
}
7246    }
7247
7248    /**
7249        Add the required entries to the data dictionary for a System table.
7250    */

7251
7252    private void addSystemTableToDictionary(TabInfoImpl ti,
7253                                  SchemaDescriptor sd,
7254                                  TransactionController tc,
7255                                  DataDescriptorGenerator ddg)
7256                        throws StandardException
7257    {
7258        CatalogRowFactory crf = ti.getCatalogRowFactory();
7259
7260        String JavaDoc name = ti.getTableName();
7261        long conglomId = ti.getHeapConglomerate();
7262        SystemColumn[] columnList = crf.buildColumnList();
7263        UUID heapUUID = crf.getCanonicalHeapUUID();
7264        String JavaDoc heapName = crf.getCanonicalHeapName();
7265        TableDescriptor td;
7266        UUID toid;
7267        ColumnDescriptor cd;
7268        int columnCount;
7269        SystemColumn column;
7270
7271        // add table to the data dictionary
7272

7273        columnCount = columnList.length;
7274        td = ddg.newTableDescriptor(name, sd, TableDescriptor.SYSTEM_TABLE_TYPE,
7275                                    TableDescriptor.ROW_LOCK_GRANULARITY);
7276        td.setUUID(crf.getCanonicalTableUUID());
7277        addDescriptor(td, sd, SYSTABLES_CATALOG_NUM,
7278                      false, tc);
7279        toid = td.getUUID();
7280    
7281        /* Add the conglomerate for the heap */
7282        ConglomerateDescriptor cgd = ddg.newConglomerateDescriptor(conglomId,
7283                                                                    heapName,
7284                                                                    false,
7285                                                                    null,
7286                                                                    false,
7287                                                                    heapUUID,
7288                                                                    toid,
7289                                                                    sd.getUUID());
7290
7291        addDescriptor(cgd, sd, SYSCONGLOMERATES_CATALOG_NUM, false, tc);
7292
7293        /* Create the columns */
7294        ColumnDescriptor[] cdlArray = new ColumnDescriptor[columnCount];
7295
7296        for (int columnNumber = 0; columnNumber < columnCount; columnNumber++)
7297        {
7298            column = columnList[columnNumber];
7299
7300            if (SanityManager.DEBUG)
7301            {
7302                if (column == null)
7303                {
7304                    SanityManager.THROWASSERT("column "+columnNumber+" for table "+ti.getTableName()+" is null");
7305                }
7306            }
7307            cdlArray[columnNumber] = makeColumnDescriptor( column,
7308                    columnNumber + 1, td );
7309        }
7310        addDescriptorArray(cdlArray, td, SYSCOLUMNS_CATALOG_NUM, false, tc);
7311        
7312        // now add the columns to the cdl of the table.
7313
ColumnDescriptorList cdl = td.getColumnDescriptorList();
7314        for (int i = 0; i < columnCount; i++)
7315            cdl.add(cdlArray[i]);
7316    }
7317
7318    /**
7319      * Converts a SystemColumn to a ColumnDescriptor.
7320      *
7321      * @param column a SystemColumn
7322      * @param columnPosition Position of the column in the table, one based.
7323      * @param td descriptor for table that column lives in
7324      *
7325      * @return a ColumnDes*criptor
7326      *
7327      * @exception StandardException Standard Cloudscape error policy
7328      */

7329    private ColumnDescriptor makeColumnDescriptor( SystemColumn column,
7330            int columnPosition,
7331                                                      TableDescriptor td )
7332                        throws StandardException
7333    {
7334        //RESOLVEAUTOINCREMENT
7335
return new ColumnDescriptor
7336            (column.getName(), columnPosition, column.getType(), null, null, td,
7337             (UUID) null, // No defaults yet for system columns
7338
0, 0
7339             );
7340    }
7341
7342
7343    /**
7344     * Create a conglomerate for a system table
7345     *
7346     * @param name Name of new catalog.
7347     * @param tc Transaction context.
7348     * @param rowTemplate Template for rows for the new table
7349     * @param properties Properties for createConglomerate
7350     *
7351     * @return Conglomerate id.
7352
7353        @exception StandardException Standard Cloudscape error policy.
7354     */

7355    private long createConglomerate(String JavaDoc name, TransactionController tc,
7356                                    ExecRow rowTemplate,
7357                                    Properties JavaDoc properties)
7358                        throws StandardException
7359    {
7360        long conglomId;
7361
7362        conglomId = tc.createConglomerate(
7363            "heap", // we're requesting a heap conglomerate
7364
rowTemplate.getRowArray(), // row template
7365
null, // default sort order
7366
properties, // default properties
7367
TransactionController.IS_DEFAULT); // not temporary
7368

7369        return conglomId;
7370    }
7371
7372    /**
7373      * Converts a UUID to an DataValueDescriptor.
7374      *
7375      * @return the UUID converted to an DataValueDescriptor
7376     *
7377     * @exception StandardException Thrown on error
7378     */

7379    public DataValueDescriptor getValueAsDVD( UUID uuid ) throws StandardException
7380    {
7381        String JavaDoc uuidString = uuid.toString();
7382        return dvf.getCharDataValue(uuidString);
7383    }
7384
7385    /**
7386      * Initialize catalog information. This method is overridden by children.
7387      * @exception StandardException Thrown on error
7388      */

7389    public void initializeCatalogInfo()
7390        throws StandardException
7391    {
7392        initializeCoreInfo();
7393        initializeNoncoreInfo();
7394    }
7395
7396    /**
7397     * Initialized the core info array.
7398     */

7399    private void initializeCoreInfo()
7400        throws StandardException
7401    {
7402        TabInfoImpl[] lcoreInfo = coreInfo = new TabInfoImpl[NUM_CORE];
7403
7404        UUIDFactory luuidFactory = uuidFactory;
7405
7406        lcoreInfo[SYSTABLES_CORE_NUM] =
7407            new TabInfoImpl(new SYSTABLESRowFactory(luuidFactory, exFactory, dvf, convertIdToLower));
7408        lcoreInfo[SYSCOLUMNS_CORE_NUM] =
7409            new TabInfoImpl(new SYSCOLUMNSRowFactory(luuidFactory, exFactory, dvf, convertIdToLower));
7410        lcoreInfo[SYSCONGLOMERATES_CORE_NUM] =
7411            new TabInfoImpl(new SYSCONGLOMERATESRowFactory(luuidFactory, exFactory, dvf, convertIdToLower));
7412        lcoreInfo[SYSSCHEMAS_CORE_NUM] =
7413            new TabInfoImpl(new SYSSCHEMASRowFactory(luuidFactory, exFactory, dvf, convertIdToLower));
7414    }
7415
7416    /**
7417     * Initialized the noncore info array.
7418     */

7419    private void initializeNoncoreInfo()
7420        throws StandardException
7421    {
7422        noncoreInfo = new TabInfoImpl[NUM_NONCORE];
7423    }
7424
7425    /**
7426     * Get the TransactionController to use, when not
7427     * passed in as a parameter. (This hides logic about
7428     * whether or not we're at boot time in a single
7429     * place. NOTE: There's no LCC at boot time.)
7430     * NOTE: All <get> methods in the DD should call this method.
7431     *
7432     * @return TransactionController The TC to use.
7433     *
7434     * @exception StandardException Thrown on error
7435     */

7436    public TransactionController getTransactionCompile()
7437        throws StandardException
7438    {
7439        if (bootingTC != null)
7440        {
7441            if (SanityManager.DEBUG)
7442            {
7443                SanityManager.ASSERT(booting, "booting is expected to be true");
7444            }
7445            return bootingTC;
7446        }
7447        else
7448        {
7449            if (SanityManager.DEBUG)
7450            {
7451                SanityManager.ASSERT(! booting, "booting is expected to be false");
7452            }
7453            {
7454            LanguageConnectionContext lcc = getLCC();
7455            return lcc.getTransactionCompile();
7456            }
7457        }
7458    }
7459
7460
7461    /**
7462     * Get the TransactionController to use, when not
7463     * passed in as a parameter. (This hides logic about
7464     * whether or not we're at boot time in a single
7465     * place. NOTE: There's no LCC at boot time.)
7466     * NOTE: All <get> methods in the DD should call this method.
7467     *
7468     * @return TransactionController The TC to use.
7469     *
7470     * @exception StandardException Thrown on error
7471     */

7472    public TransactionController getTransactionExecute()
7473        throws StandardException
7474    {
7475        if (bootingTC != null)
7476        {
7477            if (SanityManager.DEBUG)
7478            {
7479                SanityManager.ASSERT(booting, "booting is expected to be true");
7480            }
7481            return bootingTC;
7482        }
7483        else
7484        {
7485            if (SanityManager.DEBUG)
7486            {
7487                SanityManager.ASSERT(! booting, "booting is expected to be false");
7488            }
7489            {
7490            LanguageConnectionContext lcc = getLCC();
7491            return lcc.getTransactionExecute();
7492            }
7493        }
7494    }
7495
7496    /**
7497     * Return a (single or list of) catalog row descriptor(s) from a
7498     * system table where the access is from the index to the heap.
7499     *
7500     * @param indexId The id of the index (0 to # of indexes on table) to use
7501     * @param keyRow The supplied ExecIndexRow for search
7502     * @param ti The TabInfoImpl to use
7503     * @param parentTupleDescriptor The parentDescriptor, if applicable.
7504     * @param list The list to build, if supplied. If null, then caller expects
7505     * a single descriptor
7506     * @param forUpdate Whether or not to open the index for update.
7507     *
7508     * @return The last matching descriptor
7509     *
7510     * @exception StandardException Thrown on error
7511     */

7512    private final TupleDescriptor getDescriptorViaIndex(
7513                        int indexId,
7514                        ExecIndexRow keyRow,
7515                        ScanQualifier [][] scanQualifiers,
7516                        TabInfoImpl ti,
7517                        TupleDescriptor parentTupleDescriptor,
7518                        List list,
7519                        boolean forUpdate)
7520            throws StandardException
7521    {
7522        CatalogRowFactory rf = ti.getCatalogRowFactory();
7523        ConglomerateController heapCC;
7524        ExecIndexRow indexRow1;
7525        ExecIndexRow indexTemplateRow;
7526        ExecRow outRow;
7527        RowLocation baseRowLocation;
7528        ScanController scanController;
7529        TransactionController tc;
7530        TupleDescriptor td = null;
7531
7532        // Get the current transaction controller
7533
tc = getTransactionCompile();
7534
7535        outRow = rf.makeEmptyRow();
7536
7537        heapCC = tc.openConglomerate(
7538                ti.getHeapConglomerate(), false, 0,
7539                TransactionController.MODE_RECORD,
7540                TransactionController.ISOLATION_REPEATABLE_READ);
7541
7542        /* Scan the index and go to the data pages for qualifying rows to
7543         * build the column descriptor.
7544         */

7545        scanController = tc.openScan(
7546                ti.getIndexConglomerate(indexId), // conglomerate to open
7547
false, // don't hold open across commit
7548
(forUpdate) ? TransactionController.OPENMODE_FORUPDATE : 0,
7549                TransactionController.MODE_RECORD,
7550                TransactionController.ISOLATION_REPEATABLE_READ,
7551                (FormatableBitSet) null, // all fields as objects
7552
keyRow.getRowArray(), // start position - first row
7553
ScanController.GE, // startSearchOperation
7554
scanQualifiers, //scanQualifier,
7555
keyRow.getRowArray(), // stop position - through last row
7556
ScanController.GT); // stopSearchOperation
7557

7558        while (scanController.next())
7559        {
7560            // create an index row template
7561
indexRow1 = getIndexRowFromHeapRow(
7562                                    ti.getIndexRowGenerator(indexId),
7563                                    heapCC.newRowLocationTemplate(),
7564                                    outRow);
7565
7566            scanController.fetch(indexRow1.getRowArray());
7567
7568            baseRowLocation = (RowLocation) indexRow1.getColumn(
7569                                                indexRow1.nColumns());
7570
7571            // RESOLVE paulat - remove the try catch block when track 3677 is fixed
7572
// just leave the contents of the try block
7573
// adding to get more info on track 3677
7574

7575            boolean base_row_exists = false;
7576            try
7577            {
7578                base_row_exists =
7579                    heapCC.fetch(
7580                        baseRowLocation, outRow.getRowArray(), (FormatableBitSet) null);
7581            }
7582            catch (RuntimeException JavaDoc re)
7583            {
7584                if (SanityManager.DEBUG)
7585                {
7586                    if (re instanceof AssertFailure)
7587                    {
7588                        StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc("Error retrieving base row in table "+ti.getTableName());
7589                        strbuf.append(": An ASSERT was thrown when trying to locate a row matching index row "+indexRow1+" from index "+ti.getIndexName(indexId)+", conglom number "+ti.getIndexConglomerate(indexId));
7590                        debugGenerateInfo(strbuf,tc,heapCC,ti,indexId);
7591                    }
7592                }
7593                throw re;
7594            }
7595            catch (StandardException se)
7596            {
7597                if (SanityManager.DEBUG)
7598                {
7599                    // only look for a specific error i.e. that of record on page
7600
// no longer exists
7601
// do not want to catch lock timeout errors here
7602
if (se.getSQLState().equals("XSRS9"))
7603                    {
7604                        StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc("Error retrieving base row in table "+ti.getTableName());
7605                        strbuf.append(": A StandardException was thrown when trying to locate a row matching index row "+indexRow1+" from index "+ti.getIndexName(indexId)+", conglom number "+ti.getIndexConglomerate(indexId));
7606                        debugGenerateInfo(strbuf,tc,heapCC,ti,indexId);
7607                    }
7608                }
7609                throw se;
7610            }
7611
7612            if (SanityManager.DEBUG)
7613            {
7614                // it can not be possible for heap row to disappear while
7615
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
7616
if (! base_row_exists)
7617                {
7618                    StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc("Error retrieving base row in table "+ti.getTableName());
7619                    strbuf.append(": could not locate a row matching index row "+indexRow1+" from index "+ti.getIndexName(indexId)+", conglom number "+ti.getIndexConglomerate(indexId));
7620                    debugGenerateInfo(strbuf,tc,heapCC,ti,indexId);
7621                    // RESOLVE: for now, we are going to kill the VM
7622
// to help debug this problem.
7623
System.exit(1);
7624
7625                    // RESOLVE: not currently reached
7626
//SanityManager.THROWASSERT(strbuf.toString());
7627
}
7628            }
7629
7630            td = rf.buildDescriptor(outRow, parentTupleDescriptor, this);
7631
7632            /* If list is null, then caller only wants a single descriptor - we're done
7633             * else just add the current descriptor to the list.
7634             */

7635            if (list == null)
7636            {
7637                break;
7638            }
7639            else
7640            {
7641                list.add(td);
7642            }
7643        }
7644        scanController.close();
7645        heapCC.close();
7646        return td;
7647    }
7648
7649
7650    private void debugGenerateInfo(StringBuffer JavaDoc strbuf,
7651        TransactionController tc, ConglomerateController heapCC, TabInfoImpl ti,
7652        int indexId)
7653    {
7654        if (SanityManager.DEBUG) {
7655        try
7656        {
7657            strbuf.append("\nadditional information: ");
7658
7659            // print the lock table
7660
// will get a NullPointerException if lcc doesn't yet exist e.g. at boot time
7661
LanguageConnectionContext lcc = (LanguageConnectionContext)
7662                ContextService.getContext(LanguageConnectionContext.CONTEXT_ID);
7663            if (lcc != null)
7664            {
7665                long currentTime = System.currentTimeMillis();
7666//EXCLUDE-START-lockdiag-
7667
Enumeration JavaDoc lockTable = lockFactory.makeVirtualLockTable();
7668                String JavaDoc lockTableString = Timeout.buildString(lockTable,currentTime);
7669                strbuf.append("lock table at time of failure\n\n");
7670                strbuf.append(lockTableString);
7671//EXCLUDE-END-lockdiag-
7672
}
7673
7674            // consistency checking etc.
7675
ConglomerateController btreeCC =
7676                tc.openConglomerate(
7677                    ti.getIndexConglomerate(indexId),
7678                    false,
7679                    0, TransactionController.MODE_RECORD,
7680                    TransactionController.ISOLATION_REPEATABLE_READ);
7681
7682            btreeCC.debugConglomerate();
7683            heapCC.debugConglomerate();
7684            heapCC.checkConsistency();
7685            strbuf.append("\nheapCC.checkConsistency() = true");
7686            ConglomerateController indexCC = tc.openConglomerate(
7687                ti.getIndexConglomerate(indexId),
7688                false,
7689                0,
7690                TransactionController.MODE_TABLE,
7691                TransactionController.ISOLATION_REPEATABLE_READ);
7692            indexCC.checkConsistency();
7693            strbuf.append("\nindexCC.checkConsistency() = true");
7694
7695            System.err.println("ASSERT FAILURE: "+strbuf.toString());
7696            System.out.println("ASSERT FAILURE: "+strbuf.toString());
7697            SanityManager.DEBUG_PRINT("ASSERT FAILURE", strbuf.toString());
7698        }
7699        catch (StandardException se)
7700        {
7701            strbuf.append("\ngot the following error when doing extra consistency checks:\n"+se.toString());
7702        }
7703        }
7704    }
7705
7706
7707
7708    /**
7709     * Return a (single or list of) catalog row descriptor(s) from a
7710     * system table where the access a heap scan
7711     *
7712     * @param scanQualifiers qualifiers
7713     * @param ti The TabInfoImpl to use
7714     * @param parentTupleDescriptor The parentDescriptor, if applicable.
7715     * @param list The list to build, if supplied.
7716     * If null, then caller expects a single descriptor
7717     *
7718     * @return The last matching descriptor
7719     *
7720     * @exception StandardException Thrown on error
7721     */

7722    protected TupleDescriptor getDescriptorViaHeap(
7723                        ScanQualifier [][] scanQualifiers,
7724                        TabInfoImpl ti,
7725                        TupleDescriptor parentTupleDescriptor,
7726                        List list)
7727            throws StandardException
7728    {
7729        CatalogRowFactory rf = ti.getCatalogRowFactory();
7730        ConglomerateController heapCC;
7731        ExecRow outRow;
7732        ScanController scanController;
7733        TransactionController tc;
7734        TupleDescriptor td = null;
7735
7736        // Get the current transaction controller
7737
tc = getTransactionCompile();
7738
7739        outRow = rf.makeEmptyRow();
7740
7741        /*
7742        ** Table scan
7743        */

7744        scanController = tc.openScan(
7745                ti.getHeapConglomerate(), // conglomerate to open
7746
false, // don't hold open across commit
7747
0, // for read
7748
TransactionController.MODE_TABLE,
7749                TransactionController.ISOLATION_REPEATABLE_READ,
7750                (FormatableBitSet) null, // all fields as objects
7751
(DataValueDescriptor[]) null, // start position - first row
7752
0, // startSearchOperation - none
7753
scanQualifiers, // scanQualifier,
7754
(DataValueDescriptor[]) null, // stop position - through last row
7755
0); // stopSearchOperation - none
7756

7757        while (scanController.fetchNext(outRow.getRowArray()))
7758        {
7759            td = rf.buildDescriptor(outRow, parentTupleDescriptor, this);
7760
7761            /* If dList is null, then caller only wants a single descriptor - we're done
7762             * else just add the current descriptor to the list.
7763             */

7764            if (list == null)
7765            {
7766                break;
7767            }
7768            else
7769            {
7770                list.add(td);
7771            }
7772        }
7773        scanController.close();
7774        return td;
7775    }
7776
7777    /**
7778     * Get a TabInfoImpl for a non-core table.
7779     * (We fault in information about non-core tables as needed.)
7780     *
7781     * @param catalogNumber The index into noncoreTable[].
7782     *
7783     * @exception StandardException Thrown on error
7784     */

7785    private TabInfoImpl getNonCoreTI(int catalogNumber)
7786        throws StandardException
7787    {
7788        TabInfoImpl ti = getNonCoreTIByNumber(catalogNumber);
7789
7790        faultInTabInfo( ti );
7791
7792        return ti;
7793    }
7794
7795    /** returns the tabinfo for a non core system catalog. Input is a
7796     * catalogNumber (defined in DataDictionary).
7797     */

7798    protected TabInfoImpl getNonCoreTIByNumber(int catalogNumber)
7799                        throws StandardException
7800    {
7801        int nonCoreNum = catalogNumber - NUM_CORE;
7802
7803        // Look up the TabInfoImpl in the array. This does not have to be
7804
// synchronized, because getting a reference is atomic.
7805

7806        TabInfoImpl retval = noncoreInfo[nonCoreNum];
7807
7808        if (retval == null)
7809        {
7810            // If we did not find the TabInfoImpl, get the right one and
7811
// load it into the array. There is a small chance that
7812
// two threads will do this at the same time. The code will
7813
// work properly in that case, since storing a reference
7814
// is atomic (although we could get extra object instantiation
7815
// if two threads come through here at the same time.
7816
UUIDFactory luuidFactory = uuidFactory;
7817
7818            switch (catalogNumber)
7819            {
7820              case SYSCONSTRAINTS_CATALOG_NUM:
7821                retval = new TabInfoImpl(new SYSCONSTRAINTSRowFactory(
7822                                                luuidFactory, exFactory, dvf, convertIdToLower));
7823                break;
7824
7825              case SYSKEYS_CATALOG_NUM:
7826                retval = new TabInfoImpl(new SYSKEYSRowFactory(
7827                                                luuidFactory, exFactory, dvf, convertIdToLower));
7828                break;
7829
7830              case SYSDEPENDS_CATALOG_NUM:
7831                retval = new TabInfoImpl(new SYSDEPENDSRowFactory(
7832                                                luuidFactory, exFactory, dvf, convertIdToLower));
7833                break;
7834
7835              case SYSVIEWS_CATALOG_NUM:
7836                retval = new TabInfoImpl(new SYSVIEWSRowFactory(
7837                                                luuidFactory, exFactory, dvf, convertIdToLower));
7838                break;
7839
7840              case SYSCHECKS_CATALOG_NUM:
7841                retval = new TabInfoImpl(new SYSCHECKSRowFactory(
7842                                                luuidFactory, exFactory, dvf, convertIdToLower));
7843                break;
7844
7845              case SYSFOREIGNKEYS_CATALOG_NUM:
7846                retval = new TabInfoImpl(new SYSFOREIGNKEYSRowFactory(
7847                                                luuidFactory, exFactory, dvf, convertIdToLower));
7848                break;
7849
7850              case SYSSTATEMENTS_CATALOG_NUM:
7851                retval = new TabInfoImpl(new SYSSTATEMENTSRowFactory(
7852                                                luuidFactory, exFactory, dvf, convertIdToLower));
7853                break;
7854
7855              case SYSFILES_CATALOG_NUM:
7856                retval = new TabInfoImpl(new SYSFILESRowFactory(
7857                                                luuidFactory, exFactory, dvf, convertIdToLower));
7858                break;
7859
7860              case SYSALIASES_CATALOG_NUM:
7861                retval = new TabInfoImpl(new SYSALIASESRowFactory(
7862                                                luuidFactory, exFactory, dvf, convertIdToLower));
7863                break;
7864
7865              case SYSTRIGGERS_CATALOG_NUM:
7866                retval = new TabInfoImpl(new SYSTRIGGERSRowFactory(
7867                                                luuidFactory, exFactory, dvf, convertIdToLower));
7868                break;
7869
7870              case SYSSTATISTICS_CATALOG_NUM:
7871                retval = new TabInfoImpl(new SYSSTATISTICSRowFactory(
7872                                                 luuidFactory, exFactory, dvf, convertIdToLower));
7873                break;
7874
7875              case SYSDUMMY1_CATALOG_NUM:
7876                retval = new TabInfoImpl(new SYSDUMMY1RowFactory(
7877                                                 luuidFactory, exFactory, dvf, convertIdToLower));
7878                break;
7879
7880              case SYSTABLEPERMS_CATALOG_NUM:
7881                retval = new TabInfoImpl(new SYSTABLEPERMSRowFactory(
7882                                                 luuidFactory, exFactory, dvf, convertIdToLower));
7883                break;
7884
7885              case SYSCOLPERMS_CATALOG_NUM:
7886                retval = new TabInfoImpl(new SYSCOLPERMSRowFactory(
7887                                                 luuidFactory, exFactory, dvf, convertIdToLower));
7888                break;
7889
7890              case SYSROUTINEPERMS_CATALOG_NUM:
7891                retval = new TabInfoImpl(new SYSROUTINEPERMSRowFactory(
7892                                                 luuidFactory, exFactory, dvf, convertIdToLower));
7893                break;
7894            }
7895
7896            initSystemIndexVariables(retval);
7897
7898            noncoreInfo[nonCoreNum] = retval;
7899        }
7900
7901        return retval;
7902    }
7903
7904    protected void initSystemIndexVariables(TabInfoImpl ti)
7905                        throws StandardException
7906    {
7907        int numIndexes = ti.getNumberOfIndexes();
7908
7909        if (numIndexes > 0)
7910        {
7911            DataDescriptorGenerator ddg = getDataDescriptorGenerator();
7912
7913            for (int indexCtr = 0; indexCtr < numIndexes; indexCtr++)
7914            {
7915                initSystemIndexVariables(ddg, ti, indexCtr);
7916            }
7917        }
7918    }
7919
7920    // Expected to be called only during boot time, so no synchronization.
7921
private void clearNoncoreTable(int nonCoreNum)
7922    {
7923        noncoreInfo[nonCoreNum] = null;
7924    }
7925
7926    /**
7927      * Finishes building a TabInfoImpl if it hasn't already been faulted in.
7928      * NOP if TabInfoImpl has already been faulted in.
7929      *
7930      * @param ti TabInfoImpl to fault in.
7931      *
7932      * @exception StandardException Thrown on error
7933      */

7934    public void faultInTabInfo( TabInfoImpl ti )
7935        throws StandardException
7936    {
7937        int numIndexes;
7938
7939        /* Most of the time, the noncoreInfo will be complete.
7940         * It's okay to do an unsynchronized check and return
7941         * if it is complete, since it never becomes "un-complete".
7942         * If we change the code, for some reason, to allow
7943         * it to become "un-complete" after being complete,
7944         * then we will have to do a synchronized check here
7945         * as well.
7946         */

7947        if (ti.isComplete())
7948        {
7949            return;
7950        }
7951
7952        /* The completing of the noncoreInfo entry must be synchronized.
7953         * NOTE: We are assuming that we will not access a different
7954         * noncoreInfo in the course of completing of this noncoreInfo,
7955         * otherwise a deadlock could occur.
7956         */

7957        synchronized(ti)
7958        {
7959            /* Now that we can run, the 1st thing that we must do
7960             * is to verify that we still need to complete the
7961             * object. (We may have been blocked on another user
7962             * doing the same.)
7963             */

7964            if (ti.isComplete())
7965            {
7966                return;
7967            }
7968
7969            TableDescriptor td = getTableDescriptor(ti.getTableName(),
7970                                                    getSystemSchemaDescriptor());
7971
7972            // It's possible that the system table is not there right
7973
// now. This can happen, for example, if we're in the
7974
// process of upgrading a source or target to Xena, in
7975
// which case SYSSYNCINSTANTS is dropped and re-created.
7976
// Just return in this case, so we don't get a null pointer
7977
// exception.
7978
if (td == null)
7979            {
7980                return;
7981            }
7982
7983            ConglomerateDescriptor cd = null;
7984            ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
7985
7986            /* Init the heap conglomerate here */
7987            for (int index = 0; index < cds.length; index++)
7988            {
7989                cd = cds[index];
7990
7991                if (! cd.isIndex())
7992                {
7993                    ti.setHeapConglomerate(cd.getConglomerateNumber());
7994                    break;
7995                }
7996            }
7997            
7998            if (SanityManager.DEBUG)
7999            {
8000                if (cd == null)
8001                {
8002                    SanityManager.THROWASSERT("No heap conglomerate found for "
8003                        + ti.getTableName());
8004                }
8005            }
8006
8007            /* Initialize the index conglomerates */
8008            numIndexes = ti.getCatalogRowFactory().getNumIndexes();
8009            if (numIndexes == 0)
8010            {
8011                return;
8012            }
8013
8014            /* For each index, we get its id from the CDL */
8015            ConglomerateDescriptor icd = null;
8016            int indexCount = 0;
8017
8018            for (int index = 0; index < cds.length; index++)
8019            {
8020                icd = cds[index];
8021
8022                if (icd.isIndex())
8023                {
8024                    ti.setIndexConglomerate(icd);
8025                    indexCount++;
8026                }
8027                continue;
8028            }
8029
8030            if (SanityManager.DEBUG)
8031            {
8032                if (indexCount != ti.getCatalogRowFactory().getNumIndexes())
8033                {
8034                    SanityManager.THROWASSERT("Number of indexes found (" + indexCount +
8035                        ") does not match the number expected (" +
8036                        ti.getCatalogRowFactory().getNumIndexes() + ")");
8037                }
8038            }
8039        }
8040    }
8041
8042
8043    /**
8044     * Get an index row based on a row from the heap.
8045     *
8046     * @param irg IndexRowGenerator to use
8047     * @param rl RowLocation for heap
8048     * @param heapRow Row from the heap
8049     *
8050     * @return ExecIndexRow Index row.
8051     *
8052     * @exception StandardException Thrown on error
8053     */

8054    public static ExecIndexRow getIndexRowFromHeapRow(IndexRowGenerator irg,
8055                                                        RowLocation rl,
8056                                                        ExecRow heapRow)
8057        throws StandardException
8058    {
8059        ExecIndexRow indexRow;
8060
8061        indexRow = irg.getIndexRowTemplate();
8062        // Get an index row based on the base row
8063
irg.getIndexRow(heapRow, rl, indexRow, (FormatableBitSet) null);
8064
8065        return indexRow;
8066    }
8067
8068    public int getEngineType()
8069    {
8070        return engineType;
8071    }
8072
8073
8074    /**
8075     * Get the heap conglomerate number for SYS.SYSCOLUMNS.
8076     * (Useful for adding new index to the table.)
8077     *
8078     * @return The heap conglomerate number for SYS.SYSCOLUMNS.
8079     */

8080    public long getSYSCOLUMNSHeapConglomerateNumber()
8081    {
8082        return coreInfo[SYSCOLUMNS_CORE_NUM].getHeapConglomerate();
8083    }
8084
8085    void addSYSCOLUMNSIndex2Property(TransactionController tc, long index2ConglomerateNumber)
8086    {
8087        startupParameters.put(CFG_SYSCOLUMNS_INDEX2_ID,
8088                    Long.toString(index2ConglomerateNumber));
8089    }
8090
8091    /**
8092    */

8093    private long getBootParameter(Properties JavaDoc startParams, String JavaDoc key, boolean required)
8094        throws StandardException {
8095
8096        String JavaDoc value = startParams.getProperty(key);
8097        if (value == null)
8098        {
8099            if (! required)
8100            {
8101                return -1;
8102            }
8103            throw StandardException.newException(SQLState.PROPERTY_MISSING, key);
8104        }
8105
8106        try {
8107            return Long.parseLong(value);
8108        } catch (NumberFormatException JavaDoc nfe) {
8109            throw StandardException.newException(SQLState.PROPERTY_INVALID_VALUE, key, value);
8110        }
8111    }
8112
8113    /**
8114      * Returns a unique system generated name of the form SQLyymmddhhmmssxxn
8115      * yy - year, mm - month, dd - day of month, hh - hour, mm - minute, ss - second,
8116      * xx - the first 2 digits of millisec because we don't have enough space to keep the exact millisec value,
8117      * n - number between 0-9
8118      *
8119      * The number at the end is to handle more than one system generated name request came at the same time.
8120      * In that case, the timestamp will remain the same, we will just increment n at the end of the name.
8121      *
8122      * Following is how we get around the problem of more than 10 system generated name requestes at the same time:
8123      * When the database boots up, we start a counter with value -1 for the last digit in the generated name.
8124      * We also keep the time in millisec to keep track of when the last system name was generated. At the
8125      * boot time, it will be default to 0L. In addition, we have a calendar object for the time in millisec
8126      * That calendar object is used to fetch yy, mm, dd, etc for the string SQLyymmddhhmmssxxn
8127      *
8128      * When the first request for the system generated name comes, time of last system generated name will be less than
8129      * the current time. We initialize the counter to 0, set the time of last system generated name to the
8130      * current time truncated off to lower 10ms time. The first name request is the only time we know for sure the
8131      * time of last system generated name will be less than the current time. After this first request, the next request
8132      * could be at any time. We go through the following algorithm for every generated name request.
8133      *
8134      * First check if the current time(truncated off to lower 10ms) is greater than the timestamp for last system generated name
8135      *
8136      * If yes, then we change the timestamp for system generated name to the current timestamp and reset the counter to 0
8137      * and generate the name using the current timestamp and 0 as the number at the end of the generated name.
8138      *
8139      * If no, then it means this request for generated name has come at the same time as last one.
8140      * Or it may come at a time less than the last generated name request. This could be because of seasonal time change
8141      * or somebody manually changing the time on the computer. In any case,
8142      * if the counter is less than 10(meaning this is not yet our 11th request for generated name at a given time),
8143      * we use that in the generated name. But if the counter has reached 10(which means, this is the 11th name request
8144      * at the same time), then we increment the system generated name timestamp by 10ms and reset the counter to 0
8145      * (notice, at this point, the timestamp for system generated names is not in sync with the real current time, but we
8146      * need to have this mechanism to get around the problem of more than 10 generated name requests at a same physical time).
8147      *
8148      * @return system generated unique name
8149      */

8150    public String JavaDoc getSystemSQLName()
8151    {
8152        //note that we are using Date class to change the Calendar object time rather than Calendar.setTimeInMills.
8153
//This is because of java bug 4243802. setTimeInMillis and getTimeInMillis were protected prior to jdk14
8154
//But since we still support jdk13, we can't rely on these methods being public starting jdk14.
8155
//Because of that, we are using Date to do all the time manipulations on the Calendar object
8156
StringBuffer JavaDoc generatedSystemSQLName = new StringBuffer JavaDoc("SQL");
8157            synchronized (this) {
8158                //get the current timestamp
8159
long timeNow = (System.currentTimeMillis()/10L)*10L;
8160
8161                //if the current timestamp is greater than last constraint name generation time, then we reset the counter and
8162
//record the new timestamp
8163
if (timeNow > timeForLastSystemSQLName) {
8164                    systemSQLNameNumber = 0;
8165                    calendarForLastSystemSQLName.setTime(new Date JavaDoc(timeNow));
8166                    timeForLastSystemSQLName = timeNow;
8167                } else {
8168                    //the request has come at the same time as the last generated name request
8169
//or it has come at a time less than the time the last generated name request. This can happen
8170
//because of seasonal time change or manual update of computer time.
8171

8172                    //get the number that was last used for the last digit of generated name and increment it by 1.
8173
systemSQLNameNumber++;
8174                    if (systemSQLNameNumber == 10) { //we have already generated 10 names at the last system generated timestamp value
8175
//so reset the counter
8176
systemSQLNameNumber = 0;
8177                        timeForLastSystemSQLName = timeForLastSystemSQLName + 10L;
8178                        //increment the timestamp for system generated names by 10ms
8179
calendarForLastSystemSQLName.setTime(new Date JavaDoc(timeForLastSystemSQLName));
8180                    }
8181                }
8182
8183                generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.YEAR)));
8184                //have to add 1 to the month value returned because the method give 0-January, 1-February and so on and so forth
8185
generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.MONTH)+1));
8186                generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.DAY_OF_MONTH)));
8187                generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.HOUR)));
8188                generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.MINUTE)));
8189                generatedSystemSQLName.append(twoDigits(calendarForLastSystemSQLName.get(Calendar.SECOND)));
8190                //because we don't have enough space to store the entire millisec value, just store the higher 2 digits.
8191
generatedSystemSQLName.append(twoDigits((int) (calendarForLastSystemSQLName.get(Calendar.MILLISECOND)/10)));
8192                generatedSystemSQLName.append(systemSQLNameNumber);
8193            }
8194        return generatedSystemSQLName.toString();
8195    }
8196
8197    private static String JavaDoc twoDigits(int val) {
8198        String JavaDoc retval;
8199
8200        if (val < 10) {
8201            retval = "0" + val;
8202        } else {
8203            int retvalLength = Integer.toString(val).length();
8204            retval = Integer.toString(val).substring(retvalLength-2);
8205        }
8206
8207        return retval;
8208    }
8209
8210    /**
8211     * sets a new value in SYSCOLUMNS for a particular
8212     * autoincrement column.
8213     *
8214     * @param tc Transaction Controller to use.
8215     * @param columnName Name of the column.
8216     * @param aiValue Value to write to SYSCOLUMNS.
8217     * @param incrementNeeded whether to increment the value passed in by the
8218     * user (aiValue) or not before writing it to SYSCOLUMNS.
8219     */

8220    public void setAutoincrementValue(TransactionController tc,
8221                                      UUID tableUUID,
8222                                      String JavaDoc columnName,
8223                                      long aiValue, boolean incrementNeeded)
8224            throws StandardException
8225    {
8226        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
8227        ExecIndexRow keyRow = null;
8228
8229        keyRow = (ExecIndexRow)exFactory.getIndexableRow(2);
8230        keyRow.setColumn(1, dvf.getCharDataValue(tableUUID.toString()));
8231        keyRow.setColumn(2, dvf.getCharDataValue(columnName));
8232        
8233        SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti.getCatalogRowFactory();
8234        ExecRow row = rf.makeEmptyRow();
8235
8236        boolean[] bArray = new boolean[2];
8237        for (int index = 0; index < 2; index++)
8238        {
8239            bArray[index] = false;
8240        }
8241        
8242        int[] colsToUpdate = new int[1];
8243        
8244        colsToUpdate[0] = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
8245
8246        if (incrementNeeded)
8247        {
8248            ExecRow readRow = ti.getRow(tc, keyRow,
8249                                    SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID);
8250            NumberDataValue increment =
8251                (NumberDataValue)readRow.getColumn(SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTINC);
8252            aiValue += increment.getLong();
8253        }
8254        row.setColumn(SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE,
8255                      dvf.getDataValue(aiValue));
8256
8257        ti.updateRow(keyRow, row,
8258                     SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID,
8259                     bArray,
8260                     colsToUpdate,
8261                     tc);
8262        return;
8263    }
8264
8265    /**
8266     * Computes the RowLocation in SYSCOLUMNS for a particular
8267     * autoincrement column.
8268     *
8269     * @param tc Transaction Controller to use.
8270     * @param td Table Descriptor.
8271     * @param columnName Name of column which has autoincrement column.
8272     *
8273     * @exception StandardException thrown on failure.
8274     */

8275    private RowLocation computeRowLocation(TransactionController tc,
8276                                          TableDescriptor td,
8277                                          String JavaDoc columnName)
8278        throws StandardException
8279    {
8280        TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
8281        ExecIndexRow keyRow = null;
8282        ExecRow row;
8283        UUID tableUUID = td.getUUID();
8284
8285        keyRow = (ExecIndexRow)exFactory.getIndexableRow(2);
8286        keyRow.setColumn(1, dvf.getCharDataValue(tableUUID.toString()));
8287        keyRow.setColumn(2, dvf.getCharDataValue(columnName));
8288        return ti.getRowLocation(tc, keyRow,
8289                                 SYSCOLUMNSRowFactory.SYSCOLUMNS_INDEX1_ID);
8290    }
8291
8292    public RowLocation getRowLocationTemplate(LanguageConnectionContext lcc,
8293                                              TableDescriptor td)
8294          throws StandardException
8295    {
8296        RowLocation rl;
8297        ConglomerateController heapCC = null;
8298
8299        TransactionController tc =
8300            lcc.getTransactionCompile();
8301
8302        long tableId = td.getHeapConglomerateId();
8303        heapCC =
8304            tc.openConglomerate(
8305                tableId, false, 0, tc.MODE_RECORD, tc.ISOLATION_READ_COMMITTED);
8306        try
8307        {
8308            rl = heapCC.newRowLocationTemplate();
8309        }
8310        finally
8311        {
8312            heapCC.close();
8313        }
8314
8315        return rl;
8316    }
8317    
8318    /**
8319     *
8320     * Add a table descriptor to the "other" cache. The other cache is
8321     * determined by the type of the object c.
8322     *
8323     * @param td TableDescriptor to add to the other cache.
8324     * @param c Cacheable Object which lets us figure out the other cache.
8325     *
8326     * @exception StandardException
8327     */

8328    public void addTableDescriptorToOtherCache(TableDescriptor td,
8329                                               Cacheable c)
8330        throws StandardException
8331    {
8332        // get the other cache. if the entry we are setting in the cache is of
8333
// type oidtdcacheable then use the nametdcache
8334
CacheManager otherCache =
8335            (c instanceof OIDTDCacheable) ? nameTdCache : OIDTdCache;
8336        Object JavaDoc key;
8337        TDCacheable otherCacheEntry = null;
8338
8339        if (otherCache == nameTdCache)
8340            key = new TableKey(td.getSchemaDescriptor().getUUID(), td.getName());
8341        else
8342            key = td.getUUID();
8343
8344        try
8345        {
8346            // insert the entry into the the other cache.
8347
otherCacheEntry = (TDCacheable)otherCache.create(key, td);
8348        }
8349        catch (StandardException se)
8350        {
8351            // if the object already exists in cache then somebody beat us to it
8352
// otherwise throw the error.
8353
if (!(se.getMessageId().equals(SQLState.OBJECT_EXISTS_IN_CACHE)))
8354                throw se;
8355        }
8356        finally
8357        {
8358            if (otherCacheEntry != null)
8359                otherCache.release(otherCacheEntry);
8360        }
8361    }
8362    
8363
8364    /** @see DataDictionary#dropStatisticsDescriptors */
8365    public void dropStatisticsDescriptors(UUID tableUUID, UUID referenceUUID,
8366                                     TransactionController tc)
8367        throws StandardException
8368    {
8369        TabInfoImpl ti = getNonCoreTI(SYSSTATISTICS_CATALOG_NUM);
8370        DataValueDescriptor first, second;
8371        first = dvf.getCharDataValue(tableUUID.toString());
8372
8373        ExecIndexRow keyRow;
8374        if (referenceUUID != null)
8375        {
8376            keyRow = exFactory.getIndexableRow(2);
8377            second = dvf.getCharDataValue(referenceUUID.toString());
8378            keyRow.setColumn(2, second);
8379        }
8380        else
8381        {
8382            keyRow = exFactory.getIndexableRow(1);
8383        }
8384
8385        keyRow.setColumn(1, first);
8386
8387        ti.deleteRow(tc, keyRow,
8388                     SYSSTATISTICSRowFactory.SYSSTATISTICS_INDEX1_ID);
8389        
8390    }
8391
8392    private static LanguageConnectionContext getLCC() {
8393        return (LanguageConnectionContext)
8394                    ContextService.getContextOrNull(LanguageConnectionContext.CONTEXT_ID);
8395    }
8396
8397    private SchemaDescriptor newSystemSchemaDesc(
8398    String JavaDoc name,
8399    String JavaDoc uuid)
8400    {
8401        return new SchemaDescriptor(
8402                this,
8403                name,
8404                authorizationDatabaseOwner,
8405                uuidFactory.recreateUUID(uuid),
8406                true);
8407    }
8408
8409    private SchemaDescriptor newDeclaredGlobalTemporaryTablesSchemaDesc( String JavaDoc name)
8410    {
8411        return new SchemaDescriptor(this,
8412                                        name,
8413                                        authorizationDatabaseOwner,
8414                                        (UUID) null,
8415                                        false);
8416    }
8417    /**
8418        Check to see if a database has been upgraded to the required
8419        level in order to use a language feature.
8420
8421        @param requiredMajorVersion Data Dictionary major version
8422        @param feature Non-null to throw an error, null to return the state of the version match.
8423
8424        @return True if the database has been upgraded to the required level, false otherwise.
8425    */

8426    public boolean checkVersion(int requiredMajorVersion, String JavaDoc feature) throws StandardException {
8427
8428        if (requiredMajorVersion == DataDictionary.DD_VERSION_CURRENT) {
8429            requiredMajorVersion = softwareVersion.majorVersionNumber;
8430        }
8431
8432        return dictionaryVersion.checkVersion(requiredMajorVersion, feature);
8433    }
8434        
8435    /**
8436    ** Create system built-in metadata stored prepared statements.
8437    */

8438    void createSystemSps(TransactionController tc)
8439        throws StandardException
8440    {
8441        // DatabaseMetadata stored plans
8442
createSPSSet(tc, false, getSystemSchemaDescriptor().getUUID());
8443
8444        // network server stored plans
8445
createSPSSet(tc, true, getSysIBMSchemaDescriptor().getUUID());
8446    }
8447
8448    /**
8449        Create a set of stored prepared statements from a properties file.
8450        Key is the statement name, value is the SQL statement.
8451    */

8452    protected void createSPSSet(TransactionController tc, boolean net, UUID schemaID)
8453        throws StandardException
8454    {
8455        Properties JavaDoc p = getQueryDescriptions(net);
8456        Enumeration JavaDoc e = p.keys();
8457        //statement will get compiled on first execution
8458
//Note: Don't change this to FALSE LCC is not available for compiling
8459
boolean nocompile = true;
8460        
8461        while (e.hasMoreElements())
8462        {
8463            String JavaDoc spsName = (String JavaDoc)e.nextElement();
8464            String JavaDoc spsText = p.getProperty(spsName);
8465            SPSDescriptor spsd = new SPSDescriptor(this, spsName,
8466                                                   getUUIDFactory().createUUID(),
8467                                                   schemaID,
8468                                                   schemaID,
8469                                                   SPSDescriptor.SPS_TYPE_REGULAR,
8470                                                   !nocompile, // it is valid, unless nocompile
8471
spsText, //sps text
8472
!nocompile );
8473            
8474            addSPSDescriptor(spsd, tc, true);
8475        }
8476    }
8477
8478
8479    /**
8480     * Generic create procedure routine.
8481     * <p>
8482     * Takes the input procedure and inserts it into the appropriate
8483     * catalog.
8484     *
8485     * Assumes all arguments are "IN" type.
8486     *
8487     * @param routine_name name of the routine in java and the SQL
8488     * procedure name.
8489     *
8490     * @param arg_names String array of procedure argument names in order.
8491     *
8492     * @param arg_types Internal SQL types of the arguments
8493     *
8494     * @param routine_sql_control
8495     * One of the RoutineAliasInfo constants:
8496     * MODIFIES_SQL_DATA
8497     * READS_SQL_DATA
8498     * CONTAINS_SQL
8499     * NO_SQL
8500     *
8501     * @param return_type null for procedure. For functions the return type
8502     * of the function.
8503     *
8504     * @return UUID UUID of system routine that got created.
8505     *
8506     * @exception StandardException Standard exception policy.
8507     **/

8508    private final UUID createSystemProcedureOrFunction(
8509    String JavaDoc routine_name,
8510    UUID schema_uuid,
8511    String JavaDoc[] arg_names,
8512    TypeDescriptor[] arg_types,
8513    int num_out_param,
8514    int num_result_sets,
8515    short routine_sql_control,
8516    TypeDescriptor return_type,
8517    TransactionController tc)
8518        throws StandardException
8519    {
8520        int num_args = 0;
8521        if (arg_names != null)
8522            num_args = arg_names.length;
8523
8524        if (SanityManager.DEBUG)
8525        {
8526            if (num_args != 0)
8527            {
8528                SanityManager.ASSERT(arg_names != null);
8529                SanityManager.ASSERT(arg_types != null);
8530                SanityManager.ASSERT(arg_names.length == arg_types.length);
8531            }
8532        }
8533
8534        // Actual procedures are in this class:
8535
String JavaDoc procClass = "org.apache.derby.catalog.SystemProcedures";
8536
8537        // all args are only "in" arguments
8538
int[] arg_modes = null;
8539        if (num_args != 0)
8540        {
8541            arg_modes = new int[num_args];
8542            int num_in_param = num_args - num_out_param;
8543            for (int i = 0; i < num_in_param; i++)
8544                arg_modes[i] = JDBC30Translation.PARAMETER_MODE_IN;
8545            for (int i = 0; i < num_out_param; i++)
8546                arg_modes[num_in_param + i] = JDBC30Translation.PARAMETER_MODE_OUT;
8547        }
8548
8549        RoutineAliasInfo routine_alias_info =
8550            new RoutineAliasInfo(
8551                routine_name, // name of routine
8552
num_args, // number of params
8553
arg_names, // names of params
8554
arg_types, // types of params
8555
arg_modes, // all "IN" params
8556
num_result_sets, // number of result sets
8557
RoutineAliasInfo.PS_JAVA, // link to java routine
8558
routine_sql_control, // one of:
8559
// MODIFIES_SQL_DATA
8560
// READS_SQL_DATA
8561
// CONTAINS_SQL
8562
// NO_SQL
8563
true, // true - calledOnNullInput
8564
return_type);
8565
8566        UUID routine_uuid = getUUIDFactory().createUUID();
8567        AliasDescriptor ads =
8568            new AliasDescriptor(
8569                this,
8570                routine_uuid,
8571                routine_name,
8572                schema_uuid,
8573                procClass,
8574                (return_type == null) ?
8575                    AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR :
8576                    AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR,
8577                (return_type == null) ?
8578                    AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR :
8579                    AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR,
8580                false,
8581                routine_alias_info, null);
8582
8583        addDescriptor(
8584            ads, null, DataDictionary.SYSALIASES_CATALOG_NUM, false, tc);
8585
8586        return routine_uuid;
8587    }
8588
8589    /**
8590     * Create system procedures
8591     * <p>
8592     * Used to add the system procedures to the database when
8593     * it is created. System procedures are currently added to
8594     * either SYSCS_UTIL or SQLJ schemas.
8595     * <p>
8596     *
8597     * @param tc transaction controller to use. Counts on caller to
8598     * commit.
8599     *
8600     * @exception StandardException Standard exception policy.
8601     **/

8602    private final void create_SYSCS_procedures(
8603    TransactionController tc)
8604        throws StandardException
8605    {
8606        /*
8607        ** SYSCS_UTIL routines.
8608        */

8609
8610        UUID routine_uuid = null;
8611        // used to put procedure into the SYSCS_UTIL schema
8612
UUID sysUtilUUID = getSystemUtilSchemaDescriptor().getUUID();
8613
8614
8615        // void SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(
8616
// varchar(128), varchar(Limits.DB2_VARCHAR_MAXWIDTH))
8617
{
8618
8619            // procedure argument names
8620
String JavaDoc[] arg_names = {
8621                "KEY",
8622                "VALUE"};
8623
8624            // procedure argument types
8625
TypeDescriptor[] arg_types = {
8626                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8627                    Types.VARCHAR, 128),
8628                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8629                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH)
8630            };
8631
8632            createSystemProcedureOrFunction(
8633                "SYSCS_SET_DATABASE_PROPERTY",
8634                sysUtilUUID,
8635                arg_names,
8636                arg_types,
8637                0,
8638                0,
8639                RoutineAliasInfo.MODIFIES_SQL_DATA,
8640                (TypeDescriptor) null,
8641                tc);
8642        }
8643
8644
8645        // void SYSCS_UTIL.SYSCS_COMPRESS_TABLE(varchar(128), varchar(128), SMALLINT)
8646
{
8647            // procedure argument names
8648
String JavaDoc[] arg_names = {"SCHEMANAME", "TABLENAME", "SEQUENTIAL"};
8649
8650            // procedure argument types
8651
TypeDescriptor[] arg_types = {
8652                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8653                    Types.VARCHAR, 128),
8654                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8655                    Types.VARCHAR, 128),
8656                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8657                    Types.SMALLINT)
8658
8659            };
8660
8661            routine_uuid = createSystemProcedureOrFunction(
8662                "SYSCS_COMPRESS_TABLE",
8663                sysUtilUUID,
8664                arg_names,
8665                arg_types,
8666                0,
8667                0,
8668                RoutineAliasInfo.MODIFIES_SQL_DATA,
8669                (TypeDescriptor) null,
8670                tc);
8671
8672            createRoutinePermPublicDescriptor(routine_uuid, tc);
8673        }
8674
8675        // void SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE()
8676
{
8677            createSystemProcedureOrFunction(
8678                "SYSCS_CHECKPOINT_DATABASE",
8679                sysUtilUUID,
8680                null,
8681                null,
8682                0,
8683                0,
8684                RoutineAliasInfo.CONTAINS_SQL,
8685                (TypeDescriptor) null,
8686                tc);
8687        }
8688
8689        // void SYSCS_UTIL.SYSCS_FREEZE_DATABASE()
8690
{
8691            createSystemProcedureOrFunction(
8692                "SYSCS_FREEZE_DATABASE",
8693                sysUtilUUID,
8694                null,
8695                null,
8696                0,
8697                0,
8698                RoutineAliasInfo.CONTAINS_SQL,
8699                (TypeDescriptor) null,
8700                tc);
8701        }
8702
8703        // void SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE()
8704
{
8705            createSystemProcedureOrFunction(
8706                "SYSCS_UNFREEZE_DATABASE",
8707                sysUtilUUID,
8708                null,
8709                null,
8710                0,
8711                0,
8712                RoutineAliasInfo.CONTAINS_SQL,
8713                (TypeDescriptor) null,
8714                tc);
8715        }
8716
8717        // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE(varchar Limits.DB2_VARCHAR_MAXWIDTH)
8718
{
8719            // procedure argument names
8720
String JavaDoc[] arg_names = {"BACKUPDIR"};
8721
8722            // procedure argument types
8723
TypeDescriptor[] arg_types = {
8724                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8725                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH)
8726            };
8727
8728            createSystemProcedureOrFunction(
8729                "SYSCS_BACKUP_DATABASE",
8730                sysUtilUUID,
8731                arg_names,
8732                arg_types,
8733                0,
8734                0,
8735                RoutineAliasInfo.MODIFIES_SQL_DATA,
8736                (TypeDescriptor) null,
8737                tc);
8738        }
8739
8740        // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE(
8741
// varchar Limits.DB2_VARCHAR_MAXWIDTH, smallint)
8742
{
8743            // procedure argument names
8744
String JavaDoc[] arg_names = {"BACKUPDIR", "DELETE_ARCHIVED_LOG_FILES"};
8745
8746            // procedure argument types
8747
TypeDescriptor[] arg_types = {
8748                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8749                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
8750                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8751                    Types.SMALLINT)
8752            };
8753
8754            createSystemProcedureOrFunction(
8755                "SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE",
8756                sysUtilUUID,
8757                arg_names,
8758                arg_types,
8759                0,
8760                0,
8761                RoutineAliasInfo.MODIFIES_SQL_DATA,
8762                (TypeDescriptor) null,
8763                tc);
8764        }
8765
8766        // void SYSCS_UTIL.SYSCS_DISABLE_LOG_ARCHIVE_MODE(smallint)
8767
{
8768            // procedure argument names
8769
String JavaDoc[] arg_names = {"DELETE_ARCHIVED_LOG_FILES"};
8770
8771            // procedure argument types
8772
TypeDescriptor[] arg_types = {
8773                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8774                    Types.SMALLINT)
8775            };
8776
8777            createSystemProcedureOrFunction(
8778                "SYSCS_DISABLE_LOG_ARCHIVE_MODE",
8779                sysUtilUUID,
8780                arg_names,
8781                arg_types,
8782                0,
8783                0,
8784                RoutineAliasInfo.MODIFIES_SQL_DATA,
8785                (TypeDescriptor) null,
8786                tc);
8787        }
8788
8789        // void SYSCS_UTIL.SYSCS_SET_RUNTIMESTTISTICS(smallint)
8790
{
8791            // procedure argument names
8792
String JavaDoc[] arg_names = {"ENABLE"};
8793
8794            // procedure argument types
8795
TypeDescriptor[] arg_types = {
8796                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8797                    Types.SMALLINT)
8798            };
8799
8800            routine_uuid = createSystemProcedureOrFunction(
8801                "SYSCS_SET_RUNTIMESTATISTICS",
8802                sysUtilUUID,
8803                arg_names,
8804                arg_types,
8805                0,
8806                0,
8807                RoutineAliasInfo.CONTAINS_SQL,
8808                (TypeDescriptor) null,
8809                tc);
8810
8811            createRoutinePermPublicDescriptor(routine_uuid, tc);
8812        }
8813
8814        // void SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(smallint)
8815
{
8816            // procedure argument names
8817
String JavaDoc[] arg_names = {"ENABLE"};
8818
8819            // procedure argument types
8820
TypeDescriptor[] arg_types = {
8821                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8822                    Types.SMALLINT)
8823            };
8824
8825            routine_uuid = createSystemProcedureOrFunction(
8826                "SYSCS_SET_STATISTICS_TIMING",
8827                sysUtilUUID,
8828                arg_names,
8829                arg_types,
8830                0,
8831                0,
8832                RoutineAliasInfo.CONTAINS_SQL,
8833                (TypeDescriptor) null,
8834                tc);
8835
8836            createRoutinePermPublicDescriptor(routine_uuid, tc);
8837        }
8838
8839
8840        // SYSCS_UTIL functions
8841
//
8842
// TODO (mikem) -
8843
// the following need to be functions when that is supported.
8844
// until then calling them will not work.
8845

8846        // VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH)
8847
// SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(varchar(128))
8848

8849        {
8850            // procedure argument names
8851
String JavaDoc[] arg_names = {"KEY"};
8852
8853            // procedure argument types
8854
TypeDescriptor[] arg_types = {
8855                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8856                    Types.VARCHAR, 128)
8857            };
8858
8859            createSystemProcedureOrFunction(
8860                "SYSCS_GET_DATABASE_PROPERTY",
8861                sysUtilUUID,
8862                arg_names,
8863                arg_types,
8864                0,
8865                0,
8866                RoutineAliasInfo.READS_SQL_DATA,
8867                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8868                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
8869                tc);
8870        }
8871
8872        // SMALLINT SYSCS_UTIL.SYSCS_CHECK_TABLE(varchar(128), varchar(128))
8873
{
8874            // procedure argument names
8875
String JavaDoc[] arg_names = {"SCHEMANAME", "TABLENAME"};
8876
8877            // procedure argument types
8878
TypeDescriptor[] arg_types = {
8879                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8880                    Types.VARCHAR, 128),
8881                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8882                    Types.VARCHAR, 128)
8883            };
8884
8885            createSystemProcedureOrFunction(
8886                "SYSCS_CHECK_TABLE",
8887                sysUtilUUID,
8888                arg_names,
8889                arg_types,
8890                0,
8891                0,
8892                RoutineAliasInfo.READS_SQL_DATA,
8893                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8894                    Types.INTEGER),
8895                tc);
8896        }
8897
8898        // CLOB SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS()
8899
{
8900
8901            routine_uuid = createSystemProcedureOrFunction(
8902                "SYSCS_GET_RUNTIMESTATISTICS",
8903                sysUtilUUID,
8904                null,
8905                null,
8906                0,
8907                0,
8908                RoutineAliasInfo.CONTAINS_SQL,
8909                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8910                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
8911
8912                /*
8913                TODO - mikem, wants to be a CLOB, but don't know how to do
8914                that yet. Testing it with varchar for now.
8915                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8916                    Types.CLOB, Limits.DB2_LOB_MAXWIDTH),
8917                */

8918                tc);
8919
8920            createRoutinePermPublicDescriptor(routine_uuid, tc);
8921        }
8922
8923
8924        /*
8925        ** SQLJ routine.
8926        */

8927
8928        UUID sqlJUUID =
8929            getSchemaDescriptor(
8930                SchemaDescriptor.STD_SQLJ_SCHEMA_NAME, tc, true).getUUID();
8931
8932        // SQLJ.INSTALL_JAR(URL VARCHAR(??), JAR VARCHAR(128), DEPLOY INT)
8933
{
8934            String JavaDoc[] arg_names = {"URL", "JAR", "DEPLOY"};
8935
8936            TypeDescriptor[] arg_types = {
8937                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8938                    Types.VARCHAR, 256),
8939                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8940                    Types.VARCHAR, 128),
8941                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8942                    Types.INTEGER)
8943            };
8944
8945            createSystemProcedureOrFunction(
8946                "INSTALL_JAR",
8947                sqlJUUID,
8948                arg_names,
8949                arg_types,
8950                0,
8951                0,
8952                RoutineAliasInfo.MODIFIES_SQL_DATA,
8953                (TypeDescriptor) null,
8954                tc);
8955        }
8956
8957        // SQLJ.REPLACE_JAR(URL VARCHAR(??), JAR VARCHAR(128))
8958
{
8959            String JavaDoc[] arg_names = {"URL", "JAR"};
8960
8961            TypeDescriptor[] arg_types = {
8962                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8963                    Types.VARCHAR, 256),
8964                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8965                    Types.VARCHAR, 128)
8966            };
8967
8968            createSystemProcedureOrFunction(
8969                "REPLACE_JAR",
8970                sqlJUUID,
8971                arg_names,
8972                arg_types,
8973                0,
8974                0,
8975                RoutineAliasInfo.MODIFIES_SQL_DATA,
8976                (TypeDescriptor) null,
8977                tc);
8978        }
8979    
8980        // SQLJ.REMOVE_JAR(JAR VARCHAR(128), UNDEPLOY INT)
8981
{
8982            String JavaDoc[] arg_names = {"JAR", "UNDEPLOY"};
8983
8984            TypeDescriptor[] arg_types = {
8985                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8986                    Types.VARCHAR, 128),
8987                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
8988                    Types.INTEGER)
8989            };
8990
8991            createSystemProcedureOrFunction(
8992                "REMOVE_JAR",
8993                sqlJUUID,
8994                arg_names,
8995                arg_types,
8996                0,
8997                0,
8998                RoutineAliasInfo.MODIFIES_SQL_DATA,
8999                (TypeDescriptor) null,
9000                tc);
9001        }
9002
9003        /* SYSCS_EXPORT_TABLE (IN SCHEMANAME VARCHAR(128),
9004         * IN TABLENAME VARCHAR(128), IN FILENAME VARCHAR(32672) ,
9005         * IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER CHAR(1) ,
9006         * IN CODESET VARCHAR(128))
9007         */

9008
9009        
9010        {
9011            // procedure argument names
9012
String JavaDoc[] arg_names = {"schemaName", "tableName" ,
9013                                  "fileName"," columnDelimiter",
9014                                  "characterDelimiter", "codeset"};
9015
9016            // procedure argument types
9017
TypeDescriptor[] arg_types = {
9018                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9019                Types.VARCHAR, 128),
9020                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9021                Types.VARCHAR, 128),
9022                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9023                Types.VARCHAR, 32672),
9024                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9025                Types.CHAR, 1),
9026                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9027                Types.CHAR, 1),
9028                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9029                Types.VARCHAR, 128)
9030            };
9031
9032            createSystemProcedureOrFunction(
9033                "SYSCS_EXPORT_TABLE",
9034                sysUtilUUID,
9035                arg_names,
9036                arg_types,
9037                0,
9038                0,
9039                RoutineAliasInfo.READS_SQL_DATA,
9040                (TypeDescriptor) null,
9041                tc);
9042        }
9043
9044
9045        /* SYSCS_EXPORT_QUERY (IN SELECTSTATEMENT VARCHAR(32672),
9046         * IN FILENAME VARCHAR(32672) ,
9047         * IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER CHAR(1) ,
9048         * IN CODESET VARCHAR(128))
9049         */

9050        {
9051            // procedure argument names
9052
String JavaDoc[] arg_names = {"selectStatement", "fileName",
9053                                  " columnDelimiter", "characterDelimiter",
9054                                  "codeset"};
9055
9056            // procedure argument types
9057
TypeDescriptor[] arg_types = {
9058                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9059                Types.VARCHAR, 32672),
9060                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9061                Types.VARCHAR, 32672),
9062                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9063                Types.CHAR, 1),
9064                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9065                Types.CHAR, 1),
9066                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9067                Types.VARCHAR, 128)
9068            };
9069
9070            createSystemProcedureOrFunction(
9071               "SYSCS_EXPORT_QUERY",
9072                sysUtilUUID,
9073                arg_names,
9074                arg_types,
9075                0,
9076                0,
9077                RoutineAliasInfo.READS_SQL_DATA,
9078                (TypeDescriptor) null,
9079                tc);
9080        }
9081
9082        
9083        /* SYSCS_IMPORT_TABLE(IN SCHEMANAME VARCHAR(128),
9084         * IN TABLENAME VARCHAR(128), IN FILENAME VARCHAR(32762),
9085         * IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER CHAR(1),
9086         * IN CODESET VARCHAR(128) , IN REPLACE SMALLINT)
9087         */

9088        {
9089            // procedure argument names
9090
String JavaDoc[] arg_names = {"schemaName", "tableName", "fileName",
9091                                  " columnDelimiter", "characterDelimiter",
9092                                  "codeset", "replace"};
9093
9094            // procedure argument types
9095

9096            // procedure argument types
9097
TypeDescriptor[] arg_types = {
9098                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9099                Types.VARCHAR, 128),
9100                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9101                Types.VARCHAR, 128),
9102                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9103                Types.VARCHAR, 32672),
9104                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9105                Types.CHAR, 1),
9106                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9107                Types.CHAR, 1),
9108                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9109                Types.VARCHAR, 128),
9110                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9111                Types.SMALLINT),
9112            };
9113
9114
9115            createSystemProcedureOrFunction(
9116               "SYSCS_IMPORT_TABLE",
9117                sysUtilUUID,
9118                arg_names,
9119                arg_types,
9120                0,
9121                0,
9122                RoutineAliasInfo.MODIFIES_SQL_DATA,
9123                (TypeDescriptor) null,
9124                tc);
9125        }
9126
9127                
9128        /* SYSCS_IMPORT_DATA(IN SCHEMANAME VARCHAR(128),
9129         * IN TABLENAME VARCHAR(128), IN INSERTCOLUMNLIST VARCHAR(32762),
9130         * IN COLUMNINDEXES VARCHAR(32762), IN IN FILENAME VARCHAR(32762),
9131         * IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER CHAR(1),
9132         * IN CODESET VARCHAR(128) , IN REPLACE SMALLINT)
9133         */

9134        {
9135            // procedure argument names
9136
String JavaDoc[] arg_names = {"schemaName", "tableName", "insertColumnList","columnIndexes",
9137                                  "fileName", " columnDelimiter", "characterDelimiter",
9138                                  "codeset", "replace"};
9139
9140            // procedure argument types
9141

9142            // procedure argument types
9143
TypeDescriptor[] arg_types = {
9144                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9145                Types.VARCHAR, 128),
9146                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9147                Types.VARCHAR, 128),
9148                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9149                Types.VARCHAR, 32672),
9150                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9151                Types.VARCHAR, 32672),
9152                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9153                Types.VARCHAR, 32672),
9154                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9155                Types.CHAR, 1),
9156                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9157                Types.CHAR, 1),
9158                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9159                Types.VARCHAR, 128),
9160                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9161                Types.SMALLINT),
9162            };
9163
9164
9165            createSystemProcedureOrFunction(
9166               "SYSCS_IMPORT_DATA",
9167                sysUtilUUID,
9168                arg_names,
9169                arg_types,
9170                0,
9171                0,
9172                RoutineAliasInfo.MODIFIES_SQL_DATA,
9173                (TypeDescriptor) null,
9174                tc);
9175        }
9176
9177                        
9178        /*
9179         * SYSCS_BULK_INSERT(
9180         * IN SCHEMANAME VARCHAR(128),
9181         * IN TABLENAME VARCHAR(128),
9182         * IN VTINAME VARCHAR(32762),
9183         * IN VTIARG VARCHAR(32762))
9184         */

9185        {
9186            // procedure argument names
9187
String JavaDoc[] arg_names = {"schemaName", "tableName", "vtiName","vtiArg"};
9188
9189            
9190            // procedure argument types
9191
TypeDescriptor[] arg_types = {
9192                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9193                Types.VARCHAR, 128),
9194                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9195                Types.VARCHAR, 128),
9196                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9197                Types.VARCHAR, 32672),
9198                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9199                Types.VARCHAR, 32672),
9200            };
9201
9202
9203            createSystemProcedureOrFunction(
9204               "SYSCS_BULK_INSERT",
9205                sysUtilUUID,
9206                arg_names,
9207                arg_types,
9208                0,
9209                0,
9210                RoutineAliasInfo.MODIFIES_SQL_DATA,
9211                (TypeDescriptor) null,
9212                tc);
9213        }
9214
9215        // add 10.1 specific system procedures
9216
create_10_1_system_procedures(tc, sysUtilUUID);
9217        // add 10.2 specific system procedures
9218
create_10_2_system_procedures(tc, sysUtilUUID);
9219    }
9220
9221    /**
9222     * Create system procedures in SYSIBM
9223     * <p>
9224     * Used to add the system procedures to the database when
9225     * it is created. Full upgrade from version 5.1 or earlier also
9226     * calls this method.
9227     * <p>
9228     *
9229     * @param tc transaction controller to use. Counts on caller to
9230     * commit.
9231     *
9232     * @exception StandardException Standard exception policy.
9233     **/

9234    protected final void create_SYSIBM_procedures(
9235    TransactionController tc)
9236        throws StandardException
9237    {
9238        /*
9239        ** SYSIBM routines.
9240        */

9241
9242        // used to put procedure into the SYSIBM schema
9243
UUID sysIBMUUID = getSysIBMSchemaDescriptor().getUUID();
9244
9245
9246        // SYSIBM.SQLCAMESSAGE(
9247
{
9248
9249            // procedure argument names
9250
String JavaDoc[] arg_names = {
9251                "SQLCODE",
9252                "SQLERRML",
9253                "SQLERRMC",
9254                "SQLERRP",
9255                "SQLERRD0",
9256                "SQLERRD1",
9257                "SQLERRD2",
9258                "SQLERRD3",
9259                "SQLERRD4",
9260                "SQLERRD5",
9261                "SQLWARN",
9262                "SQLSTATE",
9263                "FILE",
9264                "LOCALE",
9265                "MESSAGE",
9266                "RETURNCODE"};
9267
9268            // procedure argument types
9269
TypeDescriptor[] arg_types = {
9270                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9271                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9272                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9273                        Types.VARCHAR, Limits.DB2_JCC_MAX_EXCEPTION_PARAM_LENGTH),
9274                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 8),
9275                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9276                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9277                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9278                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9279                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9280                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER),
9281                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 11),
9282                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 5),
9283                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 50),
9284                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 5),
9285                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 2400),
9286                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER)
9287            };
9288
9289            createSystemProcedureOrFunction(
9290                "SQLCAMESSAGE",
9291                sysIBMUUID,
9292                arg_names,
9293                arg_types,
9294                2,
9295                0,
9296                RoutineAliasInfo.READS_SQL_DATA,
9297                (TypeDescriptor) null,
9298                tc);
9299        }
9300
9301        // SYSIBM.SQLPROCEDURES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9302
{
9303
9304            // procedure argument names
9305
String JavaDoc[] arg_names = {
9306                "CATALOGNAME",
9307                "SCHEMANAME",
9308                "PROCNAME",
9309                "OPTIONS"};
9310
9311            // procedure argument types
9312
TypeDescriptor[] arg_types = {
9313                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9314                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9315                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9316                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9317
9318            createSystemProcedureOrFunction(
9319                "SQLPROCEDURES",
9320                sysIBMUUID,
9321                arg_names,
9322                arg_types,
9323                0,
9324                1,
9325                RoutineAliasInfo.READS_SQL_DATA,
9326                (TypeDescriptor) null,
9327                tc);
9328        }
9329
9330        // SYSIBM.SQLTABLEPRIVILEGES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9331
{
9332
9333            // procedure argument names
9334
String JavaDoc[] arg_names = {
9335                "CATALOGNAME",
9336                "SCHEMANAME",
9337                "TABLENAME",
9338                "OPTIONS"};
9339
9340            // procedure argument types
9341
TypeDescriptor[] arg_types = {
9342                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9343                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9344                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9345                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9346
9347            createSystemProcedureOrFunction(
9348                "SQLTABLEPRIVILEGES",
9349                sysIBMUUID,
9350                arg_names,
9351                arg_types,
9352                0,
9353                1,
9354                RoutineAliasInfo.READS_SQL_DATA,
9355                (TypeDescriptor) null,
9356                tc);
9357        }
9358
9359        // SYSIBM.SQLPRIMARYKEYS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9360
{
9361
9362            // procedure argument names
9363
String JavaDoc[] arg_names = {
9364                "CATALOGNAME",
9365                "SCHEMANAME",
9366                "TABLENAME",
9367                "OPTIONS"};
9368
9369            // procedure argument types
9370
TypeDescriptor[] arg_types = {
9371                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9372                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9373                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9374                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9375
9376            createSystemProcedureOrFunction(
9377                "SQLPRIMARYKEYS",
9378                sysIBMUUID,
9379                arg_names,
9380                arg_types,
9381                0,
9382                1,
9383                RoutineAliasInfo.READS_SQL_DATA,
9384                (TypeDescriptor) null,
9385                tc);
9386        }
9387
9388        // SYSIBM.SQLTABLES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000), VARCHAR(4000))
9389
{
9390
9391            // procedure argument names
9392
String JavaDoc[] arg_names = {
9393                "CATALOGNAME",
9394                "SCHEMANAME",
9395                "TABLENAME",
9396                "TABLETYPE",
9397                "OPTIONS"};
9398
9399            // procedure argument types
9400
TypeDescriptor[] arg_types = {
9401                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9402                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9403                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9404                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000),
9405                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9406
9407            createSystemProcedureOrFunction(
9408                "SQLTABLES",
9409                sysIBMUUID,
9410                arg_names,
9411                arg_types,
9412                0,
9413                1,
9414                RoutineAliasInfo.READS_SQL_DATA,
9415                (TypeDescriptor) null,
9416                tc);
9417        }
9418
9419
9420        // SYSIBM.SQLPROCEDURECOLS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9421
{
9422
9423            // procedure argument names
9424
String JavaDoc[] arg_names = {
9425                "CATALOGNAME",
9426                "SCHEMANAME",
9427                "PROCNAME",
9428                "PARAMNAME",
9429                "OPTIONS"};
9430
9431            // procedure argument types
9432
TypeDescriptor[] arg_types = {
9433                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9434                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9435                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9436                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9437                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9438
9439            createSystemProcedureOrFunction(
9440                "SQLPROCEDURECOLS",
9441                sysIBMUUID,
9442                arg_names,
9443                arg_types,
9444                0,
9445                1,
9446                RoutineAliasInfo.READS_SQL_DATA,
9447                (TypeDescriptor) null,
9448                tc);
9449        }
9450
9451        // SYSIBM.SQLCOLUMNS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9452
{
9453
9454            // procedure argument names
9455
String JavaDoc[] arg_names = {
9456                "CATALOGNAME",
9457                "SCHEMANAME",
9458                "TABLENAME",
9459                "COLUMNNAME",
9460                "OPTIONS"};
9461
9462            // procedure argument types
9463
TypeDescriptor[] arg_types = {
9464                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9465                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9466                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9467                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9468                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9469
9470            createSystemProcedureOrFunction(
9471                "SQLCOLUMNS",
9472                sysIBMUUID,
9473                arg_names,
9474                arg_types,
9475                0,
9476                1,
9477                RoutineAliasInfo.READS_SQL_DATA,
9478                (TypeDescriptor) null,
9479                tc);
9480        }
9481
9482        // SYSIBM.SQLCOLPRIVILEGES(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9483
{
9484
9485            // procedure argument names
9486
String JavaDoc[] arg_names = {
9487                "CATALOGNAME",
9488                "SCHEMANAME",
9489                "TABLENAME",
9490                "COLUMNNAME",
9491                "OPTIONS"};
9492
9493            // procedure argument types
9494
TypeDescriptor[] arg_types = {
9495                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9496                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9497                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9498                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9499                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9500
9501            createSystemProcedureOrFunction(
9502                "SQLCOLPRIVILEGES",
9503                sysIBMUUID,
9504                arg_names,
9505                arg_types,
9506                0,
9507                1,
9508                RoutineAliasInfo.READS_SQL_DATA,
9509                (TypeDescriptor) null,
9510                tc);
9511        }
9512
9513        // SYSIBM.SQLUDTS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9514
{
9515
9516            // procedure argument names
9517
String JavaDoc[] arg_names = {
9518                "CATALOGNAME",
9519                "SCHEMAPATTERN",
9520                "TYPENAMEPATTERN",
9521                "UDTTYPES",
9522                "OPTIONS"};
9523
9524            // procedure argument types
9525
TypeDescriptor[] arg_types = {
9526                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9527                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9528                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9529                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9530                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9531
9532            createSystemProcedureOrFunction(
9533                "SQLUDTS",
9534                sysIBMUUID,
9535                arg_names,
9536                arg_types,
9537                0,
9538                1,
9539                RoutineAliasInfo.READS_SQL_DATA,
9540                (TypeDescriptor) null,
9541                tc);
9542        }
9543
9544        // SYSIBM.SQLFOREIGNKEYS(VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(128),
9545
// VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9546
{
9547
9548            // procedure argument names
9549
String JavaDoc[] arg_names = {
9550                "PKCATALOGNAME",
9551                "PKSCHEMANAME",
9552                "PKTABLENAME",
9553                "FKCATALOGNAME",
9554                "FKSCHEMANAME",
9555                "FKTABLENAME",
9556                "OPTIONS"};
9557
9558            // procedure argument types
9559
TypeDescriptor[] arg_types = {
9560                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9561                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9562                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9563                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9564                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9565                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9566                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9567
9568            createSystemProcedureOrFunction(
9569                "SQLFOREIGNKEYS",
9570                sysIBMUUID,
9571                arg_names,
9572                arg_types,
9573                0,
9574                1,
9575                RoutineAliasInfo.READS_SQL_DATA,
9576                (TypeDescriptor) null,
9577                tc);
9578        }
9579
9580        // SYSIBM.SQLSPECIALCOLUMNS(SMALLINT, VARCHAR(128), VARCHAR(128), VARCHAR(128),
9581
// SMALLINT, SMALLINT, VARCHAR(4000))
9582
{
9583
9584            // procedure argument names
9585
String JavaDoc[] arg_names = {
9586                "COLTYPE",
9587                "CATALOGNAME",
9588                "SCHEMANAME",
9589                "TABLENAME",
9590                "SCOPE",
9591                "NULLABLE",
9592                "OPTIONS"};
9593
9594            // procedure argument types
9595
TypeDescriptor[] arg_types = {
9596                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9597                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9598                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9599                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9600                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9601                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9602                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9603
9604            createSystemProcedureOrFunction(
9605                "SQLSPECIALCOLUMNS",
9606                sysIBMUUID,
9607                arg_names,
9608                arg_types,
9609                0,
9610                1,
9611                RoutineAliasInfo.READS_SQL_DATA,
9612                (TypeDescriptor) null,
9613                tc);
9614        }
9615
9616        // SYSIBM.SQLGETTYPEINFO(SMALLINT, VARCHAR(4000))
9617
{
9618
9619            // procedure argument names
9620
String JavaDoc[] arg_names = {
9621                "DATATYPE",
9622                "OPTIONS"};
9623
9624            // procedure argument types
9625
TypeDescriptor[] arg_types = {
9626                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9627                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9628
9629            createSystemProcedureOrFunction(
9630                "SQLGETTYPEINFO",
9631                sysIBMUUID,
9632                arg_names,
9633                arg_types,
9634                0,
9635                1,
9636                RoutineAliasInfo.READS_SQL_DATA,
9637                (TypeDescriptor) null,
9638                tc);
9639        }
9640
9641        // SYSIBM.SQLSTATISTICS(VARCHAR(128), VARCHAR(128), VARCHAR(128),
9642
// SMALLINT, SMALLINT, VARCHAR(4000))
9643
{
9644
9645            // procedure argument names
9646
String JavaDoc[] arg_names = {
9647                "CATALOGNAME",
9648                "SCHEMANAME",
9649                "TABLENAME",
9650                "UNIQUE",
9651                "RESERVED",
9652                "OPTIONS"};
9653
9654            // procedure argument types
9655
TypeDescriptor[] arg_types = {
9656                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9657                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9658                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9659                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9660                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT),
9661                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9662
9663            createSystemProcedureOrFunction(
9664                "SQLSTATISTICS",
9665                sysIBMUUID,
9666                arg_names,
9667                arg_types,
9668                0,
9669                1,
9670                RoutineAliasInfo.READS_SQL_DATA,
9671                (TypeDescriptor) null,
9672                tc);
9673        }
9674
9675        // void SYSIBM.METADATA()
9676
{
9677            createSystemProcedureOrFunction(
9678                "METADATA",
9679                sysIBMUUID,
9680                null,
9681                null,
9682                0,
9683                1,
9684                RoutineAliasInfo.READS_SQL_DATA,
9685                (TypeDescriptor) null,
9686                tc);
9687        }
9688
9689    }
9690    
9691    /**
9692     * Grant PUBLIC access to specific system routines. Currently, this is
9693     * done for some routines in SYSCS_UTIL schema.
9694     *
9695     * @param tc TransactionController to use
9696     * @param authorizationID authorization ID of the permission grantor
9697     * @throws StandardException Standard exception policy.
9698     */

9699    public void grantPublicAccessToSystemRoutines(TransactionController tc,
9700                            String JavaDoc authorizationID) throws StandardException {
9701        
9702        // Get schema ID for SYSCS_UTIL schema
9703
String JavaDoc schemaID = getSystemUtilSchemaDescriptor().getUUID().toString();
9704        
9705        for(int i=0; i < sysUtilProceduresWithPublicAccess.length; i++) {
9706            grantPublicAccessToSystemRoutine(schemaID,
9707                    sysUtilProceduresWithPublicAccess[i],
9708                                AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR,
9709                                tc, authorizationID);
9710        }
9711        
9712        for(int i=0; i < sysUtilFunctionsWithPublicAccess.length; i++) {
9713            grantPublicAccessToSystemRoutine(schemaID,
9714                    sysUtilFunctionsWithPublicAccess[i],
9715                                AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR,
9716                                tc, authorizationID);
9717        }
9718    }
9719    
9720    
9721    /**
9722     * Grant PUBLIC access to a system routine. This method should be used only
9723     * for granting access to a system routine (other than routines in SYSFUN
9724     * schema). It expects the routine to be present in SYSALIASES catalog.
9725     *
9726     * @param schemaID Schema ID
9727     * @param routineName Routine Name
9728     * @param nameSpace Indicates whether the routine is a function/procedure.
9729     * @param tc TransactionController to use
9730     * @param authorizationID authorization ID of the permission grantor
9731     * @throws StandardException Standard exception policy.
9732     */

9733    private void grantPublicAccessToSystemRoutine(String JavaDoc schemaID,
9734                                            String JavaDoc routineName,
9735                                            char nameSpace,
9736                                            TransactionController tc,
9737                                            String JavaDoc authorizationID)
9738                                            throws StandardException {
9739        // For system routines, a valid alias descriptor will be returned.
9740
AliasDescriptor ad = getAliasDescriptor(schemaID, routineName,
9741                                                nameSpace);
9742        
9743        if (SanityManager.DEBUG) {
9744            SanityManager.ASSERT((ad != null), "Failed to get AliasDescriptor"
9745                                            + " of the routine");
9746        }
9747        
9748        UUID routineUUID = ad.getUUID();
9749        createRoutinePermPublicDescriptor(routineUUID, tc, authorizationID);
9750    }
9751    
9752
9753    /**
9754     * Create RoutinePermDescriptor to grant access to PUBLIC for
9755     * this system routine. Currently only SYSUTIL routines need access
9756     * granted to execute them when a database is created/upgraded.
9757     *
9758     * @param routineUUID uuid of the routine
9759     * @param tc TransactionController to use
9760     *
9761     * @exception StandardException Standard exception policy.
9762     */

9763    void createRoutinePermPublicDescriptor(
9764    UUID routineUUID,
9765    TransactionController tc) throws StandardException
9766    {
9767        createRoutinePermPublicDescriptor(routineUUID, tc, authorizationDatabaseOwner);
9768    }
9769
9770    /**
9771     * Create RoutinePermDescriptor to grant access to PUBLIC for
9772     * this system routine using the grantor specified in authorizationID.
9773     *
9774     * @param routineUUID uuid of the routine
9775     * @param tc TransactionController to use
9776     * @param authorizationID authorization ID of the permission grantor
9777     * @throws StandardException Standard exception policy.
9778     */

9779    void createRoutinePermPublicDescriptor(
9780    UUID routineUUID,
9781    TransactionController tc,
9782    String JavaDoc authorizationID) throws StandardException
9783    {
9784        RoutinePermsDescriptor routinePermDesc =
9785            new RoutinePermsDescriptor(
9786                this,
9787                "PUBLIC",
9788                authorizationID,
9789                routineUUID);
9790
9791        addDescriptor(
9792            routinePermDesc, null, DataDictionary.SYSROUTINEPERMS_CATALOG_NUM, false, tc);
9793    }
9794
9795    /**
9796     * Create system procedures added in version 10.1.
9797     * <p>
9798     * Create 10.1 system procedures, called by either code creating new
9799     * database, or code doing hard upgrade from previous version.
9800     * <p>
9801     *
9802     * @param sysUtilUUID uuid of the SYSUTIL schema.
9803     *
9804     * @exception StandardException Standard exception policy.
9805     **/

9806    void create_10_1_system_procedures(
9807    TransactionController tc,
9808    UUID sysUtilUUID)
9809        throws StandardException
9810    {
9811
9812        UUID routine_uuid = null;
9813
9814        // void SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(
9815
// IN SCHEMANAME VARCHAR(128),
9816
// IN TABLENAME VARCHAR(128),
9817
// IN PURGE_ROWS SMALLINT,
9818
// IN DEFRAGMENT_ROWS SMALLINT,
9819
// IN TRUNCATE_END SMALLINT
9820
// )
9821
{
9822            // procedure argument names
9823
String JavaDoc[] arg_names = {
9824                "SCHEMANAME",
9825                "TABLENAME",
9826                "PURGE_ROWS",
9827                "DEFRAGMENT_ROWS",
9828                "TRUNCATE_END"};
9829
9830            // procedure argument types
9831
TypeDescriptor[] arg_types = {
9832                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9833                    Types.VARCHAR, 128),
9834                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9835                    Types.VARCHAR, 128),
9836                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9837                    Types.SMALLINT),
9838                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9839                    Types.SMALLINT),
9840                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9841                    Types.SMALLINT)
9842            };
9843
9844            routine_uuid = createSystemProcedureOrFunction(
9845                "SYSCS_INPLACE_COMPRESS_TABLE",
9846                sysUtilUUID,
9847                arg_names,
9848                arg_types,
9849                0,
9850                0,
9851                RoutineAliasInfo.MODIFIES_SQL_DATA,
9852                (TypeDescriptor) null,
9853                tc);
9854
9855            createRoutinePermPublicDescriptor(routine_uuid, tc);
9856        }
9857    }
9858
9859    
9860    /**
9861     * Create system procedures added in version 10.2.
9862     * <p>
9863     * Create 10.2 system procedures, called by either code creating new
9864     * database, or code doing hard upgrade from previous version.
9865     * <p>
9866     *
9867     * @param sysUtilUUID uuid of the SYSUTIL schema.
9868     *
9869     * @exception StandardException Standard exception policy.
9870     **/

9871    void create_10_2_system_procedures(
9872    TransactionController tc,
9873    UUID sysUtilUUID)
9874        throws StandardException
9875    {
9876
9877        // void SYSCS_UTIL.SYSCS_BACKUP_DATABASE_NOWAIT(
9878
// IN BACKUPDIR VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH)
9879
// )
9880

9881        {
9882            // procedure argument names
9883
String JavaDoc[] arg_names = {"BACKUPDIR"};
9884
9885            // procedure argument types
9886
TypeDescriptor[] arg_types = {
9887                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9888                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH)
9889            };
9890
9891            createSystemProcedureOrFunction(
9892                "SYSCS_BACKUP_DATABASE_NOWAIT",
9893                sysUtilUUID,
9894                arg_names,
9895                arg_types,
9896                0,
9897                0,
9898                RoutineAliasInfo.MODIFIES_SQL_DATA,
9899                (TypeDescriptor) null,
9900                tc);
9901        }
9902
9903        // void
9904
// SYSCS_UTIL.SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE_NOWAIT(
9905
// IN BACKUPDIR VARCHAR(Limits.DB2_VARCHAR_MAXWIDTH),
9906
// IN DELETE_ARCHIVED_LOG_FILES SMALLINT
9907
// )
9908
{
9909            // procedure argument names
9910
String JavaDoc[] arg_names =
9911                {"BACKUPDIR", "DELETE_ARCHIVED_LOG_FILES"};
9912
9913            // procedure argument types
9914
TypeDescriptor[] arg_types = {
9915                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9916                    Types.VARCHAR, Limits.DB2_VARCHAR_MAXWIDTH),
9917                DataTypeDescriptor.getBuiltInDataTypeDescriptor(
9918                    Types.SMALLINT)
9919            };
9920
9921            createSystemProcedureOrFunction(
9922                "SYSCS_BACKUP_DATABASE_AND_ENABLE_LOG_ARCHIVE_MODE_NOWAIT",
9923                sysUtilUUID,
9924                arg_names,
9925                arg_types,
9926                0,
9927                0,
9928                RoutineAliasInfo.MODIFIES_SQL_DATA,
9929                (TypeDescriptor) null,
9930                tc);
9931        }
9932
9933        // SYSIBM.SQLFUNCTIONS(VARCHAR(128), VARCHAR(128), VARCHAR(128),
9934
// VARCHAR(4000))
9935
{
9936
9937            // procedure argument names
9938
String JavaDoc[] arg_names = {
9939                "CATALOGNAME",
9940                "SCHEMANAME",
9941                "FUNCNAME",
9942                "OPTIONS"};
9943
9944            // procedure argument types
9945
TypeDescriptor[] arg_types = {
9946                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9947                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9948                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9949                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9950
9951            createSystemProcedureOrFunction(
9952                "SQLFUNCTIONS",
9953                getSysIBMSchemaDescriptor().getUUID(),
9954                arg_names,
9955                arg_types,
9956                0,
9957                1,
9958                RoutineAliasInfo.READS_SQL_DATA,
9959                (TypeDescriptor) null,
9960                tc);
9961        }
9962
9963        // SYSIBM.SQLFUNCTIONPARAMS(VARCHAR(128), VARCHAR(128),
9964
// VARCHAR(128), VARCHAR(128), VARCHAR(4000))
9965
{
9966
9967            // procedure argument names
9968
String JavaDoc[] arg_names = {
9969                "CATALOGNAME",
9970                "SCHEMANAME",
9971                "FUNCNAME",
9972                "PARAMNAME",
9973                "OPTIONS"};
9974
9975            // procedure argument types
9976
TypeDescriptor[] arg_types = {
9977                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9978                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9979                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9980                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 128),
9981                DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, 4000)};
9982
9983            createSystemProcedureOrFunction(
9984                "SQLFUNCTIONPARAMS",
9985                getSysIBMSchemaDescriptor().getUUID(),
9986                arg_names,
9987                arg_types,
9988                0,
9989                1,
9990                RoutineAliasInfo.READS_SQL_DATA,
9991                (TypeDescriptor) null,
9992                tc);
9993        }
9994    }
9995
9996
9997    /*
9998    ** Priv block code to load net work server meta data queries.
9999    */

0000
0001    private String JavaDoc spsSet;
0002    private final synchronized Properties JavaDoc getQueryDescriptions(boolean net) {
0003        spsSet = net ? "metadata_net.properties" : "/org/apache/derby/impl/jdbc/metadata.properties";
0004        return (Properties JavaDoc) java.security.AccessController.doPrivileged(this);
0005    }
0006
0007    public final Object JavaDoc run() {
0008        // SECURITY PERMISSION - IP3
0009
Properties JavaDoc p = new Properties JavaDoc();
0010        try {
0011
0012            // SECURITY PERMISSION - IP3
0013
InputStream JavaDoc is = getClass().getResourceAsStream(spsSet);
0014            p.load(is);
0015            is.close();
0016        } catch (IOException JavaDoc ioe) {}
0017        return p;
0018    }
0019
0020
0021    private static List newSList() {
0022        return java.util.Collections.synchronizedList(new java.util.LinkedList JavaDoc());
0023    }
0024
0025    /**
0026     * Get one user's privileges on a table
0027     *
0028     * @param tableUUID
0029     * @param authorizationId The user name
0030     *
0031     * @return a TablePermsDescriptor or null if the user has no permissions on the table.
0032     *
0033     * @exception StandardException
0034     */

0035    public TablePermsDescriptor getTablePermissions( UUID tableUUID, String JavaDoc authorizationId)
0036        throws StandardException
0037    {
0038        TablePermsDescriptor key = new TablePermsDescriptor( this, authorizationId, (String JavaDoc) null, tableUUID);
0039        return (TablePermsDescriptor) getPermissions( key);
0040    } // end of getTablePermissions
0041

0042    /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getTablePermissions */
0043    public TablePermsDescriptor getTablePermissions( UUID tablePermsUUID)
0044    throws StandardException
0045    {
0046        TablePermsDescriptor key = new TablePermsDescriptor( this, tablePermsUUID);
0047        return getUncachedTablePermsDescriptor( key );
0048    }
0049
0050    private Object JavaDoc getPermissions( PermissionsDescriptor key) throws StandardException
0051    {
0052        // RESOLVE get a READ COMMITTED (shared) lock on the permission row
0053
Cacheable entry = getPermissionsCache().find( key);
0054        if( entry == null)
0055            return null;
0056        Object JavaDoc perms = entry.getIdentity();
0057        getPermissionsCache().release( entry);
0058        return perms;
0059    }
0060
0061    /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getColumnPermissions */
0062    public ColPermsDescriptor getColumnPermissions( UUID colPermsUUID)
0063    throws StandardException
0064    {
0065        ColPermsDescriptor key = new ColPermsDescriptor( this, colPermsUUID);
0066        return getUncachedColPermsDescriptor( key );
0067    }
0068
0069    /**
0070     * Get one user's column privileges for a table.
0071     *
0072     * @param tableUUID
0073     * @param privType (as int) Authorizer.SELECT_PRIV, Authorizer.UPDATE_PRIV, or Authorizer.REFERENCES_PRIV
0074     * @param forGrant
0075     * @param authorizationId The user name
0076     *
0077     * @return a ColPermsDescriptor or null if the user has no separate column
0078     * permissions of the specified type on the table. Note that the user may have been granted
0079     * permission on all the columns of the table (no column list), in which case this routine
0080     * will return null. You must also call getTablePermissions to see if the user has permission
0081     * on a set of columns.
0082     *
0083     * @exception StandardException
0084     */

0085    public ColPermsDescriptor getColumnPermissions( UUID tableUUID,
0086                                                    int privType,
0087                                                    boolean forGrant,
0088                                                    String JavaDoc authorizationId)
0089        throws StandardException
0090    {
0091        String JavaDoc privTypeStr = forGrant ? colPrivTypeMapForGrant[privType] : colPrivTypeMap[privType];
0092        if( SanityManager.DEBUG)
0093            SanityManager.ASSERT( privTypeStr != null,
0094                                  "Invalid column privilege type: " + privType);
0095        ColPermsDescriptor key = new ColPermsDescriptor( this,
0096                                                         authorizationId,
0097                                                         (String JavaDoc) null,
0098                                                         tableUUID,
0099                                                         privTypeStr);
0100        return (ColPermsDescriptor) getPermissions( key);
0101    } // end of getColumnPermissions
0102

0103    /**
0104     * Get one user's column privileges for a table. This routine gets called
0105     * during revoke privilege processing
0106     *
0107     * @param tableUUID
0108     * @param privTypeStr (as String) Authorizer.SELECT_PRIV, Authorizer.UPDATE_PRIV, or Authorizer.REFERENCES_PRIV
0109     * @param forGrant
0110     * @param authorizationId The user name
0111     *
0112     * @return a ColPermsDescriptor or null if the user has no separate column
0113     * permissions of the specified type on the table. Note that the user may have been granted
0114     * permission on all the columns of the table (no column list), in which case this routine
0115     * will return null. You must also call getTablePermissions to see if the user has permission
0116     * on a set of columns.
0117     *
0118     * @exception StandardException
0119     */

0120    public ColPermsDescriptor getColumnPermissions( UUID tableUUID,
0121            String JavaDoc privTypeStr,
0122            boolean forGrant,
0123            String JavaDoc authorizationId)
0124    throws StandardException
0125    {
0126        ColPermsDescriptor key = new ColPermsDescriptor( this,
0127                                                         authorizationId,
0128                                                         (String JavaDoc) null,
0129                                                         tableUUID,
0130                                                         privTypeStr);
0131        return (ColPermsDescriptor) getPermissions( key);
0132        
0133    }
0134
0135    private static final String JavaDoc[] colPrivTypeMap;
0136    private static final String JavaDoc[] colPrivTypeMapForGrant;
0137    static {
0138        colPrivTypeMap = new String JavaDoc[ Authorizer.PRIV_TYPE_COUNT];
0139        colPrivTypeMapForGrant = new String JavaDoc[ Authorizer.PRIV_TYPE_COUNT];
0140        colPrivTypeMap[ Authorizer.SELECT_PRIV] = "s";
0141        colPrivTypeMapForGrant[ Authorizer.SELECT_PRIV] = "S";
0142        colPrivTypeMap[ Authorizer.UPDATE_PRIV] = "u";
0143        colPrivTypeMapForGrant[ Authorizer.UPDATE_PRIV] = "U";
0144        colPrivTypeMap[ Authorizer.REFERENCES_PRIV] = "r";
0145        colPrivTypeMapForGrant[ Authorizer.REFERENCES_PRIV] = "R";
0146    }
0147
0148    /**
0149     * Get one user's permissions for a routine (function or procedure).
0150     *
0151     * @param routineUUID
0152     * @param authorizationId The user's name
0153     *
0154     * @return The descriptor of the users permissions for the routine.
0155     *
0156     * @exception StandardException
0157     */

0158    public RoutinePermsDescriptor getRoutinePermissions( UUID routineUUID, String JavaDoc authorizationId)
0159        throws StandardException
0160    {
0161        RoutinePermsDescriptor key = new RoutinePermsDescriptor( this, authorizationId, (String JavaDoc) null, routineUUID);
0162
0163        return (RoutinePermsDescriptor) getPermissions( key);
0164    } // end of getRoutinePermissions
0165

0166    /* @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getRoutinePermissions */
0167    public RoutinePermsDescriptor getRoutinePermissions( UUID routinePermsUUID)
0168    throws StandardException
0169    {
0170        RoutinePermsDescriptor key = new RoutinePermsDescriptor( this, routinePermsUUID);
0171        return getUncachedRoutinePermsDescriptor( key );
0172    }
0173
0174    /**
0175     * Add or remove a permission to/from the permission database.
0176     *
0177     * @param add if true then the permission is added, if false the permission is removed
0178     * @param perm
0179     * @param grantee
0180     * @param tc
0181     *
0182     * @return True means revoke has removed a privilege from system
0183     * table and hence the caller of this method should send invalidation
0184     * actions to PermssionDescriptor's dependents.
0185     */

0186    public boolean addRemovePermissionsDescriptor( boolean add,
0187                                                PermissionsDescriptor perm,
0188                                                String JavaDoc grantee,
0189                                                TransactionController tc)
0190        throws StandardException
0191    {
0192        int catalogNumber = perm.getCatalogNumber();
0193
0194        // It is possible for grant statements to look like following
0195
// grant execute on function f_abs to mamata2, mamata3;
0196
// grant all privileges on t11 to mamata2, mamata3;
0197
// This means that dd.addRemovePermissionsDescriptor will be called
0198
// twice for TablePermsDescriptor and twice for RoutinePermsDescriptor,
0199
// once for each grantee.
0200
// First it's called for mamta2. When a row is inserted for mamta2
0201
// into the correct system table for the permission descriptor, the
0202
// permission descriptor's uuid gets populated with the uuid of
0203
// the row that just got inserted into the system table for mamta2
0204
// Now, when dd.addRemovePermissionsDescriptor gets called again for
0205
// mamta3, the permission descriptor's uuid will still be set to
0206
// the uuid that was used for mamta2. If we do not reset the
0207
// uuid to null, we will think that there is a duplicate row getting
0208
// inserted for the same uuid. In order to get around this, we should
0209
// reset the UUID of passed PermissionDescriptor everytime this method
0210
// is called. This way, there will be no leftover values from previous
0211
// call of this method.
0212
perm.setUUID(null);
0213        perm.setGrantee( grantee);
0214        TabInfoImpl ti = getNonCoreTI( catalogNumber);
0215        PermissionsCatalogRowFactory rf = (PermissionsCatalogRowFactory) ti.getCatalogRowFactory();
0216        int primaryIndexNumber = rf.getPrimaryKeyIndexNumber();
0217        ConglomerateController heapCC = tc.openConglomerate( ti.getHeapConglomerate(),
0218                                                             false, // do not keep open across commits
0219
0,
0220                                                             TransactionController.MODE_RECORD,
0221                                                             TransactionController.ISOLATION_REPEATABLE_READ);
0222        RowLocation rl = null;
0223        try
0224        {
0225            rl = heapCC.newRowLocationTemplate();
0226        }
0227        finally
0228        {
0229            heapCC.close();
0230            heapCC = null;
0231        }
0232        ExecIndexRow key = rf.buildIndexKeyRow( primaryIndexNumber, perm);
0233        ExecRow existingRow = ti.getRow( tc, key, primaryIndexNumber);
0234        if( existingRow == null)
0235        {
0236            if( ! add)
0237                //we didn't find an entry in system catalog and this is revoke
0238
//so that means there is nothing to revoke. Simply return.
0239
//No need to reset permission descriptor's uuid because
0240
//no row was ever found in system catalog for the given
0241
//permission and hence uuid can't be non-null
0242
return false;
0243            //We didn't find an entry in system catalog and this is grant so
0244
//so that means we have to enter a new row in system catalog for
0245
//this grant.
0246
ExecRow row = ti.getCatalogRowFactory().makeRow( perm, (TupleDescriptor) null);
0247            int insertRetCode = ti.insertRow(row, tc, true /* wait */);
0248            if( SanityManager.DEBUG)
0249                SanityManager.ASSERT( insertRetCode == TabInfoImpl.ROWNOTDUPLICATE,
0250                                      "Race condition in inserting table privilege.");
0251        }
0252        else
0253        {
0254            // add/remove these permissions to/from the existing permissions
0255
boolean[] colsChanged = new boolean[ existingRow.nColumns()];
0256            boolean[] indicesToUpdate = new boolean[ rf.getNumIndexes()];
0257            int changedColCount = 0;
0258            if( add)
0259                changedColCount = rf.orPermissions( existingRow, perm, colsChanged);
0260            else
0261                changedColCount = rf.removePermissions( existingRow, perm, colsChanged);
0262            if( changedColCount == 0)
0263            {
0264                //grant/revoke privilege didn't change anything and hence
0265
//just return
0266
return false;
0267            }
0268            if (!add)
0269            {
0270                //set the uuid of the passed permission descriptor to
0271
//corresponding rows's uuid in permissions system table. The
0272
//permission descriptor's uuid is required to have the
0273
//dependency manager send the revoke privilege action to
0274
//all the dependent objects on that permission descriptor.
0275
rf.setUUIDOfThePassedDescriptor(existingRow, perm);
0276            }
0277            if( changedColCount < 0)
0278            {
0279                // No permissions left in the current row
0280
ti.deleteRow( tc, key, primaryIndexNumber);
0281            }
0282            else if( changedColCount > 0)
0283            {
0284                int[] colsToUpdate = new int[changedColCount];
0285                changedColCount = 0;
0286                for( int i = 0; i < colsChanged.length; i++)
0287                {
0288                    if( colsChanged[i])
0289                        colsToUpdate[ changedColCount++] = i + 1;
0290                }
0291                if( SanityManager.DEBUG)
0292                    SanityManager.ASSERT(
0293                        changedColCount == colsToUpdate.length,
0294                        "return value of " + rf.getClass().getName() +
0295                        ".orPermissions does not match the number of booleans it set in colsChanged.");
0296                ti.updateRow( key, existingRow, primaryIndexNumber, indicesToUpdate, colsToUpdate, tc, true /* wait */);
0297            }
0298        }
0299        // Remove cached permissions data. The cache may hold permissions data for this key even if
0300
// the row in the permissions table is new. In that case the cache may have an entry indicating no
0301
// permissions
0302
removePermEntryInCache(perm);
0303
0304        //If we are dealing with grant, then the caller does not need to send
0305
//any invalidation actions to anyone and hence return false
0306
if (add)
0307            return false;
0308        return true;
0309    } // end of addPermissionsDescriptor
0310

0311    /**
0312     * Get a table permissions descriptor from the system tables, without going through the cache.
0313     * This method is called to fill the permissions cache.
0314     *
0315     * @return a TablePermsDescriptor that describes the table permissions granted to the grantee, null
0316     * if no table-level permissions have been granted to him on the table.
0317     *
0318     * @exception StandardException
0319     */

0320    TablePermsDescriptor getUncachedTablePermsDescriptor( TablePermsDescriptor key)
0321        throws StandardException
0322    {
0323        if (key.getObjectID() == null)
0324        {
0325            //the TABLEPERMSID for SYSTABLEPERMS is not known, so use
0326
//table id, grantor and granteee to find TablePermsDescriptor
0327
return (TablePermsDescriptor)
0328              getUncachedPermissionsDescriptor( SYSTABLEPERMS_CATALOG_NUM,
0329                                                SYSTABLEPERMSRowFactory.GRANTEE_TABLE_GRANTOR_INDEX_NUM,
0330                                                key);
0331        } else
0332        {
0333            //we know the TABLEPERMSID for SYSTABLEPERMS, so use that to
0334
//find TablePermsDescriptor from the sytem table
0335
return (TablePermsDescriptor)
0336            getUncachedPermissionsDescriptor(SYSTABLEPERMS_CATALOG_NUM,
0337                    SYSTABLEPERMSRowFactory.TABLEPERMSID_INDEX_NUM,key);
0338        }
0339    } // end of getUncachedTablePermsDescriptor
0340

0341
0342    /**
0343     * Get a column permissions descriptor from the system tables, without going through the cache.
0344     * This method is called to fill the permissions cache.
0345     *
0346     *
0347     * @return a ColPermsDescriptor that describes the column permissions granted to the grantee, null
0348     * if no column permissions have been granted to him on the table.
0349     *
0350     * @exception StandardException
0351     */

0352    ColPermsDescriptor getUncachedColPermsDescriptor( ColPermsDescriptor key)
0353        throws StandardException
0354    {
0355        if (key.getObjectID() == null)
0356        {
0357            //the COLPERMSID for SYSCOLPERMS is not known, so use tableid,
0358
//privilege type, grantor and granteee to find ColPermsDescriptor
0359
return (ColPermsDescriptor)
0360              getUncachedPermissionsDescriptor( SYSCOLPERMS_CATALOG_NUM,
0361                                                SYSCOLPERMSRowFactory.GRANTEE_TABLE_TYPE_GRANTOR_INDEX_NUM,
0362                                                key);
0363        }else
0364        {
0365            //we know the COLPERMSID for SYSCOLPERMS, so use that to
0366
//find ColPermsDescriptor from the sytem table
0367
return (ColPermsDescriptor)
0368              getUncachedPermissionsDescriptor( SYSCOLPERMS_CATALOG_NUM,
0369                                                SYSCOLPERMSRowFactory.COLPERMSID_INDEX_NUM,
0370                                                key);
0371        }
0372    } // end of getUncachedColPermsDescriptor
0373

0374    private TupleDescriptor getUncachedPermissionsDescriptor( int catalogNumber,
0375                                                              int indexNumber,
0376                                                              PermissionsDescriptor key)
0377        throws StandardException
0378    {
0379        TabInfoImpl ti = getNonCoreTI( catalogNumber);
0380        PermissionsCatalogRowFactory rowFactory = (PermissionsCatalogRowFactory) ti.getCatalogRowFactory();
0381        ExecIndexRow keyRow = rowFactory.buildIndexKeyRow( indexNumber, key);
0382        return
0383          getDescriptorViaIndex( indexNumber,
0384                                 keyRow,
0385                                 (ScanQualifier [][]) null,
0386                                 ti,
0387                                 (TupleDescriptor) null,
0388                                 (List) null,
0389                                 false);
0390    } // end of getUncachedPermissionsDescriptor
0391

0392    /**
0393     * Get a routine permissions descriptor from the system tables, without going through the cache.
0394     * This method is called to fill the permissions cache.
0395     *
0396     * @return a RoutinePermsDescriptor that describes the table permissions granted to the grantee, null
0397     * if no table-level permissions have been granted to him on the table.
0398     *
0399     * @exception StandardException
0400     */

0401    RoutinePermsDescriptor getUncachedRoutinePermsDescriptor( RoutinePermsDescriptor key)
0402        throws StandardException
0403    {
0404        if (key.getObjectID() == null)
0405        {
0406            //the ROUTINEPERMSID for SYSROUTINEPERMS is not known, so use aliasid,
0407
//grantor and granteee to find RoutinePermsDescriptor
0408
return (RoutinePermsDescriptor)
0409            getUncachedPermissionsDescriptor( SYSROUTINEPERMS_CATALOG_NUM,
0410                    SYSROUTINEPERMSRowFactory.GRANTEE_ALIAS_GRANTOR_INDEX_NUM,
0411                                              key);
0412        } else
0413        {
0414            //we know the ROUTINEPERMSID for SYSROUTINEPERMS, so use that to
0415
//find RoutinePermsDescriptor from the sytem table
0416
return (RoutinePermsDescriptor)
0417            getUncachedPermissionsDescriptor(SYSROUTINEPERMS_CATALOG_NUM,
0418                    SYSROUTINEPERMSRowFactory.ROUTINEPERMSID_INDEX_NUM,key);
0419
0420        }
0421    } // end of getUncachedRoutinePermsDescriptor
0422

0423    private String JavaDoc[][] DIAG_VTI_CLASSES =
0424    {
0425            {"LOCK_TABLE", "org.apache.derby.diag.LockTable"},
0426            {"STATEMENT_CACHE", "org.apache.derby.diag.StatementCache"},
0427            {"TRANSACTION_TABLE", "org.apache.derby.diag.TransactionTable"},
0428            {"ERROR_MESSAGES", "org.apache.derby.diag.ErrorMessages"},
0429            
0430            
0431    };
0432    
0433    /**
0434     * @see org.apache.derby.iapi.sql.dictionary.DataDictionary#getVTIClass(org.apache.derby.iapi.sql.dictionary.TableDescriptor)
0435     */

0436    public String JavaDoc getVTIClass(TableDescriptor td) throws StandardException {
0437        
0438        if (SanityManager.DEBUG)
0439        {
0440            if (td.getTableType() != TableDescriptor.VTI_TYPE)
0441                SanityManager.THROWASSERT("getVTIClass: Invalid table type " + td);
0442        }
0443        
0444        for (int i = 0; i < DIAG_VTI_CLASSES.length; i++)
0445        {
0446            String JavaDoc[] entry = DIAG_VTI_CLASSES[i];
0447            if (entry[0].equals(td.getDescriptorName()))
0448                return entry[1];
0449        }
0450        
0451        return null;
0452    }
0453}
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
Popular Tags