| /* |
| |
| Derby - Class org.apache.derby.impl.sql.catalog.SYSCONSTRAINTSRowFactory |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| |
| package org.apache.derby.impl.sql.catalog; |
| |
| import java.sql.Types; |
| |
| import org.apache.derby.catalog.UUID; |
| import org.apache.derby.iapi.error.StandardException; |
| import org.apache.derby.shared.common.sanity.SanityManager; |
| import org.apache.derby.iapi.services.uuid.UUIDFactory; |
| import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory; |
| import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; |
| import org.apache.derby.iapi.sql.dictionary.DataDictionary; |
| import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.SubCheckConstraintDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.SubConstraintDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.SystemColumn; |
| import org.apache.derby.iapi.sql.dictionary.TableDescriptor; |
| import org.apache.derby.iapi.sql.dictionary.TupleDescriptor; |
| import org.apache.derby.iapi.sql.execute.ExecRow; |
| import org.apache.derby.iapi.sql.execute.ExecutionFactory; |
| import org.apache.derby.iapi.types.DataValueDescriptor; |
| import org.apache.derby.iapi.types.DataValueFactory; |
| import org.apache.derby.iapi.types.SQLChar; |
| import org.apache.derby.iapi.types.SQLInteger; |
| import org.apache.derby.iapi.types.SQLVarchar; |
| import org.apache.derby.impl.sql.compile.ConstraintDefinitionNode; |
| |
| /** |
| * Factory for creating a SYSCONTRAINTS row. |
| * |
| */ |
| |
| public class SYSCONSTRAINTSRowFactory extends CatalogRowFactory |
| { |
| private static final String TABLENAME_STRING = "SYSCONSTRAINTS"; |
| |
| protected static final int SYSCONSTRAINTS_COLUMN_COUNT = 7; |
| protected static final int SYSCONSTRAINTS_CONSTRAINTID = 1; |
| protected static final int SYSCONSTRAINTS_TABLEID = 2; |
| protected static final int SYSCONSTRAINTS_CONSTRAINTNAME = 3; |
| protected static final int SYSCONSTRAINTS_TYPE = 4; |
| protected static final int SYSCONSTRAINTS_SCHEMAID = 5; |
| public static final int SYSCONSTRAINTS_STATE = ConstraintDescriptor.SYSCONSTRAINTS_STATE_FIELD; |
| protected static final int SYSCONSTRAINTS_REFERENCECOUNT = 7; |
| |
| protected static final int SYSCONSTRAINTS_INDEX1_ID = 0; |
| protected static final int SYSCONSTRAINTS_INDEX2_ID = 1; |
| protected static final int SYSCONSTRAINTS_INDEX3_ID = 2; |
| |
| private static final boolean[] uniqueness = { |
| true, |
| true, |
| false |
| }; |
| |
| private static final int[][] indexColumnPositions = |
| { |
| {SYSCONSTRAINTS_CONSTRAINTID}, |
| {SYSCONSTRAINTS_CONSTRAINTNAME, SYSCONSTRAINTS_SCHEMAID}, |
| {SYSCONSTRAINTS_TABLEID} |
| }; |
| |
| private static final String[] uuids = |
| { |
| "8000002f-00d0-fd77-3ed8-000a0a0b1900" // catalog UUID |
| ,"80000036-00d0-fd77-3ed8-000a0a0b1900" // heap UUID |
| ,"80000031-00d0-fd77-3ed8-000a0a0b1900" // SYSCONSTRAINTS_INDEX1 |
| ,"80000033-00d0-fd77-3ed8-000a0a0b1900" // SYSCONSTRAINTS_INDEX2 |
| ,"80000035-00d0-fd77-3ed8-000a0a0b1900" // SYSCONSTRAINTS_INDEX3 |
| }; |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // CONSTRUCTORS |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| SYSCONSTRAINTSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf) |
| { |
| super(uuidf,ef,dvf); |
| initInfo(SYSCONSTRAINTS_COLUMN_COUNT, TABLENAME_STRING, |
| indexColumnPositions, uniqueness, uuids ); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // METHODS |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Make a SYSCONTRAINTS row |
| * |
| * @return Row suitable for inserting into SYSCONTRAINTS. |
| * |
| * @exception StandardException thrown on failure |
| */ |
| public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| ExecRow row; |
| int constraintIType; |
| UUID oid; |
| String constraintSType = null; |
| String constraintID = null; |
| String tableID = null; |
| String constraintName = null; |
| String schemaID = null; |
| |
| boolean deferrable = |
| ConstraintDefinitionNode.DEFERRABLE_DEFAULT; |
| boolean initiallyDeferred = |
| ConstraintDefinitionNode.INITIALLY_DEFERRED_DEFAULT; |
| boolean enforced = |
| ConstraintDefinitionNode.ENFORCED_DEFAULT; |
| |
| int referenceCount = 0; |
| |
| if (td != null) |
| { |
| ConstraintDescriptor constraint = (ConstraintDescriptor)td; |
| /* |
| ** We only allocate a new UUID if the descriptor doesn't already have one. |
| ** For descriptors replicated from a Source system, we already have an UUID. |
| */ |
| oid = constraint.getUUID(); |
| constraintID = oid.toString(); |
| |
| oid = constraint.getTableId(); |
| tableID = oid.toString(); |
| |
| constraintName = constraint.getConstraintName(); |
| |
| constraintIType = constraint.getConstraintType(); |
| switch (constraintIType) |
| { |
| case DataDictionary.PRIMARYKEY_CONSTRAINT: |
| constraintSType = "P"; |
| break; |
| |
| case DataDictionary.UNIQUE_CONSTRAINT: |
| constraintSType = "U"; |
| break; |
| |
| case DataDictionary.CHECK_CONSTRAINT: |
| constraintSType = "C"; |
| break; |
| |
| case DataDictionary.FOREIGNKEY_CONSTRAINT: |
| constraintSType = "F"; |
| break; |
| |
| default: |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.THROWASSERT("invalid constraint type"); |
| } |
| } |
| |
| schemaID = constraint.getSchemaDescriptor().getUUID().toString(); |
| |
| // constraint characteristics |
| deferrable = constraint.deferrable(); |
| initiallyDeferred = constraint.initiallyDeferred(); |
| enforced = constraint.enforced(); |
| |
| referenceCount = constraint.getReferenceCount(); |
| } |
| |
| /* Insert info into sysconstraints */ |
| |
| /* RESOLVE - It would be nice to require less knowledge about sysconstraints |
| * and have this be more table driven. |
| */ |
| |
| /* Build the row to insert */ |
| row = getExecutionFactory().getValueRow(SYSCONSTRAINTS_COLUMN_COUNT); |
| |
| /* 1st column is CONSTRAINTID (UUID - char(36)) */ |
| row.setColumn(SYSCONSTRAINTS_CONSTRAINTID, new SQLChar(constraintID)); |
| |
| /* 2nd column is TABLEID (UUID - char(36)) */ |
| row.setColumn(SYSCONSTRAINTS_TABLEID, new SQLChar(tableID)); |
| |
| /* 3rd column is NAME (varchar(128)) */ |
| row.setColumn(SYSCONSTRAINTS_CONSTRAINTNAME, new SQLVarchar(constraintName)); |
| |
| /* 4th column is TYPE (char(1)) */ |
| row.setColumn(SYSCONSTRAINTS_TYPE, new SQLChar(constraintSType)); |
| |
| /* 5th column is SCHEMAID (UUID - char(36)) */ |
| row.setColumn(SYSCONSTRAINTS_SCHEMAID, new SQLChar(schemaID)); |
| |
| /* 6th column is STATE (char(1)) */ |
| row.setColumn(SYSCONSTRAINTS_STATE, |
| new SQLChar(encodeCharacteristics(deferrable, initiallyDeferred, enforced))); |
| |
| /* 7th column is REFERENCED */ |
| row.setColumn(SYSCONSTRAINTS_REFERENCECOUNT, new SQLInteger(referenceCount)); |
| |
| return row; |
| } |
| |
| /* |
| * Encode the characteristics of the constraints into a single character. |
| * |
| * {deferrable, initiallyDeferred, enforced} -> 'e' |
| * {deferrable, initiallyDeferred, not enforced} -> 'd' |
| * {deferrable, immediate, enforced} -> 'i' |
| * {deferrable, immediate, not enforced} -> 'j' |
| * {not deferrable, immediate, enforced} -> 'E' |
| * {not deferrable, immediate, not enforced -> 'D' |
| * |
| * Other combinations are prohibited and not used. Note that the |
| * value 'E' is only value used prior to version 10.11, and as |
| * such upward compatibily since by default, constraints are {not |
| * deferrable, immediate, enforced}. |
| */ |
| private String encodeCharacteristics( |
| boolean deferrable, boolean initiallyDeferred, boolean enforced) { |
| char c; |
| |
| if (deferrable) { |
| if (initiallyDeferred) { |
| if (enforced) { |
| c = 'e'; // deferrable initially deferred enforced |
| } else { |
| c = 'd'; // deferrable initially deferred not enforced |
| } |
| } else { |
| if (enforced) { |
| c = 'i'; // deferrable initially immediate enforced |
| } else { |
| c = 'j'; // deferrable initially immediate not enforced |
| } |
| } |
| } else { |
| if (initiallyDeferred) { |
| if (SanityManager.DEBUG) { |
| SanityManager.NOTREACHED(); |
| } |
| c = 'E'; |
| } else { |
| if (enforced) { |
| c = 'E'; // not deferrable initially immediate enforced |
| } else { |
| c = 'D'; // not deferrable initially immediate not enforced |
| } |
| } |
| } |
| |
| return String.valueOf(c); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Make a ConstraintDescriptor out of a SYSCONSTRAINTS row |
| * |
| * @param row a SYSCONSTRAINTS row |
| * @param parentTupleDescriptor Subconstraint descriptor with auxiliary info. |
| * @param dd dataDictionary |
| * |
| * @exception StandardException thrown on failure |
| */ |
| public TupleDescriptor buildDescriptor( |
| ExecRow row, |
| TupleDescriptor parentTupleDescriptor, |
| DataDictionary dd ) |
| throws StandardException |
| { |
| ConstraintDescriptor constraintDesc = null; |
| |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT( |
| row.nColumns() == SYSCONSTRAINTS_COLUMN_COUNT, |
| "Wrong number of columns for a SYSCONSTRAINTS row"); |
| } |
| |
| DataValueDescriptor col; |
| ConglomerateDescriptor conglomDesc; |
| DataDescriptorGenerator ddg; |
| TableDescriptor td = null; |
| int constraintIType = -1; |
| int[] keyColumns = null; |
| UUID constraintUUID; |
| UUID schemaUUID; |
| UUID tableUUID; |
| UUID referencedConstraintId = null; |
| SchemaDescriptor schema; |
| String tableUUIDString; |
| String constraintName; |
| String constraintSType; |
| String constraintStateStr; |
| boolean deferrable = |
| ConstraintDefinitionNode.DEFERRABLE_DEFAULT; |
| boolean initiallyDeferred = |
| ConstraintDefinitionNode.INITIALLY_DEFERRED_DEFAULT; |
| boolean enforced = |
| ConstraintDefinitionNode.ENFORCED_DEFAULT; |
| int referenceCount; |
| String constraintUUIDString; |
| String schemaUUIDString; |
| SubConstraintDescriptor scd; |
| |
| if (SanityManager.DEBUG) |
| { |
| if (!(parentTupleDescriptor instanceof SubConstraintDescriptor)) |
| { |
| SanityManager.THROWASSERT( |
| "parentTupleDescriptor expected to be instanceof " + |
| "SubConstraintDescriptor, not " + |
| parentTupleDescriptor.getClass().getName()); |
| } |
| } |
| |
| scd = (SubConstraintDescriptor) parentTupleDescriptor; |
| |
| ddg = dd.getDataDescriptorGenerator(); |
| |
| /* 1st column is CONSTRAINTID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_CONSTRAINTID); |
| constraintUUIDString = col.getString(); |
| constraintUUID = getUUIDFactory().recreateUUID(constraintUUIDString); |
| |
| /* 2nd column is TABLEID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_TABLEID); |
| tableUUIDString = col.getString(); |
| tableUUID = getUUIDFactory().recreateUUID(tableUUIDString); |
| |
| /* Get the TableDescriptor. |
| * It may be cached in the SCD, |
| * otherwise we need to go to the |
| * DD. |
| */ |
| if (scd != null) |
| { |
| td = scd.getTableDescriptor(); |
| } |
| if (td == null) |
| { |
| td = dd.getTableDescriptor(tableUUID); |
| } |
| |
| /* 3rd column is NAME (varchar(128)) */ |
| col = row.getColumn(SYSCONSTRAINTS_CONSTRAINTNAME); |
| constraintName = col.getString(); |
| |
| /* 4th column is TYPE (char(1)) */ |
| col = row.getColumn(SYSCONSTRAINTS_TYPE); |
| constraintSType = col.getString(); |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(constraintSType.length() == 1, |
| "Fourth column type incorrect"); |
| } |
| |
| boolean typeSet = false; |
| switch (constraintSType.charAt(0)) |
| { |
| case 'P' : |
| constraintIType = DataDictionary.PRIMARYKEY_CONSTRAINT; |
| typeSet = true; |
| // fall through |
| |
| case 'U' : |
| if (! typeSet) |
| { |
| constraintIType = DataDictionary.UNIQUE_CONSTRAINT; |
| typeSet = true; |
| } |
| // fall through |
| |
| case 'F' : |
| if (! typeSet) |
| constraintIType = DataDictionary.FOREIGNKEY_CONSTRAINT; |
| if (SanityManager.DEBUG) |
| { |
| if (!(parentTupleDescriptor instanceof SubKeyConstraintDescriptor)) |
| { |
| SanityManager.THROWASSERT( |
| "parentTupleDescriptor expected to be instanceof " + |
| "SubKeyConstraintDescriptor, not " + |
| parentTupleDescriptor.getClass().getName()); |
| } |
| } |
| conglomDesc = td.getConglomerateDescriptor( |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getIndexId()); |
| /* Take care the rare case of conglomDesc being null. The |
| * reason is that our "td" is out of date. Another thread |
| * which was adding a constraint committed between the moment |
| * we got the table descriptor (conglomerate list) and the |
| * moment we scanned and got the constraint desc list. Since |
| * that thread just added a new row to SYSCONGLOMERATES, |
| * SYSCONSTRAINTS, etc. We wouldn't have wanted to lock the |
| * system tables just to prevent other threads from adding new |
| * rows. |
| */ |
| if (conglomDesc == null) |
| { |
| // we can't be getting td from cache because if we are |
| // here, we must have been in dd's ddl mode (that's why |
| // the ddl thread went through), we are not done yet, the |
| // dd ref count is not 0, hence it couldn't have turned |
| // into COMPILE_ONLY mode |
| td = dd.getTableDescriptor(tableUUID); |
| if (scd != null) |
| scd.setTableDescriptor(td); |
| // try again now |
| conglomDesc = td.getConglomerateDescriptor( |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getIndexId()); |
| } |
| |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(conglomDesc != null, |
| "conglomDesc is expected to be non-null for backing index"); |
| } |
| keyColumns = conglomDesc.getIndexDescriptor().baseColumnPositions(); |
| referencedConstraintId = ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getKeyConstraintId(); |
| keyColumns = conglomDesc.getIndexDescriptor().baseColumnPositions(); |
| break; |
| |
| case 'C' : |
| constraintIType = DataDictionary.CHECK_CONSTRAINT; |
| if (SanityManager.DEBUG) |
| { |
| if (!(parentTupleDescriptor instanceof SubCheckConstraintDescriptor)) |
| { |
| SanityManager.THROWASSERT("parentTupleDescriptor expected to be instanceof " + |
| "SubCheckConstraintDescriptor, not " + |
| parentTupleDescriptor.getClass().getName()); |
| } |
| } |
| break; |
| |
| default: |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.THROWASSERT("Fourth column value invalid"); |
| } |
| } |
| |
| /* 5th column is SCHEMAID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_SCHEMAID); |
| schemaUUIDString = col.getString(); |
| schemaUUID = getUUIDFactory().recreateUUID(schemaUUIDString); |
| |
| schema = dd.getSchemaDescriptor(schemaUUID, null); |
| |
| /* 6th column is STATE (char(1)) */ |
| col = row.getColumn(SYSCONSTRAINTS_STATE); |
| constraintStateStr = col.getString(); |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(constraintStateStr.length() == 1, |
| "Sixth column (state) type incorrect"); |
| } |
| |
| // Cf. the encoding description in javadoc for |
| // #encodeCharacteristics. |
| // |
| // This code is cloned by DB_Key.makeDeferredClauses(). |
| // |
| switch (constraintStateStr.charAt(0)) |
| { |
| case 'E': |
| deferrable = false; |
| initiallyDeferred = false; |
| enforced = true; |
| break; |
| case 'D': |
| deferrable = false; |
| initiallyDeferred = false; |
| enforced = false; |
| break; |
| case 'e': |
| deferrable = true; |
| initiallyDeferred = true; |
| enforced = true; |
| break; |
| case 'd': |
| deferrable = true; |
| initiallyDeferred = true; |
| enforced = false; |
| break; |
| case 'i': |
| deferrable = true; |
| initiallyDeferred = false; |
| enforced = true; |
| break; |
| case 'j': |
| deferrable = true; |
| initiallyDeferred = false; |
| enforced = false; |
| break; |
| default: |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.THROWASSERT("Invalidate state value '" |
| +constraintStateStr+ "' for constraint"); |
| } |
| } |
| |
| /* 7th column is REFERENCECOUNT, boolean */ |
| col = row.getColumn(SYSCONSTRAINTS_REFERENCECOUNT); |
| referenceCount = col.getInt(); |
| |
| /* now build and return the descriptor */ |
| |
| switch (constraintIType) |
| { |
| case DataDictionary.PRIMARYKEY_CONSTRAINT : |
| constraintDesc = ddg.newPrimaryKeyConstraintDescriptor( |
| td, |
| constraintName, |
| deferrable, |
| initiallyDeferred, |
| keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[], |
| constraintUUID, |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getIndexId(), |
| schema, |
| enforced, |
| referenceCount); |
| break; |
| |
| case DataDictionary.UNIQUE_CONSTRAINT : |
| constraintDesc = ddg.newUniqueConstraintDescriptor( |
| td, |
| constraintName, |
| deferrable, |
| initiallyDeferred, |
| keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[], |
| constraintUUID, |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getIndexId(), |
| schema, |
| enforced, |
| referenceCount); |
| break; |
| |
| case DataDictionary.FOREIGNKEY_CONSTRAINT : |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(referenceCount == 0, |
| "REFERENCECOUNT column is nonzero for fk constraint"); |
| } |
| |
| constraintDesc = ddg.newForeignKeyConstraintDescriptor( |
| td, |
| constraintName, |
| deferrable, |
| initiallyDeferred, |
| keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[], |
| constraintUUID, |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getIndexId(), |
| schema, |
| referencedConstraintId, |
| enforced, |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getRaDeleteRule(), |
| ((SubKeyConstraintDescriptor) |
| parentTupleDescriptor).getRaUpdateRule() |
| ); |
| break; |
| |
| case DataDictionary.CHECK_CONSTRAINT : |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(referenceCount == 0, |
| "REFERENCECOUNT column is nonzero for check constraint"); |
| } |
| |
| constraintDesc = ddg.newCheckConstraintDescriptor( |
| td, |
| constraintName, |
| deferrable, |
| initiallyDeferred, |
| constraintUUID, |
| ((SubCheckConstraintDescriptor) |
| parentTupleDescriptor).getConstraintText(), |
| ((SubCheckConstraintDescriptor) |
| parentTupleDescriptor).getReferencedColumnsDescriptor(), |
| schema, |
| enforced); |
| break; |
| } |
| return constraintDesc; |
| } |
| |
| /** |
| * Get the constraint ID of the row. |
| * |
| * @param row The row from sysconstraints |
| * |
| * @return UUID The constraint id |
| * |
| * @exception StandardException thrown on failure |
| */ |
| protected UUID getConstraintId(ExecRow row) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| String constraintUUIDString; |
| |
| /* 1st column is CONSTRAINTID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_CONSTRAINTID); |
| constraintUUIDString = col.getString(); |
| return getUUIDFactory().recreateUUID(constraintUUIDString); |
| } |
| |
| /** |
| * Get the constraint name of the row. |
| * |
| * @param row The row from sysconstraints |
| * |
| * @return UUID The constraint name |
| * |
| * @exception StandardException thrown on failure |
| */ |
| protected String getConstraintName(ExecRow row) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| String constraintName; |
| |
| /* 3rd column is CONSTRAINTNAME (char(128)) */ |
| col = row.getColumn(SYSCONSTRAINTS_CONSTRAINTNAME); |
| constraintName = col.getString(); |
| return constraintName; |
| } |
| |
| /** |
| * Get the schema ID of the row. |
| * |
| * @param row The row from sysconstraints |
| * |
| * @return UUID The schema |
| * |
| * @exception StandardException thrown on failure |
| */ |
| protected UUID getSchemaId(ExecRow row) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| String schemaUUIDString; |
| |
| /* 5th column is SCHEMAID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_SCHEMAID); |
| schemaUUIDString =col.getString(); |
| return getUUIDFactory().recreateUUID(schemaUUIDString); |
| } |
| |
| /** |
| * Get the table ID of the row. |
| * |
| * @param row The row from sysconstraints |
| * |
| * @return UUID The table id |
| * |
| * @exception StandardException thrown on failure |
| */ |
| protected UUID getTableId(ExecRow row) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| String tableUUIDString; |
| |
| /* 2nd column is TABLEID (UUID - char(36)) */ |
| col = row.getColumn(SYSCONSTRAINTS_TABLEID); |
| tableUUIDString = col.getString(); |
| return getUUIDFactory().recreateUUID(tableUUIDString); |
| } |
| |
| /** |
| * Get the constraint type out of the row. |
| * |
| * @param row The row from sysconstraints |
| * |
| * @return int The constraint type as an int |
| * |
| * @exception StandardException thrown on failure |
| */ |
| protected int getConstraintType(ExecRow row) |
| throws StandardException |
| { |
| DataValueDescriptor col; |
| int constraintIType; |
| String constraintSType; |
| |
| /* 4th column is TYPE (char(1)) */ |
| col = row.getColumn(SYSCONSTRAINTS_TYPE); |
| constraintSType = col.getString(); |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.ASSERT(constraintSType.length() == 1, |
| "Fourth column type incorrect"); |
| } |
| |
| switch (constraintSType.charAt(0)) |
| { |
| case 'P' : |
| constraintIType = DataDictionary.PRIMARYKEY_CONSTRAINT; |
| break; |
| |
| case 'U' : |
| constraintIType = DataDictionary.UNIQUE_CONSTRAINT; |
| break; |
| |
| case 'C' : |
| constraintIType = DataDictionary.CHECK_CONSTRAINT; |
| break; |
| |
| case 'F' : |
| constraintIType = DataDictionary.FOREIGNKEY_CONSTRAINT; |
| break; |
| |
| default: |
| if (SanityManager.DEBUG) |
| { |
| SanityManager.THROWASSERT("Fourth column value invalid"); |
| } |
| constraintIType = -1; |
| } |
| |
| return constraintIType; |
| } |
| |
| /** |
| * Builds a list of columns suitable for creating this Catalog. |
| * |
| * |
| * @return array of SystemColumn suitable for making this catalog. |
| */ |
| public SystemColumn[] buildColumnList() |
| { |
| return new SystemColumn[] { |
| SystemColumnImpl.getUUIDColumn("CONSTRAINTID", false), |
| SystemColumnImpl.getUUIDColumn("TABLEID", false), |
| SystemColumnImpl.getIdentifierColumn("CONSTRAINTNAME", false), |
| SystemColumnImpl.getIndicatorColumn("TYPE"), |
| SystemColumnImpl.getUUIDColumn("SCHEMAID", false), |
| SystemColumnImpl.getIndicatorColumn("STATE"), |
| SystemColumnImpl.getColumn("REFERENCECOUNT", Types.INTEGER, false) |
| }; |
| } |
| |
| } |