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 ...
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. 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).
That is, the REF_CONSTRAINTS and UNIQUE_
The method CmpSeabaseDDL: :getSeabaseSequ enceDesc 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 "_MD_". REF_CONSTRAINTS R,
TRAFODION. "_MD_". OBJECTS O,
TRAFODION. "_MD_". OBJECTS O2,
TRAFODION. "_MD_". TABLE_CONSTRAIN TS T 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>
from TRAFODION.
where O.object_uid = R.unique_
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: :getSeabaseSequ enceDesc 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 ...