I am using MySQL 5.6, experimenting with the new features, like INET6_ATON
and IS_IPV6
.
When the script reads IPV4
, it inserts the data into the table perfectly. But when it comes to IPv6
, one of the rows (ipTo)
fails, even though the INET6_ATON
works alone.
My Table: 4 fileds
`geoIPID` INT NOT NULL AUTO_INCREMENT ,
`IPFrom` VARBINARY(16) NOT NULL ,
`IPTo` VARBINARY(16) NOT NULL ,
`countries_countryID` INT NOT NULL
A script, which loads the text files into table:
LOAD DATA LOCAL INFILE '/Users/Invictus/Documents/htdocs/overkill/etcs/IPV6.csv'
INTO TABLE `overkill`.`geoIP`
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(@IPFrom, @IPTo, @dummy, @dummy, @countryAbbreviation, @dummy)
SET IPFrom = IF(IS_IPV4(@IPFrom),
INET_ATON(@IPFrom),
INET6_ATON(@IPFrom)),
IPTo = IF(IS_IPV4(@IPTo),
INET_ATON(@IPTo),
INET6_ATON(@IPTo)),
countries_countryID =
(
SELECT IF (COUNT(*) != 0, `countries`.`countryID`, 999)
FROM `countries`
WHERE `countries`.`countryAbbreviation` = @countryAbbreviation
LIMIT 1
);
The IPV4.csv file, like this:
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
The IPV6.csv file, like this:
"2001:200::", "2001:200:ffff:ffff:ffff:ffff:ffff:ffff", "42540528726795050063891204319802818560", "42540528806023212578155541913346768895", "JP", "Japan"
"2001:208::", "2001:208:ffff:ffff:ffff:ffff:ffff:ffff", "42540529360620350178005905068154421248", "42540529439848512692270242661698371583", "SG", "Singapore"
"2001:218::", "2001:218:ffff:ffff:ffff:ffff:ffff:ffff", "42540530628270950406235306564857626624", "42540530707499112920499644158401576959", "JP", "Japan"
My problem:
In case I load the IPv6
, the second row (ipTo)
is NULL
. Why? All the values in the files are valid, still, MySQL does not convert them.
The problem not in INET6_ATON
but in your IPV6.csv
file. Unlike IPV4.csv
you have extra spaces after commas and that makes LOAD DATA
read your second field like this
"2001:200:ffff:ffff:ffff:ffff:ffff:ffff"
^^ ^
and that is why INET6_ATON
returns NULL
.
To fix this:
FIELDS TERMINATED BY ', '
Besides you can simplify your query and just use INET6_ATON
instead of conditionally switching between INET_ATON
and INET6_ATON
. The latter works just fine with both IPV4 and IPV6.
That being said your query might look like this (assuming that you don't have extra spaces in csv file)
LOAD DATA LOCAL INFILE '/Users/Invictus/Documents/htdocs/overkill/etcs/IPV6.csv'
INTO TABLE `overkill`.`geoIP`
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(@ipfrom, @ipto, @dummy, @dummy, @abbr, @dummy)
SET IPFrom = INET6_ATON(@ipfrom),
IPTo = INET6_ATON(@ipto),
countries_countryID =
(
SELECT IF(COUNT(*) != 0, `countries`.`countryID`, 999)
FROM `countries`
WHERE `countries`.`countryAbbreviation` = @abbr
LIMIT 1
);
To test things out I've removed extra spaces, combined both of your files, and loaded them into ipv6
table. Here is the result
mysql> select geoIPID, HEX(ipfrom), HEX(ipto) from ipv6; +---------+----------------------------------+----------------------------------+ | geoIPID | HEX(ipfrom) | HEX(ipto) | +---------+----------------------------------+----------------------------------+ | 1 | 20010200000000000000000000000000 | 20010200FFFFFFFFFFFFFFFFFFFFFFFF | | 2 | 20010208000000000000000000000000 | 20010208FFFFFFFFFFFFFFFFFFFFFFFF | | 3 | 20010218000000000000000000000000 | 20010218FFFFFFFFFFFFFFFFFFFFFFFF | | 4 | 01000000 | 010000FF | | 5 | 01000100 | 010003FF | | 6 | 01000400 | 010007FF | +---------+----------------------------------+----------------------------------+ 6 rows in set (0.00 sec) mysql> select geoIPID, INET6_NTOA(ipfrom), INET6_NTOA(ipto) from ipv6; +---------+--------------------+----------------------------------------+ | geoIPID | INET6_NTOA(ipfrom) | INET6_NTOA(ipto) | +---------+--------------------+----------------------------------------+ | 1 | 2001:200:: | 2001:200:ffff:ffff:ffff:ffff:ffff:ffff | | 2 | 2001:208:: | 2001:208:ffff:ffff:ffff:ffff:ffff:ffff | | 3 | 2001:218:: | 2001:218:ffff:ffff:ffff:ffff:ffff:ffff | | 4 | 1.0.0.0 | 1.0.0.255 | | 5 | 1.0.1.0 | 1.0.3.255 | | 6 | 1.0.4.0 | 1.0.7.255 | +---------+--------------------+----------------------------------------+ 6 rows in set (0.00 sec)