From 9926ab88b4f3781620de80f8613f07146a21dd64 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Thu, 1 Aug 2024 22:44:08 -0300 Subject: [PATCH] Reimplement system triggers in C++/GDML code. --- builds/win32/msvc15/engine_static.vcxproj | 3 + .../msvc15/engine_static.vcxproj.filters | 11 +- builds/win32/preprocess.bat | 2 +- src/dsql/StmtNodes.cpp | 19 +- src/jrd/Monitoring.cpp | 7 +- src/jrd/RecordSourceNodes.cpp | 2 - src/jrd/Relation.h | 2 - src/jrd/Statement.h | 3 +- src/jrd/SystemTriggers.epp | 1275 ++++++++++++++ src/jrd/SystemTriggers.h | 57 + src/jrd/dfw.epp | 4 +- src/jrd/exe.cpp | 125 +- src/jrd/ini.epp | 276 +-- src/jrd/ini_proto.h | 2 +- src/jrd/irq.h | 1 - src/jrd/jrd.cpp | 21 +- src/jrd/jrd.h | 1 - src/jrd/met.epp | 158 +- src/jrd/met_proto.h | 1 - src/jrd/mov.cpp | 9 + src/jrd/mov_proto.h | 1 + src/jrd/trace/TraceJrdHelpers.h | 6 +- src/jrd/trig.h | 1528 ----------------- 23 files changed, 1532 insertions(+), 1982 deletions(-) create mode 100644 src/jrd/SystemTriggers.epp create mode 100644 src/jrd/SystemTriggers.h diff --git a/builds/win32/msvc15/engine_static.vcxproj b/builds/win32/msvc15/engine_static.vcxproj index c326eb491a..c2b465b4cc 100644 --- a/builds/win32/msvc15/engine_static.vcxproj +++ b/builds/win32/msvc15/engine_static.vcxproj @@ -31,6 +31,7 @@ + @@ -350,6 +351,7 @@ + @@ -390,6 +392,7 @@ + diff --git a/builds/win32/msvc15/engine_static.vcxproj.filters b/builds/win32/msvc15/engine_static.vcxproj.filters index b1e3589847..7aa65c72ea 100644 --- a/builds/win32/msvc15/engine_static.vcxproj.filters +++ b/builds/win32/msvc15/engine_static.vcxproj.filters @@ -423,6 +423,9 @@ JRD files\GPRE cpp + + JRD files\GPRE cpp + JRD files\GPRE cpp @@ -1085,6 +1088,9 @@ Header files + + Header files + Header files @@ -1139,6 +1145,9 @@ JRD files\GPRE files + + JRD files\GPRE files + Services @@ -1146,4 +1155,4 @@ DSQL - \ No newline at end of file + diff --git a/builds/win32/preprocess.bat b/builds/win32/preprocess.bat index bbc15d21fa..488b8dcbd9 100644 --- a/builds/win32/preprocess.bat +++ b/builds/win32/preprocess.bat @@ -78,7 +78,7 @@ goto :EOF @for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx @for %%i in (DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx @for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i -@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx +@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, scl, Function, SystemTriggers) do @call :PREPROCESS jrd %%i -gds_cxx @for %%i in (extract, isql, show) do @call :PREPROCESS isql %%i -ocxx @for %%i in (dba) do @call :PREPROCESS utilities/gstat %%i @for %%i in (stats) do @call :PREPROCESS utilities %%i diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index e6f9351f1d..7e23a403f6 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -2781,7 +2781,7 @@ const StmtNode* EraseNode::erase(thread_db* tdbb, Request* request, WhichTrigger spPreTriggers.release(); // Handle post operation trigger. - if (relation->rel_post_erase && whichTrig != PRE_TRIG) + if ((relation->rel_post_erase || relation->isSystem()) && whichTrig != PRE_TRIG) { EXE_execute_triggers(tdbb, &relation->rel_post_erase, rpb, NULL, TRIGGER_DELETE, POST_TRIG); } @@ -7848,7 +7848,7 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, Request* request, WhichTrigg newRpb->rpb_number = orgRpb->rpb_number; newRpb->rpb_number.setValid(true); - if (relation->rel_post_modify && whichTrig != PRE_TRIG) + if ((relation->rel_post_modify || relation->isSystem()) && whichTrig != PRE_TRIG) { EXE_execute_triggers(tdbb, &relation->rel_post_modify, orgRpb, newRpb, TRIGGER_UPDATE, POST_TRIG); @@ -8871,7 +8871,7 @@ const StmtNode* StoreNode::store(thread_db* tdbb, Request* request, WhichTrigger { SavepointChangeMarker scMarker(transaction); - if (relation && relation->rel_pre_store && whichTrig != POST_TRIG) + if (relation && (relation->rel_pre_store || relation->isSystem()) && whichTrig != POST_TRIG) { EXE_execute_triggers(tdbb, &relation->rel_pre_store, NULL, rpb, TRIGGER_INSERT, PRE_TRIG); @@ -8904,7 +8904,8 @@ const StmtNode* StoreNode::store(thread_db* tdbb, Request* request, WhichTrigger rpb->rpb_number.setValid(true); - if (relation && relation->rel_post_store && whichTrig != PRE_TRIG) + if (relation && (relation->rel_post_store || relation->isSystem()) && + relation->rel_post_store && whichTrig != PRE_TRIG) { EXE_execute_triggers(tdbb, &relation->rel_post_store, NULL, rpb, TRIGGER_INSERT, POST_TRIG); @@ -11549,11 +11550,8 @@ static RelationSourceNode* pass1Update(thread_db* tdbb, CompilerScratch* csb, jr for (FB_SIZE_T i = 0; i < trigger->getCount(); i++) { - if (!(*trigger)[i].sysTrigger) - { - userTriggers = true; - break; - } + userTriggers = true; + break; } if (userTriggers) @@ -11660,9 +11658,10 @@ static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs, FB_NEW_POOL(*tdbb->getTransaction()->tra_pool) traRpbList(*tdbb->getTransaction()->tra_pool); } + const auto relation = rpb->rpb_relation; const int rpblevel = tdbb->getTransaction()->tra_rpblist->PushRpb(rpb); - if (*trigs && whichTrig != StmtNode::POST_TRIG) + if ((*trigs || relation->isSystem()) && whichTrig != StmtNode::POST_TRIG) { try { diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index 4fef7456dc..07fc189db2 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -1498,8 +1498,7 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment, ULONG g { request->adjustCallerStats(); - if (!(request->getStatement()->flags & - (Statement::FLAG_INTERNAL | Statement::FLAG_SYS_TRIGGER)) && + if (!(request->getStatement()->flags & Statement::FLAG_INTERNAL) && request->req_caller) { putCall(record, request); @@ -1513,7 +1512,7 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment, ULONG g for (const auto statement : attachment->att_statements) { - if (!(statement->flags & (Statement::FLAG_INTERNAL | Statement::FLAG_SYS_TRIGGER))) + if (!(statement->flags & Statement::FLAG_INTERNAL)) { const string plan = Optimizer::getPlan(tdbb, statement, true); putStatement(record, statement, plan); @@ -1527,7 +1526,7 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment, ULONG g { const auto statement = request->getStatement(); - if (!(statement->flags & (Statement::FLAG_INTERNAL | Statement::FLAG_SYS_TRIGGER))) + if (!(statement->flags & Statement::FLAG_INTERNAL)) { const string plan = Optimizer::getPlan(tdbb, statement, true); putRequest(record, request, plan); diff --git a/src/jrd/RecordSourceNodes.cpp b/src/jrd/RecordSourceNodes.cpp index bbc0d4a41c..47367b41dc 100644 --- a/src/jrd/RecordSourceNodes.cpp +++ b/src/jrd/RecordSourceNodes.cpp @@ -626,8 +626,6 @@ RelationSourceNode* RelationSourceNode::parse(thread_db* tdbb, CompilerScratch* { MET_scan_relation(tdbb, node->relation); } - else if (node->relation->rel_flags & REL_sys_triggers) - MET_parse_sys_trigger(tdbb, node->relation); // generate a stream for the relation reference, assuming it is a real reference diff --git a/src/jrd/Relation.h b/src/jrd/Relation.h index 5445b60c4e..f2784c2bf6 100644 --- a/src/jrd/Relation.h +++ b/src/jrd/Relation.h @@ -393,11 +393,9 @@ const ULONG REL_deleted = 0x0004; // Relation known gonzo const ULONG REL_get_dependencies = 0x0008; // New relation needs dependencies during scan const ULONG REL_check_existence = 0x0010; // Existence lock released pending drop of relation const ULONG REL_blocking = 0x0020; // Blocking someone from dropping relation -const ULONG REL_sys_triggers = 0x0040; // The relation has system triggers to compile const ULONG REL_sql_relation = 0x0080; // Relation defined as sql table const ULONG REL_check_partners = 0x0100; // Rescan primary dependencies and foreign references const ULONG REL_being_scanned = 0x0200; // relation scan in progress -const ULONG REL_sys_trigs_being_loaded = 0x0400; // System triggers being loaded const ULONG REL_deleting = 0x0800; // relation delete in progress const ULONG REL_temp_tran = 0x1000; // relation is a GTT delete rows const ULONG REL_temp_conn = 0x2000; // relation is a GTT preserve rows diff --git a/src/jrd/Statement.h b/src/jrd/Statement.h index da27d6ff88..8db158bee8 100644 --- a/src/jrd/Statement.h +++ b/src/jrd/Statement.h @@ -34,11 +34,10 @@ class PlanEntry; class Statement : public pool_alloc { public: - static const unsigned FLAG_SYS_TRIGGER = 0x01; static const unsigned FLAG_INTERNAL = 0x02; static const unsigned FLAG_IGNORE_PERM = 0x04; //static const unsigned FLAG_VERSION4 = 0x08; - static const unsigned FLAG_POWERFUL = FLAG_SYS_TRIGGER | FLAG_INTERNAL | FLAG_IGNORE_PERM; + static const unsigned FLAG_POWERFUL = FLAG_INTERNAL | FLAG_IGNORE_PERM; //static const unsigned MAP_LENGTH; // CVC: Moved to dsql/Nodes.h as STREAM_MAP_LENGTH static const unsigned MAX_CLONES = 1000; diff --git a/src/jrd/SystemTriggers.epp b/src/jrd/SystemTriggers.epp new file mode 100644 index 0000000000..f64d186fb7 --- /dev/null +++ b/src/jrd/SystemTriggers.epp @@ -0,0 +1,1275 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2024 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "firebird.h" +#include +#include "firebird/Interface.h" +#include "../jrd/SystemTriggers.h" +#include "../jrd/constants.h" +#include "../jrd/ids.h" +#include "../jrd/req.h" +#include "../jrd/dpm_proto.h" +#include "../jrd/err_proto.h" +#include "../jrd/exe_proto.h" +#include "../jrd/evl_proto.h" +#include "../jrd/met_proto.h" +#include "../jrd/mov_proto.h" + + +DATABASE DB = FILENAME "ODS.RDB"; + +using namespace Firebird; +using namespace Jrd; + + +void SystemTriggers::beforeDeleteCheckConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descConstraintName; + MetaName constraintName; + if (EVL_field(nullptr, record, f_ccon_cname, &descConstraintName)) + MOV_get_metaname(tdbb, &descConstraintName, constraintName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$CONSTRAINT_NAME EQ constraintName.c_str() + { + ERR_post(Arg::Gds(isc_check_cnstrnt_del)); + } + END_FOR +} + +void SystemTriggers::afterDeleteCheckConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName constraintName; + if (EVL_field(nullptr, record, f_ccon_cname, &desc)) + MOV_get_metaname(tdbb, &desc, constraintName); + + MetaName triggerName; + if (EVL_field(nullptr, record, f_ccon_tname, &desc)) + MOV_get_metaname(tdbb, &desc, triggerName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + TRG IN RDB$TRIGGERS + CROSS RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$CONSTRAINT_NAME = constraintName.c_str() AND + RLC.RDB$CONSTRAINT_TYPE = FOREIGN_KEY AND + TRG.RDB$TRIGGER_NAME = triggerName.c_str() + { + ERASE TRG; + } + END_FOR + + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RFR IN RDB$RELATION_FIELDS + CROSS RLC IN RDB$RELATION_CONSTRAINTS + WITH RFR.RDB$FIELD_NAME = triggerName.c_str() AND + RLC.RDB$CONSTRAINT_NAME = constraintName.c_str() AND + RLC.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND + RLC.RDB$CONSTRAINT_TYPE = NOT_NULL_CNSTRT + { + MODIFY RFR + RFR.RDB$NULL_FLAG = 0; + END_MODIFY + } + END_FOR + + static const CachedRequestId request3CacheId; + AutoCacheRequest request3(tdbb, request3CacheId); + + FOR (REQUEST_HANDLE request3 TRANSACTION_HANDLE transaction) + TRG IN RDB$TRIGGERS + CROSS RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$CONSTRAINT_NAME = constraintName.c_str() AND + RLC.RDB$CONSTRAINT_TYPE = CHECK_CNSTRT AND + TRG.RDB$RELATION_NAME = RLC.RDB$RELATION_NAME AND + TRG.RDB$TRIGGER_NAME = triggerName.c_str() + { + ERASE TRG; + } + END_FOR +} + +void SystemTriggers::beforeUpdateCheckConstraint(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descConstraintName; + MetaName constraintName; + if (EVL_field(nullptr, orgRecord, f_ccon_cname, &descConstraintName)) + MOV_get_metaname(tdbb, &descConstraintName, constraintName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$CONSTRAINT_TYPE != NOT_NULL_CNSTRT AND + RLC.RDB$CONSTRAINT_NAME EQ constraintName.c_str() + { + ERR_post(Arg::Gds(isc_check_cnstrnt_update)); + } + END_FOR +} + +void SystemTriggers::beforeDeleteIndex(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descIndexName; + MetaName indexName; + if (EVL_field(nullptr, record, f_idx_name, &descIndexName)) + MOV_get_metaname(tdbb, &descIndexName, indexName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$INDEX_NAME EQ indexName.c_str() + { + ERR_post(Arg::Gds(isc_integ_index_del)); + } + END_FOR +} + +void SystemTriggers::beforeUpdateIndex(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descOldIndexName; + MetaName oldIndexName; + if (EVL_field(nullptr, orgRecord, f_idx_name, &descOldIndexName)) + MOV_get_metaname(tdbb, &descOldIndexName, oldIndexName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$INDEX_NAME EQ oldIndexName.c_str() + { + dsc descNewIndexName; + MetaName newIndexName; + dsc descOldRelationName, descNewRelationName; + MetaName oldRelationName, newRelationName; + dsc descOldIndexId, descNewIndexId; + SLONG oldIndexId, newIndexId; + dsc descOldSegmentCount, descNewSegmentCount; + SLONG oldSegmentCount, newSegmentCount; + dsc descOldForeignKey, descNewForeignKey; + MetaName oldForeignKey, newForeignKey; + + if (EVL_field(nullptr, newRecord, f_idx_name, &descNewIndexName) && + EVL_field(nullptr, orgRecord, f_idx_relation, &descOldRelationName) && + EVL_field(nullptr, newRecord, f_idx_relation, &descNewRelationName) && + EVL_field(nullptr, orgRecord, f_idx_id, &descOldIndexId) && + EVL_field(nullptr, newRecord, f_idx_id, &descNewIndexId) && + EVL_field(nullptr, orgRecord, f_idx_count, &descOldSegmentCount) && + EVL_field(nullptr, newRecord, f_idx_count, &descNewSegmentCount) && + EVL_field(nullptr, orgRecord, f_idx_foreign, &descOldForeignKey) && + EVL_field(nullptr, newRecord, f_idx_foreign, &descNewForeignKey)) + { + MOV_get_metaname(tdbb, &descNewIndexName, newIndexName); + MOV_get_metaname(tdbb, &descOldRelationName, oldRelationName); + MOV_get_metaname(tdbb, &descNewRelationName, newRelationName); + oldIndexId = MOV_get_long(tdbb, &descOldIndexId, 0); + newIndexId = MOV_get_long(tdbb, &descNewIndexId, 0); + oldSegmentCount = MOV_get_long(tdbb, &descOldSegmentCount, 0); + newSegmentCount = MOV_get_long(tdbb, &descNewSegmentCount, 0); + MOV_get_metaname(tdbb, &descOldForeignKey, oldForeignKey); + MOV_get_metaname(tdbb, &descNewForeignKey, newForeignKey); + + if (oldIndexName != newIndexName || + oldRelationName != newRelationName || + oldIndexId != newIndexId || + oldSegmentCount != newSegmentCount || + oldForeignKey != newForeignKey) + { + ERR_post(Arg::Gds(isc_integ_index_mod)); + } + } + } + END_FOR + + dsc descOldIndexInactive, descNewIndexInactive; + + if (EVL_field(nullptr, newRecord, f_idx_inactive, &descNewIndexInactive) && + MOV_get_long(tdbb, &descNewIndexInactive, 0) == 1 && + (!EVL_field(nullptr, orgRecord, f_idx_inactive, &descOldIndexInactive) || + MOV_get_long(tdbb, &descOldIndexInactive, 0) == 0)) + { + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RCL IN RDB$RELATION_CONSTRAINTS + CROSS IND1 IN RDB$INDICES + CROSS IND2 IN RDB$INDICES + WITH RCL.RDB$INDEX_NAME = oldIndexName.c_str() AND + IND1.RDB$INDEX_NAME = RCL.RDB$INDEX_NAME AND + IND2.RDB$FOREIGN_KEY = RCL.RDB$INDEX_NAME + { + ERR_post(Arg::Gds(isc_integ_index_deactivate)); + } + END_FOR + + static const CachedRequestId request3CacheId; + AutoCacheRequest request3(tdbb, request3CacheId); + + FOR (REQUEST_HANDLE request3 TRANSACTION_HANDLE transaction) + RCL IN RDB$RELATION_CONSTRAINTS + WITH RCL.RDB$INDEX_NAME = oldIndexName.c_str() AND + (RCL.RDB$CONSTRAINT_TYPE = PRIMARY_KEY OR + RCL.RDB$CONSTRAINT_TYPE = UNIQUE_CNSTRT OR + RCL.RDB$CONSTRAINT_TYPE = FOREIGN_KEY) + { + fb_utils::exact_name_limit(RCL.RDB$CONSTRAINT_TYPE, sizeof(RCL.RDB$CONSTRAINT_TYPE)); + + if (strcmp(RCL.RDB$CONSTRAINT_TYPE, FOREIGN_KEY) == 0) + ERR_post(Arg::Gds(isc_integ_index_deactivate)); + else + ERR_post(Arg::Gds(isc_integ_deactivate_primary)); + } + END_FOR + } +} + +void SystemTriggers::beforeDeleteIndexSegment(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descIndexName; + MetaName indexName; + if (EVL_field(nullptr, record, f_seg_name, &descIndexName)) + MOV_get_metaname(tdbb, &descIndexName, indexName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$INDEX_NAME EQ indexName.c_str() + { + ERR_post(Arg::Gds(isc_integ_index_seg_del)); + } + END_FOR +} + +void SystemTriggers::beforeUpdateIndexSegment(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descOldIndexName; + MetaName oldIndexName; + if (EVL_field(nullptr, orgRecord, f_seg_name, &descOldIndexName)) + MOV_get_metaname(tdbb, &descOldIndexName, oldIndexName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$INDEX_NAME EQ oldIndexName.c_str() + { + dsc descNewIndexName; + MetaName newIndexName; + dsc descOldFieldName, descNewFieldName; + MetaName oldFieldName, newFieldName; + dsc descOldFieldPosition, descNewFieldPosition; + SLONG oldFieldPosition, newFieldPosition; + + if (EVL_field(nullptr, newRecord, f_seg_name, &descNewIndexName) && + EVL_field(nullptr, orgRecord, f_seg_field, &descOldFieldName) && + EVL_field(nullptr, newRecord, f_seg_field, &descNewFieldName) && + EVL_field(nullptr, orgRecord, f_seg_position, &descOldFieldPosition) && + EVL_field(nullptr, newRecord, f_seg_position, &descNewFieldPosition)) + { + MOV_get_metaname(tdbb, &descNewIndexName, newIndexName); + MOV_get_metaname(tdbb, &descOldFieldName, oldFieldName); + MOV_get_metaname(tdbb, &descNewFieldName, newFieldName); + oldFieldPosition = MOV_get_long(tdbb, &descOldFieldPosition, 0); + newFieldPosition = MOV_get_long(tdbb, &descNewFieldPosition, 0); + + if (oldIndexName != newIndexName || + oldFieldName != newFieldName || + oldFieldPosition != newFieldPosition) + { + ERR_post(Arg::Gds(isc_integ_index_seg_mod)); + } + } + } + END_FOR +} + +void SystemTriggers::beforeUpdateField(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descFieldName; + MetaName fieldName; + if (!EVL_field(nullptr, orgRecord, f_fld_name, &descFieldName)) + return; + MOV_get_metaname(tdbb, &descFieldName, fieldName); + + dsc descOldFieldLength, descNewFieldLength; + SLONG oldFieldLength, newFieldLength; + dsc descOldFieldType, descNewFieldType; + SLONG oldFieldType, newFieldType; + dsc descOldCollationId, descNewCollationId; + SLONG oldCollationId, newCollationId; + dsc descOldCharSetId, descNewCharSetId; + SLONG oldCharSetId, newCharSetId; + + if (EVL_field(nullptr, orgRecord, f_fld_length, &descOldFieldLength) && + EVL_field(nullptr, newRecord, f_fld_length, &descNewFieldLength) && + EVL_field(nullptr, orgRecord, f_fld_type, &descOldFieldType) && + EVL_field(nullptr, newRecord, f_fld_type, &descNewFieldType) && + EVL_field(nullptr, orgRecord, f_fld_coll_id, &descOldCollationId) && + EVL_field(nullptr, newRecord, f_fld_coll_id, &descNewCollationId) && + EVL_field(nullptr, orgRecord, f_fld_charset_id, &descOldCharSetId) && + EVL_field(nullptr, newRecord, f_fld_charset_id, &descNewCharSetId)) + { + oldFieldLength = MOV_get_long(tdbb, &descOldFieldLength, 0); + newFieldLength = MOV_get_long(tdbb, &descNewFieldLength, 0); + oldFieldType = MOV_get_long(tdbb, &descOldFieldType, 0); + newFieldType = MOV_get_long(tdbb, &descNewFieldType, 0); + oldCollationId = MOV_get_long(tdbb, &descOldCollationId, 0); + newCollationId = MOV_get_long(tdbb, &descNewCollationId, 0); + oldCharSetId = MOV_get_long(tdbb, &descOldCharSetId, 0); + newCharSetId = MOV_get_long(tdbb, &descNewCharSetId, 0); + + if (oldFieldLength != newFieldLength || + oldFieldType != newFieldType || + oldCollationId != newCollationId || + oldCharSetId != newCharSetId) + { + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RFL IN RDB$RELATION_FIELDS + CROSS IND IN RDB$INDICES + CROSS RLC IN RDB$RELATION_CONSTRAINTS + CROSS IDS IN RDB$INDEX_SEGMENTS + WITH RFL.RDB$FIELD_SOURCE = fieldName.c_str() AND + IND.RDB$RELATION_NAME = RFL.RDB$RELATION_NAME AND + IDS.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + IDS.RDB$FIELD_NAME = RFL.RDB$FIELD_NAME AND + RLC.RDB$INDEX_NAME = IND.RDB$INDEX_NAME + { + ERR_post(Arg::Gds(isc_integ_index_seg_mod)); + } + END_FOR + } + } +} + +void SystemTriggers::beforeInsertRefConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + + dsc descConstraintName; + MetaName constraintName; + if (EVL_field(nullptr, record, f_refc_cname, &descConstraintName)) + MOV_get_metaname(tdbb, &descConstraintName, constraintName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + bool fkFound = false; + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$CONSTRAINT_TYPE = FOREIGN_KEY AND + RLC.RDB$CONSTRAINT_NAME EQ constraintName.c_str() + { + fkFound = true; + } + END_FOR + + if (!fkFound) + ERR_post(Arg::Gds(isc_ref_cnstrnt_notfound)); + + dsc descConstraintNameUq; + MetaName constraintNameUq; + if (EVL_field(nullptr, record, f_refc_uq, &descConstraintNameUq)) + MOV_get_metaname(tdbb, &descConstraintNameUq, constraintNameUq); + + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + bool pkUniqueFound = false; + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH (RLC.RDB$CONSTRAINT_TYPE = PRIMARY_KEY OR RLC.RDB$CONSTRAINT_TYPE = UNIQUE_CNSTRT) AND + RLC.RDB$CONSTRAINT_NAME EQ constraintNameUq.c_str() + { + pkUniqueFound = true; + } + END_FOR + + if (!pkUniqueFound) + ERR_post(Arg::Gds(isc_foreign_key_notfound)); +} + +void SystemTriggers::beforeDeleteRelationConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName constraintName; + if (EVL_field(nullptr, record, f_rcon_cname, &desc)) + MOV_get_metaname(tdbb, &desc, constraintName); + + string constraintType; + if (EVL_field(nullptr, record, f_rcon_ctype, &desc)) + { + MOV_get_string(tdbb, &desc, constraintType); + constraintType.rtrim(); + } + + if (constraintType == PRIMARY_KEY || constraintType == UNIQUE_CNSTRT) + { + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + REF IN RDB$REF_CONSTRAINTS + WITH REF.RDB$CONST_NAME_UQ = constraintName.c_str() + { + ERR_post(Arg::Gds(isc_primary_key_ref)); + } + END_FOR + } + else if (constraintType == FOREIGN_KEY) + { + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + REF IN RDB$REF_CONSTRAINTS + WITH REF.RDB$CONSTRAINT_NAME = constraintName.c_str() + { + ERASE REF; + } + END_FOR + } + else if (constraintType == NOT_NULL_CNSTRT) + { + MetaName relationName; + if (EVL_field(nullptr, record, f_rcon_rname, &desc)) + MOV_get_metaname(tdbb, &desc, relationName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + CROSS RFL IN RDB$RELATION_FIELDS + CROSS FLD IN RDB$FIELDS + CROSS IND IN RDB$INDICES + CROSS IDS IN RDB$INDEX_SEGMENTS + WITH CHK.RDB$CONSTRAINT_NAME = constraintName.c_str() AND + RFL.RDB$RELATION_NAME = relationName.c_str() AND + RFL.RDB$FIELD_NAME = CHK.RDB$TRIGGER_NAME AND + IND.RDB$RELATION_NAME = relationName.c_str() AND + IDS.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + IDS.RDB$FIELD_NAME = RFL.RDB$FIELD_NAME AND + FLD.RDB$FIELD_NAME = RFL.RDB$FIELD_SOURCE AND + (FLD.RDB$NULL_FLAG MISSING OR FLD.RDB$NULL_FLAG = 0) + { + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RCL IN RDB$RELATION_CONSTRAINTS + WITH RCL.RDB$INDEX_NAME = IND.RDB$INDEX_NAME + { + ERR_post(Arg::Gds(isc_primary_key_notnull)); + } + END_FOR + } + END_FOR + } +} + +void SystemTriggers::afterDeleteRelationConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + string constraintType; + if (EVL_field(nullptr, record, f_rcon_ctype, &desc)) + { + MOV_get_string(tdbb, &desc, constraintType); + constraintType.rtrim(); + } + + MetaName constraintName; + if (EVL_field(nullptr, record, f_rcon_cname, &desc)) + MOV_get_metaname(tdbb, &desc, constraintName); + + MetaName relationName; + if (EVL_field(nullptr, record, f_rcon_rname, &desc)) + MOV_get_metaname(tdbb, &desc, relationName); + + MetaName indexName; + if (EVL_field(nullptr, record, f_rcon_iname, &desc)) + MOV_get_metaname(tdbb, &desc, indexName); + + if (constraintType == FOREIGN_KEY) + { + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + WITH CHK.RDB$CONSTRAINT_NAME = constraintName.c_str() + { + ERASE CHK; + + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + TRG IN RDB$TRIGGERS + WITH TRG.RDB$TRIGGER_NAME = CHK.RDB$TRIGGER_NAME + { + ERASE TRG; + } + END_FOR + } + END_FOR + } + + if (constraintType == FOREIGN_KEY || constraintType == PRIMARY_KEY || constraintType == UNIQUE_CNSTRT) + { + static const CachedRequestId request3CacheId; + AutoCacheRequest request3(tdbb, request3CacheId); + + FOR (REQUEST_HANDLE request3 TRANSACTION_HANDLE transaction) + IND IN RDB$INDICES + WITH IND.RDB$INDEX_NAME = indexName.c_str() + { + ERASE IND; + + static const CachedRequestId request4CacheId; + AutoCacheRequest request4(tdbb, request4CacheId); + + FOR (REQUEST_HANDLE request4 TRANSACTION_HANDLE transaction) + IDS IN RDB$INDEX_SEGMENTS + WITH IDS.RDB$INDEX_NAME = IND.RDB$INDEX_NAME + { + ERASE IDS; + } + END_FOR + } + END_FOR + } + + if (constraintType == NOT_NULL_CNSTRT) + { + static const CachedRequestId request5CacheId; + AutoCacheRequest request5(tdbb, request5CacheId); + + FOR (REQUEST_HANDLE request5 TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + CROSS RFL IN RDB$RELATION_FIELDS + WITH CHK.RDB$CONSTRAINT_NAME = constraintName.c_str() AND + RFL.RDB$RELATION_NAME = relationName.c_str() AND + RFL.RDB$FIELD_NAME = CHK.RDB$TRIGGER_NAME + { + ERASE CHK; + + MODIFY RFL + { + RFL.RDB$NULL_FLAG = 0; + } + END_MODIFY + } + END_FOR + } + + if (constraintType == CHECK_CNSTRT) + { + static const CachedRequestId request6CacheId; + AutoCacheRequest request6(tdbb, request6CacheId); + + FOR (REQUEST_HANDLE request6 TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + WITH CHK.RDB$CONSTRAINT_NAME = constraintName.c_str() + { + ERASE CHK; + + static const CachedRequestId request7CacheId; + AutoCacheRequest request7(tdbb, request7CacheId); + + FOR (REQUEST_HANDLE request7 TRANSACTION_HANDLE transaction) + TRG IN RDB$TRIGGERS + WITH TRG.RDB$TRIGGER_NAME = CHK.RDB$TRIGGER_NAME AND + TRG.RDB$RELATION_NAME = relationName.c_str() + { + ERASE TRG; + } + END_FOR + } + END_FOR + } +} + +void SystemTriggers::beforeInsertRelationConstraint(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName relationName; + if (EVL_field(nullptr, record, f_rcon_rname, &desc)) + MOV_get_metaname(tdbb, &desc, relationName); + + string constraintType; + if (EVL_field(nullptr, record, f_rcon_ctype, &desc)) + { + MOV_get_string(tdbb, &desc, constraintType); + constraintType.rtrim(); + } + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + REL IN RDB$RELATIONS + WITH REL.RDB$RELATION_NAME EQ relationName.c_str() AND + REL.RDB$VIEW_SOURCE NOT MISSING + { + ERR_post(Arg::Gds(isc_constaint_on_view)); + } + END_FOR + + if (constraintType == PRIMARY_KEY) + { + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RLC IN RDB$RELATION_CONSTRAINTS + WITH RLC.RDB$RELATION_NAME EQ relationName.c_str() AND + RLC.RDB$CONSTRAINT_TYPE = PRIMARY_KEY + { + ERR_post(Arg::Gds(isc_primary_key_exists)); + } + END_FOR + } +} + +void SystemTriggers::beforeDeleteRelationField(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName relationName; + if (!EVL_field(nullptr, record, f_rfr_rname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, relationName); + + MetaName fieldName; + if (!EVL_field(nullptr, record, f_rfr_fname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, fieldName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + IND IN RDB$INDICES + CROSS RCL IN RDB$RELATION_CONSTRAINTS + CROSS IDS IN RDB$INDEX_SEGMENTS + WITH IND.RDB$RELATION_NAME = relationName.c_str() AND + IDS.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + RCL.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + IDS.RDB$FIELD_NAME = fieldName.c_str() + { + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + IDS2 IN RDB$INDEX_SEGMENTS + WITH IDS2.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + IDS2.RDB$FIELD_NAME != fieldName.c_str() + { + ERR_post(Arg::Gds(isc_cnstrnt_fld_del)); + } + END_FOR + + ERASE RCL; + } + END_FOR + + static const CachedRequestId request3CacheId; + AutoCacheRequest request3(tdbb, request3CacheId); + + FOR (REQUEST_HANDLE request3 TRANSACTION_HANDLE transaction) + IND IN RDB$INDICES + CROSS RCL IN RDB$RELATION_CONSTRAINTS + CROSS CHK IN RDB$CHECK_CONSTRAINTS + CROSS DEP IN RDB$DEPENDENCIES + WITH RCL.RDB$RELATION_NAME = relationName.c_str() AND + RCL.RDB$CONSTRAINT_TYPE = CHECK_CNSTRT AND + DEP.RDB$DEPENDED_ON_NAME = relationName.c_str() AND + DEP.RDB$FIELD_NAME = fieldName.c_str() AND + DEP.RDB$DEPENDENT_TYPE = obj_trigger AND + DEP.RDB$DEPENDED_ON_TYPE = obj_relation AND + CHK.RDB$TRIGGER_NAME = DEP.RDB$DEPENDENT_NAME + { + static const CachedRequestId request4CacheId; + AutoCacheRequest request4(tdbb, request4CacheId); + + FOR (REQUEST_HANDLE request4 TRANSACTION_HANDLE transaction) + DEP4 IN RDB$DEPENDENCIES + WITH DEP4.RDB$DEPENDENT_NAME = CHK.RDB$TRIGGER_NAME AND + DEP4.RDB$DEPENDENT_TYPE = obj_trigger AND + DEP4.RDB$DEPENDED_ON_TYPE = obj_relation AND + DEP4.RDB$DEPENDED_ON_NAME = relationName.c_str() AND + DEP4.RDB$FIELD_NAME != fieldName.c_str() + { + ERR_post(Arg::Gds(isc_cnstrnt_fld_del)); + } + END_FOR + + ERASE RCL; + } + END_FOR +} + +void SystemTriggers::afterDeleteRelationField(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName relationName; + if (!EVL_field(nullptr, record, f_rfr_rname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, relationName); + + MetaName fieldName; + if (!EVL_field(nullptr, record, f_rfr_fname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, fieldName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + CROSS RCL IN RDB$RELATION_CONSTRAINTS + WITH CHK.RDB$TRIGGER_NAME EQ fieldName.c_str() AND + RCL.RDB$CONSTRAINT_NAME EQ CHK.RDB$CONSTRAINT_NAME AND + RCL.RDB$RELATION_NAME = relationName.c_str() AND + RCL.RDB$CONSTRAINT_TYPE = NOT_NULL_CNSTRT + { + ERASE RCL; + ERASE CHK; + } + END_FOR +} + +void SystemTriggers::beforeUpdateRelationField(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + + dsc desc; + MetaName oldRelationName; + MetaName oldFieldName, newFieldName; + MetaName oldFieldSource, newFieldSource; + std::optional oldCollationId, newCollationId; + + if (EVL_field(nullptr, orgRecord, f_rfr_rname, &desc)) + MOV_get_metaname(tdbb, &desc, oldRelationName); + + if (EVL_field(nullptr, orgRecord, f_rfr_fname, &desc)) + MOV_get_metaname(tdbb, &desc, oldFieldName); + + if (EVL_field(nullptr, newRecord, f_rfr_fname, &desc)) + MOV_get_metaname(tdbb, &desc, newFieldName); + + if (EVL_field(nullptr, orgRecord, f_rfr_sname, &desc)) + MOV_get_metaname(tdbb, &desc, oldFieldSource); + + if (EVL_field(nullptr, newRecord, f_rfr_sname, &desc)) + MOV_get_metaname(tdbb, &desc, newFieldSource); + + if (EVL_field(nullptr, orgRecord, f_rfr_coll_id, &desc)) + oldCollationId = MOV_get_long(tdbb, &desc, 0); + + if (EVL_field(nullptr, newRecord, f_rfr_coll_id, &desc)) + newCollationId = MOV_get_long(tdbb, &desc, 0); + + if (oldFieldName != newFieldName || + !(oldFieldSource == newFieldSource && oldCollationId == newCollationId)) + { + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + IND IN RDB$INDICES + CROSS IDS IN RDB$INDEX_SEGMENTS + CROSS RLC IN RDB$RELATION_CONSTRAINTS + WITH IND.RDB$RELATION_NAME = oldRelationName.c_str() AND + IDS.RDB$INDEX_NAME = IND.RDB$INDEX_NAME AND + IDS.RDB$FIELD_NAME = oldFieldName.c_str() AND + RLC.RDB$INDEX_NAME = IND.RDB$INDEX_NAME + { + if (oldFieldName != newFieldName) + ERR_post(Arg::Gds(isc_cnstrnt_fld_rename)); + + if (!(oldFieldSource == newFieldSource && oldCollationId == newCollationId)) + ERR_post(Arg::Gds(isc_integ_index_seg_mod)); + } + END_FOR + } +} + +void SystemTriggers::beforeDeleteTrigger(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + if (EVL_field(nullptr, record, f_trg_sys_flag, &desc) && MOV_get_long(tdbb, &desc, 0) == 1) + ERR_post(Arg::Gds(isc_systrig_update)); + + MetaName oldTriggerName; + if (EVL_field(nullptr, record, f_trg_name, &desc)) + MOV_get_metaname(tdbb, &desc, oldTriggerName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + CROSS RCL IN RDB$RELATION_CONSTRAINTS + WITH CHK.RDB$TRIGGER_NAME EQ oldTriggerName.c_str() AND + RCL.RDB$CONSTRAINT_NAME EQ CHK.RDB$CONSTRAINT_NAME AND + RCL.RDB$CONSTRAINT_TYPE = CHECK_CNSTRT + { + ERR_post(Arg::Gds(isc_check_trig_del)); + } + END_FOR +} + +void SystemTriggers::beforeUpdateTrigger(thread_db* tdbb, Record* orgRecord, Record* newRecord) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + if (EVL_field(nullptr, orgRecord, f_trg_sys_flag, &desc) && MOV_get_long(tdbb, &desc, 0) == 1) + ERR_post(Arg::Gds(isc_systrig_update)); + + MetaName oldTriggerName, newTriggerName; + if (EVL_field(nullptr, orgRecord, f_trg_name, &desc)) + MOV_get_metaname(tdbb, &desc, oldTriggerName); + if (EVL_field(nullptr, newRecord, f_trg_name, &desc)) + MOV_get_metaname(tdbb, &desc, newTriggerName); + + MetaName oldRelationName, newRelationName; + if (EVL_field(nullptr, orgRecord, f_trg_rname, &desc)) + MOV_get_metaname(tdbb, &desc, oldRelationName); + if (EVL_field(nullptr, newRecord, f_trg_rname, &desc)) + MOV_get_metaname(tdbb, &desc, newRelationName); + + std::optional oldTriggerSequence, newTriggerSequence; + if (EVL_field(nullptr, orgRecord, f_trg_seq, &desc)) + oldTriggerSequence = MOV_get_long(tdbb, &desc, 0); + if (EVL_field(nullptr, newRecord, f_trg_seq, &desc)) + newTriggerSequence = MOV_get_long(tdbb, &desc, 0); + + std::optional oldTriggerBlr, newTriggerBlr; + if (EVL_field(nullptr, orgRecord, f_trg_blr, &desc)) + oldTriggerBlr = *(bid*) desc.dsc_address; + if (EVL_field(nullptr, newRecord, f_trg_blr, &desc)) + newTriggerBlr = *(bid*) desc.dsc_address; + + std::optional oldTriggerInactive, newTriggerInactive; + if (EVL_field(nullptr, orgRecord, f_trg_inactive, &desc)) + oldTriggerInactive = MOV_get_long(tdbb, &desc, 0); + if (EVL_field(nullptr, newRecord, f_trg_inactive, &desc)) + newTriggerInactive = MOV_get_long(tdbb, &desc, 0); + + std::optional oldFlags, newFlags; + if (EVL_field(nullptr, orgRecord, f_trg_flags, &desc)) + oldFlags = MOV_get_long(tdbb, &desc, 0); + if (EVL_field(nullptr, newRecord, f_trg_flags, &desc)) + newFlags = MOV_get_long(tdbb, &desc, 0); + + std::optional oldDebugInfo, newDebugInfo; + if (EVL_field(nullptr, orgRecord, f_trg_debug_info, &desc)) + oldDebugInfo = *(bid*) desc.dsc_address; + if (EVL_field(nullptr, newRecord, f_trg_debug_info, &desc)) + newDebugInfo = *(bid*) desc.dsc_address; + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + CHK IN RDB$CHECK_CONSTRAINTS + CROSS RCL IN RDB$RELATION_CONSTRAINTS + WITH CHK.RDB$TRIGGER_NAME = oldTriggerName.c_str() AND + RCL.RDB$CONSTRAINT_NAME = CHK.RDB$CONSTRAINT_NAME AND + RCL.RDB$CONSTRAINT_TYPE = CHECK_CNSTRT + { + if (!(oldTriggerName == newTriggerName && + oldRelationName == newRelationName && + oldTriggerSequence == newTriggerSequence && + oldTriggerBlr == newTriggerBlr && + oldTriggerInactive == newTriggerInactive && + oldFlags == newFlags && + oldDebugInfo == newDebugInfo)) + { + ERR_post(Arg::Gds(isc_check_trig_update)); + } + } + END_FOR +} + +void SystemTriggers::beforeDeleteUserPrivilege(thread_db* tdbb, Record* record) +{ + const auto transaction = tdbb->getTransaction(); + dsc desc; + + MetaName relationName; + if (!EVL_field(nullptr, record, f_prv_rname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, relationName); + + MetaName fieldName; + if (!EVL_field(nullptr, record, f_prv_fname, &desc)) + return; + MOV_get_metaname(tdbb, &desc, fieldName); + + static const CachedRequestId requestCacheId; + AutoCacheRequest request(tdbb, requestCacheId); + + FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + RFL IN RDB$RELATION_FIELDS + CROSS SEC IN RDB$SECURITY_CLASSES + WITH RFL.RDB$RELATION_NAME = relationName.c_str() AND + RFL.RDB$FIELD_NAME = fieldName.c_str() AND + RFL.RDB$SECURITY_CLASS STARTING SQL_FLD_SECCLASS_PREFIX AND + SEC.RDB$SECURITY_CLASS = RFL.RDB$SECURITY_CLASS + { + ERASE SEC; + + MODIFY RFL + { + RFL.RDB$SECURITY_CLASS.NULL = TRUE; + } + END_MODIFY + } + END_FOR +} + +void SystemTriggers::beforeInsertUserPrivilege(thread_db* tdbb, Record* record) +{ + const auto attachment = tdbb->getAttachment(); + const auto transaction = tdbb->getTransaction(); + const MetaName currentUserName(attachment->getUserName()); + const bool hasGrantRevokeOnAnyObject = + attachment->att_user && attachment->att_user->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT); + dsc desc; + + MetaName grantor; + if (EVL_field(nullptr, record, f_prv_grantor, &desc)) + MOV_get_metaname(tdbb, &desc, grantor); + + if (grantor.isEmpty()) + { + grantor = currentUserName; + + dsc desc2; + desc2.makeText((USHORT) grantor.length(), CS_METADATA, (UCHAR*) grantor.c_str()); + MOV_move(tdbb, &desc2, &desc); + record->clearNull(f_prv_grantor); + } + + MetaName user; + if (EVL_field(nullptr, record, f_prv_user, &desc)) + MOV_get_metaname(tdbb, &desc, user); + + EVL_field(nullptr, record, f_prv_o_type, &desc); + const SLONG objectType = MOV_get_long(tdbb, &desc, 0); + + string privilege; + if (EVL_field(nullptr, record, f_prv_priv, &desc)) + MOV_get_string(tdbb, &desc, privilege); + + MetaName relationName; + if (EVL_field(nullptr, record, f_prv_rname, &desc)) + MOV_get_metaname(tdbb, &desc, relationName); + + switch (objectType) + { + case obj_relation: + { + MetaName fieldName; + if (EVL_field(nullptr, record, f_prv_fname, &desc)) + MOV_get_metaname(tdbb, &desc, fieldName); + + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + REL IN RDB$RELATIONS + WITH REL.RDB$RELATION_NAME EQ relationName.c_str() + { + const MetaName relationOwner(REL.RDB$OWNER_NAME); + + if (!((relationOwner == currentUserName && relationOwner == grantor && relationOwner == user) || + hasGrantRevokeOnAnyObject)) + { + if (relationOwner == currentUserName) + { + if (fieldName.hasData()) + { + static const CachedRequestId request2CacheId; + AutoCacheRequest request2(tdbb, request2CacheId); + + FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction) + RFL2 IN RDB$RELATION_FIELDS + CROSS VRL2 IN RDB$VIEW_RELATIONS + CROSS REL2 IN RDB$RELATIONS + WITH RFL2.RDB$RELATION_NAME = relationName.c_str() AND + RFL2.RDB$FIELD_NAME = fieldName.c_str() AND + RFL2.RDB$BASE_FIELD NOT MISSING AND + VRL2.RDB$VIEW_NAME = RFL2.RDB$RELATION_NAME AND + VRL2.RDB$VIEW_CONTEXT = RFL2.RDB$VIEW_CONTEXT AND + REL2.RDB$RELATION_NAME = VRL2.RDB$RELATION_NAME + { + const MetaName relation2Owner(REL2.RDB$OWNER_NAME); + + if (relation2Owner != relationOwner && !hasGrantRevokeOnAnyObject) + { + static const CachedRequestId request3CacheId; + AutoCacheRequest request3(tdbb, request3CacheId); + bool privilegeFound = false; + + FOR (REQUEST_HANDLE request3 TRANSACTION_HANDLE transaction) + PRIV3 IN RDB$USER_PRIVILEGES + WITH PRIV3.RDB$RELATION_NAME = REL2.RDB$RELATION_NAME AND + PRIV3.RDB$OBJECT_TYPE = obj_relation AND + PRIV3.RDB$PRIVILEGE = privilege.c_str() AND + PRIV3.RDB$USER = relationOwner.c_str() AND + PRIV3.RDB$USER_TYPE = obj_user AND + PRIV3.RDB$GRANT_OPTION != 0 AND + (PRIV3.RDB$FIELD_NAME MISSING OR + PRIV3.RDB$FIELD_NAME = RFL2.RDB$BASE_FIELD) + { + privilegeFound = true; + } + END_FOR + + if (!privilegeFound) + ERR_post(Arg::Gds(isc_grant_nopriv_on_base)); + } + } + END_FOR + } + else + { + static const CachedRequestId request4CacheId; + AutoCacheRequest request4(tdbb, request4CacheId); + + FOR (REQUEST_HANDLE request4 TRANSACTION_HANDLE transaction) + VRL4 IN RDB$VIEW_RELATIONS + CROSS REL4 IN RDB$RELATIONS + WITH VRL4.RDB$VIEW_NAME = relationName.c_str() AND + REL4.RDB$RELATION_NAME = VRL4.RDB$RELATION_NAME + { + const MetaName relation4Owner(REL4.RDB$OWNER_NAME); + + if (relation4Owner != relationOwner && !hasGrantRevokeOnAnyObject) + { + static const CachedRequestId request5CacheId; + AutoCacheRequest request5(tdbb, request5CacheId); + bool privilegeFound = false; + + FOR (REQUEST_HANDLE request5 TRANSACTION_HANDLE transaction) + PRIV5 IN RDB$USER_PRIVILEGES + WITH PRIV5.RDB$RELATION_NAME = REL4.RDB$RELATION_NAME AND + PRIV5.RDB$OBJECT_TYPE = obj_relation AND + PRIV5.RDB$PRIVILEGE = privilege.c_str() AND + PRIV5.RDB$USER = relationOwner.c_str() AND + PRIV5.RDB$USER_TYPE = obj_user AND + PRIV5.RDB$GRANT_OPTION != 0 AND + PRIV5.RDB$FIELD_NAME MISSING + { + privilegeFound = true; + } + END_FOR + + if (!privilegeFound) + ERR_post(Arg::Gds(isc_grant_nopriv_on_base)); + } + } + END_FOR + } + } + } + + if (REL.RDB$SECURITY_CLASS.NULL) + { + MODIFY REL + { + sprintf(REL.RDB$SECURITY_CLASS, "%s%" SQUADFORMAT, SQL_SECCLASS_PREFIX, + DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1)); + REL.RDB$SECURITY_CLASS.NULL = FALSE; + } + END_MODIFY + } + else if (strncmp(REL.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN) != 0) + ERR_post(Arg::Gds(isc_nonsql_security_rel)); + } + END_FOR + + if (fieldName.hasData()) + { + static const CachedRequestId request6CacheId; + AutoCacheRequest request6(tdbb, request6CacheId); + + FOR (REQUEST_HANDLE request6 TRANSACTION_HANDLE transaction) + RFL6 IN RDB$RELATION_FIELDS + WITH RFL6.RDB$RELATION_NAME = relationName.c_str() AND + RFL6.RDB$FIELD_NAME = fieldName.c_str() + { + if (RFL6.RDB$SECURITY_CLASS.NULL) + { + MODIFY RFL6 + { + sprintf(RFL6.RDB$SECURITY_CLASS, "%s%" SQUADFORMAT, SQL_FLD_SECCLASS_PREFIX, + DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1)); + RFL6.RDB$SECURITY_CLASS.NULL = TRUE; + } + END_MODIFY + } + else if (strncmp(RFL6.RDB$SECURITY_CLASS, SQL_FLD_SECCLASS_PREFIX, SQL_FLD_SECCLASS_PREFIX_LEN) != 0) + ERR_post(Arg::Gds(isc_nonsql_security_fld)); + } + END_FOR + } + + break; + } + + case obj_procedure: + { + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + PRC IN RDB$PROCEDURES + WITH PRC.RDB$PROCEDURE_NAME EQ relationName.c_str() AND + PRC.RDB$PACKAGE_NAME MISSING + { + if (PRC.RDB$SECURITY_CLASS.NULL) + { + MODIFY PRC + { + sprintf(PRC.RDB$SECURITY_CLASS, "%s%" SQUADFORMAT, SQL_SECCLASS_PREFIX, + DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1)); + PRC.RDB$SECURITY_CLASS.NULL = FALSE; + } + END_MODIFY + } + else if (strncmp(PRC.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN) != 0) + ERR_post(Arg::Gds(isc_nonsql_security_rel)); + } + END_FOR + + break; + } + + case obj_udf: + { + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + FUN IN RDB$FUNCTIONS + WITH FUN.RDB$FUNCTION_NAME EQ relationName.c_str() AND + FUN.RDB$PACKAGE_NAME MISSING + { + if (FUN.RDB$SECURITY_CLASS.NULL) + { + MODIFY FUN + { + sprintf(FUN.RDB$SECURITY_CLASS, "%s%" SQUADFORMAT, SQL_SECCLASS_PREFIX, + DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1)); + FUN.RDB$SECURITY_CLASS.NULL = FALSE; + } + END_MODIFY + } + else if (strncmp(FUN.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN) != 0) + ERR_post(Arg::Gds(isc_nonsql_security_rel)); + } + END_FOR + + break; + } + + case obj_package_header: + { + static const CachedRequestId request1CacheId; + AutoCacheRequest request1(tdbb, request1CacheId); + + FOR (REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction) + PKG IN RDB$PACKAGES + WITH PKG.RDB$PACKAGE_NAME EQ relationName.c_str() + { + if (PKG.RDB$SECURITY_CLASS.NULL) + { + MODIFY PKG + { + sprintf(PKG.RDB$SECURITY_CLASS, "%s%" SQUADFORMAT, SQL_SECCLASS_PREFIX, + DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1)); + PKG.RDB$SECURITY_CLASS.NULL = FALSE; + } + END_MODIFY + } + else if (strncmp(PKG.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN) != 0) + ERR_post(Arg::Gds(isc_nonsql_security_rel)); + } + END_FOR + + break; + } + } +} diff --git a/src/jrd/SystemTriggers.h b/src/jrd/SystemTriggers.h new file mode 100644 index 0000000000..fb1820e457 --- /dev/null +++ b/src/jrd/SystemTriggers.h @@ -0,0 +1,57 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2024 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef JRD_SYSTEM_TRIGGERS_H +#define JRD_SYSTEM_TRIGGERS_H + +#include "firebird.h" + +namespace Jrd +{ + class thread_db; + class Record; +} // namespace Jrd + +namespace Jrd::SystemTriggers +{ + void beforeDeleteCheckConstraint(thread_db* tdbb, Record* record); + void afterDeleteCheckConstraint(thread_db* tdbb, Record* record); + void beforeUpdateCheckConstraint(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeDeleteIndex(thread_db* tdbb, Record* record); + void beforeUpdateIndex(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeDeleteIndexSegment(thread_db* tdbb, Record* record); + void beforeUpdateIndexSegment(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeUpdateField(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeInsertRefConstraint(thread_db* tdbb, Record* record); + void beforeDeleteRelationConstraint(thread_db* tdbb, Record* record); + void afterDeleteRelationConstraint(thread_db* tdbb, Record* record); + void beforeInsertRelationConstraint(thread_db* tdbb, Record* record); + void beforeDeleteRelationField(thread_db* tdbb, Record* record); + void afterDeleteRelationField(thread_db* tdbb, Record* record); + void beforeUpdateRelationField(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeDeleteTrigger(thread_db* tdbb, Record* record); + void beforeUpdateTrigger(thread_db* tdbb, Record* orgRecord, Record* newRecord); + void beforeDeleteUserPrivilege(thread_db* tdbb, Record* record); + void beforeInsertUserPrivilege(thread_db* tdbb, Record* record); +} // namespace Jrd::SystemTriggers + +#endif // JRD_SYSTEM_TRIGGERS_H diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index 93ee1e367f..094b3f2a70 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -6304,9 +6304,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_ // We have just loaded the triggers onto the local vector triggers. // It's now time to place them at their rightful place inside the relation block. - - if (!(relation->rel_flags & REL_sys_trigs_being_loaded)) - relation->replaceTriggers(tdbb, triggers); + relation->replaceTriggers(tdbb, triggers); // in case somebody changed the view definition or a computed // field, reset the dependencies by deleting the current ones diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index cb0b9c0772..526c0dd239 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -71,6 +71,7 @@ #include "../jrd/intl.h" #include "../jrd/sbm.h" #include "../jrd/blb.h" +#include "../jrd/SystemTriggers.h" #include "firebird/impl/blr.h" #include "../dsql/ExprNodes.h" #include "../dsql/StmtNodes.h" @@ -1294,18 +1295,123 @@ void EXE_execute_triggers(thread_db* tdbb, * if any blow up. * **************************************/ + SET_TDBB(tdbb); + + const auto dbb = tdbb->getDatabase(); + const auto old_rec = old_rpb ? old_rpb->rpb_record : nullptr; + const auto new_rec = new_rpb ? new_rpb->rpb_record : nullptr; + + if (!(dbb->dbb_flags & DBB_creating) && (old_rpb || new_rpb)) + { + if (const auto relation = old_rpb ? old_rpb->rpb_relation : new_rpb->rpb_relation; + relation->rel_flags & REL_system) + { + if (which_trig == StmtNode::PRE_TRIG && trigger_action == TriggerAction::TRIGGER_DELETE) + { + switch ((RIDS) relation->rel_id) + { + case rel_ccon: + SystemTriggers::beforeDeleteCheckConstraint(tdbb, old_rec); + break; + + case rel_indices: + SystemTriggers::beforeDeleteIndex(tdbb, old_rec); + break; + + case rel_priv: + SystemTriggers::beforeDeleteUserPrivilege(tdbb, old_rec); + break; + + case rel_rcon: + SystemTriggers::beforeDeleteRelationConstraint(tdbb, old_rec); + break; + + case rel_rfr: + SystemTriggers::beforeDeleteRelationField(tdbb, old_rec); + break; + + case rel_segments: + SystemTriggers::beforeDeleteIndexSegment(tdbb, old_rec); + break; + + case rel_triggers: + SystemTriggers::beforeDeleteTrigger(tdbb, old_rec); + break; + } + } + else if (which_trig == StmtNode::PRE_TRIG && trigger_action == TriggerAction::TRIGGER_UPDATE) + { + switch ((RIDS) relation->rel_id) + { + case rel_ccon: + SystemTriggers::beforeUpdateCheckConstraint(tdbb, old_rec, new_rec); + break; + + case rel_fields: + SystemTriggers::beforeUpdateField(tdbb, old_rec, new_rec); + break; + + case rel_indices: + SystemTriggers::beforeUpdateIndex(tdbb, old_rec, new_rec); + break; + + case rel_rfr: + SystemTriggers::beforeUpdateRelationField(tdbb, old_rec, new_rec); + break; + + case rel_segments: + SystemTriggers::beforeUpdateIndexSegment(tdbb, old_rec, new_rec); + break; + + case rel_triggers: + SystemTriggers::beforeUpdateTrigger(tdbb, old_rec, new_rec); + break; + } + } + else if (which_trig == StmtNode::PRE_TRIG && trigger_action == TriggerAction::TRIGGER_INSERT) + { + switch ((RIDS) relation->rel_id) + { + case rel_priv: + SystemTriggers::beforeInsertUserPrivilege(tdbb, new_rec); + break; + + case rel_rcon: + SystemTriggers::beforeInsertRelationConstraint(tdbb, new_rec); + break; + + case rel_refc: + SystemTriggers::beforeInsertRefConstraint(tdbb, new_rec); + break; + } + } + else if (which_trig == StmtNode::POST_TRIG && trigger_action == TriggerAction::TRIGGER_DELETE) + { + switch ((RIDS) relation->rel_id) + { + case rel_ccon: + SystemTriggers::afterDeleteCheckConstraint(tdbb, old_rec); + break; + + case rel_rcon: + SystemTriggers::afterDeleteRelationConstraint(tdbb, old_rec); + break; + + case rel_rfr: + SystemTriggers::afterDeleteRelationField(tdbb, old_rec); + break; + } + } + } + } + if (!*triggers || (*triggers)->isEmpty()) return; - SET_TDBB(tdbb); - Request* const request = tdbb->getRequest(); jrd_tra* const transaction = request ? request->req_transaction : tdbb->getTransaction(); RefPtr vector(*triggers); - Record* const old_rec = old_rpb ? old_rpb->rpb_record : NULL; - Record* const new_rec = new_rpb ? new_rpb->rpb_record : NULL; - AutoPtr null_rec; const bool is_db_trigger = (!old_rec && !new_rec); @@ -1868,15 +1974,6 @@ static void trigger_failure(thread_db* tdbb, Request* trigger) MET_trigger_msg(tdbb, msg, trigger->getStatement()->triggerName, trigger->req_label); if (msg.hasData()) { - if (trigger->getStatement()->flags & Statement::FLAG_SYS_TRIGGER) - { - ISC_STATUS code = PAR_symbol_to_gdscode(msg); - if (code) - { - ERR_post(Arg::Gds(isc_integ_fail) << Arg::Num(trigger->req_label) << - Arg::Gds(code)); - } - } ERR_post(Arg::Gds(isc_integ_fail) << Arg::Num(trigger->req_label) << Arg::Gds(isc_random) << Arg::Str(msg)); } diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 78a84bfe6d..d0d6527971 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -79,134 +79,6 @@ namespace jrd_vtof(name.c_str(), field, sizeof(field)); } - // This is the table used in defining triggers; note that - // RDB$TRIGGER_0 was first changed to RDB$TRIGGER_7 to make it easier to - // upgrade a database to support field-level grant. It has since been - // changed to RDB$TRIGGER_9 to handle SQL security on relations whose - // name is > 27 characters - - const jrd_trg triggers[] = - { - { "RDB$TRIGGER_1", (UCHAR) nam_user_privileges, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_1_BEFORE_UPDATE), - TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_1_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_8", (UCHAR) nam_user_privileges, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_8_BEFORE_DELETE), - TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_8_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_9", (UCHAR) nam_user_privileges, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_9_BEFORE_INSERT), - TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_9_BEFORE_INSERT, 0, ODS_8_0 }, - { "RDB$TRIGGER_2", (UCHAR) nam_trgs, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_2_BEFORE_UPDATE), - TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_2_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_3", (UCHAR) nam_trgs, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_3_BEFORE_DELETE), - TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_3_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_26", (UCHAR) nam_rel_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_26_BEFORE_INSERT), - TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_26_BEFORE_INSERT, 0, ODS_8_0 }, - { "RDB$TRIGGER_25", (UCHAR) nam_rel_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_25_BEFORE_UPDATE), - TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_25_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_10", (UCHAR) nam_rel_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_10_BEFORE_DELETE), - TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_10_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_11", (UCHAR) nam_rel_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_11_AFTER_DELETE), - TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_11_AFTER_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_12", (UCHAR) nam_ref_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_12_BEFORE_INSERT), - TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_12_BEFORE_INSERT, 0, ODS_8_0 }, - { "RDB$TRIGGER_13", (UCHAR) nam_ref_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_13_BEFORE_UPDATE), - TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_13_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_14", (UCHAR) nam_chk_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_14_BEFORE_UPDATE), - TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_14_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_15", (UCHAR) nam_chk_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_15_BEFORE_DELETE), - TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_15_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_16", (UCHAR) nam_chk_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_16_AFTER_DELETE), - TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_16_AFTER_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_17", (UCHAR) nam_i_segments, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_17_BEFORE_DELETE), - TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_17_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_18", (UCHAR) nam_i_segments, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_18_BEFORE_UPDATE), - TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_18_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_19", (UCHAR) nam_indices, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_INDICES_TRIGGER_19_BEFORE_DELETE), - TRIGGER_BLR_RDB_INDICES_TRIGGER_19_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_20", (UCHAR) nam_indices, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_INDICES_TRIGGER_20_BEFORE_UPDATE), - TRIGGER_BLR_RDB_INDICES_TRIGGER_20_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_21", (UCHAR) nam_trgs, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_21_BEFORE_DELETE), - TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_21_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_22", (UCHAR) nam_trgs, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_22_BEFORE_UPDATE), - TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_22_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_23", (UCHAR) nam_r_fields, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_23_BEFORE_DELETE), - TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_23_BEFORE_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_24", (UCHAR) nam_r_fields, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_24_BEFORE_UPDATE), - TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_24_BEFORE_UPDATE, 0, ODS_8_0 }, - { "RDB$TRIGGER_27", (UCHAR) nam_r_fields, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_27_AFTER_DELETE), - TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_27_AFTER_DELETE, 0, ODS_8_0 }, - { "RDB$TRIGGER_34", (UCHAR) nam_rel_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_34_AFTER_DELETE), - TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_34_AFTER_DELETE, TRG_ignore_perm, ODS_8_1 }, - { "RDB$TRIGGER_35", (UCHAR) nam_chk_constr, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_35_AFTER_DELETE), - TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_35_AFTER_DELETE, TRG_ignore_perm, ODS_8_1 }, - { "RDB$TRIGGER_36", (UCHAR) nam_fields, - RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(TRIGGER_BLR_RDB_FIELDS_TRIGGER_36_BEFORE_UPDATE), - TRIGGER_BLR_RDB_FIELDS_TRIGGER_36_BEFORE_UPDATE, 0, ODS_11_0 }, - { 0, 0, 0, 0, 0, 0 } - }; - - // this table is used in defining messages for system triggers - - const trigger_msg trigger_messages[] = - { - { "RDB$TRIGGER_9", 0, "grant_obj_notfound", ODS_8_0 }, - { "RDB$TRIGGER_9", 1, "grant_fld_notfound", ODS_8_0 }, - { "RDB$TRIGGER_9", 2, "grant_nopriv", ODS_8_0 }, - { "RDB$TRIGGER_9", 3, "nonsql_security_rel", ODS_8_0 }, - { "RDB$TRIGGER_9", 4, "nonsql_security_fld", ODS_8_0 }, - { "RDB$TRIGGER_9", 5, "grant_nopriv_on_base", ODS_8_0 }, - { "RDB$TRIGGER_1", 0, "existing_priv_mod", ODS_8_0 }, - { "RDB$TRIGGER_2", 0, "systrig_update", ODS_8_0 }, - { "RDB$TRIGGER_3", 0, "systrig_update", ODS_8_0 }, - { "RDB$TRIGGER_24", 1, "cnstrnt_fld_rename", ODS_8_0 }, - { "RDB$TRIGGER_23", 1, "cnstrnt_fld_del", ODS_8_0 }, - { "RDB$TRIGGER_22", 1, "check_trig_update", ODS_8_0 }, - { "RDB$TRIGGER_21", 1, "check_trig_del", ODS_8_0 }, - { "RDB$TRIGGER_20", 1, "integ_index_mod", ODS_8_0 }, - { "RDB$TRIGGER_20", 2, "integ_index_deactivate", ODS_8_0 }, - { "RDB$TRIGGER_20", 3, "integ_deactivate_primary", ODS_8_0 }, - { "RDB$TRIGGER_19", 1, "integ_index_del", ODS_8_0 }, - { "RDB$TRIGGER_18", 1, "integ_index_seg_mod", ODS_8_0 }, - { "RDB$TRIGGER_17", 1, "integ_index_seg_del", ODS_8_0 }, - { "RDB$TRIGGER_15", 1, "check_cnstrnt_del", ODS_8_0 }, - { "RDB$TRIGGER_14", 1, "check_cnstrnt_update", ODS_8_0 }, - { "RDB$TRIGGER_13", 1, "ref_cnstrnt_update", ODS_8_0 }, - { "RDB$TRIGGER_12", 1, "ref_cnstrnt_notfound", ODS_8_0 }, - { "RDB$TRIGGER_12", 2, "foreign_key_notfound", ODS_8_0 }, - { "RDB$TRIGGER_10", 1, "primary_key_ref", ODS_8_0 }, - { "RDB$TRIGGER_10", 2, "primary_key_notnull", ODS_8_0 }, - { "RDB$TRIGGER_25", 1, "rel_cnstrnt_update", ODS_8_0 }, - { "RDB$TRIGGER_26", 1, "constaint_on_view", ODS_8_0 }, - { "RDB$TRIGGER_26", 2, "invld_cnstrnt_type", ODS_8_0 }, - { "RDB$TRIGGER_26", 3, "primary_key_exists", ODS_8_0 }, - { "RDB$TRIGGER_24", 2, "integ_index_seg_mod", ODS_11_0 }, - { "RDB$TRIGGER_36", 1, "integ_index_seg_mod", ODS_11_0 }, - { 0, 0, 0, 0 } - }; - unsigned getLatestFormat(thread_db* tdbb, int relId, int maxFieldId) { const auto relation = MET_relation(tdbb, relId); @@ -730,11 +602,9 @@ static void store_generator(thread_db*, const gen*, AutoRequest&, NonRelationSec static void store_global_field(thread_db*, const gfld*, AutoRequest&, NonRelationSecurity&); static void store_indices(thread_db*, USHORT = 0); static void store_intlnames(thread_db*, NonRelationSecurity&); -static void store_message(thread_db*, const trigger_msg*, AutoRequest&); static void store_relation(thread_db*, int, const char*, int, int, AutoRequest&, RelationSecurity&); static void store_relation_field(thread_db*, int, const char*, const char*, const char*, int, AutoRequest&); static void store_packages(thread_db*, NonRelationSecurity&, USHORT = 0); -static void store_trigger(thread_db*, const jrd_trg*, AutoRequest&); // @@ -779,6 +649,8 @@ void INI_format(thread_db* tdbb, const string& charset) for (const int* relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1) { + const bool isVirtual = (relfld[RFLD_R_TYPE] == rel_virtual); + bool needsRdbRuntime = false; int fieldId = 0; for (fld = relfld + RFLD_RPT; fld[RFLD_F_NAME]; fld += RFLD_F_LENGTH) @@ -790,6 +662,9 @@ void INI_format(thread_db* tdbb, const string& charset) const auto globalName = names[gfield->gfld_name]; const auto updateFlag = fld[RFLD_F_UPDATE]; + if (!isVirtual && (gfield->gfld_dflt_blr || !gfield->gfld_nullable)) + needsRdbRuntime = true; + store_relation_field(tdbb, fieldId, relName, fieldName, globalName, updateFlag, handle2); ++fieldId; @@ -800,6 +675,13 @@ void INI_format(thread_db* tdbb, const string& charset) const auto relType = relfld[RFLD_R_TYPE]; store_relation(tdbb, relId, relName, fieldId, relType, handle, relSec); + + if (needsRdbRuntime) + { + dsc desc; + desc.makeText(static_cast(strlen(relName)), CS_METADATA, (UCHAR*) relName); + DFW_post_work(transaction, dfw_update_format, &desc, 0); + } } } @@ -896,20 +778,6 @@ void INI_format(thread_db* tdbb, const string& charset) // Adjust the value of the hidden generator RDB$GENERATORS DPM_gen_id(tdbb, 0, true, FB_NELEM(generators) - 1); - // Store system-defined triggers - - handle.reset(); - - for (const jrd_trg* trigger = triggers; trigger->trg_relation; ++trigger) - store_trigger(tdbb, trigger, handle); - - // Store trigger messages to go with triggers - - handle.reset(); - - for (const trigger_msg* message = trigger_messages; message->trigmsg_name; ++message) - store_message(tdbb, message, handle); - // Create system packages // Reset nonRelSec for package permissions, it should be its last usage in this function @@ -952,22 +820,6 @@ void INI_format(thread_db* tdbb, const string& charset) } -// -// Return the trigger flags for a system trigger -// - -USHORT INI_get_trig_flags(const MetaName& triggerName) -{ - for (const jrd_trg* trig = triggers; trig->trg_length > 0; trig++) - { - if (triggerName == trig->trg_name) - return trig->trg_flags; - } - - return 0; -} - - // // Initialize in-memory meta data // @@ -989,17 +841,6 @@ void INI_init(thread_db* tdbb) relation->rel_flags |= MET_get_rel_flags_from_TYPE(relfld[RFLD_R_TYPE]); relation->rel_name = names[relfld[RFLD_R_NAME]]; - // Set a flag if their is a trigger on the relation. Later we may need to compile it. - - for (const jrd_trg* trigger = triggers; trigger->trg_relation; trigger++) - { - if (relation->rel_name == names[trigger->trg_relation]) - { - relation->rel_flags |= REL_sys_triggers; - break; - } - } - HalfStaticArray fieldNames; for (fld = relfld + RFLD_RPT; fld[RFLD_F_NAME]; fld += RFLD_F_LENGTH) { @@ -1102,6 +943,30 @@ void INI_init(thread_db* tdbb) } +// Rescan system relations that have fields with default values. +void INI_init_sys_relations(thread_db* tdbb) +{ + const int* fld; + + for (const int* relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1) + { + jrd_rel* relation = MET_relation(tdbb, relfld[RFLD_R_ID]); + bool needsRdbRuntime = false; + + for (fld = relfld + RFLD_RPT; fld[RFLD_F_NAME]; fld += RFLD_F_LENGTH) + { + const auto* const gfield = &gfields[fld[RFLD_F_ID]]; + + if (!relation->isVirtual() && (gfield->gfld_dflt_blr || !gfield->gfld_nullable)) + needsRdbRuntime = true; + } + + if (needsRdbRuntime) + MET_scan_relation(tdbb, relation); + } +} + + // // Load system objects into DSQL metadata cache // @@ -1373,26 +1238,6 @@ void INI_upgrade(thread_db* tdbb) context = "indices"; store_indices(tdbb, odsVersion); - // Create new system triggers and their trigger messages - - context = "triggers"; - handle.reset(); - - for (const jrd_trg* trigger = triggers; trigger->trg_relation; ++trigger) - { - if (trigger->trg_ods_version > odsVersion) - store_trigger(tdbb, trigger, handle); - } - - context = "trigger messages"; - handle.reset(); - - for (const trigger_msg* message = trigger_messages; message->trigmsg_name; ++message) - { - if (message->trg_ods_version > odsVersion) - store_message(tdbb, message, handle); - } - // Create new system generators context = "generators"; @@ -1944,22 +1789,6 @@ static void store_intlnames(thread_db* tdbb, NonRelationSecurity& security) } -static void store_message(thread_db* tdbb, const trigger_msg* message, AutoRequest& handle) -{ - const auto attachment = tdbb->getAttachment(); - const auto transaction = tdbb->getTransaction(); - - STORE(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) - X IN RDB$TRIGGER_MESSAGES - { - PAD(message->trigmsg_name, X.RDB$TRIGGER_NAME); - X.RDB$MESSAGE_NUMBER = message->trigmsg_number; - PAD(message->trigmsg_text, X.RDB$MESSAGE); - } - END_STORE -} - - static void store_relation(thread_db* tdbb, int relId, const char* relName, @@ -2226,36 +2055,3 @@ static void store_packages(thread_db* tdbb, NonRelationSecurity& security, USHOR } } } - - -static void store_trigger(thread_db* tdbb, const jrd_trg* trigger, AutoRequest& handle) -{ - const auto attachment = tdbb->getAttachment(); - const auto transaction = tdbb->getTransaction(); - - // Indicate that the relation format needs revising - - const auto triggerName = names[trigger->trg_relation]; - - dsc desc; - desc.makeText(static_cast(strlen(triggerName)), CS_METADATA, - (UCHAR*) triggerName); - DFW_post_work(transaction, dfw_update_format, &desc, 0); - - // Store the trigger - - STORE(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) - X IN RDB$TRIGGERS - { - PAD(trigger->trg_name, X.RDB$TRIGGER_NAME); - PAD(names[trigger->trg_relation], X.RDB$RELATION_NAME); - X.RDB$TRIGGER_SEQUENCE = 0; - X.RDB$SYSTEM_FLAG = RDB_system; - X.RDB$SYSTEM_FLAG.NULL = FALSE; - X.RDB$TRIGGER_TYPE = trigger->trg_type; - X.RDB$FLAGS = trigger->trg_flags; - attachment->storeBinaryBlob(tdbb, transaction, &X.RDB$TRIGGER_BLR, - ByteChunk(trigger->trg_blr, trigger->trg_length)); - } - END_STORE -} diff --git a/src/jrd/ini_proto.h b/src/jrd/ini_proto.h index c75011a0cc..08e51b6820 100644 --- a/src/jrd/ini_proto.h +++ b/src/jrd/ini_proto.h @@ -30,8 +30,8 @@ namespace Jrd { } void INI_format(Jrd::thread_db*, const Firebird::string&); -USHORT INI_get_trig_flags(const Jrd::MetaName&); void INI_init(Jrd::thread_db*); +void INI_init_sys_relations(Jrd::thread_db*); void INI_init_dsql(Jrd::thread_db*, Jrd::dsql_dbb* database); Firebird::string INI_owner_privileges(); void INI_upgrade(Jrd::thread_db*); diff --git a/src/jrd/irq.h b/src/jrd/irq.h index 7e41cc7042..2c6d1a9288 100644 --- a/src/jrd/irq.h +++ b/src/jrd/irq.h @@ -54,7 +54,6 @@ enum irq_type_t irq_l_funct_blr, // lookup function BLR and debug info irq_l_args, // lookup function arguments irq_s_triggers, // scan triggers - irq_s_triggers2, // scan triggers irq_s_msgs, // search for message irq_grant1, // process grant option irq_grant2, // process grant option diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 1b4164b774..13c931aec9 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -944,9 +944,6 @@ void Trigger::compile(thread_db* tdbb) if (ssDefiner.asBool()) statement->triggerInvoker = att->getUserId(owner); - if (sysTrigger) - statement->flags |= Statement::FLAG_SYS_TRIGGER | Statement::FLAG_INTERNAL; - if (flags & TRG_ignore_perm) statement->flags |= Statement::FLAG_IGNORE_PERM; } @@ -955,15 +952,7 @@ void Trigger::release(thread_db* tdbb) { extTrigger.reset(); - // dimitr: We should never release triggers created by MET_parse_sys_trigger(). - // System triggers do have BLR, but it's not stored inside the trigger object. - // However, triggers backing RI constraints are also marked as system, - // but they are loaded in a regular way and their BLR is present here. - // This is why we cannot simply check for sysTrigger, sigh. - - const bool sysTableTrigger = (blr.isEmpty() && engine.isEmpty()); - - if (sysTableTrigger || !statement || statement->isActive() || releaseInProgress) + if (!statement || statement->isActive() || releaseInProgress) return; AutoSetRestore autoProgressFlag(&releaseInProgress, true); @@ -1904,6 +1893,8 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch PAG_attachment_id(tdbb); + INI_init_sys_relations(tdbb); + bool cleanupTransactions = false; if (!options.dpb_verify && CCH_exclusive(tdbb, LCK_PW, LCK_NO_WAIT, NULL)) @@ -9230,11 +9221,7 @@ ISC_STATUS thread_db::getCancelState(ISC_STATUS* secondary) if ((attachment->att_flags & ATT_cancel_raise) && !(attachment->att_flags & ATT_cancel_disable)) { - if ((!request || - !(request->getStatement()->flags & - // temporary change to fix shutdown - (/*Statement::FLAG_INTERNAL | */Statement::FLAG_SYS_TRIGGER))) && - (!transaction || !(transaction->tra_flags & TRA_system))) + if ((!transaction || !(transaction->tra_flags & TRA_system))) { return isc_cancelled; } diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 9bb03c60e8..677aafba7f 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -142,7 +142,6 @@ public: Firebird::HalfStaticArray debugInfo; // Debug info Statement* statement = nullptr; // Compiled statement bool releaseInProgress = false; - bool sysTrigger = false; FB_UINT64 type = 0; // Trigger type USHORT flags = 0; // Flags as they are in RDB$TRIGGERS table jrd_rel* relation = nullptr; // Trigger parent relation diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 0f3bae45b8..48e8cc406d 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -115,7 +115,7 @@ static int blocking_ast_relation(void*); static int partners_ast_relation(void*); static int rescan_ast_relation(void*); static ULONG get_rel_flags_from_FLAGS(USHORT); -static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, bool, +static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, USHORT, const MetaName&, const string&, const bid*, TriState ssDefiner); static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*); static void lookup_view_contexts(thread_db*, jrd_rel*); @@ -124,7 +124,7 @@ static ValueExprNode* parse_field_default_blr(thread_db* tdbb, bid* blob_id); static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const MetaName name); static bool resolve_charset_and_collation(thread_db*, USHORT*, const UCHAR*, const UCHAR*); static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, Statement*, blb*, blb*, - const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&, + const TEXT*, FB_UINT64, USHORT, const MetaName&, const string&, const bid*, TriState ssDefiner); static void scan_partners(thread_db*, jrd_rel*); static bool verify_TRG_ignore_perm(thread_db*, const MetaName&); @@ -1928,9 +1928,6 @@ void MET_load_trigger(thread_db* tdbb, if (relation) { - if (relation->rel_flags & REL_sys_trigs_being_loaded) - return; - // No need to load table triggers for ReadOnly databases, // since INSERT/DELETE/UPDATE statements are not going to be allowed // hvlad: GTT with ON COMMIT DELETE ROWS clause is writable @@ -2006,7 +2003,6 @@ void MET_load_trigger(thread_db* tdbb, triggers, TRG.RDB$TRIGGER_NAME, TRG.RDB$TRIGGER_TYPE, - (bool) TRG.RDB$SYSTEM_FLAG, trig_flags, engine, entryPoint, @@ -2027,7 +2023,6 @@ void MET_load_trigger(thread_db* tdbb, triggers + trigger_action, TRG.RDB$TRIGGER_NAME, (UCHAR) trigger_action, - (bool) TRG.RDB$SYSTEM_FLAG, trig_flags, engine, entryPoint, @@ -3213,111 +3208,6 @@ DmlNode* MET_parse_blob(thread_db* tdbb, } -void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation) -{ -/************************************** - * - * M E T _ p a r s e _ s y s _ t r i g g e r - * - ************************************** - * - * Functional description - * Parse the blr for a system relation's triggers. - * - **************************************/ - SET_TDBB(tdbb); - Attachment* attachment = tdbb->getAttachment(); - Database* dbb = tdbb->getDatabase(); - - relation->rel_flags &= ~REL_sys_triggers; - - // Release any triggers in case of a rescan - - relation->releaseTriggers(tdbb, true); - - // No need to load triggers for ReadOnly databases, since - // INSERT/DELETE/UPDATE statements are not going to be allowed - // hvlad: GTT with ON COMMIT DELETE ROWS clause is writable - - if (dbb->readOnly() && !(relation->rel_flags & REL_temp_tran)) - return; - - relation->rel_flags |= REL_sys_trigs_being_loaded; - - AutoCacheRequest request(tdbb, irq_s_triggers2, IRQ_REQUESTS); - - FOR (REQUEST_HANDLE request) - TRG IN RDB$TRIGGERS - WITH TRG.RDB$RELATION_NAME = relation->rel_name.c_str() - AND TRG.RDB$SYSTEM_FLAG = 1 - { - const FB_UINT64 type = TRG.RDB$TRIGGER_TYPE; - const USHORT trig_flags = TRG.RDB$FLAGS; - const TEXT* name = TRG.RDB$TRIGGER_NAME; - - TrigVector** ptr; - - switch (type) - { - case TRIGGER_PRE_STORE: - ptr = &relation->rel_pre_store; - break; - case TRIGGER_POST_STORE: - ptr = &relation->rel_post_store; - break; - case TRIGGER_PRE_MODIFY: - ptr = &relation->rel_pre_modify; - break; - case TRIGGER_POST_MODIFY: - ptr = &relation->rel_post_modify; - break; - case TRIGGER_PRE_ERASE: - ptr = &relation->rel_pre_erase; - break; - case TRIGGER_POST_ERASE: - ptr = &relation->rel_post_erase; - break; - default: - ptr = NULL; - break; - } - - if (ptr) - { - blb* blob = blb::open(tdbb, attachment->getSysTransaction(), &TRG.RDB$TRIGGER_BLR); - ULONG length = blob->blb_length + 10; - HalfStaticArray blr; - length = blob->BLB_get_data(tdbb, blr.getBuffer(length), length); - - USHORT par_flags = (USHORT) ((trig_flags & TRG_ignore_perm) ? csb_ignore_perm : 0); - if (type & 1) - par_flags |= csb_pre_trigger; - else - par_flags |= csb_post_trigger; - - Statement* statement = NULL; - - { - Jrd::ContextPoolHolder context(tdbb, attachment->createPool()); - PAR_blr(tdbb, relation, blr.begin(), length, NULL, NULL, &statement, true, par_flags); - } - - statement->triggerName = name; - - statement->flags |= Statement::FLAG_SYS_TRIGGER | Statement::FLAG_INTERNAL; - if (trig_flags & TRG_ignore_perm) - statement->flags |= Statement::FLAG_IGNORE_PERM; - - save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, true, 0, "", - "", NULL, TriState()); - } - } - END_FOR - - relation->rel_flags &= ~REL_sys_trigs_being_loaded; -} - - void MET_post_existence(thread_db* tdbb, jrd_rel* relation) { /************************************** @@ -3968,7 +3858,6 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation) Database* dbb = tdbb->getDatabase(); Jrd::ContextPoolHolder context(tdbb, attachment->att_pool); bool dependencies = false; - bool sys_triggers = false; blb* blob = NULL; @@ -3985,8 +3874,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation) relation->rel_flags |= REL_being_scanned; dependencies = (relation->rel_flags & REL_get_dependencies) ? true : false; - sys_triggers = (relation->rel_flags & REL_sys_triggers) ? true : false; - relation->rel_flags &= ~(REL_get_dependencies | REL_sys_triggers); + relation->rel_flags &= ~REL_get_dependencies; for (USHORT itr = 0; itr < TRIGGER_MAX; ++itr) triggers[itr] = NULL; @@ -4274,17 +4162,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation) // We have just loaded the triggers onto the local vector triggers. // It's now time to place them at their rightful place inside the relation block. - - if (!(relation->rel_flags & REL_sys_trigs_being_loaded)) - { - // if we are scanning a system relation during loading the system - // triggers, (during parsing its blr actually), we must not release the - // existing system triggers; because we have already set the - // relation->rel_flag to not have REL_sys_trig, so these - // system triggers will not get loaded again. This fixes bug 8149. - - relation->replaceTriggers(tdbb, triggers); - } + relation->replaceTriggers(tdbb, triggers); LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT); relation->rel_flags &= ~REL_being_scanned; @@ -4298,9 +4176,6 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation) if (dependencies) { relation->rel_flags |= REL_get_dependencies; } - if (sys_triggers) { - relation->rel_flags |= REL_sys_triggers; - } if (blob) blob->BLB_close(tdbb); @@ -4670,7 +4545,7 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type) static void get_trigger(thread_db* tdbb, jrd_rel* relation, bid* blob_id, bid* debug_blob_id, TrigVector** ptr, const TEXT* name, FB_UINT64 type, - bool sys_trigger, USHORT flags, + USHORT flags, const MetaName& engine, const string& entryPoint, const bid* body, TriState ssDefiner) { @@ -4700,7 +4575,7 @@ static void get_trigger(thread_db* tdbb, jrd_rel* relation, debugInfoBlob = blb::open(tdbb, attachment->getSysTransaction(), debug_blob_id); save_trigger_data(tdbb, ptr, relation, NULL, blrBlob, debugInfoBlob, - name, type, sys_trigger, flags, engine, entryPoint, body, ssDefiner); + name, type, flags, engine, entryPoint, body, ssDefiner); } @@ -5052,7 +4927,7 @@ static bool resolve_charset_and_collation(thread_db* tdbb, static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relation, Statement* statement, blb* blrBlob, blb* debugInfoBlob, const TEXT* name, FB_UINT64 type, - bool sys_trigger, USHORT flags, + USHORT flags, const MetaName& engine, const string& entryPoint, const bid* body, TriState ssDefiner) { @@ -5109,7 +4984,6 @@ static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relati t.type = type; t.flags = flags; - t.sysTrigger = sys_trigger; t.statement = statement; t.relation = relation; t.engine = engine; @@ -5305,18 +5179,7 @@ void MET_store_dependencies(thread_db* tdbb, SET_TDBB(tdbb); - const Trigger* t = 0; - const bool checkTableScope = - (dependency_type == obj_computed) || - (dependency_type == obj_trigger) && (dep_rel != 0) && - ( - (t = findTrigger(dep_rel->rel_pre_erase, object_name)) || - (t = findTrigger(dep_rel->rel_pre_modify, object_name)) || - (t = findTrigger(dep_rel->rel_pre_store, object_name)) || - (t = findTrigger(dep_rel->rel_post_erase, object_name)) || - (t = findTrigger(dep_rel->rel_post_modify, object_name)) || - (t = findTrigger(dep_rel->rel_post_store, object_name)) - ) && t && (t->sysTrigger); + const bool checkTableScope = dependency_type == obj_computed; while (dependencies.hasData()) { @@ -5538,11 +5401,6 @@ static bool verify_TRG_ignore_perm(thread_db* tdbb, const MetaName& trig_name) SET_TDBB(tdbb); Attachment* attachment = tdbb->getAttachment(); - // See if this is a system trigger, with the flag set as TRG_ignore_perm - - if (INI_get_trig_flags(trig_name) & TRG_ignore_perm) - return true; - // See if this is a RI trigger AutoCacheRequest request(tdbb, irq_c_trg_perm, IRQ_REQUESTS); diff --git a/src/jrd/met_proto.h b/src/jrd/met_proto.h index 35534208d2..1182c81449 100644 --- a/src/jrd/met_proto.h +++ b/src/jrd/met_proto.h @@ -118,7 +118,6 @@ Jrd::jrd_rel* MET_lookup_relation(Jrd::thread_db*, const Jrd::MetaName&); Jrd::jrd_rel* MET_lookup_relation_id(Jrd::thread_db*, SLONG, bool); Jrd::DmlNode* MET_parse_blob(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::bid*, Jrd::CompilerScratch**, Jrd::Statement**, bool, bool); -void MET_parse_sys_trigger(Jrd::thread_db*, Jrd::jrd_rel*); void MET_post_existence(Jrd::thread_db*, Jrd::jrd_rel*); void MET_prepare(Jrd::thread_db*, Jrd::jrd_tra*, USHORT, const UCHAR*); Jrd::jrd_prc* MET_procedure(Jrd::thread_db*, USHORT, bool, USHORT); diff --git a/src/jrd/mov.cpp b/src/jrd/mov.cpp index 1e8a618171..3f03c8f79c 100644 --- a/src/jrd/mov.cpp +++ b/src/jrd/mov.cpp @@ -242,6 +242,15 @@ int MOV_get_string(Jrd::thread_db* tdbb, const dsc* desc, UCHAR** address, vary* } +void MOV_get_string(Jrd::thread_db* tdbb, const dsc* desc, string& str) +{ + VaryStr temp; + const char* strPtr = NULL; + const auto len = MOV_make_string(tdbb, desc, ttype_metadata, &strPtr, &temp, MAX_SQL_IDENTIFIER_SIZE); + str.assign(strPtr, len); +} + + GDS_DATE MOV_get_sql_date(const dsc* desc) { /************************************** diff --git a/src/jrd/mov_proto.h b/src/jrd/mov_proto.h index 8edfd15923..d2200f6f6d 100644 --- a/src/jrd/mov_proto.h +++ b/src/jrd/mov_proto.h @@ -42,6 +42,7 @@ SQUAD MOV_get_quad(Jrd::thread_db*, const dsc*, SSHORT); SINT64 MOV_get_int64(Jrd::thread_db*, const dsc*, SSHORT); int MOV_get_string_ptr(Jrd::thread_db*, const dsc*, USHORT*, UCHAR**, vary*, USHORT); int MOV_get_string(Jrd::thread_db*, const dsc*, UCHAR**, vary*, USHORT); +void MOV_get_string(Jrd::thread_db* tdbb, const dsc* desc, Firebird::string& str); GDS_DATE MOV_get_sql_date(const dsc*); GDS_TIME MOV_get_sql_time(const dsc*); ISC_TIME_TZ MOV_get_sql_time_tz(const dsc*); diff --git a/src/jrd/trace/TraceJrdHelpers.h b/src/jrd/trace/TraceJrdHelpers.h index 3a4614c462..7458d7f078 100644 --- a/src/jrd/trace/TraceJrdHelpers.h +++ b/src/jrd/trace/TraceJrdHelpers.h @@ -431,8 +431,7 @@ public: const auto attachment = m_tdbb->getAttachment(); const auto trace_mgr = attachment->att_trace_manager; - m_need_trace = !trigger->sysTrigger && - trace_mgr->needs(ITraceFactory::TRACE_EVENT_TRIGGER_COMPILE); + m_need_trace = trace_mgr->needs(ITraceFactory::TRACE_EVENT_TRIGGER_COMPILE); if (!m_need_trace) return; @@ -529,8 +528,7 @@ public: const auto transaction = m_tdbb->getTransaction(); const auto trace_mgr = attachment->att_trace_manager; - m_need_trace = !(m_request->getStatement()->flags & Statement::FLAG_SYS_TRIGGER) && - trace_mgr->needs(ITraceFactory::TRACE_EVENT_TRIGGER_EXECUTE); + m_need_trace = trace_mgr->needs(ITraceFactory::TRACE_EVENT_TRIGGER_EXECUTE); if (!m_need_trace) return; diff --git a/src/jrd/trig.h b/src/jrd/trig.h index 47510acb8c..6b398b4abb 100644 --- a/src/jrd/trig.h +++ b/src/jrd/trig.h @@ -86,1532 +86,4 @@ static const Jrd::gen generators[] = }; -static constexpr UCHAR TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_14_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_and, - blr_not, - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 8,0, 'N','O','T',32,'N','U','L','L', - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_15_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_16_AFTER_DELETE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 4, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 8,0, 'N','O','T',32,'N','U','L','L', - blr_eql, - blr_field, 3, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_end, - blr_begin, - blr_modify, 3, 5, - blr_begin, - blr_assignment, - blr_literal, blr_long, 0, 0,0,0,0, - blr_field, 5, 13, 'R','D','B','$','N','U','L','L','_','F','L','A','G', - blr_end, - blr_end, - blr_for, - blr_rse, 2, - blr_relation, 12, 'R','D','B','$','T','R','I','G','G','E','R','S', 6, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 7, - blr_boolean, - blr_and, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_and, - blr_eql, - blr_field, 6, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 7, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 6, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 6, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_CHECK_CONSTRAINTS_TRIGGER_35_AFTER_DELETE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 12, 'R','D','B','$','T','R','I','G','G','E','R','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_eql, - blr_field, 3, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 3, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_FIELDS_TRIGGER_36_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_if, - blr_not, - blr_and, - blr_eql, - blr_field, 0, 16, 'R','D','B','$','F','I','E','L','D','_','L','E','N','G','T','H', - blr_field, 1, 16, 'R','D','B','$','F','I','E','L','D','_','L','E','N','G','T','H', - blr_and, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','T','Y','P','E', - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','T','Y','P','E', - blr_and, - blr_eql, - blr_field, 0, 16, 'R','D','B','$','C','O','L','L','A','T','I','O','N','_','I','D', - blr_field, 1, 16, 'R','D','B','$','C','O','L','L','A','T','I','O','N','_','I','D', - blr_eql, - blr_field, 0, 20, 'R','D','B','$','C','H','A','R','A','C','T','E','R','_','S','E','T','_','I','D', - blr_field, 1, 20, 'R','D','B','$','C','H','A','R','A','C','T','E','R','_','S','E','T','_','I','D', - blr_if, - blr_any, - blr_rse, 4, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_relation, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', 5, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 6, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 6, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 5, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 6, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_eql, - blr_field, 6, 16, 'R','D','B','$','F','I','E','L','D','_','S','O','U','R','C','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_17_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_INDEX_SEGMENTS_TRIGGER_18_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_if, - blr_not, - blr_and, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_eql, - blr_field, 0, 18, 'R','D','B','$','F','I','E','L','D','_','P','O','S','I','T','I','O','N', - blr_field, 1, 18, 'R','D','B','$','F','I','E','L','D','_','P','O','S','I','T','I','O','N', - blr_leave, 1, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_INDICES_TRIGGER_19_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_INDICES_TRIGGER_20_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_not, - blr_and, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 0, 12, 'R','D','B','$','I','N','D','E','X','_','I','D', - blr_field, 1, 12, 'R','D','B','$','I','N','D','E','X','_','I','D', - blr_and, - blr_eql, - blr_field, 0, 17, 'R','D','B','$','S','E','G','M','E','N','T','_','C','O','U','N','T', - blr_field, 1, 17, 'R','D','B','$','S','E','G','M','E','N','T','_','C','O','U','N','T', - blr_eql, - blr_field, 0, 15, 'R','D','B','$','F','O','R','E','I','G','N','_','K','E','Y', - blr_field, 1, 15, 'R','D','B','$','F','O','R','E','I','G','N','_','K','E','Y', - blr_leave, 1, - blr_end, - blr_end, - blr_end, - blr_for, - blr_rse, 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 5, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 6, - blr_boolean, - blr_and, - blr_eql, - blr_field, 4, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 6, 15, 'R','D','B','$','F','O','R','E','I','G','N','_','K','E','Y', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 1, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_literal, blr_long, 0, 1,0,0,0, - blr_or, - blr_eql, - blr_field, 0, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_missing, - blr_field, 0, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_end, - blr_begin, - blr_leave, 2, - blr_end, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 7, - blr_boolean, - blr_and, - blr_eql, - blr_field, 7, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_or, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_or, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 6,0, 'U','N','I','Q','U','E', - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_end, - blr_begin, - blr_if, - blr_and, - blr_eql, - blr_field, 1, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_literal, blr_long, 0, 1,0,0,0, - blr_or, - blr_eql, - blr_field, 0, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_missing, - blr_field, 0, 18, 'R','D','B','$','I','N','D','E','X','_','I','N','A','C','T','I','V','E', - blr_begin, - blr_if, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_leave, 2, - blr_leave, 3, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_12_BEFORE_INSERT[] = { - blr_version5, - blr_begin, - blr_if, - blr_not, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_end, - blr_leave, 1, - blr_end, - blr_if, - blr_not, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','C','O','N','S','T','_','N','A','M','E','_','U','Q', - blr_or, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 6,0, 'U','N','I','Q','U','E', - blr_end, - blr_leave, 2, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_REF_CONSTRAINTS_TRIGGER_13_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_leave, 1, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_10_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_label, 0, - blr_begin, - blr_begin, - blr_if, - blr_or, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text2, 0,0, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text2, 0,0, 6,0, 'U','N','I','Q','U','E', - blr_begin, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','R','E','F','_','C','O','N','S','T','R','A','I','N','T','S', 2, - blr_boolean, - blr_eql, - blr_field, 2, 17, 'R','D','B','$','C','O','N','S','T','_','N','A','M','E','_','U','Q', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_begin, - blr_begin, - blr_leave, 1, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text2, 0,0, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_begin, - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','R','E','F','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_erase, 3, - blr_end, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text2, 0,0, 8,0, 'N','O','T',32,'N','U','L','L', - blr_begin, - blr_begin, - blr_label, 1, - blr_for, - blr_rse, 5, - blr_relation2, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', - 9, 'C','1',32,'C','H','K','C','O','N', 4, - blr_relation2, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', - 6, 'C','1',32,'R','F','L', 5, - blr_relation2, 10, 'R','D','B','$','F','I','E','L','D','S', - 6, 'C','1',32,'F','L','D', 6, - blr_relation2, 11, 'R','D','B','$','I','N','D','I','C','E','S', - 6, 'C','1',32,'I','N','D', 7, - blr_relation2, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', - 9, 'C','1',32,'I','D','X','S','E','G', 8, - blr_boolean, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_eql, - blr_field, 5, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 4, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_eql, - blr_field, 5, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 5, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 8, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_eql, - blr_field, 6, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 5, 16, 'R','D','B','$','F','I','E','L','D','_','S','O','U','R','C','E', - blr_or, - blr_missing, - blr_field, 6, 13, 'R','D','B','$','N','U','L','L','_','F','L','A','G', - blr_eql, - blr_field, 6, 13, 'R','D','B','$','N','U','L','L','_','F','L','A','G', - blr_literal, blr_long, 0, 0,0,0,0, - blr_eql, - blr_field, 7, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 7, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 8, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_begin, - blr_begin, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 9, - blr_boolean, - blr_and, - blr_eql, - blr_field, 9, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_derived_expr, 1, 8, - blr_field, 8, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_eql, - blr_field, 9, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text2, 0,0, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_end, - blr_begin, - blr_begin, - blr_leave, 2, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_11_AFTER_DELETE[] = { - blr_version5, - blr_begin, - blr_if, - blr_or, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_or, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 6,0, 'U','N','I','Q','U','E', - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 3, - blr_boolean, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 3, - blr_for, - blr_rse, 1, - blr_relation, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', 4, - blr_boolean, - blr_eql, - blr_field, 4, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 4, - blr_end, - blr_end, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 8,0, 'N','O','T',32,'N','U','L','L', - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 5, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 6, - blr_boolean, - blr_and, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 5, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 6, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 6, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 5, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 5, - blr_modify, 6, 7, - blr_begin, - blr_assignment, - blr_literal, blr_long, 0, 0,0,0,0, - blr_field, 7, 13, 'R','D','B','$','N','U','L','L','_','F','L','A','G', - blr_end, - blr_end, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 8, - blr_boolean, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 8, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 8, - blr_for, - blr_rse, 1, - blr_relation, 12, 'R','D','B','$','T','R','I','G','G','E','R','S', 9, - blr_boolean, - blr_and, - blr_eql, - blr_field, 9, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 8, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_eql, - blr_field, 9, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 9, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_25_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_leave, 1, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_26_BEFORE_INSERT[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 13, 'R','D','B','$','R','E','L','A','T','I','O','N','S', 3, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_not, - blr_missing, - blr_field, 3, 15, 'R','D','B','$','V','I','E','W','_','S','O','U','R','C','E', - blr_end, - blr_leave, 1, - blr_end, - blr_if, - blr_not, - blr_or, - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 6,0, 'U','N','I','Q','U','E', - blr_or, - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_or, - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_or, - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 8,0, 'N','O','T',32,'N','U','L','L', - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_leave, 2, - blr_end, - blr_if, - blr_eql, - blr_field, 1, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'P','R','I','M','A','R','Y',32,'K','E','Y', - blr_eql, - blr_field, 4, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_leave, 3, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_CONSTRAINTS_TRIGGER_34_AFTER_DELETE[] = { - blr_version5, - blr_begin, - blr_if, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 11,0, 'F','O','R','E','I','G','N',32,'K','E','Y', - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_boolean, - blr_eql, - blr_field, 0, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 3, - blr_for, - blr_rse, 1, - blr_relation, 12, 'R','D','B','$','T','R','I','G','G','E','R','S', 4, - blr_boolean, - blr_eql, - blr_field, 4, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 3, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_end, - blr_begin, - blr_erase, 4, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_23_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 3, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_relation, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', 5, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_eql, - blr_field, 5, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', 6, - blr_boolean, - blr_and, - blr_eql, - blr_field, 6, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_neq, - blr_field, 6, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_erase, 4, - blr_end, - blr_for, - blr_rse, 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 7, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 8, - blr_relation, 16, 'R','D','B','$','D','E','P','E','N','D','E','N','C','I','E','S', 9, - blr_boolean, - blr_and, - blr_and, - blr_eql, - blr_field, 7, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_and, - blr_eql, - blr_field, 8, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 9, 18, 'R','D','B','$','D','E','P','E','N','D','E','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 9, 18, 'R','D','B','$','D','E','P','E','N','D','E','N','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 2,0,0,0, - blr_and, - blr_eql, - blr_field, 9, 20, 'R','D','B','$','D','E','P','E','N','D','E','D','_','O','N','_','T','Y','P','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_and, - blr_eql, - blr_field, 9, 20, 'R','D','B','$','D','E','P','E','N','D','E','D','_','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 9, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_eql, - blr_field, 8, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 7, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_any, - blr_rse, 1, - blr_relation, 16, 'R','D','B','$','D','E','P','E','N','D','E','N','C','I','E','S', 10, - blr_boolean, - blr_and, - blr_eql, - blr_field, 10, 18, 'R','D','B','$','D','E','P','E','N','D','E','N','T','_','N','A','M','E', - blr_field, 8, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 10, 18, 'R','D','B','$','D','E','P','E','N','D','E','N','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 2,0,0,0, - blr_and, - blr_eql, - blr_field, 10, 20, 'R','D','B','$','D','E','P','E','N','D','E','D','_','O','N','_','T','Y','P','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_and, - blr_eql, - blr_field, 10, 20, 'R','D','B','$','D','E','P','E','N','D','E','D','_','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_neq, - blr_field, 10, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_leave, 1, - blr_erase, 7, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_24_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_if, - blr_any, - blr_rse, 3, - blr_relation, 11, 'R','D','B','$','I','N','D','I','C','E','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_relation, 18, 'R','D','B','$','I','N','D','E','X','_','S','E','G','M','E','N','T','S', 5, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 3, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_field, 5, 14, 'R','D','B','$','I','N','D','E','X','_','N','A','M','E', - blr_eql, - blr_field, 5, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_neq, - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_leave, 1, - blr_end, - blr_if, - blr_not, - blr_and, - blr_eql, - blr_field, 0, 16, 'R','D','B','$','F','I','E','L','D','_','S','O','U','R','C','E', - blr_field, 1, 16, 'R','D','B','$','F','I','E','L','D','_','S','O','U','R','C','E', - blr_eql, - blr_field, 0, 16, 'R','D','B','$','C','O','L','L','A','T','I','O','N','_','I','D', - blr_field, 1, 16, 'R','D','B','$','C','O','L','L','A','T','I','O','N','_','I','D', - blr_leave, 2, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_RELATION_FIELDS_TRIGGER_27_AFTER_DELETE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 3, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 4, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 8,0, 'N','O','T',32,'N','U','L','L', - blr_end, - blr_begin, - blr_erase, 4, - blr_erase, 3, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_2_BEFORE_UPDATE[] = { - blr_version5, - blr_if, - blr_eql, - blr_field, 0, 15, 'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G', - blr_literal, blr_short, 0, 1,0, - blr_leave, 0, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_21_BEFORE_DELETE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_end, - blr_begin, - blr_leave, 1, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_22_BEFORE_UPDATE[] = { - blr_version5, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 21, 'R','D','B','$','C','H','E','C','K','_','C','O','N','S','T','R','A','I','N','T','S', 3, - blr_relation, 24, 'R','D','B','$','R','E','L','A','T','I','O','N','_','C','O','N','S','T','R','A','I','N','T','S', 4, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_field, 3, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','N','A','M','E', - blr_eql, - blr_field, 4, 19, 'R','D','B','$','C','O','N','S','T','R','A','I','N','T','_','T','Y','P','E', - blr_literal, blr_text, 5,0, 'C','H','E','C','K', - blr_end, - blr_begin, - blr_if, - blr_not, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_and, - blr_equiv, - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_field, 1, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','N','A','M','E', - blr_equiv, - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_equiv, - blr_field, 0, 20, 'R','D','B','$','T','R','I','G','G','E','R','_','S','E','Q','U','E','N','C','E', - blr_field, 1, 20, 'R','D','B','$','T','R','I','G','G','E','R','_','S','E','Q','U','E','N','C','E', - blr_equiv, - blr_field, 0, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','T','Y','P','E', - blr_field, 1, 16, 'R','D','B','$','T','R','I','G','G','E','R','_','T','Y','P','E', - blr_equiv, - blr_field, 0, 15, 'R','D','B','$','T','R','I','G','G','E','R','_','B','L','R', - blr_field, 1, 15, 'R','D','B','$','T','R','I','G','G','E','R','_','B','L','R', - blr_equiv, - blr_field, 0, 20, 'R','D','B','$','T','R','I','G','G','E','R','_','I','N','A','C','T','I','V','E', - blr_field, 1, 20, 'R','D','B','$','T','R','I','G','G','E','R','_','I','N','A','C','T','I','V','E', - blr_equiv, - blr_field, 0, 15, 'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G', - blr_field, 1, 15, 'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G', - blr_equiv, - blr_field, 0, 9, 'R','D','B','$','F','L','A','G','S', - blr_field, 1, 9, 'R','D','B','$','F','L','A','G','S', - blr_equiv, - blr_field, 0, 14, 'R','D','B','$','D','E','B','U','G','_','I','N','F','O', - blr_field, 1, 14, 'R','D','B','$','D','E','B','U','G','_','I','N','F','O', - blr_begin, - blr_leave, 1, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_TRIGGERS_TRIGGER_3_BEFORE_DELETE[] = { - blr_version5, - blr_if, - blr_eql, - blr_field, 0, 15, 'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G', - blr_literal, blr_short, 0, 1,0, - blr_leave, 0, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_1_BEFORE_UPDATE[] = { - blr_version5, - blr_leave, 0, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_8_BEFORE_DELETE[] = { - blr_version5, - blr_if, - blr_not, - blr_missing, - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_for, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 3, - blr_boolean, - blr_and, - blr_eql, - blr_field, 3, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 0, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 3, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 0, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_starting, - blr_field, 3, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_text, 9,0, 'S','Q','L','$','G','R','A','N','T', - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 20, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S','E','S', 4, - blr_boolean, - blr_eql, - blr_field, 4, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_field, 3, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_begin, - blr_erase, 4, - blr_end, - blr_modify, 3, 5, - blr_begin, - blr_assignment, - blr_null, - blr_field, 5, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - -static constexpr UCHAR TRIGGER_BLR_RDB_USER_PRIVILEGES_TRIGGER_9_BEFORE_INSERT[] = { - blr_version5, - blr_begin, - blr_if, - blr_missing, - blr_field, 1, 11, 'R','D','B','$','G','R','A','N','T','O','R', - blr_assignment, - blr_user_name, - blr_field, 1, 11, 'R','D','B','$','G','R','A','N','T','O','R', - blr_end, - blr_if, - blr_eql, - blr_field, 1, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_begin, - blr_for, - blr_rse, 1, - blr_relation, 13, 'R','D','B','$','R','E','L','A','T','I','O','N','S', 6, - blr_boolean, - blr_eql, - blr_field, 6, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_or, - blr_and, - blr_eql, - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_user_name, - blr_and, - blr_eql, - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_field, 1, 11, 'R','D','B','$','G','R','A','N','T','O','R', - blr_eql, - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_field, 1, 8, 'R','D','B','$','U','S','E','R', - blr_eql, - blr_sys_function, 20, 'R','D','B','$','S','Y','S','T','E','M','_','P','R','I','V','I','L','E','G','E',1, - blr_literal, blr_short, 0, 21,0, - blr_literal, blr_bool, 1, - blr_begin, - blr_end, - blr_if, - blr_neq, - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_user_name, - blr_begin, - blr_end, - blr_if, - blr_not, - blr_missing, - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_begin, - blr_for, - blr_rse, 3, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 8, - blr_relation, 18, 'R','D','B','$','V','I','E','W','_','R','E','L','A','T','I','O','N','S', 9, - blr_relation, 13, 'R','D','B','$','R','E','L','A','T','I','O','N','S', 10, - blr_boolean, - blr_and, - blr_eql, - blr_field, 8, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 8, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_not, - blr_missing, - blr_field, 8, 14, 'R','D','B','$','B','A','S','E','_','F','I','E','L','D', - blr_and, - blr_eql, - blr_field, 9, 13, 'R','D','B','$','V','I','E','W','_','N','A','M','E', - blr_field, 8, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 9, 16, 'R','D','B','$','V','I','E','W','_','C','O','N','T','E','X','T', - blr_field, 8, 16, 'R','D','B','$','V','I','E','W','_','C','O','N','T','E','X','T', - blr_eql, - blr_field, 9, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 10, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_and, - blr_neq, - blr_field, 10, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_neq, - blr_sys_function, 20, 'R','D','B','$','S','Y','S','T','E','M','_','P','R','I','V','I','L','E','G','E',1, - blr_literal, blr_short, 0, 21,0, - blr_literal, blr_bool, 1, - blr_begin, - blr_if, - blr_not, - blr_any, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','U','S','E','R','_','P','R','I','V','I','L','E','G','E','S', 11, - blr_boolean, - blr_and, - blr_eql, - blr_field, 11, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 10, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 11, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_and, - blr_eql, - blr_field, 11, 13, 'R','D','B','$','P','R','I','V','I','L','E','G','E', - blr_field, 1, 13, 'R','D','B','$','P','R','I','V','I','L','E','G','E', - blr_and, - blr_eql, - blr_field, 11, 8, 'R','D','B','$','U','S','E','R', - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 11, 13, 'R','D','B','$','U','S','E','R','_','T','Y','P','E', - blr_literal, blr_long, 0, 8,0,0,0, - blr_and, - blr_neq, - blr_field, 11, 16, 'R','D','B','$','G','R','A','N','T','_','O','P','T','I','O','N', - blr_literal, blr_long, 0, 0,0,0,0, - blr_or, - blr_missing, - blr_field, 11, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_eql, - blr_field, 11, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 8, 14, 'R','D','B','$','B','A','S','E','_','F','I','E','L','D', - blr_end, - blr_leave, 5, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_begin, - blr_for, - blr_rse, 2, - blr_relation, 18, 'R','D','B','$','V','I','E','W','_','R','E','L','A','T','I','O','N','S', 12, - blr_relation, 13, 'R','D','B','$','R','E','L','A','T','I','O','N','S', 13, - blr_boolean, - blr_and, - blr_eql, - blr_field, 12, 13, 'R','D','B','$','V','I','E','W','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 12, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 13, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_and, - blr_neq, - blr_field, 13, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_neq, - blr_sys_function, 20, 'R','D','B','$','S','Y','S','T','E','M','_','P','R','I','V','I','L','E','G','E',1, - blr_literal, blr_short, 0, 21,0, - blr_literal, blr_bool, 1, - blr_begin, - blr_if, - blr_not, - blr_any, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','U','S','E','R','_','P','R','I','V','I','L','E','G','E','S', 14, - blr_boolean, - blr_and, - blr_eql, - blr_field, 14, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 13, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 14, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 0,0,0,0, - blr_and, - blr_eql, - blr_field, 14, 13, 'R','D','B','$','P','R','I','V','I','L','E','G','E', - blr_field, 1, 13, 'R','D','B','$','P','R','I','V','I','L','E','G','E', - blr_and, - blr_eql, - blr_field, 14, 8, 'R','D','B','$','U','S','E','R', - blr_field, 6, 14, 'R','D','B','$','O','W','N','E','R','_','N','A','M','E', - blr_and, - blr_eql, - blr_field, 14, 13, 'R','D','B','$','U','S','E','R','_','T','Y','P','E', - blr_literal, blr_long, 0, 8,0,0,0, - blr_and, - blr_neq, - blr_field, 14, 16, 'R','D','B','$','G','R','A','N','T','_','O','P','T','I','O','N', - blr_literal, blr_long, 0, 0,0,0,0, - blr_missing, - blr_field, 14, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_leave, 5, - blr_end, - blr_end, - blr_end, - blr_end, - blr_end, - blr_if, - blr_missing, - blr_field, 6, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_modify, 6, 15, - blr_begin, - blr_assignment, - blr_cast, blr_varying2, 4,0, 252,0, - blr_concatenate, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_gen_id, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_long, 0, 1,0,0,0, - blr_field, 15, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_if, - blr_not, - blr_starting, - blr_field, 6, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_cast, blr_varying2, 4,0, 252,0, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_leave, 3, - blr_end, - blr_end, - blr_if, - blr_not, - blr_missing, - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_for, - blr_rse, 1, - blr_relation, 19, 'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 16, - blr_boolean, - blr_and, - blr_eql, - blr_field, 16, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_eql, - blr_field, 16, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_field, 1, 14, 'R','D','B','$','F','I','E','L','D','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_missing, - blr_field, 16, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_modify, 16, 17, - blr_begin, - blr_assignment, - blr_concatenate, - blr_literal, blr_text, 9,0, 'S','Q','L','$','G','R','A','N','T', - blr_gen_id, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_long, 0, 1,0,0,0, - blr_field, 17, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_if, - blr_not, - blr_starting, - blr_field, 16, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_text, 9,0, 'S','Q','L','$','G','R','A','N','T', - blr_leave, 4, - blr_end, - blr_end, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 1, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 5,0,0,0, - blr_for, - blr_rse, 1, - blr_relation, 14, 'R','D','B','$','P','R','O','C','E','D','U','R','E','S', 18, - blr_boolean, - blr_and, - blr_missing, - blr_field, 18, 16, 'R','D','B','$','P','A','C','K','A','G','E','_','N','A','M','E', - blr_eql, - blr_field, 18, 18, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_missing, - blr_field, 18, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_modify, 18, 20, - blr_begin, - blr_assignment, - blr_cast, blr_varying2, 4,0, 252,0, - blr_concatenate, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_gen_id, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_long, 0, 1,0,0,0, - blr_field, 20, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_if, - blr_not, - blr_starting, - blr_field, 18, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_cast, blr_varying2, 4,0, 252,0, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_leave, 3, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 1, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 15,0,0,0, - blr_for, - blr_rse, 1, - blr_relation, 13, 'R','D','B','$','F','U','N','C','T','I','O','N','S', 26, - blr_boolean, - blr_and, - blr_missing, - blr_field, 26, 16, 'R','D','B','$','P','A','C','K','A','G','E','_','N','A','M','E', - blr_eql, - blr_field, 26, 17, 'R','D','B','$','F','U','N','C','T','I','O','N','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_missing, - blr_field, 26, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_modify, 26, 28, - blr_begin, - blr_assignment, - blr_cast, blr_varying2, 4,0, 252,0, - blr_concatenate, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_gen_id, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_long, 0, 1,0,0,0, - blr_field, 28, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_if, - blr_not, - blr_starting, - blr_field, 26, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_cast, blr_varying2, 4,0, 252,0, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_leave, 3, - blr_end, - blr_end, - blr_if, - blr_eql, - blr_field, 1, 15, 'R','D','B','$','O','B','J','E','C','T','_','T','Y','P','E', - blr_literal, blr_long, 0, 18,0,0,0, - blr_for, - blr_rse, 1, - blr_relation, 12, 'R','D','B','$','P','A','C','K','A','G','E','S', 22, - blr_boolean, - blr_eql, - blr_field, 22, 16, 'R','D','B','$','P','A','C','K','A','G','E','_','N','A','M','E', - blr_field, 1, 17, 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E', - blr_end, - blr_begin, - blr_if, - blr_missing, - blr_field, 22, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_modify, 22, 23, - blr_begin, - blr_assignment, - blr_cast, blr_varying2, 4,0, 252,0, - blr_concatenate, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_gen_id, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_literal, blr_long, 0, 1,0,0,0, - blr_field, 23, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_end, - blr_if, - blr_not, - blr_starting, - blr_field, 22, 18, 'R','D','B','$','S','E','C','U','R','I','T','Y','_','C','L','A','S','S', - blr_cast, blr_varying2, 4,0, 252,0, - blr_literal, blr_text2, 1,0, 4,0, 'S','Q','L','$', - blr_leave, 3, - blr_end, - blr_end, - blr_end, - blr_end, - blr_eoc -}; - - #endif /* JRD_TRIG_H */