Если вдруг вам понадобилось базу IP2Location перевести из DECIMAL-представления IP-адресов в "родной" для PostgreSQL тип inet, то для IPv4-адресов все будет тривиально:
'0.0.0.0'::inet + ipnum::bigint
А вот для преобразования числа к формату IPv6-адреса придется проявить немного изобретательности:
"математически" разбиваем число на 8 двухбайтовых сегментов по
(2 ^ 16) ^ iкаждое значение преобразуем в шестнадцатиричную систему счисления и добиваем лидирующими нулями
склеиваем сегменты через двоеточие и кастуем к
inet
array_to_string(ARRAY( SELECT lpad(to_hex(trunc( ipnum % (2::numeric(39,0) ^ ((i + 1) * 16)) / (2::numeric(39,0) ^ (i * 16)) )::integer), 4, '0') FROM generate_series(7, 0, -1) i ), ':')::inet
В принципе, после этого мы можем "свернуть" ip_from и ip_to в подсеть, не обращая внимания на исходный формат:
inet_merge(ip_from, ip_to) subnet
А если проиндексируем эти подсети с помощью gist...
CREATE INDEX ON country_inet USING gist(subnet inet_ops);
... то сможем по индексу быстро определять принадлежность произвольного IPv4/IPv6-адреса подсетям с помощью соответствующих операторов примерно таким запросом:
SELECT * FROM country_inet WHERE subnet >> '8.8.8.8' AND country <> '-' ORDER BY masklen(subnet) DESC LIMIT 1;
