mysql5/mysql-5.7.27/sql/transaction_info.cc

122 lines
4.1 KiB
C++

/*
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
#include "transaction_info.h"
#include "mysys_err.h"
#include "sql_class.h"
Transaction_ctx::Transaction_ctx()
: m_savepoints(NULL), m_xid_state(), m_changed_tables(NULL),
last_committed(0), sequence_number(0),
m_rpl_transaction_ctx(), m_transaction_write_set_ctx()
{
memset(&m_scope_info, 0, sizeof(m_scope_info));
memset(&m_flags, 0, sizeof(m_flags));
init_sql_alloc(key_memory_thd_transactions, &m_mem_root,
global_system_variables.trans_alloc_block_size,
global_system_variables.trans_prealloc_size);
}
void Transaction_ctx::push_unsafe_rollback_warnings(THD *thd)
{
if (m_scope_info[SESSION].has_modified_non_trans_table())
push_warning(thd, Sql_condition::SL_WARNING,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
if (m_scope_info[SESSION].has_created_temp_table())
push_warning(thd, Sql_condition::SL_WARNING,
ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE));
if (m_scope_info[SESSION].has_dropped_temp_table())
push_warning(thd, Sql_condition::SL_WARNING,
ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE));
}
bool Transaction_ctx::add_changed_table(const char *key, long key_length)
{
DBUG_ENTER("Transaction_ctx::add_changed_table");
CHANGED_TABLE_LIST **prev_changed = &m_changed_tables;
CHANGED_TABLE_LIST *curr = m_changed_tables;
for (; curr; prev_changed = &(curr->next), curr = curr->next)
{
int cmp = (long)curr->key_length - key_length;
if (cmp < 0)
{
if (list_include(prev_changed, curr,
changed_table_dup(key, key_length)))
DBUG_RETURN(true);
DBUG_PRINT("info",
("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_RETURN(false);
}
else if (cmp == 0)
{
cmp = memcmp(curr->key, key, curr->key_length);
if (cmp < 0)
{
if (list_include(prev_changed, curr, changed_table_dup(key, key_length)))
DBUG_RETURN(true);
DBUG_PRINT("info",
("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_RETURN(false);
}
else if (cmp == 0)
{
DBUG_PRINT("info", ("already in list"));
DBUG_RETURN(false);
DBUG_RETURN(false);
}
}
}
*prev_changed = changed_table_dup(key, key_length);
if (!(*prev_changed))
DBUG_RETURN(true);
DBUG_PRINT("info", ("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_RETURN(false);
}
CHANGED_TABLE_LIST* Transaction_ctx::changed_table_dup(const char *key,
long key_length)
{
CHANGED_TABLE_LIST* new_table =
(CHANGED_TABLE_LIST*) allocate_memory(
ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST)) + key_length + 1);
if (!new_table)
{
my_error(EE_OUTOFMEMORY, MYF(ME_FATALERROR),
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
return 0;
}
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
new_table->next = 0;
new_table->key_length = key_length;
::memcpy(new_table->key, key, key_length);
return new_table;
}