mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.1-new-rpl
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.1-merge client/mysqlbinlog.cc: Auto merged mysql-test/extra/binlog_tests/binlog.test: Auto merged mysql-test/r/binlog_row_binlog.result: Auto merged mysql-test/r/binlog_stm_binlog.result: Auto merged mysql-test/t/disabled.def: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/lock.cc: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_select.cc: Auto merged sql/table.h: Auto merged mysql-test/r/rpl_ndb_log.result: Manual merge main->rpl 5.1 mysql-test/r/rpl_truncate_7ndb.result: Manual merge main->rpl 5.1 sql/log.cc: Manual merge main->rpl 5.1 sql/log_event.cc: Manual merge main->rpl 5.1
This commit is contained in:
122
sql/sql_class.cc
122
sql/sql_class.cc
@@ -679,11 +679,22 @@ bool THD::store_globals()
|
||||
|
||||
void THD::cleanup_after_query()
|
||||
{
|
||||
/*
|
||||
Reset rand_used so that detection of calls to rand() will save random
|
||||
seeds if needed by the slave.
|
||||
|
||||
Do not reset rand_used if inside a stored function or trigger because
|
||||
only the call to these operations is logged. Thus only the calling
|
||||
statement needs to detect rand() calls made by its substatements. These
|
||||
substatements must not set rand_used to 0 because it would remove the
|
||||
detection of rand() by the calling statement.
|
||||
*/
|
||||
if (!in_sub_stmt) /* stored functions and triggers are a special case */
|
||||
{
|
||||
/* Forget those values, for next binlogger: */
|
||||
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
|
||||
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
|
||||
rand_used= 0;
|
||||
}
|
||||
if (first_successful_insert_id_in_cur_stmt > 0)
|
||||
{
|
||||
@@ -2542,30 +2553,111 @@ my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
|
||||
}
|
||||
|
||||
|
||||
my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data,
|
||||
const byte *record) const
|
||||
/*
|
||||
Pack a record of data for a table into a format suitable for
|
||||
transfer via the binary log.
|
||||
|
||||
SYNOPSIS
|
||||
THD::pack_row()
|
||||
table Table describing the format of the record
|
||||
cols Bitmap with a set bit for each column that should be
|
||||
stored in the row
|
||||
row_data Pointer to memory where row will be written
|
||||
record Pointer to record that should be packed. It is assumed
|
||||
that the pointer refers to either record[0] or
|
||||
record[1], but no such check is made since the code does
|
||||
not rely on that.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
The format for a row in transfer with N fields is the following:
|
||||
|
||||
ceil(N/8) null bytes:
|
||||
One null bit for every column *regardless of whether it can be
|
||||
null or not*. This simplifies the decoding. Observe that the
|
||||
number of null bits is equal to the number of set bits in the
|
||||
'cols' bitmap. The number of null bytes is the smallest number
|
||||
of bytes necessary to store the null bits.
|
||||
|
||||
Padding bits are 1.
|
||||
|
||||
N packets:
|
||||
Each field is stored in packed format.
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
|
||||
The number of bytes written at 'row_data'.
|
||||
*/
|
||||
my_size_t
|
||||
THD::pack_row(TABLE *table, MY_BITMAP const* cols,
|
||||
byte *const row_data, const byte *record) const
|
||||
{
|
||||
Field **p_field= table->field, *field;
|
||||
int n_null_bytes= table->s->null_bytes;
|
||||
byte *ptr;
|
||||
uint i;
|
||||
int const null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
|
||||
byte *pack_ptr = row_data + null_byte_count;
|
||||
byte *null_ptr = row_data;
|
||||
my_ptrdiff_t const rec_offset= record - table->record[0];
|
||||
my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
|
||||
memcpy(row_data, record, n_null_bytes);
|
||||
ptr= row_data+n_null_bytes;
|
||||
|
||||
for (i= 0 ; (field= *p_field) ; i++, p_field++)
|
||||
/*
|
||||
We write the null bits and the packed records using one pass
|
||||
through all the fields. The null bytes are written little-endian,
|
||||
i.e., the first fields are in the first byte.
|
||||
*/
|
||||
unsigned int null_bits= (1U << 8) - 1;
|
||||
// Mask to mask out the correct but among the null bits
|
||||
unsigned int null_mask= 1U;
|
||||
for ( ; (field= *p_field) ; p_field++)
|
||||
{
|
||||
if (bitmap_is_set(cols,i))
|
||||
DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
|
||||
null_mask, null_ptr, row_data, null_byte_count));
|
||||
if (bitmap_is_set(cols, p_field - table->field))
|
||||
{
|
||||
my_ptrdiff_t const offset=
|
||||
field->is_null((uint) rec_offset) ? def_offset : rec_offset;
|
||||
field->move_field_offset(offset);
|
||||
ptr= (byte*)field->pack((char *) ptr, field->ptr);
|
||||
field->move_field_offset(-offset);
|
||||
my_ptrdiff_t offset;
|
||||
if (field->is_null(rec_offset))
|
||||
{
|
||||
offset= def_offset;
|
||||
null_bits |= null_mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset= rec_offset;
|
||||
null_bits &= ~null_mask;
|
||||
|
||||
/*
|
||||
We only store the data of the field if it is non-null
|
||||
*/
|
||||
pack_ptr= (byte*)field->pack((char *) pack_ptr, field->ptr + offset);
|
||||
}
|
||||
|
||||
null_mask <<= 1;
|
||||
if ((null_mask & 0xFF) == 0)
|
||||
{
|
||||
DBUG_ASSERT(null_ptr < row_data + null_byte_count);
|
||||
null_mask = 1U;
|
||||
*null_ptr++ = null_bits;
|
||||
null_bits= (1U << 8) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (static_cast<my_size_t>(ptr - row_data));
|
||||
|
||||
/*
|
||||
Write the last (partial) byte, if there is one
|
||||
*/
|
||||
if ((null_mask & 0xFF) > 1)
|
||||
{
|
||||
DBUG_ASSERT(null_ptr < row_data + null_byte_count);
|
||||
*null_ptr++ = null_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
The null pointer should now point to the first byte of the
|
||||
packed data. If it doesn't, something is very wrong.
|
||||
*/
|
||||
DBUG_ASSERT(null_ptr == row_data + null_byte_count);
|
||||
|
||||
return static_cast<my_size_t>(pack_ptr - row_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user