mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
Merge mysql_cab_desk.:C:/source/c++/mysql-5.1-new-rpl
into mysql_cab_desk.:C:/source/c++/mysql-5.1_BUG_30790
This commit is contained in:
commit
17f804f8d3
4 changed files with 41 additions and 20 deletions
|
@ -6732,6 +6732,7 @@ const uint Field_varstring::MAX_SIZE= UINT_MAX16;
|
|||
int Field_varstring::do_save_field_metadata(uchar *metadata_ptr)
|
||||
{
|
||||
char *ptr= (char *)metadata_ptr;
|
||||
DBUG_ASSERT(field_length <= 65535);
|
||||
int2store(ptr, field_length);
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -6469,6 +6469,16 @@ void Rows_log_event::print_helper(FILE *file,
|
|||
data) in the table map are initialized as zero (0). The array size is the
|
||||
same as the columns for the table on the slave.
|
||||
|
||||
Additionally, values saved for field metadata on the master are saved as a
|
||||
string of bytes (uchar) in the binlog. A field may require 1 or more bytes
|
||||
to store the information. In cases where values require multiple bytes
|
||||
(e.g. values > 255), the endian-safe methods are used to properly encode
|
||||
the values on the master and decode them on the slave. When the field
|
||||
metadata values are captured on the slave, they are stored in an array of
|
||||
type uint16. This allows the least number of casts to prevent casting bugs
|
||||
when the field metadata is used in comparisons of field attributes. When
|
||||
the field metadata is used for calculating addresses in pointer math, the
|
||||
type used is uint32.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,31 +31,34 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
|
|||
switch (type(col)) {
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
length= my_decimal_get_binary_size(m_field_metadata[col] >> 8,
|
||||
m_field_metadata[col] - ((m_field_metadata[col] >> 8) << 8));
|
||||
m_field_metadata[col] & 0xff);
|
||||
break;
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
length= m_field_metadata[col];
|
||||
break;
|
||||
/*
|
||||
The cases for SET and ENUM are include for completeness, however
|
||||
both are mapped to type MYSQL_TYPE_STRING and their real types
|
||||
are encoded in the field metadata.
|
||||
*/
|
||||
case MYSQL_TYPE_SET:
|
||||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_STRING:
|
||||
{
|
||||
if (((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_SET << 8)) ||
|
||||
((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_ENUM << 8)))
|
||||
uchar type= m_field_metadata[col] >> 8U;
|
||||
if ((type == MYSQL_TYPE_SET) || (type == MYSQL_TYPE_ENUM))
|
||||
length= m_field_metadata[col] & 0x00ff;
|
||||
else
|
||||
{
|
||||
length= m_field_metadata[col] & 0x00ff;
|
||||
DBUG_ASSERT(length > 0);
|
||||
if (length > 255)
|
||||
{
|
||||
DBUG_ASSERT(uint2korr(master_data) > 0);
|
||||
length= uint2korr(master_data) + 2;
|
||||
}
|
||||
else
|
||||
length= (uint) *master_data + 1;
|
||||
/*
|
||||
We are reading the actual size from the master_data record
|
||||
because this field has the actual lengh stored in the first
|
||||
byte.
|
||||
*/
|
||||
length= (uint) *master_data + 1;
|
||||
DBUG_ASSERT(length != 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -95,6 +98,13 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
|
|||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
{
|
||||
/*
|
||||
Decode the size of the bit field from the master.
|
||||
from_len is the length in bytes from the master
|
||||
from_bit_len is the number of extra bits stored in the master record
|
||||
If from_bit_len is not 0, add 1 to the length to account for accurate
|
||||
number of bytes needed.
|
||||
*/
|
||||
uint from_len= (m_field_metadata[col] >> 8U) & 0x00ff;
|
||||
uint from_bit_len= m_field_metadata[col] & 0x00ff;
|
||||
DBUG_ASSERT(from_bit_len <= 7);
|
||||
|
@ -136,7 +146,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
|
|||
length= *master_data;
|
||||
break;
|
||||
case 2:
|
||||
length= sint2korr(master_data);
|
||||
length= uint2korr(master_data);
|
||||
break;
|
||||
case 3:
|
||||
length= uint3korr(master_data);
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
/*
|
||||
These types store a single byte.
|
||||
*/
|
||||
m_field_metadata[i]= (uchar)field_metadata[index];
|
||||
m_field_metadata[i]= field_metadata[index];
|
||||
index++;
|
||||
break;
|
||||
}
|
||||
|
@ -107,14 +107,14 @@ public:
|
|||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_STRING:
|
||||
{
|
||||
short int x= field_metadata[index++] << 8U; // real_type
|
||||
x = x + field_metadata[index++]; // pack or field length
|
||||
uint16 x= field_metadata[index++] << 8U; // real_type
|
||||
x+= field_metadata[index++]; // pack or field length
|
||||
m_field_metadata[i]= x;
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_BIT:
|
||||
{
|
||||
short int x= field_metadata[index++];
|
||||
uint16 x= field_metadata[index++];
|
||||
x = x + (field_metadata[index++] << 8U);
|
||||
m_field_metadata[i]= x;
|
||||
break;
|
||||
|
@ -125,14 +125,14 @@ public:
|
|||
These types store two bytes.
|
||||
*/
|
||||
char *ptr= (char *)&field_metadata[index];
|
||||
m_field_metadata[i]= sint2korr(ptr);
|
||||
m_field_metadata[i]= uint2korr(ptr);
|
||||
index= index + 2;
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
{
|
||||
short int x= field_metadata[index++] << 8U; // precision
|
||||
x = x + field_metadata[index++]; // decimals
|
||||
uint16 x= field_metadata[index++] << 8U; // precision
|
||||
x+= field_metadata[index++]; // decimals
|
||||
m_field_metadata[i]= x;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue