diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-10-10 08:12:14 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-10-10 08:12:14 +0400 |
commit | 312ba3cc3dd13fe3da1aeac8a32887be98c8a7ae (patch) | |
tree | 608d138c261c1b20fea2daaa0a88b53139b3643f | |
parent | b37386d854b37743a7b4ae578312dd27bec055ce (diff) | |
download | mariadb-git-312ba3cc3dd13fe3da1aeac8a32887be98c8a7ae.tar.gz |
MDEV-20783 INET6 cannot be converted to BINARY(16)
-rw-r--r-- | plugin/type_inet/mysql-test/type_inet/type_inet6.result | 118 | ||||
-rw-r--r-- | plugin/type_inet/mysql-test/type_inet/type_inet6.test | 114 | ||||
-rw-r--r-- | plugin/type_inet/sql_type_inet.cc | 50 | ||||
-rw-r--r-- | sql/field.h | 5 | ||||
-rw-r--r-- | sql/field_conv.cc | 6 |
5 files changed, 271 insertions, 22 deletions
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index b402e1cae2a..3e5905cecec 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -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); @@ -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 @@ -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; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test index 2abcb2a9fc5..03b83214edc 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test @@ -815,6 +815,16 @@ 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 # @@ -904,6 +914,100 @@ 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. --echo # The test for a valid data type should be moved @@ -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; diff --git a/plugin/type_inet/sql_type_inet.cc b/plugin/type_inet/sql_type_inet.cc index 4cd104af206..0c50cfe034c 100644 --- a/plugin/type_inet/sql_type_inet.cc +++ b/plugin/type_inet/sql_type_inet.cc @@ -823,26 +823,38 @@ public: 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 diff --git a/sql/field.h b/sql/field.h index 9c98ea810f6..a0d8476df94 100644 --- a/sql/field.h +++ b/sql/field.h @@ -742,6 +742,7 @@ protected: } 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); @@ -893,6 +894,10 @@ public: */ 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; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index f96c6742ea7..f975597cf70 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -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); } @@ -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; } } @@ -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; } |