Je crois avoir trouvé la solution. Cela implique d'abord de modifier les données, puis de masser l'entrée. Voici ce qui a fonctionné.
Tout d'abord, les données doivent être converties afin que toutes les adresses soient complètes, sans raccourcissement, avec les séparateurs point-virgule supprimés. Les exemples de données affichés dans ma question sont convertis en :
t_start | t_end | t_country_code
----------------------------------+----------------------------------+----------------
00000000000000000000000000000000 | 00ffffffffffffffffffffffffffffff | ZZ
01000000000000000000000000000000 | 01ffffffffffffffffffffffffffffff | ZZ
...
20000000000000000000000000000000 | 2000ffffffffffffffffffffffffffff | ZZ
...
20011200000000000000000000000000 | 20011200ffffffffffffffffffffffff | MX
...
C'est ce qui est stocké dans la base de données.
L'étape suivante consistait à convertir l'adresse IP reçue dans le code pour qu'elle soit dans le même format. Cela se fait en PHP avec le code suivant (supposons que $ip_address
est l'adresse IPv6 entrante) :
$addr_bin = inet_pton($ip_address);
$bytes = unpack('n*', $addr_bin);
$ip_address = implode('', array_map(function ($b) {return sprintf("%04x", $b); }, $bytes));
Maintenant la variable $ip_adress
contiendra l'adresse IPv6 complète, par exemple
:: => 00000000000000000000000000000000
2001:1200::ab => 200112000000000000000000000000ab
et ainsi de suite.
Maintenant, vous pouvez simplement comparer cette adresse complète avec les plages de la base de données. J'ai ajouté une deuxième fonction à la base de données pour gérer les adresses IPv6, qui ressemble à ceci :
CREATE OR REPLACE FUNCTION get_country_for_ipv6(character varying)
RETURNS character varying AS
$BODY$
declare
ip ALIAS for $1;
ccode varchar;
begin
select into ccode t_country_code from ipv6_to_country where addr between n_from and n_to limit 1;
if ccode is null then
ccode := '';
end if;
return ccode;
end;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Enfin, dans mon code php, j'ai ajouté le code qui appelle l'une ou l'autre fonction Postgres en fonction de l'entrée ip_address.