8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:03:02 +01:00

Added checkReload() support to startup barrier of versioned object

This commit is contained in:
AlexPeshkoff 2024-03-29 20:13:36 +03:00
parent c2413fb667
commit 320c7a6821
16 changed files with 156 additions and 73 deletions

View File

@ -12983,7 +12983,7 @@ ValueExprNode* UdfCallNode::pass2(thread_db* tdbb, CompilerScratch* csb)
dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
{
Function* f = function(request->getResources());
const Function* func = function(request->getResources());
UCHAR* impure = request->getImpure<UCHAR>(impureOffset);
Impure* impureArea = request->getImpure<Impure>(impureOffset);
@ -13007,13 +13007,13 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
}
}
if (!f->isImplemented())
if (!func->isImplemented())
{
status_exception::raise(
Arg::Gds(isc_func_pack_not_implemented) <<
Arg::Str(function()->getName().identifier) << Arg::Str(function()->getName().package));
}
else if (!f->isDefined())
else if (!func->isDefined())
{
status_exception::raise(
Arg::Gds(isc_funnotdef) << Arg::Str(function()->getName().toString()) <<
@ -13026,9 +13026,9 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
// Evaluate the function.
if (f->fun_entrypoint)
if (func->fun_entrypoint)
{
const Parameter* const returnParam = f->getOutputFields()[0];
const Parameter* const returnParam = func->getOutputFields()[0];
value->vlu_desc = returnParam->prm_desc;
// If the return data type is any of the string types, allocate space to hold value.
@ -13062,22 +13062,21 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
FB_NEW_POOL(*tdbb->getDefaultPool()) Array<UCHAR>(*tdbb->getDefaultPool());
}
FUN_evaluate(tdbb, f, args->items, value, *impureArea->temp);
FUN_evaluate(tdbb, func, args->items, value, *impureArea->temp);
}
else
{
//const_cast<Function*>(function.getObject())->checkReload(tdbb);
func->checkReload(tdbb);
Jrd::Attachment* attachment = tdbb->getAttachment();
const ULONG inMsgLength = f->getInputFormat() ? f->getInputFormat()->fmt_length : 0;
const ULONG outMsgLength = f->getOutputFormat()->fmt_length;
const ULONG inMsgLength = func->getInputFormat() ? func->getInputFormat()->fmt_length : 0;
const ULONG outMsgLength = func->getOutputFormat()->fmt_length;
UCHAR* const inMsg = FB_ALIGN(impure + sizeof(impure_value), FB_ALIGNMENT);
UCHAR* const outMsg = FB_ALIGN(inMsg + inMsgLength, FB_ALIGNMENT);
if (f->fun_inputs != 0)
if (func->fun_inputs != 0)
{
const dsc* fmtDesc = f->getInputFormat()->fmt_desc.begin();
const dsc* fmtDesc = func->getInputFormat()->fmt_desc.begin();
for (auto& source : args->items)
{
@ -13107,7 +13106,7 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
const SavNumber savNumber = transaction->tra_save_point ?
transaction->tra_save_point->getNumber() : 0;
Request* funcRequest = f->getStatement()->findRequest(tdbb);
Request* funcRequest = func->getStatement()->findRequest(tdbb);
// trace function execution start
TraceFuncExecute trace(tdbb, funcRequest, request, inMsg, inMsgLength);
@ -13154,7 +13153,7 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
throw;
}
const dsc* fmtDesc = f->getOutputFormat()->fmt_desc.begin();
const dsc* fmtDesc = func->getOutputFormat()->fmt_desc.begin();
const ULONG nullOffset = (IPTR) fmtDesc[1].dsc_address;
SSHORT* const nullPtr = reinterpret_cast<SSHORT*>(outMsg + nullOffset);

View File

@ -2163,7 +2163,7 @@ public:
public:
QualifiedName name;
NestConst<ValueListNode> args;
SubRoutine<Function> function;
SubRoutine<Function> function; // NestConst ????????????????
private:
dsql_udf* dsqlFunction;

View File

@ -3175,10 +3175,10 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
ExecProcedureNode* ExecProcedureNode::pass1(thread_db* tdbb, CompilerScratch* csb)
{
if (!procedure->getPermanent()->isSubRoutine())
if (!procedure()->isSubRoutine())
{
// Post access to procedure.
CMP_post_procedure_access(tdbb, csb, procedure->getPermanent());
CMP_post_procedure_access(tdbb, csb, procedure());
}
doPass1(tdbb, csb, inputSources.getAddress());
@ -3228,22 +3228,25 @@ const StmtNode* ExecProcedureNode::execute(thread_db* tdbb, Request* request, Ex
// End by assigning the output parameters.
void ExecProcedureNode::executeProcedure(thread_db* tdbb, Request* request) const
{
if (!procedure->isImplemented())
const jrd_prc* proc = procedure(request->getResources());
if (!proc->isImplemented())
{
status_exception::raise(
Arg::Gds(isc_proc_pack_not_implemented) <<
Arg::Str(procedure->getName().identifier) << Arg::Str(procedure->getName().package));
Arg::Str(proc->getName().identifier) << Arg::Str(proc->getName().package));
}
else if (!procedure->isDefined())
else if (!proc->isDefined())
{
status_exception::raise(
Arg::Gds(isc_prcnotdef) << Arg::Str(procedure->getName().toString()) <<
Arg::Gds(isc_prcnotdef) << Arg::Str(proc->getName().toString()) <<
Arg::Gds(isc_modnotfound));
}
const_cast<jrd_prc*>(procedure.getObject())->checkReload(tdbb);
//const_cast<jrd_prc*>
proc->checkReload(tdbb);
UserId* invoker = procedure->invoker ? procedure->invoker : tdbb->getAttachment()->att_ss_user;
UserId* invoker = proc->invoker ? proc->invoker : tdbb->getAttachment()->att_ss_user;
AutoSetRestore<UserId*> userIdHolder(&tdbb->getAttachment()->att_ss_user, invoker);
ULONG inMsgLength = 0;
@ -3268,7 +3271,7 @@ void ExecProcedureNode::executeProcedure(thread_db* tdbb, Request* request) cons
}
else
{
format = procedure->getOutputFormat();
format = proc->getOutputFormat();
outMsgLength = format->fmt_length;
outMsg = tempBuffer.getBuffer(outMsgLength + FB_DOUBLE_ALIGN - 1);
outMsg = FB_ALIGN(outMsg, FB_DOUBLE_ALIGN);
@ -3289,7 +3292,7 @@ void ExecProcedureNode::executeProcedure(thread_db* tdbb, Request* request) cons
const SavNumber savNumber = transaction->tra_save_point ?
transaction->tra_save_point->getNumber() : 0;
Request* procRequest = procedure->getStatement()->findRequest(tdbb);
Request* procRequest = proc->getStatement()->findRequest(tdbb);
// trace procedure execution start
TraceProcExecute trace(tdbb, procRequest, request, inputTargets);

View File

@ -642,7 +642,7 @@ public:
NestConst<ValueListNode> outputSources;
NestConst<ValueListNode> outputTargets;
NestConst<MessageNode> outputMessage;
NestConst<jrd_prc> procedure;
SubRoutine<jrd_prc> procedure; // NestConst ????????????????????
};

View File

@ -131,7 +131,7 @@ public:
static void destroy(CharSetVers* csv);
static CharSetVers* create(thread_db* tdbb, MemoryPool& p, Cached::Charset* perm);
void scan(thread_db* tdbb, ObjectBase::Flag flags);
bool scan(thread_db* tdbb, ObjectBase::Flag flags);
static Lock* makeLock(thread_db*, MemoryPool&);
Collation* getCollation(TTypeId tt_id);

View File

@ -124,7 +124,7 @@ int Function::blockingAst(void* ast_object)
return 0;
}
void Function::scan(thread_db* tdbb, ObjectBase::Flag)
bool Function::scan(thread_db* tdbb, ObjectBase::Flag)
{
Attachment* attachment = tdbb->getAttachment();
jrd_tra* sysTransaction = attachment->getSysTransaction();
@ -425,6 +425,8 @@ void Function::scan(thread_db* tdbb, ObjectBase::Flag)
}
END_FOR
}
return !(this->flags & FLAG_RELOAD);
}
bool Function::reload(thread_db* tdbb)

View File

@ -75,7 +75,7 @@ namespace Jrd
}
static Function* create(thread_db* tdbb, MemoryPool& pool, Cached::Function* perm);
void scan(thread_db* tdbb, ObjectBase::Flag flags);
bool scan(thread_db* tdbb, ObjectBase::Flag flags);
static const char* objectFamily(void*)
{
@ -124,8 +124,7 @@ namespace Jrd
return cachedFunction;
}
protected:
virtual bool reload(thread_db* tdbb);
bool reload(thread_db* tdbb) override;
};
}

View File

@ -86,3 +86,10 @@ MemoryPool& CachePool::get(thread_db* tdbb)
fatal_exception::raiseFmt("%s %s%sid=%d busy in another thread - operation failed\n",
family, name ? name : "", name ? " " : "", id);
}
bool ObjectBase::reload(thread_db* tdbb)
{
// default implementation for missing reload call
fatal_exception::raise("Unable to recompile this type of cached object");
}

View File

@ -400,6 +400,7 @@ public:
typedef unsigned Flag;
virtual void lockedExcl [[noreturn]] (thread_db* tdbb) /*const*/;
virtual const char* c_name() const = 0;
virtual bool reload(thread_db* tdbb);
};
@ -464,13 +465,13 @@ public:
}
void pass(std::function<void()> scan)
void scanPass(std::function<bool(bool)> objScan)
{
// no need opening barrier twice
if (flg == READY)
return;
// enable recursive pass by scanning thread
// enable recursive no-action pass by scanning thread
// if thd is current thread flg is not going to be changed - current thread holds mutex
if ((thd == Thread::getId()) && (flg == SCANNING))
return;
@ -478,28 +479,39 @@ public:
std::unique_lock<std::mutex> g(mtx);
for(;;)
{
bool reason = true;
switch (flg)
{
case INITIAL: // out thread becomes scanning thread
case INITIAL: // Our thread becomes scanning thread
reason = false;
// fall through...
case RELOAD: // may be because object body reload required.
thd = Thread::getId();
flg = SCANNING;
try
{
scan();
if (!objScan(reason))
{
// scan complete but reload was requested
flg = RELOAD;
thd = 0;
cond.notify_all(); // avoid deadlock in other threads
return;
}
}
catch(...) // scan failed - give up
{
flg = INITIAL;
thd = 0;
cond.notify_all(); // avoid deadlock in other threads
throw;
}
flg = READY;
cond.notify_all();
cond.notify_all(); // other threads may proceed successfully
return;
case SCANNING: // somebody is already scanning object
@ -516,7 +528,9 @@ private:
std::condition_variable cond;
std::mutex mtx;
ThreadId thd;
enum { INITIAL, SCANNING, READY } flg;
public:
enum { INITIAL, RELOAD, SCANNING, READY } flg;
};
template <class OBJ>
@ -668,10 +682,10 @@ public:
fb_assert(cacheFlags & CacheFlag::COMMITTED);
}
void scan(std::function<void()> objScan, ObjectBase::Flag flags)
void scan(std::function<bool(bool)> objScan, ObjectBase::Flag flags)
{
if (!(flags & CacheFlag::NOSCAN))
bar.pass(objScan);
bar.scanPass(objScan);
}
bool scanInProgress() const
@ -731,6 +745,23 @@ public:
cleanup();
}
bool rescan(thread_db* tdbb, Versioned* obj, bool rld, ObjectBase::Flag flags)
{
return rld ? obj->reload(tdbb) : obj->scan(tdbb, flags);
}
Versioned* reload(thread_db* tdbb)
{
HazardPtr<ListEntry<Versioned>> listEntry(list);
TraNumber cur = TransactionNumber::current(tdbb);
if (listEntry)
{
Versioned* obj = ListEntry<Versioned>::getObject(listEntry, cur, 0);
if (obj)
listEntry->scan([&](bool rld){ return rescan(tdbb, obj, rld, flags); }, flags);
}
}
Versioned* getObject(thread_db* tdbb, ObjectBase::Flag flags = 0)
{
TraNumber cur = TransactionNumber::current(tdbb);
@ -749,7 +780,7 @@ public:
if (ListEntry<Versioned>::replace(list, newEntry, nullptr))
{
newEntry->scan([&](){ obj->scan(tdbb, flags); }, flags);
newEntry->scan([&](bool rld){ return rescan(tdbb, obj, rld, flags); }, flags);
return obj;
}
@ -791,7 +822,14 @@ public:
{
setNewResetAt(oldResetAt, current);
if (obj)
newEntry->scan([&](){ obj->scan(tdbb, flags); }, flags);
{
newEntry->scan(
[&](bool rld)
{
return rescan(tdbb, obj, rld, flags);
},
flags);
}
}
else
delete newEntry;

View File

@ -233,7 +233,7 @@ public:
}
static Lock* makeLock(thread_db* tdbb, MemoryPool& p);
void scan(thread_db* tdbb, ObjectBase::Flag flags);
bool scan(thread_db* tdbb, ObjectBase::Flag flags);
const char* c_name() const override
{
@ -492,7 +492,7 @@ public:
bool isSystem() const;
bool isReplicating(thread_db* tdbb);
void scan(thread_db* tdbb, ObjectBase::Flag flags); // Scan the newly loaded relation for meta data
bool scan(thread_db* tdbb, ObjectBase::Flag flags); // Scan the newly loaded relation for meta data
MetaName getName() const;
MemoryPool& getPool() const;
MetaName getSecurityName() const;

View File

@ -173,7 +173,8 @@ void Routine::parseBlr(thread_db* tdbb, CompilerScratch* csb, bid* blob_id, bid*
PAR_blr(tdbb, nullptr, tmp.begin(), (ULONG) tmp.getCount(), NULL, &csb, &statement, false, 0);
setStatement(statement);
// reload?????????????????????
if (csb->csb_g_flags & csb_reload)
flags |= FLAG_RELOAD;
if (!blob_id)
setImplemented(false);
@ -308,4 +309,12 @@ void RoutinePermanent::releaseLocks(thread_db* tdbb)
LCK_release(tdbb, existenceLock);
}
void Routine::checkReload(thread_db* tdbb) const
{
if (!(flags & FLAG_RELOAD))
return;
const_cast<Routine*>(this)->reload(tdbb);
}
} // namespace Jrd

View File

@ -113,6 +113,9 @@ namespace Jrd
{
}
public:
static const USHORT FLAG_RELOAD = 32; // Recompile before execution
public:
static const USHORT MAX_ALTER_COUNT = 64; // Number of times an in-cache routine can be altered ?????????
@ -139,7 +142,7 @@ namespace Jrd
bool isDefined() const { return defined; }
void setDefined(bool value) { defined = value; }
void checkReload(thread_db* tdbb);
void checkReload(thread_db* tdbb) const;
USHORT getDefaultCount() const { return defaultCount; }
void setDefaultCount(USHORT value) { defaultCount = value; }
@ -175,8 +178,6 @@ namespace Jrd
public:
virtual int getObjectType() const = 0;
virtual SLONG getSclType() const = 0;
public:
virtual RoutinePermanent* getPermanent() const = 0; // Permanent part of data
private:
@ -189,9 +190,6 @@ namespace Jrd
Firebird::Array<NestConst<Parameter> > inputFields; // array of field blocks
Firebird::Array<NestConst<Parameter> > outputFields; // array of field blocks
protected:
virtual bool reload(thread_db* tdbb) = 0;
public:
USHORT flags;
StartupBarrier startup;
@ -232,12 +230,23 @@ namespace Jrd
}
template <typename T>
R* operator()(T t) const
R* operator()(T t)
{
return isSubRoutine() ? subroutine : routine(t);
}
CacheElement<R, RoutinePermanent>* operator()() const
template <typename T>
const R* operator()(T t) const
{
return isSubRoutine() ? subroutine : routine(t);
}
CacheElement<R, RoutinePermanent>* operator()()
{
return isSubRoutine() ? subroutine->getPermanent() : routine();
}
const CacheElement<R, RoutinePermanent>* operator()() const
{
return isSubRoutine() ? subroutine->getPermanent() : routine();
}

View File

@ -1545,7 +1545,7 @@ void MET_get_shadow_files(thread_db* tdbb, bool delete_files)
}
void DbTriggers::scan(thread_db* tdbb, ObjectBase::Flag flags)
bool DbTriggers::scan(thread_db* tdbb, ObjectBase::Flag flags)
{
/********************************************
*
@ -1583,6 +1583,8 @@ void DbTriggers::scan(thread_db* tdbb, ObjectBase::Flag flags)
}
END_FOR
}
return true;
}
@ -2538,7 +2540,7 @@ bool MET_lookup_partner(thread_db* tdbb, RelationPermanent* relation, index_desc
}
jrd_prc* MetadataCache::lookup_procedure(thread_db* tdbb, const QualifiedName& name)
jrd_prc* MetadataCache::lookup_procedure(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags)
{
/**************************************
*
@ -2564,6 +2566,9 @@ jrd_prc* MetadataCache::lookup_procedure(thread_db* tdbb, const QualifiedName& n
}
}
if (!(flags & CacheFlag::AUTOCREATE))
return nullptr;
// We need to look up the procedure name in RDB$PROCEDURES
jrd_prc* procedure = nullptr;
@ -2575,7 +2580,7 @@ jrd_prc* MetadataCache::lookup_procedure(thread_db* tdbb, const QualifiedName& n
WITH P.RDB$PROCEDURE_NAME EQ name.identifier.c_str() AND
P.RDB$PACKAGE_NAME EQUIV NULLIF(name.package.c_str(), '')
{
procedure = mdc->mdc_procedures.getObject(tdbb, P.RDB$PROCEDURE_ID, CacheFlag::AUTOCREATE);
procedure = mdc->mdc_procedures.getObject(tdbb, P.RDB$PROCEDURE_ID, flags);
}
END_FOR
@ -2584,7 +2589,7 @@ jrd_prc* MetadataCache::lookup_procedure(thread_db* tdbb, const QualifiedName& n
}
jrd_prc* MetadataCache::lookup_procedure_id(thread_db* tdbb, MetaId id, USHORT flags)
jrd_prc* MetadataCache::lookup_procedure_id(thread_db* tdbb, MetaId id, ObjectBase::Flag flags)
{
/**************************************
*
@ -2600,7 +2605,7 @@ jrd_prc* MetadataCache::lookup_procedure_id(thread_db* tdbb, MetaId id, USHORT f
Attachment* attachment = tdbb->getAttachment();
MetadataCache* mdc = attachment->att_database->dbb_mdc;
return mdc->mdc_procedures.getObject(tdbb, id, CacheFlag::AUTOCREATE);
return mdc->mdc_procedures.getObject(tdbb, id, flags);
}
@ -2895,7 +2900,7 @@ jrd_prc* jrd_prc::create(thread_db* tdbb, MemoryPool&, Cached::Procedure* perm)
return FB_NEW_POOL(perm->getPool()) jrd_prc(perm);
}
void jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag)
bool jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag)
{
Attachment* attachment = tdbb->getAttachment();
Database* dbb = tdbb->getDatabase();
@ -3152,10 +3157,14 @@ void jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag)
}
END_FOR
}
return !(this->flags & FLAG_RELOAD);
}
bool jrd_prc::reload(thread_db* tdbb)
{
fb_assert(this->flags & Routine::FLAG_RELOAD);
Attachment* attachment = tdbb->getAttachment();
AutoCacheRequest request(tdbb, irq_r_proc_blr, IRQ_REQUESTS);
@ -3173,6 +3182,8 @@ bool jrd_prc::reload(thread_db* tdbb)
{
this->parseBlr(tdbb, csb, &P.RDB$PROCEDURE_BLR,
P.RDB$DEBUG_INFO.NULL ? NULL : &P.RDB$DEBUG_INFO);
return !(this->flags & Routine::FLAG_RELOAD);
}
catch (const Exception& ex)
{
@ -3291,7 +3302,7 @@ void MET_scan_partners(thread_db* tdbb, RelationPermanent* relation)
}
void jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag flags)
bool jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag flags)
{
/**************************************
*
@ -3624,6 +3635,8 @@ void jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag flags)
throw;
}
return true;
}
@ -4209,7 +4222,7 @@ bool MetadataCache::resolve_charset_and_collation(thread_db* tdbb, TTypeId* id,
}
void CharSetVers::scan(thread_db* tdbb, ObjectBase::Flag flags)
bool CharSetVers::scan(thread_db* tdbb, ObjectBase::Flag flags)
{
fb_assert(perm->hasData()); // character set to be filled earlier
@ -4293,6 +4306,8 @@ void CharSetVers::scan(thread_db* tdbb, ObjectBase::Flag flags)
charset_collations[colId] = collation;
}
END_FOR
return true;
}

View File

@ -154,7 +154,7 @@ private:
public:
static jrd_prc* create(thread_db* tdbb, MemoryPool& p, Cached::Procedure* perm);
static Lock* makeLock(thread_db* tdbb, MemoryPool& p);
void scan(thread_db* tdbb, ObjectBase::Flag);
bool scan(thread_db* tdbb, ObjectBase::Flag);
void releaseExternal() override
{
@ -172,8 +172,7 @@ public:
return "procedure";
}
protected:
bool reload(thread_db* tdbb) override; // impl is in met.epp
bool reload(thread_db* tdbb) override;
};
@ -288,8 +287,8 @@ public:
static void update_partners(thread_db* tdbb);
void load_db_triggers(thread_db* tdbb, int type, bool force = false);
void load_ddl_triggers(thread_db* tdbb, bool force = false);
static jrd_prc* lookup_procedure(thread_db* tdbb, const QualifiedName& name);
static jrd_prc* lookup_procedure_id(thread_db* tdbb, MetaId id, USHORT flags);
static jrd_prc* lookup_procedure(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags = CacheFlag::AUTOCREATE);
static jrd_prc* lookup_procedure_id(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static Function* lookup_function(thread_db* tdbb, const QualifiedName& name);
static Function* lookup_function(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static Cached::Procedure* lookupProcedure(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags = 0);

View File

@ -58,22 +58,25 @@ ProcedureScan::ProcedureScan(thread_db* tdbb, CompilerScratch* csb, const string
void ProcedureScan::internalOpen(thread_db* tdbb) const
{
if (!m_procedure(tdbb)->isImplemented())
Request* const request = tdbb->getRequest();
const jrd_prc* proc = m_procedure(request->getResources());
if (!proc->isImplemented())
{
status_exception::raise(
Arg::Gds(isc_proc_pack_not_implemented) <<
Arg::Str(m_procedure()->getName().identifier) << Arg::Str(m_procedure()->getName().package));
}
else if (!m_procedure(tdbb)->isDefined())
else if (!proc->isDefined())
{
status_exception::raise(
Arg::Gds(isc_prcnotdef) << Arg::Str(m_procedure()->getName().toString()) <<
Arg::Gds(isc_modnotfound));
}
// ????????????? const_cast<jrd_prc*>(m_procedure)->checkReload(tdbb);
proc->checkReload(tdbb);
Request* const request = tdbb->getRequest();
Impure* const impure = request->getImpure<Impure>(m_impure);
impure->irsb_flags = irsb_open;
@ -107,7 +110,7 @@ void ProcedureScan::internalOpen(thread_db* tdbb) const
im = NULL;
}
Request* const proc_request = m_procedure(request->getResources())->getStatement()->findRequest(tdbb);
Request* const proc_request = proc->getStatement()->findRequest(tdbb);
impure->irsb_req_handle = proc_request;
// req_proc_fetch flag used only when fetching rows, so
@ -174,7 +177,7 @@ bool ProcedureScan::internalGetRecord(thread_db* tdbb) const
JRD_reschedule(tdbb);
Request* const request = tdbb->getRequest();
jrd_prc* proc = m_procedure(request->getResources());
const jrd_prc* proc = m_procedure(request->getResources());
UserId* invoker = proc->invoker ? proc->invoker : tdbb->getAttachment()->att_ss_user;
AutoSetRestore<UserId*> userIdHolder(&tdbb->getAttachment()->att_ss_user, invoker);

View File

@ -2198,7 +2198,7 @@ bool VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
EVL_field(0, rpb->rpb_record, f_prm_name, &desc2);
if ( (procedure = MetadataCache::lookup_procedure(tdbb,
QualifiedName(object_name, package_name)/*, CacheFlag::AUTOCREATE | CacheFlag::NOSCAN*/)) )
QualifiedName(object_name, package_name), CacheFlag::AUTOCREATE | CacheFlag::NOSCAN)) )
{
work = DFW_post_work(transaction, dfw_delete_prm, &desc2, procedure->getId(),
package_name);