检查IP地址的整数值是否在PostgreSQL的私有范围内

时间:2013-03-18 17:46:38

标签: postgresql ip postgresql-8.3

我正在使用分离出版本8.3的PostgreSQL的MPP版本

我有一个包含一个名为ip_address的列的大表,它是inet,另一个名为hash_ip_address的列是bigint。 hash_ip_address列中的每个值都是使用hashinet函数从ip_address列转换的值。我试图使用整数值来确定地址是私有还是公共的。我遇到的问题是我没有看到检查IP地址的整数值是否为私有的一般方法,因为某些值为正,有些值为负,如下例所示:

select hashinet('10.10.0.1'::inet);
  hashinet
-------------
 -1939051471
(1 row)

select hashinet('10.0.0.4'::inet);
  hashinet
------------
 1510004552
(1 row)

有没有办法通过hashinet函数仅使用转换后的整数值来确定IP地址是否为私有?

编辑:这是来自http://doxygen.postgresql.org/network_8c.html#a0baabf8b98dbbcc39c6c1c814f9d86f8

的hashinet函数的定义

Datum hashinet(PG_FUNCTION_ARGS)

文件network.c的第527行定义。

引用hash_any(),ip_addrsize(),PG_GETARG_INET_PP和VARDATA_ANY。

{
    inet       *addr = PG_GETARG_INET_PP(0);
    int         addrsize = ip_addrsize(addr);

    /* XXX this assumes there are no pad bytes in the data structure */
    return hash_any((unsigned char *) VARDATA_ANY(addr), addrsize + 2);
}

1 个答案:

答案 0 :(得分:0)

哇。您正在使用文档中没有的内部PostgreSQL函数。

在我看来,像hashinet调用hash_any()这是一个真正的哈希,所以没有办法做到这一点。

如果你需要使用int而不仅仅是将任意int绑定到IP地址,那么更好的方法是通过创建一个新函数来创建你的ip地址到int:

 CREATE FUNCTION inet_to_int(inet) RETURNS INT language sql immutable AS 
 $$
 SELECT $1 - '0.0.0.0'::inet;
 $$;

然后使用它。从那里你的私人范围将对应于int范围,你可以更容易地检查。

例如,10/8地址为BETWEEN 167772160 AND 184549375 ....