Skip to content

Commit fcdcaae

Browse files
committed
Fixed various issues with procedures & functions
1 parent d9bc480 commit fcdcaae

6 files changed

Lines changed: 75 additions & 40 deletions

File tree

src/dsql/DdlNodes.epp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,7 +1853,15 @@ void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsql
18531853
else if (!executeCreate(tdbb, dsqlScratch, transaction))
18541854
return;
18551855

1856-
compile(tdbb, dsqlScratch);
1856+
fb_assert(id);
1857+
auto* permanent = MetadataCache::newVersion<Cached::Function>(tdbb, id);
1858+
auto* prc = permanent ? permanent->getVersioned(tdbb, CacheFlag::NOCOMMIT | CacheFlag::MINISCAN) : nullptr;
1859+
{
1860+
bool dummy = false;
1861+
AutoSetRestore compiling(prc ? &(prc->compiling) : &dummy, true);
1862+
1863+
compile(tdbb, dsqlScratch);
1864+
}
18571865

18581866
{ // scope
18591867
// avoid modify routine dfw during second pass on CREATE
@@ -1866,9 +1874,6 @@ void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsql
18661874
executeAlter(tdbb, dsqlScratch, transaction, true, false);
18671875
}
18681876

1869-
fb_assert(id);
1870-
MetadataCache::newVersion<Cached::Function>(tdbb, id);
1871-
18721877
if (name.package.isEmpty())
18731878
{
18741879
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,
@@ -2911,7 +2916,15 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq
29112916
else if (!executeCreate(tdbb, dsqlScratch, transaction))
29122917
return;
29132918

2914-
compile(tdbb, dsqlScratch);
2919+
fb_assert(id);
2920+
auto* permanent = MetadataCache::newVersion<Cached::Procedure>(tdbb, id);
2921+
auto* prc = permanent ? permanent->getVersioned(tdbb, CacheFlag::NOCOMMIT | CacheFlag::MINISCAN) : nullptr;
2922+
{
2923+
bool dummy = false;
2924+
AutoSetRestore compiling(prc ? &(prc->compiling) : &dummy, true);
2925+
2926+
compile(tdbb, dsqlScratch);
2927+
}
29152928

29162929
{ // scope
29172930
// avoid modify routine dfw during second pass on CREATE
@@ -2924,9 +2937,6 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq
29242937
executeAlter(tdbb, dsqlScratch, transaction, true, false);
29252938
}
29262939

2927-
fb_assert(id);
2928-
MetadataCache::newVersion<Cached::Procedure>(tdbb, id);
2929-
29302940
if (name.package.isEmpty())
29312941
{
29322942
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,

src/jrd/CacheVector.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ class ListEntry : public HazardObject
368368
// Handle front & back of MDC
369369
VersionIncr incr(tdbb);
370370

371-
// And finally try to make object version world-visible
371+
// And finally make object version world-visible
372372
if (cacheFlags.compare_exchange_weak(flags, newFlags,
373373
atomics::memory_order_release, atomics::memory_order_acquire))
374374
{
@@ -535,6 +535,11 @@ class ListEntry : public HazardObject
535535
return (state == READY) || ((thd == Thread::getId()) && (state == SCANNING));
536536
}
537537

538+
bool isAvailable()
539+
{
540+
return isReady() || !(getFlags() & CacheFlag::NOCOMMIT);
541+
}
542+
538543
bool scanInProgress() const
539544
{
540545
return state == READY ? false : (thd == Thread::getId()) && (state == SCANNING);
@@ -685,7 +690,7 @@ class CacheElement : public ElementBase, public P
685690
return OCCUPIED;
686691
}
687692

688-
return entry->isReady() ? READY : MODIFIED;
693+
return entry->isAvailable() ? READY : MODIFIED;
689694
}
690695
}
691696

src/jrd/Function.epp

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Function* Function::lookup(thread_db* tdbb, const QualifiedName& name, ObjectBas
7979
return MetadataCache::lookup_function(tdbb, name, flags);
8080
}
8181

82-
ScanResult Function::scan(thread_db* tdbb, ObjectBase::Flag)
82+
ScanResult Function::scan(thread_db* tdbb, ObjectBase::Flag flags)
8383
{
8484
Attachment* attachment = tdbb->getAttachment();
8585
jrd_tra* metaTransaction = attachment->getMetaTransaction(tdbb);
@@ -335,23 +335,28 @@ ScanResult Function::scan(thread_db* tdbb, ObjectBase::Flag)
335335
}
336336
else if (!X.RDB$FUNCTION_BLR.NULL)
337337
{
338-
const string name = getName().toQuotedString();
339-
340-
try
341-
{
342-
TraceFuncCompile trace(tdbb, name);
343-
344-
parseBlr(tdbb, csb, &X.RDB$FUNCTION_BLR,
345-
X.RDB$DEBUG_INFO.NULL ? nullptr : &X.RDB$DEBUG_INFO);
346-
347-
trace.finish(getStatement(), ITracePlugin::RESULT_SUCCESS);
348-
}
349-
catch (const Exception& ex)
338+
if (compiling || (flags & CacheFlag::MINISCAN))
339+
flReload = true;
340+
else
350341
{
351-
StaticStatusVector temp_status;
352-
ex.stuffException(temp_status);
353-
(Arg::Gds(isc_bad_fun_BLR) << Arg::Str(name)
354-
<< Arg::StatusVector(temp_status.begin())).raise();
342+
const string name = getName().toQuotedString();
343+
344+
try
345+
{
346+
TraceFuncCompile trace(tdbb, name);
347+
348+
parseBlr(tdbb, csb, &X.RDB$FUNCTION_BLR,
349+
X.RDB$DEBUG_INFO.NULL ? nullptr : &X.RDB$DEBUG_INFO);
350+
351+
trace.finish(getStatement(), ITracePlugin::RESULT_SUCCESS);
352+
}
353+
catch (const Exception& ex)
354+
{
355+
StaticStatusVector temp_status;
356+
ex.stuffException(temp_status);
357+
(Arg::Gds(isc_bad_fun_BLR) << Arg::Str(name)
358+
<< Arg::StatusVector(temp_status.begin())).raise();
359+
}
355360
}
356361
}
357362
}
@@ -361,7 +366,7 @@ ScanResult Function::scan(thread_db* tdbb, ObjectBase::Flag)
361366
throw;
362367
}
363368

364-
fb_assert(!isDefined() || this == getStatement()->function);
369+
fb_assert(!isDefined() || flReload || this == getStatement()->function);
365370
}
366371
else
367372
{
@@ -371,7 +376,10 @@ ScanResult Function::scan(thread_db* tdbb, ObjectBase::Flag)
371376
RefPtr<MsgMetadata> outputMetadata(REF_NO_INCR, createMetadata(getOutputFields(), false));
372377
setOutputFormat(createFormat(pool, outputMetadata, true));
373378

374-
setImplemented(false);
379+
if (compiling)
380+
flReload = true;
381+
else
382+
setImplemented(false);
375383
}
376384

377385
if (!dbb->readOnly() &&

src/jrd/Routine.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,18 +174,19 @@ namespace Jrd
174174
virtual SLONG getSclType() const noexcept = 0;
175175

176176
private:
177-
USHORT id; // routine ID
178-
Statement* statement; // compiled routine statement
179-
bool implemented; // Is the packaged routine missing the body/entrypoint?
180-
bool defined; // UDF has its implementation module available
181-
USHORT defaultCount; // default input arguments
182-
const Format* inputFormat; // input format
183-
const Format* outputFormat; // output format
177+
USHORT id; // routine ID
178+
Statement* statement; // compiled routine statement
179+
bool implemented; // Is the packaged routine missing the body/entrypoint?
180+
bool defined; // UDF has its implementation module available
181+
USHORT defaultCount; // default input arguments
182+
const Format* inputFormat; // input format
183+
const Format* outputFormat; // output format
184184
Firebird::Array<NestConst<Parameter> > inputFields; // array of field blocks
185185
Firebird::Array<NestConst<Parameter> > outputFields; // array of field blocks
186186

187187
public:
188188
bool flReload;
189+
bool compiling = false; // Do not try to load routine's BLR in scan/reload during compile
189190

190191
public:
191192
Jrd::UserId* invoker; // Invoker ID

src/jrd/SystemTriggers.epp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,10 @@ void SystemTriggers::executeAfterInsertTriggers(thread_db* tdbb, jrd_rel* relati
17251725
case rel_procedures:
17261726
afterInsertProcedure(tdbb, record);
17271727
break;
1728+
1729+
case rel_funs:
1730+
afterInsertFunction(tdbb, record);
1731+
break;
17281732
}
17291733
}
17301734

src/jrd/met.epp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,7 +2725,9 @@ ScanResult jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag flags)
27252725
if (!getExternal())
27262726
setDefined(false);
27272727
}
2728-
else if (!(flags & CacheFlag::MINISCAN))
2728+
else if (compiling || (flags & CacheFlag::MINISCAN))
2729+
flReload = true;
2730+
else
27292731
{
27302732
const string name = getName().toQuotedString();
27312733

@@ -2746,8 +2748,6 @@ ScanResult jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag flags)
27462748
Arg::StatusVector(temp_status.begin())).raise();
27472749
}
27482750
}
2749-
else
2750-
flReload = true;
27512751
}
27522752
catch (const Exception&)
27532753
{
@@ -2773,7 +2773,10 @@ ScanResult jrd_prc::scan(thread_db* tdbb, ObjectBase::Flag flags)
27732773
setOutputFormat(
27742774
Routine::createFormat(getPermanent()->getPool(), outputMetadata, true));
27752775

2776-
setImplemented(false);
2776+
if (compiling)
2777+
flReload = true;
2778+
else
2779+
setImplemented(false);
27772780
}
27782781

27792782
if (!dbb->readOnly() &&
@@ -2819,6 +2822,10 @@ ScanResult jrd_prc::reload(thread_db* tdbb, ObjectBase::Flag /*unused*/)
28192822
P IN RDB$PROCEDURES
28202823
WITH P.RDB$PROCEDURE_ID EQ this->getId()
28212824
{
2825+
// sanity check
2826+
if (compiling || P.RDB$PROCEDURE_BLR.NULL)
2827+
return ScanResult::REPEAT;
2828+
28222829
MemoryPool* const csb_pool = tdbb->getDatabase()->createPool(ALLOC_ARGS0);
28232830
Jrd::ContextPoolHolder context(tdbb, csb_pool);
28242831

0 commit comments

Comments
 (0)