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

Fixed SF #1475979: Dropping and recreating a table in the same txn disables PK.

This commit is contained in:
dimitr 2006-04-30 04:51:10 +00:00
parent 331843b213
commit b93f103c49
2 changed files with 32 additions and 40 deletions

View File

@ -2422,14 +2422,20 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
SET_TDBB(tdbb); SET_TDBB(tdbb);
const DeferredWork* arg = work->dfw_args;
while (arg && (arg->dfw_type != dfw_arg_index_name))
arg = arg->dfw_next;
fb_assert(arg);
switch (phase) switch (phase)
{ {
case 0: case 0:
relation = MET_lookup_relation(tdbb, work->dfw_name); relation = MET_lookup_relation_id(tdbb, work->dfw_id, false);
if (!relation) { if (!relation) {
return false; return false;
} }
id = work->dfw_id - 1; id = arg->dfw_id - 1;
index = CMP_get_index_lock(tdbb, relation, id); index = CMP_get_index_lock(tdbb, relation, id);
if (index) { if (index) {
if (!index->idl_count) { if (!index->idl_count) {
@ -2439,17 +2445,9 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
return false; return false;
case 1: case 1:
{
const DeferredWork* arg = work->dfw_args;
while (arg && (arg->dfw_type != dfw_arg_index_name))
arg = arg->dfw_next;
fb_assert(arg);
check_dependencies(tdbb, arg->dfw_name.c_str(), NULL, check_dependencies(tdbb, arg->dfw_name.c_str(), NULL,
obj_index, transaction); obj_index, transaction);
return true; return true;
}
case 2: case 2:
return true; return true;
@ -2458,14 +2456,14 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
/* Look up the relation. If we can't find the relation, /* Look up the relation. If we can't find the relation,
don't worry about the index. */ don't worry about the index. */
relation = MET_lookup_relation(tdbb, work->dfw_name); relation = MET_lookup_relation_id(tdbb, work->dfw_id, false);
if (!relation) { if (!relation) {
return false; return false;
} }
/* Make sure nobody is currently using the index */ /* Make sure nobody is currently using the index */
id = work->dfw_id - 1; id = arg->dfw_id - 1;
index = CMP_get_index_lock(tdbb, relation, id); index = CMP_get_index_lock(tdbb, relation, id);
if (index) if (index)
{ {
@ -2487,35 +2485,22 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
return true; return true;
case 4: case 4:
relation = MET_lookup_relation(tdbb, work->dfw_name); relation = MET_lookup_relation_id(tdbb, work->dfw_id, false);
if (!relation) { if (!relation) {
return false; return false;
} }
id = work->dfw_id - 1; id = arg->dfw_id - 1;
index = CMP_get_index_lock(tdbb, relation, id); index = CMP_get_index_lock(tdbb, relation, id);
IDX_delete_index(tdbb, relation, id); IDX_delete_index(tdbb, relation, id);
if (work->dfw_type == dfw_delete_expression_index) if (work->dfw_type == dfw_delete_expression_index)
{ {
// for expression index there are dependencies MET_delete_dependencies(tdbb, arg->dfw_name, obj_expression_index);
// therefore work->dfw_args was set in VIO_erase
// to let us know that expression index name
fb_assert(work->dfw_args);
const DeferredWork* arg = work->dfw_args;
while (arg && (arg->dfw_type != dfw_arg_index_name))
{
arg = arg->dfw_next;
}
fb_assert(arg);
MET_delete_dependencies(tdbb,
arg->dfw_name, obj_expression_index);
} }
// if index was bound to deleted FK constraint // if index was bound to deleted FK constraint
// then work->dfw_args was set in VIO_erase // then work->dfw_args was set in VIO_erase
const DeferredWork* arg = work->dfw_args; arg = work->dfw_args;
while (arg && (arg->dfw_type != dfw_arg_partner_rel_id)) while (arg && (arg->dfw_type != dfw_arg_partner_rel_id))
{ {
arg = arg->dfw_next; arg = arg->dfw_next;

View File

@ -1212,12 +1212,21 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
EVL_field(0, rpb->rpb_record, f_idx_id, &desc2); EVL_field(0, rpb->rpb_record, f_idx_id, &desc2);
if ( (id = MOV_get_long(&desc2, 0)) ) if ( (id = MOV_get_long(&desc2, 0)) )
{ {
if (EVL_field(0, rpb->rpb_record, f_idx_exp_blr, &desc2)) MOV_get_metadata_str(&desc, relation_name, sizeof(relation_name));
work = DFW_post_work(transaction, dfw_delete_expression_index, &desc, id); r2 = MET_lookup_relation(tdbb, relation_name);
else fb_assert(r2);
work = DFW_post_work(transaction, dfw_delete_index, &desc, id);
// add index name to correctly delete dependencies if (EVL_field(0, rpb->rpb_record, f_idx_exp_blr, &desc2)) {
work = DFW_post_work(transaction, dfw_delete_expression_index,
NULL, r2->rel_id);
}
else {
work = DFW_post_work(transaction, dfw_delete_index,
NULL, r2->rel_id);
}
// add index id and name (the latter is required
// to delete dependencies correctly)
DSC idx_name; DSC idx_name;
EVL_field(0, rpb->rpb_record, f_idx_name, &idx_name); EVL_field(0, rpb->rpb_record, f_idx_name, &idx_name);
DeferredWork* arg = DFW_post_work_arg(transaction, work, &idx_name, id); DeferredWork* arg = DFW_post_work_arg(transaction, work, &idx_name, id);
@ -1226,8 +1235,6 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
// get partner relation for FK index // get partner relation for FK index
if (EVL_field(0, rpb->rpb_record, f_idx_foreign, &desc2)) if (EVL_field(0, rpb->rpb_record, f_idx_foreign, &desc2))
{ {
MOV_get_metadata_str(&desc, relation_name, sizeof(relation_name));
DSC desc3; DSC desc3;
EVL_field(0, rpb->rpb_record, f_idx_name, &desc3); EVL_field(0, rpb->rpb_record, f_idx_name, &desc3);
@ -1237,12 +1244,12 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
jrd_rel *partner; jrd_rel *partner;
index_desc idx; index_desc idx;
if ((r2 = MET_lookup_relation(tdbb, relation_name)) && if ((BTR_lookup(tdbb, r2, id - 1, &idx) == FB_SUCCESS) &&
(BTR_lookup(tdbb, r2, id-1, &idx) == FB_SUCCESS) &&
(MET_lookup_partner(tdbb, r2, &idx, idx_name)) && (MET_lookup_partner(tdbb, r2, &idx, idx_name)) &&
(partner = MET_lookup_relation_id(tdbb, idx.idx_primary_relation, false)) ) (partner = MET_lookup_relation_id(tdbb, idx.idx_primary_relation, false)) )
{ {
DeferredWork* arg = DFW_post_work_arg(transaction, work, 0, partner->rel_id); DeferredWork* arg =
DFW_post_work_arg(transaction, work, 0, partner->rel_id);
arg->dfw_type = dfw_arg_partner_rel_id; arg->dfw_type = dfw_arg_partner_rel_id;
} }
else else