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:
parent
c2413fb667
commit
320c7a6821
@ -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);
|
||||
|
||||
|
@ -2163,7 +2163,7 @@ public:
|
||||
public:
|
||||
QualifiedName name;
|
||||
NestConst<ValueListNode> args;
|
||||
SubRoutine<Function> function;
|
||||
SubRoutine<Function> function; // NestConst ????????????????
|
||||
|
||||
private:
|
||||
dsql_udf* dsqlFunction;
|
||||
|
@ -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);
|
||||
|
@ -642,7 +642,7 @@ public:
|
||||
NestConst<ValueListNode> outputSources;
|
||||
NestConst<ValueListNode> outputTargets;
|
||||
NestConst<MessageNode> outputMessage;
|
||||
NestConst<jrd_prc> procedure;
|
||||
SubRoutine<jrd_prc> procedure; // NestConst ????????????????????
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user