List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:February 8 2011 11:24am
Subject:bzr commit into mysql-trunk branch (alexander.nozdrin:3594) WL#5787
View as plain text  
#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#5787Alexander Nozdrin8 Feb