mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 02:03:04 +01:00
Fixed two DFW bugs
1. Unregistered FB2 bug - expression index dependencies was tracked not correctly. 2. SF #1250150
This commit is contained in:
parent
39da9e362f
commit
c104f1b23d
@ -167,9 +167,6 @@ static bool add_difference(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool delete_difference(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool begin_backup(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool end_backup(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static Lock* protect_relation(thread_db*, jrd_tra*, jrd_rel*, bool&);
|
||||
static void release_protect_lock(thread_db*, jrd_tra*, Lock*);
|
||||
static void check_partners(thread_db*, const USHORT);
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
@ -193,6 +190,10 @@ static void setup_trigger_details(thread_db*, jrd_rel*, blb*, trig_vec**, const
|
||||
const TEXT*, bool);
|
||||
static bool validate_text_type (thread_db*, const TemporaryField*);
|
||||
|
||||
static Lock* protect_relation(thread_db*, jrd_tra*, jrd_rel*, bool&);
|
||||
static void release_protect_lock(thread_db*, jrd_tra*, Lock*);
|
||||
static void check_partners(thread_db*, const USHORT);
|
||||
|
||||
static const UCHAR nonnull_validation_blr[] =
|
||||
{
|
||||
blr_version5,
|
||||
@ -213,6 +214,7 @@ static const deferred_task task_table[] =
|
||||
{ dfw_add_file, add_file },
|
||||
{ dfw_add_shadow, add_shadow },
|
||||
{ dfw_delete_index, delete_index },
|
||||
{ dfw_delete_expression_index, delete_index },
|
||||
{ dfw_delete_rfr, delete_rfr },
|
||||
{ dfw_delete_relation, delete_relation },
|
||||
{ dfw_delete_shadow, delete_shadow },
|
||||
@ -226,7 +228,6 @@ static const deferred_task task_table[] =
|
||||
#ifdef EXPRESSION_INDICES
|
||||
{ dfw_create_expression_index, PCMET_expression_index },
|
||||
#endif
|
||||
{ dfw_delete_expression_index, delete_index },
|
||||
{ dfw_grant, GRANT_privileges },
|
||||
{ dfw_create_trigger, create_trigger },
|
||||
{ dfw_delete_trigger, delete_trigger },
|
||||
@ -637,7 +638,7 @@ DeferredWork* DFW_post_work(jrd_tra* transaction, enum dfw_t type, const dsc* de
|
||||
}
|
||||
|
||||
|
||||
void DFW_post_work_arg( jrd_tra* transaction, DeferredWork* work, const dsc* desc,
|
||||
DeferredWork* DFW_post_work_arg( jrd_tra* transaction, DeferredWork* work, const dsc* desc,
|
||||
USHORT id)
|
||||
{
|
||||
/**************************************
|
||||
@ -651,7 +652,7 @@ void DFW_post_work_arg( jrd_tra* transaction, DeferredWork* work, const dsc* des
|
||||
*
|
||||
**************************************/
|
||||
|
||||
post_work(transaction,
|
||||
return post_work(transaction,
|
||||
work->dfw_sav_number,
|
||||
&work->dfw_args,
|
||||
work->dfw_type,
|
||||
@ -2443,18 +2444,36 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
IDX_delete_index(tdbb, relation, id);
|
||||
if (work->dfw_type == dfw_delete_expression_index)
|
||||
{
|
||||
// for expression index there are dependincies
|
||||
// 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,
|
||||
work->dfw_name,
|
||||
arg->dfw_name,
|
||||
obj_expression_index);
|
||||
}
|
||||
|
||||
// if index was bound to deleted FK constraint
|
||||
// then work->dfw_args was set in VIO_erase
|
||||
if (work->dfw_args) {
|
||||
if (work->dfw_args->dfw_id) {
|
||||
const DeferredWork* arg = work->dfw_args;
|
||||
while(arg && (arg->dfw_type != dfw_arg_partner_rel_id))
|
||||
{
|
||||
arg = arg->dfw_next;
|
||||
}
|
||||
|
||||
if (arg) {
|
||||
if (arg->dfw_id) {
|
||||
check_partners(tdbb, relation->rel_id);
|
||||
if (relation->rel_id != work->dfw_args->dfw_id) {
|
||||
check_partners(tdbb, work->dfw_args->dfw_id);
|
||||
if (relation->rel_id != arg->dfw_id) {
|
||||
check_partners(tdbb, arg->dfw_id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -3136,7 +3155,7 @@ static bool find_depend_in_dfw( thread_db* tdbb,
|
||||
dfw_type = dfw_delete_procedure;
|
||||
break;
|
||||
case obj_expression_index:
|
||||
dfw_type = dfw_delete_index;
|
||||
dfw_type = dfw_delete_expression_index;
|
||||
break;
|
||||
default:
|
||||
fb_assert(false);
|
||||
@ -3154,6 +3173,21 @@ static bool find_depend_in_dfw( thread_db* tdbb,
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (work->dfw_type == dfw_type &&
|
||||
dfw_type == dfw_delete_expression_index)
|
||||
{
|
||||
const DeferredWork* arg = work->dfw_args;
|
||||
while (arg)
|
||||
{
|
||||
if (arg->dfw_type == dfw_arg_index_name &&
|
||||
arg->dfw_name == object_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
arg = arg->dfw_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dfw_type == dfw_delete_global)
|
||||
|
@ -31,7 +31,7 @@ void DFW_perform_system_work(void);
|
||||
void DFW_perform_work(Jrd::jrd_tra*);
|
||||
void DFW_perform_post_commit_work(Jrd::jrd_tra*);
|
||||
Jrd::DeferredWork* DFW_post_work(Jrd::jrd_tra*, enum Jrd::dfw_t, const dsc*, USHORT);
|
||||
void DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const dsc*, USHORT);
|
||||
Jrd::DeferredWork* DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const dsc*, USHORT);
|
||||
void DFW_update_index(const TEXT*, USHORT, const Jrd::SelectivityList&);
|
||||
|
||||
#endif // JRD_DFW_PROTO_H
|
||||
|
@ -244,7 +244,12 @@ enum dfw_t {
|
||||
dfw_add_difference,
|
||||
dfw_delete_difference,
|
||||
dfw_begin_backup,
|
||||
dfw_end_backup
|
||||
dfw_end_backup,
|
||||
|
||||
// deffered works argument types
|
||||
dfw_arg_index_name, // index name for dfw_delete_expression_index, mandatory
|
||||
dfw_arg_partner_rel_id, // partner relation id for dfw_delete_index if index is FK, optional
|
||||
dfw_arg_proc_name // procedure name for dfw_delete_prm, mandatory
|
||||
};
|
||||
|
||||
class DeferredWork : public pool_alloc<type_dfw>
|
||||
|
@ -1327,6 +1327,12 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
{
|
||||
work = DFW_post_work(transaction, dfw_delete_expression_index,
|
||||
&desc, id);
|
||||
|
||||
// add expression index name to correctly delete dependencies
|
||||
DSC idx_name;
|
||||
EVL_field(0, rpb->rpb_record, f_idx_name, &idx_name);
|
||||
DeferredWork* arg = DFW_post_work_arg(transaction, work, &idx_name, id);
|
||||
arg->dfw_type = dfw_arg_index_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1353,12 +1359,14 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
(MET_lookup_partner(tdbb, r2, &idx, idx_name)) &&
|
||||
(partner = MET_lookup_relation_id(tdbb, idx.idx_primary_relation, false)) )
|
||||
{
|
||||
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;
|
||||
}
|
||||
else { // can't find partner relation - impossible ?
|
||||
// add empty argument to let DFW know dropping
|
||||
// index was bound with FK
|
||||
DFW_post_work_arg(transaction, work, 0, 0);
|
||||
DeferredWork* arg = DFW_post_work_arg(transaction, work, 0, 0);
|
||||
arg->dfw_type = dfw_arg_partner_rel_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1385,8 +1393,13 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
MOV_get_metadata_str(&desc, procedure_name, sizeof(procedure_name));
|
||||
if ( (procedure = MET_lookup_procedure(tdbb, procedure_name, true)) )
|
||||
{
|
||||
DFW_post_work(transaction, dfw_delete_prm, &desc2,
|
||||
work = DFW_post_work(transaction, dfw_delete_prm, &desc2,
|
||||
procedure->prc_id);
|
||||
|
||||
// procedure name to track parameter dependencies
|
||||
DeferredWork* arg = DFW_post_work_arg(transaction, work, &desc,
|
||||
procedure->prc_id);
|
||||
arg->dfw_type = dfw_arg_proc_name;
|
||||
}
|
||||
EVL_field(0, rpb->rpb_record, f_prm_sname, &desc2);
|
||||
DFW_post_work(transaction, dfw_delete_global, &desc2, 0);
|
||||
@ -3826,13 +3839,13 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
|
||||
Express interest in the relation to prevent it from being deleted
|
||||
out from under us while garbage collection is in-progress. */
|
||||
|
||||
//hvlad: skip system relations
|
||||
vec* vector = dbb->dbb_relations;
|
||||
for (ULONG id = 0; vector && id < vector->count(); ++id) {
|
||||
relation = (jrd_rel*) (*vector)[id];
|
||||
RelationGarbage *relGarbage =
|
||||
relation ? (RelationGarbage*)relation->rel_garbage : NULL;
|
||||
|
||||
//hvlad: skip system relations
|
||||
if (relation && (relation->rel_gc_bitmap || relGarbage) &&
|
||||
!(relation->rel_flags & (REL_deleted | REL_deleting | REL_system)))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user