summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-10-10 08:12:14 +0400
committerAlexander Barkov <bar@mariadb.com>2019-10-10 08:12:14 +0400
commit312ba3cc3dd13fe3da1aeac8a32887be98c8a7ae (patch)
tree608d138c261c1b20fea2daaa0a88b53139b3643f /plugin
parentb37386d854b37743a7b4ae578312dd27bec055ce (diff)
downloadmariadb-git-312ba3cc3dd13fe3da1aeac8a32887be98c8a7ae.tar.gz
MDEV-20783 INET6 cannot be converted to BINARY(16)
Diffstat (limited to 'plugin')
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.result118
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.test114
-rw-r--r--plugin/type_inet/sql_type_inet.cc50
3 files changed, 263 insertions, 19 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