diff --git a/src/jrd/Function.epp b/src/jrd/Function.epp index 5bc45e1029..9396bd786b 100644 --- a/src/jrd/Function.epp +++ b/src/jrd/Function.epp @@ -65,6 +65,7 @@ Function* Function::lookup(thread_db* tdbb, USHORT id, bool return_deleted, bool Function* function = (id < attachment->att_functions.getCount()) ? attachment->att_functions[id] : NULL; if (function && function->getId() == id && + !(function->flags & Routine::FLAG_CLEARED) && !(function->flags & Routine::FLAG_BEING_SCANNED) && ((function->flags & Routine::FLAG_SCANNED) || noscan) && !(function->flags & Routine::FLAG_BEING_ALTERED) && @@ -118,6 +119,7 @@ Function* Function::lookup(thread_db* tdbb, const QualifiedName& name, bool nosc Function* const function = *iter; if (function && !(function->flags & Routine::FLAG_OBSOLETE) && + !(function->flags & Routine::FLAG_CLEARED) && ((function->flags & Routine::FLAG_SCANNED) || noscan) && !(function->flags & Routine::FLAG_BEING_SCANNED) && !(function->flags & Routine::FLAG_BEING_ALTERED)) @@ -194,7 +196,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT try { function->flags |= (Routine::FLAG_BEING_SCANNED | flags); - function->flags &= ~Routine::FLAG_OBSOLETE; + function->flags &= ~(Routine::FLAG_OBSOLETE | Routine::FLAG_CLEARED); function->setId(id); attachment->att_functions[id] = function; diff --git a/src/jrd/Routine.cpp b/src/jrd/Routine.cpp index 92f38372f9..be0fdc143a 100644 --- a/src/jrd/Routine.cpp +++ b/src/jrd/Routine.cpp @@ -365,12 +367,12 @@ void Routine::remove(thread_db* tdbb) else { // Fully clear routine block. Some pieces of code check for empty - // routine name and ID, this is why we do it. + // routine name, this is why we do it. setName(QualifiedName()); setSecurityName(""); - setId(0); setDefaultCount(0); releaseExternal(); + flags |= FLAG_CLEARED; } } diff --git a/src/jrd/Routine.h b/src/jrd/Routine.h index 90d62f4dc4..5c72e16e63 100644 --- a/src/jrd/Routine.h +++ b/src/jrd/Routine.h @@ -82,6 +84,7 @@ namespace Jrd // invalidating procedure pointers from other parts of metadata cache static const USHORT FLAG_CHECK_EXISTENCE = 16; // Existence lock released static const USHORT FLAG_RELOAD = 32; // Recompile before execution + static const USHORT FLAG_CLEARED = 64; // Routine cleared but not removed from cache static const USHORT MAX_ALTER_COUNT = 64; // Number of times an in-cache routine can be altered diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 93db683e87..461e4cab4b 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -2777,6 +2777,7 @@ jrd_prc* MET_lookup_procedure(thread_db* tdbb, const QualifiedName& name, bool n jrd_prc* procedure = *iter; if (procedure && !(procedure->flags & Routine::FLAG_OBSOLETE) && + !(procedure->flags & Routine::FLAG_CLEARED) && ((procedure->flags & Routine::FLAG_SCANNED) || noscan) && !(procedure->flags & Routine::FLAG_BEING_SCANNED) && !(procedure->flags & Routine::FLAG_BEING_ALTERED)) @@ -2845,6 +2846,7 @@ jrd_prc* MET_lookup_procedure_id(thread_db* tdbb, USHORT id, if (id < (USHORT) attachment->att_procedures.getCount() && (procedure = attachment->att_procedures[id]) && procedure->getId() == id && + !(procedure->flags & Routine::FLAG_CLEARED) && !(procedure->flags & Routine::FLAG_BEING_SCANNED) && ((procedure->flags & Routine::FLAG_SCANNED) || noscan) && !(procedure->flags & Routine::FLAG_BEING_ALTERED) && @@ -3336,7 +3338,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) try { procedure->flags |= (Routine::FLAG_BEING_SCANNED | flags); - procedure->flags &= ~Routine::FLAG_OBSOLETE; + procedure->flags &= ~(Routine::FLAG_OBSOLETE | Routine::FLAG_CLEARED); procedure->setId(id); attachment->att_procedures[id] = procedure; @@ -3529,7 +3531,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) { try { - procedure->parseBlr(tdbb, csb, &P.RDB$PROCEDURE_BLR, + procedure->parseBlr(tdbb, csb, &P.RDB$PROCEDURE_BLR, P.RDB$DEBUG_INFO.NULL ? NULL : &P.RDB$DEBUG_INFO); } catch (const Exception& ex)