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
This commit is contained in:
Alexander Barkov 2016-01-11 17:20:16 +04:00
parent 250ab81200
commit 454589b67f
18 changed files with 827 additions and 126 deletions

View File

@ -4691,6 +4691,9 @@ FROM t1 LEFT JOIN
(t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b (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; WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c;
a 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 optimizer_switch = 'outer_join_with_cache=off';
SET SESSION join_cache_level = DEFAULT; SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;

View File

@ -937,6 +937,8 @@ SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' ) WHERE a = d AND ( pk < 2 OR d = 'z' )
); );
a b c a b c
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'x'
DROP TABLE t1, t2; DROP TABLE t1, t2;
# #
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view

View File

@ -952,6 +952,8 @@ SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' ) WHERE a = d AND ( pk < 2 OR d = 'z' )
); );
a b c a b c
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'x'
DROP TABLE t1, t2; DROP TABLE t1, t2;
# #
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view

View File

@ -939,6 +939,8 @@ SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' ) WHERE a = d AND ( pk < 2 OR d = 'z' )
); );
a b c a b c
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'x'
DROP TABLE t1, t2; DROP TABLE t1, t2;
# #
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view

View File

@ -1141,3 +1141,54 @@ DROP TABLE t1;
# #
# End of 10.1 tests # 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
#

View File

@ -2134,3 +2134,84 @@ DROP TABLE t1;
# #
# End of 10.1 tests # 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;

View File

@ -36,3 +36,60 @@ DROP TABLE t1;
# #
# End of 10.1 tests # 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
#

View File

@ -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
#

View File

@ -1217,3 +1217,32 @@ DROP TABLE t1;
# #
# End of 10.1 tests # 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
#

View File

@ -438,3 +438,48 @@ DROP TABLE t1;
# #
# End of 10.1 tests # 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
#

View File

@ -695,3 +695,51 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --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 #

View File

@ -388,3 +388,65 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --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;

View File

@ -26,3 +26,53 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --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 #

View File

@ -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 #

View File

@ -726,3 +726,25 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --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 #

View File

@ -210,3 +210,45 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --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 #

View File

@ -33,6 +33,7 @@
#include "compat56.h" #include "compat56.h"
class Send_field; class Send_field;
class Copy_field;
class Protocol; class Protocol;
class Create_field; class Create_field;
class Relay_log_info; class Relay_log_info;
@ -621,6 +622,11 @@ protected:
val_str(&result); val_str(&result);
return to->store(result.ptr(), result.length(), charset()); 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: public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw () static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); } { return alloc_root(mem_root, size); }
@ -733,6 +739,12 @@ public:
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg); const char *field_name_arg);
virtual ~Field() {} 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 */ /* 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 store_field(Field *from) { return from->save_in_field(this); }
virtual int save_in_field(Field *to)= 0; virtual int save_in_field(Field *to)= 0;
@ -1265,6 +1277,7 @@ protected:
return (op_result == E_DEC_OVERFLOW); return (op_result == E_DEC_OVERFLOW);
} }
int warn_if_overflow(int op_result); int warn_if_overflow(int op_result);
Copy_func *get_identical_copy_func() const;
public: public:
void set_table_name(String *alias) void set_table_name(String *alias)
{ {
@ -1528,6 +1541,10 @@ public:
uint decimals() const { return (uint) dec; } uint decimals() const { return (uint) dec; }
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
bool eq_def(const Field *field) const; 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) int save_in_field(Field *to)
{ {
return to->store(val_int(), MY_TEST(flags & UNSIGNED_FLAG)); return to->store(val_int(), MY_TEST(flags & UNSIGNED_FLAG));
@ -1678,6 +1695,10 @@ public:
not_fixed(dec_arg >= NOT_FIXED_DEC) not_fixed(dec_arg >= NOT_FIXED_DEC)
{} {}
Item_result result_type () const { return REAL_RESULT; } 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 save_in_field(Field *to) { return to->store(val_real()); }
int store_decimal(const my_decimal *); int store_decimal(const my_decimal *);
int store_time_dec(MYSQL_TIME *ltime, uint dec); int store_time_dec(MYSQL_TIME *ltime, uint dec);
@ -1703,6 +1724,10 @@ public:
enum_field_types type() const { return MYSQL_TYPE_DECIMAL;} enum_field_types type() const { return MYSQL_TYPE_DECIMAL;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } { 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 reset(void);
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
@ -1746,6 +1771,12 @@ public:
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
Item_result result_type () const { return DECIMAL_RESULT; } 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) int save_in_field(Field *to)
{ {
my_decimal buff; my_decimal buff;
@ -2092,6 +2123,10 @@ public:
unireg_check_arg, field_name_arg, cs) unireg_check_arg, field_name_arg, cs)
{} {}
enum_field_types type() const { return MYSQL_TYPE_NULL;} 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) int store(const char *to, uint length, CHARSET_INFO *cs)
{ null[0]=1; return 0; } { null[0]=1; return 0; }
int store(double nr) { 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); return store(str, length, &my_charset_bin);
} }
Copy_func *get_copy_func(const Field *from) const;
int save_in_field(Field *to) int save_in_field(Field *to)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
@ -2413,6 +2449,28 @@ public:
unireg_check_arg, field_name_arg, 1, 1) unireg_check_arg, field_name_arg, 1, 1)
{} {}
enum_field_types type() const { return MYSQL_TYPE_YEAR;} 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(const char *to,uint 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);
@ -2502,6 +2560,7 @@ protected:
int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str, int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str,
int was_cut, int have_smth_to_conv); int was_cut, int have_smth_to_conv);
bool check_zero_in_date_with_warn(ulonglong fuzzydate); bool check_zero_in_date_with_warn(ulonglong fuzzydate);
static void do_field_time(Copy_field *copy);
public: public:
Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg, Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_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_field_types type() const { return MYSQL_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } 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 bool memcpy_field_possible(const Field *from) const
{ {
return real_type() == from->real_type() && return real_type() == from->real_type() &&
@ -2884,6 +2951,7 @@ public:
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
bool zero_pack() const { return 0; } bool zero_pack() const { return 0; }
Copy_func *get_copy_func(const Field *from) const;
int reset(void) int reset(void)
{ {
charset()->cset->fill(charset(),(char*) ptr, field_length, charset()->cset->fill(charset(),(char*) ptr, field_length,
@ -2980,6 +3048,7 @@ public:
return (uint32) field_length + (field_charset == &my_charset_bin ? return (uint32) field_length + (field_charset == &my_charset_bin ?
length_bytes : 0); length_bytes : 0);
} }
Copy_func *get_copy_func(const Field *from) const;
bool memcpy_field_possible(const Field *from) const bool memcpy_field_possible(const Field *from) const
{ {
return Field_str::memcpy_field_possible(from) && return Field_str::memcpy_field_possible(from) &&
@ -3038,6 +3107,8 @@ protected:
*/ */
String value; String value;
static void do_copy_blob(Copy_field *copy);
static void do_conv_blob(Copy_field *copy);
public: public:
Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_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_field_types type() const { return MYSQL_TYPE_BLOB;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } { 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) int store_field(Field *from)
{ // Be sure the value is stored { // Be sure the value is stored
from->val_str(&value); 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 { class Field_enum :public Field_str {
static void do_field_enum(Copy_field *copy_field);
protected: protected:
uint packlength; uint packlength;
public: public:
@ -3278,6 +3363,17 @@ public:
enum_field_types type() const { return MYSQL_TYPE_STRING; } enum_field_types type() const { return MYSQL_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; } enum Item_result cmp_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const; 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) int store_field(Field *from)
{ {
if (from->real_type() == MYSQL_TYPE_ENUM && from->val_int() == 0) 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); clr_rec_bits(bit_ptr, bit_ofs, bit_len);
return 0; 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); } int save_in_field(Field *to) { return to->store(val_int(), true); }
bool memcpy_field_possible(const Field *from) const { return false; } bool memcpy_field_possible(const Field *from) const { return false; }
int store(const char *to, uint length, CHARSET_INFO *charset); 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 { 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: public:
uchar *from_ptr,*to_ptr; uchar *from_ptr,*to_ptr;
uchar *from_null_ptr,*to_null_ptr; uchar *from_null_ptr,*to_null_ptr;
@ -3728,7 +3822,7 @@ public:
Note that for VARCHARs, do_copy() will be do_varstring*() which Note that for VARCHARs, do_copy() will be do_varstring*() which
only copies the length-bytes (1 or 2) + the actual length of the 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; uint from_length,to_length;
Field *from_field,*to_field; Field *from_field,*to_field;

View File

@ -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)); ((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(&copy->tmp); copy->from_field->val_str(&copy->tmp);
((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), ((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]; char buff[MAX_FIELD_WIDTH];
String res(buff, sizeof(buff), copy->from_field->charset()); 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) if (copy->from_field->val_int() == 0)
((Field_enum *) copy->to_field)->store_type((ulonglong) 0); ((Field_enum *) copy->to_field)->store_type((ulonglong) 0);
@ -397,31 +397,44 @@ 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(); longlong value= copy->from_field->val_int();
copy->to_field->store(value, copy->to_field->store(value,
MY_TEST(copy->from_field->flags & UNSIGNED_FLAG)); 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(); double value=copy->from_field->val_real();
copy->to_field->store(value); copy->to_field->store(value);
} }
static void do_field_decimal(Copy_field *copy) void Field::do_field_decimal(Copy_field *copy)
{ {
my_decimal value; my_decimal value;
copy->to_field->store_decimal(copy->from_field->val_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; MYSQL_TIME ltime;
copy->from_field->get_date(&ltime, 0); // TODO: we now need to check result
if (copy->from_field->get_date(&ltime, 0))
copy->to_field->reset();
else
copy->to_field->store_time_dec(&ltime, copy->from_field->decimals());
}
void Field_time::do_field_time(Copy_field *copy)
{
MYSQL_TIME ltime;
if (copy->from_field->get_date(&ltime, TIME_TIME_ONLY))
copy->to_field->reset();
else
copy->to_field->store_time_dec(&ltime, copy->from_field->decimals()); copy->to_field->store_time_dec(&ltime, copy->from_field->decimals());
} }
@ -698,122 +711,72 @@ void Copy_field::set(Field *to,Field *from,bool save)
if ((to->flags & BLOB_FLAG) && save) if ((to->flags & BLOB_FLAG) && save)
do_copy2= do_save_blob; do_copy2= do_save_blob;
else else
do_copy2= get_copy_func(to,from); do_copy2= to->get_copy_func(from);
if (!do_copy) // Not null if (!do_copy) // Not null
do_copy=do_copy2; do_copy=do_copy2;
} }
Copy_field::Copy_func * Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
Copy_field::get_copy_func(const Field *to, const Field *from)
{ {
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 types are not 100 % identical then convert trough get_date() */
if (!to->eq_def(from) || if (from->cmp_type() == REAL_RESULT)
((to->table->in_use->variables.sql_mode & return do_field_string; // TODO: MDEV-9344
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) && if (from->type() == MYSQL_TYPE_YEAR)
mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME)) 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 do_field_temporal;
/* Do binary copy */ return get_identical_copy_func();
} }
// Check if identical fields
if (from->result_type() == STRING_RESULT)
{ 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 Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
use special copy function that removes trailing spaces and thus use special copy function that removes trailing spaces and thus
repairs data. repairs data.
*/ */
if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() &&
to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset()) !Field_varstring::has_charset())
return do_field_varbinary_pre50; 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);
}
if (to->real_type() != from->real_type())
{ Field::Copy_func *Field_string::get_copy_func(const Field *from) const
if (from->real_type() == MYSQL_TYPE_ENUM || {
from->real_type() == MYSQL_TYPE_SET) if (from->type() == MYSQL_TYPE_BIT)
if (to->result_type() != STRING_RESULT) return do_field_int;
return do_field_int; // Convert SET to number if (Field_string::real_type() != from->real_type() ||
Field_string::charset() != from->charset())
return do_field_string; return do_field_string;
} if (Field_string::pack_length() < from->pack_length())
if (to->real_type() == MYSQL_TYPE_ENUM || return (Field_string::charset()->mbmaxlen == 1 ?
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); do_cut_string : do_cut_string_complex);
else if (to_length > from_length) if (Field_string::pack_length() > from->pack_length())
{ return Field_string::charset() == &my_charset_bin ? do_expand_binary :
if (to->charset() == &my_charset_bin) do_expand_string;
return do_expand_binary; return get_identical_copy_func();
return do_expand_string; }
}
}
else if (to->real_type() != from->real_type() || Field::Copy_func *Field::get_identical_copy_func() const
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 */ /* Identical field types */
switch (to_length) { switch (pack_length()) {
case 1: return do_field_1; case 1: return do_field_1;
case 2: return do_field_2; case 2: return do_field_2;
case 3: return do_field_3; case 3: return do_field_3;