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

WIP (i.e. a lot of noisy debugging), but collation created in one transaction remains invisible in others

This commit is contained in:
AlexPeshkoff 2024-06-13 20:23:27 +03:00
parent c801683372
commit 8216d90e5b
5 changed files with 128 additions and 47 deletions

View File

@ -2813,8 +2813,6 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq
METD_drop_procedure(transaction, QualifiedName(name, package));
MetadataCache::dsql_cache_release(tdbb, SYM_procedure, name, package);
}
}
void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -2898,6 +2896,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
Attachment* const attachment = transaction->getAttachment();
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
bool modified = false;
MetaId id;
DsqlStatement* statement = dsqlScratch->getDsqlStatement();
@ -2913,10 +2912,17 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
MetaName(P.RDB$PROCEDURE_NAME));
}
if (!secondPass && runTriggers && package.isEmpty())
id = P.RDB$PROCEDURE_ID;
if (!secondPass && runTriggers)
{
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_ALTER_PROCEDURE, name, NULL);
if (package.isEmpty())
{
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_ALTER_PROCEDURE, name, NULL);
}
MetadataCache::oldVersion(tdbb, obj_procedure, id);
}
MODIFY P
@ -3060,6 +3066,9 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
END_FOR
}
if (secondPass && modified)
MetadataCache::newVersion(tdbb, obj_procedure, id);
return modified;
}
@ -3985,6 +3994,8 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_CREATE_COLLATION, name, NULL);
MetadataCache::oldVersion(tdbb, obj_charset, forCharSetId);
AutoCacheRequest request(tdbb, drq_s_colls, DYN_REQUESTS);
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
@ -4132,13 +4143,7 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
storePrivileges(tdbb, transaction, name, obj_collation, USAGE_PRIVILEGES);
auto* cs = MetadataCache::getCharSet(tdbb, forCharSetId, CacheFlag::AUTOCREATE | CacheFlag::NOCOMMIT);
if (!cs)
{
ERR_post(Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_charset_not_found) << Arg::Num(forCharSetId));
}
cs->resetDependentObject(tdbb, ElementBase::ResetType::Recompile);
MetadataCache::newVersion(tdbb, obj_charset, forCharSetId);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,
DDL_TRIGGER_CREATE_COLLATION, name, NULL);

View File

@ -605,8 +605,6 @@ public:
ObjectBase::Flag f(listEntry->getFlags());
//printf("gO %s %02x %lld (%lld)\n", listEntry->object->c_name(), f, listEntry->traNumber, currentTrans);
if ((!(f & CacheFlag::COMMITTED)) && (listEntry->traNumber != currentTrans))
printf("Oblom\n");
if ((f & CacheFlag::COMMITTED) ||
// committed (i.e. confirmed) objects are freely available
@ -621,7 +619,7 @@ public:
if (fl & CacheFlag::ERASED)
continue;
return nullptr;
return nullptr; // object dropped
}
// required entry found in the list
@ -638,6 +636,8 @@ public:
}
return obj;
}
else
printf("Oblom\n");
}
return nullptr; // object created (not by us) and not committed yet
@ -660,7 +660,7 @@ public:
do
{
while(oldVal && oldVal->isBusy(oldVal->traNumber))
while(oldVal && oldVal->isBusy(newVal->traNumber))
{
// modified in transaction oldVal->traNumber
if (TransactionNumber::isDead(tdbb, oldVal->traNumber))
@ -725,6 +725,8 @@ public:
fb_assert((getFlags() & CacheFlag::IGNORE_MASK) == 0);
fb_assert(traNumber == currentTrans);
printf("commit %s %lld=>%lld\n", object->c_name(), traNumber, nextTrans);
if (strcmp(object->c_name(), "ISO88591") == 0)
printf("ISO");
traNumber = nextTrans;
version = VersionSupport::next(tdbb);
@ -747,8 +749,11 @@ public:
if (entry.replace(list, entry->next))
{
entry->retire();
entry->next = nullptr;
OBJ::destroy(tdbb, entry->object);
entry->object = nullptr;
entry->retire();
entry = list;
}
}
@ -1136,7 +1141,7 @@ public:
if (data)
{
auto rc = data->getObject(tdbb, fl);
if (rc)
//if (rc)
return rc;
}
}
@ -1153,7 +1158,6 @@ public:
#endif
}
private:
Versioned* makeObject(thread_db* tdbb, MetaId id, ObjectBase::Flag fl)
{
if (id >= getCount())
@ -1187,7 +1191,6 @@ private:
return nullptr;
}
public:
StoredElement* lookup(thread_db*tdbb, std::function<bool(Permanent* val)> cmp) const
{
auto a = m_objects.readAccessor();

View File

@ -696,13 +696,20 @@ namespace
switch (phase)
{
case 0:
{
T* routine = lookupById(tdbb, work->dfw_id, CacheFlag::NOSCAN);
if (routine)
routine->rollback(tdbb);
return false;
}
case 1:
case 2:
case 3:
case 4:
return true;
case 5:
case 3:
{
const bool compile = !work->findArg(dfw_arg_check_blr);
getDependencies(work, compile, transaction);
@ -726,7 +733,7 @@ namespace
{
SET_TDBB(tdbb);
const QualifiedName name(work->dfw_name, work->dfw_package);
Routine* routine;
T* routine;
fprintf(stderr, "routine %d %s ph %d\n", work->dfw_id, name.c_str(), phase);
@ -734,8 +741,12 @@ namespace
{
case 0:
routine = lookupById(tdbb, work->dfw_id, CacheFlag::NOSCAN);
if (routine && routine->getPermanent()->existenceLock)
LCK_release(tdbb, routine->getPermanent()->existenceLock);
if (routine)
{
if (routine->existenceLock)
LCK_release(tdbb, routine->existenceLock);
routine->rollback(tdbb);
}
return false;
@ -748,11 +759,11 @@ namespace
if (!routine)
return false;
if (routine->getPermanent()->existenceLock)
if (routine->existenceLock)
{
// Let routine be deleted if only this transaction is using it
//if (!routine->getPermanent()->existenceLock->exclLock(tdbb))
//if (!routine->existenceLock->exclLock(tdbb))
// !!!!!!!!!!!!!!!!!!!!!!!!!!! raiseRoutineInUseError(routine, name);
}
@ -767,7 +778,7 @@ namespace
routine = lookupById(tdbb, work->dfw_id, CacheFlag::NOSCAN);
if (!routine)
return false;
/*
if (routine->getStatement())
{
//if (routine->getStatement()->isActive())
@ -777,7 +788,7 @@ namespace
routine->releaseStatement(tdbb);
}
*/
// delete dependency lists
if (work->dfw_package.isEmpty())
@ -791,8 +802,8 @@ namespace
*/
// routine->flags = (Routine::FLAG_OBSOLETE | Routine::FLAG_BEING_ALTERED);
if (routine->getPermanent()->existenceLock)
LCK_release(tdbb, routine->getPermanent()->existenceLock);
if (routine->existenceLock)
LCK_release(tdbb, routine->existenceLock);
// Now handle the new definition
bool compile = !work->findArg(dfw_arg_check_blr);
@ -852,8 +863,8 @@ namespace
if (!routine)
return false;
if (routine->getPermanent()->existenceLock)
LCK_release(tdbb, routine->getPermanent()->existenceLock);
if (routine->existenceLock)
LCK_release(tdbb, routine->existenceLock);
return false;
@ -878,18 +889,19 @@ namespace
if (!routine)
return false;
/*
if (routine->getStatement())
{
routine->releaseStatement(tdbb);
}
}*/
// delete dependency lists
if (work->dfw_package.isEmpty())
MET_delete_dependencies(tdbb, work->dfw_name, objType, transaction);
//if (routine->getPermanent()->existenceLock)
// routine->getPermanent()->existenceLock->releaseLock(tdbb, ExistenceLock::ReleaseMethod::DropObject);
//if (routine->existenceLock)
// routine->existenceLock->releaseLock(tdbb, ExistenceLock::ReleaseMethod::DropObject);
break;
}
@ -987,8 +999,9 @@ namespace
}
};
class FunctionManager : public RoutineManager<FunctionManager, Function, obj_udf,
Function::lookup, Function::lookup>
class FunctionManager : public RoutineManager<FunctionManager, Cached::Function, obj_udf,
// Function::lookup, Function::lookup>
MetadataCache::lookupFunction, MetadataCache::lookupFunction>
{
public:
static const char* const getTypeStr()
@ -1002,8 +1015,9 @@ namespace
static void checkOutParamDependencies(thread_db* tdbb, DeferredWork* work, jrd_tra* transaction);
};
class ProcedureManager : public RoutineManager<ProcedureManager, jrd_prc, obj_procedure,
MetadataCache::lookup_procedure_id, MetadataCache::lookup_procedure>
class ProcedureManager : public RoutineManager<ProcedureManager, Cached::Procedure, obj_procedure,
// MetadataCache::lookup_procedure_id, MetadataCache::lookup_procedure>
MetadataCache::lookupProcedure, MetadataCache::lookupProcedure>
{
public:
static const char* const getTypeStr()

View File

@ -490,7 +490,7 @@ void MetadataCache::cleanup(thread_db* tdbb)
}
};
for (int i = 1; i < DB_TRIGGER_MAX; ++i)
for (unsigned i = 1; i < DB_TRIGGER_MAX; ++i)
cleanSet(mdc_triggers[i]);
cleanSet(mdc_ddl_triggers);
}
@ -2731,7 +2731,7 @@ jrd_rel* MetadataCache::lookup_relation_id(thread_db* tdbb, MetaId id, ObjectBas
}
CharSetVers* MetadataCache::lookup_charset(thread_db* tdbb, MetaId id, ObjectBase::Flag flags)
CharSetVers* MetadataCache::lookup_charset(thread_db* tdbb, CSetId id, ObjectBase::Flag flags)
{
SET_TDBB(tdbb);
MetadataCache* mdc = tdbb->getDatabase()->dbb_mdc;
@ -5215,7 +5215,6 @@ Cached::Function* MetadataCache::lookupFunction(thread_db* tdbb, const Qualified
{
SET_TDBB(tdbb);
Attachment* attachment = tdbb->getAttachment();
MetadataCache* mdc = tdbb->getDatabase()->dbb_mdc;
// See if we already know the relation by name
@ -5228,12 +5227,27 @@ Cached::Function* MetadataCache::lookupFunction(thread_db* tdbb, const Qualified
return fun ? fun->getPermanent() : nullptr;
}
Cached::Function* MetadataCache::lookupFunction(thread_db* tdbb, MetaId id, ObjectBase::Flag flags)
{
SET_TDBB(tdbb);
MetadataCache* mdc = tdbb->getDatabase()->dbb_mdc;
auto* rc = mdc->mdc_functions.getData(tdbb, id, flags);
if (rc || !(flags & CacheFlag::AUTOCREATE))
return rc;
if (auto* fun = mdc->mdc_functions.getObject(tdbb, id, flags))
rc = fun->getPermanent();
return rc;
}
Cached::Procedure* MetadataCache::lookupProcedure(thread_db* tdbb, MetaId id, ObjectBase::Flag flags)
{
SET_TDBB(tdbb);
MetadataCache* mdc = tdbb->getDatabase()->dbb_mdc;
auto rc = mdc->mdc_procedures.getData(tdbb, id, flags);
auto* rc = mdc->mdc_procedures.getData(tdbb, id, flags);
if (rc || !(flags & CacheFlag::AUTOCREATE))
return rc;
@ -5300,3 +5314,28 @@ Cached::CharSet* MetadataCache::getCharSet(thread_db* tdbb, CSetId id, ObjectBas
return rc;
}
void MetadataCache::changeVersion(thread_db* tdbb, bool loadOld, ObjectType objType, MetaId id)
{
auto* mdc = tdbb->getDatabase()->dbb_mdc;
switch(objType)
{
case obj_procedure:
changeVersion(tdbb, loadOld, mdc->mdc_procedures, id);
break;
case obj_charset:
changeVersion(tdbb, loadOld, mdc->mdc_charsets, id);
break;
/*
case :
changeVersion(tdbb, loadOld, mdc->, id);
break;
*/
default:
fb_assert(!"object in changeVersion");
break;
}
}

View File

@ -294,7 +294,7 @@ public:
static Cached::Procedure* lookupProcedure(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags);
static Cached::Procedure* lookupProcedure(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static Cached::Function* lookupFunction(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags);
//static Cached::Function* lookupFunction(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static Cached::Function* lookupFunction(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static jrd_rel* lookup_relation(thread_db*, const MetaName&);
static jrd_rel* lookup_relation_id(thread_db*, MetaId, ObjectBase::Flag flags);
static Cached::Relation* lookupRelation(thread_db* tdbb, const MetaName& name, ObjectBase::Flag flags);
@ -330,7 +330,7 @@ public:
static bool dsql_cache_use(thread_db* tdbb, sym_type type, const MetaName& name, const MetaName& package = "");
// end of met_proto.h
static CharSetVers* lookup_charset(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
static CharSetVers* lookup_charset(thread_db* tdbb, CSetId id, ObjectBase::Flag flags);
static void release_temp_tables(thread_db* tdbb, jrd_tra* transaction);
static void retain_temp_tables(thread_db* tdbb, jrd_tra* transaction, TraNumber new_number);
@ -360,7 +360,27 @@ public:
return mdc_generators.lookup(id, name);
}
static void oldVersion(thread_db* tdbb, ObjectType objType, MetaId id)
{
changeVersion(tdbb, true, objType, id);
}
static void newVersion(thread_db* tdbb, ObjectType objType, MetaId id)
{
changeVersion(tdbb, false, objType, id);
}
private:
static void changeVersion(thread_db* tdbb, bool loadOld, ObjectType objType, MetaId id);
template <typename C>
static void changeVersion(thread_db* tdbb, bool loadOld, CacheVector<C>& vector, MetaId id)
{
auto* ver = loadOld ? vector.getObject(tdbb, id, CacheFlag::AUTOCREATE) :
vector.makeObject(tdbb, id, CacheFlag::NOCOMMIT);
fb_assert(ver);
}
class GeneratorFinder
{
typedef Firebird::MutexLockGuard Guard;