Skip to content

Implement #8598 : Don't fire referential integrity triggers if primary or unique keys haven't changed #8600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: v5.0-release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/jrd/exe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,17 @@ void EXE_execute_triggers(thread_db* tdbb,
{
for (TrigVector::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
{
// The system trigger that implement cascading action can be skipped if
// no PK/UK field have been changed by UPDATE.

if ((which_trig == StmtNode::POST_TRIG) && (trigger_action == TRIGGER_UPDATE) &&
(ptr->sysTrigger == fb_sysflag_referential_constraint))
{
fb_assert(new_rpb);
if (!(new_rpb->rpb_runtime_flags & RPB_uk_updated))
continue;
}

if (trigger_action == TRIGGER_DDL && ddl_action)
{
// Skip triggers not matching our action
Expand Down
5 changes: 5 additions & 0 deletions src/jrd/idx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,8 @@ void IDX_modify(thread_db* tdbb,
RelationPages* relPages = org_rpb->rpb_relation->getPages(tdbb);
WIN window(relPages->rel_pg_space_id, -1);

new_rpb->rpb_runtime_flags &= ~RPB_uk_updated;

while (BTR_next_index(tdbb, org_rpb->rpb_relation, transaction, &idx, &window))
{
IndexErrorContext context(new_rpb->rpb_relation, &idx);
Expand Down Expand Up @@ -1346,6 +1348,9 @@ void IDX_modify(thread_db* tdbb,
{
context.raise(tdbb, error_code, new_rpb->rpb_record);
}

if (idx.idx_flags & (idx_primary | idx_unique))
new_rpb->rpb_runtime_flags |= RPB_uk_updated;
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/jrd/jrd.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,19 @@ class Trigger
public:
Firebird::HalfStaticArray<UCHAR, 128> blr; // BLR code
Firebird::HalfStaticArray<UCHAR, 128> debugInfo; // Debug info
Statement* statement; // Compiled statement
Statement* statement; // Compiled statement
bool releaseInProgress;
bool sysTrigger;
SSHORT sysTrigger; // See fb_sysflag in constants.h
FB_UINT64 type; // Trigger type
USHORT flags; // Flags as they are in RDB$TRIGGERS table
jrd_rel* relation; // Trigger parent relation
MetaName name; // Trigger name
MetaName engine; // External engine name
MetaName name; // Trigger name
MetaName engine; // External engine name
Firebird::string entryPoint; // External trigger entrypoint
Firebird::string extBody; // External trigger body
ExtEngineManager::Trigger* extTrigger; // External trigger
Nullable<bool> ssDefiner;
MetaName owner; // Owner for SQL SECURITY
MetaName owner; // Owner for SQL SECURITY

bool isActive() const;

Expand Down
14 changes: 7 additions & 7 deletions src/jrd/met.epp
Original file line number Diff line number Diff line change
Expand Up @@ -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, SSHORT,
USHORT, const MetaName&, const string&, const bid*, Nullable<bool> ssDefiner);
static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*);
static void lookup_view_contexts(thread_db*, jrd_rel*);
Expand All @@ -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, SSHORT, USHORT, const MetaName&, const string&,
const bid*, Nullable<bool> ssDefiner);
static void scan_partners(thread_db*, jrd_rel*);
static bool verify_TRG_ignore_perm(thread_db*, const MetaName&);
Expand Down Expand Up @@ -2049,7 +2049,7 @@ void MET_load_trigger(thread_db* tdbb,
triggers,
TRG.RDB$TRIGGER_NAME,
TRG.RDB$TRIGGER_TYPE,
(bool) TRG.RDB$SYSTEM_FLAG,
TRG.RDB$SYSTEM_FLAG,
trig_flags,
engine,
entryPoint,
Expand All @@ -2070,7 +2070,7 @@ void MET_load_trigger(thread_db* tdbb,
triggers + trigger_action,
TRG.RDB$TRIGGER_NAME,
(UCHAR) trigger_action,
(bool) TRG.RDB$SYSTEM_FLAG,
TRG.RDB$SYSTEM_FLAG,
trig_flags,
engine,
entryPoint,
Expand Down Expand Up @@ -3382,7 +3382,7 @@ void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation)
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, "",
save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, TRG.RDB$SYSTEM_FLAG, 0, "",
"", NULL, Nullable<bool>());
}
}
Expand Down Expand Up @@ -4744,7 +4744,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,
SSHORT sys_trigger, USHORT flags,
const MetaName& engine, const string& entryPoint,
const bid* body, Nullable<bool> ssDefiner)
{
Expand Down Expand Up @@ -5126,7 +5126,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,
SSHORT sys_trigger, USHORT flags,
const MetaName& engine, const string& entryPoint,
const bid* body, Nullable<bool> ssDefiner)
{
Expand Down
1 change: 1 addition & 0 deletions src/jrd/req.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ const USHORT RPB_undo_data = 0x02; // data got from undo log
const USHORT RPB_undo_read = 0x04; // read was performed using the undo log
const USHORT RPB_undo_deleted = 0x08; // read was performed using the undo log, primary version is deleted
const USHORT RPB_just_deleted = 0x10; // record was just deleted by us
const USHORT RPB_uk_updated = 0x20; // set by IDX_modify if it insert key into any primary or unique index

const USHORT RPB_UNDO_FLAGS = (RPB_undo_data | RPB_undo_read | RPB_undo_deleted);
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted);
Expand Down
Loading