2 * PostgreSQL type definitions for the INET and CIDR types.
4 * src/backend/utils/adt/network.c
6 * Jon Postel RIP 16 Oct 1998
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
15 #include "access/stratnum.h"
16 #include "catalog/pg_opfamily.h"
17 #include "catalog/pg_type.h"
18 #include "common/hashfn.h"
19 #include "common/ip.h"
20 #include "lib/hyperloglog.h"
21 #include "libpq/libpq-be.h"
22 #include "libpq/pqformat.h"
23 #include "miscadmin.h"
24 #include "nodes/makefuncs.h"
25 #include "nodes/nodeFuncs.h"
26 #include "nodes/supportnodes.h"
27 #include "utils/builtins.h"
28 #include "utils/fmgroids.h"
29 #include "utils/guc.h"
30 #include "utils/inet.h"
31 #include "utils/lsyscache.h"
32 #include "utils/sortsupport.h"
36 * An IPv4 netmask size is a value in the range of 0 - 32, which is
37 * represented with 6 bits in inet/cidr abbreviated keys where possible.
39 * An IPv4 inet/cidr abbreviated key can use up to 25 bits for subnet
42 #define ABBREV_BITS_INET4_NETMASK_SIZE 6
43 #define ABBREV_BITS_INET4_SUBNET 25
45 /* sortsupport for inet/cidr */
48 int64 input_count
; /* number of non-null values seen */
49 bool estimating
; /* true if estimating cardinality */
51 hyperLogLogState abbr_card
; /* cardinality estimator */
52 } network_sortsupport_state
;
54 static int32
network_cmp_internal(inet
*a1
, inet
*a2
);
55 static int network_fast_cmp(Datum x
, Datum y
, SortSupport ssup
);
56 static bool network_abbrev_abort(int memtupcount
, SortSupport ssup
);
57 static Datum
network_abbrev_convert(Datum original
, SortSupport ssup
);
58 static List
*match_network_function(Node
*leftop
,
63 static List
*match_network_subset(Node
*leftop
,
67 static bool addressOK(unsigned char *a
, int bits
, int family
);
68 static inet
*internal_inetpl(inet
*ip
, int64 addend
);
72 * Common INET/CIDR input routine
75 network_in(char *src
, bool is_cidr
, Node
*escontext
)
80 dst
= (inet
*) palloc0(sizeof(inet
));
83 * First, check to see if this is an IPv6 or IPv4 address. IPv6 addresses
84 * will have a : somewhere in them (several, in fact) so if there is one
85 * present, assume it's V6, otherwise assume it's V4.
88 if (strchr(src
, ':') != NULL
)
89 ip_family(dst
) = PGSQL_AF_INET6
;
91 ip_family(dst
) = PGSQL_AF_INET
;
93 bits
= pg_inet_net_pton(ip_family(dst
), src
, ip_addr(dst
),
94 is_cidr
? ip_addrsize(dst
) : -1);
95 if ((bits
< 0) || (bits
> ip_maxbits(dst
)))
96 ereturn(escontext
, NULL
,
97 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION
),
98 /* translator: first %s is inet or cidr */
99 errmsg("invalid input syntax for type %s: \"%s\"",
100 is_cidr
? "cidr" : "inet", src
)));
103 * Error check: CIDR values must not have any bits set beyond the masklen.
107 if (!addressOK(ip_addr(dst
), bits
, ip_family(dst
)))
108 ereturn(escontext
, NULL
,
109 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION
),
110 errmsg("invalid cidr value: \"%s\"", src
),
111 errdetail("Value has bits set to right of mask.")));
115 SET_INET_VARSIZE(dst
);
121 inet_in(PG_FUNCTION_ARGS
)
123 char *src
= PG_GETARG_CSTRING(0);
125 PG_RETURN_INET_P(network_in(src
, false, fcinfo
->context
));
129 cidr_in(PG_FUNCTION_ARGS
)
131 char *src
= PG_GETARG_CSTRING(0);
133 PG_RETURN_INET_P(network_in(src
, true, fcinfo
->context
));
138 * Common INET/CIDR output routine
141 network_out(inet
*src
, bool is_cidr
)
143 char tmp
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
147 dst
= pg_inet_net_ntop(ip_family(src
), ip_addr(src
), ip_bits(src
),
151 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
152 errmsg("could not format inet value: %m")));
154 /* For CIDR, add /n if not present */
155 if (is_cidr
&& strchr(tmp
, '/') == NULL
)
158 snprintf(tmp
+ len
, sizeof(tmp
) - len
, "/%u", ip_bits(src
));
165 inet_out(PG_FUNCTION_ARGS
)
167 inet
*src
= PG_GETARG_INET_PP(0);
169 PG_RETURN_CSTRING(network_out(src
, false));
173 cidr_out(PG_FUNCTION_ARGS
)
175 inet
*src
= PG_GETARG_INET_PP(0);
177 PG_RETURN_CSTRING(network_out(src
, true));
182 * network_recv - converts external binary format to inet
184 * The external representation is (one byte apiece for)
185 * family, bits, is_cidr, address length, address in network byte order.
187 * Presence of is_cidr is largely for historical reasons, though it might
188 * allow some code-sharing on the client side. We send it correctly on
189 * output, but ignore the value on input.
192 network_recv(StringInfo buf
, bool is_cidr
)
200 /* make sure any unused bits in a CIDR value are zeroed */
201 addr
= (inet
*) palloc0(sizeof(inet
));
203 ip_family(addr
) = pq_getmsgbyte(buf
);
204 if (ip_family(addr
) != PGSQL_AF_INET
&&
205 ip_family(addr
) != PGSQL_AF_INET6
)
207 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
208 /* translator: %s is inet or cidr */
209 errmsg("invalid address family in external \"%s\" value",
210 is_cidr
? "cidr" : "inet")));
211 bits
= pq_getmsgbyte(buf
);
212 if (bits
< 0 || bits
> ip_maxbits(addr
))
214 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
215 /* translator: %s is inet or cidr */
216 errmsg("invalid bits in external \"%s\" value",
217 is_cidr
? "cidr" : "inet")));
218 ip_bits(addr
) = bits
;
219 i
= pq_getmsgbyte(buf
); /* ignore is_cidr */
220 nb
= pq_getmsgbyte(buf
);
221 if (nb
!= ip_addrsize(addr
))
223 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
224 /* translator: %s is inet or cidr */
225 errmsg("invalid length in external \"%s\" value",
226 is_cidr
? "cidr" : "inet")));
228 addrptr
= (char *) ip_addr(addr
);
229 for (i
= 0; i
< nb
; i
++)
230 addrptr
[i
] = pq_getmsgbyte(buf
);
233 * Error check: CIDR values must not have any bits set beyond the masklen.
237 if (!addressOK(ip_addr(addr
), bits
, ip_family(addr
)))
239 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
240 errmsg("invalid external \"cidr\" value"),
241 errdetail("Value has bits set to right of mask.")));
244 SET_INET_VARSIZE(addr
);
250 inet_recv(PG_FUNCTION_ARGS
)
252 StringInfo buf
= (StringInfo
) PG_GETARG_POINTER(0);
254 PG_RETURN_INET_P(network_recv(buf
, false));
258 cidr_recv(PG_FUNCTION_ARGS
)
260 StringInfo buf
= (StringInfo
) PG_GETARG_POINTER(0);
262 PG_RETURN_INET_P(network_recv(buf
, true));
267 * network_send - converts inet to binary format
270 network_send(inet
*addr
, bool is_cidr
)
277 pq_begintypsend(&buf
);
278 pq_sendbyte(&buf
, ip_family(addr
));
279 pq_sendbyte(&buf
, ip_bits(addr
));
280 pq_sendbyte(&buf
, is_cidr
);
281 nb
= ip_addrsize(addr
);
284 pq_sendbyte(&buf
, nb
);
285 addrptr
= (char *) ip_addr(addr
);
286 for (i
= 0; i
< nb
; i
++)
287 pq_sendbyte(&buf
, addrptr
[i
]);
288 return pq_endtypsend(&buf
);
292 inet_send(PG_FUNCTION_ARGS
)
294 inet
*addr
= PG_GETARG_INET_PP(0);
296 PG_RETURN_BYTEA_P(network_send(addr
, false));
300 cidr_send(PG_FUNCTION_ARGS
)
302 inet
*addr
= PG_GETARG_INET_PP(0);
304 PG_RETURN_BYTEA_P(network_send(addr
, true));
309 inet_to_cidr(PG_FUNCTION_ARGS
)
311 inet
*src
= PG_GETARG_INET_PP(0);
317 if ((bits
< 0) || (bits
> ip_maxbits(src
)))
318 elog(ERROR
, "invalid inet bit length: %d", bits
);
320 PG_RETURN_INET_P(cidr_set_masklen_internal(src
, bits
));
324 inet_set_masklen(PG_FUNCTION_ARGS
)
326 inet
*src
= PG_GETARG_INET_PP(0);
327 int bits
= PG_GETARG_INT32(1);
331 bits
= ip_maxbits(src
);
333 if ((bits
< 0) || (bits
> ip_maxbits(src
)))
335 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
336 errmsg("invalid mask length: %d", bits
)));
338 /* clone the original data */
339 dst
= (inet
*) palloc(VARSIZE_ANY(src
));
340 memcpy(dst
, src
, VARSIZE_ANY(src
));
344 PG_RETURN_INET_P(dst
);
348 cidr_set_masklen(PG_FUNCTION_ARGS
)
350 inet
*src
= PG_GETARG_INET_PP(0);
351 int bits
= PG_GETARG_INT32(1);
354 bits
= ip_maxbits(src
);
356 if ((bits
< 0) || (bits
> ip_maxbits(src
)))
358 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
359 errmsg("invalid mask length: %d", bits
)));
361 PG_RETURN_INET_P(cidr_set_masklen_internal(src
, bits
));
365 * Copy src and set mask length to 'bits' (which must be valid for the family)
368 cidr_set_masklen_internal(const inet
*src
, int bits
)
370 inet
*dst
= (inet
*) palloc0(sizeof(inet
));
372 ip_family(dst
) = ip_family(src
);
377 Assert(bits
<= ip_maxbits(dst
));
379 /* Clone appropriate bytes of the address, leaving the rest 0 */
380 memcpy(ip_addr(dst
), ip_addr(src
), (bits
+ 7) / 8);
382 /* Clear any unwanted bits in the last partial byte */
384 ip_addr(dst
)[bits
/ 8] &= ~(0xFF >> (bits
% 8));
387 /* Set varlena header correctly */
388 SET_INET_VARSIZE(dst
);
394 * Basic comparison function for sorting and inet/cidr comparisons.
396 * Comparison is first on the common bits of the network part, then on
397 * the length of the network part, and then on the whole unmasked address.
398 * The effect is that the network part is the major sort key, and for
399 * equal network parts we sort on the host part. Note this is only sane
400 * for CIDR if address bits to the right of the mask are guaranteed zero;
401 * otherwise logically-equal CIDRs might compare different.
405 network_cmp_internal(inet
*a1
, inet
*a2
)
407 if (ip_family(a1
) == ip_family(a2
))
411 order
= bitncmp(ip_addr(a1
), ip_addr(a2
),
412 Min(ip_bits(a1
), ip_bits(a2
)));
415 order
= ((int) ip_bits(a1
)) - ((int) ip_bits(a2
));
418 return bitncmp(ip_addr(a1
), ip_addr(a2
), ip_maxbits(a1
));
421 return ip_family(a1
) - ip_family(a2
);
425 network_cmp(PG_FUNCTION_ARGS
)
427 inet
*a1
= PG_GETARG_INET_PP(0);
428 inet
*a2
= PG_GETARG_INET_PP(1);
430 PG_RETURN_INT32(network_cmp_internal(a1
, a2
));
434 * SortSupport strategy routine
437 network_sortsupport(PG_FUNCTION_ARGS
)
439 SortSupport ssup
= (SortSupport
) PG_GETARG_POINTER(0);
441 ssup
->comparator
= network_fast_cmp
;
442 ssup
->ssup_extra
= NULL
;
444 if (ssup
->abbreviate
)
446 network_sortsupport_state
*uss
;
447 MemoryContext oldcontext
;
449 oldcontext
= MemoryContextSwitchTo(ssup
->ssup_cxt
);
451 uss
= palloc(sizeof(network_sortsupport_state
));
452 uss
->input_count
= 0;
453 uss
->estimating
= true;
454 initHyperLogLog(&uss
->abbr_card
, 10);
456 ssup
->ssup_extra
= uss
;
458 ssup
->comparator
= ssup_datum_unsigned_cmp
;
459 ssup
->abbrev_converter
= network_abbrev_convert
;
460 ssup
->abbrev_abort
= network_abbrev_abort
;
461 ssup
->abbrev_full_comparator
= network_fast_cmp
;
463 MemoryContextSwitchTo(oldcontext
);
470 * SortSupport comparison func
473 network_fast_cmp(Datum x
, Datum y
, SortSupport ssup
)
475 inet
*arg1
= DatumGetInetPP(x
);
476 inet
*arg2
= DatumGetInetPP(y
);
478 return network_cmp_internal(arg1
, arg2
);
482 * Callback for estimating effectiveness of abbreviated key optimization.
484 * We pay no attention to the cardinality of the non-abbreviated data, because
485 * there is no equality fast-path within authoritative inet comparator.
488 network_abbrev_abort(int memtupcount
, SortSupport ssup
)
490 network_sortsupport_state
*uss
= ssup
->ssup_extra
;
493 if (memtupcount
< 10000 || uss
->input_count
< 10000 || !uss
->estimating
)
496 abbr_card
= estimateHyperLogLog(&uss
->abbr_card
);
499 * If we have >100k distinct values, then even if we were sorting many
500 * billion rows we'd likely still break even, and the penalty of undoing
501 * that many rows of abbrevs would probably not be worth it. At this point
502 * we stop counting because we know that we're now fully committed.
504 if (abbr_card
> 100000.0)
508 "network_abbrev: estimation ends at cardinality %f"
509 " after " INT64_FORMAT
" values (%d rows)",
510 abbr_card
, uss
->input_count
, memtupcount
);
511 uss
->estimating
= false;
516 * Target minimum cardinality is 1 per ~2k of non-null inputs. 0.5 row
517 * fudge factor allows us to abort earlier on genuinely pathological data
518 * where we've had exactly one abbreviated value in the first 2k
521 if (abbr_card
< uss
->input_count
/ 2000.0 + 0.5)
525 "network_abbrev: aborting abbreviation at cardinality %f"
526 " below threshold %f after " INT64_FORMAT
" values (%d rows)",
527 abbr_card
, uss
->input_count
/ 2000.0 + 0.5, uss
->input_count
,
534 "network_abbrev: cardinality %f after " INT64_FORMAT
535 " values (%d rows)", abbr_card
, uss
->input_count
, memtupcount
);
541 * SortSupport conversion routine. Converts original inet/cidr representation
542 * to abbreviated key representation that works with simple 3-way unsigned int
543 * comparisons. The network_cmp_internal() rules for sorting inet/cidr datums
544 * are followed by abbreviated comparisons by an encoding scheme that
545 * conditions keys through careful use of padding.
547 * Some background: inet values have three major components (take for example
548 * the address 1.2.3.4/24):
550 * * A network, or netmasked bits (1.2.3.0).
551 * * A netmask size (/24).
552 * * A subnet, or bits outside of the netmask (0.0.0.4).
554 * cidr values are the same except that with only the first two components --
555 * all their subnet bits *must* be zero (1.2.3.0/24).
557 * IPv4 and IPv6 are identical in this makeup, with the difference being that
558 * IPv4 addresses have a maximum of 32 bits compared to IPv6's 64 bits, so in
559 * IPv6 each part may be larger.
561 * inet/cidr types compare using these sorting rules. If inequality is detected
562 * at any step, comparison is finished. If any rule is a tie, the algorithm
563 * drops through to the next to break it:
565 * 1. IPv4 always appears before IPv6.
566 * 2. Network bits are compared.
567 * 3. Netmask size is compared.
568 * 4. All bits are compared (having made it here, we know that both
569 * netmasked bits and netmask size are equal, so we're in effect only
570 * comparing subnet bits).
572 * When generating abbreviated keys for SortSupport, we pack as much as we can
573 * into a datum while ensuring that when comparing those keys as integers,
574 * these rules will be respected. Exact contents depend on IP family and datum
582 * Start with 1 bit for the IP family (IPv4 or IPv6; this bit is present in
583 * every case below) followed by all but 1 of the netmasked bits.
585 * +----------+---------------------+
586 * | 1 bit IP | 31 bits network | (1 bit network
587 * | family | (truncated) | omitted)
588 * +----------+---------------------+
592 * We have space to store all netmasked bits, followed by the netmask size,
593 * followed by 25 bits of the subnet (25 bits is usually more than enough in
594 * practice). cidr datums always have all-zero subnet bits.
596 * +----------+-----------------------+--------------+--------------------+
597 * | 1 bit IP | 32 bits network | 6 bits | 25 bits subnet |
598 * | family | (full) | network size | (truncated) |
599 * +----------+-----------------------+--------------+--------------------+
606 * +----------+---------------------+
607 * | 1 bit IP | 31 bits network | (up to 97 bits
608 * | family | (truncated) | network omitted)
609 * +----------+---------------------+
613 * +----------+---------------------------------+
614 * | 1 bit IP | 63 bits network | (up to 65 bits
615 * | family | (truncated) | network omitted)
616 * +----------+---------------------------------+
619 network_abbrev_convert(Datum original
, SortSupport ssup
)
621 network_sortsupport_state
*uss
= ssup
->ssup_extra
;
622 inet
*authoritative
= DatumGetInetPP(original
);
629 Assert(ip_family(authoritative
) == PGSQL_AF_INET
||
630 ip_family(authoritative
) == PGSQL_AF_INET6
);
633 * Get an unsigned integer representation of the IP address by taking its
634 * first 4 or 8 bytes. Always take all 4 bytes of an IPv4 address. Take
635 * the first 8 bytes of an IPv6 address with an 8 byte datum and 4 bytes
638 * We're consuming an array of unsigned char, so byteswap on little endian
639 * systems (an inet's ipaddr field stores the most significant byte
642 if (ip_family(authoritative
) == PGSQL_AF_INET
)
644 uint32 ipaddr_datum32
;
646 memcpy(&ipaddr_datum32
, ip_addr(authoritative
), sizeof(uint32
));
648 /* Must byteswap on little-endian machines */
649 #ifndef WORDS_BIGENDIAN
650 ipaddr_datum
= pg_bswap32(ipaddr_datum32
);
652 ipaddr_datum
= ipaddr_datum32
;
655 /* Initialize result without setting ipfamily bit */
660 memcpy(&ipaddr_datum
, ip_addr(authoritative
), sizeof(Datum
));
662 /* Must byteswap on little-endian machines */
663 ipaddr_datum
= DatumBigEndianToNative(ipaddr_datum
);
665 /* Initialize result with ipfamily (most significant) bit set */
666 res
= ((Datum
) 1) << (SIZEOF_DATUM
* BITS_PER_BYTE
- 1);
670 * ipaddr_datum must be "split": high order bits go in "network" component
671 * of abbreviated key (often with zeroed bits at the end due to masking),
672 * while low order bits go in "subnet" component when there is space for
673 * one. This is often accomplished by generating a temp datum subnet
674 * bitmask, which we may reuse later when generating the subnet bits
675 * themselves. (Note that subnet bits are only used with IPv4 datums on
676 * platforms where datum is 8 bytes.)
678 * The number of bits in subnet is used to generate a datum subnet
679 * bitmask. For example, with a /24 IPv4 datum there are 8 subnet bits
680 * (since 32 - 24 is 8), so the final subnet bitmask is B'1111 1111'. We
681 * need explicit handling for cases where the ipaddr bits cannot all fit
682 * in a datum, though (otherwise we'd incorrectly mask the network
683 * component with IPv6 values).
685 subnet_size
= ip_maxbits(authoritative
) - ip_bits(authoritative
);
686 Assert(subnet_size
>= 0);
687 /* subnet size must work with prefix ipaddr cases */
688 subnet_size
%= SIZEOF_DATUM
* BITS_PER_BYTE
;
689 if (ip_bits(authoritative
) == 0)
691 /* Fit as many ipaddr bits as possible into subnet */
692 subnet_bitmask
= ((Datum
) 0) - 1;
695 else if (ip_bits(authoritative
) < SIZEOF_DATUM
* BITS_PER_BYTE
)
697 /* Split ipaddr bits between network and subnet */
698 subnet_bitmask
= (((Datum
) 1) << subnet_size
) - 1;
699 network
= ipaddr_datum
& ~subnet_bitmask
;
703 /* Fit as many ipaddr bits as possible into network */
705 network
= ipaddr_datum
;
708 #if SIZEOF_DATUM == 8
709 if (ip_family(authoritative
) == PGSQL_AF_INET
)
712 * IPv4 with 8 byte datums: keep all 32 netmasked bits, netmask size,
713 * and most significant 25 subnet bits
715 Datum netmask_size
= (Datum
) ip_bits(authoritative
);
719 * Shift left 31 bits: 6 bits netmask size + 25 subnet bits.
721 * We don't make any distinction between network bits that are zero
722 * due to masking and "true"/non-masked zero bits. An abbreviated
723 * comparison that is resolved by comparing a non-masked and non-zero
724 * bit to a masked/zeroed bit is effectively resolved based on
725 * ip_bits(), even though the comparison won't reach the netmask_size
728 network
<<= (ABBREV_BITS_INET4_NETMASK_SIZE
+
729 ABBREV_BITS_INET4_SUBNET
);
731 /* Shift size to make room for subnet bits at the end */
732 netmask_size
<<= ABBREV_BITS_INET4_SUBNET
;
734 /* Extract subnet bits without shifting them */
735 subnet
= ipaddr_datum
& subnet_bitmask
;
738 * If we have more than 25 subnet bits, we can't fit everything. Shift
739 * subnet down to avoid clobbering bits that are only supposed to be
740 * used for netmask_size.
742 * Discarding the least significant subnet bits like this is correct
743 * because abbreviated comparisons that are resolved at the subnet
744 * level must have had equal netmask_size/ip_bits() values in order to
747 if (subnet_size
> ABBREV_BITS_INET4_SUBNET
)
748 subnet
>>= subnet_size
- ABBREV_BITS_INET4_SUBNET
;
751 * Assemble the final abbreviated key without clobbering the ipfamily
752 * bit that must remain a zero.
754 res
|= network
| netmask_size
| subnet
;
760 * 4 byte datums, or IPv6 with 8 byte datums: Use as many of the
761 * netmasked bits as will fit in final abbreviated key. Avoid
762 * clobbering the ipfamily bit that was set earlier.
767 uss
->input_count
+= 1;
769 /* Hash abbreviated key */
774 #if SIZEOF_DATUM == 8
775 tmp
= (uint32
) res
^ (uint32
) ((uint64
) res
>> 32);
776 #else /* SIZEOF_DATUM != 8 */
780 addHyperLogLog(&uss
->abbr_card
, DatumGetUInt32(hash_uint32(tmp
)));
787 * Boolean ordering tests.
790 network_lt(PG_FUNCTION_ARGS
)
792 inet
*a1
= PG_GETARG_INET_PP(0);
793 inet
*a2
= PG_GETARG_INET_PP(1);
795 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) < 0);
799 network_le(PG_FUNCTION_ARGS
)
801 inet
*a1
= PG_GETARG_INET_PP(0);
802 inet
*a2
= PG_GETARG_INET_PP(1);
804 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) <= 0);
808 network_eq(PG_FUNCTION_ARGS
)
810 inet
*a1
= PG_GETARG_INET_PP(0);
811 inet
*a2
= PG_GETARG_INET_PP(1);
813 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) == 0);
817 network_ge(PG_FUNCTION_ARGS
)
819 inet
*a1
= PG_GETARG_INET_PP(0);
820 inet
*a2
= PG_GETARG_INET_PP(1);
822 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) >= 0);
826 network_gt(PG_FUNCTION_ARGS
)
828 inet
*a1
= PG_GETARG_INET_PP(0);
829 inet
*a2
= PG_GETARG_INET_PP(1);
831 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) > 0);
835 network_ne(PG_FUNCTION_ARGS
)
837 inet
*a1
= PG_GETARG_INET_PP(0);
838 inet
*a2
= PG_GETARG_INET_PP(1);
840 PG_RETURN_BOOL(network_cmp_internal(a1
, a2
) != 0);
844 * MIN/MAX support functions.
847 network_smaller(PG_FUNCTION_ARGS
)
849 inet
*a1
= PG_GETARG_INET_PP(0);
850 inet
*a2
= PG_GETARG_INET_PP(1);
852 if (network_cmp_internal(a1
, a2
) < 0)
853 PG_RETURN_INET_P(a1
);
855 PG_RETURN_INET_P(a2
);
859 network_larger(PG_FUNCTION_ARGS
)
861 inet
*a1
= PG_GETARG_INET_PP(0);
862 inet
*a2
= PG_GETARG_INET_PP(1);
864 if (network_cmp_internal(a1
, a2
) > 0)
865 PG_RETURN_INET_P(a1
);
867 PG_RETURN_INET_P(a2
);
871 * Support function for hash indexes on inet/cidr.
874 hashinet(PG_FUNCTION_ARGS
)
876 inet
*addr
= PG_GETARG_INET_PP(0);
877 int addrsize
= ip_addrsize(addr
);
879 /* XXX this assumes there are no pad bytes in the data structure */
880 return hash_any((unsigned char *) VARDATA_ANY(addr
), addrsize
+ 2);
884 hashinetextended(PG_FUNCTION_ARGS
)
886 inet
*addr
= PG_GETARG_INET_PP(0);
887 int addrsize
= ip_addrsize(addr
);
889 return hash_any_extended((unsigned char *) VARDATA_ANY(addr
), addrsize
+ 2,
894 * Boolean network-inclusion tests.
897 network_sub(PG_FUNCTION_ARGS
)
899 inet
*a1
= PG_GETARG_INET_PP(0);
900 inet
*a2
= PG_GETARG_INET_PP(1);
902 if (ip_family(a1
) == ip_family(a2
))
904 PG_RETURN_BOOL(ip_bits(a1
) > ip_bits(a2
) &&
905 bitncmp(ip_addr(a1
), ip_addr(a2
), ip_bits(a2
)) == 0);
908 PG_RETURN_BOOL(false);
912 network_subeq(PG_FUNCTION_ARGS
)
914 inet
*a1
= PG_GETARG_INET_PP(0);
915 inet
*a2
= PG_GETARG_INET_PP(1);
917 if (ip_family(a1
) == ip_family(a2
))
919 PG_RETURN_BOOL(ip_bits(a1
) >= ip_bits(a2
) &&
920 bitncmp(ip_addr(a1
), ip_addr(a2
), ip_bits(a2
)) == 0);
923 PG_RETURN_BOOL(false);
927 network_sup(PG_FUNCTION_ARGS
)
929 inet
*a1
= PG_GETARG_INET_PP(0);
930 inet
*a2
= PG_GETARG_INET_PP(1);
932 if (ip_family(a1
) == ip_family(a2
))
934 PG_RETURN_BOOL(ip_bits(a1
) < ip_bits(a2
) &&
935 bitncmp(ip_addr(a1
), ip_addr(a2
), ip_bits(a1
)) == 0);
938 PG_RETURN_BOOL(false);
942 network_supeq(PG_FUNCTION_ARGS
)
944 inet
*a1
= PG_GETARG_INET_PP(0);
945 inet
*a2
= PG_GETARG_INET_PP(1);
947 if (ip_family(a1
) == ip_family(a2
))
949 PG_RETURN_BOOL(ip_bits(a1
) <= ip_bits(a2
) &&
950 bitncmp(ip_addr(a1
), ip_addr(a2
), ip_bits(a1
)) == 0);
953 PG_RETURN_BOOL(false);
957 network_overlap(PG_FUNCTION_ARGS
)
959 inet
*a1
= PG_GETARG_INET_PP(0);
960 inet
*a2
= PG_GETARG_INET_PP(1);
962 if (ip_family(a1
) == ip_family(a2
))
964 PG_RETURN_BOOL(bitncmp(ip_addr(a1
), ip_addr(a2
),
965 Min(ip_bits(a1
), ip_bits(a2
))) == 0);
968 PG_RETURN_BOOL(false);
972 * Planner support function for network subset/superset operators
975 network_subset_support(PG_FUNCTION_ARGS
)
977 Node
*rawreq
= (Node
*) PG_GETARG_POINTER(0);
980 if (IsA(rawreq
, SupportRequestIndexCondition
))
982 /* Try to convert operator/function call to index conditions */
983 SupportRequestIndexCondition
*req
= (SupportRequestIndexCondition
*) rawreq
;
985 if (is_opclause(req
->node
))
987 OpExpr
*clause
= (OpExpr
*) req
->node
;
989 Assert(list_length(clause
->args
) == 2);
991 match_network_function((Node
*) linitial(clause
->args
),
992 (Node
*) lsecond(clause
->args
),
997 else if (is_funcclause(req
->node
)) /* be paranoid */
999 FuncExpr
*clause
= (FuncExpr
*) req
->node
;
1001 Assert(list_length(clause
->args
) == 2);
1003 match_network_function((Node
*) linitial(clause
->args
),
1004 (Node
*) lsecond(clause
->args
),
1011 PG_RETURN_POINTER(ret
);
1015 * match_network_function
1016 * Try to generate an indexqual for a network subset/superset function.
1018 * This layer is just concerned with identifying the function and swapping
1019 * the arguments if necessary.
1022 match_network_function(Node
*leftop
,
1031 /* indexkey must be on the left */
1034 return match_network_subset(leftop
, rightop
, false, opfamily
);
1036 case F_NETWORK_SUBEQ
:
1037 /* indexkey must be on the left */
1040 return match_network_subset(leftop
, rightop
, true, opfamily
);
1043 /* indexkey must be on the right */
1046 return match_network_subset(rightop
, leftop
, false, opfamily
);
1048 case F_NETWORK_SUPEQ
:
1049 /* indexkey must be on the right */
1052 return match_network_subset(rightop
, leftop
, true, opfamily
);
1057 * We'd only get here if somebody attached this support function
1058 * to an unexpected function. Maybe we should complain, but for
1066 * match_network_subset
1067 * Try to generate an indexqual for a network subset function.
1070 match_network_subset(Node
*leftop
,
1077 Oid datatype
= INETOID
;
1085 * Can't do anything with a non-constant or NULL comparison value.
1087 * Note that since we restrict ourselves to cases with a hard constant on
1088 * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry
1089 * about verifying that.
1091 if (!IsA(rightop
, Const
) ||
1092 ((Const
*) rightop
)->constisnull
)
1094 rightopval
= ((Const
*) rightop
)->constvalue
;
1097 * Must check that index's opfamily supports the operators we will want to
1100 * We insist on the opfamily being the specific one we expect, else we'd
1101 * do the wrong thing if someone were to make a reverse-sort opfamily with
1102 * the same operators.
1104 if (opfamily
!= NETWORK_BTREE_FAM_OID
)
1108 * create clause "key >= network_scan_first( rightopval )", or ">" if the
1109 * operator disallows equality.
1111 * Note: seeing that this function supports only fixed values for opfamily
1112 * and datatype, we could just hard-wire the operator OIDs instead of
1113 * looking them up. But for now it seems better to be general.
1117 opr1oid
= get_opfamily_member(opfamily
, datatype
, datatype
,
1118 BTGreaterEqualStrategyNumber
);
1119 if (opr1oid
== InvalidOid
)
1120 elog(ERROR
, "no >= operator for opfamily %u", opfamily
);
1124 opr1oid
= get_opfamily_member(opfamily
, datatype
, datatype
,
1125 BTGreaterStrategyNumber
);
1126 if (opr1oid
== InvalidOid
)
1127 elog(ERROR
, "no > operator for opfamily %u", opfamily
);
1130 opr1right
= network_scan_first(rightopval
);
1132 expr
= make_opclause(opr1oid
, BOOLOID
, false,
1134 (Expr
*) makeConst(datatype
, -1,
1135 InvalidOid
, /* not collatable */
1138 InvalidOid
, InvalidOid
);
1139 result
= list_make1(expr
);
1141 /* create clause "key <= network_scan_last( rightopval )" */
1143 opr2oid
= get_opfamily_member(opfamily
, datatype
, datatype
,
1144 BTLessEqualStrategyNumber
);
1145 if (opr2oid
== InvalidOid
)
1146 elog(ERROR
, "no <= operator for opfamily %u", opfamily
);
1148 opr2right
= network_scan_last(rightopval
);
1150 expr
= make_opclause(opr2oid
, BOOLOID
, false,
1152 (Expr
*) makeConst(datatype
, -1,
1153 InvalidOid
, /* not collatable */
1156 InvalidOid
, InvalidOid
);
1157 result
= lappend(result
, expr
);
1164 * Extract data from a network datatype.
1167 network_host(PG_FUNCTION_ARGS
)
1169 inet
*ip
= PG_GETARG_INET_PP(0);
1171 char tmp
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1173 /* force display of max bits, regardless of masklen... */
1174 if (pg_inet_net_ntop(ip_family(ip
), ip_addr(ip
), ip_maxbits(ip
),
1175 tmp
, sizeof(tmp
)) == NULL
)
1177 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
1178 errmsg("could not format inet value: %m")));
1180 /* Suppress /n if present (shouldn't happen now) */
1181 if ((ptr
= strchr(tmp
, '/')) != NULL
)
1184 PG_RETURN_TEXT_P(cstring_to_text(tmp
));
1188 * network_show implements the inet and cidr casts to text. This is not
1189 * quite the same behavior as network_out, hence we can't drop it in favor
1193 network_show(PG_FUNCTION_ARGS
)
1195 inet
*ip
= PG_GETARG_INET_PP(0);
1197 char tmp
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1199 if (pg_inet_net_ntop(ip_family(ip
), ip_addr(ip
), ip_maxbits(ip
),
1200 tmp
, sizeof(tmp
)) == NULL
)
1202 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
1203 errmsg("could not format inet value: %m")));
1205 /* Add /n if not present (which it won't be) */
1206 if (strchr(tmp
, '/') == NULL
)
1209 snprintf(tmp
+ len
, sizeof(tmp
) - len
, "/%u", ip_bits(ip
));
1212 PG_RETURN_TEXT_P(cstring_to_text(tmp
));
1216 inet_abbrev(PG_FUNCTION_ARGS
)
1218 inet
*ip
= PG_GETARG_INET_PP(0);
1220 char tmp
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1222 dst
= pg_inet_net_ntop(ip_family(ip
), ip_addr(ip
),
1223 ip_bits(ip
), tmp
, sizeof(tmp
));
1227 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
1228 errmsg("could not format inet value: %m")));
1230 PG_RETURN_TEXT_P(cstring_to_text(tmp
));
1234 cidr_abbrev(PG_FUNCTION_ARGS
)
1236 inet
*ip
= PG_GETARG_INET_PP(0);
1238 char tmp
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1240 dst
= pg_inet_cidr_ntop(ip_family(ip
), ip_addr(ip
),
1241 ip_bits(ip
), tmp
, sizeof(tmp
));
1245 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
1246 errmsg("could not format cidr value: %m")));
1248 PG_RETURN_TEXT_P(cstring_to_text(tmp
));
1252 network_masklen(PG_FUNCTION_ARGS
)
1254 inet
*ip
= PG_GETARG_INET_PP(0);
1256 PG_RETURN_INT32(ip_bits(ip
));
1260 network_family(PG_FUNCTION_ARGS
)
1262 inet
*ip
= PG_GETARG_INET_PP(0);
1264 switch (ip_family(ip
))
1269 case PGSQL_AF_INET6
:
1279 network_broadcast(PG_FUNCTION_ARGS
)
1281 inet
*ip
= PG_GETARG_INET_PP(0);
1290 /* make sure any unused bits are zeroed */
1291 dst
= (inet
*) palloc0(sizeof(inet
));
1293 maxbytes
= ip_addrsize(ip
);
1298 for (byte
= 0; byte
< maxbytes
; byte
++)
1309 mask
= 0xff >> bits
;
1313 b
[byte
] = a
[byte
] | mask
;
1316 ip_family(dst
) = ip_family(ip
);
1317 ip_bits(dst
) = ip_bits(ip
);
1318 SET_INET_VARSIZE(dst
);
1320 PG_RETURN_INET_P(dst
);
1324 network_network(PG_FUNCTION_ARGS
)
1326 inet
*ip
= PG_GETARG_INET_PP(0);
1334 /* make sure any unused bits are zeroed */
1335 dst
= (inet
*) palloc0(sizeof(inet
));
1352 mask
= 0xff << (8 - bits
);
1356 b
[byte
] = a
[byte
] & mask
;
1360 ip_family(dst
) = ip_family(ip
);
1361 ip_bits(dst
) = ip_bits(ip
);
1362 SET_INET_VARSIZE(dst
);
1364 PG_RETURN_INET_P(dst
);
1368 network_netmask(PG_FUNCTION_ARGS
)
1370 inet
*ip
= PG_GETARG_INET_PP(0);
1377 /* make sure any unused bits are zeroed */
1378 dst
= (inet
*) palloc0(sizeof(inet
));
1394 mask
= 0xff << (8 - bits
);
1402 ip_family(dst
) = ip_family(ip
);
1403 ip_bits(dst
) = ip_maxbits(ip
);
1404 SET_INET_VARSIZE(dst
);
1406 PG_RETURN_INET_P(dst
);
1410 network_hostmask(PG_FUNCTION_ARGS
)
1412 inet
*ip
= PG_GETARG_INET_PP(0);
1420 /* make sure any unused bits are zeroed */
1421 dst
= (inet
*) palloc0(sizeof(inet
));
1423 maxbytes
= ip_addrsize(ip
);
1424 bits
= ip_maxbits(ip
) - ip_bits(ip
);
1427 byte
= maxbytes
- 1;
1438 mask
= 0xff >> (8 - bits
);
1446 ip_family(dst
) = ip_family(ip
);
1447 ip_bits(dst
) = ip_maxbits(ip
);
1448 SET_INET_VARSIZE(dst
);
1450 PG_RETURN_INET_P(dst
);
1454 * Returns true if the addresses are from the same family, or false. Used to
1455 * check that we can create a network which contains both of the networks.
1458 inet_same_family(PG_FUNCTION_ARGS
)
1460 inet
*a1
= PG_GETARG_INET_PP(0);
1461 inet
*a2
= PG_GETARG_INET_PP(1);
1463 PG_RETURN_BOOL(ip_family(a1
) == ip_family(a2
));
1467 * Returns the smallest CIDR which contains both of the inputs.
1470 inet_merge(PG_FUNCTION_ARGS
)
1472 inet
*a1
= PG_GETARG_INET_PP(0),
1473 *a2
= PG_GETARG_INET_PP(1);
1476 if (ip_family(a1
) != ip_family(a2
))
1478 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1479 errmsg("cannot merge addresses from different families")));
1481 commonbits
= bitncommon(ip_addr(a1
), ip_addr(a2
),
1482 Min(ip_bits(a1
), ip_bits(a2
)));
1484 PG_RETURN_INET_P(cidr_set_masklen_internal(a1
, commonbits
));
1488 * Convert a value of a network datatype to an approximate scalar value.
1489 * This is used for estimating selectivities of inequality operators
1490 * involving network types.
1492 * On failure (e.g., unsupported typid), set *failure to true;
1493 * otherwise, that variable is not changed.
1496 convert_network_to_scalar(Datum value
, Oid typid
, bool *failure
)
1503 inet
*ip
= DatumGetInetPP(value
);
1509 * Note that we don't use the full address for IPv6.
1511 if (ip_family(ip
) == PGSQL_AF_INET
)
1516 res
= ip_family(ip
);
1517 for (i
= 0; i
< len
; i
++)
1520 res
+= ip_addr(ip
)[i
];
1526 macaddr
*mac
= DatumGetMacaddrP(value
);
1529 res
= (mac
->a
<< 16) | (mac
->b
<< 8) | (mac
->c
);
1530 res
*= 256 * 256 * 256;
1531 res
+= (mac
->d
<< 16) | (mac
->e
<< 8) | (mac
->f
);
1536 macaddr8
*mac
= DatumGetMacaddr8P(value
);
1539 res
= (mac
->a
<< 24) | (mac
->b
<< 16) | (mac
->c
<< 8) | (mac
->d
);
1540 res
*= ((double) 256) * 256 * 256 * 256;
1541 res
+= (mac
->e
<< 24) | (mac
->f
<< 16) | (mac
->g
<< 8) | (mac
->h
);
1553 * compare bit masks l and r, for n bits.
1555 * <0, >0, or 0 in the libc tradition.
1557 * network byte order assumed. this means 192.5.5.240/28 has
1558 * 0x11110000 in its fourth octet.
1560 * Paul Vixie (ISC), June 1996
1563 bitncmp(const unsigned char *l
, const unsigned char *r
, int n
)
1571 x
= memcmp(l
, r
, b
);
1572 if (x
|| (n
% 8) == 0)
1577 for (b
= n
% 8; b
> 0; b
--)
1579 if (IS_HIGHBIT_SET(lb
) != IS_HIGHBIT_SET(rb
))
1581 if (IS_HIGHBIT_SET(lb
))
1592 * bitncommon: compare bit masks l and r, for up to n bits.
1594 * Returns the number of leading bits that match (0 to n).
1597 bitncommon(const unsigned char *l
, const unsigned char *r
, int n
)
1602 /* number of bits to examine in last byte */
1605 /* check whole bytes */
1606 for (byte
= 0; byte
< n
/ 8; byte
++)
1608 if (l
[byte
] != r
[byte
])
1610 /* at least one bit in the last byte is not common */
1616 /* check bits in last partial byte */
1619 /* calculate diff of first non-matching bytes */
1620 unsigned int diff
= l
[byte
] ^ r
[byte
];
1622 /* compare the bits from the most to the least */
1623 while ((diff
>> (8 - nbits
)) != 0)
1627 return (8 * byte
) + nbits
;
1632 * Verify a CIDR address is OK (doesn't have bits set past the masklen)
1635 addressOK(unsigned char *a
, int bits
, int family
)
1643 if (family
== PGSQL_AF_INET
)
1653 Assert(bits
<= maxbits
);
1655 if (bits
== maxbits
)
1665 while (byte
< maxbytes
)
1667 if ((a
[byte
] & mask
) != 0)
1678 * These functions are used by planner to generate indexscan limits
1679 * for clauses a << b and a <<= b
1682 /* return the minimal value for an IP on a given network */
1684 network_scan_first(Datum in
)
1686 return DirectFunctionCall1(network_network
, in
);
1690 * return "last" IP on a given network. It's the broadcast address,
1691 * however, masklen has to be set to its max bits, since
1692 * 192.168.0.255/24 is considered less than 192.168.0.255/32
1694 * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
1695 * and 32 for IPv4 when given '-1' as argument.
1698 network_scan_last(Datum in
)
1700 return DirectFunctionCall2(inet_set_masklen
,
1701 DirectFunctionCall1(network_broadcast
, in
),
1707 * IP address that the client is connecting from (NULL if Unix socket)
1710 inet_client_addr(PG_FUNCTION_ARGS
)
1712 Port
*port
= MyProcPort
;
1713 char remote_host
[NI_MAXHOST
];
1719 switch (port
->raddr
.addr
.ss_family
)
1728 remote_host
[0] = '\0';
1730 ret
= pg_getnameinfo_all(&port
->raddr
.addr
, port
->raddr
.salen
,
1731 remote_host
, sizeof(remote_host
),
1733 NI_NUMERICHOST
| NI_NUMERICSERV
);
1737 clean_ipv6_addr(port
->raddr
.addr
.ss_family
, remote_host
);
1739 PG_RETURN_INET_P(network_in(remote_host
, false, NULL
));
1744 * port that the client is connecting from (NULL if Unix socket)
1747 inet_client_port(PG_FUNCTION_ARGS
)
1749 Port
*port
= MyProcPort
;
1750 char remote_port
[NI_MAXSERV
];
1756 switch (port
->raddr
.addr
.ss_family
)
1765 remote_port
[0] = '\0';
1767 ret
= pg_getnameinfo_all(&port
->raddr
.addr
, port
->raddr
.salen
,
1769 remote_port
, sizeof(remote_port
),
1770 NI_NUMERICHOST
| NI_NUMERICSERV
);
1774 PG_RETURN_DATUM(DirectFunctionCall1(int4in
, CStringGetDatum(remote_port
)));
1779 * IP address that the server accepted the connection on (NULL if Unix socket)
1782 inet_server_addr(PG_FUNCTION_ARGS
)
1784 Port
*port
= MyProcPort
;
1785 char local_host
[NI_MAXHOST
];
1791 switch (port
->laddr
.addr
.ss_family
)
1800 local_host
[0] = '\0';
1802 ret
= pg_getnameinfo_all(&port
->laddr
.addr
, port
->laddr
.salen
,
1803 local_host
, sizeof(local_host
),
1805 NI_NUMERICHOST
| NI_NUMERICSERV
);
1809 clean_ipv6_addr(port
->laddr
.addr
.ss_family
, local_host
);
1811 PG_RETURN_INET_P(network_in(local_host
, false, NULL
));
1816 * port that the server accepted the connection on (NULL if Unix socket)
1819 inet_server_port(PG_FUNCTION_ARGS
)
1821 Port
*port
= MyProcPort
;
1822 char local_port
[NI_MAXSERV
];
1828 switch (port
->laddr
.addr
.ss_family
)
1837 local_port
[0] = '\0';
1839 ret
= pg_getnameinfo_all(&port
->laddr
.addr
, port
->laddr
.salen
,
1841 local_port
, sizeof(local_port
),
1842 NI_NUMERICHOST
| NI_NUMERICSERV
);
1846 PG_RETURN_DATUM(DirectFunctionCall1(int4in
, CStringGetDatum(local_port
)));
1851 inetnot(PG_FUNCTION_ARGS
)
1853 inet
*ip
= PG_GETARG_INET_PP(0);
1856 dst
= (inet
*) palloc0(sizeof(inet
));
1859 int nb
= ip_addrsize(ip
);
1860 unsigned char *pip
= ip_addr(ip
);
1861 unsigned char *pdst
= ip_addr(dst
);
1864 pdst
[nb
] = ~pip
[nb
];
1866 ip_bits(dst
) = ip_bits(ip
);
1868 ip_family(dst
) = ip_family(ip
);
1869 SET_INET_VARSIZE(dst
);
1871 PG_RETURN_INET_P(dst
);
1876 inetand(PG_FUNCTION_ARGS
)
1878 inet
*ip
= PG_GETARG_INET_PP(0);
1879 inet
*ip2
= PG_GETARG_INET_PP(1);
1882 dst
= (inet
*) palloc0(sizeof(inet
));
1884 if (ip_family(ip
) != ip_family(ip2
))
1886 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1887 errmsg("cannot AND inet values of different sizes")));
1890 int nb
= ip_addrsize(ip
);
1891 unsigned char *pip
= ip_addr(ip
);
1892 unsigned char *pip2
= ip_addr(ip2
);
1893 unsigned char *pdst
= ip_addr(dst
);
1896 pdst
[nb
] = pip
[nb
] & pip2
[nb
];
1898 ip_bits(dst
) = Max(ip_bits(ip
), ip_bits(ip2
));
1900 ip_family(dst
) = ip_family(ip
);
1901 SET_INET_VARSIZE(dst
);
1903 PG_RETURN_INET_P(dst
);
1908 inetor(PG_FUNCTION_ARGS
)
1910 inet
*ip
= PG_GETARG_INET_PP(0);
1911 inet
*ip2
= PG_GETARG_INET_PP(1);
1914 dst
= (inet
*) palloc0(sizeof(inet
));
1916 if (ip_family(ip
) != ip_family(ip2
))
1918 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1919 errmsg("cannot OR inet values of different sizes")));
1922 int nb
= ip_addrsize(ip
);
1923 unsigned char *pip
= ip_addr(ip
);
1924 unsigned char *pip2
= ip_addr(ip2
);
1925 unsigned char *pdst
= ip_addr(dst
);
1928 pdst
[nb
] = pip
[nb
] | pip2
[nb
];
1930 ip_bits(dst
) = Max(ip_bits(ip
), ip_bits(ip2
));
1932 ip_family(dst
) = ip_family(ip
);
1933 SET_INET_VARSIZE(dst
);
1935 PG_RETURN_INET_P(dst
);
1940 internal_inetpl(inet
*ip
, int64 addend
)
1944 dst
= (inet
*) palloc0(sizeof(inet
));
1947 int nb
= ip_addrsize(ip
);
1948 unsigned char *pip
= ip_addr(ip
);
1949 unsigned char *pdst
= ip_addr(dst
);
1954 carry
= pip
[nb
] + (int) (addend
& 0xFF) + carry
;
1955 pdst
[nb
] = (unsigned char) (carry
& 0xFF);
1959 * We have to be careful about right-shifting addend because
1960 * right-shift isn't portable for negative values, while simply
1961 * dividing by 256 doesn't work (the standard rounding is in the
1962 * wrong direction, besides which there may be machines out there
1963 * that round the wrong way). So, explicitly clear the low-order
1964 * byte to remove any doubt about the correct result of the
1965 * division, and then divide rather than shift.
1967 addend
&= ~((int64
) 0xFF);
1972 * At this point we should have addend and carry both zero if original
1973 * addend was >= 0, or addend -1 and carry 1 if original addend was <
1974 * 0. Anything else means overflow.
1976 if (!((addend
== 0 && carry
== 0) ||
1977 (addend
== -1 && carry
== 1)))
1979 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE
),
1980 errmsg("result is out of range")));
1983 ip_bits(dst
) = ip_bits(ip
);
1984 ip_family(dst
) = ip_family(ip
);
1985 SET_INET_VARSIZE(dst
);
1992 inetpl(PG_FUNCTION_ARGS
)
1994 inet
*ip
= PG_GETARG_INET_PP(0);
1995 int64 addend
= PG_GETARG_INT64(1);
1997 PG_RETURN_INET_P(internal_inetpl(ip
, addend
));
2002 inetmi_int8(PG_FUNCTION_ARGS
)
2004 inet
*ip
= PG_GETARG_INET_PP(0);
2005 int64 addend
= PG_GETARG_INT64(1);
2007 PG_RETURN_INET_P(internal_inetpl(ip
, -addend
));
2012 inetmi(PG_FUNCTION_ARGS
)
2014 inet
*ip
= PG_GETARG_INET_PP(0);
2015 inet
*ip2
= PG_GETARG_INET_PP(1);
2018 if (ip_family(ip
) != ip_family(ip2
))
2020 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
2021 errmsg("cannot subtract inet values of different sizes")));
2025 * We form the difference using the traditional complement, increment,
2026 * and add rule, with the increment part being handled by starting the
2027 * carry off at 1. If you don't think integer arithmetic is done in
2028 * two's complement, too bad.
2030 int nb
= ip_addrsize(ip
);
2032 unsigned char *pip
= ip_addr(ip
);
2033 unsigned char *pip2
= ip_addr(ip2
);
2040 carry
= pip
[nb
] + (~pip2
[nb
] & 0xFF) + carry
;
2041 lobyte
= carry
& 0xFF;
2042 if (byte
< sizeof(int64
))
2044 res
|= ((int64
) lobyte
) << (byte
* 8);
2049 * Input wider than int64: check for overflow. All bytes to
2050 * the left of what will fit should be 0 or 0xFF, depending on
2051 * sign of the now-complete result.
2053 if ((res
< 0) ? (lobyte
!= 0xFF) : (lobyte
!= 0))
2055 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE
),
2056 errmsg("result is out of range")));
2063 * If input is narrower than int64, overflow is not possible, but we
2064 * have to do proper sign extension.
2066 if (carry
== 0 && byte
< sizeof(int64
))
2067 res
|= ((uint64
) (int64
) -1) << (byte
* 8);
2070 PG_RETURN_INT64(res
);
2075 * clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string
2077 * XXX This should go away someday!
2079 * This is a kluge needed because we don't yet support zones in stored inet
2080 * values. Since the result of getnameinfo() might include a zone spec,
2081 * call this to remove it anywhere we want to feed getnameinfo's output to
2082 * network_in. Beats failing entirely.
2084 * An alternative approach would be to let network_in ignore %-parts for
2085 * itself, but that would mean we'd silently drop zone specs in user input,
2086 * which seems not such a good idea.
2089 clean_ipv6_addr(int addr_family
, char *addr
)
2091 if (addr_family
== AF_INET6
)
2093 char *pct
= strchr(addr
, '%');