diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-01-11 17:20:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2016-01-11 17:20:16 +0400 |
commit | 454589b67f9609a78f00e521fe2ef0994eed4f3f (patch) | |
tree | 1d17569e30a61865cc6af35e025fb4e03952efbf | |
parent | 250ab81200bf62d02c25144e3da38f7a9d3ced19 (diff) | |
download | mariadb-git-454589b67f9609a78f00e521fe2ef0994eed4f3f.tar.gz |
MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field
Also fixes:
MDEV-9391 InnoDB does not produce warnings when doing WHERE int_column=varchar_column
MDEV-9337 ALTER from DECIMAL and INT to DATETIME returns a wrong result
MDEV-9340 Copying from INT/DOUBLE to ENUM is inconsistent
MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings
-rw-r--r-- | mysql-test/r/join_cache.result | 3 | ||||
-rw-r--r-- | mysql-test/r/subselect_sj2.result | 2 | ||||
-rw-r--r-- | mysql-test/r/subselect_sj2_jcl6.result | 2 | ||||
-rw-r--r-- | mysql-test/r/subselect_sj2_mat.result | 2 | ||||
-rw-r--r-- | mysql-test/r/type_datetime.result | 51 | ||||
-rw-r--r-- | mysql-test/r/type_enum.result | 81 | ||||
-rw-r--r-- | mysql-test/r/type_int.result | 57 | ||||
-rw-r--r-- | mysql-test/r/type_num_innodb.result | 107 | ||||
-rw-r--r-- | mysql-test/r/type_time.result | 29 | ||||
-rw-r--r-- | mysql-test/r/type_year.result | 45 | ||||
-rw-r--r-- | mysql-test/t/type_datetime.test | 48 | ||||
-rw-r--r-- | mysql-test/t/type_enum.test | 62 | ||||
-rw-r--r-- | mysql-test/t/type_int.test | 50 | ||||
-rw-r--r-- | mysql-test/t/type_num_innodb.test | 41 | ||||
-rw-r--r-- | mysql-test/t/type_time.test | 22 | ||||
-rw-r--r-- | mysql-test/t/type_year.test | 42 | ||||
-rw-r--r-- | sql/field.h | 110 | ||||
-rw-r--r-- | sql/field_conv.cc | 201 |
18 files changed, 828 insertions, 127 deletions
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 90d305fb384..d816b1acf92 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -4691,6 +4691,9 @@ FROM t1 LEFT JOIN (t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c; a +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'h' +Warning 1292 Truncated incorrect INTEGER value: 'j' SET SESSION optimizer_switch = 'outer_join_with_cache=off'; SET SESSION join_cache_level = DEFAULT; DROP TABLE t1,t2,t3; diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 21d97b3faea..98a8907f741 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -937,6 +937,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index eb91fe6d61b..1b8c1fc1158 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -952,6 +952,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 16e8f88168d..ac38e57d60a 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -939,6 +939,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 155e9535a0a..d0cd2c97510 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -1141,3 +1141,54 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9337 ALTER from DECIMAL and INT to DATETIME returns a wrong result +# +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000); +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000.0); +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a DECIMAL(4,0)); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(4,0)); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index d901434fd6e..f0152d08c32 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -2134,3 +2134,84 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# MDEV-9340 Copying from INT/DOUBLE to ENUM is inconsistent +# +CREATE TABLE t1 (a ENUM('9e200','9e100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('9e100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (9e100); +ALTER TABLE t1 MODIFY a ENUM('9e200','9e100'); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '9e100' +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES ('200'); +ALTER TABLE t1 MODIFY a ENUM('200','100'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT *FROM t1; +a + +DROP TABLE t1; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a ENUM('2001','2002')); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES ('2001'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES ('2001'); +ALTER TABLE t1 MODIFY a ENUM('2001','2002'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1; diff --git a/mysql-test/r/type_int.result b/mysql-test/r/type_int.result index 4e7b928ac07..530a4134f4a 100644 --- a/mysql-test/r/type_int.result +++ b/mysql-test/r/type_int.result @@ -36,3 +36,60 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10.1),(10.9); +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a DECIMAL(10,2)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(10,2)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (TIME'00:00:10.1'),(TIME'00:00:10.9'); +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a TIME(1)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1,t2; +CREATE TABLE t1 (a TIME(1)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_num_innodb.result b/mysql-test/r/type_num_innodb.result new file mode 100644 index 00000000000..581a387b2e8 --- /dev/null +++ b/mysql-test/r/type_num_innodb.result @@ -0,0 +1,107 @@ +# +# Start of 10.2 tests +# +# +# MDEV-9391 InnoDB does not produce warnings when doing WHERE int_column=varchar_column +# +CREATE TABLE t1 ( +a DOUBLE, b VARCHAR(1), c INT, +KEY(a), KEY(b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5), +(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9), +(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), +(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); +CREATE TABLE t2 ( +pk INT, d VARCHAR(1), e INT, +PRIMARY KEY(pk), KEY(d,e) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), +(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), +(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), +(15,'g',6),(16,'x',7),(17,'f',8); +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'k' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'q' +Warning 1292 Truncated incorrect DOUBLE value: 'r' +Warning 1292 Truncated incorrect DOUBLE value: 'u' +Warning 1292 Truncated incorrect DOUBLE value: 'w' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'y' +ALTER TABLE t1 MODIFY a DECIMAL(10,0); +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'k' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'o' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'q' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'r' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'u' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'w' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'y' +ALTER TABLE t1 MODIFY a DOUBLE; +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'k' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'q' +Warning 1292 Truncated incorrect DOUBLE value: 'r' +Warning 1292 Truncated incorrect DOUBLE value: 'u' +Warning 1292 Truncated incorrect DOUBLE value: 'w' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'y' +DROP TABLE t1,t2; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index bdcffc8d824..e4347509d5e 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1217,3 +1217,32 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +# +CREATE TABLE t1 (a YEAR, b TIME, c YEAR); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES (0),(1999),(2000),(2030),(2050),(2070); +INSERT INTO t1 (a,b,c) SELECT a,a,a FROM t2; +Warnings: +Warning 1265 Data truncated for column 'b' at row 2 +Warning 1265 Data truncated for column 'b' at row 6 +ALTER TABLE t1 MODIFY c TIME; +Warnings: +Warning 1265 Data truncated for column 'c' at row 2 +Warning 1265 Data truncated for column 'c' at row 6 +SELECT * FROM t1; +a b c +0000 00:00:00 00:00:00 +1999 00:00:00 00:00:00 +2000 00:20:00 00:20:00 +2030 00:20:30 00:20:30 +2050 00:20:50 00:20:50 +2070 00:00:00 00:00:00 +DROP TABLE t1,t2; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 842a16e3b4a..4d28a7b8d25 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -438,3 +438,48 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings +# +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DECIMAL(10,1)); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1e0); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 444ab02d223..7c9d56a0780 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -695,3 +695,51 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9337 ALTER from DECIMAL and INT to DATETIME returns a wrong result +--echo # +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000.0); +SELECT * FROM t1; +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a DECIMAL(4,0)); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(4,0)); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 314cb237dd3..63e9e9e7b09 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -388,3 +388,65 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + + +--echo # +--echo # MDEV-9340 Copying from INT/DOUBLE to ENUM is inconsistent +--echo # + +# DOUBLE -> ENUM +CREATE TABLE t1 (a ENUM('9e200','9e100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('9e100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (9e100); +ALTER TABLE t1 MODIFY a ENUM('9e200','9e100'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +# INT -> ENUM +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES ('200'); +ALTER TABLE t1 MODIFY a ENUM('200','100'); +SELECT *FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + + +# YEAR -> ENUM +CREATE TABLE t1 (a ENUM('2001','2002')); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES ('2001'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES ('2001'); +ALTER TABLE t1 MODIFY a ENUM('2001','2002'); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/type_int.test b/mysql-test/t/type_int.test index e8b9b2cffcd..271b4d5862a 100644 --- a/mysql-test/t/type_int.test +++ b/mysql-test/t/type_int.test @@ -26,3 +26,53 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +--echo # + +# DECIMAL -> INT +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10.1),(10.9); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a DECIMAL(10,2)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(10,2)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +DROP TABLE t1; + +# TIME -> INT +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (TIME'00:00:10.1'),(TIME'00:00:10.9'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a TIME(1)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a TIME(1)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_num_innodb.test b/mysql-test/t/type_num_innodb.test new file mode 100644 index 00000000000..04bdd4c63b0 --- /dev/null +++ b/mysql-test/t/type_num_innodb.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9391 InnoDB does not produce warnings when doing WHERE int_column=varchar_column +--echo # + +CREATE TABLE t1 ( + a DOUBLE, b VARCHAR(1), c INT, + KEY(a), KEY(b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5), +(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9), +(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), +(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); +CREATE TABLE t2 ( + pk INT, d VARCHAR(1), e INT, + PRIMARY KEY(pk), KEY(d,e) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), +(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), +(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), +(15,'g',6),(16,'x',7),(17,'f',8); +SELECT * FROM t1,t2 WHERE a=d; + +ALTER TABLE t1 MODIFY a DECIMAL(10,0); +SELECT * FROM t1,t2 WHERE a=d; + +ALTER TABLE t1 MODIFY a DOUBLE; +SELECT * FROM t1,t2 WHERE a=d; + +DROP TABLE t1,t2; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 27679b9ec5a..c4b93d6dbb2 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -726,3 +726,25 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + + +--echo # +--echo # MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +--echo # + +CREATE TABLE t1 (a YEAR, b TIME, c YEAR); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES (0),(1999),(2000),(2030),(2050),(2070); +INSERT INTO t1 (a,b,c) SELECT a,a,a FROM t2; +ALTER TABLE t1 MODIFY c TIME; +SELECT * FROM t1; +DROP TABLE t1,t2; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index d9fa2af1eb4..22f164a757c 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -210,3 +210,45 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings +--echo # +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1); +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DECIMAL(10,1)); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1e0); +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/field.h b/sql/field.h index 7daf7da01cb..435ea20825a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -33,6 +33,7 @@ #include "compat56.h" class Send_field; +class Copy_field; class Protocol; class Create_field; class Relay_log_info; @@ -621,6 +622,11 @@ protected: val_str(&result); return to->store(result.ptr(), result.length(), charset()); } + static void do_field_int(Copy_field *copy); + static void do_field_real(Copy_field *copy); + static void do_field_string(Copy_field *copy); + static void do_field_temporal(Copy_field *copy); + static void do_field_decimal(Copy_field *copy); public: static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } @@ -733,6 +739,12 @@ public: uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg); virtual ~Field() {} + /** + Convenience definition of a copy function returned by + Field::get_copy_func() + */ + typedef void Copy_func(Copy_field*); + virtual Copy_func *get_copy_func(const Field *from) const= 0; /* Store functions returns 1 on overflow and -1 on fatal error */ virtual int store_field(Field *from) { return from->save_in_field(this); } virtual int save_in_field(Field *to)= 0; @@ -1265,6 +1277,7 @@ protected: return (op_result == E_DEC_OVERFLOW); } int warn_if_overflow(int op_result); + Copy_func *get_identical_copy_func() const; public: void set_table_name(String *alias) { @@ -1528,6 +1541,10 @@ public: uint decimals() const { return (uint) dec; } uint size_of() const { return sizeof(*this); } bool eq_def(const Field *field) const; + Copy_func *get_copy_func(const Field *from) const + { + return do_field_int; + } int save_in_field(Field *to) { return to->store(val_int(), MY_TEST(flags & UNSIGNED_FLAG)); @@ -1678,6 +1695,10 @@ public: not_fixed(dec_arg >= NOT_FIXED_DEC) {} Item_result result_type () const { return REAL_RESULT; } + Copy_func *get_copy_func(const Field *from) const + { + return do_field_real; + } int save_in_field(Field *to) { return to->store(val_real()); } int store_decimal(const my_decimal *); int store_time_dec(MYSQL_TIME *ltime, uint dec); @@ -1703,6 +1724,10 @@ public: enum_field_types type() const { return MYSQL_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } + Copy_func *get_copy_func(const Field *from) const + { + return eq_def(from) ? get_identical_copy_func() : do_field_string; + } int reset(void); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); @@ -1746,6 +1771,12 @@ public: enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } Item_result result_type () const { return DECIMAL_RESULT; } + Copy_func *get_copy_func(const Field *from) const + { + // if (from->real_type() == MYSQL_TYPE_BIT) // QQ: why? + // return do_field_int; + return do_field_decimal; + } int save_in_field(Field *to) { my_decimal buff; @@ -2092,6 +2123,10 @@ public: unireg_check_arg, field_name_arg, cs) {} enum_field_types type() const { return MYSQL_TYPE_NULL;} + Copy_func *get_copy_func(const Field *from) const + { + return do_field_string; + } int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; } @@ -2142,6 +2177,7 @@ public: { return store(str, length, &my_charset_bin); } + Copy_func *get_copy_func(const Field *from) const; int save_in_field(Field *to) { MYSQL_TIME ltime; @@ -2413,6 +2449,28 @@ public: unireg_check_arg, field_name_arg, 1, 1) {} enum_field_types type() const { return MYSQL_TYPE_YEAR;} + Copy_func *get_copy_func(const Field *from) const + { + if (eq_def(from)) + return get_identical_copy_func(); + switch (from->cmp_type()) { + case STRING_RESULT: + return do_field_string; + case TIME_RESULT: + return do_field_temporal; + case DECIMAL_RESULT: + return do_field_decimal; + case REAL_RESULT: + return do_field_real; + case INT_RESULT: + break; + case ROW_RESULT: + default: + DBUG_ASSERT(0); + break; + } + return do_field_int; + } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -2502,6 +2560,7 @@ protected: int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str, int was_cut, int have_smth_to_conv); bool check_zero_in_date_with_warn(ulonglong fuzzydate); + static void do_field_time(Copy_field *copy); public: Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, @@ -2511,6 +2570,14 @@ public: {} enum_field_types type() const { return MYSQL_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } + Copy_func *get_copy_func(const Field *from) const + { + return from->cmp_type() == REAL_RESULT ? do_field_string : // MDEV-9344 + from->type() == MYSQL_TYPE_YEAR ? do_field_int : + from->type() == MYSQL_TYPE_BIT ? do_field_int : + eq_def(from) ? get_identical_copy_func() : + do_field_time; + } bool memcpy_field_possible(const Field *from) const { return real_type() == from->real_type() && @@ -2884,6 +2951,7 @@ public: enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } bool zero_pack() const { return 0; } + Copy_func *get_copy_func(const Field *from) const; int reset(void) { charset()->cset->fill(charset(),(char*) ptr, field_length, @@ -2980,6 +3048,7 @@ public: return (uint32) field_length + (field_charset == &my_charset_bin ? length_bytes : 0); } + Copy_func *get_copy_func(const Field *from) const; bool memcpy_field_possible(const Field *from) const { return Field_str::memcpy_field_possible(from) && @@ -3037,7 +3106,9 @@ protected: The 'value'-object is a cache fronting the storage engine. */ String value; - + + static void do_copy_blob(Copy_field *copy); + static void do_conv_blob(Copy_field *copy); public: Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, @@ -3072,6 +3143,19 @@ public: enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } + Copy_func *get_copy_func(const Field *from) const + { + /* + TODO: MDEV-9331 + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + */ + if (!(from->flags & BLOB_FLAG) || from->charset() != charset()) + return do_conv_blob; + if (from->pack_length() != Field_blob::pack_length()) + return do_copy_blob; + return get_identical_copy_func(); + } int store_field(Field *from) { // Be sure the value is stored from->val_str(&value); @@ -3258,6 +3342,7 @@ uint gis_field_options_read(const uchar *buf, uint buf_len, class Field_enum :public Field_str { + static void do_field_enum(Copy_field *copy_field); protected: uint packlength; public: @@ -3278,6 +3363,17 @@ public: enum_field_types type() const { return MYSQL_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; + Copy_func *get_copy_func(const Field *from) const + { + if (eq_def(from)) + return get_identical_copy_func(); + if (real_type() == MYSQL_TYPE_ENUM && + from->real_type() == MYSQL_TYPE_ENUM) + return do_field_enum; + if (from->result_type() == STRING_RESULT) + return do_field_string; + return do_field_int; + } int store_field(Field *from) { if (from->real_type() == MYSQL_TYPE_ENUM && from->val_int() == 0) @@ -3409,6 +3505,10 @@ public: clr_rec_bits(bit_ptr, bit_ofs, bit_len); return 0; } + Copy_func *get_copy_func(const Field *from) const + { + return do_field_int; + } int save_in_field(Field *to) { return to->store(val_int(), true); } bool memcpy_field_possible(const Field *from) const { return false; } int store(const char *to, uint length, CHARSET_INFO *charset); @@ -3702,12 +3802,6 @@ class Send_field :public Sql_alloc { */ class Copy_field :public Sql_alloc { - /** - Convenience definition of a copy function returned by - get_copy_func. - */ - typedef void Copy_func(Copy_field*); - Copy_func *get_copy_func(const Field *to, const Field *from); public: uchar *from_ptr,*to_ptr; uchar *from_null_ptr,*to_null_ptr; @@ -3728,7 +3822,7 @@ public: Note that for VARCHARs, do_copy() will be do_varstring*() which only copies the length-bytes (1 or 2) + the actual length of the - text instead of from/to_length bytes. @see get_copy_func() + text instead of from/to_length bytes. */ uint from_length,to_length; Field *from_field,*to_field; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 21f46bbbedb..ecad05c7530 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -335,12 +335,12 @@ static void do_copy_next_number(Copy_field *copy) } -static void do_copy_blob(Copy_field *copy) +void Field_blob::do_copy_blob(Copy_field *copy) { ((Field_blob*) copy->to_field)->copy_value(((Field_blob*) copy->from_field)); } -static void do_conv_blob(Copy_field *copy) +void Field_blob::do_conv_blob(Copy_field *copy) { copy->from_field->val_str(©->tmp); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), @@ -362,7 +362,7 @@ static void do_save_blob(Copy_field *copy) } -static void do_field_string(Copy_field *copy) +void Field::do_field_string(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; String res(buff, sizeof(buff), copy->from_field->charset()); @@ -373,7 +373,7 @@ static void do_field_string(Copy_field *copy) } -static void do_field_enum(Copy_field *copy) +void Field_enum::do_field_enum(Copy_field *copy) { if (copy->from_field->val_int() == 0) ((Field_enum *) copy->to_field)->store_type((ulonglong) 0); @@ -397,32 +397,45 @@ static void do_field_varbinary_pre50(Copy_field *copy) } -static void do_field_int(Copy_field *copy) +void Field::do_field_int(Copy_field *copy) { longlong value= copy->from_field->val_int(); copy->to_field->store(value, MY_TEST(copy->from_field->flags & UNSIGNED_FLAG)); } -static void do_field_real(Copy_field *copy) +void Field::do_field_real(Copy_field *copy) { double value=copy->from_field->val_real(); copy->to_field->store(value); } -static void do_field_decimal(Copy_field *copy) +void Field::do_field_decimal(Copy_field *copy) { my_decimal value; copy->to_field->store_decimal(copy->from_field->val_decimal(&value)); } -static void do_field_temporal(Copy_field *copy) +void Field::do_field_temporal(Copy_field *copy) { MYSQL_TIME ltime; - copy->from_field->get_date(<ime, 0); - copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); + // TODO: we now need to check result + if (copy->from_field->get_date(<ime, 0)) + copy->to_field->reset(); + else + copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); +} + + +void Field_time::do_field_time(Copy_field *copy) +{ + MYSQL_TIME ltime; + if (copy->from_field->get_date(<ime, TIME_TIME_ONLY)) + copy->to_field->reset(); + else + copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); } @@ -698,122 +711,72 @@ void Copy_field::set(Field *to,Field *from,bool save) if ((to->flags & BLOB_FLAG) && save) do_copy2= do_save_blob; else - do_copy2= get_copy_func(to,from); + do_copy2= to->get_copy_func(from); if (!do_copy) // Not null do_copy=do_copy2; } -Copy_field::Copy_func * -Copy_field::get_copy_func(const Field *to, const Field *from) +Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const +{ + /* If types are not 100 % identical then convert trough get_date() */ + if (from->cmp_type() == REAL_RESULT) + return do_field_string; // TODO: MDEV-9344 + if (from->type() == MYSQL_TYPE_YEAR) + return do_field_string; // TODO: MDEV-9343 + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + if (!eq_def(from) || + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))) + return do_field_temporal; + return get_identical_copy_func(); +} + + +Field::Copy_func *Field_varstring::get_copy_func(const Field *from) const +{ + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + /* + Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and + use special copy function that removes trailing spaces and thus + repairs data. + */ + if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && + !Field_varstring::has_charset()) + return do_field_varbinary_pre50; + if (Field_varstring::real_type() != from->real_type() || + Field_varstring::charset() != from->charset() || + length_bytes != ((const Field_varstring*) from)->length_bytes) + return do_field_string; + return length_bytes == 1 ? + (from->charset()->mbmaxlen == 1 ? do_varstring1 : do_varstring1_mb) : + (from->charset()->mbmaxlen == 1 ? do_varstring2 : do_varstring2_mb); +} + + +Field::Copy_func *Field_string::get_copy_func(const Field *from) const +{ + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + if (Field_string::real_type() != from->real_type() || + Field_string::charset() != from->charset()) + return do_field_string; + if (Field_string::pack_length() < from->pack_length()) + return (Field_string::charset()->mbmaxlen == 1 ? + do_cut_string : do_cut_string_complex); + if (Field_string::pack_length() > from->pack_length()) + return Field_string::charset() == &my_charset_bin ? do_expand_binary : + do_expand_string; + return get_identical_copy_func(); +} + + +Field::Copy_func *Field::get_identical_copy_func() const { - if (to->flags & BLOB_FLAG) - { - if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) - return do_conv_blob; - if (from_length != to_length) - return do_copy_blob; - } - else - { - if (to->real_type() == MYSQL_TYPE_BIT || - from->real_type() == MYSQL_TYPE_BIT) - return do_field_int; - if (to->result_type() == DECIMAL_RESULT) - return do_field_decimal; - if (from->cmp_type() == TIME_RESULT) - { - /* If types are not 100 % identical then convert trough get_date() */ - if (!to->eq_def(from) || - ((to->table->in_use->variables.sql_mode & - (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) && - mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME)) - return do_field_temporal; - /* Do binary copy */ - } - // Check if identical fields - if (from->result_type() == STRING_RESULT) - { - /* - Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and - use special copy function that removes trailing spaces and thus - repairs data. - */ - if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && - to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset()) - return do_field_varbinary_pre50; - - if (to->real_type() != from->real_type()) - { - if (from->real_type() == MYSQL_TYPE_ENUM || - from->real_type() == MYSQL_TYPE_SET) - if (to->result_type() != STRING_RESULT) - return do_field_int; // Convert SET to number - return do_field_string; - } - if (to->real_type() == MYSQL_TYPE_ENUM || - to->real_type() == MYSQL_TYPE_SET) - { - if (!to->eq_def(from)) - { - if (from->real_type() == MYSQL_TYPE_ENUM && - to->real_type() == MYSQL_TYPE_ENUM) - return do_field_enum; - return do_field_string; - } - } - else if (to->charset() != from->charset()) - return do_field_string; - else if (to->real_type() == MYSQL_TYPE_VARCHAR) - { - if (((Field_varstring*) to)->length_bytes != - ((Field_varstring*) from)->length_bytes) - return do_field_string; - return (((Field_varstring*) to)->length_bytes == 1 ? - (from->charset()->mbmaxlen == 1 ? do_varstring1 : - do_varstring1_mb) : - (from->charset()->mbmaxlen == 1 ? do_varstring2 : - do_varstring2_mb)); - } - else if (to_length < from_length) - return (from->charset()->mbmaxlen == 1 ? - do_cut_string : do_cut_string_complex); - else if (to_length > from_length) - { - if (to->charset() == &my_charset_bin) - return do_expand_binary; - return do_expand_string; - } - } - else if (to->real_type() != from->real_type() || - to_length != from_length) - { - if ((to->real_type() == MYSQL_TYPE_ENUM || - to->real_type() == MYSQL_TYPE_SET) && - from->real_type() == MYSQL_TYPE_NEWDECIMAL) - return do_field_decimal; - if (to->real_type() == MYSQL_TYPE_DECIMAL || - to->result_type() == STRING_RESULT) - return do_field_string; - if (to->result_type() == INT_RESULT) - return do_field_int; - return do_field_real; - } - else - { - if (!to->eq_def(from)) - { - if (to->real_type() == MYSQL_TYPE_DECIMAL) - return do_field_string; - if (to->result_type() == INT_RESULT) - return do_field_int; - else - return do_field_real; - } - } - } /* Identical field types */ - switch (to_length) { + switch (pack_length()) { case 1: return do_field_1; case 2: return do_field_2; case 3: return do_field_3; |