Skip to content

Commit e493545

Browse files
author
Venkatesh Duggirala
committed
Bug#24397517 ADD CASCADE FOREIGN KEY INFORMATION TO
TRANS_TABLE_INFO STRUTURE Group replication plugin requires the information from the server whether a table has 'foreign key' with 'CASCADE' clause or not. Trans_table_info is the structure that is communicated between server and GR plugin. Adding this cascade foreign key information to Trans_table_info_struture which will be used by GR plugin code.
1 parent 788525c commit e493545

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

sql/replication.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ typedef struct Trans_table_info {
5151
uint number_of_primary_keys;
5252
/// The db_type of the storage engine used by the table
5353
int db_type;
54+
/// information to store if the table has foreign key with 'CASCADE' clause.
55+
bool has_cascade_foreign_key;
5456
} Trans_table_info;
5557

5658
/**

sql/rpl_handler.cc

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,44 @@ int Trans_delegate::before_commit(THD *thd, bool all,
326326
DBUG_RETURN(ret);
327327
}
328328

329+
/**
330+
Helper method to check if the given table has 'CASCADE' foreign key or not.
331+
332+
@param[in] TABLE Table object that needs to be verified.
333+
@param[in] THD Current execution thread.
334+
335+
@return bool TRUE If the table has 'CASCADE' foreign key.
336+
FALSE If the table does not have 'CASCADE' foreign key.
337+
*/
338+
bool has_cascade_foreign_key(TABLE *table, THD *thd)
339+
{
340+
DBUG_ENTER("has_cascade_foreign_key");
341+
List<FOREIGN_KEY_INFO> f_key_list;
342+
table->file->get_foreign_key_list(thd, &f_key_list);
343+
344+
FOREIGN_KEY_INFO *f_key_info;
345+
List_iterator_fast<FOREIGN_KEY_INFO> foreign_key_iterator(f_key_list);
346+
while ((f_key_info=foreign_key_iterator++))
347+
{
348+
/*
349+
The possible values for update_method are
350+
{"CASCADE", "SET NULL", "NO ACTION", "RESTRICT"}.
351+
352+
Hence we are avoiding the usage of strncmp
353+
("'update_method' value with 'CASCADE'") and just comparing
354+
the first character of the update_method value with 'C'.
355+
*/
356+
if (f_key_info->update_method->str[0] == 'C' ||
357+
f_key_info->delete_method->str[0] == 'C')
358+
{
359+
DBUG_ASSERT(!strncmp(f_key_info->update_method->str, "CASCADE", 7) ||
360+
!strncmp(f_key_info->delete_method->str, "CASCADE", 7));
361+
DBUG_RETURN(TRUE);
362+
}
363+
}
364+
DBUG_RETURN(FALSE);
365+
}
366+
329367
/**
330368
Helper method to create table information for the hook call
331369
*/
@@ -348,7 +386,7 @@ Trans_delegate::prepare_table_info(THD* thd,
348386
std::vector<Trans_table_info> table_info_holder;
349387
for(; open_tables != NULL; open_tables= open_tables->next)
350388
{
351-
Trans_table_info table_info = {0,0,0};
389+
Trans_table_info table_info = {0,0,0,0};
352390

353391
if (open_tables->no_replicate)
354392
{
@@ -373,6 +411,12 @@ Trans_delegate::prepare_table_info(THD* thd,
373411

374412
table_info.db_type= open_tables->s->db_type()->db_type;
375413

414+
/*
415+
Find out if the table has foreign key with ON UPDATE/DELETE CASCADE
416+
clause.
417+
*/
418+
table_info.has_cascade_foreign_key= has_cascade_foreign_key(open_tables, thd);
419+
376420
table_info_holder.push_back(table_info);
377421
}
378422

@@ -399,6 +443,8 @@ Trans_delegate::prepare_table_info(THD* thd,
399443
= (*table_info_holder_it).table_name;
400444
table_info_list[table].db_type
401445
= (*table_info_holder_it).db_type;
446+
table_info_list[table].has_cascade_foreign_key
447+
= (*table_info_holder_it).has_cascade_foreign_key;
402448
}
403449
}
404450

0 commit comments

Comments
 (0)