KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.catalog.SYSCOLUMNSRowFactory
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.Property;
25
26 import org.apache.derby.iapi.types.DataTypeDescriptor;
27 import org.apache.derby.iapi.types.TypeId;
28 import org.apache.derby.iapi.types.DataValueDescriptor;
29
30 import org.apache.derby.iapi.store.raw.RawStoreFactory;
31
32 import org.apache.derby.iapi.types.DataValueFactory;
33 import org.apache.derby.iapi.sql.dictionary.SystemColumn;
34 import org.apache.derby.catalog.TypeDescriptor;
35 import org.apache.derby.catalog.types.BaseTypeIdImpl;
36
37 import org.apache.derby.iapi.types.DataValueDescriptor;
38
39 import org.apache.derby.iapi.types.TypeId;
40 import org.apache.derby.iapi.types.DataTypeDescriptor;
41 import org.apache.derby.iapi.types.DataValueFactory;
42 import org.apache.derby.iapi.types.RowLocation;
43
44 import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
45 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
46 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
47 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
48 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
49 import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
50 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
51 import org.apache.derby.iapi.sql.dictionary.UniqueTupleDescriptor;
52
53 import org.apache.derby.iapi.sql.execute.ExecutionContext;
54 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
55 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
56 import org.apache.derby.iapi.sql.execute.ExecRow;
57
58 import org.apache.derby.iapi.error.StandardException;
59
60 import org.apache.derby.iapi.services.sanity.SanityManager;
61
62 import org.apache.derby.iapi.services.monitor.Monitor;
63 import org.apache.derby.catalog.types.TypeDescriptorImpl;
64 import org.apache.derby.catalog.DefaultInfo;
65 import org.apache.derby.iapi.services.uuid.UUIDFactory;
66 import org.apache.derby.catalog.UUID;
67
68 import org.apache.derby.impl.sql.compile.ColumnDefinitionNode;
69
70 import org.apache.derby.catalog.types.DefaultInfoImpl;
71
72 import org.apache.derby.iapi.types.*;
73
74 import java.io.Serializable JavaDoc;
75
76 import java.util.Properties JavaDoc;
77
78 /**
79  * Factory for creating a SYSCOLUMNS row.
80  *
81  *
82  * @version 0.1
83  * @author Rick Hillegas (extracted from DataDictionaryImpl).
84  */

85
86 public class SYSCOLUMNSRowFactory extends CatalogRowFactory
87 {
88     static final String JavaDoc TABLENAME_STRING = "SYSCOLUMNS";
89
90     /**
91      * Old name for REFERENCEID, used by upgrade
92      */

93     public static final String JavaDoc OLD_REFERENCEID_NAME = "TABLEID";
94
95     protected static final int SYSCOLUMNS_COLUMN_COUNT = 9;
96     /* Column #s for syscolumns (1 based) */
97
98     //TABLEID is an obsolete name, it is better to use
99
//REFERENCEID, but to make life easier you can use either
100
protected static final int SYSCOLUMNS_TABLEID = 1;
101     protected static final int SYSCOLUMNS_REFERENCEID = 1;
102     protected static final int SYSCOLUMNS_COLUMNNAME = 2;
103     protected static final int SYSCOLUMNS_COLUMNNUMBER = 3;
104     protected static final int SYSCOLUMNS_COLUMNDATATYPE = 4;
105     protected static final int SYSCOLUMNS_COLUMNDEFAULT = 5;
106     protected static final int SYSCOLUMNS_COLUMNDEFAULTID = 6;
107     protected static final int SYSCOLUMNS_AUTOINCREMENTVALUE = 7;
108     protected static final int SYSCOLUMNS_AUTOINCREMENTSTART = 8;
109     protected static final int SYSCOLUMNS_AUTOINCREMENTINC = 9;
110
111     //private static final String SYSCOLUMNS_INDEX1_NAME = "SYSCOLUMNS_INDEX1";
112
protected static final int SYSCOLUMNS_INDEX1_ID = 0;
113
114     //private static final String SYSCOLUMNS_INDEX2_NAME = "SYSCOLUMNS_INDEX2";
115
protected static final int SYSCOLUMNS_INDEX2_ID = 1;
116
117     protected static final String JavaDoc REFERENCEDID_STRING = "REFERENCEID";
118     protected static final String JavaDoc COLUMNNAME_STRING = "COLUMNNAME";
119     protected static final String JavaDoc COLUMNDEFAULTID_STRING = "COLUMNDEFAULTID";
120
121     private static final boolean[] uniqueness = {
122                                                        true,
123                                                        false
124                                                      };
125
126     private static final String JavaDoc[] uuids =
127     {
128          "8000001e-00d0-fd77-3ed8-000a0a0b1900" // catalog UUID
129
,"80000029-00d0-fd77-3ed8-000a0a0b1900" // heap UUID
130
,"80000020-00d0-fd77-3ed8-000a0a0b1900" // SYSCOLUMNS_INDEX1 UUID
131
,"6839c016-00d9-2829-dfcd-000a0a411400" // SYSCOLUMNS_INDEX2 UUID
132
};
133
134     private static final int[][] indexColumnPositions =
135     {
136         {SYSCOLUMNS_REFERENCEID, SYSCOLUMNS_COLUMNNAME},
137         {SYSCOLUMNS_COLUMNDEFAULTID}
138     };
139
140     /////////////////////////////////////////////////////////////////////////////
141
//
142
// STATE
143
//
144
/////////////////////////////////////////////////////////////////////////////
145

146     private SystemColumn[] columnList;
147
148     /////////////////////////////////////////////////////////////////////////////
149
//
150
// CONSTRUCTORS
151
//
152
/////////////////////////////////////////////////////////////////////////////
153

154     public SYSCOLUMNSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf,
155                                  boolean convertIdToLower)
156     {
157         this(uuidf, ef, dvf, convertIdToLower, TABLENAME_STRING);
158     }
159
160     public SYSCOLUMNSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf,
161                                  boolean convertIdToLower, String JavaDoc myName )
162     {
163         super(uuidf,ef,dvf,convertIdToLower);
164         initInfo(SYSCOLUMNS_COLUMN_COUNT, myName, indexColumnPositions, uniqueness, uuids);
165     }
166
167     /////////////////////////////////////////////////////////////////////////////
168
//
169
// METHODS
170
//
171
/////////////////////////////////////////////////////////////////////////////
172

173   /**
174      * Make a SYSCOLUMNS row
175      *
176      * @return Row suitable for inserting into SYSCOLUMNS.
177      *
178      * @exception StandardException thrown on failure
179      */

180
181     public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
182                     throws StandardException
183     {
184         ExecRow row;
185         DataValueDescriptor col;
186
187         String JavaDoc colName = null;
188         String JavaDoc defaultID = null;
189         String JavaDoc tabID = null;
190         Integer JavaDoc colID = null;
191         TypeDescriptorImpl typeDesc = null;
192         Object JavaDoc defaultSerializable = null;
193         long autoincStart = 0;
194         long autoincInc = 0;
195         //The SYSCOLUMNS table's autoinc related columns change with different
196
//values depending on what happened to the autoinc column, ie is the
197
//user adding an autoincrement column, or is user changing the existing
198
//autoincrement column to change it's increment value or to change it's
199
//start value? Following variable is used to keep track of what happened
200
//to the autoincrement column.
201
long autoinc_create_or_modify_Start_Increment = -1;
202
203         if (td != null)
204         {
205             ColumnDescriptor column = (ColumnDescriptor)td;
206         
207             /* Lots of info in the column's type descriptor */
208             typeDesc = column.getType().getCatalogType();
209
210             tabID = column.getReferencingUUID().toString();
211             colName = column.getColumnName();
212             colID = new Integer JavaDoc(column.getPosition() );
213             autoincStart = column.getAutoincStart();
214             autoincInc = column.getAutoincInc();
215             autoinc_create_or_modify_Start_Increment = column.getAutoinc_create_or_modify_Start_Increment();
216             if (column.getDefaultInfo() != null)
217             {
218                 defaultSerializable = column.getDefaultInfo();
219             }
220             else
221             {
222                 defaultSerializable = column.getDefaultValue();
223             }
224             if (column.getDefaultUUID() != null)
225             {
226                 defaultID = column.getDefaultUUID().toString();
227             }
228         }
229
230         /* Insert info into syscolumns */
231
232         /* RESOLVE - It would be nice to require less knowledge about syscolumns
233          * and have this be more table driven.
234          * RESOLVE - We'd like to store the DataTypeDescriptor in a column.
235          */

236
237         /* Build the row to insert */
238         row = getExecutionFactory().getValueRow(SYSCOLUMNS_COLUMN_COUNT);
239
240         /* 1st column is REFERENCEID (UUID - char(36)) */
241         row.setColumn(SYSCOLUMNS_REFERENCEID, dvf.getCharDataValue(tabID));
242
243         /* 2nd column is COLUMNNAME (varchar(128)) */
244         row.setColumn(SYSCOLUMNS_COLUMNNAME, dvf.getVarcharDataValue(colName));
245
246         /* 3rd column is COLUMNNUMBER (int) */
247         row.setColumn(SYSCOLUMNS_COLUMNNUMBER, dvf.getDataValue(colID));
248
249         /* 4th column is COLUMNDATATYPE */
250         row.setColumn(SYSCOLUMNS_COLUMNDATATYPE,
251                 dvf.getDataValue(typeDesc));
252
253         /* 5th column is COLUMNDEFAULT */
254         row.setColumn(SYSCOLUMNS_COLUMNDEFAULT,
255                       dvf.getDataValue(defaultSerializable));
256
257         /* 6th column is DEFAULTID (UUID - char(36)) */
258         row.setColumn(SYSCOLUMNS_COLUMNDEFAULTID, dvf.getCharDataValue(defaultID));
259
260         if (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.CREATE_AUTOINCREMENT ||
261                 autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE)
262         {//user is adding an autoinc column or is changing the increment value of autoinc column
263
row.setColumn(SYSCOLUMNS_AUTOINCREMENTVALUE,
264                           new SQLLongint(autoincStart));
265             row.setColumn(SYSCOLUMNS_AUTOINCREMENTSTART,
266                           new SQLLongint(autoincStart));
267             row.setColumn(SYSCOLUMNS_AUTOINCREMENTINC,
268                           new SQLLongint(autoincInc));
269         } else if (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_RESTART_VALUE)
270         {//user asked for restart with a new value, so don't change increment by and original start
271
//with values in the SYSCOLUMNS table. Just record the RESTART WITH value as the
272
//next value to be generated in the SYSCOLUMNS table
273
ColumnDescriptor column = (ColumnDescriptor)td;
274             row.setColumn(SYSCOLUMNS_AUTOINCREMENTVALUE, new SQLLongint(autoincStart));
275             row.setColumn(SYSCOLUMNS_AUTOINCREMENTSTART, new SQLLongint(autoincStart));
276             row.setColumn(SYSCOLUMNS_AUTOINCREMENTINC, new SQLLongint(
277                     column.getTableDescriptor().getColumnDescriptor(colName).getAutoincInc()));
278         }
279         else
280         {
281             row.setColumn(SYSCOLUMNS_AUTOINCREMENTVALUE,
282                           new SQLLongint());
283             row.setColumn(SYSCOLUMNS_AUTOINCREMENTSTART,
284                           new SQLLongint());
285             row.setColumn(SYSCOLUMNS_AUTOINCREMENTINC,
286                           new SQLLongint());
287         }
288         return row;
289     }
290
291     /**
292      * Get the Properties associated with creating the heap.
293      *
294      * @return The Properties associated with creating the heap.
295      */

296     public Properties JavaDoc getCreateHeapProperties()
297     {
298         Properties JavaDoc properties = new Properties JavaDoc();
299         // keep page size at 4K since its a big table
300
properties.put(Property.PAGE_SIZE_PARAMETER,"4096");
301         // default properties for system tables:
302
properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER,"0");
303         properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,"1");
304         return properties;
305     }
306
307     /**
308      * Get the Properties associated with creating the specified index.
309      *
310      * @param indexNumber The specified index number.
311      *
312      * @return The Properties associated with creating the specified index.
313      */

314     public Properties JavaDoc getCreateIndexProperties(int indexNumber)
315     {
316         Properties JavaDoc properties = new Properties JavaDoc();
317         // keep page size for all indexes at 4K since its a big table
318
properties.put(Property.PAGE_SIZE_PARAMETER,"4096");
319         return properties;
320     }
321
322     ///////////////////////////////////////////////////////////////////////////
323
//
324
// ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
325
//
326
///////////////////////////////////////////////////////////////////////////
327

328     /**
329      * Make a ColumnDescriptor out of a SYSCOLUMNS row
330      *
331      * @param row a SYSCOLUMNS row
332      * @param parentTupleDescriptor The UniqueTupleDescriptor for the object that is tied
333      * to this column
334      * @param dd dataDictionary
335      *
336      * @return a column descriptor equivalent to a SYSCOLUMNS row
337      *
338      * @exception StandardException thrown on failure
339      */

340     public TupleDescriptor buildDescriptor(
341         ExecRow row,
342         TupleDescriptor parentTupleDescriptor,
343         DataDictionary dd )
344                     throws StandardException
345     {
346         if (SanityManager.DEBUG)
347         {
348             SanityManager.ASSERT(row.nColumns() == SYSCOLUMNS_COLUMN_COUNT,
349                                  "Wrong number of columns for a SYSCOLUMNS row");
350         }
351
352         int columnNumber;
353         String JavaDoc columnName;
354         String JavaDoc defaultID;
355         DefaultInfoImpl defaultInfo = null;
356         ColumnDescriptor colDesc;
357         BaseTypeIdImpl typeId;
358         TypeId wrapperTypeId;
359         DataValueDescriptor defaultValue = null;
360         UUID defaultUUID = null;
361         UUID uuid = null;
362         UUIDFactory uuidFactory = getUUIDFactory();
363         long autoincStart, autoincInc;
364
365         DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
366
367
368         /*
369         ** We're going to be getting the UUID for this sucka
370         ** so make sure it is a UniqueTupleDescriptor.
371         */

372         if (parentTupleDescriptor != null)
373         {
374             if (SanityManager.DEBUG)
375             {
376                 if (!(parentTupleDescriptor instanceof UniqueTupleDescriptor))
377                 {
378                     SanityManager.THROWASSERT(parentTupleDescriptor.getClass().getName()
379                             + " not instanceof UniqueTupleDescriptor");
380                 }
381             }
382             uuid = ((UniqueTupleDescriptor)parentTupleDescriptor).getUUID();
383         }
384         else
385         {
386             /* 1st column is REFERENCEID (char(36)) */
387             uuid = uuidFactory.recreateUUID(row.getColumn(SYSCOLUMNS_REFERENCEID).
388                                                     getString());
389         }
390
391         /* NOTE: We get columns 5 and 6 next in order to work around
392          * a 1.3.0 HotSpot bug. (#4361550)
393          */

394
395         // 5th column is COLUMNDEFAULT (serialiazable)
396
Object JavaDoc object = row.getColumn(SYSCOLUMNS_COLUMNDEFAULT).getObject();
397         if (object instanceof DataValueDescriptor)
398         {
399             defaultValue = (DataValueDescriptor) object;
400         }
401         else if (object instanceof DefaultInfoImpl)
402         {
403             defaultInfo = (DefaultInfoImpl) object;
404             defaultValue = defaultInfo.getDefaultValue();
405         }
406
407         /* 6th column is DEFAULTID (char(36)) */
408         defaultID = row.getColumn(SYSCOLUMNS_COLUMNDEFAULTID).getString();
409
410         if (defaultID != null)
411         {
412             defaultUUID = uuidFactory.recreateUUID(defaultID);
413         }
414
415         /* 2nd column is COLUMNNAME (varchar(128)) */
416         columnName = row.getColumn(SYSCOLUMNS_COLUMNNAME).getString();
417
418         /* 3rd column is COLUMNNUMBER (int) */
419         columnNumber = row.getColumn(SYSCOLUMNS_COLUMNNUMBER).getInt();
420
421         /* 4th column is COLUMNDATATYPE */
422
423         /*
424         ** What is stored in the column is a TypeDescriptorImpl, which
425         ** points to a BaseTypeIdImpl. These are simple types that are
426         ** intended to be movable to the client, so they don't have
427         ** the entire implementation. We need to wrap them in DataTypeServices
428         ** and TypeId objects that contain the full implementations for
429         ** language processing.
430         */

431         TypeDescriptorImpl typeDescriptor = (TypeDescriptorImpl) row.getColumn(SYSCOLUMNS_COLUMNDATATYPE).
432                                                     getObject();
433         typeId = typeDescriptor.getTypeId();
434
435         /*
436         ** The BaseTypeIdImpl tells what type of TypeId it is supposed to
437         ** be wrapped in.
438         */

439         wrapperTypeId =
440             (TypeId) Monitor.newInstanceFromIdentifier(typeId.wrapperTypeFormatId());
441         /* Wrap the BaseTypeIdImpl in a full type id */
442         wrapperTypeId.setNestedTypeId(typeId);
443
444         /* Wrap the TypeDescriptorImpl in a full DataTypeDescriptor */
445         DataTypeDescriptor dataTypeServices = new DataTypeDescriptor(typeDescriptor,
446                                                     wrapperTypeId);
447
448         /* 7th column is AUTOINCREMENTVALUE, not cached in descriptor (long) */
449
450         /* 8th column is AUTOINCREMENTSTART (long) */
451         autoincStart = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART).getLong();
452
453         /* 9th column is AUTOINCREMENTINC (long) */
454         autoincInc = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC).getLong();
455
456         DataValueDescriptor col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART);
457         autoincStart = col.getLong();
458
459         col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC);
460         autoincInc = col.getLong();
461
462         colDesc = new ColumnDescriptor(columnName, columnNumber,
463                             dataTypeServices, defaultValue, defaultInfo, uuid,
464                             defaultUUID, autoincStart, autoincInc);
465         return colDesc;
466     }
467
468     /**
469       * Get the index number for the primary key index on this catalog.
470       *
471       * @return a 0-based number
472       *
473       */

474     public int getPrimaryKeyIndexNumber()
475     {
476         return SYSCOLUMNS_INDEX1_ID;
477     }
478
479     /**
480      * Builds a list of columns suitable for creating this Catalog.
481      *
482      *
483      * @return array of SystemColumn suitable for making this catalog.
484      */

485     public SystemColumn[] buildColumnList()
486     {
487         if ( columnList != null ) { return columnList; }
488
489         columnList = new SystemColumn[SYSCOLUMNS_COLUMN_COUNT];
490
491         // describe columns
492

493         columnList[0] =
494                     new SystemColumnImpl(
495                                 convertIdCase( REFERENCEDID_STRING), // column name
496
SYSCOLUMNS_REFERENCEID,// column number
497
0, // precision
498
0, // scale
499
false, // nullability
500
"CHAR", // dataType
501
true, // built-in type
502
36 // maxLength
503
);
504
505         columnList[1] =
506                     new SystemColumnImpl( // SQL IDENTIFIER
507
convertIdCase( COLUMNNAME_STRING), // column name
508
SYSCOLUMNS_COLUMNNAME, // column number
509
false // nullability
510
);
511
512         columnList[2] =
513                     new SystemColumnImpl(
514                                 convertIdCase( "COLUMNNUMBER"), // column name
515
SYSCOLUMNS_COLUMNNUMBER, // column number
516
0, // precision
517
0, // scale
518
false, // nullability
519
"INTEGER", // dataType
520
true, // built-in type
521
4 // maxLength
522
);
523
524         columnList[3] =
525                     new SystemColumnImpl(
526                             convertIdCase( "COLUMNDATATYPE"), // column name
527
SYSCOLUMNS_COLUMNDATATYPE, // column number
528
0, // precision
529
0, // scale
530
false, // nullability
531
"org.apache.derby.catalog.TypeDescriptor", // dataType
532
false, // built-in type
533
TypeDescriptor.MAXIMUM_WIDTH_UNKNOWN // maxLength
534
);
535
536         columnList[4] =
537                     new SystemColumnImpl(
538                             convertIdCase( "COLUMNDEFAULT"), // column name
539
SYSCOLUMNS_COLUMNDEFAULT, // column number
540
0, // precision
541
0, // scale
542
true, // nullability
543
"java.io.Serializable", // dataType
544
false, // built-in type
545
TypeDescriptor.MAXIMUM_WIDTH_UNKNOWN // maxLength
546
);
547
548         columnList[5] =
549                     new SystemColumnImpl(
550                                 convertIdCase( COLUMNDEFAULTID_STRING), // column name
551
SYSCOLUMNS_COLUMNDEFAULTID,// column number
552
0, // precision
553
0, // scale
554
true, // nullability
555
"CHAR", // dataType
556
true, // built-in type
557
36 // maxLength
558
);
559
560         // new columns for autoincrement.
561
columnList[6] =
562                     new SystemColumnImpl(
563                                 convertIdCase( "AUTOINCREMENTVALUE"), // column name
564
SYSCOLUMNS_AUTOINCREMENTVALUE,
565                                 0,
566                                 0,
567                                 true,
568                                 "BIGINT",
569                                 true,
570                                 TypeId.LONGINT_MAXWIDTH
571                                );
572         
573         columnList[7] =
574                     new SystemColumnImpl(
575                                 convertIdCase( "AUTOINCREMENTSTART"), // column name
576
SYSCOLUMNS_AUTOINCREMENTSTART,
577                                 0,
578                                 0,
579                                 true,
580                                 "BIGINT",
581                                 true,
582                                 TypeId.LONGINT_MAXWIDTH
583                                );
584
585         columnList[8] =
586                     new SystemColumnImpl(
587                                 convertIdCase( "AUTOINCREMENTINC"), // column name
588
SYSCOLUMNS_AUTOINCREMENTINC,
589                                 0,
590                                 0,
591                                 true,
592                                 "BIGINT",
593                                 true,
594                                 TypeId.LONGINT_MAXWIDTH
595                                );
596
597         return columnList;
598     }
599 }
600
Popular Tags