26#include "utils/fmgroids.h"
40#define ABBREV_BITS_INET4_NETMASK_SIZE 6
41#define ABBREV_BITS_INET4_SUBNET 25
65static bool addressOK(
unsigned char *
a,
int bits,
int family);
86 if (strchr(src,
':') != NULL)
95 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
97 errmsg(
"invalid input syntax for type %s: \"%s\"",
98 is_cidr ?
"cidr" :
"inet", src)));
107 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
108 errmsg(
"invalid cidr value: \"%s\"", src),
109 errdetail(
"Value has bits set to right of mask.")));
141 char tmp[
sizeof(
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
149 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
150 errmsg(
"could not format inet value: %m")));
153 if (is_cidr && strchr(tmp,
'/') == NULL)
205 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
207 errmsg(
"invalid address family in external \"%s\" value",
208 is_cidr ?
"cidr" :
"inet")));
212 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
214 errmsg(
"invalid bits in external \"%s\" value",
215 is_cidr ?
"cidr" :
"inet")));
221 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
223 errmsg(
"invalid length in external \"%s\" value",
224 is_cidr ?
"cidr" :
"inet")));
226 addrptr = (
char *)
ip_addr(addr);
227 for (
i = 0;
i < nb;
i++)
237 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
238 errmsg(
"invalid external \"cidr\" value"),
239 errdetail(
"Value has bits set to right of mask.")));
281 addrptr = (
char *)
ip_addr(addr);
282 for (
i = 0;
i < nb;
i++)
314 elog(
ERROR,
"invalid inet bit length: %d", bits);
331 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
332 errmsg(
"invalid mask length: %d", bits)));
354 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
355 errmsg(
"invalid mask length: %d", bits)));
380 ip_addr(dst)[bits / 8] &= ~(0xFF >> (bits % 8));
489 if (memtupcount < 10000 || uss->input_count < 10000 || !uss->estimating)
500 if (abbr_card > 100000.0)
504 "network_abbrev: estimation ends at cardinality %f"
517 if (abbr_card < uss->input_count / 2000.0 + 0.5)
521 "network_abbrev: aborting abbreviation at cardinality %f"
522 " below threshold %f after " INT64_FORMAT " values (%d rows)",
531 " values (%d rows)", abbr_card, uss->
input_count, memtupcount);
619 memcpy(&ipaddr_datum32,
ip_addr(authoritative),
sizeof(
uint32));
622#ifndef WORDS_BIGENDIAN
625 ipaddr_datum = ipaddr_datum32;
633 memcpy(&ipaddr_datum,
ip_addr(authoritative),
sizeof(
Datum));
661 if (
ip_bits(authoritative) == 0)
664 subnet_bitmask = ((
Datum) 0) - 1;
670 subnet_bitmask = (((
Datum) 1) << subnet_size) - 1;
671 network = ipaddr_datum & ~subnet_bitmask;
677 network = ipaddr_datum;
706 subnet = ipaddr_datum & subnet_bitmask;
725 res |= network | netmask_size | subnet;
1002 case F_NETWORK_SUBEQ:
1014 case F_NETWORK_SUPEQ:
1043 Oid datatype = INETOID;
1058 ((
Const *) rightop)->constisnull)
1060 rightopval = ((
Const *) rightop)->constvalue;
1096 result =
lappend(result, expr);
1110 char tmp[
sizeof(
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1114 tmp,
sizeof(tmp)) == NULL)
1116 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1117 errmsg(
"could not format inet value: %m")));
1120 if ((ptr = strchr(tmp,
'/')) != NULL)
1136 char tmp[
sizeof(
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1139 tmp,
sizeof(tmp)) == NULL)
1141 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1142 errmsg(
"could not format inet value: %m")));
1145 if (strchr(tmp,
'/') == NULL)
1159 char tmp[
sizeof(
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1162 ip_bits(ip), tmp,
sizeof(tmp));
1166 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1167 errmsg(
"could not format inet value: %m")));
1177 char tmp[
sizeof(
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1180 ip_bits(ip), tmp,
sizeof(tmp));
1184 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1185 errmsg(
"could not format cidr value: %m")));
1237 for (
byte = 0;
byte < maxbytes;
byte++)
1248 mask = 0xff >> bits;
1252 b[byte] =
a[byte] | mask;
1291 mask = 0xff << (8 - bits);
1295 b[byte] =
a[byte] & mask;
1333 mask = 0xff << (8 - bits);
1366 byte = maxbytes - 1;
1377 mask = 0xff >> (8 - bits);
1417 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1418 errmsg(
"cannot merge addresses from different families")));
1456 for (
i = 0;
i <
len;
i++)
1468 res = (mac->
a << 16) | (mac->
b << 8) | (mac->
c);
1469 res *= 256 * 256 * 256;
1470 res += (mac->
d << 16) | (mac->
e << 8) | (mac->
f);
1478 res = (mac->
a << 24) | (mac->
b << 16) | (mac->
c << 8) | (mac->
d);
1479 res *= ((double) 256) * 256 * 256 * 256;
1480 res += (mac->
e << 24) | (mac->
f << 16) | (mac->
g << 8) | (mac->
h);
1502bitncmp(
const unsigned char *l,
const unsigned char *r,
int n)
1510 x = memcmp(l, r,
b);
1511 if (
x || (n % 8) == 0)
1516 for (
b = n % 8;
b > 0;
b--)
1545 for (
byte = 0;
byte < n / 8;
byte++)
1547 if (l[
byte] != r[
byte])
1559 unsigned int diff = l[byte] ^ r[byte];
1562 while ((diff >> (8 - nbits)) != 0)
1566 return (8 *
byte) + nbits;
1594 if (bits == maxbits)
1604 while (
byte < maxbytes)
1606 if ((
a[
byte] & mask) != 0)
1652 char remote_host[NI_MAXHOST];
1658 switch (
port->raddr.addr.ss_family)
1667 remote_host[0] =
'\0';
1670 remote_host,
sizeof(remote_host),
1672 NI_NUMERICHOST | NI_NUMERICSERV);
1689 char remote_port[NI_MAXSERV];
1695 switch (
port->raddr.addr.ss_family)
1704 remote_port[0] =
'\0';
1708 remote_port,
sizeof(remote_port),
1709 NI_NUMERICHOST | NI_NUMERICSERV);
1724 char local_host[NI_MAXHOST];
1730 switch (
port->laddr.addr.ss_family)
1739 local_host[0] =
'\0';
1742 local_host,
sizeof(local_host),
1744 NI_NUMERICHOST | NI_NUMERICSERV);
1761 char local_port[NI_MAXSERV];
1767 switch (
port->laddr.addr.ss_family)
1776 local_port[0] =
'\0';
1780 local_port,
sizeof(local_port),
1781 NI_NUMERICHOST | NI_NUMERICSERV);
1799 unsigned char *pip =
ip_addr(ip);
1800 unsigned char *pdst =
ip_addr(dst);
1803 pdst[nb] = ~pip[nb];
1825 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1826 errmsg(
"cannot AND inet values of different sizes")));
1830 unsigned char *pip =
ip_addr(ip);
1831 unsigned char *pip2 =
ip_addr(ip2);
1832 unsigned char *pdst =
ip_addr(dst);
1835 pdst[nb] = pip[nb] & pip2[nb];
1857 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1858 errmsg(
"cannot OR inet values of different sizes")));
1862 unsigned char *pip =
ip_addr(ip);
1863 unsigned char *pip2 =
ip_addr(ip2);
1864 unsigned char *pdst =
ip_addr(dst);
1867 pdst[nb] = pip[nb] | pip2[nb];
1887 unsigned char *pip =
ip_addr(ip);
1888 unsigned char *pdst =
ip_addr(dst);
1893 carry = pip[nb] + (int) (addend & 0xFF) + carry;
1894 pdst[nb] = (
unsigned char) (carry & 0xFF);
1906 addend &= ~((
int64) 0xFF);
1915 if (!((addend == 0 && carry == 0) ||
1916 (addend == -1 && carry == 1)))
1918 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1919 errmsg(
"result is out of range")));
1959 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1960 errmsg(
"cannot subtract inet values of different sizes")));
1971 unsigned char *pip =
ip_addr(ip);
1972 unsigned char *pip2 =
ip_addr(ip2);
1979 carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
1980 lobyte = carry & 0xFF;
1981 if (
byte <
sizeof(
int64))
1983 res |= ((
int64) lobyte) << (
byte * 8);
1992 if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
1994 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1995 errmsg(
"result is out of range")));
2005 if (carry == 0 &&
byte <
sizeof(
int64))
2030 if (addr_family == AF_INET6)
2032 char *pct = strchr(addr,
'%');
#define IS_HIGHBIT_SET(ch)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define ereport(elevel,...)
#define PG_RETURN_BYTEA_P(x)
#define DirectFunctionCall2(func, arg1, arg2)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define PG_RETURN_INT64(x)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_CSTRING(n)
#define PG_GETARG_INT64(n)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_DATUM(x)
#define PG_RETURN_POINTER(x)
#define PG_RETURN_BOOL(x)
static Datum hash_uint32(uint32 k)
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
static Datum hash_any(const unsigned char *k, int keylen)
Assert(PointerIsAligned(start, uint64))
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
double estimateHyperLogLog(hyperLogLogState *cState)
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
char * pg_inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
int pg_inet_net_pton(int af, const char *src, void *dst, size_t size)
Datum int4in(PG_FUNCTION_ARGS)
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
List * lappend(List *list, void *datum)
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
char * pstrdup(const char *in)
void * palloc0(Size size)
Datum inet_server_addr(PG_FUNCTION_ARGS)
Datum hashinet(PG_FUNCTION_ARGS)
static List * match_network_subset(Node *leftop, Node *rightop, bool is_eq, Oid opfamily)
static int network_fast_cmp(Datum x, Datum y, SortSupport ssup)
Datum inet_send(PG_FUNCTION_ARGS)
static List * match_network_function(Node *leftop, Node *rightop, int indexarg, Oid funcid, Oid opfamily)
void clean_ipv6_addr(int addr_family, char *addr)
Datum cidr_out(PG_FUNCTION_ARGS)
Datum inet_client_addr(PG_FUNCTION_ARGS)
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
inet * cidr_set_masklen_internal(const inet *src, int bits)
Datum network_hostmask(PG_FUNCTION_ARGS)
Datum network_scan_last(Datum in)
Datum network_overlap(PG_FUNCTION_ARGS)
static inet * network_in(char *src, bool is_cidr, Node *escontext)
Datum inet_to_cidr(PG_FUNCTION_ARGS)
Datum inet_abbrev(PG_FUNCTION_ARGS)
Datum inetand(PG_FUNCTION_ARGS)
Datum network_subset_support(PG_FUNCTION_ARGS)
Datum network_sup(PG_FUNCTION_ARGS)
Datum network_host(PG_FUNCTION_ARGS)
Datum network_supeq(PG_FUNCTION_ARGS)
Datum inetpl(PG_FUNCTION_ARGS)
Datum cidr_abbrev(PG_FUNCTION_ARGS)
Datum inet_server_port(PG_FUNCTION_ARGS)
static bool addressOK(unsigned char *a, int bits, int family)
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Datum network_netmask(PG_FUNCTION_ARGS)
Datum network_broadcast(PG_FUNCTION_ARGS)
Datum network_smaller(PG_FUNCTION_ARGS)
Datum inetor(PG_FUNCTION_ARGS)
Datum inet_set_masklen(PG_FUNCTION_ARGS)
static inet * network_recv(StringInfo buf, bool is_cidr)
Datum inet_in(PG_FUNCTION_ARGS)
Datum inetnot(PG_FUNCTION_ARGS)
Datum network_ge(PG_FUNCTION_ARGS)
#define ABBREV_BITS_INET4_SUBNET
Datum inetmi_int8(PG_FUNCTION_ARGS)
Datum inet_same_family(PG_FUNCTION_ARGS)
double convert_network_to_scalar(Datum value, Oid typid, bool *failure)
Datum hashinetextended(PG_FUNCTION_ARGS)
Datum cidr_send(PG_FUNCTION_ARGS)
Datum network_sub(PG_FUNCTION_ARGS)
Datum network_ne(PG_FUNCTION_ARGS)
#define ABBREV_BITS_INET4_NETMASK_SIZE
Datum network_le(PG_FUNCTION_ARGS)
Datum network_sortsupport(PG_FUNCTION_ARGS)
Datum cidr_recv(PG_FUNCTION_ARGS)
Datum inet_client_port(PG_FUNCTION_ARGS)
static inet * internal_inetpl(inet *ip, int64 addend)
Datum inetmi(PG_FUNCTION_ARGS)
Datum cidr_set_masklen(PG_FUNCTION_ARGS)
Datum network_family(PG_FUNCTION_ARGS)
Datum network_show(PG_FUNCTION_ARGS)
static int32 network_cmp_internal(inet *a1, inet *a2)
Datum network_lt(PG_FUNCTION_ARGS)
static bytea * network_send(inet *addr, bool is_cidr)
Datum network_eq(PG_FUNCTION_ARGS)
static char * network_out(inet *src, bool is_cidr)
Datum network_subeq(PG_FUNCTION_ARGS)
Datum network_gt(PG_FUNCTION_ARGS)
Datum inet_merge(PG_FUNCTION_ARGS)
Datum inet_recv(PG_FUNCTION_ARGS)
Datum network_cmp(PG_FUNCTION_ARGS)
Datum network_larger(PG_FUNCTION_ARGS)
Datum network_network(PG_FUNCTION_ARGS)
static Datum network_abbrev_convert(Datum original, SortSupport ssup)
static bool network_abbrev_abort(int memtupcount, SortSupport ssup)
Datum network_masklen(PG_FUNCTION_ARGS)
Datum network_scan_first(Datum in)
Datum inet_out(PG_FUNCTION_ARGS)
Datum cidr_in(PG_FUNCTION_ARGS)
static bool is_opclause(const void *clause)
static bool is_funcclause(const void *clause)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static uint32 pg_bswap32(uint32 x)
#define DatumBigEndianToNative(x)
static int list_length(const List *l)
char * pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
static uint32 DatumGetUInt32(Datum X)
static uint64 DatumGetUInt64(Datum X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
struct SortSupportData * SortSupport
struct StringInfoData * StringInfo
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
hyperLogLogState abbr_card
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
#define PG_RETURN_INET_P(x)
static macaddr8 * DatumGetMacaddr8P(Datum X)
static inet * DatumGetInetPP(Datum X)
#define SET_INET_VARSIZE(dst)
#define PG_GETARG_INET_PP(n)
#define ip_family(inetptr)
static macaddr * DatumGetMacaddrP(Datum X)
#define ip_addrsize(inetptr)
#define ip_maxbits(inetptr)
static Size VARSIZE_ANY(const void *PTR)
static char * VARDATA_ANY(const void *PTR)
text * cstring_to_text(const char *s)