--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.catalog.DD_Version\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.impl.sql.catalog;\r
+\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.types.RowLocation;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.store.access.ConglomerateController;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;\r
+import org.apache.derby.iapi.store.access.ScanController;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.ExecIndexRow;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.services.info.ProductGenusNames;\r
+import org.apache.derby.iapi.services.info.ProductVersionHolder;\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.reference.Limits;\r
+import org.apache.derby.iapi.util.IdUtil;\r
+\r
+import org.apache.derby.iapi.services.uuid.UUIDFactory;\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.catalog.types.RoutineAliasInfo;\r
+import org.apache.derby.catalog.AliasInfo;\r
+import org.apache.derby.catalog.TypeDescriptor;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import java.io.IOException;\r
+import java.io.ObjectInput;\r
+import java.io.ObjectOutput;\r
+import java.sql.Types;\r
+import java.util.Enumeration;\r
+import java.util.Properties;\r
+\r
+/**\r
+ * Generic code for upgrading data dictionaries.\r
+ * Currently has all minor version upgrade logic.\r
+ * <p>\r
+ * A word about minor vs. major upgraded. Minor\r
+ * upgrades must be backwards/forwards compatible.\r
+ * So they cannot version classes or introduce new\r
+ * classes. Major releases are only backwards compatible;\r
+ * they will run against an old database, but not the\r
+ * other way around. So they can introduce new classes,\r
+ * etc.\r
+ *\r
+ */\r
+\r
+public class DD_Version implements Formatable\r
+{\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // STATE\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ private transient DataDictionaryImpl bootingDictionary;\r
+\r
+ int majorVersionNumber;\r
+ private int minorVersionNumber;\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // CONSTRUCTORS\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Public niladic constructor needed for Formatable interface.\r
+ */\r
+ public DD_Version() {}\r
+\r
+\r
+ /**\r
+ * Construct a Version for the currently booting data dictionary.\r
+ * The minor version is set by the subclass.\r
+ *\r
+ * @param bootingDictionary The booting dictionary that needs to be upgraded.\r
+ */\r
+ DD_Version( DataDictionaryImpl bootingDictionary, int majorVersionNumber)\r
+ {\r
+ this.majorVersionNumber = majorVersionNumber;\r
+ this.minorVersionNumber = getJBMSMinorVersionNumber();\r
+ this.bootingDictionary = bootingDictionary;\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // OVERRIDE OBJECT METHODS\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Stringify this Version.\r
+ *\r
+ * @return String representation of this Version.\r
+ */\r
+ public String toString()\r
+ {\r
+ return DD_Version.majorToString(majorVersionNumber);\r
+ }\r
+\r
+ private static String majorToString(int majorVersionNumber) {\r
+ switch (majorVersionNumber) {\r
+ case DataDictionary.DD_VERSION_CS_5_0:\r
+ return "5.0";\r
+ case DataDictionary.DD_VERSION_CS_5_1:\r
+ return "5.1";\r
+ case DataDictionary.DD_VERSION_CS_5_2:\r
+ return "5.2";\r
+ case DataDictionary.DD_VERSION_CS_8_1:\r
+ return "8.1";\r
+ case DataDictionary.DD_VERSION_CS_10_0:\r
+ return "10.0";\r
+ case DataDictionary.DD_VERSION_DERBY_10_1:\r
+ return "10.1";\r
+ case DataDictionary.DD_VERSION_DERBY_10_2:\r
+ return "10.2";\r
+ case DataDictionary.DD_VERSION_DERBY_10_3:\r
+ return "10.3";\r
+ default:\r
+ return null;\r
+ }\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // DataDictionary SPECIFIC\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Upgrade the data dictionary catalogs to the version represented by this\r
+ * DD_Version.\r
+ *\r
+ * @param dictionaryVersion the version of the data dictionary tables.\r
+ * @exception StandardException Ooops\r
+ */\r
+ void upgradeIfNeeded(DD_Version dictionaryVersion,\r
+ TransactionController tc, Properties startParams)\r
+ throws StandardException\r
+ {\r
+ // database has been upgrade with a later engine version than this?\r
+ if (dictionaryVersion.majorVersionNumber > majorVersionNumber) {\r
+ throw StandardException.newException(SQLState.LANG_CANT_UPGRADE_CATALOGS, \r
+ dictionaryVersion, this);\r
+ }\r
+\r
+\r
+ boolean minorOnly = false;\r
+ boolean performMajorUpgrade = false;\r
+ boolean softUpgradeRun = false;\r
+ boolean isReadOnly = bootingDictionary.af.isReadOnly(); \r
+\r
+ if (dictionaryVersion.majorVersionNumber == majorVersionNumber) {\r
+\r
+ // exact match of engine to database, do nothing.\r
+ if (dictionaryVersion.minorVersionNumber == minorVersionNumber)\r
+ return;\r
+\r
+ // database and engine at same major level\r
+ minorOnly = true;\r
+\r
+ } else {\r
+ \r
+ if (Monitor.isFullUpgrade(startParams, dictionaryVersion.toString())) {\r
+ performMajorUpgrade = true;\r
+ } else {\r
+ softUpgradeRun = true;\r
+ }\r
+ }\r
+\r
+ // make sure we have a clean transaction for the upgrade\r
+ tc.commit();\r
+\r
+ if (performMajorUpgrade) {\r
+ // real upgrade changes. Get user name of current user.\r
+ String userName = IdUtil.getUserNameFromURLProps(startParams);\r
+ doFullUpgrade(tc, dictionaryVersion.majorVersionNumber,IdUtil.getUserAuthorizationId(userName));\r
+ }\r
+\r
+ if (!minorOnly && !isReadOnly) {\r
+ // apply changes that can be made and will continue to work\r
+ // against previous version.\r
+\r
+ // See if we have already applied these changes.\r
+ DD_Version softUpgradeVersion = (DD_Version) tc.getProperty(\r
+ DataDictionary.SOFT_DATA_DICTIONARY_VERSION);\r
+\r
+ // need to apply them if we have never performed a soft upgrade\r
+ // or only a soft upgrade using a previous version.\r
+ int softUpgradeMajorVersion = 0;\r
+ if (softUpgradeVersion != null)\r
+ softUpgradeMajorVersion = softUpgradeVersion.majorVersionNumber;\r
+\r
+ if (softUpgradeMajorVersion < majorVersionNumber) {\r
+ applySafeChanges( tc, dictionaryVersion.majorVersionNumber, softUpgradeMajorVersion);\r
+ }\r
+ }\r
+\r
+ // changes such as invalidating SPS so they will recompile against\r
+ // the new internal classes.\r
+ // this method also changes the on-disk format version on the disk and in-memory as well.\r
+ handleMinorRevisionChange(tc, dictionaryVersion, softUpgradeRun);\r
+\r
+ // commit any upgrade\r
+ tc.commit();\r
+ }\r
+\r
+ /**\r
+ Apply changes that can safely be made in soft upgrade.\r
+ Any changes must not prevent the database from being re-booted\r
+ by the a Derby engine at the older version fromMajorVersionNumber.\r
+ <BR>\r
+ Examples are fixes to catalog meta data, e.g. fix nullability of\r
+ a system column.\r
+\r
+ <BR>\r
+ <B>Upgrade items for 10.1</B>\r
+ <UL>\r
+ <LI> None.\r
+ </UL>\r
+ *\r
+ * @param tc transaction controller\r
+ * @param fromMajorVersionNumber version of the on-disk database\r
+ @param lastSoftUpgradeVersion last engine to perform a soft upgrade that made changes.\r
+ *\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ private void applySafeChanges(TransactionController tc, int fromMajorVersionNumber, int lastSoftUpgradeVersion)\r
+ throws StandardException\r
+ {\r
+\r
+ /*\r
+ * OLD Cloudscape 5.1 upgrade code, Derby does not support\r
+ * upgrade from Cloudscape 5.x databases. If it ever is changed\r
+ * to do so, this code would be useful.\r
+ * \r
+ * \r
+ if (lastSoftUpgradeVersion <= DataDictionary.DD_VERSION_CS_5_1)\r
+ {\r
+\r
+ // All these soft upgrade actions are new in 5.2 (first ever soft upgrade)\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_0)\r
+ modifySysTableNullability(tc,\r
+ DataDictionaryImpl.SYSALIASES_CATALOG_NUM);\r
+\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_1)\r
+ modifySysTableNullability(tc,\r
+ DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM);\r
+\r
+ }\r
+ */\r
+\r
+ /*\r
+ * Derby soft upgrade code\r
+ */\r
+ if (lastSoftUpgradeVersion <= DataDictionary.DD_VERSION_DERBY_10_2)\r
+ {\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_2)\r
+ {\r
+ modifySysTableNullability(tc,\r
+ DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM);\r
+ \r
+ modifySysTableNullability(tc,\r
+ DataDictionaryImpl.SYSVIEWS_CATALOG_NUM);\r
+ }\r
+ }\r
+ \r
+ tc.setProperty(DataDictionary.SOFT_DATA_DICTIONARY_VERSION, this, true);\r
+ }\r
+\r
+ /**\r
+ Do full upgrade. Apply changes that can NOT be safely made in soft upgrade.\r
+ \r
+ <BR>\r
+ <B>Upgrade items for every new release</B>\r
+ <UL>\r
+ <LI> Drop and recreate the stored versions of the JDBC database metadata queries\r
+ </UL>\r
+ \r
+ <BR>\r
+ <B>Upgrade items for 10.1</B>\r
+ <UL>\r
+ <LI> None.\r
+ </UL>\r
+ \r
+ *\r
+ * @param tc transaction controller\r
+ * @param fromMajorVersionNumber version of the on-disk database\r
+ * @param aid AuthorizationID of current user to be made Database Owner\r
+ *\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ private void doFullUpgrade(TransactionController tc, int fromMajorVersionNumber, String aid)\r
+ throws StandardException\r
+ {\r
+ // Only supports upgrade from Derby 10.0 releases onwards\r
+ if (fromMajorVersionNumber < DataDictionary.DD_VERSION_CS_10_0)\r
+ {\r
+ throw StandardException.newException(SQLState.UPGRADE_UNSUPPORTED,\r
+ DD_Version.majorToString(fromMajorVersionNumber), this); \r
+ }\r
+\r
+ //Drop and recreate the stored versions of the JDBC database metadata queries\r
+ //This is to make sure that we have the stored versions of JDBC database\r
+ //metadata queries matching with this release of the engine.\r
+ dropJDBCMetadataSPSes(tc, false);\r
+ bootingDictionary.createSystemSps(tc);\r
+\r
+ /*\r
+ * OLD Cloudscape 5.1 upgrade code, Derby does not support\r
+ * upgrade from Cloudscape 5.x databases. If it ever is changed\r
+ * to do so, this code would be useful.\r
+ \r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_CS_5_1)\r
+ {\r
+ // drop sps in SYSIBM, SYSIBM, recreate SYSIBM, SYSDUMMY1, populate SYSDUMMY1, create procs\r
+ dropJDBCMetadataSPSes(tc, true);\r
+ SchemaDescriptor sd = bootingDictionary.getSchemaDescriptor("SYSIBM", null, false);\r
+ if (sd != null)\r
+ bootingDictionary.dropSchemaDescriptor("SYSIBM", tc);\r
+ sd = bootingDictionary.getSysIBMSchemaDescriptor();\r
+ bootingDictionary.addDescriptor(sd, null, DataDictionary.SYSSCHEMAS_CATALOG_NUM, false, tc);\r
+ bootingDictionary.upgradeMakeCatalog(tc, DataDictionary.SYSDUMMY1_CATALOG_NUM);\r
+ bootingDictionary.populateSYSDUMMY1(tc);\r
+ bootingDictionary.create_SYSIBM_procedures(tc);\r
+ bootingDictionary.createSystemSps(tc);\r
+ }\r
+ \r
+ */\r
+\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_1)\r
+ {\r
+ // add catalogs 1st, subsequent procedure adding may depend on\r
+ // catalogs.\r
+\r
+ // Add new system catalogs created for grant and revoke\r
+ bootingDictionary.upgradeMakeCatalog(\r
+ tc, DataDictionary.SYSTABLEPERMS_CATALOG_NUM);\r
+ bootingDictionary.upgradeMakeCatalog(\r
+ tc, DataDictionary.SYSCOLPERMS_CATALOG_NUM);\r
+ bootingDictionary.upgradeMakeCatalog(\r
+ tc, DataDictionary.SYSROUTINEPERMS_CATALOG_NUM);\r
+ }\r
+\r
+ if (fromMajorVersionNumber == DataDictionary.DD_VERSION_CS_10_0)\r
+ {\r
+ // This upgrade depends on the SYSUTIL schema, which only exists\r
+ // since 10.0. Will not work to upgrade any db previous to 10.0,\r
+ // thus only checks for 10.0 rather than <= 10.0.\r
+ bootingDictionary.create_10_1_system_procedures(\r
+ tc, \r
+ bootingDictionary.getSystemUtilSchemaDescriptor().getUUID());\r
+ }\r
+\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_1)\r
+ {\r
+ // On ugrade from versions before 10.2, create system procedures\r
+ // added in 10.2.\r
+ bootingDictionary.create_10_2_system_procedures(\r
+ tc, \r
+ bootingDictionary.getSystemUtilSchemaDescriptor().getUUID());\r
+\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT((aid != null), \r
+ "Failed to get new Database Owner authorization");\r
+ }\r
+\r
+ // Change system schemas to be owned by aid\r
+ bootingDictionary.updateSystemSchemaAuthorization(aid, tc);\r
+ \r
+ // Grant PUBLIC access to some system routines\r
+ bootingDictionary.grantPublicAccessToSystemRoutines(tc, aid);\r
+ }\r
+\r
+ if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_2)\r
+ {\r
+ // On ugrade from versions before 10.3, create system procedures\r
+ // added in 10.3.\r
+ bootingDictionary.create_10_3_system_procedures(tc);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Do any work needed for a minor revision change.\r
+ * For the data dictionary this is always invalidating\r
+ * stored prepared statements. When we are done \r
+ * with the upgrade, we always recompile all SPSes\r
+ * so the customer doesn't have to (and isn't going\r
+ * to get deadlocks because of the recomp).\r
+ *\r
+ * @param tc the xact\r
+ *\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ private void handleMinorRevisionChange(TransactionController tc, DD_Version fromVersion, boolean softUpgradeRun) \r
+ throws StandardException\r
+ {\r
+ boolean isReadOnly = bootingDictionary.af.isReadOnly();\r
+\r
+ if (!isReadOnly) {\r
+ bootingDictionary.clearSPSPlans();\r
+\r
+ DD_Version lastRun;\r
+ \r
+ if (softUpgradeRun)\r
+ {\r
+ // log a version that will cause a minor revision change\r
+ // for any subsequent re-boot, including an old Cloudscape version\r
+ fromVersion.minorVersionNumber = 1; // see getJBMSMinorVersionNumber\r
+ lastRun = fromVersion;\r
+ }\r
+ else\r
+ {\r
+ // log the new version\r
+ lastRun = this;\r
+ \r
+ // and change the in-memory version.\r
+ fromVersion.majorVersionNumber = majorVersionNumber;\r
+ fromVersion.minorVersionNumber = minorVersionNumber;\r
+ }\r
+\r
+ tc.setProperty(DataDictionary.CORE_DATA_DICTIONARY_VERSION, fromVersion, true);\r
+ }\r
+ else\r
+ {\r
+ // For a readonly database where we need some kind of upgrade\r
+ // (either minor release or soft upgrade) then since we cannot\r
+ // invalidate all the procedures we need to indicate that\r
+ // any procedure we read off disk is automatically invalid,\r
+ // so we do not try to load the generated class.\r
+ bootingDictionary.readOnlyUpgrade = true;\r
+ }\r
+\r
+ bootingDictionary.clearCaches();\r
+ }\r
+\r
+ /**\r
+ * Drop all jdbc metadata spses. This\r
+ * it to ensure that we don't have any problems\r
+ * with old metadata queries that have outdated\r
+ * query text (the plans are always cleared out\r
+ * on upgrade time).\r
+ *\r
+ * @param tc the xact\r
+ * @param removeSYSIBMonly if <code>true</code>, remove stored\r
+ * prepared statements in the SYSIBM schema only; otherwise,\r
+ * remove stored prepared statements in all system schemas\r
+ * (including SYSIBM)\r
+ *\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ protected void dropJDBCMetadataSPSes(TransactionController tc, boolean removeSYSIBMonly)\r
+ throws StandardException\r
+ {\r
+ for (java.util.Iterator it = bootingDictionary.getAllSPSDescriptors().iterator(); it.hasNext(); )\r
+ {\r
+ SPSDescriptor spsd = (SPSDescriptor) it.next();\r
+ SchemaDescriptor sd = spsd.getSchemaDescriptor();\r
+ // need to compare the name, old SYSIBM is not built-in\r
+ boolean isSYSIBM = sd.getSchemaName().equals(SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME);\r
+\r
+ // don't drop statements in non-system schemas\r
+ if (!sd.isSystemSchema() && !isSYSIBM) {\r
+ continue;\r
+ }\r
+\r
+ // don't drop statements outside the SYSIBM schema if\r
+ // we're told not to\r
+ if (removeSYSIBMonly && !isSYSIBM) {\r
+ continue;\r
+ }\r
+\r
+ bootingDictionary.dropSPSDescriptor(spsd, tc);\r
+ bootingDictionary.dropDependentsStoredDependencies(spsd.getUUID(),\r
+ tc);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Make a catalog.\r
+ * @param tc TransactionController\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ protected void makeSystemCatalog(TransactionController tc,\r
+ TabInfoImpl ti)\r
+ throws StandardException\r
+ {\r
+ SchemaDescriptor sd = bootingDictionary.getSystemSchemaDescriptor();\r
+ bootingDictionary.makeCatalog(ti,sd,tc);\r
+ }\r
+\r
+ /**\r
+ Remove the description of a System table from the data dictionary.\r
+ This does not delete the conglomerates that hold the catalog or\r
+ its indexes.\r
+ @param tc TransactionController\r
+ @param td Table descriptor for the catalog to drop. \r
+ @exception StandardException Standard Derby error policy.\r
+ */\r
+ protected void\r
+ dropSystemCatalogDescription(TransactionController tc, TableDescriptor td)\r
+ throws StandardException\r
+ {\r
+ /* Drop the columns */\r
+ bootingDictionary.dropAllColumnDescriptors(td.getUUID(), tc);\r
+\r
+ /* Drop the conglomerate descriptors */\r
+ bootingDictionary.dropAllConglomerateDescriptors(td, tc);\r
+\r
+ /* Drop table descriptor */\r
+ bootingDictionary.dropTableDescriptor( td, td.getSchemaDescriptor(), tc );\r
+ bootingDictionary.clearCaches();\r
+ }\r
+\r
+ /**\r
+ * Drop a System catalog.\r
+ * @param tc TransactionController\r
+ * @param crf CatalogRowFactory for the catalog to drop.\r
+ * @exception StandardException Standard Derby error policy.\r
+ */\r
+ protected void dropSystemCatalog(TransactionController tc,\r
+ CatalogRowFactory crf)\r
+ throws StandardException\r
+ {\r
+ SchemaDescriptor sd = bootingDictionary.getSystemSchemaDescriptor();\r
+ TableDescriptor td = bootingDictionary.getTableDescriptor(\r
+ crf.getCatalogName(),\r
+ sd);\r
+ ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();\r
+ for (int index = 0; index < cds.length; index++)\r
+ {\r
+ tc.dropConglomerate(cds[index].getConglomerateNumber());\r
+ }\r
+ dropSystemCatalogDescription(tc,td);\r
+ }\r
+\r
+\r
+ /**\r
+ * Populates a new system index from the base system table.\r
+ *\r
+ * @param tc transaction controller\r
+ * @param heapConglomerateNumber identifies system table to Store\r
+ * @param tabInfo describes base system table\r
+ * @param indexNumber index to populate\r
+ *\r
+ *\r
+ * @exception StandardException Thrown on failure\r
+ */\r
+ protected void fillIndex\r
+ (\r
+ TransactionController tc,\r
+ long heapConglomerateNumber,\r
+ TabInfoImpl tabInfo,\r
+ int indexNumber\r
+ )\r
+ throws StandardException\r
+ {\r
+ long indexConglomerateNumber = tabInfo.getIndexConglomerate( indexNumber );\r
+ IndexRowGenerator indexRowGenerator = tabInfo.getIndexRowGenerator( indexNumber );\r
+ CatalogRowFactory rowFactory = tabInfo.getCatalogRowFactory();\r
+ ExecRow heapRow = rowFactory.makeEmptyRow();\r
+ ExecIndexRow indexableRow = indexRowGenerator.getIndexRowTemplate();\r
+\r
+ ScanController heapScan =\r
+ tc.openScan(\r
+ heapConglomerateNumber, // conglomerate to open\r
+ false, // don't hold open across commit\r
+ 0, // for read\r
+ TransactionController.MODE_TABLE,\r
+ TransactionController.ISOLATION_REPEATABLE_READ,\r
+ (FormatableBitSet) null, // all fields as objects\r
+ null, // start position - first row\r
+ ScanController.GE, // startSearchOperation\r
+ null, //scanQualifier,\r
+ null, //stop position-through last row\r
+ ScanController.GT); // stopSearchOperation\r
+\r
+ RowLocation heapLocation = \r
+ heapScan.newRowLocationTemplate();\r
+\r
+ ConglomerateController indexController = \r
+ tc.openConglomerate( \r
+ indexConglomerateNumber, \r
+ false,\r
+ TransactionController.OPENMODE_FORUPDATE,\r
+ TransactionController.MODE_TABLE,\r
+ TransactionController.ISOLATION_REPEATABLE_READ);\r
+\r
+ while ( heapScan.fetchNext(heapRow.getRowArray()) )\r
+ {\r
+ heapScan.fetchLocation( heapLocation );\r
+\r
+ indexRowGenerator.getIndexRow( heapRow, heapLocation, indexableRow, (FormatableBitSet) null );\r
+\r
+ indexController.insert(indexableRow.getRowArray());\r
+ }\r
+\r
+ indexController.close();\r
+ heapScan.close();\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // FORMATABLE INTERFACE\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+ /**\r
+ * Get the formatID which corresponds to this class.\r
+ Map to the 5.0 version identifier so that 5.0 will understand\r
+ this object when we write it out in soft upgrade mode.\r
+ CS 5.0 will de-serialize it correctly.\r
+ When we are writing out a 5.1 version number we write out\r
+ the 5.1 version just to ensure no problems.\r
+ \r
+ *\r
+ * @return the formatID of this class\r
+ */\r
+ public int getTypeFormatId() {\r
+ return majorVersionNumber == DataDictionary.DD_VERSION_CS_5_1 ?\r
+ StoredFormatIds.DD_ARWEN_VERSION_ID : StoredFormatIds.DD_DB2J72_VERSION_ID;\r
+ }\r
+ /**\r
+ * Read this object from a stream of stored objects. Set\r
+ * the minor version. Ignore the major version. \r
+ *\r
+ * @param in read this.\r
+ *\r
+ * @exception IOException on error\r
+ */\r
+ public final void readExternal( ObjectInput in ) throws IOException\r
+ {\r
+ majorVersionNumber = in.readInt();\r
+ minorVersionNumber = in.readInt();\r
+ }\r
+\r
+ /**\r
+ * Write this object to a stream of stored objects. Write\r
+ * out the minor version which is bumped across minor release.\r
+ * Just to be safe, write out the major version too. This\r
+ * will allow us to do versioning of a specific Version impl\r
+ * in the future.\r
+ *\r
+ * @param out write bytes here.\r
+ *\r
+ * @exception IOException on error\r
+ */\r
+ public final void writeExternal( ObjectOutput out ) throws IOException\r
+ { \r
+ out.writeInt(majorVersionNumber);\r
+ out.writeInt(minorVersionNumber);\r
+ }\r
+ /**\r
+ * Get the minor version from the JBMS product minor version/maint version.\r
+ * Bumps it up by 1 if production, or 0 if beta to ensure\r
+ * minor upgrade across beta. Starts at 2 because of an\r
+ * old convention. We use this starting at 2 to allow soft upgrade to\r
+ * write a version of 1 with the old major number to ensure a minor upgrade\r
+ when reverting to an old version afer a soft upgrade. E.g run with 5.0.2,\r
+ then 5.2.1.1, then 5.0.2. Want to ensure 5.0.2 does the minor upgrade.\r
+ *\r
+ * @return the minor version\r
+\r
+ For 5.0 and 5.1 the minor number was calculated as\r
+\r
+ jbmsVersion.getMinorVersion()*100 +jbmsVersion.getMaintVersion() + (jbmsVersion.isBeta() ? 0 : 1) + 2\r
+\r
+ 5.0.22 => (0*100) + 22 + 2 = 24 - (5.0 has a unique major number)\r
+ 5.1.2 => (1*100) + 2 + 2 = 104 - (5.1 has a unique major number) \r
+\r
+\r
+ With the switch to the four part scheme in 5.2, the maint number now is in increments of one million,\r
+ thus the above scheme could lead to duplicate numbers. Note that the major number may not change\r
+ when the minor external release changes, e.g. 5.2 and 5.3 could share a DD_Version major number.\r
+\r
+ 5.2.1.100 => (2*100) + 1000100 + 2 = 1000302\r
+ 5.3.1.0 => (3*100) + 1000000 + 2 = 1000302\r
+\r
+ \r
+\r
+ */\r
+ private int getJBMSMinorVersionNumber() \r
+ {\r
+ ProductVersionHolder jbmsVersion = Monitor.getMonitor().getEngineVersion();\r
+\r
+ return jbmsVersion.getMinorVersion()*100 +jbmsVersion.getMaintVersion() + (jbmsVersion.isBeta() ? 0 : 1) + 2;\r
+ }\r
+ \r
+ /**\r
+ * \r
+ * Modifies the nullability of the system table corresponding\r
+ * to the received catalog number.\r
+ * \r
+ * @param tc TransactionController.\r
+ * @param catalogNum The catalog number corresponding\r
+ * to the table for which we will modify the nullability.\r
+ * \r
+ * OLD Cloudscape 5.1 upgrade code\r
+ * If this corresponds to SYSALIASES, then the nullability of\r
+ * the SYSALIASES.ALIASINFO column will be changed to true\r
+ * (Beetle 4430). If this corresponds to SYSSTATEMENTS,\r
+ * the nullability of the SYSSTATEMENTS.LASTCOMPILED\r
+ * column will be changed to true.\r
+ *\r
+ * Derby upgrade code\r
+ * If this corresponds to SYSSTATEMENTS, then the nullability of\r
+ * the SYSSTATEMENTS.COMPILATION_SCHEMAID column will \r
+ * be changed to true. If this corresponds to SYSVIEWS, the nullability\r
+ * of the SYSVIEWS.COMPILATION_SCHEMAID column will be changed to true.\r
+ * \r
+ * @exception StandardException Thrown on error\r
+ */\r
+ private void modifySysTableNullability(TransactionController tc, int catalogNum)\r
+ throws StandardException\r
+ { \r
+ TabInfoImpl ti = bootingDictionary.getNonCoreTIByNumber(catalogNum);\r
+ CatalogRowFactory rowFactory = ti.getCatalogRowFactory();\r
+ \r
+ if (catalogNum == DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM)\r
+ {\r
+ // SYSSTATEMENTS table ==> SYSSTATEMENTS_COMPILATION_SCHEMAID needs \r
+ // to be modified.\r
+ bootingDictionary.upgrade_setNullability(rowFactory,\r
+ SYSSTATEMENTSRowFactory.SYSSTATEMENTS_COMPILATION_SCHEMAID, \r
+ true, tc);\r
+ }\r
+ else if (catalogNum == DataDictionaryImpl.SYSVIEWS_CATALOG_NUM)\r
+ {\r
+ // SYSVIEWS table ==> SYSVIEWS_COMPILATION_SCHEMAID needs \r
+ // to be modified.\r
+ bootingDictionary.upgrade_setNullability(rowFactory,\r
+ SYSVIEWSRowFactory.SYSVIEWS_COMPILATION_SCHEMAID, \r
+ true, tc);\r
+ }\r
+ \r
+ /* OLD Cloudscape 5.1 upgrade code. See applySafeChanges(). \r
+ if (catalogNum == DataDictionaryImpl.SYSALIASES_CATALOG_NUM) {\r
+ // SYSALIASES table ==> ALIASINFO needs to be modified.\r
+ bootingDictionary.upgrade_setNullability(rowFactory,\r
+ SYSALIASESRowFactory.SYSALIASES_ALIASINFO, true, tc);\r
+ }\r
+ else if (catalogNum == DataDictionaryImpl.SYSSTATEMENTS_CATALOG_NUM) {\r
+ // SYSSTATEMENTS table ==> LASTCOMPILED needs to be modified.\r
+ bootingDictionary.upgrade_setNullability(rowFactory,\r
+ SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED, true, tc);\r
+ }\r
+ */ \r
+ \r
+ }\r
+\r
+ /**\r
+ Check to see if a database has been upgraded to the required\r
+ level in order to use a language feature.\r
+\r
+ @param requiredMajorVersion Data Dictionary major version\r
+ @param feature Non-null to throw an error, null to return the state of the version match.\r
+\r
+ @return True if the database has been upgraded to the required level, false otherwise.\r
+ */\r
+ boolean checkVersion(int requiredMajorVersion, String feature) throws StandardException {\r
+\r
+ if (majorVersionNumber < requiredMajorVersion) {\r
+\r
+ if (feature != null)\r
+ throw StandardException.newException(SQLState.LANG_STATEMENT_UPGRADE_REQUIRED, feature,\r
+ DD_Version.majorToString(majorVersionNumber),\r
+ DD_Version.majorToString(requiredMajorVersion));\r
+\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+}\r