diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-10-15 13:50:41 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-10-15 15:30:18 +0400 |
commit | 22b645ef5292387871b12b26fd550eed6e57aa2d (patch) | |
tree | 15eec65381faa46d6181c84d25166db471e1b249 /plugin | |
parent | 8ec978142b1572f54ce8b1afc71a68e924c089f4 (diff) | |
download | mariadb-git-22b645ef5292387871b12b26fd550eed6e57aa2d.tar.gz |
MDEV-20831 Table partitioned by LIST/RANGE COLUMNS(inet6) can be created, but not inserted into
This clause in CREATE TABLE:
PARTITION BY LIST COLUMNS (inet6column)
(PARTITION p1 VALUES IN ('::'))
was erroneously written to frm file as:
PARTITION BY LIST COLUMNS(inet6column)
(PARTITION p1 VALUES IN (_binary 0x3A3A))
I.e. the text value '::' was converted to HEX representation
and prefixed with _binary.
A simple fix could write `_latin1 0x3A3A` instead of `_binary 0x3A3A`,
but in case of INET6 we don't need neither character set introducers,
nor HEX encoding, because text representation of INET6 values consist
of pure ASCII characters.
So this patch changes the above clause to be printed as:
PARTITION BY LIST COLUMNS(inet6column)
(PARTITION p1 VALUES IN ('::'))
Details:
The old code in check_part_field() was not friendly to pluggable data types.
Replacing this function to two new virtual methods in Type_handler:
virtual bool partition_field_check(const LEX_CSTRING &field_name,
Item *item_expr) const;
virtual bool partition_field_append_value(String *str,
Item *item_expr,
CHARSET_INFO *field_cs,
partition_value_print_mode_t mode)
const;
so data type plugins can decide whether they need to use character set
introducer and/or hex encoding when printing partition values.
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/type_inet/mysql-test/type_inet/type_inet6_partition.result | 29 | ||||
-rw-r--r-- | plugin/type_inet/mysql-test/type_inet/type_inet6_partition.test | 32 | ||||
-rw-r--r-- | plugin/type_inet/sql_type_inet.cc | 34 | ||||
-rw-r--r-- | plugin/type_inet/sql_type_inet.h | 9 |
4 files changed, 104 insertions, 0 deletions
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.result new file mode 100644 index 00000000000..1b98078a91d --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.result @@ -0,0 +1,29 @@ +# +# MDEV-20831 Table partitioned by LIST/RANGE COLUMNS(inet6) can be created, but not inserted into +# +SET NAMES utf8; +CREATE TABLE t1 (a INET6) +PARTITION BY LIST COLUMNS(a) +(PARTITION p00 VALUES IN (10)); +ERROR HY000: Partition column values of incorrect type +CREATE TABLE t1 (a INET6) +PARTITION BY LIST COLUMNS(a) +(PARTITION p00 VALUES IN (TIME'10:20:30')); +ERROR HY000: Partition column values of incorrect type +CREATE TABLE t1 (a INET6) +PARTITION BY LIST COLUMNS(a) +(PARTITION p00 VALUES IN ('€')); +ERROR HY000: This partition function is not allowed +CREATE TABLE t1 (a INET6) +PARTITION BY LIST COLUMNS(a) +(PARTITION p00 VALUES IN ('::'), +PARTITION pFF VALUES IN (0xFFFF000000000000000000000000FFFF)); +INSERT INTO t1 VALUES ('::'); +INSERT INTO t1 VALUES ('ffff::ffff'); +SELECT * FROM t1 PARTITION (p00); +a +:: +SELECT * FROM t1 PARTITION (pFF); +a +ffff::ffff +DROP TABLE t1; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.test b/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.test new file mode 100644 index 00000000000..95aec533506 --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_partition.test @@ -0,0 +1,32 @@ +--source include/have_partition.inc + +--echo # +--echo # MDEV-20831 Table partitioned by LIST/RANGE COLUMNS(inet6) can be created, but not inserted into +--echo # + +SET NAMES utf8; + +--error ER_WRONG_TYPE_COLUMN_VALUE_ERROR +CREATE TABLE t1 (a INET6) + PARTITION BY LIST COLUMNS(a) + (PARTITION p00 VALUES IN (10)); + +--error ER_WRONG_TYPE_COLUMN_VALUE_ERROR +CREATE TABLE t1 (a INET6) + PARTITION BY LIST COLUMNS(a) + (PARTITION p00 VALUES IN (TIME'10:20:30')); + +--error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED +CREATE TABLE t1 (a INET6) + PARTITION BY LIST COLUMNS(a) + (PARTITION p00 VALUES IN ('€')); + +CREATE TABLE t1 (a INET6) + PARTITION BY LIST COLUMNS(a) + (PARTITION p00 VALUES IN ('::'), + PARTITION pFF VALUES IN (0xFFFF000000000000000000000000FFFF)); +INSERT INTO t1 VALUES ('::'); +INSERT INTO t1 VALUES ('ffff::ffff'); +SELECT * FROM t1 PARTITION (p00); +SELECT * FROM t1 PARTITION (pFF); +DROP TABLE t1; diff --git a/plugin/type_inet/sql_type_inet.cc b/plugin/type_inet/sql_type_inet.cc index d6c6703aaa3..0502cde4f7b 100644 --- a/plugin/type_inet/sql_type_inet.cc +++ b/plugin/type_inet/sql_type_inet.cc @@ -1449,6 +1449,40 @@ Field *Type_handler_inet6::make_conversion_table_field(MEM_ROOT *root, } +bool Type_handler_inet6::partition_field_check(const LEX_CSTRING &field_name, + Item *item_expr) const +{ + if (item_expr->cmp_type() != STRING_RESULT) + { + my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0)); + return true; + } + return false; +} + + +bool +Type_handler_inet6::partition_field_append_value( + String *to, + Item *item_expr, + CHARSET_INFO *field_cs, + partition_value_print_mode_t mode) + const +{ + StringBufferInet6 inet6str; + Inet6_null inet6(item_expr); + if (inet6.is_null()) + { + my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); + return true; + } + return inet6.to_string(&inet6str) || + to->append('\'') || + to->append(inet6str) || + to->append('\''); +} + + /***************************************************************/ diff --git a/plugin/type_inet/sql_type_inet.h b/plugin/type_inet/sql_type_inet.h index c00237cf4fc..430f7ec30c0 100644 --- a/plugin/type_inet/sql_type_inet.h +++ b/plugin/type_inet/sql_type_inet.h @@ -478,6 +478,15 @@ public: return false; } + bool partition_field_check(const LEX_CSTRING &field_name, + Item *item_expr) const override; + + bool partition_field_append_value(String *to, + Item *item_expr, + CHARSET_INFO *field_cs, + partition_value_print_mode_t mode) + const override; + Field *make_table_field(MEM_ROOT *root, const LEX_CSTRING *name, const Record_addr &addr, |