Skip to content

Commit f6a3e4c

Browse files
committed
Front-ported pull request #8600
Implement #8598 : Don't fire referential integrity triggers if primary or unique keys haven't changed
1 parent 45be57b commit f6a3e4c

File tree

5 files changed

+26
-9
lines changed

5 files changed

+26
-9
lines changed

src/jrd/exe.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,17 @@ void EXE_execute_triggers(thread_db* tdbb,
14191419
{
14201420
for (TrigVector::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
14211421
{
1422+
// The system trigger that implement cascading action can be skipped if
1423+
// no PK/UK field have been changed by UPDATE.
1424+
1425+
if ((which_trig == StmtNode::POST_TRIG) && (trigger_action == TRIGGER_UPDATE) &&
1426+
(ptr->sysTrigger == fb_sysflag_referential_constraint))
1427+
{
1428+
fb_assert(new_rpb);
1429+
if (!(new_rpb->rpb_runtime_flags & RPB_uk_updated))
1430+
continue;
1431+
}
1432+
14221433
if (trigger_action == TRIGGER_DDL && ddl_action)
14231434
{
14241435
// Skip triggers not matching our action

src/jrd/idx.cpp

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

1290+
new_rpb->rpb_runtime_flags &= ~RPB_uk_updated;
1291+
12901292
while (BTR_next_index(tdbb, org_rpb->rpb_relation, transaction, &idx, &window))
12911293
{
12921294
IndexErrorContext context(new_rpb->rpb_relation, &idx);
@@ -1350,6 +1352,9 @@ void IDX_modify(thread_db* tdbb,
13501352
{
13511353
context.raise(tdbb, error_code, new_rpb->rpb_record);
13521354
}
1355+
1356+
if (idx.idx_flags & (idx_primary | idx_unique))
1357+
new_rpb->rpb_runtime_flags |= RPB_uk_updated;
13531358
}
13541359
}
13551360

src/jrd/jrd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ class Trigger
144144
Firebird::HalfStaticArray<UCHAR, 128> debugInfo; // Debug info
145145
Statement* statement = nullptr; // Compiled statement
146146
bool releaseInProgress = false;
147-
bool sysTrigger = false;
147+
SSHORT sysTrigger = 0; // See fb_sysflag in constants.h
148148
FB_UINT64 type = 0; // Trigger type
149149
USHORT flags = 0; // Flags as they are in RDB$TRIGGERS table
150150
jrd_rel* relation = nullptr; // Trigger parent relation
151-
QualifiedName name; // Trigger name
151+
QualifiedName name; // Trigger name
152152
MetaName engine; // External engine name
153153
MetaName owner; // Owner for SQL SECURITY
154154
Firebird::string entryPoint; // External trigger entrypoint

src/jrd/met.epp

Lines changed: 6 additions & 6 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 QualifiedName&, FB_UINT64, bool,
117+
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const QualifiedName&, FB_UINT64, SSHORT,
118118
USHORT, const MetaName&, const string&, const bid*, TriState ssDefiner);
119119
static bool get_type(thread_db*, USHORT*, const MetaName&, 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, const MetaName& s
123123
static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const QualifiedName& name);
124124
static bool resolve_charset_and_collation(thread_db*, USHORT*, const QualifiedName&, const QualifiedName&);
125125
static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, Statement*, blb*, blb*,
126-
const QualifiedName*, FB_UINT64, bool, USHORT, const MetaName&, const string&,
126+
const QualifiedName*, FB_UINT64, SSHORT, USHORT, const MetaName&, const string&,
127127
const bid*, TriState ssDefiner);
128128
static void scan_partners(thread_db*, jrd_rel*);
129129
static bool verify_TRG_ignore_perm(thread_db*, const QualifiedName&);
@@ -1983,7 +1983,7 @@ void MET_load_trigger(thread_db* tdbb,
19831983
triggers,
19841984
trigger_name,
19851985
TRG.RDB$TRIGGER_TYPE,
1986-
(bool) TRG.RDB$SYSTEM_FLAG,
1986+
TRG.RDB$SYSTEM_FLAG,
19871987
trig_flags,
19881988
engine,
19891989
entryPoint,
@@ -2004,7 +2004,7 @@ void MET_load_trigger(thread_db* tdbb,
20042004
triggers + trigger_action,
20052005
trigger_name,
20062006
(UCHAR) trigger_action,
2007-
(bool) TRG.RDB$SYSTEM_FLAG,
2007+
TRG.RDB$SYSTEM_FLAG,
20082008
trig_flags,
20092009
engine,
20102010
entryPoint,
@@ -4612,7 +4612,7 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type)
46124612
static void get_trigger(thread_db* tdbb, jrd_rel* relation,
46134613
bid* blob_id, bid* debug_blob_id, TrigVector** ptr,
46144614
const QualifiedName& name, FB_UINT64 type,
4615-
bool sys_trigger, USHORT flags,
4615+
SSHORT sys_trigger, USHORT flags,
46164616
const MetaName& engine, const string& entryPoint,
46174617
const bid* body, TriState ssDefiner)
46184618
{
@@ -4993,7 +4993,7 @@ static bool resolve_charset_and_collation(thread_db* tdbb,
49934993
static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relation,
49944994
Statement* statement, blb* blrBlob, blb* debugInfoBlob,
49954995
const QualifiedName* name, FB_UINT64 type,
4996-
bool sys_trigger, USHORT flags,
4996+
SSHORT sys_trigger, USHORT flags,
49974997
const MetaName& engine, const string& entryPoint,
49984998
const bid* body, TriState ssDefiner)
49994999
{

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)