8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:03:03 +01:00

Don't allow to create primary key constraint on non-null fields with null values.

For example:

create table buggg (f1 int not null, f2 int not null);
commit;

insert into buggg values (1, 1)
commit;

alter table buggg add pk int not null primary key;
or
alter table buggg add constraint pk_buggg primary key (pk)
or
alter table buggg add constraint pk_buggg primary key (f1, f2, pk)
This commit is contained in:
hvlad 2005-10-26 15:11:51 +00:00
parent 9de0576587
commit 0216a3d2f5
3 changed files with 22 additions and 1 deletions

View File

@ -872,6 +872,7 @@ IDX_E BTR_key(thread_db* tdbb, jrd_rel* relation, Record* record, index_desc* id
IDX_E result = idx_e_ok;
index_desc::idx_repeat* tail = idx->idx_rpt;
key->key_flags = key_all_nulls;
key->key_null_segment = 0;
try {
@ -965,7 +966,9 @@ IDX_E BTR_key(thread_db* tdbb, jrd_rel* relation, Record* record, index_desc* id
const bool isNull =
!EVL_field(relation, record, tail->idx_field, desc_ptr);
if (isNull && (idx->idx_flags & idx_unique)) {
missing_unique_segments++;
if (missing_unique_segments++ == 0) {
key->key_null_segment = n;
}
}
if (!isNull) {
@ -1300,6 +1303,7 @@ IDX_E BTR_make_key(thread_db* tdbb,
IDX_E result = idx_e_ok;
key->key_flags = key_all_nulls;
key->key_null_segment = 0;
index_desc::idx_repeat* tail = idx->idx_rpt;

View File

@ -151,6 +151,10 @@ struct temporary_key {
USHORT key_length;
UCHAR key_data[MAX_KEY + 1];
UCHAR key_flags;
USHORT key_null_segment; // index of first encountered null segment.
// Evaluated in BTR_key only and used in IDX_create_index for better
// error diagnostics
/* AB: I don't see the use of multiplying with 2 anymore. */
//UCHAR key_data[MAX_KEY * 2];
// This needs to be on a SHORT boundary.

View File

@ -255,6 +255,7 @@ void IDX_create_index(
const bool isODS11 = (dbb->dbb_ods_version >= ODS_VERSION11);
const bool isDescending = (idx->idx_flags & idx_descending);
const bool isPrimary = (idx->idx_flags & idx_primary);
const USHORT key_length = ROUNDUP(BTR_key_length(tdbb, relation, idx), sizeof(SLONG));
@ -400,6 +401,18 @@ void IDX_create_index(
idx_null_state null_state;
BTR_key(tdbb, relation, record, idx, &key, &null_state, false);
key_is_null = (null_state == idx_nulls_all);
if (isPrimary && null_state != idx_nulls_none)
{
fb_assert(key.key_null_segment < idx->idx_count);
const USHORT bad_id = idx->idx_rpt[key.key_null_segment].idx_field;
const jrd_fld *bad_fld = MET_get_field(relation, bad_id);
ERR_post(isc_not_valid,
isc_arg_string, bad_fld->fld_name.c_str(),
isc_arg_string, "*** null ***", 0);
}
}
else {
do {