@@ -115,6 +115,7 @@ static int blocking_ast_relation(void*);
115115static int partners_ast_relation(void*);
116116static int rescan_ast_relation(void*);
117117static ULONG get_rel_flags_from_FLAGS(USHORT);
118+ static USHORT get_sysrel_ods(jrd_rel*);
118119static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, SSHORT,
119120 USHORT, const MetaName&, const string&, const bid*, Nullable<bool> ssDefiner);
120121static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*);
@@ -4095,9 +4096,13 @@ static void scan_relation(thread_db* tdbb, jrd_rel* relation)
40954096 AutoCacheRequest request(tdbb, irq_r_fields, IRQ_REQUESTS);
40964097 CompilerScratch* csb = NULL;
40974098
4099+ bool found = false;
4100+
40984101 FOR(REQUEST_HANDLE request)
40994102 REL IN RDB$RELATIONS WITH REL.RDB$RELATION_ID EQ relation->rel_id
41004103 {
4104+ found = true;
4105+
41014106 // Pick up relation level stuff
41024107 relation->rel_current_fmt = REL.RDB$FORMAT;
41034108 vec<jrd_fld*>* vector = relation->rel_fields =
@@ -4371,6 +4376,30 @@ static void scan_relation(thread_db* tdbb, jrd_rel* relation)
43714376
43724377 delete csb;
43734378
4379+ if (!found && !(relation->rel_flags & REL_scanned))
4380+ {
4381+ // Relation was not found in RDB$RELATIONS. It could be system relation
4382+ // defined in INI for latest supported ODS while database is in older ODS.
4383+
4384+ const USHORT dbbOds = ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_version);
4385+
4386+ if (relation->isSystem() && dbbOds < ODS_CURRENT_VERSION &&
4387+ dbbOds < get_sysrel_ods(relation))
4388+ {
4389+ relation->rel_flags |= REL_scanned;
4390+ }
4391+ else
4392+ {
4393+ fb_assert(false);
4394+
4395+ string name(relation->rel_name);
4396+ if (name.isEmpty())
4397+ name.printf("<ID = %u>", relation->rel_id);
4398+
4399+ ERR_post(Arg::Gds(isc_relnotdef) << Arg::Str(name));
4400+ }
4401+ }
4402+
43744403 // We have just loaded the triggers onto the local vector triggers.
43754404 // It's now time to place them at their rightful place inside the relation block.
43764405
@@ -4776,6 +4805,37 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type)
47764805}
47774806
47784807
4808+ // Search system-defined list for given relation and return its ODS.
4809+ // Return zero, if not found.
4810+ static USHORT get_sysrel_ods(jrd_rel* relation)
4811+ {
4812+ if (relation->rel_id >= rel_MAX)
4813+ return 0;
4814+
4815+ #define RELATION(name, id, ods, type) id, ods,
4816+ #define FIELD(symbol, name, id, update, ods)
4817+ #define END_RELATION
4818+
4819+ static const int rels[] =
4820+ {
4821+ #include "../jrd/relations.h"
4822+ 0, 0
4823+ };
4824+
4825+ #undef RELATION
4826+ #undef FIELD
4827+ #undef END_RELATION
4828+
4829+ for (int n = 0; n < FB_NELEM(rels); n += 2)
4830+ {
4831+ if (relation->rel_id == rels[n])
4832+ return rels[n + 1];
4833+ }
4834+
4835+ return 0;
4836+ }
4837+
4838+
47794839static void get_trigger(thread_db* tdbb, jrd_rel* relation,
47804840 bid* blob_id, bid* debug_blob_id, TrigVector** ptr,
47814841 const TEXT* name, FB_UINT64 type,
0 commit comments