--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.sql.dictionary;\r
+\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.Provider;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.StatementType;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.catalog.DependableFinder;\r
+import org.apache.derby.catalog.Dependable;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+\r
+import org.apache.derby.iapi.services.uuid.UUIDFactory;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+/**\r
+ * The ConglomerateDescriptor class is used to get information about\r
+ * conglomerates for the purpose of optimization.\r
+ * \r
+ * A ConglomerateDescriptor can map to a base table, an index\r
+ * or a index backing a constraint. Multiple ConglomerateDescriptors\r
+ * can map to a single underlying store conglomerate, such as when\r
+ * multiple index definitions share a physical file.\r
+ *\r
+ * NOTE: The language module does not have to know much about conglomerates\r
+ * with this architecture. To get the cost of using a conglomerate, all it\r
+ * has to do is pass the ConglomerateDescriptor to the access methods, along\r
+ * with the predicate. What the access methods need from a\r
+ * ConglomerateDescriptor remains to be seen.\r
+ * \r
+ * \r
+ *\r
+ * @version 0.1\r
+ */\r
+\r
+public final class ConglomerateDescriptor extends TupleDescriptor\r
+ implements UniqueTupleDescriptor, Provider\r
+{\r
+ // Implementation\r
+ private long conglomerateNumber;\r
+ private String name;\r
+ private transient String[] columnNames;\r
+ private final boolean indexable;\r
+ private final boolean forConstraint;\r
+ private final IndexRowGenerator indexRowGenerator;\r
+ private final UUID uuid;\r
+ private final UUID tableID;\r
+ private final UUID schemaID;\r
+\r
+ /**\r
+ * Constructor for a conglomerate descriptor.\r
+ *\r
+ * @param dataDictionary The data dictionary that this descriptor lives in\r
+ * @param conglomerateNumber The number for the conglomerate\r
+ * we're interested in\r
+ * @param name The name of the conglomerate, if any\r
+ * @param indexable TRUE means the conglomerate is indexable,\r
+ * FALSE means it isn't\r
+ * @param indexRowGenerator The descriptor of the index if it's not a\r
+ * heap\r
+ * @param forConstraint TRUE means the conglomerate is an index backing up\r
+ * a constraint, FALSE means it isn't\r
+ * @param uuid UUID for this conglomerate\r
+ * @param tableID UUID for the table that this conglomerate belongs to\r
+ * @param schemaID UUID for the schema that this conglomerate belongs to\r
+ */\r
+ ConglomerateDescriptor(DataDictionary dataDictionary,\r
+ long conglomerateNumber,\r
+ String name,\r
+ boolean indexable,\r
+ IndexRowGenerator indexRowGenerator,\r
+ boolean forConstraint,\r
+ UUID uuid,\r
+ UUID tableID,\r
+ UUID schemaID)\r
+ {\r
+ super( dataDictionary );\r
+\r
+ this.conglomerateNumber = conglomerateNumber;\r
+ this.name = name;\r
+ this.indexable = indexable;\r
+ this.indexRowGenerator = indexRowGenerator;\r
+ this.forConstraint = forConstraint;\r
+ if (uuid == null)\r
+ {\r
+ UUIDFactory uuidFactory = Monitor.getMonitor().getUUIDFactory();\r
+ uuid = uuidFactory.createUUID();\r
+ }\r
+ this.uuid = uuid;\r
+ this.tableID = tableID;\r
+ this.schemaID = schemaID;\r
+ }\r
+\r
+ /**\r
+ * Gets the number for the conglomerate.\r
+ *\r
+ * @return A long identifier for the conglomerate\r
+ */\r
+ public long getConglomerateNumber()\r
+ {\r
+ return conglomerateNumber;\r
+ }\r
+\r
+ /**\r
+ * Set the conglomerate number.\r
+ * This is useful when swapping conglomerates, like for bulkInsert.\r
+ *\r
+ * @param conglomerateNumber The new conglomerate number.\r
+ */\r
+ public void setConglomerateNumber(long conglomerateNumber)\r
+ {\r
+ this.conglomerateNumber = conglomerateNumber;\r
+ }\r
+\r
+ /**\r
+ * Gets the UUID String for the conglomerate.\r
+ *\r
+ * @return The UUID String for the conglomerate\r
+ */\r
+ public UUID getUUID()\r
+ {\r
+ return uuid;\r
+ }\r
+\r
+ /**\r
+ * Gets the UUID for the table that the conglomerate belongs to.\r
+ *\r
+ * @return The UUID String for the conglomerate\r
+ */\r
+ public UUID getTableID()\r
+ {\r
+ return tableID;\r
+ }\r
+\r
+ /**\r
+ * Gets the UUID for the schema that the conglomerate belongs to.\r
+ *\r
+ * @return The UUID String for the schema that the conglomerate belongs to\r
+ */\r
+ public UUID getSchemaID()\r
+ {\r
+ return schemaID;\r
+ }\r
+\r
+ /**\r
+ * Tells whether the conglomerate can be used as an index.\r
+ *\r
+ * @return TRUE if the conglomerate can be used as an index, FALSE if not\r
+ */\r
+ public boolean isIndex()\r
+ {\r
+ return indexable;\r
+ }\r
+\r
+ /**\r
+ * Tells whether the conglomerate is an index backing up a constraint.\r
+ *\r
+ * @return TRUE if the conglomerate is an index backing up a constraint, FALSE if not\r
+ */\r
+ public boolean isConstraint()\r
+ {\r
+ return forConstraint;\r
+ }\r
+\r
+ /**\r
+ * Gets the name of the conglomerate. For heaps, this is null. For\r
+ * indexes, it is the index name.\r
+ *\r
+ * @return The name of the conglomerate, null if it's the heap for a table.\r
+ */\r
+ public String getConglomerateName()\r
+ {\r
+ return name;\r
+ }\r
+\r
+ /**\r
+ * Set the name of the conglomerate. Used only by rename index.\r
+ *\r
+ * @param newName The new name of the conglomerate.\r
+ */\r
+ public void setConglomerateName(String newName)\r
+ {\r
+ name = newName;\r
+ }\r
+\r
+ /**\r
+ * Gets the index row generator for this conglomerate, null if the\r
+ * conglomerate is not an index.\r
+ *\r
+ * @return The index descriptor for this conglomerate, if any.\r
+ */\r
+ public IndexRowGenerator getIndexDescriptor()\r
+ {\r
+ return indexRowGenerator;\r
+ }\r
+\r
+ /**\r
+ * Set the column names for this conglomerate descriptor.\r
+ * This is useful for tracing the optimizer.\r
+ *\r
+ * @param columnNames 0-based array of column names.\r
+ */\r
+ public void setColumnNames(String[] columnNames)\r
+ {\r
+ this.columnNames = columnNames;\r
+ }\r
+\r
+ /**\r
+ * Get the column names for this conglomerate descriptor.\r
+ * This is useful for tracing the optimizer.\r
+ *\r
+ * @return the column names for the conglomerate descriptor.\r
+ */\r
+ public String[] getColumnNames()\r
+ {\r
+ return columnNames;\r
+ }\r
+\r
+ //\r
+ // Provider interface\r
+ //\r
+\r
+ /** \r
+ @return the stored form of this provider\r
+ */\r
+ public DependableFinder getDependableFinder() \r
+ {\r
+ return getDependableFinder(StoredFormatIds.CONGLOMERATE_DESCRIPTOR_FINDER_V01_ID);\r
+ }\r
+\r
+ /**\r
+ * Return the name of this Provider. (Useful for errors.)\r
+ *\r
+ * @return String The name of this provider.\r
+ */\r
+ public String getObjectName()\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(name != null,\r
+ "ConglomerateDescriptor only expected to be provider for indexes");\r
+ }\r
+ return name;\r
+ }\r
+\r
+ /**\r
+ * Get the provider's UUID\r
+ *\r
+ * @return The provider's UUID\r
+ */\r
+ public UUID getObjectID()\r
+ {\r
+ return uuid;\r
+ }\r
+\r
+ /**\r
+ * Get the provider's type.\r
+ *\r
+ * @return char The provider's type.\r
+ */\r
+ public String getClassType()\r
+ {\r
+ if (indexable)\r
+ {\r
+ return Dependable.INDEX;\r
+ }\r
+ else\r
+ {\r
+ return Dependable.HEAP;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Convert the conglomerate descriptor to a String\r
+ *\r
+ * @return The conglomerate descriptor as a String\r
+ */\r
+\r
+ public String toString()\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ String keyString = "";\r
+\r
+ if (indexable && columnNames != null )\r
+ {\r
+ int[] keyColumns = indexRowGenerator.baseColumnPositions();\r
+\r
+ keyString = ", key columns = {" + columnNames[keyColumns[0] - 1];\r
+ for (int index = 1; index < keyColumns.length; index++)\r
+ {\r
+ keyString = keyString + ", " + columnNames[keyColumns[index] - 1];\r
+ }\r
+ keyString = keyString + "}";\r
+ }\r
+\r
+ return "ConglomerateDescriptor: conglomerateNumber = " + conglomerateNumber +\r
+ " name = " + name +\r
+ " uuid = " + uuid +\r
+ " indexable = " + indexable + keyString;\r
+ }\r
+ else\r
+ {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ /** @see TupleDescriptor#getDescriptorType */\r
+ public String getDescriptorType()\r
+ {\r
+ if (indexable)\r
+ return "Index";\r
+ else\r
+ return "Table";\r
+ }\r
+\r
+ /** @see TupleDescriptor#getDescriptorName */\r
+ public String getDescriptorName() { return name; }\r
+ \r
+ /**\r
+ * Drop this ConglomerateDescriptor when it represents\r
+ * an index. If this is the last desciptor for\r
+ * a physical index then the physical index (conglomerate)\r
+ * and its descriptor will be dropped.\r
+ * \r
+ * @param lcc\r
+ * @param td\r
+ * @throws StandardException\r
+ */\r
+ public void drop(LanguageConnectionContext lcc,\r
+ TableDescriptor td)\r
+ throws StandardException\r
+ { \r
+ DataDictionary dd = getDataDictionary();\r
+ DependencyManager dm = dd.getDependencyManager();\r
+ TransactionController tc = lcc.getTransactionExecute();\r
+ \r
+ // invalidate any prepared statements that\r
+ // depended on the index (including this one)\r
+ dm.invalidateFor(this, DependencyManager.DROP_INDEX, lcc);\r
+ \r
+ // only drop the conglomerate if no similar index but with different\r
+ // name. Get from dd in case we drop other dup indexes with a cascade operation \r
+ if (dd.getConglomerateDescriptors(getConglomerateNumber()).length == 1)\r
+ {\r
+ /* Drop statistics */\r
+ dd.dropStatisticsDescriptors(td.getUUID(), getUUID(), tc);\r
+ \r
+ /* Drop the conglomerate */\r
+ tc.dropConglomerate(getConglomerateNumber());\r
+ } \r
+ \r
+ /* Drop the conglomerate descriptor */\r
+ dd.dropConglomerateDescriptor(this, tc);\r
+ \r
+ /* \r
+ ** Remove the conglomerate descriptor from the list hanging off of the\r
+ ** table descriptor\r
+ */\r
+ td.removeConglomerateDescriptor(this);\r
+ }\r
+ \r
+}\r