Commit e555df64 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20285 Wrong result on INSERT..SELECT when converting from SIGNED to UNSIGNED

parent 7fc86a73
......@@ -236,5 +236,18 @@ DROP FUNCTION sint32;
DROP FUNCTION uint64;
DROP FUNCTION sint64;
#
# MDEV-20285 Wrong result on INSERT..SELECT when converting from SIGNED to UNSIGNED
#
CREATE TABLE t1 (a TINYINT UNSIGNED);
CREATE TABLE t2 (a TINYINT);
INSERT INTO t1 VALUES (255);
INSERT IGNORE INTO t2 SELECT a FROM t1;
Warnings:
Warning 1264 Out of range value for column 'a' at row 1
SELECT * FROM t2;
a
127
DROP TABLE t1, t2;
#
# End of 10.3 tests
#
......@@ -176,6 +176,17 @@ DROP FUNCTION sint32;
DROP FUNCTION uint64;
DROP FUNCTION sint64;
--echo #
--echo # MDEV-20285 Wrong result on INSERT..SELECT when converting from SIGNED to UNSIGNED
--echo #
CREATE TABLE t1 (a TINYINT UNSIGNED);
CREATE TABLE t2 (a TINYINT);
INSERT INTO t1 VALUES (255);
INSERT IGNORE INTO t2 SELECT a FROM t1;
SELECT * FROM t2;
DROP TABLE t1, t2;
--echo #
--echo # End of 10.3 tests
--echo #
......@@ -115,6 +115,7 @@ insert ignore into t2 select b,c from t1;
Warnings:
Warning 1265 Data truncated for column 'b' at row 1
Warning 1265 Data truncated for column 'b' at row 2
Warning 1264 Out of range value for column 'a' at row 3
Warning 1265 Data truncated for column 'b' at row 3
Warning 1048 Column 'a' cannot be null
Warning 1265 Data truncated for column 'b' at row 4
......
......@@ -1708,13 +1708,6 @@ class Field_num :public Field {
{
return to->store(val_int(), MY_TEST(flags & UNSIGNED_FLAG));
}
bool memcpy_field_possible(const Field *from) const
{
return real_type() == from->real_type() &&
pack_length() == from->pack_length() &&
!((flags & UNSIGNED_FLAG) && !(from->flags & UNSIGNED_FLAG)) &&
decimals() == from->decimals();
}
uint is_equal(Create_field *new_field);
uint row_pack_length() const { return pack_length(); }
uint32 pack_length_from_metadata(uint field_metadata) {
......@@ -1892,7 +1885,10 @@ class Field_real :public Field_num {
e.g. a DOUBLE(53,10) into a DOUBLE(10,10).
But it should be OK the other way around.
*/
return Field_num::memcpy_field_possible(from) &&
return real_type() == from->real_type() &&
pack_length() == from->pack_length() &&
is_unsigned() <= from->is_unsigned() &&
decimals() == from->decimals() &&
field_length >= from->field_length;
}
int store_decimal(const my_decimal *);
......@@ -1983,7 +1979,10 @@ class Field_new_decimal :public Field_num {
}
bool memcpy_field_possible(const Field *from) const
{
return Field_num::memcpy_field_possible(from) &&
return real_type() == from->real_type() &&
pack_length() == from->pack_length() &&
is_unsigned() <= from->is_unsigned() &&
decimals() == from->decimals() &&
field_length == from->field_length;
}
int reset(void);
......@@ -2041,6 +2040,12 @@ class Field_int :public Field_num
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, 0, zero_arg, unsigned_arg)
{}
bool memcpy_field_possible(const Field *from) const
{
return real_type() == from->real_type() &&
pack_length() == from->pack_length() &&
is_unsigned() == from->is_unsigned();
}
int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *);
bool val_bool() { return val_int() != 0; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment