#At file:///home/alik/MySQL/bzr/00/wl5787/mysql-trunk-wl5787/ based on revid:marc.alff@stripped
3594 Alexander Nozdrin 2011-02-08
Patch for WL#5787 (IPv6-capable INET_ATON and INET_NTOA functions).
The patch introduces INET6_ATON() and INET6_NTOA().
modified:
mysql-test/r/func_misc.result
mysql-test/t/func_misc.test
sql/item_create.cc
sql/item_strfunc.cc
sql/item_strfunc.h
=== modified file 'mysql-test/r/func_misc.result'
--- a/mysql-test/r/func_misc.result 2010-12-17 11:28:59 +0000
+++ b/mysql-test/r/func_misc.result 2011-02-08 11:24:46 +0000
@@ -400,6 +400,322 @@ DROP TABLE t1;
#
# End of 5.5 tests
#
+
+# --
+# -- WL#5787: IPv6-capable INET_ATON and INET_NTOA functions.
+# --
+
+# -- INET6_ATON: checking NULL, invalid types, out-of range values...
+
+SELECT INET6_ATON(NULL);
+INET6_ATON(NULL)
+NULL
+SELECT INET6_ATON(123);
+INET6_ATON(123)
+NULL
+SELECT INET6_ATON(123.45);
+INET6_ATON(123.45)
+NULL
+SELECT INET6_ATON(NOW());
+INET6_ATON(NOW())
+NULL
+SELECT INET6_ATON('256.1.2.12345678');
+INET6_ATON('256.1.2.12345678')
+NULL
+SELECT INET6_ATON('-1.1.2.3');
+INET6_ATON('-1.1.2.3')
+NULL
+SELECT INET6_ATON('0xR.1.2.3');
+INET6_ATON('0xR.1.2.3')
+NULL
+SELECT INET6_ATON('08.1.2.3');
+INET6_ATON('08.1.2.3')
+NULL
+SELECT INET6_ATON('0A.1.2.3');
+INET6_ATON('0A.1.2.3')
+NULL
+SELECT INET6_ATON('mysql.com');
+INET6_ATON('mysql.com')
+NULL
+SELECT INET6_ATON('1.2.3.4:80');
+INET6_ATON('1.2.3.4:80')
+NULL
+SELECT INET6_ATON('1.2.3.4/32');
+INET6_ATON('1.2.3.4/32')
+NULL
+SELECT INET6_ATON(':::');
+INET6_ATON(':::')
+NULL
+SELECT INET6_ATON('::c0a80102');
+INET6_ATON('::c0a80102')
+NULL
+SELECT INET6_ATON('1020::3040::5060');
+INET6_ATON('1020::3040::5060')
+NULL
+SELECT INET6_ATON('::ABCZ');
+INET6_ATON('::ABCZ')
+NULL
+
+# -- INET6_ATON: checking binary representation...
+
+SELECT HEX(INET6_ATON('1.2.3.4'));
+HEX(INET6_ATON('1.2.3.4'))
+01020304
+SELECT HEX(INET6_ATON('01.02.03.04'));
+HEX(INET6_ATON('01.02.03.04'))
+01020304
+SELECT HEX(INET6_ATON('0x01.0x02.0x03.0x04'));
+HEX(INET6_ATON('0x01.0x02.0x03.0x04'))
+01020304
+SELECT HEX(INET6_ATON('::'));
+HEX(INET6_ATON('::'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('0::0'));
+HEX(INET6_ATON('0::0'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('0::'));
+HEX(INET6_ATON('0::'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('::0'));
+HEX(INET6_ATON('::0'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('::1'));
+HEX(INET6_ATON('::1'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('0000:0000::0000:0001'));
+HEX(INET6_ATON('0000:0000::0000:0001'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('::C0A8:0102'));
+HEX(INET6_ATON('::C0A8:0102'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::c0a8:0102'));
+HEX(INET6_ATON('::c0a8:0102'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::192.168.1.2'));
+HEX(INET6_ATON('::192.168.1.2'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::FfFf:C0a8:0102'));
+HEX(INET6_ATON('::FfFf:C0a8:0102'))
+00000000000000000000FFFFC0A80102
+SELECT HEX(INET6_ATON('::ffff:c0a8:0102'));
+HEX(INET6_ATON('::ffff:c0a8:0102'))
+00000000000000000000FFFFC0A80102
+SELECT HEX(INET6_ATON('::ffff:192.168.1.2'));
+HEX(INET6_ATON('::ffff:192.168.1.2'))
+00000000000000000000FFFFC0A80102
+
+# -- INET6_ATON: checking the length is either 4 or 16...
+
+SELECT LENGTH(INET6_ATON('0.0.0.0'));
+LENGTH(INET6_ATON('0.0.0.0'))
+4
+SELECT LENGTH(INET6_ATON('255.255.255.255'));
+LENGTH(INET6_ATON('255.255.255.255'))
+4
+SELECT LENGTH(INET6_ATON('::'));
+LENGTH(INET6_ATON('::'))
+16
+SELECT LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'))
+16
+
+# -- INET6_NTOA: checking NULL, invalid types, out-of range values...
+
+SELECT INET6_NTOA(NULL);
+INET6_NTOA(NULL)
+NULL
+SELECT INET6_NTOA(123);
+INET6_NTOA(123)
+NULL
+SELECT INET6_NTOA(123.456);
+INET6_NTOA(123.456)
+NULL
+SELECT INET6_NTOA(NOW());
+INET6_NTOA(NOW())
+NULL
+SELECT INET6_NTOA(UNHEX('C0A801'));
+INET6_NTOA(UNHEX('C0A801'))
+NULL
+SELECT INET6_NTOA(UNHEX('C0A80102'));
+INET6_NTOA(UNHEX('C0A80102'))
+192.168.1.2
+SELECT INET6_NTOA(UNHEX('C0A8010203'));
+INET6_NTOA(UNHEX('C0A8010203'))
+NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F'))
+NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10'))
+102:304:506:708:90a:b0c:d0e:f10
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011'))
+NULL
+
+# -- Checking double-conversion...
+
+SELECT INET6_NTOA(INET6_ATON('::'));
+INET6_NTOA(INET6_ATON('::'))
+::
+SELECT INET6_NTOA(INET6_ATON('0::0'));
+INET6_NTOA(INET6_ATON('0::0'))
+::
+SELECT INET6_NTOA(INET6_ATON('0::'));
+INET6_NTOA(INET6_ATON('0::'))
+::
+SELECT INET6_NTOA(INET6_ATON('::0'));
+INET6_NTOA(INET6_ATON('::0'))
+::
+SELECT INET6_NTOA(INET6_ATON('::1'));
+INET6_NTOA(INET6_ATON('::1'))
+::1
+SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001'));
+INET6_NTOA(INET6_ATON('0000:0000::0000:0001'))
+::1
+SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'))
+::1
+SELECT INET6_NTOA(INET6_ATON('::C0A8:0102'));
+INET6_NTOA(INET6_ATON('::C0A8:0102'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::c0a8:0102'));
+INET6_NTOA(INET6_ATON('::c0a8:0102'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::192.168.1.2'));
+INET6_NTOA(INET6_ATON('::192.168.1.2'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::FFFF:C0A8:0102'));
+INET6_NTOA(INET6_ATON('::FFFF:C0A8:0102'))
+::ffff:192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'));
+INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'))
+::ffff:192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'));
+INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'))
+::ffff:192.168.1.2
+
+# -- Comparing INET_ATON() and INET6_ATON()...
+
+SELECT HEX(INET_ATON('192.168.1.2'));
+HEX(INET_ATON('192.168.1.2'))
+C0A80102
+SELECT HEX(INET6_ATON('192.168.1.2'));
+HEX(INET6_ATON('192.168.1.2'))
+C0A80102
+SELECT HEX(INET_ATON('255.255.255.255'));
+HEX(INET_ATON('255.255.255.255'))
+FFFFFFFF
+SELECT HEX(INET6_ATON('255.255.255.255'));
+HEX(INET6_ATON('255.255.255.255'))
+FFFFFFFF
+SELECT HEX(INET_ATON('192.168.08.2'));
+HEX(INET_ATON('192.168.08.2'))
+C0A80802
+SELECT HEX(INET6_ATON('192.168.08.2'));
+HEX(INET6_ATON('192.168.08.2'))
+NULL
+SELECT HEX(INET_ATON('192.168.0x8.2'));
+HEX(INET_ATON('192.168.0x8.2'))
+NULL
+SELECT HEX(INET6_ATON('192.168.0x8.2'));
+HEX(INET6_ATON('192.168.0x8.2'))
+C0A80802
+SELECT HEX(INET_ATON('192.168.1'));
+HEX(INET_ATON('192.168.1'))
+C0A80001
+SELECT INET_NTOA(INET_ATON('192.168.1'));
+INET_NTOA(INET_ATON('192.168.1'))
+192.168.0.1
+SELECT HEX(INET6_ATON('192.168.1'));
+HEX(INET6_ATON('192.168.1'))
+C0A80001
+SELECT INET6_NTOA(INET6_ATON('192.168.1'));
+INET6_NTOA(INET6_ATON('192.168.1'))
+192.168.0.1
+SELECT HEX(INET_ATON('192.168'));
+HEX(INET_ATON('192.168'))
+C00000A8
+SELECT INET_NTOA(INET_ATON('192.168'));
+INET_NTOA(INET_ATON('192.168'))
+192.0.0.168
+SELECT HEX(INET6_ATON('192.168'));
+HEX(INET6_ATON('192.168'))
+C00000A8
+SELECT INET6_NTOA(INET6_ATON('192.168'));
+INET6_NTOA(INET6_ATON('192.168'))
+192.0.0.168
+SELECT HEX(INET_ATON('192'));
+HEX(INET_ATON('192'))
+C0
+SELECT INET_NTOA(INET_ATON('192'));
+INET_NTOA(INET_ATON('192'))
+0.0.0.192
+SELECT HEX(INET6_ATON('192'));
+HEX(INET6_ATON('192'))
+000000C0
+SELECT INET6_NTOA(INET6_ATON('192'));
+INET6_NTOA(INET6_ATON('192'))
+0.0.0.192
+
+# -- Checking mix of INET- and INET6- functions...
+
+SELECT HEX(INET6_ATON(INET_NTOA(INET_ATON('1.2.3.4')))) AS x;
+x
+01020304
+
+# -- Working with a table...
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t1(ip INT UNSIGNED);
+CREATE TABLE t2(ip VARBINARY(16));
+CREATE TABLE t3 SELECT INET6_ATON('::1') AS ip;
+
+INSERT INTO t1 VALUES
+(INET_ATON('1.2.3.4')), (INET_ATON('255.255.255.255'));
+SELECT INET_NTOA(ip) FROM t1;
+INET_NTOA(ip)
+1.2.3.4
+255.255.255.255
+
+INSERT INTO t2 SELECT INET6_ATON(INET_NTOA(ip)) FROM t1;
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+INET6_NTOA(ip) HEX(ip) LENGTH(ip)
+1.2.3.4 01020304 4
+255.255.255.255 FFFFFFFF 4
+DELETE FROM t2;
+
+INSERT INTO t2 VALUES
+(INET6_ATON('1.2.3.4')), (INET6_ATON('255.255.255.255')),
+(INET6_ATON('::1.2.3.4')), (INET6_ATON('::ffff:255.255.255.255')),
+(INET6_ATON('::')), (INET6_ATON('::1')),
+(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+INET6_NTOA(ip) HEX(ip) LENGTH(ip)
+1.2.3.4 01020304 4
+255.255.255.255 FFFFFFFF 4
+::1.2.3.4 00000000000000000000000001020304 16
+::ffff:255.255.255.255 00000000000000000000FFFFFFFFFFFF 16
+:: 00000000000000000000000000000000 16
+::1 00000000000000000000000000000001 16
+1020:3040:5060:7080:90a0:b0c0:d0e0:f010 102030405060708090A0B0C0D0E0F010 16
+
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `ip` varbinary(16) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+# -- Done.
+
#
# End of tests
#
=== modified file 'mysql-test/t/func_misc.test'
--- a/mysql-test/t/func_misc.test 2010-12-17 11:28:59 +0000
+++ b/mysql-test/t/func_misc.test 2011-02-08 11:24:46 +0000
@@ -541,6 +541,181 @@ DROP TABLE t1;
--echo # End of 5.5 tests
--echo #
+--echo
+--echo # --
+--echo # -- WL#5787: IPv6-capable INET_ATON and INET_NTOA functions.
+--echo # --
+
+--echo
+--echo # -- INET6_ATON: checking NULL, invalid types, out-of range values...
+--echo
+
+SELECT INET6_ATON(NULL);
+SELECT INET6_ATON(123);
+SELECT INET6_ATON(123.45);
+SELECT INET6_ATON(NOW());
+SELECT INET6_ATON('256.1.2.12345678');
+SELECT INET6_ATON('-1.1.2.3');
+SELECT INET6_ATON('0xR.1.2.3');
+SELECT INET6_ATON('08.1.2.3');
+SELECT INET6_ATON('0A.1.2.3');
+SELECT INET6_ATON('mysql.com');
+SELECT INET6_ATON('1.2.3.4:80');
+SELECT INET6_ATON('1.2.3.4/32');
+SELECT INET6_ATON(':::');
+SELECT INET6_ATON('::c0a80102');
+SELECT INET6_ATON('1020::3040::5060');
+SELECT INET6_ATON('::ABCZ');
+
+--echo
+--echo # -- INET6_ATON: checking binary representation...
+--echo
+
+SELECT HEX(INET6_ATON('1.2.3.4'));
+SELECT HEX(INET6_ATON('01.02.03.04'));
+SELECT HEX(INET6_ATON('0x01.0x02.0x03.0x04'));
+SELECT HEX(INET6_ATON('::'));
+SELECT HEX(INET6_ATON('0::0'));
+SELECT HEX(INET6_ATON('0::'));
+SELECT HEX(INET6_ATON('::0'));
+SELECT HEX(INET6_ATON('::1'));
+SELECT HEX(INET6_ATON('0000:0000::0000:0001'));
+SELECT HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+SELECT HEX(INET6_ATON('::C0A8:0102'));
+SELECT HEX(INET6_ATON('::c0a8:0102'));
+SELECT HEX(INET6_ATON('::192.168.1.2'));
+SELECT HEX(INET6_ATON('::FfFf:C0a8:0102'));
+SELECT HEX(INET6_ATON('::ffff:c0a8:0102'));
+SELECT HEX(INET6_ATON('::ffff:192.168.1.2'));
+
+--echo
+--echo # -- INET6_ATON: checking the length is either 4 or 16...
+--echo
+
+SELECT LENGTH(INET6_ATON('0.0.0.0'));
+SELECT LENGTH(INET6_ATON('255.255.255.255'));
+SELECT LENGTH(INET6_ATON('::'));
+SELECT LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+
+--echo
+--echo # -- INET6_NTOA: checking NULL, invalid types, out-of range values...
+--echo
+
+SELECT INET6_NTOA(NULL);
+SELECT INET6_NTOA(123);
+SELECT INET6_NTOA(123.456);
+SELECT INET6_NTOA(NOW());
+SELECT INET6_NTOA(UNHEX('C0A801')); # 3 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('C0A80102')); # 4 bytes -> 192.168.1.2
+SELECT INET6_NTOA(UNHEX('C0A8010203')); # 5 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F')); # 15 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10')); # 16 bytes -> IP
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011')); # 17 bytes -> NULL
+
+--echo
+--echo # -- Checking double-conversion...
+--echo
+
+SELECT INET6_NTOA(INET6_ATON('::'));
+SELECT INET6_NTOA(INET6_ATON('0::0'));
+SELECT INET6_NTOA(INET6_ATON('0::'));
+SELECT INET6_NTOA(INET6_ATON('::0'));
+SELECT INET6_NTOA(INET6_ATON('::1'));
+SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001'));
+SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+SELECT INET6_NTOA(INET6_ATON('::C0A8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::c0a8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::192.168.1.2'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:C0A8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'));
+
+--echo
+--echo # -- Comparing INET_ATON() and INET6_ATON()...
+--echo
+
+SELECT HEX(INET_ATON('192.168.1.2'));
+SELECT HEX(INET6_ATON('192.168.1.2'));
+
+SELECT HEX(INET_ATON('255.255.255.255'));
+SELECT HEX(INET6_ATON('255.255.255.255'));
+
+SELECT HEX(INET_ATON('192.168.08.2'));
+SELECT HEX(INET6_ATON('192.168.08.2'));
+
+SELECT HEX(INET_ATON('192.168.0x8.2'));
+SELECT HEX(INET6_ATON('192.168.0x8.2'));
+
+SELECT HEX(INET_ATON('192.168.1'));
+SELECT INET_NTOA(INET_ATON('192.168.1'));
+SELECT HEX(INET6_ATON('192.168.1'));
+SELECT INET6_NTOA(INET6_ATON('192.168.1'));
+
+SELECT HEX(INET_ATON('192.168'));
+SELECT INET_NTOA(INET_ATON('192.168'));
+SELECT HEX(INET6_ATON('192.168'));
+SELECT INET6_NTOA(INET6_ATON('192.168'));
+
+SELECT HEX(INET_ATON('192'));
+SELECT INET_NTOA(INET_ATON('192'));
+SELECT HEX(INET6_ATON('192'));
+SELECT INET6_NTOA(INET6_ATON('192'));
+
+--echo
+--echo # -- Checking mix of INET- and INET6- functions...
+--echo
+
+SELECT HEX(INET6_ATON(INET_NTOA(INET_ATON('1.2.3.4')))) AS x;
+
+--echo
+--echo # -- Working with a table...
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE TABLE t1(ip INT UNSIGNED);
+CREATE TABLE t2(ip VARBINARY(16));
+CREATE TABLE t3 SELECT INET6_ATON('::1') AS ip;
+
+--echo
+
+INSERT INTO t1 VALUES
+ (INET_ATON('1.2.3.4')), (INET_ATON('255.255.255.255'));
+SELECT INET_NTOA(ip) FROM t1;
+
+--echo
+
+INSERT INTO t2 SELECT INET6_ATON(INET_NTOA(ip)) FROM t1;
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+DELETE FROM t2;
+
+--echo
+
+INSERT INTO t2 VALUES
+ (INET6_ATON('1.2.3.4')), (INET6_ATON('255.255.255.255')),
+ (INET6_ATON('::1.2.3.4')), (INET6_ATON('::ffff:255.255.255.255')),
+ (INET6_ATON('::')), (INET6_ATON('::1')),
+ (INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+
+--echo
+
+SHOW CREATE TABLE t3;
+
+--echo
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--echo
+--echo # -- Done.
+--echo
+
--echo #
--echo # End of tests
--echo #
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2010-12-02 13:44:21 +0000
+++ b/sql/item_create.cc 2011-02-08 11:24:46 +0000
@@ -1203,6 +1203,32 @@ protected:
};
+class Create_func_inet6_aton : public Create_func_arg1
+{
+public:
+ virtual Item *create(THD *thd, Item *arg1);
+
+ static Create_func_inet6_aton s_singleton;
+
+protected:
+ Create_func_inet6_aton() {}
+ virtual ~Create_func_inet6_aton() {}
+};
+
+
+class Create_func_inet6_ntoa : public Create_func_arg1
+{
+public:
+ virtual Item *create(THD *thd, Item *arg1);
+
+ static Create_func_inet6_ntoa s_singleton;
+
+protected:
+ Create_func_inet6_ntoa() {}
+ virtual ~Create_func_inet6_ntoa() {}
+};
+
+
class Create_func_instr : public Create_func_arg2
{
public:
@@ -3903,6 +3929,24 @@ Create_func_inet_ntoa::create(THD *thd,
}
+Create_func_inet6_aton Create_func_inet6_aton::s_singleton;
+
+Item*
+Create_func_inet6_aton::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_inet6_aton(arg1);
+}
+
+
+Create_func_inet6_ntoa Create_func_inet6_ntoa::s_singleton;
+
+Item*
+Create_func_inet6_ntoa::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_inet6_ntoa(arg1);
+}
+
+
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
@@ -5278,6 +5322,8 @@ static Native_func_registry func_array[]
{ { C_STRING_WITH_LEN("IFNULL") }, BUILDER(Create_func_ifnull)},
{ { C_STRING_WITH_LEN("INET_ATON") }, BUILDER(Create_func_inet_aton)},
{ { C_STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
+ { { C_STRING_WITH_LEN("INET6_ATON") }, BUILDER(Create_func_inet6_aton)},
+ { { C_STRING_WITH_LEN("INET6_NTOA") }, BUILDER(Create_func_inet6_ntoa)},
{ { C_STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
{ { C_STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
{ { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2011-01-17 12:35:58 +0000
+++ b/sql/item_strfunc.cc 2011-02-08 11:24:46 +0000
@@ -3547,6 +3547,172 @@ String* Item_func_inet_ntoa::val_str(Str
return str;
}
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+
+String *Item_func_inet6_aton::val_str_ascii(String *str)
+{
+ // ipv4-string -> varbinary(4)
+ // ipv6-string -> varbinary(16)
+
+ // Note: don't throw SQL-warning to be consistent with INET_ATON().
+
+ DBUG_ASSERT(fixed == 1);
+
+ if (args[0]->result_type() != STRING_RESULT)
+ {
+ DBUG_PRINT("error", ("INET6_ATON(): string argument expected."));
+ null_value= 1;
+ return NULL;
+ }
+
+ String *arg_str_value= args[0]->val_str(str);
+
+ if (!arg_str_value)
+ {
+ DBUG_PRINT("error", ("INET6_ATON(): not-NULL argument expected."));
+ null_value= 1;
+ return NULL;
+ }
+
+ bool is_ipv6_address= strchr(arg_str_value->ptr(), ':');
+
+ struct addrinfo hints;
+ bzero(&hints, sizeof (hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = is_ipv6_address ? AF_INET6 : AF_INET;
+
+ struct addrinfo *result;
+
+ int err_code= getaddrinfo(arg_str_value->ptr(), NULL, &hints, &result);
+
+ if (err_code)
+ {
+ DBUG_PRINT("error", ("INET6_ATON(): getaddrinfo('%s') failed with %d: %s",
+ arg_str_value->ptr(),
+ err_code, gai_strerror(err_code)));
+ null_value= 1;
+ return NULL;
+ }
+
+ if (!result)
+ {
+ sql_print_warning("INET6_ATON(): getaddrinfo('%s') succeeded, "
+ "but returned NULL.",
+ arg_str_value->ptr());
+ null_value= 1;
+ return NULL;
+ }
+
+ str->length(0);
+
+ if (is_ipv6_address)
+ {
+ sockaddr_in6 *ip6= (sockaddr_in6 *) result->ai_addr;
+ str->append((const char *) &ip6->sin6_addr, sizeof (struct in6_addr),
+ &my_charset_bin);
+ }
+ else
+ {
+ sockaddr_in *ip4= (sockaddr_in *) result->ai_addr;
+ str->append((const char *) &ip4->sin_addr, sizeof (struct in_addr),
+ &my_charset_bin);
+ }
+
+ freeaddrinfo(result);
+
+ return str;
+}
+
+
+String *Item_func_inet6_ntoa::val_str_ascii(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+
+ if (args[0]->result_type() != STRING_RESULT)
+ {
+ DBUG_PRINT("error", ("INET6_NTOA(): string argument expected."));
+ null_value= 1;
+ return NULL;
+ }
+
+ String *arg_str_value= args[0]->val_str(str);
+
+ if (!arg_str_value)
+ {
+ DBUG_PRINT("error", ("INET6_NTOA(): not-NULL argument expected."));
+ null_value= 1;
+ return NULL;
+ }
+
+ bool is_ipv4_address= arg_str_value->length() == 4;
+ bool is_ipv6_address= arg_str_value->length() == 16;
+
+ if (is_ipv4_address)
+ {
+ sockaddr_in ip4;
+ bzero(&ip4, sizeof (ip4));
+ ip4.sin_family = AF_INET;
+ memcpy(&ip4.sin_addr, arg_str_value->ptr(), 4);
+
+ char ip4_string[INET_ADDRSTRLEN];
+
+ int err_code= vio_getnameinfo((const sockaddr *) &ip4,
+ ip4_string, sizeof (ip4_string),
+ NULL, 0,
+ NI_NUMERICHOST);
+
+ if (err_code)
+ {
+ sql_print_warning("INET6_NTOA(): getnameinfo() failed with %d: %s",
+ err_code, gai_strerror(err_code));
+ null_value= 1;
+ return NULL;
+ }
+
+ str->length(0);
+ str->append(ip4_string, strlen(ip4_string), &my_charset_latin1);
+
+ return str;
+ }
+
+ if (is_ipv6_address)
+ {
+ sockaddr_in6 ip6;
+ bzero(&ip6, sizeof (ip6));
+ ip6.sin6_family = AF_INET6;
+ memcpy(&ip6.sin6_addr, arg_str_value->ptr(), 16);
+
+ char ip6_string[INET6_ADDRSTRLEN];
+
+ int err_code= vio_getnameinfo((const sockaddr *) &ip6,
+ ip6_string, sizeof (ip6_string),
+ NULL, 0,
+ NI_NUMERICHOST);
+
+ if (err_code)
+ {
+ sql_print_warning("INET6_NTOA(): getnameinfo() failed with %d: %s",
+ err_code, gai_strerror(err_code));
+ null_value= 1;
+ return NULL;
+ }
+
+ str->length(0);
+ str->append(ip6_string, strlen(ip6_string), &my_charset_latin1);
+
+ return str;
+ }
+
+ DBUG_PRINT("info",
+ ("INET6_NTOA(): varbinary(4) or varbinary(16) expected."));
+ null_value= 1;
+ return NULL;
+}
+
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h 2011-01-17 12:35:58 +0000
+++ b/sql/item_strfunc.h 2011-02-08 11:24:46 +0000
@@ -794,6 +794,55 @@ public:
}
};
+class Item_func_inet6_aton : public Item_str_ascii_func
+{
+public:
+ inline Item_func_inet6_aton(Item *ip_addr)
+ : Item_str_ascii_func(ip_addr)
+ { }
+
+public:
+ inline const char *func_name() const
+ { return "inet6_aton"; }
+
+ inline void fix_length_and_dec()
+ {
+ decimals= 0;
+ fix_length_and_charset(16, &my_charset_bin);
+ maybe_null= 1;
+ }
+
+public:
+ String *val_str_ascii(String *str);
+};
+
+class Item_func_inet6_ntoa : public Item_str_ascii_func
+{
+public:
+ inline Item_func_inet6_ntoa(Item *ip_addr)
+ : Item_str_ascii_func(ip_addr)
+ { }
+
+public:
+ inline const char *func_name() const
+ { return "inet6_ntoa"; }
+
+ inline void fix_length_and_dec()
+ {
+ decimals= 0;
+
+ // max length: IPv6-address -- 16 bytes
+ // 16 bytes / 2 bytes per group == 8 groups => 7 delimiter
+ // 4 symbols per group
+ fix_length_and_charset(8 * 4 + 7, default_charset());
+
+ maybe_null= 1;
+ }
+
+public:
+ String *val_str_ascii(String *str);
+};
+
class Item_func_quote :public Item_str_func
{
String tmp_value;
Attachment: [text/bzr-bundle] bzr/alexander.nozdrin@oracle.com-20110208112446-pp5sdjz7buj47hru.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk branch (alexander.nozdrin:3594) WL#5787 | Alexander Nozdrin | 8 Feb |