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:
parent
331843b213
commit
b93f103c49
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user