Skip to content

Commit cf67735

Browse files
committed
Merge pull request #8600 from FirebirdSQL/work/gh-8598-ri-triggs
Implement #8598 : Don't fire referential integrity triggers if primary or unique keys haven't changed
1 parent e11f62c commit cf67735

File tree

5 files changed

+29
-12
lines changed

5 files changed

+29
-12
lines changed

src/jrd/exe.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,17 @@ void EXE_execute_triggers(thread_db* tdbb,
11341134
{
11351135
for (TrigVector::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
11361136
{
1137+
// The system trigger that implement cascading action can be skipped if
1138+
// no PK/UK field have been changed by UPDATE.
1139+
1140+
if ((which_trig == StmtNode::POST_TRIG) && (trigger_action == TRIGGER_UPDATE) &&
1141+
(ptr->sysTrigger == fb_sysflag_referential_constraint))
1142+
{
1143+
fb_assert(new_rpb);
1144+
if (!(new_rpb->rpb_runtime_flags & RPB_uk_updated))
1145+
continue;
1146+
}
1147+
11371148
if (trigger_action == TRIGGER_DDL && ddl_action)
11381149
{
11391150
// Skip triggers not matching our action

src/jrd/idx.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,8 @@ void IDX_modify(thread_db* tdbb,
862862
RelationPages* relPages = org_rpb->rpb_relation->getPages(tdbb);
863863
WIN window(relPages->rel_pg_space_id, -1);
864864

865+
new_rpb->rpb_runtime_flags &= ~RPB_uk_updated;
866+
865867
while (BTR_next_index(tdbb, org_rpb->rpb_relation, transaction, &idx, &window))
866868
{
867869
IndexErrorContext context(new_rpb->rpb_relation, &idx);
@@ -891,6 +893,9 @@ void IDX_modify(thread_db* tdbb,
891893
context.raise(tdbb, error_code, new_rpb->rpb_record);
892894
}
893895
}
896+
897+
if (idx.idx_flags & (idx_primary | idx_unique))
898+
new_rpb->rpb_runtime_flags |= RPB_uk_updated;
894899
}
895900
}
896901

src/jrd/jrd.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,17 @@ class Trigger
138138
Firebird::HalfStaticArray<UCHAR, 128> debugInfo; // Debug info
139139
JrdStatement* statement; // Compiled statement
140140
bool releaseInProgress;
141-
bool sysTrigger;
141+
SSHORT sysTrigger; // See fb_sysflag in constants.h
142142
FB_UINT64 type; // Trigger type
143143
USHORT flags; // Flags as they are in RDB$TRIGGERS table
144144
jrd_rel* relation; // Trigger parent relation
145-
MetaName name; // Trigger name
146-
MetaName engine; // External engine name
145+
MetaName name; // Trigger name
146+
MetaName engine; // External engine name
147147
Firebird::string entryPoint; // External trigger entrypoint
148148
Firebird::string extBody; // External trigger body
149149
ExtEngineManager::Trigger* extTrigger; // External trigger
150150
Nullable<bool> ssDefiner;
151-
MetaName owner; // Owner for SQL SECURITY
151+
MetaName owner; // Owner for SQL SECURITY
152152

153153
bool isActive() const;
154154

src/jrd/met.epp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ static int blocking_ast_relation(void*);
114114
static int partners_ast_relation(void*);
115115
static int rescan_ast_relation(void*);
116116
static ULONG get_rel_flags_from_FLAGS(USHORT);
117-
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, bool,
117+
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, SSHORT,
118118
USHORT, const MetaName&, const string&, const bid*, Nullable<bool> ssDefiner);
119119
static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*);
120120
static void lookup_view_contexts(thread_db*, jrd_rel*);
@@ -123,7 +123,7 @@ static ValueExprNode* parse_field_default_blr(thread_db* tdbb, bid* blob_id);
123123
static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const MetaName name);
124124
static bool resolve_charset_and_collation(thread_db*, USHORT*, const UCHAR*, const UCHAR*);
125125
static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, JrdStatement*, blb*, blb*,
126-
const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&,
126+
const TEXT*, FB_UINT64, SSHORT, USHORT, const MetaName&, const string&,
127127
const bid*, Nullable<bool> ssDefiner);
128128
static void scan_partners(thread_db*, jrd_rel*);
129129
static void store_dependencies(thread_db*, CompilerScratch*, const jrd_rel*,
@@ -2044,7 +2044,7 @@ void MET_load_trigger(thread_db* tdbb,
20442044
triggers,
20452045
TRG.RDB$TRIGGER_NAME,
20462046
TRG.RDB$TRIGGER_TYPE & ~TRIGGER_TYPE_MASK,
2047-
(bool) TRG.RDB$SYSTEM_FLAG,
2047+
TRG.RDB$SYSTEM_FLAG,
20482048
trig_flags,
20492049
engine,
20502050
entryPoint,
@@ -2065,7 +2065,7 @@ void MET_load_trigger(thread_db* tdbb,
20652065
triggers + trigger_action,
20662066
TRG.RDB$TRIGGER_NAME,
20672067
(UCHAR) trigger_action,
2068-
(bool) TRG.RDB$SYSTEM_FLAG,
2068+
TRG.RDB$SYSTEM_FLAG,
20692069
trig_flags,
20702070
engine,
20712071
entryPoint,
@@ -3251,7 +3251,7 @@ void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation)
32513251
if (trig_flags & TRG_ignore_perm)
32523252
statement->flags |= JrdStatement::FLAG_IGNORE_PERM;
32533253

3254-
save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, true, 0, "",
3254+
save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, TRG.RDB$SYSTEM_FLAG, 0, "",
32553255
"", NULL, Nullable<bool>());
32563256
}
32573257
}
@@ -4601,7 +4601,7 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type)
46014601
static void get_trigger(thread_db* tdbb, jrd_rel* relation,
46024602
bid* blob_id, bid* debug_blob_id, TrigVector** ptr,
46034603
const TEXT* name, FB_UINT64 type,
4604-
bool sys_trigger, USHORT flags,
4604+
SSHORT sys_trigger, USHORT flags,
46054605
const MetaName& engine, const string& entryPoint,
46064606
const bid* body, Nullable<bool> ssDefiner)
46074607
{
@@ -4983,7 +4983,7 @@ static bool resolve_charset_and_collation(thread_db* tdbb,
49834983
static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relation,
49844984
JrdStatement* statement, blb* blrBlob, blb* debugInfoBlob,
49854985
const TEXT* name, FB_UINT64 type,
4986-
bool sys_trigger, USHORT flags,
4986+
SSHORT sys_trigger, USHORT flags,
49874987
const MetaName& engine, const string& entryPoint,
49884988
const bid* body, Nullable<bool> ssDefiner)
49894989
{

src/jrd/req.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ const USHORT RPB_undo_data = 0x02; // data got from undo log
133133
const USHORT RPB_undo_read = 0x04; // read was performed using the undo log
134134
const USHORT RPB_undo_deleted = 0x08; // read was performed using the undo log, primary version is deleted
135135
const USHORT RPB_just_deleted = 0x10; // record was just deleted by us
136+
const USHORT RPB_uk_updated = 0x20; // set by IDX_modify if it insert key into any primary or unique index
136137

137138
const USHORT RPB_UNDO_FLAGS = (RPB_undo_data | RPB_undo_read | RPB_undo_deleted);
138-
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted);
139+
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted | RPB_uk_updated);
139140

140141
const unsigned int MAX_DIFFERENCES = 1024; // Max length of generated Differences string
141142
// between two records

0 commit comments

Comments
 (0)