0

我正在使用 PostgreSQL 的 MPP 版本,它是从 8.3 版分叉出来的

我有一个大表,其中包含一个名为 ip_address 的列,它是 inet 和另一个名为 hash_ip_address 的列,它是 bigint。hash_ip_address 列中的每个值都是使用 hashnet 函数从 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)

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

编辑:这是来自http://doxygen.postgresql.org/network_8c.html#a0baabf8b98dbbcc39c6c1c814f9d86f8的 hashnet 函数的定义

基准哈希网 (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);
}
4

1 回答 1

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....

于 2013-03-22T01:38:27.287 回答