mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04: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)
|
int Field_varstring::do_save_field_metadata(uchar *metadata_ptr)
|
||||||
{
|
{
|
||||||
char *ptr= (char *)metadata_ptr;
|
char *ptr= (char *)metadata_ptr;
|
||||||
|
DBUG_ASSERT(field_length <= 65535);
|
||||||
int2store(ptr, field_length);
|
int2store(ptr, field_length);
|
||||||
return 2;
|
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
|
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.
|
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)) {
|
switch (type(col)) {
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
length= my_decimal_get_binary_size(m_field_metadata[col] >> 8,
|
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;
|
break;
|
||||||
case MYSQL_TYPE_DECIMAL:
|
case MYSQL_TYPE_DECIMAL:
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
case MYSQL_TYPE_DOUBLE:
|
case MYSQL_TYPE_DOUBLE:
|
||||||
length= m_field_metadata[col];
|
length= m_field_metadata[col];
|
||||||
break;
|
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_SET:
|
||||||
case MYSQL_TYPE_ENUM:
|
case MYSQL_TYPE_ENUM:
|
||||||
case MYSQL_TYPE_STRING:
|
case MYSQL_TYPE_STRING:
|
||||||
{
|
{
|
||||||
if (((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_SET << 8)) ||
|
uchar type= m_field_metadata[col] >> 8U;
|
||||||
((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_ENUM << 8)))
|
if ((type == MYSQL_TYPE_SET) || (type == MYSQL_TYPE_ENUM))
|
||||||
length= m_field_metadata[col] & 0x00ff;
|
length= m_field_metadata[col] & 0x00ff;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
length= m_field_metadata[col] & 0x00ff;
|
/*
|
||||||
DBUG_ASSERT(length > 0);
|
We are reading the actual size from the master_data record
|
||||||
if (length > 255)
|
because this field has the actual lengh stored in the first
|
||||||
{
|
byte.
|
||||||
DBUG_ASSERT(uint2korr(master_data) > 0);
|
*/
|
||||||
length= uint2korr(master_data) + 2;
|
length= (uint) *master_data + 1;
|
||||||
}
|
DBUG_ASSERT(length != 0);
|
||||||
else
|
|
||||||
length= (uint) *master_data + 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +98,13 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_BIT:
|
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_len= (m_field_metadata[col] >> 8U) & 0x00ff;
|
||||||
uint from_bit_len= m_field_metadata[col] & 0x00ff;
|
uint from_bit_len= m_field_metadata[col] & 0x00ff;
|
||||||
DBUG_ASSERT(from_bit_len <= 7);
|
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;
|
length= *master_data;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
length= sint2korr(master_data);
|
length= uint2korr(master_data);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
length= uint3korr(master_data);
|
length= uint3korr(master_data);
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
/*
|
/*
|
||||||
These types store a single byte.
|
These types store a single byte.
|
||||||
*/
|
*/
|
||||||
m_field_metadata[i]= (uchar)field_metadata[index];
|
m_field_metadata[i]= field_metadata[index];
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,14 @@ public:
|
||||||
case MYSQL_TYPE_ENUM:
|
case MYSQL_TYPE_ENUM:
|
||||||
case MYSQL_TYPE_STRING:
|
case MYSQL_TYPE_STRING:
|
||||||
{
|
{
|
||||||
short int x= field_metadata[index++] << 8U; // real_type
|
uint16 x= field_metadata[index++] << 8U; // real_type
|
||||||
x = x + field_metadata[index++]; // pack or field length
|
x+= field_metadata[index++]; // pack or field length
|
||||||
m_field_metadata[i]= x;
|
m_field_metadata[i]= x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_BIT:
|
case MYSQL_TYPE_BIT:
|
||||||
{
|
{
|
||||||
short int x= field_metadata[index++];
|
uint16 x= field_metadata[index++];
|
||||||
x = x + (field_metadata[index++] << 8U);
|
x = x + (field_metadata[index++] << 8U);
|
||||||
m_field_metadata[i]= x;
|
m_field_metadata[i]= x;
|
||||||
break;
|
break;
|
||||||
|
@ -125,14 +125,14 @@ public:
|
||||||
These types store two bytes.
|
These types store two bytes.
|
||||||
*/
|
*/
|
||||||
char *ptr= (char *)&field_metadata[index];
|
char *ptr= (char *)&field_metadata[index];
|
||||||
m_field_metadata[i]= sint2korr(ptr);
|
m_field_metadata[i]= uint2korr(ptr);
|
||||||
index= index + 2;
|
index= index + 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
{
|
{
|
||||||
short int x= field_metadata[index++] << 8U; // precision
|
uint16 x= field_metadata[index++] << 8U; // precision
|
||||||
x = x + field_metadata[index++]; // decimals
|
x+= field_metadata[index++]; // decimals
|
||||||
m_field_metadata[i]= x;
|
m_field_metadata[i]= x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue