"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 constraintEnabled;
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");
}
switch (constraintStateStr.charAt(0))
{
case 'E':
constraintEnabled = true;
break;
case 'D':
constraintEnabled = false;
break;
default:
constraintEnabled = true;
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,
false, //deferable,
false, //initiallyDeferred,
keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[],
constraintUUID,
((SubKeyConstraintDescriptor)
parentTupleDescriptor).getIndexId(),
schema,
constraintEnabled,
referenceCount);
break;
case DataDictionary.UNIQUE_CONSTRAINT :
constraintDesc = ddg.newUniqueConstraintDescriptor(
td,
constraintName,
false, //deferable,
false, //initiallyDeferred,
keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[],
constraintUUID,
((SubKeyConstraintDescriptor)
parentTupleDescriptor).getIndexId(),
schema,
constraintEnabled,
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,
false, //deferable,
false, //initiallyDeferred,
keyColumns,//genReferencedColumns(dd, td), //int referencedColumns[],
constraintUUID,
((SubKeyConstraintDescriptor)
parentTupleDescriptor).getIndexId(),
schema,
referencedConstraintId,
constraintEnabled,
((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,
false, //deferable,
false, //initiallyDeferred,
constraintUUID,