mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge 10.4 into 10.5
This commit is contained in:
122
sql/sql_base.cc
122
sql/sql_base.cc
@ -4591,7 +4591,72 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
Extend the table_list to include foreign tables for prelocking.
|
||||
|
||||
@param[in] thd Thread context.
|
||||
@param[in] prelocking_ctx Prelocking context of the statement.
|
||||
@param[in] table_list Table list element for table.
|
||||
@param[in] sp Routine body.
|
||||
@param[out] need_prelocking Set to TRUE if method detects that prelocking
|
||||
required, not changed otherwise.
|
||||
|
||||
@retval FALSE Success.
|
||||
@retval TRUE Failure (OOM).
|
||||
*/
|
||||
inline bool
|
||||
prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
TABLE_LIST *table_list, bool *need_prelocking,
|
||||
uint8 op)
|
||||
{
|
||||
DBUG_ENTER("prepare_fk_prelocking_list");
|
||||
List <FOREIGN_KEY_INFO> fk_list;
|
||||
List_iterator<FOREIGN_KEY_INFO> fk_list_it(fk_list);
|
||||
FOREIGN_KEY_INFO *fk;
|
||||
Query_arena *arena, backup;
|
||||
TABLE *table= table_list->table;
|
||||
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
|
||||
table->file->get_parent_foreign_key_list(thd, &fk_list);
|
||||
if (unlikely(thd->is_error()))
|
||||
{
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*need_prelocking= TRUE;
|
||||
|
||||
while ((fk= fk_list_it++))
|
||||
{
|
||||
// FK_OPTION_RESTRICT and FK_OPTION_NO_ACTION only need read access
|
||||
thr_lock_type lock_type;
|
||||
|
||||
if ((op & (1 << TRG_EVENT_DELETE) && fk_modifies_child(fk->delete_method))
|
||||
|| (op & (1 << TRG_EVENT_UPDATE) && fk_modifies_child(fk->update_method)))
|
||||
lock_type= TL_WRITE_ALLOW_WRITE;
|
||||
else
|
||||
lock_type= TL_READ;
|
||||
|
||||
if (table_already_fk_prelocked(prelocking_ctx->query_tables,
|
||||
fk->foreign_db, fk->foreign_table,
|
||||
lock_type))
|
||||
continue;
|
||||
|
||||
TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
|
||||
tl->init_one_table_for_prelocking(fk->foreign_db,
|
||||
fk->foreign_table,
|
||||
NULL, lock_type,
|
||||
TABLE_LIST::PRELOCK_FK,
|
||||
table_list->belong_to_view, op,
|
||||
&prelocking_ctx->query_tables_last,
|
||||
table_list->for_insert_data);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
Defines how prelocking algorithm for DML statements should handle table list
|
||||
@ -4638,53 +4703,20 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
|
||||
if (table->file->referenced_by_foreign_key())
|
||||
{
|
||||
List <FOREIGN_KEY_INFO> fk_list;
|
||||
List_iterator<FOREIGN_KEY_INFO> fk_list_it(fk_list);
|
||||
FOREIGN_KEY_INFO *fk;
|
||||
Query_arena *arena, backup;
|
||||
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
|
||||
table->file->get_parent_foreign_key_list(thd, &fk_list);
|
||||
if (unlikely(thd->is_error()))
|
||||
{
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
*need_prelocking= TRUE;
|
||||
|
||||
while ((fk= fk_list_it++))
|
||||
{
|
||||
// FK_OPTION_RESTRICT and FK_OPTION_NO_ACTION only need read access
|
||||
uint8 op= table_list->trg_event_map;
|
||||
thr_lock_type lock_type;
|
||||
|
||||
if ((op & (1 << TRG_EVENT_DELETE) && fk_modifies_child(fk->delete_method))
|
||||
|| (op & (1 << TRG_EVENT_UPDATE) && fk_modifies_child(fk->update_method)))
|
||||
lock_type= TL_WRITE_ALLOW_WRITE;
|
||||
else
|
||||
lock_type= TL_READ;
|
||||
|
||||
if (table_already_fk_prelocked(prelocking_ctx->query_tables,
|
||||
fk->foreign_db, fk->foreign_table,
|
||||
lock_type))
|
||||
continue;
|
||||
|
||||
TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
|
||||
tl->init_one_table_for_prelocking(fk->foreign_db,
|
||||
fk->foreign_table,
|
||||
NULL, lock_type,
|
||||
TABLE_LIST::PRELOCK_FK,
|
||||
table_list->belong_to_view, op,
|
||||
&prelocking_ctx->query_tables_last,
|
||||
table_list->for_insert_data);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list,
|
||||
need_prelocking,
|
||||
table_list->trg_event_map))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (table_list->slave_fk_event_map &&
|
||||
table->file->referenced_by_foreign_key())
|
||||
{
|
||||
if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list,
|
||||
need_prelocking,
|
||||
table_list->slave_fk_event_map))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Open any tables used by DEFAULT (like sequence tables) */
|
||||
DBUG_PRINT("info", ("table: %p name: %s db: %s flags: %u",
|
||||
|
Reference in New Issue
Block a user