mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 07:23: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 delete_difference(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||||
static bool begin_backup(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 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);
|
const TEXT*, bool);
|
||||||
static bool validate_text_type (thread_db*, const TemporaryField*);
|
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[] =
|
static const UCHAR nonnull_validation_blr[] =
|
||||||
{
|
{
|
||||||
blr_version5,
|
blr_version5,
|
||||||
@ -213,6 +214,7 @@ static const deferred_task task_table[] =
|
|||||||
{ dfw_add_file, add_file },
|
{ dfw_add_file, add_file },
|
||||||
{ dfw_add_shadow, add_shadow },
|
{ dfw_add_shadow, add_shadow },
|
||||||
{ dfw_delete_index, delete_index },
|
{ dfw_delete_index, delete_index },
|
||||||
|
{ dfw_delete_expression_index, delete_index },
|
||||||
{ dfw_delete_rfr, delete_rfr },
|
{ dfw_delete_rfr, delete_rfr },
|
||||||
{ dfw_delete_relation, delete_relation },
|
{ dfw_delete_relation, delete_relation },
|
||||||
{ dfw_delete_shadow, delete_shadow },
|
{ dfw_delete_shadow, delete_shadow },
|
||||||
@ -226,7 +228,6 @@ static const deferred_task task_table[] =
|
|||||||
#ifdef EXPRESSION_INDICES
|
#ifdef EXPRESSION_INDICES
|
||||||
{ dfw_create_expression_index, PCMET_expression_index },
|
{ dfw_create_expression_index, PCMET_expression_index },
|
||||||
#endif
|
#endif
|
||||||
{ dfw_delete_expression_index, delete_index },
|
|
||||||
{ dfw_grant, GRANT_privileges },
|
{ dfw_grant, GRANT_privileges },
|
||||||
{ dfw_create_trigger, create_trigger },
|
{ dfw_create_trigger, create_trigger },
|
||||||
{ dfw_delete_trigger, delete_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)
|
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_sav_number,
|
||||||
&work->dfw_args,
|
&work->dfw_args,
|
||||||
work->dfw_type,
|
work->dfw_type,
|
||||||
@ -2443,18 +2444,36 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
|||||||
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 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,
|
MET_delete_dependencies(tdbb,
|
||||||
work->dfw_name,
|
arg->dfw_name,
|
||||||
obj_expression_index);
|
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
|
||||||
if (work->dfw_args) {
|
const DeferredWork* arg = work->dfw_args;
|
||||||
if (work->dfw_args->dfw_id) {
|
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);
|
check_partners(tdbb, relation->rel_id);
|
||||||
if (relation->rel_id != work->dfw_args->dfw_id) {
|
if (relation->rel_id != arg->dfw_id) {
|
||||||
check_partners(tdbb, work->dfw_args->dfw_id);
|
check_partners(tdbb, arg->dfw_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3136,7 +3155,7 @@ static bool find_depend_in_dfw( thread_db* tdbb,
|
|||||||
dfw_type = dfw_delete_procedure;
|
dfw_type = dfw_delete_procedure;
|
||||||
break;
|
break;
|
||||||
case obj_expression_index:
|
case obj_expression_index:
|
||||||
dfw_type = dfw_delete_index;
|
dfw_type = dfw_delete_expression_index;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fb_assert(false);
|
fb_assert(false);
|
||||||
@ -3154,6 +3173,21 @@ static bool find_depend_in_dfw( thread_db* tdbb,
|
|||||||
{
|
{
|
||||||
return true;
|
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)
|
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_work(Jrd::jrd_tra*);
|
||||||
void DFW_perform_post_commit_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);
|
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&);
|
void DFW_update_index(const TEXT*, USHORT, const Jrd::SelectivityList&);
|
||||||
|
|
||||||
#endif // JRD_DFW_PROTO_H
|
#endif // JRD_DFW_PROTO_H
|
||||||
|
@ -244,7 +244,12 @@ enum dfw_t {
|
|||||||
dfw_add_difference,
|
dfw_add_difference,
|
||||||
dfw_delete_difference,
|
dfw_delete_difference,
|
||||||
dfw_begin_backup,
|
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>
|
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,
|
work = DFW_post_work(transaction, dfw_delete_expression_index,
|
||||||
&desc, id);
|
&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
|
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)) &&
|
(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)) )
|
||||||
{
|
{
|
||||||
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 ?
|
else { // can't find partner relation - impossible ?
|
||||||
// add empty argument to let DFW know dropping
|
// add empty argument to let DFW know dropping
|
||||||
// index was bound with FK
|
// 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;
|
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));
|
MOV_get_metadata_str(&desc, procedure_name, sizeof(procedure_name));
|
||||||
if ( (procedure = MET_lookup_procedure(tdbb, procedure_name, true)) )
|
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->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);
|
EVL_field(0, rpb->rpb_record, f_prm_sname, &desc2);
|
||||||
DFW_post_work(transaction, dfw_delete_global, &desc2, 0);
|
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
|
Express interest in the relation to prevent it from being deleted
|
||||||
out from under us while garbage collection is in-progress. */
|
out from under us while garbage collection is in-progress. */
|
||||||
|
|
||||||
//hvlad: skip system relations
|
|
||||||
vec* vector = dbb->dbb_relations;
|
vec* vector = dbb->dbb_relations;
|
||||||
for (ULONG id = 0; vector && id < vector->count(); ++id) {
|
for (ULONG id = 0; vector && id < vector->count(); ++id) {
|
||||||
relation = (jrd_rel*) (*vector)[id];
|
relation = (jrd_rel*) (*vector)[id];
|
||||||
RelationGarbage *relGarbage =
|
RelationGarbage *relGarbage =
|
||||||
relation ? (RelationGarbage*)relation->rel_garbage : NULL;
|
relation ? (RelationGarbage*)relation->rel_garbage : NULL;
|
||||||
|
|
||||||
|
//hvlad: skip system relations
|
||||||
if (relation && (relation->rel_gc_bitmap || relGarbage) &&
|
if (relation && (relation->rel_gc_bitmap || relGarbage) &&
|
||||||
!(relation->rel_flags & (REL_deleted | REL_deleting | REL_system)))
|
!(relation->rel_flags & (REL_deleted | REL_deleting | REL_system)))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user