Skip to content

Commit 449449c

Browse files
authored
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
2 parents b8e226a + 2fef99a commit 449449c

File tree

5 files changed

+30
-13
lines changed

5 files changed

+30
-13
lines changed

src/jrd/exe.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,17 @@ void EXE_execute_triggers(thread_db* tdbb,
11571157
{
11581158
for (TrigVector::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
11591159
{
1160+
// The system trigger that implement cascading action can be skipped if
1161+
// no PK/UK field have been changed by UPDATE.
1162+
1163+
if ((which_trig == StmtNode::POST_TRIG) && (trigger_action == TRIGGER_UPDATE) &&
1164+
(ptr->sysTrigger == fb_sysflag_referential_constraint))
1165+
{
1166+
fb_assert(new_rpb);
1167+
if (!(new_rpb->rpb_runtime_flags & RPB_uk_updated))
1168+
continue;
1169+
}
1170+
11601171
if (trigger_action == TRIGGER_DDL && ddl_action)
11611172
{
11621173
// Skip triggers not matching our action

src/jrd/idx.cpp

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

1286+
new_rpb->rpb_runtime_flags &= ~RPB_uk_updated;
1287+
12861288
while (BTR_next_index(tdbb, org_rpb->rpb_relation, transaction, &idx, &window))
12871289
{
12881290
IndexErrorContext context(new_rpb->rpb_relation, &idx);
@@ -1346,6 +1348,9 @@ void IDX_modify(thread_db* tdbb,
13461348
{
13471349
context.raise(tdbb, error_code, new_rpb->rpb_record);
13481350
}
1351+
1352+
if (idx.idx_flags & (idx_primary | idx_unique))
1353+
new_rpb->rpb_runtime_flags |= RPB_uk_updated;
13491354
}
13501355
}
13511356

src/jrd/jrd.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,19 @@ class Trigger
137137
public:
138138
Firebird::HalfStaticArray<UCHAR, 128> blr; // BLR code
139139
Firebird::HalfStaticArray<UCHAR, 128> debugInfo; // Debug info
140-
Statement* statement; // Compiled statement
140+
Statement* statement; // Compiled statement
141141
bool releaseInProgress;
142-
bool sysTrigger;
142+
SSHORT sysTrigger; // See fb_sysflag in constants.h
143143
FB_UINT64 type; // Trigger type
144144
USHORT flags; // Flags as they are in RDB$TRIGGERS table
145145
jrd_rel* relation; // Trigger parent relation
146-
MetaName name; // Trigger name
147-
MetaName engine; // External engine name
146+
MetaName name; // Trigger name
147+
MetaName engine; // External engine name
148148
Firebird::string entryPoint; // External trigger entrypoint
149149
Firebird::string extBody; // External trigger body
150150
ExtEngineManager::Trigger* extTrigger; // External trigger
151151
Nullable<bool> ssDefiner;
152-
MetaName owner; // Owner for SQL SECURITY
152+
MetaName owner; // Owner for SQL SECURITY
153153

154154
bool isActive() const;
155155

src/jrd/met.epp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static int blocking_ast_relation(void*);
115115
static int partners_ast_relation(void*);
116116
static int rescan_ast_relation(void*);
117117
static ULONG get_rel_flags_from_FLAGS(USHORT);
118-
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, bool,
118+
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, SSHORT,
119119
USHORT, const MetaName&, const string&, const bid*, Nullable<bool> ssDefiner);
120120
static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*);
121121
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);
124124
static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const MetaName name);
125125
static bool resolve_charset_and_collation(thread_db*, USHORT*, const UCHAR*, const UCHAR*);
126126
static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, Statement*, blb*, blb*,
127-
const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&,
127+
const TEXT*, FB_UINT64, SSHORT, USHORT, const MetaName&, const string&,
128128
const bid*, Nullable<bool> ssDefiner);
129129
static void scan_partners(thread_db*, jrd_rel*);
130130
static bool verify_TRG_ignore_perm(thread_db*, const MetaName&);
@@ -2049,7 +2049,7 @@ void MET_load_trigger(thread_db* tdbb,
20492049
triggers,
20502050
TRG.RDB$TRIGGER_NAME,
20512051
TRG.RDB$TRIGGER_TYPE,
2052-
(bool) TRG.RDB$SYSTEM_FLAG,
2052+
TRG.RDB$SYSTEM_FLAG,
20532053
trig_flags,
20542054
engine,
20552055
entryPoint,
@@ -2070,7 +2070,7 @@ void MET_load_trigger(thread_db* tdbb,
20702070
triggers + trigger_action,
20712071
TRG.RDB$TRIGGER_NAME,
20722072
(UCHAR) trigger_action,
2073-
(bool) TRG.RDB$SYSTEM_FLAG,
2073+
TRG.RDB$SYSTEM_FLAG,
20742074
trig_flags,
20752075
engine,
20762076
entryPoint,
@@ -3382,7 +3382,7 @@ void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation)
33823382
if (trig_flags & TRG_ignore_perm)
33833383
statement->flags |= Statement::FLAG_IGNORE_PERM;
33843384

3385-
save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, true, 0, "",
3385+
save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, TRG.RDB$SYSTEM_FLAG, 0, "",
33863386
"", NULL, Nullable<bool>());
33873387
}
33883388
}
@@ -4744,7 +4744,7 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type)
47444744
static void get_trigger(thread_db* tdbb, jrd_rel* relation,
47454745
bid* blob_id, bid* debug_blob_id, TrigVector** ptr,
47464746
const TEXT* name, FB_UINT64 type,
4747-
bool sys_trigger, USHORT flags,
4747+
SSHORT sys_trigger, USHORT flags,
47484748
const MetaName& engine, const string& entryPoint,
47494749
const bid* body, Nullable<bool> ssDefiner)
47504750
{
@@ -5126,7 +5126,7 @@ static bool resolve_charset_and_collation(thread_db* tdbb,
51265126
static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relation,
51275127
Statement* statement, blb* blrBlob, blb* debugInfoBlob,
51285128
const TEXT* name, FB_UINT64 type,
5129-
bool sys_trigger, USHORT flags,
5129+
SSHORT sys_trigger, USHORT flags,
51305130
const MetaName& engine, const string& entryPoint,
51315131
const bid* body, Nullable<bool> ssDefiner)
51325132
{

src/jrd/req.h

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

140141
const USHORT RPB_UNDO_FLAGS = (RPB_undo_data | RPB_undo_read | RPB_undo_deleted);
141-
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted);
142+
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted | RPB_uk_updated);
142143

143144
// List of active blobs controlled by request
144145

0 commit comments

Comments
 (0)