From fea7c61d9741dc142fa020bf3aa93af7e52e2002 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Thu, 17 Jan 2019 14:06:54 +0300 Subject: [PATCH] Attempted to fix CORE-2440, CORE-5118 and CORE-5900 together (expression indices contain NULL keys after restore). --- src/burp/restore.epp | 44 ++++++++++++++++++++++++++------------------ src/jrd/met.epp | 2 ++ src/jrd/met_proto.h | 1 + src/jrd/opt.cpp | 2 +- src/jrd/par.cpp | 26 ++++++++++++++++++++++---- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 85669b1be9..eabd880feb 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -344,6 +344,20 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) } END_ERROR; + if (tdgbl->global_trans) + { + BURP_verbose (68); + // msg 68 committing meta data + EXEC SQL COMMIT TRANSACTION tdgbl->global_trans; + if (gds_status->hasData()) + general_on_error (); + // Check to see if there is a warning + if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) + { + BURP_print_warning(gds_status); + } + } + // Activate the indices for foreign keys and do another commit if (!tdgbl->gbl_sw_deactivate_indexes) { @@ -467,20 +481,6 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; } - if (tdgbl->global_trans) - { - BURP_verbose (68); - // msg 68 committing meta data - EXEC SQL COMMIT TRANSACTION tdgbl->global_trans; - if (gds_status->hasData()) - general_on_error (); - // Check to see if there is a warning - if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) - { - BURP_print_warning(gds_status); - } - } - EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; if (gds_status->hasData()) EXEC SQL SET TRANSACTION; @@ -7037,9 +7037,10 @@ bool get_index(BurpGlobals* tdgbl, const burp_rel* relation) * **************************************/ BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; - att_type attribute; - bool foreign_index = false; - scan_attr_t scan_next_attr; + att_type attribute; + bool foreign_index = false; + bool expr_index = false; + scan_attr_t scan_next_attr; SSHORT count = 0, segments = 0; @@ -7089,7 +7090,7 @@ bool get_index(BurpGlobals* tdgbl, const burp_rel* relation) } else { - if (!X.RDB$INDEX_INACTIVE && foreign_index) + if (!X.RDB$INDEX_INACTIVE && (foreign_index || expr_index)) X.RDB$INDEX_INACTIVE = DEFERRED_ACTIVE; } if (tdgbl->gbl_sw_deactivate_indexes) @@ -7129,6 +7130,12 @@ bool get_index(BurpGlobals* tdgbl, const burp_rel* relation) break; case att_index_expression_blr: + expr_index = true; + // Defer expression index activation + if (!X.RDB$INDEX_INACTIVE) + X.RDB$INDEX_INACTIVE = DEFERRED_ACTIVE; + if (tdgbl->gbl_sw_deactivate_indexes) + X.RDB$INDEX_INACTIVE = TRUE; X.RDB$EXPRESSION_BLR.NULL = FALSE; get_blr_blob (tdgbl, X.RDB$EXPRESSION_BLR, false); break; @@ -11317,6 +11324,7 @@ void update_global_field(BurpGlobals* tdgbl) ON_ERROR general_on_error (); END_ERROR; + gfld* n_gfield = gfield->gfld_next; BURP_free (gfield); gfield = n_gfield; diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 2e46fe62b6..bb153fc134 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -2496,6 +2496,8 @@ SLONG MET_lookup_index_name(thread_db* tdbb, { if (X.RDB$INDEX_INACTIVE == 0) *status = MET_object_active; + else if (X.RDB$INDEX_INACTIVE == 3) + *status = MET_object_deferred_active; else *status = MET_object_inactive; diff --git a/src/jrd/met_proto.h b/src/jrd/met_proto.h index 44f9743565..4981bc7e3e 100644 --- a/src/jrd/met_proto.h +++ b/src/jrd/met_proto.h @@ -51,6 +51,7 @@ namespace Jrd enum IndexStatus { MET_object_active, + MET_object_deferred_active, MET_object_inactive, MET_object_unknown }; diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index a091913c0d..a45a5da682 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -972,7 +972,7 @@ static void check_indices(const CompilerScratch::csb_repeat* csb_tail) // if there were no indices fetched at all but the // user specified some, error out using the first index specified - if (!csb_tail->csb_indices && plan->accessType) + if (!csb_tail->csb_indices && plan->accessType && !tdbb->getAttachment()->isGbak()) { // index %s cannot be used in the specified plan ERR_post(Arg::Gds(isc_index_unused) << plan->accessType->items[0].indexName); diff --git a/src/jrd/par.cpp b/src/jrd/par.cpp index a8f99075ae..c4dada62e8 100644 --- a/src/jrd/par.cpp +++ b/src/jrd/par.cpp @@ -994,6 +994,8 @@ static PlanNode* par_plan(thread_db* tdbb, CompilerScratch* csb) node_type = (USHORT) csb->csb_blr_reader.getByte(); + const bool isGbak = tdbb->getAttachment()->isGbak(); + switch (node_type) { case blr_navigational: @@ -1012,7 +1014,7 @@ static PlanNode* par_plan(thread_db* tdbb, CompilerScratch* csb) if (idx_status == MET_object_unknown || idx_status == MET_object_inactive) { - if (tdbb->getAttachment()->isGbak()) + if (isGbak) { PAR_warning(Arg::Warning(isc_indexname) << Arg::Str(name) << Arg::Str(relation->rel_name)); @@ -1020,7 +1022,15 @@ static PlanNode* par_plan(thread_db* tdbb, CompilerScratch* csb) else { PAR_error(csb, Arg::Gds(isc_indexname) << Arg::Str(name) << - Arg::Str(relation->rel_name)); + Arg::Str(relation->rel_name)); + } + } + else if (idx_status == MET_object_deferred_active) + { + if (!isGbak) + { + PAR_error(csb, Arg::Gds(isc_indexname) << Arg::Str(name) << + Arg::Str(relation->rel_name)); } } @@ -1070,7 +1080,7 @@ static PlanNode* par_plan(thread_db* tdbb, CompilerScratch* csb) if (idx_status == MET_object_unknown || idx_status == MET_object_inactive) { - if (tdbb->getAttachment()->isGbak()) + if (isGbak) { PAR_warning(Arg::Warning(isc_indexname) << Arg::Str(name) << Arg::Str(relation->rel_name)); @@ -1078,7 +1088,15 @@ static PlanNode* par_plan(thread_db* tdbb, CompilerScratch* csb) else { PAR_error(csb, Arg::Gds(isc_indexname) << Arg::Str(name) << - Arg::Str(relation->rel_name)); + Arg::Str(relation->rel_name)); + } + } + else if (idx_status == MET_object_deferred_active) + { + if (!isGbak) + { + PAR_error(csb, Arg::Gds(isc_indexname) << Arg::Str(name) << + Arg::Str(relation->rel_name)); } }