@@ -117,11 +117,12 @@ namespace CacheFlag
117117 static constexpr ObjectBase::Flag RETIRED = 0x040 ; // object is in a process of GC
118118 static constexpr ObjectBase::Flag MINISCAN = 0x080 ; // perform minimum scan and set cache entry to reload state
119119 static constexpr ObjectBase::Flag DB_VERSION = 0x100 ; // execute version upgrade in database
120+ static constexpr ObjectBase::Flag DEPENDS = 0x200 ; // collect object dependencies
120121
121122 // Useful combinations
122123 static constexpr ObjectBase::Flag TAG_FOR_UPDATE = NOCOMMIT | MINISCAN | DB_VERSION ;
123124 static constexpr ObjectBase::Flag OLD_DROP = MINISCAN | AUTOCREATE ;
124- static constexpr ObjectBase::Flag OLD_ALTER = MINISCAN | AUTOCREATE ;
125+ static constexpr ObjectBase::Flag OLD_ALTER = MINISCAN | AUTOCREATE | DEPENDS ;
125126}
126127
127128
@@ -747,8 +748,7 @@ class CacheElement : public ElementBase, public P
747748 ListEntry<Versioned>* newEntry = nullptr ;
748749 try
749750 {
750- newEntry = FB_NEW_POOL (*getDefaultMemoryPool ())
751- ListEntry<Versioned>(obj, traNum, fl & ~CacheFlag::ERASED );
751+ newEntry = FB_NEW ListEntry<Versioned>(obj, traNum, fl & ~CacheFlag::ERASED );
752752 }
753753 catch (const Firebird::Exception&)
754754 {
@@ -812,7 +812,7 @@ class CacheElement : public ElementBase, public P
812812
813813 if (!cur)
814814 cur = TransactionNumber::current (tdbb);
815- ListEntry<Versioned>* newEntry = FB_NEW_POOL (* getDefaultMemoryPool ()) ListEntry<Versioned>(obj, cur, fl);
815+ ListEntry<Versioned>* newEntry = FB_NEW ListEntry<Versioned>(obj, cur, fl);
816816 if (!ListEntry<Versioned>::add (tdbb, list, newEntry))
817817 {
818818 newEntry->cleanup (tdbb, false );
@@ -990,13 +990,20 @@ class CacheElement : public ElementBase, public P
990990 CacheFlag::COMMITTED | CacheFlag::MINISCAN | CacheFlag::DB_VERSION , l.getPointer ());
991991 if (l.replace (list, newEntry))
992992 return true ;
993+
994+ // undo changes
993995 delete newEntry;
994996
995997 // Someone already added entry - see is it OK for us
996998 l.set (list);
997999 return ListEntry<Versioned>::upgradable (l, from);
9981000 }
9991001
1002+ bool nameIs (const QualifiedName& name)
1003+ {
1004+ return this ->getName () == name;
1005+ }
1006+
10001007private:
10011008 void setNewResetAt (TraNumber oldVal, TraNumber newVal)
10021009 {
@@ -1016,6 +1023,21 @@ struct NoData
10161023 NoData () { }
10171024};
10181025
1026+ template <typename EXTEND = NoData>
1027+ struct ExName
1028+ {
1029+ ExName (const QualifiedName& name)
1030+ : name(name)
1031+ { }
1032+
1033+ ExName (const QualifiedName& name, EXTEND ex)
1034+ : name(name), ex(ex)
1035+ { }
1036+
1037+ const QualifiedName& name;
1038+ EXTEND ex = EXTEND ();
1039+ };
1040+
10191041template <class StoredElement , unsigned SUBARRAY_SHIFT = 8 , typename EXTEND = NoData>
10201042class CacheVector : public Firebird ::PermanentStorage
10211043{
@@ -1227,36 +1249,6 @@ class CacheVector : public Firebird::PermanentStorage
12271249 return false ;
12281250 }
12291251
1230- template <typename F>
1231- StoredElement* lookup (thread_db* tdbb, F&& cmp, ObjectBase::Flag fl) const
1232- {
1233- auto a = m_objects.readAccessor ();
1234- for (FB_SIZE_T i = 0 ; i < a->getCount (); ++i)
1235- {
1236- SubArrayData* const sub = a->value (i).load (atomics::memory_order_relaxed);
1237- if (!sub)
1238- continue ;
1239-
1240- for (SubArrayData* end = &sub[SUBARRAY_SIZE ]; sub < end--;)
1241- {
1242- StoredElement* ptr = end->load (atomics::memory_order_relaxed);
1243- if (ptr)
1244- {
1245- auto listEntry = ptr->getEntry (tdbb, TransactionNumber::current (tdbb), fl | CacheFlag::MINISCAN );
1246- if (listEntry && cmp (ptr))
1247- {
1248- // if (!(fl & (CacheFlag::ERASED | CacheFlag::MINISCAN)))
1249- if (!(fl & CacheFlag::ERASED ))
1250- ptr->reload (tdbb, fl); // found object to be reloaded w/o MINISCAN flag
1251- return ptr;
1252- }
1253- }
1254- }
1255- }
1256-
1257- return nullptr ;
1258- }
1259-
12601252 bool lookup (thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag fl,
12611253 StoredElement** element, Versioned** versioned)
12621254 {
@@ -1274,9 +1266,9 @@ class CacheVector : public Firebird::PermanentStorage
12741266 {
12751267 auto listEntry = ptr->getEntry (tdbb, TransactionNumber::current (tdbb), fl | CacheFlag::MINISCAN );
12761268
1277- if (listEntry && ptr->getName () == name)
1269+ if (listEntry && ptr->nameIs ( name) )
12781270 {
1279- if (!(fl & CacheFlag::ERASED ))
1271+ if (!(fl & ( CacheFlag::ERASED | CacheFlag:: MINISCAN ) ))
12801272 ptr->reload (tdbb, fl); // found object to be reloaded w/o MINISCAN flag
12811273 if (versioned)
12821274 *versioned = listEntry->getVersioned ();
@@ -1292,7 +1284,7 @@ class CacheVector : public Firebird::PermanentStorage
12921284 if (!(fl & CacheFlag::AUTOCREATE ))
12931285 return false ;
12941286
1295- auto id = Versioned::getIdByName (tdbb, name);
1287+ auto id = Versioned::getIdByName (tdbb, { name, m_extend} );
12961288 if (!id.has_value ())
12971289 return false ;
12981290
0 commit comments