Skip to content

Commit

Permalink
MDEV-20783 INET6 cannot be converted to BINARY(16)
Browse files Browse the repository at this point in the history
  • Loading branch information
abarkov committed Oct 10, 2019
1 parent b37386d commit 312ba3c
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 22 deletions.
118 changes: 118 additions & 0 deletions plugin/type_inet/mysql-test/type_inet/type_inet6.result
Expand Up @@ -1266,6 +1266,16 @@ Warning 1292 Incorrect inet6 value: '::192.168.0.1'
Warning 1292 Incorrect inet6 value: '::ffff:192.168.0.1'
DROP TABLE t1;
#
# ALTER from INET6 to INET6
#
CREATE TABLE t1 (a INET6, b INT);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329', 1);
ALTER TABLE t1 MODIFY b DECIMAL(10,2);
SELECT * FROM t1;
a b
2001:db8::ff00:42:8329 1.00
DROP TABLE t1;
#
# ALTER to character string data types
#
CREATE OR REPLACE TABLE t1 (a INET6);
Expand Down Expand Up @@ -1377,6 +1387,104 @@ a
2001:db8::ff00:42:8329
DROP TABLE t1;
#
# ALTER to binary string data types
#
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(16);
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(17);
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF000042832900
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(15);
ERROR 22001: Data too long for column 'a' at row 1
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a TINYBLOB;
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BLOB;
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a MEDIUMBLOB;
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a LONGBLOB;
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
#
# ALTER from binary string data types
#
CREATE TABLE t1 (a BINARY(16));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
CREATE TABLE t1 (a BINARY(17));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF000042832900');
ALTER TABLE t1 MODIFY a INET6;
ERROR 22007: Incorrect inet6 value: ' \x01\x0D\xB8\x00\x00\x00\x00\x00\x00\xFF\x00\x00B\x83)\x00' for column `test`.`t1`.`a` at row 1
DROP TABLE t1;
CREATE TABLE t1 (a BINARY(15));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF00004283');
ALTER TABLE t1 MODIFY a INET6;
ERROR 22007: Incorrect inet6 value: ' \x01\x0D\xB8\x00\x00\x00\x00\x00\x00\xFF\x00\x00B\x83' for column `test`.`t1`.`a` at row 1
DROP TABLE t1;
CREATE TABLE t1 (a TINYBLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
CREATE TABLE t1 (a BLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
CREATE TABLE t1 (a MEDIUMBLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
CREATE TABLE t1 (a BLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
#
# Limit clause parameter
# TODO: this should fail.
# The test for a valid data type should be moved
Expand All @@ -1398,3 +1506,13 @@ SELECT * FROM t1;
a
2001:db8::ff00:42:8329
DROP TABLE t1;
#
# MDEV-20783 INET6 cannot be converted to BINARY(16) (requires clarification in documentation)
#
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(16);
SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
114 changes: 114 additions & 0 deletions plugin/type_inet/mysql-test/type_inet/type_inet6.test
Expand Up @@ -814,6 +814,16 @@ SELECT id, length(a), a, IS_IPV4_COMPAT(BINARY a) FROM t1 ORDER BY id;
DROP TABLE t1;


--echo #
--echo # ALTER from INET6 to INET6
--echo #

CREATE TABLE t1 (a INET6, b INT);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329', 1);
ALTER TABLE t1 MODIFY b DECIMAL(10,2);
SELECT * FROM t1;
DROP TABLE t1;

--echo #
--echo # ALTER to character string data types
--echo #
Expand Down Expand Up @@ -903,6 +913,100 @@ SELECT * FROM t1;
DROP TABLE t1;


--echo #
--echo # ALTER to binary string data types
--echo #

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(16);
SELECT HEX(a) FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(17);
SELECT HEX(a) FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
--error ER_DATA_TOO_LONG
ALTER TABLE t1 MODIFY a BINARY(15);
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a TINYBLOB;
SELECT HEX(a) FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BLOB;
SELECT HEX(a) FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a MEDIUMBLOB;
SELECT HEX(a) FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a LONGBLOB;
SELECT HEX(a) FROM t1;
DROP TABLE t1;


--echo #
--echo # ALTER from binary string data types
--echo #

CREATE TABLE t1 (a BINARY(16));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a BINARY(17));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF000042832900');
--error ER_TRUNCATED_WRONG_VALUE
ALTER TABLE t1 MODIFY a INET6;
DROP TABLE t1;

CREATE TABLE t1 (a BINARY(15));
INSERT INTO t1 VALUES (X'20010DB8000000000000FF00004283');
--error ER_TRUNCATED_WRONG_VALUE
ALTER TABLE t1 MODIFY a INET6;
DROP TABLE t1;

CREATE TABLE t1 (a TINYBLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a BLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a MEDIUMBLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a BLOB);
INSERT INTO t1 VALUES (X'20010DB8000000000000FF0000428329');
ALTER TABLE t1 MODIFY a INET6;
SELECT a FROM t1;
DROP TABLE t1;


--echo #
--echo # Limit clause parameter
--echo # TODO: this should fail.
Expand Down Expand Up @@ -935,3 +1039,13 @@ SELECT CAST(a AS CHAR(39)) FROM t1;
ALTER TABLE t1 MODIFY a CHAR(39);
SELECT * FROM t1;
DROP TABLE t1;

--echo #
--echo # MDEV-20783 INET6 cannot be converted to BINARY(16) (requires clarification in documentation)
--echo #

CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER TABLE t1 MODIFY a BINARY(16);
SELECT HEX(a) FROM t1;
DROP TABLE t1;
50 changes: 31 additions & 19 deletions plugin/type_inet/sql_type_inet.cc
Expand Up @@ -823,26 +823,38 @@ class Field_inet6: public Field
Copy_func *get_copy_func(const Field *from) const override
{
// ALTER to INET6 from another field
/*
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:
return do_field_int;
case ROW_RESULT:
DBUG_ASSERT(0);
break;
return do_field_string;
}

Copy_func *get_copy_func_to(const Field *to) const override
{
if (type_handler() == to->type_handler())
{
// ALTER from INET6 to INET6
DBUG_ASSERT(pack_length() == to->pack_length());
DBUG_ASSERT(charset() == to->charset());
DBUG_ASSERT(sort_charset() == to->sort_charset());
return Field::do_field_eq;
}
*/
return do_field_string;//QQ
// ALTER from INET6 to another data type
if (to->charset() == &my_charset_bin &&
dynamic_cast<const Type_handler_general_purpose_string*>
(to->type_handler()))
{
/*
ALTER from INET6 to a binary string type, e.g.:
BINARY, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
*/
return do_field_inet6_native_to_binary;
}
return do_field_string;
}

static void do_field_inet6_native_to_binary(Copy_field *copy)
{
NativeBufferInet6 res;
copy->from_field->val_native(&res);
copy->to_field->store(res.ptr(), res.length(), &my_charset_bin);
}

bool memcpy_field_possible(const Field *from) const override
Expand Down
5 changes: 5 additions & 0 deletions sql/field.h
Expand Up @@ -742,6 +742,7 @@ class Field: public Value_source
}
void error_generated_column_function_is_not_allowed(THD *thd, bool error)
const;
static void do_field_eq(Copy_field *copy);
static void do_field_int(Copy_field *copy);
static void do_field_real(Copy_field *copy);
static void do_field_string(Copy_field *copy);
Expand Down Expand Up @@ -893,6 +894,10 @@ class Field: public Value_source
*/
typedef void Copy_func(Copy_field*);
virtual Copy_func *get_copy_func(const Field *from) const= 0;
virtual Copy_func *get_copy_func_to(const Field *to) const
{
return to->get_copy_func(this);
}
/* 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;
Expand Down
6 changes: 3 additions & 3 deletions sql/field_conv.cc
Expand Up @@ -30,7 +30,7 @@
#include "sql_class.h" // THD
#include <m_ctype.h>

static void do_field_eq(Copy_field *copy)
void Field::do_field_eq(Copy_field *copy)
{
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
}
Expand Down Expand Up @@ -638,7 +638,7 @@ void Copy_field::set(uchar *to,Field *from)
else
{
to_null_ptr= 0; // For easy debugging
do_copy= do_field_eq;
do_copy= Field::do_field_eq;
}
}

Expand Down Expand Up @@ -719,7 +719,7 @@ void Copy_field::set(Field *to,Field *from,bool save)
if ((to->flags & BLOB_FLAG) && save)
do_copy2= do_save_blob;
else
do_copy2= to->get_copy_func(from);
do_copy2= from->get_copy_func_to(to);
if (!do_copy) // Not null
do_copy=do_copy2;
}
Expand Down

0 comments on commit 312ba3c

Please sign in to comment.