mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-19710 Split the server side code in rpl_utility.cc into virtual methods in Type_handler
This commit is contained in:
@ -101,7 +101,9 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||||||
../sql/multi_range_read.cc
|
../sql/multi_range_read.cc
|
||||||
../sql/opt_index_cond_pushdown.cc
|
../sql/opt_index_cond_pushdown.cc
|
||||||
../sql/opt_subselect.cc
|
../sql/opt_subselect.cc
|
||||||
../sql/create_options.cc ../sql/rpl_utility.cc
|
../sql/create_options.cc
|
||||||
|
../sql/rpl_utility.cc
|
||||||
|
../sql/rpl_utility_server.cc
|
||||||
../sql/rpl_reporting.cc
|
../sql/rpl_reporting.cc
|
||||||
../sql/sql_expression_cache.cc
|
../sql/sql_expression_cache.cc
|
||||||
../sql/my_apc.cc ../sql/my_apc.h
|
../sql/my_apc.cc ../sql/my_apc.h
|
||||||
|
@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT),
|
|||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)''
|
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254)''
|
||||||
|
|
||||||
*** Drop t11 ***
|
*** Drop t11 ***
|
||||||
connection master;
|
connection master;
|
||||||
|
@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT),
|
|||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)''
|
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254)''
|
||||||
|
|
||||||
*** Drop t11 ***
|
*** Drop t11 ***
|
||||||
connection master;
|
connection master;
|
||||||
|
@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST
|
|||||||
********************************************
|
********************************************
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)''
|
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)''
|
||||||
*** Drop t3 ***
|
*** Drop t3 ***
|
||||||
connection master;
|
connection master;
|
||||||
DROP TABLE t3;
|
DROP TABLE t3;
|
||||||
|
@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST
|
|||||||
********************************************
|
********************************************
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)''
|
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)''
|
||||||
*** Drop t3 ***
|
*** Drop t3 ***
|
||||||
connection master;
|
connection master;
|
||||||
DROP TABLE t3;
|
DROP TABLE t3;
|
||||||
|
@ -334,7 +334,7 @@ INSERT INTO t1 VALUES ('This is a test.');
|
|||||||
connection slave;
|
connection slave;
|
||||||
START SLAVE;
|
START SLAVE;
|
||||||
include/wait_for_slave_sql_error.inc [errno=1677]
|
include/wait_for_slave_sql_error.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'tinyblob' to type 'tinyblob''
|
Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'longblob' to type 'tinyblob''
|
||||||
SELECT COUNT(*) FROM t1;
|
SELECT COUNT(*) FROM t1;
|
||||||
COUNT(*)
|
COUNT(*)
|
||||||
0
|
0
|
||||||
|
@ -111,7 +111,8 @@ SET (SQL_SOURCE
|
|||||||
rpl_tblmap.cc sql_binlog.cc event_scheduler.cc event_data_objects.cc
|
rpl_tblmap.cc sql_binlog.cc event_scheduler.cc event_data_objects.cc
|
||||||
event_queue.cc event_db_repository.cc
|
event_queue.cc event_db_repository.cc
|
||||||
sql_tablespace.cc events.cc ../sql-common/my_user.c
|
sql_tablespace.cc events.cc ../sql-common/my_user.c
|
||||||
partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc
|
partition_info.cc rpl_utility.cc rpl_utility_server.cc
|
||||||
|
rpl_injector.cc sql_locale.cc
|
||||||
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
|
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
|
||||||
sql_connect.cc scheduler.cc sql_partition_admin.cc
|
sql_connect.cc scheduler.cc sql_partition_admin.cc
|
||||||
sql_profile.cc event_parse_data.cc sql_alter.cc
|
sql_profile.cc event_parse_data.cc sql_alter.cc
|
||||||
|
110
sql/field.h
110
sql/field.h
@ -60,6 +60,46 @@ enum enum_check_fields
|
|||||||
CHECK_FIELD_ERROR_FOR_NULL,
|
CHECK_FIELD_ERROR_FOR_NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum enum_conv_type
|
||||||
|
{
|
||||||
|
CONV_TYPE_PRECISE,
|
||||||
|
CONV_TYPE_VARIANT,
|
||||||
|
CONV_TYPE_SUBSET_TO_SUPERSET,
|
||||||
|
CONV_TYPE_SUPERSET_TO_SUBSET,
|
||||||
|
CONV_TYPE_IMPOSSIBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Conv_param
|
||||||
|
{
|
||||||
|
uint16 m_table_def_flags;
|
||||||
|
public:
|
||||||
|
Conv_param(uint16 table_def_flags)
|
||||||
|
:m_table_def_flags(table_def_flags)
|
||||||
|
{ }
|
||||||
|
uint16 table_def_flags() const { return m_table_def_flags; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Conv_source: public Type_handler_hybrid_field_type
|
||||||
|
{
|
||||||
|
enum_field_types m_type;
|
||||||
|
uint16 m_metadata;
|
||||||
|
CHARSET_INFO *m_cs;
|
||||||
|
public:
|
||||||
|
Conv_source(const Type_handler *h, uint16 metadata, CHARSET_INFO *cs)
|
||||||
|
:Type_handler_hybrid_field_type(h),
|
||||||
|
m_metadata(metadata),
|
||||||
|
m_cs(cs)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cs);
|
||||||
|
}
|
||||||
|
uint16 metadata() const { return m_metadata; }
|
||||||
|
uint mbmaxlen() const { return m_cs->mbmaxlen; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Common declarations for Field and Item
|
Common declarations for Field and Item
|
||||||
*/
|
*/
|
||||||
@ -1085,6 +1125,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
return type();
|
return type();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Conversion type for from the source to the current field.
|
||||||
|
*/
|
||||||
|
virtual enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m)
|
||||||
|
const= 0;
|
||||||
|
enum_conv_type rpl_conv_type_from_same_data_type(uint16 metadata,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m)
|
||||||
|
const;
|
||||||
inline int cmp(const uchar *str) { return cmp(ptr,str); }
|
inline int cmp(const uchar *str) { return cmp(ptr,str); }
|
||||||
virtual int cmp_max(const uchar *a, const uchar *b, uint max_len)
|
virtual int cmp_max(const uchar *a, const uchar *b, uint max_len)
|
||||||
{ return cmp(a, b); }
|
{ return cmp(a, b); }
|
||||||
@ -1940,7 +1991,9 @@ public:
|
|||||||
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
||||||
field_name_arg, collation)
|
field_name_arg, collation)
|
||||||
{}
|
{}
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int store_decimal(const my_decimal *d);
|
int store_decimal(const my_decimal *d);
|
||||||
uint32 max_data_length() const;
|
uint32 max_data_length() const;
|
||||||
|
|
||||||
@ -1981,6 +2034,9 @@ public:
|
|||||||
{
|
{
|
||||||
return do_field_real;
|
return do_field_real;
|
||||||
}
|
}
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Information_schema_numeric_attributes
|
Information_schema_numeric_attributes
|
||||||
information_schema_numeric_attributes() const
|
information_schema_numeric_attributes() const
|
||||||
{
|
{
|
||||||
@ -2090,6 +2146,9 @@ public:
|
|||||||
return Field_num::memcpy_field_possible(from) &&
|
return Field_num::memcpy_field_possible(from) &&
|
||||||
field_length == from->field_length;
|
field_length == from->field_length;
|
||||||
}
|
}
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int reset(void);
|
int reset(void);
|
||||||
bool store_value(const my_decimal *decimal_value);
|
bool store_value(const my_decimal *decimal_value);
|
||||||
bool store_value(const my_decimal *decimal_value, int *native_error);
|
bool store_value(const my_decimal *decimal_value, int *native_error);
|
||||||
@ -2162,6 +2221,9 @@ public:
|
|||||||
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, 0, zero_arg, unsigned_arg)
|
unireg_check_arg, field_name_arg, 0, zero_arg, unsigned_arg)
|
||||||
{}
|
{}
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int store_decimal(const my_decimal *);
|
int store_decimal(const my_decimal *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
bool val_bool() { return val_int() != 0; }
|
bool val_bool() { return val_int() != 0; }
|
||||||
@ -2627,6 +2689,9 @@ public:
|
|||||||
unireg_check_arg, field_name_arg, collation)
|
unireg_check_arg, field_name_arg, collation)
|
||||||
{}
|
{}
|
||||||
const Type_handler *type_handler() const { return &type_handler_null; }
|
const Type_handler *type_handler() const { return &type_handler_null; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Information_schema_character_attributes
|
Information_schema_character_attributes
|
||||||
information_schema_character_attributes() const
|
information_schema_character_attributes() const
|
||||||
{
|
{
|
||||||
@ -2815,6 +2880,9 @@ public:
|
|||||||
TABLE_SHARE *share);
|
TABLE_SHARE *share);
|
||||||
const Type_handler *type_handler() const { return &type_handler_timestamp; }
|
const Type_handler *type_handler() const { return &type_handler_timestamp; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Copy_func *get_copy_func(const Field *from) const;
|
Copy_func *get_copy_func(const Field *from) const;
|
||||||
int store(const char *to,size_t length,CHARSET_INFO *charset);
|
int store(const char *to,size_t length,CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
@ -2967,6 +3035,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
const Type_handler *type_handler() const { return &type_handler_timestamp2; }
|
const Type_handler *type_handler() const { return &type_handler_timestamp2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
return my_timestamp_binary_length(dec);
|
return my_timestamp_binary_length(dec);
|
||||||
@ -3006,6 +3077,9 @@ public:
|
|||||||
{
|
{
|
||||||
return field_length == 2 ? &type_handler_year2 : &type_handler_year;
|
return field_length == 2 ? &type_handler_year2 : &type_handler_year;
|
||||||
}
|
}
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
if (eq_def(from))
|
if (eq_def(from))
|
||||||
@ -3088,6 +3162,9 @@ public:
|
|||||||
unireg_check_arg, field_name_arg) {}
|
unireg_check_arg, field_name_arg) {}
|
||||||
const Type_handler *type_handler() const { return &type_handler_date; }
|
const Type_handler *type_handler() const { return &type_handler_date; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
|
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
|
||||||
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{ return Field_date::get_TIME(ltime, ptr, fuzzydate); }
|
{ return Field_date::get_TIME(ltime, ptr, fuzzydate); }
|
||||||
@ -3125,6 +3202,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
const Type_handler *type_handler() const { return &type_handler_newdate; }
|
const Type_handler *type_handler() const { return &type_handler_newdate; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
|
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
|
||||||
double val_real(void);
|
double val_real(void);
|
||||||
longlong val_int(void);
|
longlong val_int(void);
|
||||||
@ -3168,6 +3248,9 @@ public:
|
|||||||
const Item_equal *item_equal);
|
const Item_equal *item_equal);
|
||||||
const Type_handler *type_handler() const { return &type_handler_time; }
|
const Type_handler *type_handler() const { return &type_handler_time; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
return from->cmp_type() == REAL_RESULT ? do_field_string : // MDEV-9344
|
return from->cmp_type() == REAL_RESULT ? do_field_string : // MDEV-9344
|
||||||
@ -3280,6 +3363,9 @@ public:
|
|||||||
}
|
}
|
||||||
const Type_handler *type_handler() const { return &type_handler_time2; }
|
const Type_handler *type_handler() const { return &type_handler_time2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_TIME2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_TIME2; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
return my_time_binary_length(dec);
|
return my_time_binary_length(dec);
|
||||||
@ -3325,6 +3411,9 @@ public:
|
|||||||
}
|
}
|
||||||
const Type_handler *type_handler() const { return &type_handler_datetime; }
|
const Type_handler *type_handler() const { return &type_handler_datetime; }
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
int store(const char *to, size_t length, CHARSET_INFO *charset);
|
int store(const char *to, size_t length, CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
int store(longlong nr, bool unsigned_val);
|
int store(longlong nr, bool unsigned_val);
|
||||||
@ -3447,6 +3536,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
const Type_handler *type_handler() const { return &type_handler_datetime2; }
|
const Type_handler *type_handler() const { return &type_handler_datetime2; }
|
||||||
enum_field_types binlog_type() const { return MYSQL_TYPE_DATETIME2; }
|
enum_field_types binlog_type() const { return MYSQL_TYPE_DATETIME2; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
uint32 pack_length() const
|
uint32 pack_length() const
|
||||||
{
|
{
|
||||||
return my_datetime_binary_length(dec);
|
return my_datetime_binary_length(dec);
|
||||||
@ -4130,6 +4222,9 @@ public:
|
|||||||
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
||||||
field_name_arg, share, blob_pack_length, &my_charset_bin)
|
field_name_arg, share, blob_pack_length, &my_charset_bin)
|
||||||
{ geom_type= geom_type_arg; srid= field_srid; }
|
{ geom_type= geom_type_arg; srid= field_srid; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{
|
{
|
||||||
@ -4212,6 +4307,9 @@ public:
|
|||||||
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
|
||||||
const Type_handler *type_handler() const { return &type_handler_enum; }
|
const Type_handler *type_handler() const { return &type_handler_enum; }
|
||||||
enum ha_base_keytype key_type() const;
|
enum ha_base_keytype key_type() const;
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Copy_func *get_copy_func(const Field *from) const
|
Copy_func *get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
if (eq_def(from))
|
if (eq_def(from))
|
||||||
@ -4365,6 +4463,9 @@ public:
|
|||||||
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
|
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
|
||||||
uint32 max_data_length() const { return (field_length + 7) / 8; }
|
uint32 max_data_length() const { return (field_length + 7) / 8; }
|
||||||
uint32 max_display_length() const { return field_length; }
|
uint32 max_display_length() const { return field_length; }
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const;
|
||||||
Information_schema_numeric_attributes
|
Information_schema_numeric_attributes
|
||||||
information_schema_numeric_attributes() const
|
information_schema_numeric_attributes() const
|
||||||
{
|
{
|
||||||
@ -4531,6 +4632,13 @@ public:
|
|||||||
m_table(NULL)
|
m_table(NULL)
|
||||||
{}
|
{}
|
||||||
~Field_row();
|
~Field_row();
|
||||||
|
enum_conv_type rpl_conv_type_from(const Conv_source &source,
|
||||||
|
const Relay_log_info *rli,
|
||||||
|
const Conv_param ¶m) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return CONV_TYPE_IMPOSSIBLE;
|
||||||
|
}
|
||||||
Virtual_tmp_table **virtual_tmp_table_addr() { return &m_table; }
|
Virtual_tmp_table **virtual_tmp_table_addr() { return &m_table; }
|
||||||
bool sp_prepare_and_store_item(THD *thd, Item **value);
|
bool sp_prepare_and_store_item(THD *thd, Item **value);
|
||||||
};
|
};
|
||||||
|
@ -19,185 +19,7 @@
|
|||||||
#include "rpl_utility.h"
|
#include "rpl_utility.h"
|
||||||
#include "log_event.h"
|
#include "log_event.h"
|
||||||
|
|
||||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
|
||||||
#include "rpl_rli.h"
|
|
||||||
#include "sql_select.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate display length for MySQL56 temporal data types from their metadata.
|
|
||||||
It contains fractional precision in the low 16-bit word.
|
|
||||||
*/
|
|
||||||
static uint32
|
|
||||||
max_display_length_for_temporal2_field(uint32 int_display_length,
|
|
||||||
unsigned int metadata)
|
|
||||||
{
|
|
||||||
metadata&= 0x00ff;
|
|
||||||
return int_display_length + metadata + (metadata ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compute the maximum display length of a field.
|
|
||||||
|
|
||||||
@param sql_type Type of the field
|
|
||||||
@param metadata The metadata from the master for the field.
|
|
||||||
@return Maximum length of the field in bytes.
|
|
||||||
|
|
||||||
The precise values calculated by field->max_display_length() and
|
|
||||||
calculated by max_display_length_for_field() can differ (by +1 or -1)
|
|
||||||
for integer data types (TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT).
|
|
||||||
This slight difference is not important here, because we call
|
|
||||||
this function only for two *different* integer data types.
|
|
||||||
*/
|
|
||||||
static uint32
|
|
||||||
max_display_length_for_field(enum_field_types sql_type, unsigned int metadata)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("debug", ("sql_type: %d, metadata: 0x%x", sql_type, metadata));
|
|
||||||
DBUG_ASSERT(metadata >> 16 == 0);
|
|
||||||
|
|
||||||
switch (sql_type) {
|
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
|
||||||
return metadata >> 8;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_FLOAT:
|
|
||||||
return 12;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DOUBLE:
|
|
||||||
return 22;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_SET:
|
|
||||||
case MYSQL_TYPE_ENUM:
|
|
||||||
return metadata & 0x00ff;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_STRING:
|
|
||||||
{
|
|
||||||
uchar type= metadata >> 8;
|
|
||||||
if (type == MYSQL_TYPE_SET || type == MYSQL_TYPE_ENUM)
|
|
||||||
return metadata & 0xff;
|
|
||||||
else
|
|
||||||
/* This is taken from Field_string::unpack. */
|
|
||||||
return (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
case MYSQL_TYPE_YEAR:
|
|
||||||
case MYSQL_TYPE_TINY:
|
|
||||||
return 4;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_SHORT:
|
|
||||||
return 6;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_INT24:
|
|
||||||
return 9;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_LONG:
|
|
||||||
return 11;
|
|
||||||
|
|
||||||
#ifdef HAVE_LONG_LONG
|
|
||||||
case MYSQL_TYPE_LONGLONG:
|
|
||||||
return 20;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
case MYSQL_TYPE_NULL:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_NEWDATE:
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DATE:
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIME:
|
|
||||||
return MIN_TIME_WIDTH;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIME2:
|
|
||||||
return max_display_length_for_temporal2_field(MIN_TIME_WIDTH, metadata);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
return MAX_DATETIME_WIDTH;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIMESTAMP2:
|
|
||||||
return max_display_length_for_temporal2_field(MAX_DATETIME_WIDTH, metadata);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DATETIME:
|
|
||||||
return MAX_DATETIME_WIDTH;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DATETIME2:
|
|
||||||
return max_display_length_for_temporal2_field(MAX_DATETIME_WIDTH, metadata);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_BIT:
|
|
||||||
/*
|
|
||||||
Decode the size of the bit field from the master.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT((metadata & 0xff) <= 7);
|
|
||||||
return 8 * (metadata >> 8U) + (metadata & 0x00ff);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
return metadata;
|
|
||||||
case MYSQL_TYPE_VARCHAR_COMPRESSED:
|
|
||||||
return metadata - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
The actual length for these types does not really matter since
|
|
||||||
they are used to calc_pack_length, which ignores the given
|
|
||||||
length for these types.
|
|
||||||
|
|
||||||
Since we want this to be accurate for other uses, we return the
|
|
||||||
maximum size in bytes of these BLOBs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
|
||||||
return (uint32)my_set_bits(1 * 8);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
|
||||||
return (uint32)my_set_bits(3 * 8);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB_COMPRESSED:
|
|
||||||
/*
|
|
||||||
For the blob type, Field::real_type() lies and say that all
|
|
||||||
blobs are of type MYSQL_TYPE_BLOB. In that case, we have to look
|
|
||||||
at the length instead to decide what the max display size is.
|
|
||||||
*/
|
|
||||||
return (uint32)my_set_bits(metadata * 8);
|
|
||||||
|
|
||||||
case MYSQL_TYPE_LONG_BLOB:
|
|
||||||
case MYSQL_TYPE_GEOMETRY:
|
|
||||||
return (uint32)my_set_bits(4 * 8);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ~(uint32) 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Compare the pack lengths of a source field (on the master) and a
|
|
||||||
target field (on the slave).
|
|
||||||
|
|
||||||
@param field Target field.
|
|
||||||
@param type Source field type.
|
|
||||||
@param metadata Source field metadata.
|
|
||||||
|
|
||||||
@retval -1 The length of the source field is smaller than the target field.
|
|
||||||
@retval 0 The length of the source and target fields are the same.
|
|
||||||
@retval 1 The length of the source field is greater than the target field.
|
|
||||||
*/
|
|
||||||
int compare_lengths(Field *field, enum_field_types source_type, uint16 metadata)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("compare_lengths");
|
|
||||||
size_t const source_length=
|
|
||||||
max_display_length_for_field(source_type, metadata);
|
|
||||||
size_t const target_length= field->max_display_length();
|
|
||||||
DBUG_PRINT("debug", ("source_length: %lu, source_type: %u,"
|
|
||||||
" target_length: %lu, target_type: %u",
|
|
||||||
(unsigned long) source_length, source_type,
|
|
||||||
(unsigned long) target_length, field->real_type()));
|
|
||||||
int result= source_length < target_length ? -1 : source_length > target_length;
|
|
||||||
DBUG_PRINT("result", ("%d", result));
|
|
||||||
DBUG_RETURN(result);
|
|
||||||
}
|
|
||||||
#endif //MYSQL_CLIENT
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* table_def member definitions *
|
* table_def member definitions *
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
@ -349,739 +171,6 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_INFO *field_cs)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("show_sql_type");
|
|
||||||
DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata));
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_TINY:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("tinyint"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_SHORT:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("smallint"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_LONG:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("int"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_FLOAT:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("float"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DOUBLE:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("double"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_NULL:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("null"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
case MYSQL_TYPE_TIMESTAMP2:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("timestamp"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_LONGLONG:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("bigint"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_INT24:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("mediumint"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_NEWDATE:
|
|
||||||
case MYSQL_TYPE_DATE:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("date"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_TIME:
|
|
||||||
case MYSQL_TYPE_TIME2:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("time"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DATETIME:
|
|
||||||
case MYSQL_TYPE_DATETIME2:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("datetime"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_YEAR:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("year"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
case MYSQL_TYPE_VARCHAR_COMPRESSED:
|
|
||||||
{
|
|
||||||
CHARSET_INFO *cs= str->charset();
|
|
||||||
size_t length=
|
|
||||||
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
|
|
||||||
"varchar(%u)%s", metadata,
|
|
||||||
type == MYSQL_TYPE_VARCHAR_COMPRESSED ? " compressed"
|
|
||||||
: "");
|
|
||||||
str->length(length);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_BIT:
|
|
||||||
{
|
|
||||||
CHARSET_INFO *cs= str->charset();
|
|
||||||
int bit_length= 8 * (metadata >> 8) + (metadata & 0xFF);
|
|
||||||
size_t length=
|
|
||||||
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
|
|
||||||
"bit(%d)", bit_length);
|
|
||||||
str->length(length);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DECIMAL:
|
|
||||||
{
|
|
||||||
CHARSET_INFO *cs= str->charset();
|
|
||||||
size_t length=
|
|
||||||
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
|
|
||||||
"decimal(%d,?)/*old*/", metadata);
|
|
||||||
str->length(length);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
|
||||||
{
|
|
||||||
CHARSET_INFO *cs= str->charset();
|
|
||||||
size_t length=
|
|
||||||
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
|
|
||||||
"decimal(%d,%d)", metadata >> 8, metadata & 0xff);
|
|
||||||
str->length(length);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_ENUM:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("enum"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_SET:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("set"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB_COMPRESSED:
|
|
||||||
/*
|
|
||||||
Field::real_type() lies regarding the actual type of a BLOB, so
|
|
||||||
it is necessary to check the pack length to figure out what kind
|
|
||||||
of blob it really is.
|
|
||||||
*/
|
|
||||||
switch (get_blob_type_from_length(metadata))
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("tinyblob"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("mediumblob"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_LONG_BLOB:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("longblob"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("blob"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == MYSQL_TYPE_BLOB_COMPRESSED)
|
|
||||||
str->append(STRING_WITH_LEN(" compressed"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_STRING:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This is taken from Field_string::unpack.
|
|
||||||
*/
|
|
||||||
CHARSET_INFO *cs= str->charset();
|
|
||||||
uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
|
|
||||||
size_t length=
|
|
||||||
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
|
|
||||||
"char(%d)", bytes / field_cs->mbmaxlen);
|
|
||||||
str->length(length);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_GEOMETRY:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("geometry"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
str->set_ascii(STRING_WITH_LEN("<unknown type>"));
|
|
||||||
}
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check the order variable and print errors if the order is not
|
|
||||||
acceptable according to the current settings.
|
|
||||||
|
|
||||||
@param order The computed order of the conversion needed.
|
|
||||||
@param rli The relay log info data structure: for error reporting.
|
|
||||||
*/
|
|
||||||
bool is_conversion_ok(int order, Relay_log_info *rli)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("is_conversion_ok");
|
|
||||||
bool allow_non_lossy, allow_lossy;
|
|
||||||
|
|
||||||
allow_non_lossy = slave_type_conversions_options &
|
|
||||||
(1ULL << SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY);
|
|
||||||
allow_lossy= slave_type_conversions_options &
|
|
||||||
(1ULL << SLAVE_TYPE_CONVERSIONS_ALL_LOSSY);
|
|
||||||
|
|
||||||
DBUG_PRINT("enter", ("order: %d, flags:%s%s", order,
|
|
||||||
allow_non_lossy ? " ALL_NON_LOSSY" : "",
|
|
||||||
allow_lossy ? " ALL_LOSSY" : ""));
|
|
||||||
if (order < 0 && !allow_non_lossy)
|
|
||||||
{
|
|
||||||
/* !!! Add error message saying that non-lossy conversions need to be allowed. */
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (order > 0 && !allow_lossy)
|
|
||||||
{
|
|
||||||
/* !!! Add error message saying that lossy conversions need to be allowed. */
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Can a type potentially be converted to another type?
|
|
||||||
|
|
||||||
This function check if the types are convertible and what
|
|
||||||
conversion is required.
|
|
||||||
|
|
||||||
If conversion is not possible, and error is printed.
|
|
||||||
|
|
||||||
If conversion is possible:
|
|
||||||
|
|
||||||
- *order will be set to -1 if source type is smaller than target
|
|
||||||
type and a non-lossy conversion can be required. This includes
|
|
||||||
the case where the field types are different but types could
|
|
||||||
actually be converted in either direction.
|
|
||||||
|
|
||||||
- *order will be set to 0 if no conversion is required.
|
|
||||||
|
|
||||||
- *order will be set to 1 if the source type is strictly larger
|
|
||||||
than the target type and that conversion is potentially lossy.
|
|
||||||
|
|
||||||
@param[in] field Target field
|
|
||||||
@param[in] type Source field type
|
|
||||||
@param[in] metadata Source field metadata
|
|
||||||
@param[in] rli Relay log info (for error reporting)
|
|
||||||
@param[in] mflags Flags from the table map event
|
|
||||||
@param[out] order Order between source field and target field
|
|
||||||
|
|
||||||
@return @c true if conversion is possible according to the current
|
|
||||||
settings, @c false if conversion is not possible according to the
|
|
||||||
current setting.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
can_convert_field_to(Field *field,
|
|
||||||
enum_field_types source_type, uint16 metadata,
|
|
||||||
Relay_log_info *rli, uint16 mflags,
|
|
||||||
int *order_var)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("can_convert_field_to");
|
|
||||||
bool same_type;
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
char field_type_buf[MAX_FIELD_WIDTH];
|
|
||||||
String field_type(field_type_buf, sizeof(field_type_buf), &my_charset_latin1);
|
|
||||||
field->sql_type(field_type);
|
|
||||||
DBUG_PRINT("enter", ("field_type: %s, target_type: %d, source_type: %d, source_metadata: 0x%x",
|
|
||||||
field_type.c_ptr_safe(), field->real_type(), source_type, metadata));
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
@todo
|
|
||||||
Implement Field_varstring_cmopressed::real_type() and
|
|
||||||
Field_blob_compressed::real_type() properly. All occurencies
|
|
||||||
of Field::real_type() have to be inspected and adjusted if needed.
|
|
||||||
|
|
||||||
Until it is not ready we have to compare source_type against
|
|
||||||
binlog_type() when replicating from or to compressed data types.
|
|
||||||
|
|
||||||
@sa Comment for Field::binlog_type()
|
|
||||||
*/
|
|
||||||
if (source_type == MYSQL_TYPE_VARCHAR_COMPRESSED ||
|
|
||||||
source_type == MYSQL_TYPE_BLOB_COMPRESSED ||
|
|
||||||
field->binlog_type() == MYSQL_TYPE_VARCHAR_COMPRESSED ||
|
|
||||||
field->binlog_type() == MYSQL_TYPE_BLOB_COMPRESSED)
|
|
||||||
same_type= field->binlog_type() == source_type;
|
|
||||||
else
|
|
||||||
same_type= field->real_type() == source_type;
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the real type is the same, we need to check the metadata to
|
|
||||||
decide if conversions are allowed.
|
|
||||||
*/
|
|
||||||
if (same_type)
|
|
||||||
{
|
|
||||||
if (metadata == 0) // Metadata can only be zero if no metadata was provided
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If there is no metadata, we either have an old event where no
|
|
||||||
metadata were supplied, or a type that does not require any
|
|
||||||
metadata. In either case, conversion can be done but no
|
|
||||||
conversion table is necessary.
|
|
||||||
*/
|
|
||||||
DBUG_PRINT("debug", ("Base types are identical, but there is no metadata"));
|
|
||||||
*order_var= 0;
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_PRINT("debug", ("Base types are identical, doing field size comparison"));
|
|
||||||
if (field->compatible_field_size(metadata, rli, mflags, order_var))
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
else
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
/*
|
|
||||||
Conversion from MariaDB TIMESTAMP(0), TIME(0), DATETIME(0)
|
|
||||||
to the corresponding MySQL56 types is non-lossy.
|
|
||||||
*/
|
|
||||||
(metadata == 0 &&
|
|
||||||
((field->real_type() == MYSQL_TYPE_TIMESTAMP2 &&
|
|
||||||
source_type == MYSQL_TYPE_TIMESTAMP) ||
|
|
||||||
(field->real_type() == MYSQL_TYPE_TIME2 &&
|
|
||||||
source_type == MYSQL_TYPE_TIME) ||
|
|
||||||
(field->real_type() == MYSQL_TYPE_DATETIME2 &&
|
|
||||||
source_type == MYSQL_TYPE_DATETIME))) ||
|
|
||||||
/*
|
|
||||||
Conversion from MySQL56 TIMESTAMP(N), TIME(N), DATETIME(N)
|
|
||||||
to the corresponding MariaDB or MySQL55 types is non-lossy.
|
|
||||||
*/
|
|
||||||
(metadata == field->decimals() &&
|
|
||||||
((field->real_type() == MYSQL_TYPE_TIMESTAMP &&
|
|
||||||
source_type == MYSQL_TYPE_TIMESTAMP2) ||
|
|
||||||
(field->real_type() == MYSQL_TYPE_TIME &&
|
|
||||||
source_type == MYSQL_TYPE_TIME2) ||
|
|
||||||
(field->real_type() == MYSQL_TYPE_DATETIME &&
|
|
||||||
source_type == MYSQL_TYPE_DATETIME2))))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TS-TODO: conversion from FSP1>FSP2.
|
|
||||||
*/
|
|
||||||
*order_var= -1;
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
else if (!slave_type_conversions_options)
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Here, from and to will always be different. Since the types are
|
|
||||||
different, we cannot use the compatible_field_size() function, but
|
|
||||||
have to rely on hard-coded max-sizes for fields.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DBUG_PRINT("debug", ("Base types are different, checking conversion"));
|
|
||||||
switch (source_type) // Source type (on master)
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_DECIMAL:
|
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
|
||||||
case MYSQL_TYPE_FLOAT:
|
|
||||||
case MYSQL_TYPE_DOUBLE:
|
|
||||||
switch (field->real_type())
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
|
||||||
/*
|
|
||||||
Then the other type is either FLOAT, DOUBLE, or old style
|
|
||||||
DECIMAL, so we require lossy conversion.
|
|
||||||
*/
|
|
||||||
*order_var= 1;
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
|
|
||||||
case MYSQL_TYPE_DECIMAL:
|
|
||||||
case MYSQL_TYPE_FLOAT:
|
|
||||||
case MYSQL_TYPE_DOUBLE:
|
|
||||||
{
|
|
||||||
if (source_type == MYSQL_TYPE_NEWDECIMAL ||
|
|
||||||
source_type == MYSQL_TYPE_DECIMAL)
|
|
||||||
*order_var = 1; // Always require lossy conversions
|
|
||||||
else
|
|
||||||
*order_var= compare_lengths(field, source_type, metadata);
|
|
||||||
DBUG_ASSERT(*order_var != 0);
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
The length comparison check will do the correct job of comparing
|
|
||||||
the field lengths (in bytes) of two integer types.
|
|
||||||
*/
|
|
||||||
case MYSQL_TYPE_TINY:
|
|
||||||
case MYSQL_TYPE_SHORT:
|
|
||||||
case MYSQL_TYPE_INT24:
|
|
||||||
case MYSQL_TYPE_LONG:
|
|
||||||
case MYSQL_TYPE_LONGLONG:
|
|
||||||
switch (field->real_type())
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_TINY:
|
|
||||||
case MYSQL_TYPE_SHORT:
|
|
||||||
case MYSQL_TYPE_INT24:
|
|
||||||
case MYSQL_TYPE_LONG:
|
|
||||||
case MYSQL_TYPE_LONGLONG:
|
|
||||||
/*
|
|
||||||
max_display_length_for_field() is not fully precise for the integer
|
|
||||||
data types. So its result cannot be compared to the result of
|
|
||||||
field->max_dispay_length() when the table field and the binlog field
|
|
||||||
are of the same type.
|
|
||||||
This code should eventually be rewritten not to use
|
|
||||||
compare_lengths(), to detect subtype/supetype relations
|
|
||||||
just using the type codes.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(source_type != field->real_type());
|
|
||||||
*order_var= compare_lengths(field, source_type, metadata);
|
|
||||||
DBUG_ASSERT(*order_var != 0);
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
|
|
||||||
default:
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Since source and target type is different, and it is not possible
|
|
||||||
to convert bit types to anything else, this will return false.
|
|
||||||
*/
|
|
||||||
case MYSQL_TYPE_BIT:
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
If all conversions are disabled, it is not allowed to convert
|
|
||||||
between these types. Since the TEXT vs. BINARY is distinguished by
|
|
||||||
the charset, and the charset is not replicated, we cannot
|
|
||||||
currently distinguish between , e.g., TEXT and BLOB.
|
|
||||||
*/
|
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
|
||||||
case MYSQL_TYPE_LONG_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB_COMPRESSED:
|
|
||||||
case MYSQL_TYPE_STRING:
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
case MYSQL_TYPE_VARCHAR_COMPRESSED:
|
|
||||||
switch (field->real_type())
|
|
||||||
{
|
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
|
||||||
case MYSQL_TYPE_LONG_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
case MYSQL_TYPE_BLOB_COMPRESSED:
|
|
||||||
case MYSQL_TYPE_STRING:
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
case MYSQL_TYPE_VARCHAR_COMPRESSED:
|
|
||||||
*order_var= compare_lengths(field, source_type, metadata);
|
|
||||||
/*
|
|
||||||
Here we know that the types are different, so if the order
|
|
||||||
gives that they do not require any conversion, we still need
|
|
||||||
to have non-lossy conversion enabled to allow conversion
|
|
||||||
between different (string) types of the same length.
|
|
||||||
*/
|
|
||||||
if (*order_var == 0)
|
|
||||||
*order_var= -1;
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
|
|
||||||
default:
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MYSQL_TYPE_GEOMETRY:
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
case MYSQL_TYPE_DATE:
|
|
||||||
case MYSQL_TYPE_TIME:
|
|
||||||
case MYSQL_TYPE_DATETIME:
|
|
||||||
case MYSQL_TYPE_YEAR:
|
|
||||||
case MYSQL_TYPE_NULL:
|
|
||||||
case MYSQL_TYPE_ENUM:
|
|
||||||
case MYSQL_TYPE_SET:
|
|
||||||
case MYSQL_TYPE_TIMESTAMP2:
|
|
||||||
case MYSQL_TYPE_TIME2:
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
case MYSQL_TYPE_NEWDATE:
|
|
||||||
{
|
|
||||||
if (field->real_type() == MYSQL_TYPE_DATETIME2 ||
|
|
||||||
field->real_type() == MYSQL_TYPE_DATETIME)
|
|
||||||
{
|
|
||||||
*order_var= -1;
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//case MYSQL_TYPE_DATETIME: TODO: fix MDEV-17394 and uncomment.
|
|
||||||
//
|
|
||||||
//The "old" type does not specify the fraction part size which is required
|
|
||||||
//for correct conversion.
|
|
||||||
case MYSQL_TYPE_DATETIME2:
|
|
||||||
{
|
|
||||||
if (field->real_type() == MYSQL_TYPE_NEWDATE)
|
|
||||||
{
|
|
||||||
*order_var= 1;
|
|
||||||
DBUG_RETURN(is_conversion_ok(*order_var, rli));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DBUG_RETURN(false); // To keep GCC happy
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Is the definition compatible with a table?
|
|
||||||
|
|
||||||
This function will compare the master table with an existing table
|
|
||||||
on the slave and see if they are compatible with respect to the
|
|
||||||
current settings of @c SLAVE_TYPE_CONVERSIONS.
|
|
||||||
|
|
||||||
If the tables are compatible and conversions are required, @c
|
|
||||||
*tmp_table_var will be set to a virtual temporary table with field
|
|
||||||
pointers for the fields that require conversions. This allow simple
|
|
||||||
checking of whether a conversion are to be applied or not.
|
|
||||||
|
|
||||||
If tables are compatible, but no conversions are necessary, @c
|
|
||||||
*tmp_table_var will be set to NULL.
|
|
||||||
|
|
||||||
@param rli_arg[in]
|
|
||||||
Relay log info, for error reporting.
|
|
||||||
|
|
||||||
@param table[in]
|
|
||||||
Table to compare with
|
|
||||||
|
|
||||||
@param tmp_table_var[out]
|
|
||||||
Virtual temporary table for performing conversions, if necessary.
|
|
||||||
|
|
||||||
@retval true Master table is compatible with slave table.
|
|
||||||
@retval false Master table is not compatible with slave table.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
table_def::compatible_with(THD *thd, rpl_group_info *rgi,
|
|
||||||
TABLE *table, TABLE **conv_table_var)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We only check the initial columns for the tables.
|
|
||||||
*/
|
|
||||||
uint const cols_to_check= MY_MIN(table->s->fields, size());
|
|
||||||
Relay_log_info *rli= rgi->rli;
|
|
||||||
TABLE *tmp_table= NULL;
|
|
||||||
|
|
||||||
for (uint col= 0 ; col < cols_to_check ; ++col)
|
|
||||||
{
|
|
||||||
Field *const field= table->field[col];
|
|
||||||
int order;
|
|
||||||
if (can_convert_field_to(field, type(col), field_metadata(col), rli, m_flags, &order))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("debug", ("Checking column %d -"
|
|
||||||
" field '%s' can be converted - order: %d",
|
|
||||||
col, field->field_name.str, order));
|
|
||||||
DBUG_ASSERT(order >= -1 && order <= 1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
If order is not 0, a conversion is required, so we need to set
|
|
||||||
up the conversion table.
|
|
||||||
*/
|
|
||||||
if (order != 0 && tmp_table == NULL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This will create the full table with all fields. This is
|
|
||||||
necessary to ge the correct field lengths for the record.
|
|
||||||
*/
|
|
||||||
tmp_table= create_conversion_table(thd, rgi, table);
|
|
||||||
if (tmp_table == NULL)
|
|
||||||
return false;
|
|
||||||
/*
|
|
||||||
Clear all fields up to, but not including, this column.
|
|
||||||
*/
|
|
||||||
for (unsigned int i= 0; i < col; ++i)
|
|
||||||
tmp_table->field[i]= NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (order == 0 && tmp_table != NULL)
|
|
||||||
tmp_table->field[col]= NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_PRINT("debug", ("Checking column %d -"
|
|
||||||
" field '%s' can not be converted",
|
|
||||||
col, field->field_name.str));
|
|
||||||
DBUG_ASSERT(col < size() && col < table->s->fields);
|
|
||||||
DBUG_ASSERT(table->s->db.str && table->s->table_name.str);
|
|
||||||
DBUG_ASSERT(table->in_use);
|
|
||||||
const char *db_name= table->s->db.str;
|
|
||||||
const char *tbl_name= table->s->table_name.str;
|
|
||||||
char source_buf[MAX_FIELD_WIDTH];
|
|
||||||
char target_buf[MAX_FIELD_WIDTH];
|
|
||||||
String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
|
|
||||||
String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
|
|
||||||
THD *thd= table->in_use;
|
|
||||||
|
|
||||||
show_sql_type(type(col), field_metadata(col), &source_type, field->charset());
|
|
||||||
field->sql_type(target_type);
|
|
||||||
rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED, rgi->gtid_info(),
|
|
||||||
ER_THD(thd, ER_SLAVE_CONVERSION_FAILED),
|
|
||||||
col, db_name, tbl_name,
|
|
||||||
source_type.c_ptr_safe(), target_type.c_ptr_safe());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
if (tmp_table)
|
|
||||||
{
|
|
||||||
for (unsigned int col= 0; col < tmp_table->s->fields; ++col)
|
|
||||||
if (tmp_table->field[col])
|
|
||||||
{
|
|
||||||
char source_buf[MAX_FIELD_WIDTH];
|
|
||||||
char target_buf[MAX_FIELD_WIDTH];
|
|
||||||
String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
|
|
||||||
String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
|
|
||||||
tmp_table->field[col]->sql_type(source_type);
|
|
||||||
table->field[col]->sql_type(target_type);
|
|
||||||
DBUG_PRINT("debug", ("Field %s - conversion required."
|
|
||||||
" Source type: '%s', Target type: '%s'",
|
|
||||||
tmp_table->field[col]->field_name.str,
|
|
||||||
source_type.c_ptr_safe(), target_type.c_ptr_safe()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*conv_table_var= tmp_table;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
A wrapper to Virtual_tmp_table, to get access to its constructor,
|
|
||||||
which is protected for safety purposes (against illegal use on stack).
|
|
||||||
*/
|
|
||||||
class Virtual_conversion_table: public Virtual_tmp_table
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Virtual_conversion_table(THD *thd) :Virtual_tmp_table(thd) { }
|
|
||||||
/**
|
|
||||||
Add a new field into the virtual table.
|
|
||||||
@param sql_type - The real_type of the field.
|
|
||||||
@param metadata - The RBR binary log metadata for this field.
|
|
||||||
@param target_field - The field from the target table, to get extra
|
|
||||||
attributes from (e.g. typelib in case of ENUM).
|
|
||||||
*/
|
|
||||||
bool add(enum_field_types sql_type,
|
|
||||||
uint16 metadata, const Field *target_field)
|
|
||||||
{
|
|
||||||
const Type_handler *handler= Type_handler::get_handler_by_real_type(sql_type);
|
|
||||||
if (!handler)
|
|
||||||
{
|
|
||||||
sql_print_error("In RBR mode, Slave received unknown field type field %d "
|
|
||||||
" for column Name: %s.%s.%s.",
|
|
||||||
(int) sql_type,
|
|
||||||
target_field->table->s->db.str,
|
|
||||||
target_field->table->s->table_name.str,
|
|
||||||
target_field->field_name.str);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Field *tmp= handler->make_conversion_table_field(this, metadata,
|
|
||||||
target_field);
|
|
||||||
if (!tmp)
|
|
||||||
return true;
|
|
||||||
Virtual_tmp_table::add(tmp);
|
|
||||||
DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d,"
|
|
||||||
" maybe_null: %d, unsigned_flag: %d, pack_length: %u",
|
|
||||||
sql_type, target_field->field_name.str,
|
|
||||||
tmp->field_length, tmp->decimals(), TRUE,
|
|
||||||
tmp->flags, tmp->pack_length()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a conversion table.
|
|
||||||
|
|
||||||
If the function is unable to create the conversion table, an error
|
|
||||||
will be printed and NULL will be returned.
|
|
||||||
|
|
||||||
@return Pointer to conversion table, or NULL if unable to create
|
|
||||||
conversion table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
|
|
||||||
TABLE *target_table) const
|
|
||||||
{
|
|
||||||
DBUG_ENTER("table_def::create_conversion_table");
|
|
||||||
|
|
||||||
Virtual_conversion_table *conv_table;
|
|
||||||
Relay_log_info *rli= rgi->rli;
|
|
||||||
/*
|
|
||||||
At slave, columns may differ. So we should create
|
|
||||||
MY_MIN(columns@master, columns@slave) columns in the
|
|
||||||
conversion table.
|
|
||||||
*/
|
|
||||||
uint const cols_to_create= MY_MIN(target_table->s->fields, size());
|
|
||||||
if (!(conv_table= new(thd) Virtual_conversion_table(thd)) ||
|
|
||||||
conv_table->init(cols_to_create))
|
|
||||||
goto err;
|
|
||||||
for (uint col= 0 ; col < cols_to_create; ++col)
|
|
||||||
{
|
|
||||||
if (conv_table->add(type(col), field_metadata(col),
|
|
||||||
target_table->field[col]))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("debug", ("binlog_type: %d, metadata: %04X, target_field: '%s'"
|
|
||||||
" make_conversion_table_field() failed",
|
|
||||||
binlog_type(col), field_metadata(col),
|
|
||||||
target_table->field[col]->field_name.str));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conv_table->open())
|
|
||||||
goto err; // Could not allocate record buffer?
|
|
||||||
|
|
||||||
DBUG_RETURN(conv_table);
|
|
||||||
|
|
||||||
err:
|
|
||||||
if (conv_table)
|
|
||||||
delete conv_table;
|
|
||||||
rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION, rgi->gtid_info(),
|
|
||||||
ER_THD(thd, ER_SLAVE_CANT_CREATE_CONVERSION),
|
|
||||||
target_table->s->db.str,
|
|
||||||
target_table->s->table_name.str);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
#endif /* MYSQL_CLIENT */
|
|
||||||
|
|
||||||
table_def::table_def(unsigned char *types, ulong size,
|
table_def::table_def(unsigned char *types, ulong size,
|
||||||
uchar *field_metadata, int metadata_size,
|
uchar *field_metadata, int metadata_size,
|
||||||
@ -1245,67 +334,3 @@ bool event_checksum_test(uchar *event_buf, ulong event_len, enum enum_binlog_che
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
|
|
||||||
|
|
||||||
Deferred_log_events::Deferred_log_events(Relay_log_info *rli) : last_added(NULL)
|
|
||||||
{
|
|
||||||
my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16, MYF(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
Deferred_log_events::~Deferred_log_events()
|
|
||||||
{
|
|
||||||
delete_dynamic(&array);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Deferred_log_events::add(Log_event *ev)
|
|
||||||
{
|
|
||||||
last_added= ev;
|
|
||||||
insert_dynamic(&array, (uchar*) &ev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Deferred_log_events::is_empty()
|
|
||||||
{
|
|
||||||
return array.elements == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Deferred_log_events::execute(rpl_group_info *rgi)
|
|
||||||
{
|
|
||||||
bool res= false;
|
|
||||||
DBUG_ENTER("Deferred_log_events::execute");
|
|
||||||
DBUG_ASSERT(rgi->deferred_events_collecting);
|
|
||||||
|
|
||||||
rgi->deferred_events_collecting= false;
|
|
||||||
for (uint i= 0; !res && i < array.elements; i++)
|
|
||||||
{
|
|
||||||
Log_event *ev= (* (Log_event **)
|
|
||||||
dynamic_array_ptr(&array, i));
|
|
||||||
res= ev->apply_event(rgi);
|
|
||||||
}
|
|
||||||
rgi->deferred_events_collecting= true;
|
|
||||||
DBUG_RETURN(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Deferred_log_events::rewind()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Reset preceding Query log event events which execution was
|
|
||||||
deferred because of slave side filtering.
|
|
||||||
*/
|
|
||||||
if (!is_empty())
|
|
||||||
{
|
|
||||||
for (uint i= 0; i < array.elements; i++)
|
|
||||||
{
|
|
||||||
Log_event *ev= *(Log_event **) dynamic_array_ptr(&array, i);
|
|
||||||
delete ev;
|
|
||||||
}
|
|
||||||
last_added= NULL;
|
|
||||||
if (array.elements > array.max_element)
|
|
||||||
freeze_size(&array);
|
|
||||||
reset_dynamic(&array);
|
|
||||||
}
|
|
||||||
last_added= NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -118,7 +118,9 @@ public:
|
|||||||
|
|
||||||
return source_type;
|
return source_type;
|
||||||
}
|
}
|
||||||
|
#ifdef MYSQL_SERVER
|
||||||
|
const Type_handler *field_type_handler(uint index) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function allows callers to get the extra field data from the
|
This function allows callers to get the extra field data from the
|
||||||
|
1191
sql/rpl_utility_server.cc
Normal file
1191
sql/rpl_utility_server.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -60,13 +60,13 @@ Type_handler_string type_handler_string;
|
|||||||
Type_handler_var_string type_handler_var_string;
|
Type_handler_var_string type_handler_var_string;
|
||||||
Type_handler_varchar type_handler_varchar;
|
Type_handler_varchar type_handler_varchar;
|
||||||
Type_handler_hex_hybrid type_handler_hex_hybrid;
|
Type_handler_hex_hybrid type_handler_hex_hybrid;
|
||||||
static Type_handler_varchar_compressed type_handler_varchar_compressed;
|
Type_handler_varchar_compressed type_handler_varchar_compressed;
|
||||||
|
|
||||||
Type_handler_tiny_blob type_handler_tiny_blob;
|
Type_handler_tiny_blob type_handler_tiny_blob;
|
||||||
Type_handler_medium_blob type_handler_medium_blob;
|
Type_handler_medium_blob type_handler_medium_blob;
|
||||||
Type_handler_long_blob type_handler_long_blob;
|
Type_handler_long_blob type_handler_long_blob;
|
||||||
Type_handler_blob type_handler_blob;
|
Type_handler_blob type_handler_blob;
|
||||||
static Type_handler_blob_compressed type_handler_blob_compressed;
|
Type_handler_blob_compressed type_handler_blob_compressed;
|
||||||
|
|
||||||
Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff;
|
Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff;
|
||||||
|
|
||||||
@ -1908,13 +1908,7 @@ Type_handler::get_handler_by_real_type(enum_field_types type)
|
|||||||
case MYSQL_TYPE_LONG_BLOB: return &type_handler_long_blob;
|
case MYSQL_TYPE_LONG_BLOB: return &type_handler_long_blob;
|
||||||
case MYSQL_TYPE_BLOB: return &type_handler_blob;
|
case MYSQL_TYPE_BLOB: return &type_handler_blob;
|
||||||
case MYSQL_TYPE_BLOB_COMPRESSED: return &type_handler_blob_compressed;
|
case MYSQL_TYPE_BLOB_COMPRESSED: return &type_handler_blob_compressed;
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
case MYSQL_TYPE_VAR_STRING: return &type_handler_var_string;
|
||||||
/*
|
|
||||||
VAR_STRING is actually a field_type(), not a real_type(),
|
|
||||||
but it's used around the code in real_type() context.
|
|
||||||
We should clean up the code and add DBUG_ASSERT(0) here.
|
|
||||||
*/
|
|
||||||
return &type_handler_string;
|
|
||||||
case MYSQL_TYPE_STRING: return &type_handler_string;
|
case MYSQL_TYPE_STRING: return &type_handler_string;
|
||||||
case MYSQL_TYPE_ENUM: return &type_handler_enum;
|
case MYSQL_TYPE_ENUM: return &type_handler_enum;
|
||||||
case MYSQL_TYPE_SET: return &type_handler_set;
|
case MYSQL_TYPE_SET: return &type_handler_set;
|
||||||
@ -1933,8 +1927,7 @@ Type_handler::get_handler_by_real_type(enum_field_types type)
|
|||||||
case MYSQL_TYPE_DATETIME2: return &type_handler_datetime2;
|
case MYSQL_TYPE_DATETIME2: return &type_handler_datetime2;
|
||||||
case MYSQL_TYPE_NEWDATE: return &type_handler_newdate;
|
case MYSQL_TYPE_NEWDATE: return &type_handler_newdate;
|
||||||
};
|
};
|
||||||
DBUG_ASSERT(0);
|
return NULL;
|
||||||
return &type_handler_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ struct TABLE;
|
|||||||
struct SORT_FIELD_ATTR;
|
struct SORT_FIELD_ATTR;
|
||||||
class Vers_history_point;
|
class Vers_history_point;
|
||||||
class Virtual_column_info;
|
class Virtual_column_info;
|
||||||
|
class Conv_source;
|
||||||
struct ST_FIELD_INFO;
|
struct ST_FIELD_INFO;
|
||||||
|
|
||||||
#define my_charset_numeric my_charset_latin1
|
#define my_charset_numeric my_charset_latin1
|
||||||
@ -3393,6 +3394,8 @@ public:
|
|||||||
virtual Field *make_conversion_table_field(TABLE *TABLE,
|
virtual Field *make_conversion_table_field(TABLE *TABLE,
|
||||||
uint metadata,
|
uint metadata,
|
||||||
const Field *target) const= 0;
|
const Field *target) const= 0;
|
||||||
|
virtual void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
|
virtual uint32 max_display_length_for_field(const Conv_source &src) const= 0;
|
||||||
/*
|
/*
|
||||||
Performs the final data type validation for a UNION element,
|
Performs the final data type validation for a UNION element,
|
||||||
after the regular "aggregation for result" was done.
|
after the regular "aggregation for result" was done.
|
||||||
@ -3891,6 +3894,11 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32 calc_pack_length(uint32 length) const
|
uint32 calc_pack_length(uint32 length) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@ -4825,6 +4833,8 @@ public:
|
|||||||
return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8;
|
return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8;
|
||||||
}
|
}
|
||||||
uint32 calc_pack_length(uint32 length) const { return 1; }
|
uint32 calc_pack_length(uint32 length) const { return 1; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 4; }
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
return Item_send_tiny(item, protocol, buf);
|
return Item_send_tiny(item, protocol, buf);
|
||||||
@ -4877,6 +4887,8 @@ public:
|
|||||||
{
|
{
|
||||||
return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16;
|
return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16;
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 6; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return 2; }
|
uint32 calc_pack_length(uint32 length) const { return 2; }
|
||||||
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
|
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -4922,6 +4934,8 @@ public:
|
|||||||
{
|
{
|
||||||
return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32;
|
return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32;
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 11; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return 4; }
|
uint32 calc_pack_length(uint32 length) const { return 4; }
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
@ -4982,6 +4996,8 @@ public:
|
|||||||
{
|
{
|
||||||
return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64;
|
return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64;
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 20; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return 8; }
|
uint32 calc_pack_length(uint32 length) const { return 8; }
|
||||||
Item *create_typecast_item(THD *thd, Item *item,
|
Item *create_typecast_item(THD *thd, Item *item,
|
||||||
const Type_cast_attributes &attr) const;
|
const Type_cast_attributes &attr) const;
|
||||||
@ -5050,6 +5066,8 @@ public:
|
|||||||
{
|
{
|
||||||
return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24;
|
return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24;
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 9; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return 3; }
|
uint32 calc_pack_length(uint32 length) const { return 3; }
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5084,6 +5102,8 @@ public:
|
|||||||
return PROTOCOL_SEND_SHORT;
|
return PROTOCOL_SEND_SHORT;
|
||||||
}
|
}
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 4; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return 1; }
|
uint32 calc_pack_length(uint32 length) const { return 1; }
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
@ -5133,6 +5153,7 @@ public:
|
|||||||
return PROTOCOL_SEND_STRING;
|
return PROTOCOL_SEND_STRING;
|
||||||
}
|
}
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const { return length / 8; }
|
uint32 calc_pack_length(uint32 length) const { return length / 8; }
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
@ -5142,6 +5163,7 @@ public:
|
|||||||
{
|
{
|
||||||
return print_item_value_csstr(thd, item, str);
|
return print_item_value_csstr(thd, item, str);
|
||||||
}
|
}
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
@ -5186,6 +5208,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool type_can_have_auto_increment_attribute() const { return true; }
|
bool type_can_have_auto_increment_attribute() const { return true; }
|
||||||
uint32 max_display_length(const Item *item) const { return 25; }
|
uint32 max_display_length(const Item *item) const { return 25; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 12; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return sizeof(float); }
|
uint32 calc_pack_length(uint32 length) const { return sizeof(float); }
|
||||||
Item *create_typecast_item(THD *thd, Item *item,
|
Item *create_typecast_item(THD *thd, Item *item,
|
||||||
const Type_cast_attributes &attr) const;
|
const Type_cast_attributes &attr) const;
|
||||||
@ -5239,6 +5263,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool type_can_have_auto_increment_attribute() const { return true; }
|
bool type_can_have_auto_increment_attribute() const { return true; }
|
||||||
uint32 max_display_length(const Item *item) const { return 53; }
|
uint32 max_display_length(const Item *item) const { return 53; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 22; }
|
||||||
uint32 calc_pack_length(uint32 length) const { return sizeof(double); }
|
uint32 calc_pack_length(uint32 length) const { return sizeof(double); }
|
||||||
Item *create_typecast_item(THD *thd, Item *item,
|
Item *create_typecast_item(THD *thd, Item *item,
|
||||||
const Type_cast_attributes &attr) const;
|
const Type_cast_attributes &attr) const;
|
||||||
@ -5375,6 +5401,8 @@ public:
|
|||||||
static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
|
static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
|
||||||
virtual ~Type_handler_time() {}
|
virtual ~Type_handler_time() {}
|
||||||
const Name version() const { return m_version_mariadb53; }
|
const Name version() const { return m_version_mariadb53; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return MIN_TIME_WIDTH; }
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5402,6 +5430,7 @@ public:
|
|||||||
virtual ~Type_handler_time2() {}
|
virtual ~Type_handler_time2() {}
|
||||||
const Name version() const { return m_version_mysql56; }
|
const Name version() const { return m_version_mysql56; }
|
||||||
enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; }
|
enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5456,6 +5485,8 @@ public:
|
|||||||
const Name &default_value() const;
|
const Name &default_value() const;
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return 3; }
|
||||||
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
||||||
{
|
{
|
||||||
return DYN_COL_DATE;
|
return DYN_COL_DATE;
|
||||||
@ -5624,6 +5655,8 @@ public:
|
|||||||
static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
|
static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
|
||||||
virtual ~Type_handler_datetime() {}
|
virtual ~Type_handler_datetime() {}
|
||||||
const Name version() const { return m_version_mariadb53; }
|
const Name version() const { return m_version_mariadb53; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return MAX_DATETIME_WIDTH; }
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5651,6 +5684,7 @@ public:
|
|||||||
virtual ~Type_handler_datetime2() {}
|
virtual ~Type_handler_datetime2() {}
|
||||||
const Name version() const { return m_version_mysql56; }
|
const Name version() const { return m_version_mysql56; }
|
||||||
enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
|
enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5759,6 +5793,8 @@ public:
|
|||||||
static uint sec_part_bytes(uint dec) { return m_sec_part_bytes[dec]; }
|
static uint sec_part_bytes(uint dec) { return m_sec_part_bytes[dec]; }
|
||||||
virtual ~Type_handler_timestamp() {}
|
virtual ~Type_handler_timestamp() {}
|
||||||
const Name version() const { return m_version_mariadb53; }
|
const Name version() const { return m_version_mariadb53; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const
|
||||||
|
{ return MAX_DATETIME_WIDTH; }
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5786,6 +5822,7 @@ public:
|
|||||||
virtual ~Type_handler_timestamp2() {}
|
virtual ~Type_handler_timestamp2() {}
|
||||||
const Name version() const { return m_version_mysql56; }
|
const Name version() const { return m_version_mysql56; }
|
||||||
enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
@ -5816,9 +5853,11 @@ public:
|
|||||||
virtual ~Type_handler_olddecimal() {}
|
virtual ~Type_handler_olddecimal() {}
|
||||||
const Name name() const { return m_name_decimal; }
|
const Name name() const { return m_name_decimal; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const { return length; }
|
uint32 calc_pack_length(uint32 length) const { return length; }
|
||||||
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
||||||
const Type_handler *type_handler_for_union(const Item *item) const;
|
const Type_handler *type_handler_for_union(const Item *item) const;
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
@ -5847,7 +5886,9 @@ public:
|
|||||||
virtual ~Type_handler_newdecimal() {}
|
virtual ~Type_handler_newdecimal() {}
|
||||||
const Name name() const { return m_name_decimal; }
|
const Name name() const { return m_name_decimal; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
|
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
@ -5893,6 +5934,7 @@ public:
|
|||||||
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
|
||||||
const Type_handler *type_handler_for_union(const Item *) const;
|
const Type_handler *type_handler_for_union(const Item *) const;
|
||||||
uint32 max_display_length(const Item *item) const { return 0; }
|
uint32 max_display_length(const Item *item) const { return 0; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const { return 0;}
|
||||||
uint32 calc_pack_length(uint32 length) const { return 0; }
|
uint32 calc_pack_length(uint32 length) const { return 0; }
|
||||||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||||
bool binary_cmp) const;
|
bool binary_cmp) const;
|
||||||
@ -5947,11 +5989,13 @@ public:
|
|||||||
const Name name() const { return m_name_char; }
|
const Name name() const { return m_name_char; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
bool is_param_long_data_type() const { return true; }
|
bool is_param_long_data_type() const { return true; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const { return length; }
|
uint32 calc_pack_length(uint32 length) const { return length; }
|
||||||
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
const Type_handler *type_handler_for_tmp_table(const Item *item) const
|
||||||
{
|
{
|
||||||
return varstring_type_handler(item);
|
return varstring_type_handler(item);
|
||||||
}
|
}
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
@ -5993,6 +6037,8 @@ public:
|
|||||||
{
|
{
|
||||||
return varstring_type_handler(item);
|
return varstring_type_handler(item);
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
void Column_definition_implicit_upgrade(Column_definition *c) const;
|
void Column_definition_implicit_upgrade(Column_definition *c) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
bool Column_definition_prepare_stage2(Column_definition *c,
|
bool Column_definition_prepare_stage2(Column_definition *c,
|
||||||
@ -6017,6 +6063,7 @@ public:
|
|||||||
{
|
{
|
||||||
return MYSQL_TYPE_VAR_STRING; // Keep things compatible for old clients
|
return MYSQL_TYPE_VAR_STRING; // Keep things compatible for old clients
|
||||||
}
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const
|
uint32 calc_pack_length(uint32 length) const
|
||||||
{
|
{
|
||||||
return (length + (length < 256 ? 1: 2));
|
return (length + (length < 256 ? 1: 2));
|
||||||
@ -6030,6 +6077,7 @@ public:
|
|||||||
return varstring_type_handler(item);
|
return varstring_type_handler(item);
|
||||||
}
|
}
|
||||||
bool is_param_long_data_type() const { return true; }
|
bool is_param_long_data_type() const { return true; }
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const;
|
bool Column_definition_fix_attributes(Column_definition *c) const;
|
||||||
@ -6065,6 +6113,12 @@ public:
|
|||||||
class Type_handler_varchar_compressed: public Type_handler_varchar
|
class Type_handler_varchar_compressed: public Type_handler_varchar
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum_field_types real_field_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TYPE_VARCHAR_COMPRESSED;
|
||||||
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
||||||
@ -6132,6 +6186,7 @@ public:
|
|||||||
uint length_bytes() const { return 1; }
|
uint length_bytes() const { return 1; }
|
||||||
const Name name() const { return m_name_tinyblob; }
|
const Name name() const { return m_name_tinyblob; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; }
|
enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_table_field(const LEX_CSTRING *name,
|
Field *make_table_field(const LEX_CSTRING *name,
|
||||||
const Record_addr &addr,
|
const Record_addr &addr,
|
||||||
@ -6149,6 +6204,7 @@ public:
|
|||||||
uint length_bytes() const { return 3; }
|
uint length_bytes() const { return 3; }
|
||||||
const Name name() const { return m_name_mediumblob; }
|
const Name name() const { return m_name_mediumblob; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; }
|
enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_table_field(const LEX_CSTRING *name,
|
Field *make_table_field(const LEX_CSTRING *name,
|
||||||
const Record_addr &addr,
|
const Record_addr &addr,
|
||||||
@ -6166,6 +6222,7 @@ public:
|
|||||||
uint length_bytes() const { return 4; }
|
uint length_bytes() const { return 4; }
|
||||||
const Name name() const { return m_name_longblob; }
|
const Name name() const { return m_name_longblob; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
|
enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Item *create_typecast_item(THD *thd, Item *item,
|
Item *create_typecast_item(THD *thd, Item *item,
|
||||||
const Type_cast_attributes &attr) const;
|
const Type_cast_attributes &attr) const;
|
||||||
@ -6185,6 +6242,7 @@ public:
|
|||||||
uint length_bytes() const { return 2; }
|
uint length_bytes() const { return 2; }
|
||||||
const Name name() const { return m_name_blob; }
|
const Name name() const { return m_name_blob; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
|
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
Field *make_table_field(const LEX_CSTRING *name,
|
Field *make_table_field(const LEX_CSTRING *name,
|
||||||
const Record_addr &addr,
|
const Record_addr &addr,
|
||||||
@ -6197,6 +6255,12 @@ public:
|
|||||||
class Type_handler_blob_compressed: public Type_handler_blob
|
class Type_handler_blob_compressed: public Type_handler_blob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum_field_types real_field_type() const
|
||||||
|
{
|
||||||
|
return MYSQL_TYPE_BLOB_COMPRESSED;
|
||||||
|
}
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
|
void show_binlog_type(const Conv_source &src, String *str) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const
|
||||||
@ -6216,6 +6280,7 @@ public:
|
|||||||
const Name name() const { return m_name_geometry; }
|
const Name name() const { return m_name_geometry; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
||||||
bool is_param_long_data_type() const { return true; }
|
bool is_param_long_data_type() const { return true; }
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
uint32 calc_pack_length(uint32 length) const;
|
uint32 calc_pack_length(uint32 length) const;
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
bool type_can_have_key_part() const
|
bool type_can_have_key_part() const
|
||||||
@ -6313,6 +6378,7 @@ public:
|
|||||||
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
|
||||||
const Type_handler *type_handler_for_item_field() const;
|
const Type_handler *type_handler_for_item_field() const;
|
||||||
const Type_handler *cast_to_int_type_handler() const;
|
const Type_handler *cast_to_int_type_handler() const;
|
||||||
|
uint32 max_display_length_for_field(const Conv_source &src) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd,
|
bool Item_hybrid_func_fix_attributes(THD *thd,
|
||||||
const char *name,
|
const char *name,
|
||||||
Type_handler_hybrid_field_type *,
|
Type_handler_hybrid_field_type *,
|
||||||
@ -6508,12 +6574,16 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_set type_handler_set;
|
|||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_string type_handler_string;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_string type_handler_string;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_var_string type_handler_var_string;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_var_string type_handler_var_string;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_varchar type_handler_varchar;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_varchar type_handler_varchar;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT Type_handler_varchar_compressed
|
||||||
|
type_handler_varchar_compressed;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_hex_hybrid type_handler_hex_hybrid;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_hex_hybrid type_handler_hex_hybrid;
|
||||||
|
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT Type_handler_blob_compressed
|
||||||
|
type_handler_blob_compressed;
|
||||||
|
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool;
|
||||||
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny type_handler_tiny;
|
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny type_handler_tiny;
|
||||||
|
@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT),
|
|||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)''
|
Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254)''
|
||||||
|
|
||||||
*** Drop t11 ***
|
*** Drop t11 ***
|
||||||
connection master;
|
connection master;
|
||||||
|
@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST
|
|||||||
********************************************
|
********************************************
|
||||||
connection slave;
|
connection slave;
|
||||||
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
include/wait_for_slave_sql_error_and_skip.inc [errno=1677]
|
||||||
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)''
|
Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)''
|
||||||
*** Drop t3 ***
|
*** Drop t3 ***
|
||||||
connection master;
|
connection master;
|
||||||
DROP TABLE t3;
|
DROP TABLE t3;
|
||||||
|
Reference in New Issue
Block a user