Approved.
Luís.
On Thu, 2009-12-10 at 11:12 +0000, Mats Kindahl wrote:
> #At file:///home/bzr/mkindahl/w5151-mysql-5.1/pipes/conversion-table/ based on
> revid:mats@stripped
>
> 3182 Mats Kindahl 2009-12-10
> WL#5151: Conversion between different types when replicating
>
> Patch addressing review comments.
> @ mysql-test/extra/rpl_tests/check_type.inc
> Correcting typo in comment.
> @ mysql-test/extra/rpl_tests/type_conversions.test
> Adding some extra conversions for values outside the range of the target
> type.
> @ sql/mysqld.cc
> Clarifying description for slave-type-conversions option.
> @ sql/rpl_utility.cc
> Handling MYSQL_TYPE_VAR_STRING and MYSQL_TYPE_DECIMAL.
> Adding optimization to not check compatibility if no
> slave type conversions are enabled.
> @ sql/set_var.cc
> Using unsigned int instead of size_t.
>
> modified:
> mysql-test/extra/rpl_tests/check_type.inc
> mysql-test/extra/rpl_tests/type_conversions.test
> mysql-test/suite/rpl/r/rpl_row_colSize.result
> mysql-test/suite/rpl/r/rpl_typeconv.result
> sql/mysqld.cc
> sql/rpl_utility.cc
> sql/set_var.cc
> === modified file 'mysql-test/extra/rpl_tests/check_type.inc'
> --- a/mysql-test/extra/rpl_tests/check_type.inc 2009-12-08 17:32:10 +0000
> +++ b/mysql-test/extra/rpl_tests/check_type.inc 2009-12-10 11:12:15 +0000
> @@ -6,8 +6,8 @@
> # Input:
> # $source_type Type on the master
> # $target_type Type on the slave
> -# $source_value Type on the master (inserted into the table)
> -# $target_value Type on the slave (expected value in the table
> +# $source_value Value on the master (inserted into the table)
> +# $target_value Value on the slave (expected value in the table
> # on the slave)
> # $can_convert True if conversion shall work, false if it
> # shall generate an error
>
> === modified file 'mysql-test/extra/rpl_tests/type_conversions.test'
> --- a/mysql-test/extra/rpl_tests/type_conversions.test 2009-12-08 17:32:10 +0000
> +++ b/mysql-test/extra/rpl_tests/type_conversions.test 2009-12-10 11:12:15 +0000
> @@ -119,8 +119,15 @@ source extra/rpl_tests/check_type.inc;
>
> let $source_type= SMALLINT;
> let $target_type= TINYINT;
> -let $source_value= 512;
> -let $target_value= 127;
> +let $source_value= 1 << 9;
> +let $target_value= (1 << 7) - 1;
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= SMALLINT;
> +let $target_type= TINYINT UNSIGNED;
> +let $source_value= 1 << 9;
> +let $target_value= (1 << 8) - 1;
> let $can_convert = $if_is_lossy;
> source extra/rpl_tests/check_type.inc;
>
> @@ -160,6 +167,20 @@ let $can_convert = $if_is_lossy;
> source extra/rpl_tests/check_type.inc;
>
> let $source_type= MEDIUMINT;
> +let $target_type= TINYINT;
> +let $source_value= 1 << 20;
> +let $target_value= (1 << 7) - 1;
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= MEDIUMINT;
> +let $target_type= TINYINT UNSIGNED;
> +let $source_value= 1 << 20;
> +let $target_value= (1 << 8) - 1;
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= MEDIUMINT;
> let $target_type= SMALLINT;
> let $source_value= 1;
> let $target_value= 1;
> @@ -195,6 +216,20 @@ let $can_convert = $if_is_lossy;
> source extra/rpl_tests/check_type.inc;
>
> let $source_type= INT;
> +let $target_type= TINYINT;
> +let $source_value= (1 << 30);
> +let $target_value= (1 << 7) - 1;
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= INT;
> +let $target_type= TINYINT UNSIGNED;
> +let $source_value= (1 << 30);
> +let $target_value= (1 << 8) - 1;
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= INT;
> let $target_type= SMALLINT;
> let $source_value= 1;
> let $target_value= 1;
> @@ -508,6 +543,27 @@ let $target_value= left('$blob', 255);
> let $can_convert = $if_is_lossy;
> source extra/rpl_tests/check_type.inc;
>
> +let $source_type= TINYTEXT;
> +let $target_type= TINYTEXT;
> +let $source_value= '$tiny_blob';
> +let $target_value= '$tiny_blob';
> +let $can_convert = 1;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= TINYTEXT;
> +let $target_type= TEXT;
> +let $source_value= '$tiny_blob';
> +let $target_value= '$tiny_blob';
> +let $can_convert = $if_is_non_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> +let $source_type= TEXT;
> +let $target_type= TINYTEXT;
> +let $source_value= '$blob';
> +let $target_value= left('$blob',255);
> +let $can_convert = $if_is_lossy;
> +source extra/rpl_tests/check_type.inc;
> +
> let $source_type= DECIMAL(10,5);
> let $target_type= DECIMAL(10,5);
> let $source_value= 3.14159;
>
> === modified file 'mysql-test/suite/rpl/r/rpl_row_colSize.result'
> --- a/mysql-test/suite/rpl/r/rpl_row_colSize.result 2009-12-08 17:32:10 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_colSize.result 2009-12-10 11:12:15 +0000
> @@ -365,7 +365,7 @@ Replicate_Ignore_Table #
> Replicate_Wild_Do_Table
> Replicate_Wild_Ignore_Table
> Last_Errno 1641
> -Last_Error Column 0 of table 'test.t1' cannot be converted from type 'char(2)' to
> type 'set('4')'
> +Last_Error Column 0 of table 'test.t1' cannot be converted from type 'set' to type
> 'set('4')'
> Skip_Counter 0
> Exec_Master_Log_Pos #
> Relay_Log_Space #
> @@ -383,7 +383,7 @@ Master_SSL_Verify_Server_Cert No
> Last_IO_Errno #
> Last_IO_Error #
> Last_SQL_Errno 1641
> -Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'char(2)'
> to type 'set('4')'
> +Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'set' to
> type 'set('4')'
> SELECT COUNT(*) FROM t1;
> COUNT(*)
> 0
> @@ -506,7 +506,7 @@ Replicate_Ignore_Table #
> Replicate_Wild_Do_Table
> Replicate_Wild_Ignore_Table
> Last_Errno 1641
> -Last_Error Column 0 of table 'test.t1' cannot be converted from type 'char(2)' to
> type 'enum('44','54')'
> +Last_Error Column 0 of table 'test.t1' cannot be converted from type 'enum' to type
> 'enum('44','54')'
> Skip_Counter 0
> Exec_Master_Log_Pos #
> Relay_Log_Space #
> @@ -524,7 +524,7 @@ Master_SSL_Verify_Server_Cert No
> Last_IO_Errno #
> Last_IO_Error #
> Last_SQL_Errno 1641
> -Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'char(2)'
> to type 'enum('44','54')'
> +Last_SQL_Error Column 0 of table 'test.t1' cannot be converted from type 'enum' to
> type 'enum('44','54')'
> SELECT COUNT(*) FROM t1;
> COUNT(*)
> 0
>
> === modified file 'mysql-test/suite/rpl/r/rpl_typeconv.result'
> --- a/mysql-test/suite/rpl/r/rpl_typeconv.result 2009-12-08 17:32:10 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_typeconv.result 2009-12-10 11:12:15 +0000
> @@ -85,16 +85,21 @@ TINYINT INT
> TINYINT BIGINT <Correct error>
> SMALLINT TINYINT <Correct error>
> SMALLINT TINYINT <Correct error>
> +SMALLINT TINYINT UNSIGNE <Correct error>
> SMALLINT SMALLINT <Correct value>
> SMALLINT MEDIUMINT <Correct error>
> SMALLINT INT <Correct error>
> SMALLINT BIGINT <Correct error>
> MEDIUMINT TINYINT <Correct error>
> +MEDIUMINT TINYINT <Correct error>
> +MEDIUMINT TINYINT UNSIGNE <Correct error>
> MEDIUMINT SMALLINT <Correct error>
> MEDIUMINT MEDIUMINT <Correct value>
> MEDIUMINT INT <Correct error>
> MEDIUMINT BIGINT <Correct error>
> INT TINYINT <Correct error>
> +INT TINYINT <Correct error>
> +INT TINYINT UNSIGNE <Correct error>
> INT SMALLINT <Correct error>
> INT MEDIUMINT <Correct error>
> INT INT <Correct value>
> @@ -139,6 +144,9 @@ TINYTEXT CHAR(250)
> TEXT CHAR(255) <Correct error>
> MEDIUMTEXT CHAR(255) <Correct error>
> LONGTEXT CHAR(255) <Correct error>
> +TINYTEXT TINYTEXT <Correct value>
> +TINYTEXT TEXT <Correct error>
> +TEXT TINYTEXT <Correct error>
> DECIMAL(10,5) DECIMAL(10,5) <Correct value>
> DECIMAL(10,5) DECIMAL(10,6) <Correct error>
> DECIMAL(10,5) DECIMAL(11,5) <Correct error>
> @@ -175,16 +183,21 @@ TINYINT INT ALL_NON_
> TINYINT BIGINT ALL_NON_LOSSY <Correct value>
> SMALLINT TINYINT ALL_NON_LOSSY <Correct error>
> SMALLINT TINYINT ALL_NON_LOSSY <Correct error>
> +SMALLINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
> SMALLINT SMALLINT ALL_NON_LOSSY <Correct value>
> SMALLINT MEDIUMINT ALL_NON_LOSSY <Correct value>
> SMALLINT INT ALL_NON_LOSSY <Correct value>
> SMALLINT BIGINT ALL_NON_LOSSY <Correct value>
> MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error>
> +MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error>
> +MEDIUMINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
> MEDIUMINT SMALLINT ALL_NON_LOSSY <Correct error>
> MEDIUMINT MEDIUMINT ALL_NON_LOSSY <Correct value>
> MEDIUMINT INT ALL_NON_LOSSY <Correct value>
> MEDIUMINT BIGINT ALL_NON_LOSSY <Correct value>
> INT TINYINT ALL_NON_LOSSY <Correct error>
> +INT TINYINT ALL_NON_LOSSY <Correct error>
> +INT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error>
> INT SMALLINT ALL_NON_LOSSY <Correct error>
> INT MEDIUMINT ALL_NON_LOSSY <Correct error>
> INT INT ALL_NON_LOSSY <Correct value>
> @@ -229,6 +242,9 @@ TINYTEXT CHAR(250) ALL_NON_
> TEXT CHAR(255) ALL_NON_LOSSY <Correct error>
> MEDIUMTEXT CHAR(255) ALL_NON_LOSSY <Correct error>
> LONGTEXT CHAR(255) ALL_NON_LOSSY <Correct error>
> +TINYTEXT TINYTEXT ALL_NON_LOSSY <Correct value>
> +TINYTEXT TEXT ALL_NON_LOSSY <Correct value>
> +TEXT TINYTEXT ALL_NON_LOSSY <Correct error>
> DECIMAL(10,5) DECIMAL(10,5) ALL_NON_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(10,6) ALL_NON_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(11,5) ALL_NON_LOSSY <Correct value>
> @@ -265,16 +281,21 @@ TINYINT INT ALL_LOSS
> TINYINT BIGINT ALL_LOSSY <Correct error>
> SMALLINT TINYINT ALL_LOSSY <Correct value>
> SMALLINT TINYINT ALL_LOSSY <Correct value>
> +SMALLINT TINYINT UNSIGNE ALL_LOSSY <Correct value>
> SMALLINT SMALLINT ALL_LOSSY <Correct value>
> SMALLINT MEDIUMINT ALL_LOSSY <Correct error>
> SMALLINT INT ALL_LOSSY <Correct error>
> SMALLINT BIGINT ALL_LOSSY <Correct error>
> MEDIUMINT TINYINT ALL_LOSSY <Correct value>
> +MEDIUMINT TINYINT ALL_LOSSY <Correct value>
> +MEDIUMINT TINYINT UNSIGNE ALL_LOSSY <Correct value>
> MEDIUMINT SMALLINT ALL_LOSSY <Correct value>
> MEDIUMINT MEDIUMINT ALL_LOSSY <Correct value>
> MEDIUMINT INT ALL_LOSSY <Correct error>
> MEDIUMINT BIGINT ALL_LOSSY <Correct error>
> INT TINYINT ALL_LOSSY <Correct value>
> +INT TINYINT ALL_LOSSY <Correct value>
> +INT TINYINT UNSIGNE ALL_LOSSY <Correct value>
> INT SMALLINT ALL_LOSSY <Correct value>
> INT MEDIUMINT ALL_LOSSY <Correct value>
> INT INT ALL_LOSSY <Correct value>
> @@ -319,6 +340,9 @@ TINYTEXT CHAR(250) ALL_LOSS
> TEXT CHAR(255) ALL_LOSSY <Correct value>
> MEDIUMTEXT CHAR(255) ALL_LOSSY <Correct value>
> LONGTEXT CHAR(255) ALL_LOSSY <Correct value>
> +TINYTEXT TINYTEXT ALL_LOSSY <Correct value>
> +TINYTEXT TEXT ALL_LOSSY <Correct error>
> +TEXT TINYTEXT ALL_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY <Correct error>
> DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY <Correct error>
> @@ -355,16 +379,21 @@ TINYINT INT ALL_LOSS
> TINYINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +SMALLINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> SMALLINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +MEDIUMINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +INT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> INT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> INT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> INT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> @@ -409,6 +438,9 @@ TINYTEXT CHAR(250) ALL_LOSS
> TEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> MEDIUMTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> LONGTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +TINYTEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +TINYTEXT TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> +TEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
> DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value>
>
> === modified file 'sql/mysqld.cc'
> --- a/sql/mysqld.cc 2009-12-08 17:32:10 +0000
> +++ b/sql/mysqld.cc 2009-12-10 11:12:15 +0000
> @@ -6417,9 +6417,11 @@ replicating a LOAD DATA INFILE command."
> "Modes for how replication events should be executed. Legal values are STRICT
> (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations
> that are idempotent. In STRICT mode, replication will stop on any unexpected difference
> between the master and the slave.",
> (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0,
> GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
> {"slave-type-conversions", OPT_SLAVE_TYPE_CONVERSIONS,
> - "Slave type conversions that are enabled. Legal values are"
> + "Set of slave type conversions that are enabled. Legal values are:"
> " ALL_LOSSY to enable lossy conversions and"
> - " ALL_NON_LOSSY to enable non-lossy conversions.",
> + " ALL_NON_LOSSY to enable non-lossy conversions."
> + " If the variable is assigned the empty set, no conversions are"
> + " allowed and it is expected that the types match exactly.",
> (uchar**) &slave_type_conversions_default,
> (uchar**) &slave_type_conversions_default,
> 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
>
> === modified file 'sql/rpl_utility.cc'
> --- a/sql/rpl_utility.cc 2009-12-08 17:32:10 +0000
> +++ b/sql/rpl_utility.cc 2009-12-10 11:12:15 +0000
> @@ -40,7 +40,7 @@ namespace {
> The somewhat contorted expression is to avoid overflow.
> */
> uint32 uint_max(int bits) {
> - return ((1UL << (bits - 1)) - 1) << 1 | 1;
> + return (((1UL << (bits - 1)) - 1) << 1) | 1;
> }
>
>
> @@ -127,6 +127,8 @@ max_display_length_for_field(enum_field_
> DBUG_ASSERT(from_bit_len <= 7);
> return 8 * from_len + from_bit_len;
> }
> +
> + case MYSQL_TYPE_VAR_STRING:
> case MYSQL_TYPE_VARCHAR:
> return metadata;
>
> @@ -177,7 +179,7 @@ max_display_length_for_field(enum_field_
> */
> int compare_lengths(Field *field, enum_field_types source_type, uint16 metadata)
> {
> - DBUG_ENTER(__FUNCTION__);
> + 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();
> @@ -348,7 +350,7 @@ uint32 table_def::calc_field_size(uint c
> */
> void show_sql_type(enum_field_types type, uint16 metadata, String *str)
> {
> - DBUG_ENTER(__FUNCTION__);
> + DBUG_ENTER("show_sql_type");
> DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata));
>
> switch (type)
> @@ -406,6 +408,7 @@ void show_sql_type(enum_field_types type
> str->set_ascii(STRING_WITH_LEN("year"));
> break;
>
> + case MYSQL_TYPE_VAR_STRING:
> case MYSQL_TYPE_VARCHAR:
> {
> CHARSET_INFO *cs= str->charset();
> @@ -427,6 +430,16 @@ void show_sql_type(enum_field_types type
> }
> break;
>
> + case MYSQL_TYPE_DECIMAL:
> + {
> + CHARSET_INFO *cs= str->charset();
> + uint32 length=
> + cs->cset->snprintf(cs, (char*) str->ptr(),
> str->alloced_length(),
> + "decimal(%d,?)", metadata);
> + str->length(length);
> + }
> + break;
> +
> case MYSQL_TYPE_NEWDECIMAL:
> {
> CHARSET_INFO *cs= str->charset();
> @@ -493,10 +506,6 @@ void show_sql_type(enum_field_types type
> str->set_ascii(STRING_WITH_LEN("geometry"));
> break;
>
> - case MYSQL_TYPE_DECIMAL:
> - case MYSQL_TYPE_VAR_STRING:
> - DBUG_ASSERT(0);
> -
> default:
> str->set_ascii(STRING_WITH_LEN("<unknown type>"));
> }
> @@ -510,7 +519,7 @@ void show_sql_type(enum_field_types type
> */
> bool is_conversion_ok(int order, Relay_log_info *rli)
> {
> - DBUG_ENTER(__FUNCTION__);
> + DBUG_ENTER("is_conversion_ok");
> bool allow_non_lossy=
> bit_is_set(slave_type_conversions_options,
> SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY);
> bool allow_lossy=
> @@ -566,10 +575,11 @@ bool is_conversion_ok(int order, Relay_l
> current setting.
> */
> static bool
> -can_convert_field_to(Field *field, enum_field_types source_type, uint16 metadata,
> +can_convert_field_to(Field *field,
> + enum_field_types source_type, uint16 metadata,
> Relay_log_info *rli, int *order_var)
> {
> - DBUG_ENTER(__FUNCTION__);
> + DBUG_ENTER("can_convert_field_to");
> #ifndef DBUG_OFF
> char field_type_buf[MAX_FIELD_WIDTH];
> String field_type(field_type_buf, sizeof(field_type_buf), field->charset());
> @@ -584,11 +594,13 @@ can_convert_field_to(Field *field, enum_
> if (field->real_type() == source_type)
> {
> DBUG_PRINT("debug", ("Base types are identical, doing field size comparison"));
> - if (const_cast<Field*>(field)->compatible_field_size(metadata, rli,
> order_var))
> + if (field->compatible_field_size(metadata, rli, order_var))
> DBUG_RETURN(is_conversion_ok(*order_var, rli));
> else
> DBUG_RETURN(false);
> }
> + else if (!slave_type_conversions_options)
> + DBUG_RETURN(false);
>
> /*
> Here, from and to will always be different. Since the types are
> @@ -599,6 +611,7 @@ can_convert_field_to(Field *field, enum_
> 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:
> @@ -606,16 +619,18 @@ can_convert_field_to(Field *field, enum_
> {
> case MYSQL_TYPE_NEWDECIMAL:
> /*
> - Then the other type is either FLOAT or DOUBLE, so we require
> - lossy conversion.
> + 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)
> + 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);
> @@ -663,7 +678,7 @@ can_convert_field_to(Field *field, enum_
> /*
> 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 replication, we cannot
> + the charset, and the charset is not replicated, we cannot
> currently distinguish between , e.g., TEXT and BLOB.
> */
> case MYSQL_TYPE_TINY_BLOB:
> @@ -671,6 +686,7 @@ can_convert_field_to(Field *field, enum_
> case MYSQL_TYPE_LONG_BLOB:
> case MYSQL_TYPE_BLOB:
> case MYSQL_TYPE_STRING:
> + case MYSQL_TYPE_VAR_STRING:
> case MYSQL_TYPE_VARCHAR:
> switch (field->real_type())
> {
> @@ -679,6 +695,7 @@ can_convert_field_to(Field *field, enum_
> case MYSQL_TYPE_LONG_BLOB:
> case MYSQL_TYPE_BLOB:
> case MYSQL_TYPE_STRING:
> + case MYSQL_TYPE_VAR_STRING:
> case MYSQL_TYPE_VARCHAR:
> *order_var= compare_lengths(field, source_type, metadata);
> /*
> @@ -707,14 +724,6 @@ can_convert_field_to(Field *field, enum_
> case MYSQL_TYPE_ENUM:
> case MYSQL_TYPE_SET:
> DBUG_RETURN(false);
> -
> - /*
> - The types MYSQL_TYPE_DECIMAL and MYSQL_TYPE_VAR_STRING should not
> - appear inside the server at all.
> - */
> - case MYSQL_TYPE_DECIMAL:
> - case MYSQL_TYPE_VAR_STRING:
> - DBUG_ASSERT(0);
> }
> DBUG_RETURN(false); // To keep GCC happy
> }
> @@ -883,12 +892,18 @@ TABLE *table_def::create_conversion_tabl
> length that should be supplied to make_field, so we correct
> the length here.
> */
> - precision = field_metadata(col) >> 8;
> + precision= field_metadata(col) >> 8;
> decimals= field_metadata(col) & 0x00ff;
> max_length=
> my_decimal_precision_to_length(precision, decimals, FALSE);
> break;
>
> + case MYSQL_TYPE_DECIMAL:
> + precision= field_metadata(col);
> + decimals= static_cast<Field_num*>(target_table->field[col])->dec;
> + max_length= field_metadata(col);
> + break;
> +
> case MYSQL_TYPE_TINY_BLOB:
> case MYSQL_TYPE_MEDIUM_BLOB:
> case MYSQL_TYPE_LONG_BLOB:
> @@ -908,7 +923,7 @@ TABLE *table_def::create_conversion_tabl
> field_def->init_for_tmp_table(type(col),
> max_length,
> decimals,
> - TRUE, // maybe_null
> + maybe_null(col), // maybe_null
> FALSE, // unsigned_flag
> pack_length);
> field_def->charset= target_table->field[col]->charset();
>
> === modified file 'sql/set_var.cc'
> --- a/sql/set_var.cc 2009-12-04 10:53:15 +0000
> +++ b/sql/set_var.cc 2009-12-10 11:12:15 +0000
> @@ -106,7 +106,7 @@ const char *slave_type_conversions_type_
> NullS
> };
>
> -size_t slave_type_conversions_type_length[]= {
> +unsigned int slave_type_conversions_type_length[]= {
> sizeof("ALL_LOSSY")-1,
> sizeof("ALL_NON_LOSSY")-1,
> 0