summaryrefslogtreecommitdiff
path: root/sql/rpl_utility.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/rpl_utility.h')
-rw-r--r--sql/rpl_utility.h132
1 files changed, 126 insertions, 6 deletions
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 79e69aecaeb..c91113c9e2a 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -25,8 +25,6 @@
struct st_relay_log_info;
typedef st_relay_log_info RELAY_LOG_INFO;
-uint32
-field_length_from_packed(enum_field_types field_type, uchar const *data);
/**
A table definition from the master.
@@ -57,19 +55,96 @@ public:
@param types Array of types
@param size Number of elements in array 'types'
+ @param field_metadata Array of extra information about fields
+ @param metadata_size Size of the field_metadata array
+ @param null_bitmap The bitmap of fields that can be null
*/
- table_def(field_type *types, ulong size)
- : m_size(size), m_type(new unsigned char [size])
+ table_def(field_type *types, ulong size, uchar *field_metadata,
+ int metadata_size, uchar *null_bitmap)
+ : m_size(size), m_type(0),
+ m_field_metadata(0), m_null_bits(0), m_memory(NULL)
{
+ m_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
+ &m_type, size,
+ &m_field_metadata, size * sizeof(short),
+ &m_null_bits, (m_size + 7) / 8,
+ NULL);
if (m_type)
memcpy(m_type, types, size);
else
m_size= 0;
+ /*
+ Extract the data from the table map into the field metadata array
+ iff there is field metadata. The variable metadata_size will be
+ 0 if we are replicating from an older version server since no field
+ metadata was written to the table map. This can also happen if
+ there were no fields in the master that needed extra metadata.
+ */
+ if (m_size && metadata_size)
+ {
+ int index= 0;
+ for (unsigned int i= 0; i < m_size; i++)
+ {
+ switch (m_type[i]) {
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_DOUBLE:
+ case MYSQL_TYPE_FLOAT:
+ {
+ /*
+ These types store a single byte.
+ */
+ m_field_metadata[i]= (uchar)field_metadata[index];
+ index++;
+ break;
+ }
+ case MYSQL_TYPE_SET:
+ 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
+ m_field_metadata[i]= x;
+ break;
+ }
+ case MYSQL_TYPE_BIT:
+ {
+ short int x= field_metadata[index++];
+ x = x + (field_metadata[index++] << 8U);
+ m_field_metadata[i]= x;
+ break;
+ }
+ case MYSQL_TYPE_VARCHAR:
+ {
+ /*
+ These types store two bytes.
+ */
+ char *ptr= (char *)&field_metadata[index];
+ m_field_metadata[i]= sint2korr(ptr);
+ index= index + sizeof(short int);
+ break;
+ }
+ case MYSQL_TYPE_NEWDECIMAL:
+ {
+ short int x= field_metadata[index++] << 8U; // precision
+ x = x + field_metadata[index++]; // decimals
+ m_field_metadata[i]= x;
+ break;
+ }
+ default:
+ m_field_metadata[i]= 0;
+ break;
+ }
+ }
+ }
+ if (m_size && null_bitmap)
+ memcpy(m_null_bits, null_bitmap, (m_size + 7) / 8);
}
~table_def() {
- if (m_type)
- delete [] m_type;
+ my_free(m_memory, MYF(0));
#ifndef DBUG_OFF
m_type= 0;
m_size= 0;
@@ -99,6 +174,48 @@ public:
return m_type[index];
}
+
+ /*
+ This function allows callers to get the extra field data from the
+ table map for a given field. If there is no metadata for that field
+ or there is no extra metadata at all, the function returns 0.
+
+ The function returns the value for the field metadata for column at
+ position indicated by index. As mentioned, if the field was a type
+ that stores field metadata, that value is returned else zero (0) is
+ returned. This method is used in the unpack() methods of the
+ corresponding fields to properly extract the data from the binary log
+ in the event that the master's field is smaller than the slave.
+ */
+ uint16 field_metadata(uint index) const
+ {
+ DBUG_ASSERT(index < m_size);
+ if (m_field_metadata)
+ return m_field_metadata[index];
+ else
+ return 0;
+ }
+
+ /*
+ This function returns whether the field on the master can be null.
+ This value is derived from field->maybe_null().
+ */
+ my_bool maybe_null(uint index) const
+ {
+ DBUG_ASSERT(index < m_size);
+ return ((m_null_bits[(index / 8)] &
+ (1 << (index % 8))) == (1 << (index %8)));
+ }
+
+ /*
+ This function returns the field size in raw bytes based on the type
+ and the encoded field data from the master's raw data. This method can
+ be used for situations where the slave needs to skip a column (e.g.,
+ WL#3915) or needs to advance the pointer for the fields in the raw
+ data from the master to a specific column.
+ */
+ uint32 calc_field_size(uint col, uchar *master_data);
+
/**
Decide if the table definition is compatible with a table.
@@ -121,6 +238,9 @@ public:
private:
ulong m_size; // Number of elements in the types array
field_type *m_type; // Array of type descriptors
+ short int *m_field_metadata;
+ uchar *m_null_bits;
+ uchar *m_memory;
};
/**