From 4c0b81656881bf0140eea21587bf4f875ba6883f Mon Sep 17 00:00:00 2001 From: robocop Date: Tue, 11 Jul 2006 04:57:28 +0000 Subject: [PATCH] CORE-847 Deleting dependencies for fields that WERE computed. --- src/jrd/dfw.epp | 22 +++++++++++++++++----- src/jrd/met.epp | 11 +++++++---- src/jrd/met_proto.h | 3 ++- src/jrd/tra.h | 3 ++- src/jrd/vio.cpp | 22 +++++++++++++++++----- 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index 26e0a39393..93d8086896 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -3731,8 +3731,8 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, FOR(REQUEST_HANDLE request_fmt1) REL IN RDB$RELATIONS WITH REL.RDB$RELATION_NAME EQ work->dfw_name.c_str() - if (!REQUEST(irq_format1)) { - REQUEST(irq_format1) = request_fmt1; + if (!REQUEST(irq_format1)) { + REQUEST(irq_format1) = request_fmt1; } relation = MET_lookup_relation_id(tdbb, REL.RDB$RELATION_ID, false); @@ -3894,7 +3894,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, } /* Make sure the text type specified is implemented */ - if (!(validate_text_type(tdbb, tfb))) + if (!(validate_text_type(tdbb, tfb))) { EXE_unwind(tdbb, request_fmt1); EXE_unwind(tdbb, request_fmtx); @@ -3976,6 +3976,18 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, if (!null_view) MET_delete_dependencies(tdbb, work->dfw_name, obj_view); + { // begin scope + const DeferredWork* arg = work->dfw_args; + while (arg && (arg->dfw_type != dfw_force_computed)) + arg = arg->dfw_next; + + if (arg && arg->dfw_type == dfw_force_computed) + { + computed_field = true; + MET_delete_dependencies(tdbb, arg->dfw_name, obj_computed); + } + } // end scope + if (!null_view || computed_field) relation->rel_flags |= REL_get_dependencies; @@ -3984,8 +3996,8 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_req* temp = NULL; FOR(REQUEST_HANDLE temp) FMTS IN RDB$FORMATS WITH FMTS.RDB$RELATION_ID EQ relation->rel_id AND - FMTS.RDB$FORMAT EQ 0 - ERASE FMTS; + FMTS.RDB$FORMAT EQ 0 + ERASE FMTS; END_FOR; CMP_release(tdbb, temp); make_format(tdbb, relation, 0, external); diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 18a021ae3c..46e607e845 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -634,7 +634,7 @@ ULONG MET_align(Database* dbb, const dsc* desc, ULONG value) } -void MET_change_fields( thread_db* tdbb, jrd_tra* transaction, const dsc* field_source) +DeferredWork* MET_change_fields( thread_db* tdbb, jrd_tra* transaction, const dsc* field_source) { /************************************** * @@ -650,14 +650,15 @@ void MET_change_fields( thread_db* tdbb, jrd_tra* transaction, const dsc* field_ SET_TDBB(tdbb); Database* dbb = tdbb->tdbb_database; - dsc relation_name; + dsc relation_name; + DeferredWork* dw = 0; jrd_req* request = CMP_find_request(tdbb, irq_m_fields, IRQ_REQUESTS); FOR(REQUEST_HANDLE request) X IN RDB$RELATION_FIELDS WITH X.RDB$FIELD_SOURCE EQ field_source->dsc_address - if (!REQUEST(irq_m_fields)) + if (!REQUEST(irq_m_fields)) REQUEST(irq_m_fields) = request; relation_name.dsc_dtype = dtype_text; @@ -665,11 +666,13 @@ void MET_change_fields( thread_db* tdbb, jrd_tra* transaction, const dsc* field_ relation_name.dsc_length = sizeof(X.RDB$RELATION_NAME); relation_name.dsc_address = (UCHAR *) X.RDB$RELATION_NAME; SCL_check_relation(&relation_name, SCL_control); - DFW_post_work(transaction, dfw_update_format, &relation_name, 0); + dw = DFW_post_work(transaction, dfw_update_format, &relation_name, 0); END_FOR; if (!REQUEST(irq_m_fields)) REQUEST(irq_m_fields) = request; + + return dw; } diff --git a/src/jrd/met_proto.h b/src/jrd/met_proto.h index e841b0f640..41a46fcf62 100644 --- a/src/jrd/met_proto.h +++ b/src/jrd/met_proto.h @@ -43,6 +43,7 @@ namespace Jrd { struct index_desc; class jrd_fld; class Shadow; + class DeferredWork; } struct SubtypeInfo @@ -57,7 +58,7 @@ struct SubtypeInfo void MET_activate_shadow(Jrd::thread_db*); ULONG MET_align(Jrd::Database* dbb, const dsc*, ULONG); -void MET_change_fields(Jrd::thread_db*, Jrd::jrd_tra*, const dsc*); +Jrd::DeferredWork* MET_change_fields(Jrd::thread_db*, Jrd::jrd_tra*, const dsc*); Jrd::Format* MET_current(Jrd::thread_db*, Jrd::jrd_rel*); void MET_delete_dependencies(Jrd::thread_db*, const Firebird::MetaName&, USHORT); void MET_delete_shadow(Jrd::thread_db*, USHORT); diff --git a/src/jrd/tra.h b/src/jrd/tra.h index 183d508b03..e5c325b86e 100644 --- a/src/jrd/tra.h +++ b/src/jrd/tra.h @@ -253,7 +253,8 @@ enum dfw_t { // deferred 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 + dfw_arg_proc_name, // procedure name for dfw_delete_prm, mandatory + dfw_force_computed // we need to drop dependencies from a field that WAS computed }; class DeferredWork : public pool_alloc diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index bc66cdc4af..525cbdc4c4 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -2198,11 +2198,23 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, break; case rel_fields: - check_control(tdbb); - EVL_field(0, org_rpb->rpb_record, f_fld_name, &desc1); - MET_change_fields(tdbb, transaction, &desc1); - EVL_field(0, new_rpb->rpb_record, f_fld_name, &desc2); - MET_change_fields(tdbb, transaction, &desc2); + { + check_control(tdbb); + EVL_field(0, org_rpb->rpb_record, f_fld_name, &desc1); + MET_change_fields(tdbb, transaction, &desc1); + EVL_field(0, new_rpb->rpb_record, f_fld_name, &desc2); + DeferredWork* dw = MET_change_fields(tdbb, transaction, &desc2); + // Did we convert computed field into physical, stored field? + // If we did, then force the deletion of the dependencies. + // Warning: getting the result of MET_change_fields is the last relation + // that was affected, but for computed fields, it's an implicit domain + // and hence it can be used only by a single field and therefore one relation. + dsc desc3, desc4; + bool rc1 = EVL_field(0, org_rpb->rpb_record, f_fld_computed, &desc3); + bool rc2 = EVL_field(0, new_rpb->rpb_record, f_fld_computed, &desc4); + if (rc1 != rc2 || rc1 && MOV_compare(&desc3, &desc4)) + DFW_post_work_arg(transaction, dw, &desc1, 0)->dfw_type = dfw_force_computed; + } break; case rel_classes: