Skip to content

Commit 4eeea4e

Browse files
committed
Fixed execution & creation of DB-wide triggers
1 parent 7b45f27 commit 4eeea4e

File tree

9 files changed

+158
-146
lines changed

9 files changed

+158
-146
lines changed

src/jrd/CacheVector.h

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,17 @@ class ElementBase
7575

7676
namespace CacheFlag
7777
{
78-
static const ObjectBase::Flag COMMITTED = 0x01; // version already committed
79-
static const ObjectBase::Flag ERASED = 0x02; // object erased
80-
static const ObjectBase::Flag NOSCAN = 0x04; // do not call Versioned::scan()
81-
static const ObjectBase::Flag AUTOCREATE = 0x08; // create initial version automatically
82-
static const ObjectBase::Flag NOCOMMIT = 0x10; // do not commit created version
83-
static const ObjectBase::Flag RET_ERASED = 0x20; // return erased objects
84-
static const ObjectBase::Flag RETIRED = 0x40; // object is in a process of GC
85-
static const ObjectBase::Flag UPGRADE = 0x80; // create new versions for already existing in a cache objects
78+
static constexpr ObjectBase::Flag COMMITTED = 0x01; // version already committed
79+
static constexpr ObjectBase::Flag ERASED = 0x02; // object erased
80+
static constexpr ObjectBase::Flag NOSCAN = 0x04; // do not call Versioned::scan()
81+
static constexpr ObjectBase::Flag AUTOCREATE = 0x08; // create initial version automatically
82+
static constexpr ObjectBase::Flag NOCOMMIT = 0x10; // do not commit created version
83+
static constexpr ObjectBase::Flag RET_ERASED = 0x20; // return erased objects
84+
static constexpr ObjectBase::Flag RETIRED = 0x40; // object is in a process of GC
85+
static constexpr ObjectBase::Flag UPGRADE = 0x80; // create new versions for already existing in a cache objects
86+
87+
// Useful combinations
88+
static constexpr ObjectBase::Flag TAG_FOR_UPDATE = NOCOMMIT | NOSCAN;
8689
}
8790

8891

@@ -787,6 +790,31 @@ class CacheElement : public ElementBase, public P
787790
return Versioned::objectType();
788791
}
789792

793+
void tagForUpdate(thread_db* tdbb)
794+
{
795+
TraNumber traNum;
796+
797+
switch (isAvailable(tdbb, &traNum))
798+
{
799+
case OCCUPIED:
800+
Firebird::fatal_exception::raiseFmt("tagForUpdate: %s %s is used by transaction %d\n",
801+
Versioned::objectFamily(this), this->c_name(), traNum);
802+
803+
case MODIFIED:
804+
return;
805+
806+
case MISSING:
807+
case READY:
808+
if (scanInProgress())
809+
{
810+
Firebird::fatal_exception::raiseFmt("tagForUpdate: %s %s is scanned by us\n",
811+
Versioned::objectFamily(this), this->c_name());
812+
}
813+
makeObject(tdbb, CacheFlag::TAG_FOR_UPDATE);
814+
return;
815+
}
816+
}
817+
790818
private:
791819
void setNewResetAt(TraNumber oldVal, TraNumber newVal)
792820
{
@@ -979,31 +1007,10 @@ class CacheVector : public Firebird::PermanentStorage
9791007

9801008
StoredElement* data = ptr->load(atomics::memory_order_acquire);
9811009
if (data)
982-
{
983-
TraNumber traNum;
984-
switch (data->isAvailable(tdbb, &traNum))
985-
{
986-
case StoredElement::OCCUPIED:
987-
Firebird::fatal_exception::raiseFmt("tagForUpdate: %s %s is used by transaction %d\n",
988-
Versioned::objectFamily(data), data->c_name(), traNum);
989-
990-
case StoredElement::MODIFIED:
991-
return;
992-
993-
case StoredElement::MISSING:
994-
case StoredElement::READY:
995-
if (data->scanInProgress())
996-
{
997-
Firebird::fatal_exception::raiseFmt("tagForUpdate: %s %s is scanned by us\n",
998-
Versioned::objectFamily(data), data->c_name());
999-
}
1000-
data->makeObject(tdbb, fl);
1001-
return;
1002-
}
1003-
}
1010+
data->tagForUpdate(tdbb);
10041011
}
10051012

1006-
makeObject(tdbb, id, fl);
1013+
makeObject(tdbb, id, CacheFlag::TAG_FOR_UPDATE);
10071014
}
10081015

10091016
template <typename F>

src/jrd/Relation.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -546,18 +546,11 @@ void RelationPermanent::tagForUpdate(thread_db* tdbb, const MetaName name)
546546
CacheFlag::AUTOCREATE | CacheFlag::NOCOMMIT | CacheFlag::NOSCAN);
547547
fb_assert(relation);
548548

549-
if (relation)
550-
relation->tagForUpdate(tdbb);
551-
}
552-
553-
554-
void RelationPermanent::tagForUpdate(thread_db* tdbb)
555-
{
556-
if (getId())
549+
if (relation && relation->getId())
557550
{
558-
MetadataCache::tagForUpdate<Cached::Relation>(tdbb, getId());
559-
rel_flags |= REL_format;
560-
DFW_post_work(tdbb->getTransaction(), dfw_commit_relation, nullptr, getId());
551+
relation->tagForUpdate(tdbb);
552+
relation->rel_flags |= REL_format;
553+
DFW_post_work(tdbb->getTransaction(), dfw_commit_relation, nullptr, relation->getId());
561554
}
562555
}
563556

src/jrd/Relation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ class RelationPermanent : public Firebird::PermanentStorage
893893
static int rescan_ast_relation(void* ast_object);
894894
static int blocking_ast_relation(void* ast_object);
895895

896-
void tagForUpdate(thread_db* tdbb); // Relation must be updated on next use or commit
896+
// Relation must be updated on next use or commit
897897
static void tagForUpdate(thread_db* tdbb, const MetaName name);
898898

899899
vec<Format*>* rel_formats; // Known record formats

src/jrd/constants.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ enum TriggerAction {
323323
TRIGGER_UPDATE = 2,
324324
TRIGGER_DELETE = 3,
325325
TRIGGER_CONNECT = 4,
326-
TRIGGER_DISCONNECT = 5,
326+
TRIGGER_DISCONNECT = 5,
327327
TRIGGER_TRANS_START = 6,
328328
TRIGGER_TRANS_COMMIT = 7,
329329
TRIGGER_TRANS_ROLLBACK = 8,
@@ -342,7 +342,8 @@ const unsigned DB_TRIGGER_DISCONNECT = 1;
342342
const unsigned DB_TRIGGER_TRANS_START = 2;
343343
const unsigned DB_TRIGGER_TRANS_COMMIT = 3;
344344
const unsigned DB_TRIGGER_TRANS_ROLLBACK = 4;
345-
const unsigned DB_TRIGGER_MAX = 5;
345+
const unsigned DB_TRIGGER_DDL = 5;
346+
const unsigned DB_TRIGGERS_COUNT = 6;
346347

347348
static const char* const DDL_TRIGGER_ACTION_NAMES[][2] =
348349
{

src/jrd/jrd.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,14 +2154,14 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
21542154
{
21552155
// load all database triggers
21562156
MetadataCache* mdc = dbb->dbb_mdc;
2157-
mdc->load_db_triggers(tdbb, DB_TRIGGER_CONNECT);
2158-
mdc->load_db_triggers(tdbb, DB_TRIGGER_DISCONNECT);
2159-
mdc->load_db_triggers(tdbb, DB_TRIGGER_TRANS_START);
2160-
mdc->load_db_triggers(tdbb, DB_TRIGGER_TRANS_COMMIT);
2161-
mdc->load_db_triggers(tdbb, DB_TRIGGER_TRANS_ROLLBACK);
2157+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_CONNECT);
2158+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_DISCONNECT);
2159+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_TRANS_START);
2160+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_TRANS_COMMIT);
2161+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_TRANS_ROLLBACK);
21622162

21632163
// load DDL triggers
2164-
mdc->load_ddl_triggers(tdbb);
2164+
mdc->loadDbTriggers(tdbb, DB_TRIGGER_DDL);
21652165

21662166
auto* trig_connect = dbb->dbb_mdc->getTriggers(tdbb, DB_TRIGGER_CONNECT | TRIGGER_TYPE_DB);
21672167
if (trig_connect && *trig_connect)

src/jrd/met.epp

Lines changed: 38 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -480,19 +480,15 @@ void MetadataCache::cleanup(thread_db* tdbb)
480480
mdc_functions.cleanup(tdbb);
481481
mdc_charsets.cleanup(tdbb);
482482

483-
auto cleanSet = [tdbb](TriggersSet& set)
483+
for (unsigned i = 0; i < DB_TRIGGERS_COUNT; ++i)
484484
{
485-
auto* ptr = set.load(atomics::memory_order_relaxed);
485+
auto* ptr = mdc_triggers[i].load(atomics::memory_order_relaxed);
486486
if (ptr)
487487
{
488488
Cached::Triggers::cleanup(tdbb, ptr);
489-
set.store(nullptr, atomics::memory_order_relaxed);
489+
mdc_triggers[i].store(nullptr, atomics::memory_order_relaxed);
490490
}
491-
};
492-
493-
for (unsigned i = 1; i < DB_TRIGGER_MAX; ++i)
494-
cleanSet(mdc_triggers[i]);
495-
cleanSet(mdc_ddl_triggers);
491+
}
496492
}
497493

498494

@@ -520,11 +516,9 @@ void MetadataCache::clear(thread_db* tdbb)
520516

521517
// Release global (db-level and DDL) triggers
522518

523-
for (unsigned i = 0; i < DB_TRIGGER_MAX; i++)
519+
for (unsigned i = 0; i < DB_TRIGGERS_COUNT; i++)
524520
MET_release_triggers(tdbb, &att->att_triggers[i], false);
525521

526-
MET_release_triggers(tdbb, &att->att_ddl_triggers, false);
527-
528522
// Release relation triggers
529523

530524
vec<jrd_rel*>* const relations = att->att_relations;
@@ -1522,30 +1516,30 @@ ScanResult DbTriggers::scan(thread_db* tdbb, ObjectBase::Flag flags)
15221516
CHECK_DBB(dbb);
15231517

15241518
auto type = perm->getId();
1525-
bool found = false;
1519+
FB_UINT64 mask = (type == DB_TRIGGER_DDL) ? TRIGGER_TYPE_MASK : ~FB_UINT64(0);
1520+
type = (type == DB_TRIGGER_DDL) ? TRIGGER_TYPE_DDL : type | TRIGGER_TYPE_DB;
15261521

15271522
AutoRequest trigger_request;
1523+
jrd_tra* trans = tdbb->getTransaction() ? tdbb->getTransaction() : attachment->getSysTransaction();
15281524

1529-
FOR(REQUEST_HANDLE trigger_request)
1525+
FOR(REQUEST_HANDLE trigger_request TRANSACTION_HANDLE trans)
15301526
TRG IN RDB$TRIGGERS
15311527
WITH TRG.RDB$RELATION_NAME MISSING AND
15321528
TRG.RDB$TRIGGER_INACTIVE EQ 0
15331529
SORTED BY TRG.RDB$TRIGGER_SEQUENCE
15341530
{
1535-
if ((TRG.RDB$TRIGGER_TYPE == type | TRIGGER_TYPE_DB) ||
1536-
(type == DB_TRIGGER_MAX && (TRG.RDB$TRIGGER_TYPE & TRIGGER_TYPE_MASK) == TRIGGER_TYPE_DDL))
1531+
if ((TRG.RDB$TRIGGER_TYPE & mask) == type)
15371532
{
1538-
found = true;
15391533
MET_load_trigger(tdbb, nullptr, TRG.RDB$TRIGGER_NAME, [this](int)->Triggers& {return *this;});
15401534
}
15411535
}
15421536
END_FOR
15431537

1544-
return found ? ScanResult::COMPLETE : ScanResult::MISS;
1538+
return ScanResult::COMPLETE;
15451539
}
15461540

15471541

1548-
void MetadataCache::load_db_triggers(thread_db* tdbb, int type, bool force)
1542+
void MetadataCache::loadDbTriggers(thread_db* tdbb, unsigned int type)
15491543
{
15501544
/**************************************
15511545
*
@@ -1563,46 +1557,37 @@ void MetadataCache::load_db_triggers(thread_db* tdbb, int type, bool force)
15631557
Database* dbb = tdbb->getDatabase();
15641558
CHECK_DBB(dbb);
15651559

1560+
fb_assert(type < DB_TRIGGERS_COUNT);
15661561
auto* cacheElement = mdc_triggers[type].load(atomics::memory_order_acquire);
1567-
if (force || !cacheElement)
1568-
{
1569-
if (!cacheElement)
1570-
{
1571-
// actual type will be taken into an account in DbTriggers::scan
1572-
auto* newCacheElement = FB_NEW_POOL(getPool())
1573-
Cached::Triggers(tdbb, getPool(), type, DbTriggers::makeLock, NoData());
1574-
if (mdc_triggers[type].compare_exchange_strong(cacheElement, newCacheElement,
1575-
atomics::memory_order_release, atomics::memory_order_acquire))
1576-
{
1577-
cacheElement = newCacheElement;
1578-
}
1579-
else
1580-
{
1581-
delete newCacheElement;
1582-
return;
1583-
}
1584-
}
15851562

1586-
DbTriggers* triggers = DbTriggers::create(tdbb, getPool(), cacheElement);
1587-
try
1563+
if (!cacheElement)
1564+
{
1565+
// actual type will be taken into an account in DbTriggers::scan
1566+
auto* newCacheElement = FB_NEW_POOL(getPool())
1567+
Cached::Triggers(tdbb, getPool(), type, DbTriggers::makeLock, NoData());
1568+
if (mdc_triggers[type].compare_exchange_strong(cacheElement, newCacheElement,
1569+
atomics::memory_order_release, atomics::memory_order_acquire))
15881570
{
1589-
if (cacheElement->storeObject(tdbb, triggers, 0) == StoreResult::DUP)
1590-
DbTriggers::destroy(tdbb, triggers);
1571+
cacheElement = newCacheElement;
15911572
}
1592-
catch(const Exception&)
1573+
else
15931574
{
1594-
DbTriggers::destroy(tdbb, triggers);
1595-
throw;
1575+
delete newCacheElement;
1576+
return;
15961577
}
15971578
}
1598-
}
1599-
16001579

1601-
// Load DDL triggers from RDB$TRIGGERS.
1602-
void MetadataCache::load_ddl_triggers(thread_db* tdbb, bool force)
1603-
{
1604-
// actual type will be taken into an account in DbTriggers::scan
1605-
load_db_triggers(tdbb, DB_TRIGGER_MAX, force);
1580+
DbTriggers* triggers = DbTriggers::create(tdbb, getPool(), cacheElement);
1581+
try
1582+
{
1583+
if (cacheElement->storeObject(tdbb, triggers, 0) == StoreResult::DUP)
1584+
DbTriggers::destroy(tdbb, triggers);
1585+
}
1586+
catch(const Exception&)
1587+
{
1588+
DbTriggers::destroy(tdbb, triggers);
1589+
throw;
1590+
}
16061591
}
16071592

16081593

@@ -4809,14 +4794,14 @@ void MetadataCache::invalidateReplSet(thread_db* tdbb)
48094794

48104795
Cached::Triggers* MetadataCache::getTriggersSet(thread_db* tdbb, MetaId triggerId)
48114796
{
4812-
if (triggerId & TRIGGER_TYPE_MASK == TRIGGER_TYPE_DB)
4797+
if ((triggerId & TRIGGER_TYPE_MASK) == TRIGGER_TYPE_DB)
48134798
{
48144799
triggerId &= ~TRIGGER_TYPE_MASK;
48154800
return mdc_triggers[triggerId].load(atomics::memory_order_acquire);
48164801
}
48174802

4818-
if (triggerId & TRIGGER_TYPE_MASK == TRIGGER_TYPE_DDL)
4819-
return mdc_ddl_triggers.load(atomics::memory_order_acquire);
4803+
if ((triggerId & TRIGGER_TYPE_MASK) == TRIGGER_TYPE_DDL)
4804+
return mdc_triggers[DB_TRIGGER_DDL].load(atomics::memory_order_acquire);
48204805

48214806
return nullptr;
48224807
}

src/jrd/met.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ class MetadataCache : public Firebird::PermanentStorage
234234
mdc_procedures(getPool()),
235235
mdc_functions(getPool()),
236236
mdc_charsets(getPool()),
237-
mdc_ddl_triggers(nullptr),
238237
mdc_version(0),
239238
mdc_cleanup_queue(pool)
240239
{
@@ -287,8 +286,7 @@ class MetadataCache : public Firebird::PermanentStorage
287286
#endif
288287
static void clear(thread_db* tdbb);
289288
static void update_partners(thread_db* tdbb);
290-
void load_db_triggers(thread_db* tdbb, int type, bool force = false);
291-
void load_ddl_triggers(thread_db* tdbb, bool force = false);
289+
void loadDbTriggers(thread_db* tdbb, unsigned int type);
292290
static jrd_prc* lookup_procedure(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags);
293291
static jrd_prc* lookup_procedure_id(thread_db* tdbb, MetaId id, ObjectBase::Flag flags);
294292
static Function* lookup_function(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag flags);
@@ -551,8 +549,7 @@ class MetadataCache : public Firebird::PermanentStorage
551549
CacheVector<Cached::Procedure> mdc_procedures;
552550
CacheVector<Cached::Function> mdc_functions; // User defined functions
553551
CacheVector<Cached::CharSet> mdc_charsets; // intl character set descriptions
554-
TriggersSet mdc_triggers[DB_TRIGGER_MAX];
555-
TriggersSet mdc_ddl_triggers;
552+
TriggersSet mdc_triggers[DB_TRIGGERS_COUNT];
556553

557554
std::atomic<MdcVersion> mdc_version; // Current version of metadata cache (should have 2 nums???????????????)
558555
CleanupQueue mdc_cleanup_queue;

src/jrd/trace/TraceJrdHelpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ class TraceTrigCompile
457457

458458
case TRIGGER_TYPE_DB:
459459
{
460-
m_action = type + DB_TRIGGER_MAX - 1;
460+
m_action = type + TRIGGER_CONNECT;
461461

462462
fb_assert(m_action == TRIGGER_CONNECT ||
463463
m_action == TRIGGER_DISCONNECT ||

0 commit comments

Comments
 (0)