KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > sql > dictionary > TableDescriptor


1 /*
2
3    Derby - Class org.apache.derby.iapi.sql.dictionary.TableDescriptor
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.iapi.sql.dictionary;
23
24 import org.apache.derby.iapi.services.context.ContextManager;
25
26 import org.apache.derby.iapi.error.StandardException;
27
28 import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
29
30 import org.apache.derby.iapi.sql.depend.Provider;
31
32 import org.apache.derby.iapi.sql.execute.ExecRow;
33 import org.apache.derby.catalog.UUID;
34 import org.apache.derby.catalog.DependableFinder;
35 import org.apache.derby.iapi.services.io.FormatableBitSet;
36 import org.apache.derby.iapi.sql.StatementType;
37 import org.apache.derby.iapi.services.io.StoredFormatIds;
38
39 import org.apache.derby.iapi.types.DataValueDescriptor;
40 import org.apache.derby.iapi.sql.depend.Provider;
41 import org.apache.derby.iapi.sql.execute.ExecRow;
42 import org.apache.derby.iapi.sql.execute.ExecutionContext;
43
44 import org.apache.derby.iapi.reference.SQLState;
45 import org.apache.derby.catalog.Dependable;
46 import org.apache.derby.iapi.services.sanity.SanityManager;
47
48 import java.util.Vector JavaDoc;
49 import java.util.Enumeration JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.Iterator JavaDoc;
52
53 /**
54  * This class represents a table descriptor. The external interface to this
55  * class is:
56  <p>
57         <ol>
58         <li>external interface </li>
59         <li>public String getSchemaName();</li>
60         <li>public String getQualifiedName();</li>
61         <li>public int getTableType();</li>
62         <li>public long getHeapConglomerateId() throws StandardException;</li>
63         <li>public int getNumberOfColumns(); </li>
64         <li>public FormatableBitSet getReferencedColumnMap();</li>
65         <li>public void setReferencedColumnMap(FormatableBitSet referencedColumnMap);</li>
66         <li>public int getMaxColumnID() throws StandardException;</li>
67         <li>public void setUUID(UUID uuid);</li>
68         <li>public char getLockGranularity();</li>
69         <li>public void setTableName(String newTableName);</li>
70         <li>public void setLockGranularity(char lockGranularity);</li>
71         <li>public ExecRow getEmptyExecRow( ContextManager cm) throws StandardException;</li>
72         <li>public boolean tableNameEquals(String otherSchemaName, String otherTableName);</li>
73         <li>public ReferencedKeyConstraintDescriptor getPrimaryKey() throws StandardException;</li>
74         <li>public void removeConglomerateDescriptor(ConglomerateDescriptor cd) throws StandardException;</li>
75         <li>public void removeConstraintDescriptor(ConstraintDescriptor cd) throws StandardException;</li>
76         <li>public void getAffectedIndexes(...) throws StandardException;</li>
77         <li>public void getAllRelevantTriggers(...) throws StandardException;</li>
78         <li>public void getAllRelevantConstraints(...) throws StandardException</li>
79         <li>public ColumnDescriptorList getColumnDescriptorList();</li>
80         <li> public String[] getColumnNamesArray();</li>
81         <li>public long[] getAutoincIncrementArray();</li>
82         <li>public ColumnDescriptor getColumnDescriptor(String columnName);</li>
83         <li>public ColumnDescriptor getColumnDescriptor(int columnNumber);</li>
84         <li>public ConglomerateDescriptor[] getConglomerateDescriptors() throws StandardException;</li>
85         <li>public ConglomerateDescriptor getConglomerateDescriptor(long conglomerateNumber) throws StandardException;</li>
86         <li>public ConglomerateDescriptor getConglomerateDescriptor(UUID conglomerateUUID) throws StandardException;</li>
87         <li>public IndexLister getIndexLister() throws StandardException;</li>
88         <li>public ViewDescriptor getViewDescriptor();</li>
89         <li>public boolean tableHasAutoincrement();</li>
90         <li>public boolean statisticsExist(ConglomerateDescriptor cd) throws StandardException;</li>
91         <li>public double selectivityForConglomerate(...)throws StandardException;</li>
92         </ol>
93     <p>
94     *
95     * @author Jeff Lichtman
96     */

97
98 public class TableDescriptor extends TupleDescriptor
99     implements UniqueSQLObjectDescriptor, Provider
100 {
101     public static final int BASE_TABLE_TYPE = 0;
102     public static final int SYSTEM_TABLE_TYPE = 1;
103     public static final int VIEW_TYPE = 2;
104     public static final int GLOBAL_TEMPORARY_TABLE_TYPE = 3;
105     public static final int SYNONYM_TYPE = 4;
106     public static final int VTI_TYPE = 5;
107
108     public static final char ROW_LOCK_GRANULARITY = 'R';
109     public static final char TABLE_LOCK_GRANULARITY = 'T';
110     public static final char DEFAULT_LOCK_GRANULARITY = ROW_LOCK_GRANULARITY;
111
112     /**
113     */

114
115     // implementation
116
private char lockGranularity;
117     private boolean onCommitDeleteRows; //true means on commit delete rows, false means on commit preserve rows of temporary table.
118
private boolean onRollbackDeleteRows; //true means on rollback delete rows. This is the only value supported.
119
SchemaDescriptor schema;
120     String JavaDoc tableName;
121     UUID oid;
122     int tableType;
123     long heapConglomNumber = -1;
124     ColumnDescriptorList columnDescriptorList;
125     ConglomerateDescriptorList conglomerateDescriptorList;
126     ConstraintDescriptorList constraintDescriptorList;
127     private GenericDescriptorList triggerDescriptorList;
128     ViewDescriptor viewDescriptor;
129     FormatableBitSet referencedColumnMap;
130
131     /** A list of statistics pertaining to this table--
132      */

133     private List statisticsDescriptorList;
134
135     /**
136      * Constructor for a TableDescriptor (this is for a temporary table).
137      *
138      * @param dataDictionary The data dictionary that this descriptor lives in
139      * @param tableName The name of the temporary table
140      * @param schema The schema descriptor for this table.
141      * @param tableType An integer identifier for the type of the table : declared global temporary table
142      * @param onCommitDeleteRows If true, on commit delete rows else on commit preserve rows of temporary table.
143      * @param onRollbackDeleteRows If true, on rollback, delete rows from temp tables which were logically modified. true is the only supported value
144      */

145
146     public TableDescriptor
147     (
148         DataDictionary dataDictionary,
149         String JavaDoc tableName,
150         SchemaDescriptor schema,
151         int tableType,
152         boolean onCommitDeleteRows,
153         boolean onRollbackDeleteRows
154     )
155     {
156         this(dataDictionary, tableName, schema, tableType, '\0');
157
158         this.onCommitDeleteRows = onCommitDeleteRows;
159         this.onRollbackDeleteRows = onRollbackDeleteRows;
160     }
161
162     /**
163      * Constructor for a TableDescriptor.
164      *
165      * @param dataDictionary The data dictionary that this descriptor lives in
166      * @param tableName The name of the table
167      * @param schema The schema descriptor for this table.
168      * @param tableType An integer identifier for the type of the table
169      * (base table, view, etc.)
170      * @param lockGranularity The lock granularity.
171      */

172
173     public TableDescriptor
174     (
175         DataDictionary dataDictionary,
176         String JavaDoc tableName,
177         SchemaDescriptor schema,
178         int tableType,
179         char lockGranularity
180     )
181     {
182         super( dataDictionary );
183
184         this.schema = schema;
185         this.tableName = tableName;
186         this.tableType = tableType;
187         this.lockGranularity = lockGranularity;
188
189         this.conglomerateDescriptorList = new ConglomerateDescriptorList();
190         this.columnDescriptorList = new ColumnDescriptorList();
191         this.constraintDescriptorList = new ConstraintDescriptorList();
192         this.triggerDescriptorList = new GenericDescriptorList();
193     }
194
195     //
196
// TableDescriptor interface
197
//
198

199     /**
200      * Gets the name of the schema the table lives in.
201      *
202      * @return A String containing the name of the schema the table
203      * lives in.
204      */

205     public String JavaDoc getSchemaName()
206     {
207         return schema.getSchemaName();
208     }
209
210     /**
211      * Gets the SchemaDescriptor for this TableDescriptor.
212      *
213      * @return SchemaDescriptor The SchemaDescriptor.
214      */

215     public SchemaDescriptor getSchemaDescriptor()
216     {
217         return schema;
218     }
219
220     /**
221      * Gets the name of the table.
222      *
223      * @return A String containing the name of the table.
224      */

225     public String JavaDoc getName()
226     {
227         return tableName;
228     }
229
230     /**
231      * Sets the the table name in case of rename table.
232      *
233      * This is used only by rename table
234      * @param newTableName The new table name.
235      */

236     public void setTableName(String JavaDoc newTableName)
237     {
238         this.tableName = newTableName;
239     }
240
241     /**
242      * Gets the full, qualified name of the table.
243      *
244      * @return A String containing the name of the table.
245      */

246     public String JavaDoc getQualifiedName()
247     {
248         //quoteStringIfNecessary is for bug 3476. If the schemaName and/or tableName has
249
//double quotes in it, this method will put them in quotes and replace every
250
//double quote with 2 double quotes.
251
return quoteStringIfNecessary(getSchemaName()) + "." +
252             quoteStringIfNecessary(getName());
253     }
254
255     /**
256      * If the name has double quotes in it, put two double quotes for every single
257      * double quote.
258      * For eg, if table name is m"n, return it as "m""n". For now, this is used
259      * by DMLModStatementNode.parseCheckConstraint().
260      *
261      * @param name The String with or without double quotes
262      *
263      * @return The quoted String
264      */

265
266     private String JavaDoc quoteStringIfNecessary(String JavaDoc name)
267     {
268         String JavaDoc quotedString = name;
269         int quotePos = name.indexOf("\"");
270
271         if (quotePos == -1)
272             return name;
273
274         //string does have quotes in it.
275
while(quotePos != -1) {
276             quotedString = quotedString.substring(0,quotePos) + "\"" +
277                 quotedString.substring(quotePos);
278             quotePos = quotedString.indexOf("\"",quotePos+2);
279         }
280         return "\"" + quotedString + "\"";
281
282     }
283
284     /**
285      * Gets the UUID of the table.
286      *
287      * @return The UUID of the table.
288      */

289     public UUID getUUID()
290     {
291         return oid;
292     }
293
294     /**
295      * Gets an identifier telling what type of table this is
296      * (base table, declared global temporary table, view, etc.)
297      *
298      * @return An identifier telling what type of table this is.
299      */

300     public int getTableType()
301     {
302         return tableType;
303     }
304
305     /**
306      * Gets the id for the heap conglomerate of the table.
307      * There may also be keyed conglomerates, these are
308      * stored separately in the conglomerates table.
309      *
310      * @return the id of the heap conglomerate for the table.
311      *
312      * @exception StandardException Thrown on error
313      */

314     public long getHeapConglomerateId()
315             throws StandardException
316     {
317         DataDictionary dd = getDataDictionary();
318
319         ConglomerateDescriptor cd = null;
320
321         /* If we've already cached the heap conglomerate number, then
322          * simply return it.
323          */

324         if (heapConglomNumber != -1)
325         {
326             return heapConglomNumber;
327         }
328
329         ConglomerateDescriptor[] cds = getConglomerateDescriptors();
330
331         for (int index = 0; index < cds.length; index++)
332         {
333             cd = cds[index];
334             if ( ! cd.isIndex())
335                 break;
336         }
337
338         if (SanityManager.DEBUG)
339         {
340             if (cd == null)
341             {
342                 SanityManager.THROWASSERT(
343                     "cd is expected to be non-null for " + tableName);
344             }
345
346             if (cd.isIndex())
347             {
348                 SanityManager.THROWASSERT(
349                     "Did not find heap conglomerate for " + tableName);
350             }
351         }
352
353         heapConglomNumber = cd.getConglomerateNumber();
354
355         return heapConglomNumber;
356     }
357
358     /**
359      * Gets the number of columns in the table.
360      *
361      * @return the number of columns in the table.
362      *
363      */

364     public int getNumberOfColumns()
365     {
366         return getColumnDescriptorList().size();
367     }
368
369     /**
370      * Get the referenced column map of the table.
371      *
372      * @return the referencedColumnMap of the table.
373      *
374      */

375     public FormatableBitSet getReferencedColumnMap()
376     {
377         return referencedColumnMap;
378     }
379
380     /**
381      * Set the referenced column map of the table.
382      *
383      * @param referencedColumnMap FormatableBitSet of referenced columns.
384      *
385      */

386     public void setReferencedColumnMap(FormatableBitSet referencedColumnMap)
387     {
388         this.referencedColumnMap = referencedColumnMap;
389     }
390
391     /**
392      * Gets the highest column id in the table. For now this is the same as
393      * the number of columns. However, in the future, after we implement
394      * ALTER TABLE DROP COLUMN, this correspondence won't hold any longer.
395      *
396      * @return the highest column ID in the table
397      *
398      * @exception StandardException Thrown on error
399      */

400     public int getMaxColumnID()
401         throws StandardException
402     {
403         int maxColumnID = 1;
404         int cdlSize = getColumnDescriptorList().size();
405         for (int index = 0; index < cdlSize; index++)
406         {
407             ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(index);
408             maxColumnID = Math.max( maxColumnID, cd.getPosition() );
409         }
410
411         return maxColumnID;
412     }
413
414     /**
415      * Sets the UUID of the table
416      *
417      * @param oid The UUID of the table to be set in the descriptor
418      */

419     public void setUUID(UUID oid)
420     {
421         this.oid = oid;
422     }
423
424     /**
425      * Gets the lock granularity for the table.
426      *
427      * @return A char representing the lock granularity for the table.
428      */

429     public char getLockGranularity()
430     {
431         return lockGranularity;
432     }
433
434     /**
435      * Sets the lock granularity for the table to the specified value.
436      *
437      * @param lockGranularity The new lockGranularity.
438      */

439     public void setLockGranularity(char lockGranularity)
440     {
441         this.lockGranularity = lockGranularity;
442     }
443
444     /**
445      * Gets the on rollback behavior for the declared global temporary table.
446      *
447      * @return A boolean representing the on rollback behavior for the declared global temporary table.
448      */

449     public boolean isOnRollbackDeleteRows()
450     {
451         return onRollbackDeleteRows;
452     }
453
454     /**
455      * Gets the on commit behavior for the declared global temporary table.
456      *
457      * @return A boolean representing the on commit behavior for the declared global temporary table.
458      */

459     public boolean isOnCommitDeleteRows()
460     {
461         return onCommitDeleteRows;
462     }
463
464     /**
465      * Sets the heapConglomNumber to -1 for temporary table since the table was dropped and recreated at the commit time
466      * and hence its conglomerate id has changed. This is used for temporary table descriptors only
467      */

468     public void resetHeapConglomNumber()
469     {
470         if (SanityManager.DEBUG)
471         {
472             if (tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
473             {
474                 SanityManager.THROWASSERT("tableType expected to be TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, not " +
475                 tableType);
476             }
477         }
478         heapConglomNumber = -1;
479     }
480
481     /**
482      * Gets an ExecRow for rows stored in the table this describes.
483      *
484      * @param cm Current ContextManager
485      *
486      * @return the row.
487      * @exception StandardException Thrown on failure
488      */

489     public ExecRow getEmptyExecRow( ContextManager cm)
490          throws StandardException
491     {
492         int columnCount = getNumberOfColumns();
493         ExecutionContext ec = (ExecutionContext) cm.getContext(ExecutionContext.CONTEXT_ID);
494         ExecRow result = ec.getExecutionFactory().getValueRow(columnCount);
495
496         for (int index = 0; index < columnCount; index++)
497         {
498             ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(index);
499             //String name = column.getColumnName();
500
DataValueDescriptor dataValue = cd.getType().getNull();
501             result.setColumn(index + 1, dataValue);
502         }
503         return result;
504     }
505
506     /**
507      * Gets the conglomerate descriptor list
508      *
509      * @return The conglomerate descriptor list for this table descriptor
510      */

511     public ConglomerateDescriptorList getConglomerateDescriptorList()
512     {
513         return conglomerateDescriptorList;
514     }
515
516     /**
517      * Gets the view descriptor for this TableDescriptor.
518      *
519      * @return ViewDescriptor The ViewDescriptor, if any.
520      */

521     public ViewDescriptor getViewDescriptor()
522     {
523         return viewDescriptor;
524     }
525
526     /**
527      * Set (cache) the view descriptor for this TableDescriptor
528      *
529      * @param viewDescriptor The view descriptor to cache.
530      */

531     public void setViewDescriptor(ViewDescriptor viewDescriptor)
532     {
533         if (SanityManager.DEBUG)
534         {
535             if (tableType != TableDescriptor.VIEW_TYPE)
536             {
537                 SanityManager.THROWASSERT("tableType expected to be TableDescriptor.VIEW_TYPE, not " +
538                 tableType);
539             }
540         }
541         this.viewDescriptor = viewDescriptor;
542     }
543
544     /**
545      * Is this provider persistent? A stored dependency will be required
546      * if both the dependent and provider are persistent.
547      *
548      * @return boolean Whether or not this provider is persistent.
549      */

550     public boolean isPersistent()
551     {
552         if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
553             return false;
554         else
555             return(super.isPersistent());
556     }
557
558     /**
559      * Is this descriptor represents a synonym?
560      *
561      * @return boolean Whether or not this represents a synonym
562      */

563     public boolean isSynonymDescriptor()
564     {
565         if (tableType == TableDescriptor.SYNONYM_TYPE)
566             return true;
567         return false;
568     }
569
570     /**
571      * Gets the number of indexes on the table, including the backing indexes.
572      *
573      * @return the number of columns in the table.
574      *
575      */

576     public int getTotalNumberOfIndexes()
577         throws StandardException
578     {
579         int totalNumberOfIndexes = 0;
580         ConglomerateDescriptor[] cds = getConglomerateDescriptors();
581
582         for (int index = 0; index < cds.length; index++)
583         {
584             if (cds[index].isIndex()) { totalNumberOfIndexes++; }
585         }
586
587         return totalNumberOfIndexes;
588     }
589
590
591     /**
592       * Builds a list of all triggers which are relevant to a
593       * given statement type, given a list of updated columns.
594       *
595       * @param statementType defined in StatementType
596       * @param changedColumnIds array of changed columns
597       * @param relevantTriggers IN/OUT. Passed in as an empty list. Filled in as we go.
598       *
599       * @exception StandardException Thrown on error
600       */

601     public void getAllRelevantTriggers
602     (
603         int statementType,
604         int[] changedColumnIds,
605         GenericDescriptorList relevantTriggers
606     )
607         throws StandardException
608     {
609         if (SanityManager.DEBUG)
610         {
611             SanityManager.ASSERT((statementType == StatementType.INSERT) ||
612                                  (statementType == StatementType.BULK_INSERT_REPLACE) ||
613                                  (statementType == StatementType.UPDATE) ||
614                                  (statementType == StatementType.DELETE),
615                             "invalid statement type "+statementType);
616         }
617
618         DataDictionary dd = getDataDictionary();
619         Enumeration JavaDoc descs = dd.getTriggerDescriptors(this).elements();
620
621         while (descs.hasMoreElements())
622         {
623             TriggerDescriptor tgr = (TriggerDescriptor)descs.nextElement();
624
625             if (tgr.needsToFire(statementType, changedColumnIds))
626             {
627                 relevantTriggers.add(tgr);
628             }
629         }
630     }
631
632     /**
633       * Gets all of the relevant constraints for a statement, given its
634       * statement type and its list of updated columns.
635       *
636       * @param statementType As defined in StatementType.
637       * @param skipCheckConstraints Skip check constraints
638       * @param changedColumnIds If null, all columns being changed, otherwise array
639       * of 1-based column ids for columns being changed
640       * @param needsDeferredProcessing IN/OUT. true if the statement already needs
641       * deferred processing. set while evaluating this
642       * routine if a trigger or constraint requires
643       * deferred processing
644       * @param relevantConstraints IN/OUT. Empty list is passed in. We hang constraints on it as we go.
645       *
646       * @exception StandardException Thrown on error
647       */

648     public void getAllRelevantConstraints
649     (
650         int statementType,
651         boolean skipCheckConstraints,
652         int[] changedColumnIds,
653         boolean[] needsDeferredProcessing,
654         ConstraintDescriptorList relevantConstraints
655     )
656         throws StandardException
657     {
658         if (SanityManager.DEBUG)
659         {
660             SanityManager.ASSERT((statementType == StatementType.INSERT) ||
661                                  (statementType == StatementType.BULK_INSERT_REPLACE) ||
662                                  (statementType == StatementType.UPDATE) ||
663                                  (statementType == StatementType.DELETE),
664                             "invalid statement type "+statementType);
665         }
666
667         DataDictionary dd = getDataDictionary();
668         ConstraintDescriptorList cdl = dd.getConstraintDescriptors(this);
669         int cdlSize = cdl.size();
670
671         for (int index = 0; index < cdlSize; index++)
672         {
673             ConstraintDescriptor cd = cdl.elementAt(index);
674
675             if (skipCheckConstraints &&
676                     (cd.getConstraintType() == DataDictionary.CHECK_CONSTRAINT))
677             {
678                 continue;
679             }
680
681             /*
682             ** For each constraint, figure out if it requires deferred processing.
683             ** Note that we need to do this on constraints that don't
684             ** necessarily need to fire -- e.g. for an insert into a
685             ** a table with a self-referencing constraint, we don't
686             ** need to check the primary key constraint (assuming it
687             ** is only referenced by the self-referencing fk on the same
688             ** table), but we have to run in deferred mode nonetheless
689             ** (even though we aren't going to check the pk constraint).
690             */

691             if (!needsDeferredProcessing[0] &&
692                 (cd instanceof ReferencedKeyConstraintDescriptor) &&
693                 (statementType != StatementType.UPDATE &&
694                  statementType != StatementType.BULK_INSERT_REPLACE))
695             {
696                 /* For insert (bulk or regular) on a non-published table,
697                  * we only need deferred mode if there is a
698                  * self-referencing foreign key constraint.
699                  */

700                 needsDeferredProcessing[0] = ((ReferencedKeyConstraintDescriptor)cd).
701                                     hasSelfReferencingFK(cdl, ConstraintDescriptor.ENABLED);
702             }
703
704             if (cd.needsToFire(statementType, changedColumnIds))
705             {
706                 /*
707                 ** For update, if we are updating a referenced key, then
708                 ** we have to do it in deferred mode (in case we update
709                 ** multiple rows).
710                 */

711                 if ((cd instanceof ReferencedKeyConstraintDescriptor) &&
712                     (statementType == StatementType.UPDATE ||
713                      statementType == StatementType.BULK_INSERT_REPLACE))
714                 {
715                     needsDeferredProcessing[0] = true;
716                 }
717
718                 relevantConstraints.add(cd);
719             }
720         }
721     }
722
723
724     //
725
// Provider interface
726
//
727

728     /**
729         @return the stored form of this provider
730
731             @see Dependable#getDependableFinder
732      */

733     public DependableFinder getDependableFinder()
734     {
735         if (referencedColumnMap == null)
736             return getDependableFinder(StoredFormatIds.TABLE_DESCRIPTOR_FINDER_V01_ID);
737         else
738             return getColumnDependableFinder(StoredFormatIds.COLUMN_DESCRIPTOR_FINDER_V01_ID,
739                                              referencedColumnMap.getByteArray());
740     }
741
742     /**
743      * Return the name of this Provider. (Useful for errors.)
744      *
745      * @return String The name of this provider.
746      */

747     public String JavaDoc getObjectName()
748     {
749         if (referencedColumnMap == null)
750             return tableName;
751         else
752         {
753             String JavaDoc name = new String JavaDoc(tableName);
754             boolean first = true;
755             for (int i = 0; i < columnDescriptorList.size(); i++)
756             {
757                 ColumnDescriptor cd = (ColumnDescriptor) columnDescriptorList.elementAt(i);
758                 if (referencedColumnMap.isSet(cd.getPosition()))
759                 {
760                     if (first)
761                     {
762                         name += "(" + cd.getColumnName();
763                         first = false;
764                     }
765                     else
766                         name += ", " + cd.getColumnName();
767                 }
768             }
769             if (! first)
770                 name += ")";
771             return name;
772         }
773     }
774
775     /**
776      * Get the provider's UUID
777      *
778      * @return String The provider's UUID
779      */

780     public UUID getObjectID()
781     {
782         return oid;
783     }
784
785     /**
786      * Get the provider's type.
787      *
788      * @return String The provider's type.
789      */

790     public String JavaDoc getClassType()
791     {
792         return Dependable.TABLE;
793     }
794
795     //
796
// class interface
797
//
798

799     /**
800      * Prints the contents of the TableDescriptor
801      *
802      * @return The contents as a String
803      */

804     public String JavaDoc toString()
805     {
806         if (SanityManager.DEBUG)
807         {
808             String JavaDoc tempString = "SCHEMA:\n" + schema + "\ntableName: " + tableName + "\n" +
809                 "oid: " + oid + " tableType: " + tableType + "\n" +
810                 "conglomerateDescriptorList: " + conglomerateDescriptorList + "\n" +
811                 "columnDescriptorList: " + columnDescriptorList + "\n" +
812                 "constraintDescriptorList: " + constraintDescriptorList + "\n" +
813                 "heapConglomNumber: " + heapConglomNumber + "\n";
814             if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
815             {
816                 tempString = tempString + "onCommitDeleteRows: " + "\n" + onCommitDeleteRows + "\n";
817                 tempString = tempString + "onRollbackDeleteRows: " + "\n" + onRollbackDeleteRows + "\n";
818             } else
819                 tempString = tempString + "lockGranularity: " + lockGranularity + "\n";
820             return tempString;
821         }
822         else
823         {
824             return "";
825         }
826     }
827
828     /**
829      * Gets the column descriptor list
830      *
831      * @return The column descriptor list for this table descriptor
832      *
833      */

834     public ColumnDescriptorList getColumnDescriptorList()
835     {
836         return columnDescriptorList;
837     }
838
839     /**
840      * Gets the constraint descriptor list
841      *
842      * @return The constraint descriptor list for this table descriptor
843      *
844      * @exception StandardException Thrown on failure
845      */

846     public ConstraintDescriptorList getConstraintDescriptorList()
847         throws StandardException
848     {
849         return constraintDescriptorList;
850     }
851
852     /**
853      * Sets the constraint descriptor list
854      *
855      * @param newCDL The new constraint descriptor list for this table descriptor
856      */

857     public void setConstraintDescriptorList(ConstraintDescriptorList newCDL)
858     {
859         constraintDescriptorList = newCDL;
860     }
861
862     /**
863      * Empty the constraint descriptor list
864      *
865      * @exception StandardException Thrown on failure
866      */

867     public void emptyConstraintDescriptorList()
868         throws StandardException
869     {
870         // Easier just to get a new CDL then to clean out the current one
871
this.constraintDescriptorList = new ConstraintDescriptorList();
872     }
873
874     /**
875      * Gets the primary key, may return null if no primary key
876      *
877      * @return The priamry key or null
878      *
879      * @exception StandardException Thrown on failure
880      */

881     public ReferencedKeyConstraintDescriptor getPrimaryKey()
882         throws StandardException
883     {
884         ConstraintDescriptorList cdl = getDataDictionary().getConstraintDescriptors(this);
885         
886         return cdl.getPrimaryKey();
887     }
888
889     /**
890      * Gets the trigger descriptor list
891      *
892      * @return The trigger descriptor list for this table descriptor
893      *
894      * @exception StandardException Thrown on failure
895      */

896     public GenericDescriptorList getTriggerDescriptorList()
897         throws StandardException
898     {
899         return triggerDescriptorList;
900     }
901
902     /**
903      * Sets the trigger descriptor list
904      *
905      * @param newCDL The new trigger descriptor list for this table descriptor
906      */

907     public void setTriggerDescriptorList(GenericDescriptorList newCDL)
908     {
909         triggerDescriptorList = newCDL;
910     }
911
912     /**
913      * Empty the trigger descriptor list
914      *
915      * @exception StandardException Thrown on failure
916      */

917     public void emptyTriggerDescriptorList()
918         throws StandardException
919     {
920         // Easier just to get a new CDL then to clean out the current one
921
this.triggerDescriptorList = new GenericDescriptorList();
922     }
923
924     
925     /**
926      * Compare the tables descriptors based on the names.
927      * Null schema names match.
928      *
929      * @param otherTableName the other table name
930      * @param otherSchemaName the other schema name
931      *
932      * @return boolean Whether or not the 2 TableNames are equal.
933      */

934     public boolean tableNameEquals(String JavaDoc otherTableName, String JavaDoc otherSchemaName)
935     {
936         String JavaDoc schemaName = getSchemaName();
937
938         if ((schemaName == null) ||
939                  (otherSchemaName == null))
940         {
941             return tableName.equals(otherTableName);
942         }
943         else
944         {
945             return schemaName.equals(otherSchemaName) &&
946                     tableName.equals(otherTableName);
947         }
948     }
949
950     /**
951      * Remove this descriptor
952      *
953      * @param cd The conglomerate descriptor
954      *
955      * @exception StandardException on error
956      */

957     public void removeConglomerateDescriptor(ConglomerateDescriptor cd)
958         throws StandardException
959     {
960         conglomerateDescriptorList.dropConglomerateDescriptor(getUUID(), cd);
961     }
962
963     /**
964      * Remove this descriptor. Warning, removes by using object
965      * reference, not uuid.
966      *
967      * @param cd constraint descriptor
968      *
969      * @exception StandardException on error
970      */

971     public void removeConstraintDescriptor(ConstraintDescriptor cd)
972         throws StandardException
973     {
974         constraintDescriptorList.remove(cd);
975     }
976
977     /**
978      * Get the descriptor for a column in the table,
979      * either by the column name or by its ordinal position (column number).
980      * Returns NULL for columns that do not exist.
981      *
982      * @param columnName A String containing the name of the column
983      *
984      * @return A ColumnDescriptor describing the column
985      */

986     public ColumnDescriptor getColumnDescriptor(String JavaDoc columnName)
987     {
988         return columnDescriptorList.getColumnDescriptor(oid, columnName);
989     }
990
991     /**
992      * @param columnNumber The ordinal position of the column in the table
993      *
994      * @return A ColumnDescriptor describing the column
995      */

996     public ColumnDescriptor getColumnDescriptor(int columnNumber)
997     {
998         return columnDescriptorList.getColumnDescriptor(oid, columnNumber);
999     }
1000
1001    /**
1002     * Gets a ConglomerateDescriptor[] to loop through all the conglomerate descriptors
1003     * for the table.
1004     *
1005     * @return A ConglomerateDescriptor[] for looping through the table's conglomerates
1006     *
1007     * @exception StandardException Thrown on failure
1008     */

1009    public ConglomerateDescriptor[] getConglomerateDescriptors()
1010    {
1011
1012        int size = conglomerateDescriptorList.size();
1013        ConglomerateDescriptor[] cdls = new ConglomerateDescriptor[size];
1014        conglomerateDescriptorList.toArray(cdls);
1015        return cdls;
1016    }
1017
1018    /**
1019     * Gets a conglomerate descriptor for the given table and conglomerate number.
1020     *
1021     * @param conglomerateNumber The conglomerate number
1022     * we're interested in
1023     *
1024     * @return A ConglomerateDescriptor describing the requested
1025     * conglomerate. Returns NULL if no such conglomerate.
1026     *
1027     * @exception StandardException Thrown on failure
1028     */

1029    public ConglomerateDescriptor getConglomerateDescriptor(
1030                        long conglomerateNumber)
1031                        throws StandardException
1032    {
1033        return conglomerateDescriptorList.getConglomerateDescriptor(conglomerateNumber);
1034    }
1035
1036    /**
1037     * Gets array of conglomerate descriptors for the given table and
1038     * conglomerate number. More than one descriptors if duplicate indexes
1039     * share one conglomerate.
1040     *
1041     * @param conglomerateNumber The conglomerate number
1042     * we're interested in
1043     *
1044     * @return Array of ConglomerateDescriptors with the requested
1045     * conglomerate number. Returns size 0 array if no such conglomerate.
1046     *
1047     * @exception StandardException Thrown on failure
1048     */

1049    public ConglomerateDescriptor[] getConglomerateDescriptors(
1050                        long conglomerateNumber)
1051                        throws StandardException
1052    {
1053        return conglomerateDescriptorList.getConglomerateDescriptors(conglomerateNumber);
1054    }
1055
1056
1057    /**
1058     * Gets a conglomerate descriptor for the given table and conglomerate UUID String.
1059     *
1060     * @param conglomerateUUID The UUID for the conglomerate
1061     * we're interested in
1062     *
1063     * @return A ConglomerateDescriptor describing the requested
1064     * conglomerate. Returns NULL if no such conglomerate.
1065     *
1066     * @exception StandardException Thrown on failure
1067     */

1068    public ConglomerateDescriptor getConglomerateDescriptor(
1069                        UUID conglomerateUUID)
1070                        throws StandardException
1071    {
1072        return conglomerateDescriptorList.getConglomerateDescriptor(conglomerateUUID);
1073    }
1074
1075    /**
1076     * Gets array of conglomerate descriptors for the given table and
1077     * conglomerate UUID. More than one descriptors if duplicate indexes
1078     * share one conglomerate.
1079     *
1080     * @param conglomerateUUID The conglomerate UUID
1081     * we're interested in
1082     *
1083     * @return Array of ConglomerateDescriptors with the requested
1084     * conglomerate UUID. Returns size 0 array if no such conglomerate.
1085     *
1086     * @exception StandardException Thrown on failure
1087     */

1088    public ConglomerateDescriptor[] getConglomerateDescriptors(
1089                        UUID conglomerateUUID)
1090                        throws StandardException
1091    {
1092        return conglomerateDescriptorList.getConglomerateDescriptors(conglomerateUUID);
1093    }
1094
1095    /**
1096     * Gets an object which lists out all the index row generators on a table together
1097     * with their conglomerate ids.
1098     *
1099     * @return An object to list out the index row generators.
1100     *
1101     * @exception StandardException Thrown on failure
1102     */

1103    public IndexLister getIndexLister()
1104                        throws StandardException
1105    {
1106        return new IndexLister( this );
1107    }
1108
1109    /**
1110     * Does the table have an autoincrement column or not?
1111     *
1112     * @return TRUE if the table has atleast one autoincrement column, false
1113     * otherwise
1114     */

1115    public boolean tableHasAutoincrement()
1116    {
1117        int cdlSize = getColumnDescriptorList().size();
1118        for (int index = 0; index < cdlSize; index++)
1119        {
1120            ColumnDescriptor cd =
1121                (ColumnDescriptor) columnDescriptorList.elementAt(index);
1122            if (cd.isAutoincrement())
1123                return true;
1124        }
1125        return false;
1126    }
1127    
1128    /**
1129     * Gets an array of column names.
1130     *
1131     * @return An array, filled with the column names in the table.
1132     *
1133     */

1134    public String JavaDoc[] getColumnNamesArray()
1135    {
1136        int size = getNumberOfColumns();
1137        String JavaDoc[] s = new String JavaDoc[size];
1138
1139        for (int i = 0; i < size; i++)
1140            s[i] = getColumnDescriptor(i+1).getColumnName();
1141        
1142        return s;
1143    }
1144
1145    /**
1146     * gets an array of increment values for autoincrement columns in the target
1147     * table. If column is not an autoincrement column, then increment value is
1148     * 0. If table has no autoincrement columns, returns NULL.
1149     *
1150     * @return array containing the increment values of autoincrement
1151     * columns.
1152     *
1153     */

1154    public long[] getAutoincIncrementArray()
1155    {
1156        if (!tableHasAutoincrement())
1157            return null;
1158
1159        int size = getNumberOfColumns();
1160        long[] inc = new long[size];
1161
1162        for (int i = 0; i < size; i++)
1163        {
1164            ColumnDescriptor cd = getColumnDescriptor(i + 1);
1165            if (cd.isAutoincrement())
1166                inc[i] = cd.getAutoincInc();
1167        }
1168
1169        return inc;
1170    }
1171
1172    
1173    /** Returns a list of statistics for this table.
1174     */

1175    private synchronized List getStatistics() throws StandardException
1176    {
1177        // if table already has the statistics descriptors initialized
1178
// no need to do anything
1179
if (statisticsDescriptorList != null)
1180            return statisticsDescriptorList;
1181
1182        DataDictionary dd = getDataDictionary();
1183        return statisticsDescriptorList = dd.getStatisticsDescriptors(this);
1184    }
1185
1186    /**
1187     * Are there statistics for this particular conglomerate.
1188     *
1189     * @param cd Conglomerate/Index for which we want to check if statistics
1190     * exist. cd can be null in which case user wants to know if there are any
1191     * statistics at all on the table.
1192     */

1193    public boolean statisticsExist(ConglomerateDescriptor cd)
1194        throws StandardException
1195    {
1196        List sdl = getStatistics();
1197
1198        if (cd == null)
1199            return (sdl.size() > 0);
1200
1201        UUID cdUUID = cd.getUUID();
1202
1203        for (Iterator JavaDoc li = sdl.iterator(); li.hasNext(); )
1204        {
1205            StatisticsDescriptor statDesc = (StatisticsDescriptor) li.next();
1206            if (cdUUID.equals(statDesc.getReferenceID()))
1207                return true;
1208
1209        }
1210
1211        return false;
1212    }
1213
1214    /**
1215     * For this conglomerate (index), return the selectivity of the first
1216     * numKeys. This basically returns the reciprocal of the number of unique
1217     * values in the leading numKey columns of the index. It is assumed that
1218     * statistics exist for the conglomerate if this function is called.
1219     *
1220     * @param cd ConglomerateDescriptor (Index) whose
1221     * cardinality we are interested in.
1222     * @param numKeys Number of leading columns of the index for which
1223     * cardinality is desired.
1224
1225     */

1226    public double selectivityForConglomerate(ConglomerateDescriptor cd,
1227                                             int numKeys)
1228        throws StandardException
1229    {
1230        if (!statisticsExist(cd))
1231        {
1232            if (SanityManager.DEBUG)
1233            {
1234                SanityManager.THROWASSERT("no statistics exist for conglomerate"
1235                                          + cd);
1236            }
1237            else
1238            {
1239                double selectivity = 0.1;
1240                for (int i = 0; i < numKeys; i++)
1241                    selectivity *= 0.1;
1242                return selectivity;
1243            }
1244        }
1245        
1246        UUID referenceUUID = cd.getUUID();
1247
1248        List sdl = getStatistics();
1249        for (Iterator JavaDoc li = sdl.iterator(); li.hasNext(); )
1250        {
1251            StatisticsDescriptor statDesc = (StatisticsDescriptor) li.next();
1252
1253            if (!referenceUUID.equals(statDesc.getReferenceID()))
1254                continue;
1255            
1256            if (statDesc.getColumnCount() != numKeys)
1257                continue;
1258            
1259            return statDesc.getStatistic().selectivity((Object JavaDoc[])null);
1260        }
1261        
1262        if (SanityManager.DEBUG)
1263            SanityManager.THROWASSERT("Internal Error-- statistics not found in selectivityForConglomerate.\n cd = " + cd + "\nnumKeys = " + numKeys);
1264        return 0.1; // shouldn't come here.
1265
}
1266
1267    /** @see TupleDescriptor#getDescriptorName */
1268    public String JavaDoc getDescriptorName() { return tableName; }
1269
1270    /** @see TupleDescriptor#getDescriptorType */
1271    public String JavaDoc getDescriptorType()
1272    {
1273        return (tableType == TableDescriptor.SYNONYM_TYPE) ? "Synonym" : "Table/View";
1274    }
1275}
1276
Popular Tags