INET6
Тип данных INET6 был добавлен в MariaDB 10.5.0
Синтаксис
INET6
Описание
Тип данных INET6 предназначен для хранения адресов IPv6, а также адресов IPv4 с учётом стандартного преобразования адресов IPv4 в адреса IPv6.
Допускается использование короткой и длинной нотации IPv6 в соответствии с RFC-5952.
- Значения хранятся как бинарная строка фиксированной длины 16 байт, с старшим байтом в начале.
- Двигатели хранилищ видят INET6 как BINARY(16).
- Клиенты видят INET6 как CHAR(39) и получают текстовое представление при извлечении.
Использование IPv4-совместимой нотации считается устаревшим. Оно поддерживается для совместимости с функцией INET6_ATON, которая также понимает этот формат. Рекомендуется использовать сопоставленный формат для хранения адресов IPv4 в INET6.
Когда значение, соответствующее или совместимое с IPv4, хранится в INET6, оно всё ещё занимает 16 байт:
Извлечение
При извлечении в текстовом протоколе клиент-сервер значения INET6 преобразуются в короткое текстовое представление в соответствии с RFC-5952, то есть с удалением всех ведущих нулей в каждой группе и сжатием последующих нулевых групп.
Помимо создания собственной сохранённой функции, нет способа извлечь значение INET6 с использованием длинного текстового представления.
Преобразование типов
- CAST из символьной строки в INET6 понимает адреса в короткой или длинной текстовой нотации (включая сопоставленные и совместимые адреса IPv4). Возвращается NULL, если формат не распознаётся.
- CAST из бинарной строки в INET6 требует 16-байтовую строку в качестве аргумента. Возвращается NULL, если длина аргумента не равна 16.
- CAST из других типов данных в INET6 сначала преобразует данные в символьную строку, затем применяется CAST из символьной строки в INET6.
- CAST из INET6 в CHAR возвращает короткое текстовое представление адреса.
- CAST из INET6 в BINARY возвращает его 16-байтовое бинарное строковое представление.
- CAST из INET6 в типы данных, отличные от CHAR (например, SIGNED, UNSIGNED, TIME и т. д.) возвращает ошибку.
Сравнения
Выражение INET6 может быть сравнено с:
- другим выражением INET6
- выражением символьной строки с текстовым (коротким или длинным) представлением адреса:
- выражением 16-байтовой бинарной строки:
Попытка сравнения INET6 с выражением любого другого типа данных возвращает ошибку.
Смешивание значений INET6 для результата
Выражение INET6 может быть смешано для результата (например, UNION, CASE..THEN, COALESCE и т. д.) со:
- другим выражением INET6. Результирующий тип данных — INET6.
- символьной строкой в текстовом (коротком или длинном) представлении адреса. Тип данных результата — INET6. Символьная строка автоматически преобразуется в INET6. Если формат строки не понят, он преобразуется с предупреждением либо в NULL, либо в '::', в зависимости от возможности NULL в результате.
- 16-байтовой бинарной строкой. Результирующий тип данных — INET6. Бинарная строка автоматически преобразуется в INET6. Если длина бинарной строки не равна 16, она преобразуется с предупреждением в NULL или в '::', в зависимости от возможности NULL в результате.
Попытки смешать INET6 с другими типами данных для результата приведут к ошибке.
Смешивание INET6 с другими типами данных для LEAST и GREATEST, когда смешивание для сравнения и смешивание для результата участвуют одновременно, использует те же правила, что и смешивание для результата, описанные в предыдущих абзацах.
Функции и операторы
- HEX() с аргументом INET6 возвращает шестнадцатеричное представление лежащей в основе 16-байтовой бинарной строки
- Арифметические операторы (+,-,*,/,MOD,DIV) не поддерживаются для INET6. Это может измениться в будущем.
- Функция INET6_ATON теперь понимает значения INET6 в качестве аргумента
- Прототипы функций IS_IPV4_COMPAT и IS_IPV4_MAPPED изменились с
a BINARY(16)наa INET6, - Если аргумент этих двух функций не INET6, применяется автоматическое неявное преобразование к INET6. В результате обе функции теперь понимают аргументы как в текстовом представлении, так и в бинарном (16) представлении. До MariaDB 10.5.0 эти функции понимали только бинарное представление (16).
Параметры подготовленных запросов
INET6 понимает как текстовое (text), так и бинарное (16) (binary(16)) представление адреса в параметрах подготовленных запросов (prepared statement) (PREPARE..EXECUTE и EXECUTE IMMEDIATE).
Миграция между BINARY(16) и INET6
До MariaDB 10.5.0 вы, возможно, использовали BINARY(16) для хранения адресов IPv6, в сочетании с INET6_ATON и INET6_NTOA для вставки и извлечения данных соответственно.
Начиная с версии 10.5, вы можете изменить столбцы BINARY(16), хранящие адреса IPv6, на INET6. После такой модификации нет необходимости использовать INET6_ATON() и INET6_NTOA(). Адреса могут быть вставлены и извлечены напрямую.
Также возможно преобразовать столбцы INET6 в BINARY(16) и продолжить использование данных в сочетании с INET6_NTOA() и INET6_ATON().
Примеры
CREATE TABLE t1 (a INET6);
Вставка с использованием короткого текстового обозначения адреса:
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
Длинное текстовое обозначение адреса:
INSERT INTO t1 VALUES ('2001:0db8:0000:0000:0000:ff00:0042:8329');
16-байтовое бинарное обозначение:
INSERT INTO t1 VALUES (0x20010DB8000000000000FF0000428329);
INSERT INTO t1 VALUES (UNHEX('20010DB8000000000000FF0000428329'));
Адреса IPv4 с использованием обозначений IPv4-сопоставления и IPv4-совместимости:
INSERT INTO t1 VALUES ('::ffff:192.0.2.128'); -- mapped
INSERT INTO t1 VALUES ('::192.0.2.128'); -- compatible
SELECT * FROM t1; +------------------------+ | a | +------------------------+ | 2001:db8::ff00:42:8329 | | 2001:db8::ff00:42:8329 | | 2001:db8::ff00:42:8329 | | 2001:db8::ff00:42:8329 | | ::ffff:192.0.2.128 | | ::192.0.2.128 | +------------------------+
Значения, сопоставленные или совместимые с IPv4, всё ещё занимают 16 байт:
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('::ffff:192.0.2.128');
SELECT * FROM t1;
+--------------------+
| a |
+--------------------+
| ::ffff:192.0.2.128 |
+--------------------+
SELECT HEX(a) FROM t1;
+----------------------------------+
| HEX(a) |
+----------------------------------+
| 00000000000000000000FFFFC0000280 |
+----------------------------------+
Преобразование из INET6 в любой тип данных, кроме CHAR, возвращает ошибку:
SELECT CAST(a AS DECIMAL) FROM t1; ERROR 4079 (HY000): Illegal parameter data type inet6 for operation 'decimal_typecast'
Примеры сравнения
Сравнение с другим выражением INET6:
CREATE OR REPLACE TABLE t1 (a INET6);
CREATE OR REPLACE TABLE t2 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8328'),('2001:db8::ff00:42:8329');
INSERT INTO t2 VALUES ('2001:db8::ff00:42:832a'),('2001:db8::ff00:42:8329');
SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a;
+------------------------+
| a |
+------------------------+
| 2001:db8::ff00:42:8329 |
+------------------------+
Со строковым выражением с текстовым (коротким или длинным) представлением адреса:
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
SELECT * FROM t1 WHERE a='2001:db8::ff00:42:8329';
+------------------------+
| a |
+------------------------+
| 2001:db8::ff00:42:8329 |
+------------------------+
С выражением 16-байтовой бинарной строки:
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
SELECT * FROM t1 WHERE a=X'20010DB8000000000000FF0000428329';
+------------------------+
| a |
+------------------------+
| 2001:db8::ff00:42:8329 |
+------------------------+
С выражением другого типа данных:
SELECT * FROM t1 WHERE a=1; ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation '='
Примеры смешивания для результата
Смешанное с другим выражением INET6, возвращающим тип данных INET6:
CREATE OR REPLACE TABLE t1 (a INET6, b INET6);
INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8329');
SELECT a FROM t1 UNION SELECT b FROM t1;
+------------------------+
| a |
+------------------------+
| NULL |
| 2001:db8::ff00:42:8329 |
+------------------------+
SELECT COALESCE(a, b) FROM t1;
+------------------------+
| COALESCE(a, b) |
+------------------------+
| 2001:db8::ff00:42:8329 |
+------------------------+
Смешанное со строковым выражением с текстовым (коротким или длинным) представлением адреса:
CREATE OR REPLACE TABLE t1 (a INET6, b VARCHAR(64));
INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8328');
INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:832a garbage');
SELECT COALESCE(a,b) FROM t1;
+------------------------+
| COALESCE(a,b) |
+------------------------+
| 2001:db8::ff00:42:8328 |
| NULL |
+------------------------+
2 rows in set, 1 warning (0.001 sec)
SHOW WARNINGS;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1292 | Incorrect inet6 value: '2001:db8::ff00:42:832a garbage' |
+---------+------+---------------------------------------------------------+
Смешанное с 16-байтовой бинарной строкой:
CREATE OR REPLACE TABLE t1 (a INET6, b VARBINARY(16));
INSERT INTO t1 VALUES (NULL,CONCAT(0xFFFF,REPEAT(0x0000,6),0xFFFF));
INSERT INTO t1 VALUES (NULL,0x00/*garbage*/);
SELECT COALESCE(a,b) FROM t1;
+---------------+
| COALESCE(a,b) |
+---------------+
| ffff::ffff |
| NULL |
+---------------+
2 rows in set, 1 warning (0.001 sec)
SHOW WARNINGS;
+---------+------+-------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------+
| Warning | 1292 | Incorrect inet6 value: '\x00' |
+---------+------+-------------------------------+
Смешивание с другими типами данных:
SELECT CAST('ffff::ffff' AS INET6) UNION SELECT 1;
ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation 'UNION'
Примеры функций и операторов
HEX с аргументом INET6, возвращающим шестнадцатеричное представление:
SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));
+----------------------------------------------+
| HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
+----------------------------------------------+
| 20010DB8000000000000FF0000428329 |
+----------------------------------------------+
INET6_ATON теперь понимает значения INET6 в качестве аргумента:
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
SELECT a, HEX(INET6_ATON(a)) FROM t1;
+------------------------+----------------------------------+
| a | HEX(INET6_ATON(a)) |
+------------------------+----------------------------------+
| 2001:db8::ff00:42:8329 | 20010DB8000000000000FF0000428329 |
+------------------------+----------------------------------+
IS_IPV4_COMPAT и IS_IPV4_MAPPED прототип теперь a BINARY(16)):
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
INSERT INTO t1 VALUES ('::192.168.0.1');
SELECT a, IS_IPV4_MAPPED(a), IS_IPV4_COMPAT(a) FROM t1;
+------------------------+-------------------+-------------------+
| a | IS_IPV4_MAPPED(a) | IS_IPV4_COMPAT(a) |
+------------------------+-------------------+-------------------+
| 2001:db8::ff00:42:8329 | 0 | 0 |
| ::ffff:192.168.0.1 | 1 | 0 |
| ::192.168.0.1 | 0 | 1 |
+------------------------+-------------------+-------------------+
Автоматическое неявное преобразование к INET6:
CREATE OR REPLACE TABLE t1 (
a INET6,
b VARCHAR(39) DEFAULT a
);
INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');
SELECT a, IS_IPV4_MAPPED(a), b, IS_IPV4_MAPPED(b) FROM t1;
+--------------------+-------------------+--------------------+-------------------+
| a | IS_IPV4_MAPPED(a) | b | IS_IPV4_MAPPED(b) |
+--------------------+-------------------+--------------------+-------------------+
| ffff::ffff | 0 | ffff::ffff | 0 |
| ::ffff:192.168.0.1 | 1 | ::ffff:192.168.0.1 | 1 |
+--------------------+-------------------+--------------------+-------------------+
CREATE OR REPLACE TABLE t1 (
a INET6,
b BINARY(16) DEFAULT UNHEX(HEX(a))
);
INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');
SELECT a, IS_IPV4_MAPPED(a), HEX(b), IS_IPV4_MAPPED(b) FROM t1;
+--------------------+-------------------+----------------------------------+-------------------+
| a | IS_IPV4_MAPPED(a) | HEX(b) | IS_IPV4_MAPPED(b) |
+--------------------+-------------------+----------------------------------+-------------------+
| ffff::ffff | 0 | FFFF000000000000000000000000FFFF | 0 |
| ::ffff:192.168.0.1 | 1 | 00000000000000000000FFFFC0A80001 | 1 |
+--------------------+-------------------+----------------------------------+-------------------+
Примеры параметров подготовленных запросов
CREATE OR REPLACE TABLE t1 (a INET6); EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING 'ffff::fffe'; EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING X'FFFF000000000000000000000000FFFF'; SELECT * FROM t1; +------------+ | a | +------------+ | ffff::fffe | | ffff::ffff | +------------+ EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING 'ffff::fffe'; +------------+ | a | +------------+ | ffff::fffe | +------------+ EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING X'FFFF000000000000000000000000FFFF'; +------------+ | a | +------------+ | ffff::ffff | +------------+
Примеры миграции между BINARY(16) и INET6
До MariaDB 10.5:
CREATE OR REPLACE TABLE t1 (a BINARY(16));
INSERT INTO t1 VALUES (INET6_ATON('ffff::ffff'));
SELECT INET6_NTOA(a) FROM t1;
+---------------+
| INET6_NTOA(a) |
+---------------+
| ffff::ffff |
+---------------+
Миграция в INET6, начиная с MariaDB 10.5:
ALTER TABLE t1 MODIFY a INET6;
INSERT INTO t1 VALUES ('ffff::fffe');
SELECT * FROM t1;
+------------+
| a |
+------------+
| ffff::ffff |
| ffff::fffe |
+------------+
Миграция из INET6 в BINARY(16):
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
INSERT INTO t1 VALUES ('::192.168.0.1');
ALTER TABLE t1 MODIFY a BINARY(16);
SELECT INET6_NTOA(a) FROM t1;
+------------------------+
| INET6_NTOA(a) |
+------------------------+
| 2001:db8::ff00:42:8329 |
| ::ffff:192.168.0.1 |
| ::192.168.0.1 |
+------------------------+
См. также
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/inet6/