Comment 4 for bug 1329443

Revision history for this message
Roberta Marton (roberta-marton) wrote :

Encountered a similar problem while testing grant and revoke with referential integrity constraints.
Here is some background on the problem and what was observed:

An RI constraint is a relationship between a set of columns on one table with a set of columns on another table. Each set of columns must be defined as an unique constraint (which include primary key constraints).
Relationships are stored through the constraints not their underlying tables.

 for example:

      create table dept (dept_no int not null primary key, ... );
      create table empl (empl_no int not null primary key, dept_no int, ... );
      alter table empl add constraint empl_dept foreign key references dept;

 empl_dept is the name of the RI constraint
 during the alter table empl request, a unique constraint is silently added

Now:

empl - has three constraints
  primary key constraint
  unique constraint on dept_no
  referential constraint called empl_dept

dept - has one constraint
   primary key constraint on dept_no

What is observed is that the system defined unique constraint automatically defined on the referencing table (empl) is missing.
That is, the REF_CONSTRAINTS and UNIQUE_REF_CONSTR_USAGE tables contain the references between empl & dept but the corresponding constraint identified by the UNIQUE_CONTRAINT_UID is not longer defined in the metadata (TABLE_CONSTRAINTS and OBJECTS).

The method CmpSeabaseDDL::getSeabaseSequenceDesc reads the metadata to get relationship information:

select trim(O.catalog_name || '.' || '\"' ||
            O.schema_name || '\"' || '.' || '\"' ||
            O.object_name || '\"' ) constr_name,
       trim(O2.catalog_name || '.' || '\"' ||
            O2.schema_name || '\"' || '.' || '\"' ||
            O2.object_name || '\"' ) table_name
  from TRAFODION."_MD_".REF_CONSTRAINTS R,
       TRAFODION."_MD_".OBJECTS O,
       TRAFODION."_MD_".OBJECTS O2,
       TRAFODION."_MD_".TABLE_CONSTRAINTS T
  where O.object_uid = R.unique_constraint_uid and
         O2.object_uid = T.table_uid and
         T.constraint_uid = R.unique_constraint_uid and
         R.ref_constraint_uid = <uid of ref_constraint, e.g. empl_dept>

This query returns the table name (dept) and constraint name (dept's primary key) that the empl table references.
But since the metadata is missing from TABLE_CONSTRAINTS for the empl's unique constraint, this query returns no rows. Therefore data is not set up in the descriptor structure (it is NULL). Later when code references this data, a core file is generated - accessing a NULL pointer.

The code in CmpSeabaseDDL::getSeabaseSequenceDesc should check to see if any rows are returned. If not, an internal error should be generated. It would be good to support a cleanup option for drop table to handle this issue and similar issues going forward.

Will continue to see how the metadata got in this state in the first place ...