sepgsql: update TAP test to use fat comma style
[pgsql.git] / src / backend / utils / adt / network.c
blob450dacd031ca7a12c0f944f30d972dbac136b34b
1 /*
2 * PostgreSQL type definitions for the INET and CIDR types.
4 * src/backend/utils/adt/network.c
6 * Jon Postel RIP 16 Oct 1998
7 */
9 #include "postgres.h"
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
40 * component.
42 #define ABBREV_BITS_INET4_NETMASK_SIZE 6
43 #define ABBREV_BITS_INET4_SUBNET 25
45 /* sortsupport for inet/cidr */
46 typedef struct
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,
59 Node *rightop,
60 int indexarg,
61 Oid funcid,
62 Oid opfamily);
63 static List *match_network_subset(Node *leftop,
64 Node *rightop,
65 bool is_eq,
66 Oid opfamily);
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
74 static inet *
75 network_in(char *src, bool is_cidr, Node *escontext)
77 int bits;
78 inet *dst;
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;
90 else
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.
105 if (is_cidr)
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.")));
114 ip_bits(dst) = bits;
115 SET_INET_VARSIZE(dst);
117 return dst;
120 Datum
121 inet_in(PG_FUNCTION_ARGS)
123 char *src = PG_GETARG_CSTRING(0);
125 PG_RETURN_INET_P(network_in(src, false, fcinfo->context));
128 Datum
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
140 static char *
141 network_out(inet *src, bool is_cidr)
143 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
144 char *dst;
145 int len;
147 dst = pg_inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
148 tmp, sizeof(tmp));
149 if (dst == NULL)
150 ereport(ERROR,
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)
157 len = strlen(tmp);
158 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
161 return pstrdup(tmp);
164 Datum
165 inet_out(PG_FUNCTION_ARGS)
167 inet *src = PG_GETARG_INET_PP(0);
169 PG_RETURN_CSTRING(network_out(src, false));
172 Datum
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.
191 static inet *
192 network_recv(StringInfo buf, bool is_cidr)
194 inet *addr;
195 char *addrptr;
196 int bits;
197 int nb,
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)
206 ereport(ERROR,
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))
213 ereport(ERROR,
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))
222 ereport(ERROR,
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.
235 if (is_cidr)
237 if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
238 ereport(ERROR,
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);
246 return addr;
249 Datum
250 inet_recv(PG_FUNCTION_ARGS)
252 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
254 PG_RETURN_INET_P(network_recv(buf, false));
257 Datum
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
269 static bytea *
270 network_send(inet *addr, bool is_cidr)
272 StringInfoData buf;
273 char *addrptr;
274 int nb,
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);
282 if (nb < 0)
283 nb = 0;
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);
291 Datum
292 inet_send(PG_FUNCTION_ARGS)
294 inet *addr = PG_GETARG_INET_PP(0);
296 PG_RETURN_BYTEA_P(network_send(addr, false));
299 Datum
300 cidr_send(PG_FUNCTION_ARGS)
302 inet *addr = PG_GETARG_INET_PP(0);
304 PG_RETURN_BYTEA_P(network_send(addr, true));
308 Datum
309 inet_to_cidr(PG_FUNCTION_ARGS)
311 inet *src = PG_GETARG_INET_PP(0);
312 int bits;
314 bits = ip_bits(src);
316 /* safety check */
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));
323 Datum
324 inet_set_masklen(PG_FUNCTION_ARGS)
326 inet *src = PG_GETARG_INET_PP(0);
327 int bits = PG_GETARG_INT32(1);
328 inet *dst;
330 if (bits == -1)
331 bits = ip_maxbits(src);
333 if ((bits < 0) || (bits > ip_maxbits(src)))
334 ereport(ERROR,
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));
342 ip_bits(dst) = bits;
344 PG_RETURN_INET_P(dst);
347 Datum
348 cidr_set_masklen(PG_FUNCTION_ARGS)
350 inet *src = PG_GETARG_INET_PP(0);
351 int bits = PG_GETARG_INT32(1);
353 if (bits == -1)
354 bits = ip_maxbits(src);
356 if ((bits < 0) || (bits > ip_maxbits(src)))
357 ereport(ERROR,
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)
367 inet *
368 cidr_set_masklen_internal(const inet *src, int bits)
370 inet *dst = (inet *) palloc0(sizeof(inet));
372 ip_family(dst) = ip_family(src);
373 ip_bits(dst) = bits;
375 if (bits > 0)
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 */
383 if (bits % 8)
384 ip_addr(dst)[bits / 8] &= ~(0xFF >> (bits % 8));
387 /* Set varlena header correctly */
388 SET_INET_VARSIZE(dst);
390 return 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.
404 static int32
405 network_cmp_internal(inet *a1, inet *a2)
407 if (ip_family(a1) == ip_family(a2))
409 int order;
411 order = bitncmp(ip_addr(a1), ip_addr(a2),
412 Min(ip_bits(a1), ip_bits(a2)));
413 if (order != 0)
414 return order;
415 order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
416 if (order != 0)
417 return order;
418 return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
421 return ip_family(a1) - ip_family(a2);
424 Datum
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
436 Datum
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);
466 PG_RETURN_VOID();
470 * SortSupport comparison func
472 static int
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.
487 static bool
488 network_abbrev_abort(int memtupcount, SortSupport ssup)
490 network_sortsupport_state *uss = ssup->ssup_extra;
491 double abbr_card;
493 if (memtupcount < 10000 || uss->input_count < 10000 || !uss->estimating)
494 return false;
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)
506 if (trace_sort)
507 elog(LOG,
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;
512 return 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
519 * (non-null) rows.
521 if (abbr_card < uss->input_count / 2000.0 + 0.5)
523 if (trace_sort)
524 elog(LOG,
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,
528 memtupcount);
529 return true;
532 if (trace_sort)
533 elog(LOG,
534 "network_abbrev: cardinality %f after " INT64_FORMAT
535 " values (%d rows)", abbr_card, uss->input_count, memtupcount);
537 return false;
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
575 * size.
577 * IPv4
578 * ----
580 * 4 byte datums:
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 * +----------+---------------------+
590 * 8 byte datums:
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 * +----------+-----------------------+--------------+--------------------+
601 * IPv6
602 * ----
604 * 4 byte datums:
606 * +----------+---------------------+
607 * | 1 bit IP | 31 bits network | (up to 97 bits
608 * | family | (truncated) | network omitted)
609 * +----------+---------------------+
611 * 8 byte datums:
613 * +----------+---------------------------------+
614 * | 1 bit IP | 63 bits network | (up to 65 bits
615 * | family | (truncated) | network omitted)
616 * +----------+---------------------------------+
618 static Datum
619 network_abbrev_convert(Datum original, SortSupport ssup)
621 network_sortsupport_state *uss = ssup->ssup_extra;
622 inet *authoritative = DatumGetInetPP(original);
623 Datum res,
624 ipaddr_datum,
625 subnet_bitmask,
626 network;
627 int subnet_size;
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
636 * otherwise.
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
640 * first).
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);
651 #else
652 ipaddr_datum = ipaddr_datum32;
653 #endif
655 /* Initialize result without setting ipfamily bit */
656 res = (Datum) 0;
658 else
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;
693 network = 0;
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;
701 else
703 /* Fit as many ipaddr bits as possible into network */
704 subnet_bitmask = 0;
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);
716 Datum subnet;
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
726 * bits.
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
745 * get that far.
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;
756 else
757 #endif
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.
764 res |= network >> 1;
767 uss->input_count += 1;
769 /* Hash abbreviated key */
770 if (uss->estimating)
772 uint32 tmp;
774 #if SIZEOF_DATUM == 8
775 tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
776 #else /* SIZEOF_DATUM != 8 */
777 tmp = (uint32) res;
778 #endif
780 addHyperLogLog(&uss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
783 return res;
787 * Boolean ordering tests.
789 Datum
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);
798 Datum
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);
807 Datum
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);
816 Datum
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);
825 Datum
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);
834 Datum
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.
846 Datum
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);
854 else
855 PG_RETURN_INET_P(a2);
858 Datum
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);
866 else
867 PG_RETURN_INET_P(a2);
871 * Support function for hash indexes on inet/cidr.
873 Datum
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);
883 Datum
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,
890 PG_GETARG_INT64(1));
894 * Boolean network-inclusion tests.
896 Datum
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);
911 Datum
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);
926 Datum
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);
941 Datum
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);
956 Datum
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
974 Datum
975 network_subset_support(PG_FUNCTION_ARGS)
977 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
978 Node *ret = NULL;
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);
990 ret = (Node *)
991 match_network_function((Node *) linitial(clause->args),
992 (Node *) lsecond(clause->args),
993 req->indexarg,
994 req->funcid,
995 req->opfamily);
997 else if (is_funcclause(req->node)) /* be paranoid */
999 FuncExpr *clause = (FuncExpr *) req->node;
1001 Assert(list_length(clause->args) == 2);
1002 ret = (Node *)
1003 match_network_function((Node *) linitial(clause->args),
1004 (Node *) lsecond(clause->args),
1005 req->indexarg,
1006 req->funcid,
1007 req->opfamily);
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.
1021 static List *
1022 match_network_function(Node *leftop,
1023 Node *rightop,
1024 int indexarg,
1025 Oid funcid,
1026 Oid opfamily)
1028 switch (funcid)
1030 case F_NETWORK_SUB:
1031 /* indexkey must be on the left */
1032 if (indexarg != 0)
1033 return NIL;
1034 return match_network_subset(leftop, rightop, false, opfamily);
1036 case F_NETWORK_SUBEQ:
1037 /* indexkey must be on the left */
1038 if (indexarg != 0)
1039 return NIL;
1040 return match_network_subset(leftop, rightop, true, opfamily);
1042 case F_NETWORK_SUP:
1043 /* indexkey must be on the right */
1044 if (indexarg != 1)
1045 return NIL;
1046 return match_network_subset(rightop, leftop, false, opfamily);
1048 case F_NETWORK_SUPEQ:
1049 /* indexkey must be on the right */
1050 if (indexarg != 1)
1051 return NIL;
1052 return match_network_subset(rightop, leftop, true, opfamily);
1054 default:
1057 * We'd only get here if somebody attached this support function
1058 * to an unexpected function. Maybe we should complain, but for
1059 * now, do nothing.
1061 return NIL;
1066 * match_network_subset
1067 * Try to generate an indexqual for a network subset function.
1069 static List *
1070 match_network_subset(Node *leftop,
1071 Node *rightop,
1072 bool is_eq,
1073 Oid opfamily)
1075 List *result;
1076 Datum rightopval;
1077 Oid datatype = INETOID;
1078 Oid opr1oid;
1079 Oid opr2oid;
1080 Datum opr1right;
1081 Datum opr2right;
1082 Expr *expr;
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)
1093 return NIL;
1094 rightopval = ((Const *) rightop)->constvalue;
1097 * Must check that index's opfamily supports the operators we will want to
1098 * apply.
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)
1105 return NIL;
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.
1115 if (is_eq)
1117 opr1oid = get_opfamily_member(opfamily, datatype, datatype,
1118 BTGreaterEqualStrategyNumber);
1119 if (opr1oid == InvalidOid)
1120 elog(ERROR, "no >= operator for opfamily %u", opfamily);
1122 else
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,
1133 (Expr *) leftop,
1134 (Expr *) makeConst(datatype, -1,
1135 InvalidOid, /* not collatable */
1136 -1, opr1right,
1137 false, false),
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,
1151 (Expr *) leftop,
1152 (Expr *) makeConst(datatype, -1,
1153 InvalidOid, /* not collatable */
1154 -1, opr2right,
1155 false, false),
1156 InvalidOid, InvalidOid);
1157 result = lappend(result, expr);
1159 return result;
1164 * Extract data from a network datatype.
1166 Datum
1167 network_host(PG_FUNCTION_ARGS)
1169 inet *ip = PG_GETARG_INET_PP(0);
1170 char *ptr;
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)
1176 ereport(ERROR,
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)
1182 *ptr = '\0';
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
1190 * of CoerceViaIO.
1192 Datum
1193 network_show(PG_FUNCTION_ARGS)
1195 inet *ip = PG_GETARG_INET_PP(0);
1196 int len;
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)
1201 ereport(ERROR,
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)
1208 len = strlen(tmp);
1209 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
1212 PG_RETURN_TEXT_P(cstring_to_text(tmp));
1215 Datum
1216 inet_abbrev(PG_FUNCTION_ARGS)
1218 inet *ip = PG_GETARG_INET_PP(0);
1219 char *dst;
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));
1225 if (dst == NULL)
1226 ereport(ERROR,
1227 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1228 errmsg("could not format inet value: %m")));
1230 PG_RETURN_TEXT_P(cstring_to_text(tmp));
1233 Datum
1234 cidr_abbrev(PG_FUNCTION_ARGS)
1236 inet *ip = PG_GETARG_INET_PP(0);
1237 char *dst;
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));
1243 if (dst == NULL)
1244 ereport(ERROR,
1245 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1246 errmsg("could not format cidr value: %m")));
1248 PG_RETURN_TEXT_P(cstring_to_text(tmp));
1251 Datum
1252 network_masklen(PG_FUNCTION_ARGS)
1254 inet *ip = PG_GETARG_INET_PP(0);
1256 PG_RETURN_INT32(ip_bits(ip));
1259 Datum
1260 network_family(PG_FUNCTION_ARGS)
1262 inet *ip = PG_GETARG_INET_PP(0);
1264 switch (ip_family(ip))
1266 case PGSQL_AF_INET:
1267 PG_RETURN_INT32(4);
1268 break;
1269 case PGSQL_AF_INET6:
1270 PG_RETURN_INT32(6);
1271 break;
1272 default:
1273 PG_RETURN_INT32(0);
1274 break;
1278 Datum
1279 network_broadcast(PG_FUNCTION_ARGS)
1281 inet *ip = PG_GETARG_INET_PP(0);
1282 inet *dst;
1283 int byte;
1284 int bits;
1285 int maxbytes;
1286 unsigned char mask;
1287 unsigned char *a,
1290 /* make sure any unused bits are zeroed */
1291 dst = (inet *) palloc0(sizeof(inet));
1293 maxbytes = ip_addrsize(ip);
1294 bits = ip_bits(ip);
1295 a = ip_addr(ip);
1296 b = ip_addr(dst);
1298 for (byte = 0; byte < maxbytes; byte++)
1300 if (bits >= 8)
1302 mask = 0x00;
1303 bits -= 8;
1305 else if (bits == 0)
1306 mask = 0xff;
1307 else
1309 mask = 0xff >> bits;
1310 bits = 0;
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);
1323 Datum
1324 network_network(PG_FUNCTION_ARGS)
1326 inet *ip = PG_GETARG_INET_PP(0);
1327 inet *dst;
1328 int byte;
1329 int bits;
1330 unsigned char mask;
1331 unsigned char *a,
1334 /* make sure any unused bits are zeroed */
1335 dst = (inet *) palloc0(sizeof(inet));
1337 bits = ip_bits(ip);
1338 a = ip_addr(ip);
1339 b = ip_addr(dst);
1341 byte = 0;
1343 while (bits)
1345 if (bits >= 8)
1347 mask = 0xff;
1348 bits -= 8;
1350 else
1352 mask = 0xff << (8 - bits);
1353 bits = 0;
1356 b[byte] = a[byte] & mask;
1357 byte++;
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);
1367 Datum
1368 network_netmask(PG_FUNCTION_ARGS)
1370 inet *ip = PG_GETARG_INET_PP(0);
1371 inet *dst;
1372 int byte;
1373 int bits;
1374 unsigned char mask;
1375 unsigned char *b;
1377 /* make sure any unused bits are zeroed */
1378 dst = (inet *) palloc0(sizeof(inet));
1380 bits = ip_bits(ip);
1381 b = ip_addr(dst);
1383 byte = 0;
1385 while (bits)
1387 if (bits >= 8)
1389 mask = 0xff;
1390 bits -= 8;
1392 else
1394 mask = 0xff << (8 - bits);
1395 bits = 0;
1398 b[byte] = mask;
1399 byte++;
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);
1409 Datum
1410 network_hostmask(PG_FUNCTION_ARGS)
1412 inet *ip = PG_GETARG_INET_PP(0);
1413 inet *dst;
1414 int byte;
1415 int bits;
1416 int maxbytes;
1417 unsigned char mask;
1418 unsigned char *b;
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);
1425 b = ip_addr(dst);
1427 byte = maxbytes - 1;
1429 while (bits)
1431 if (bits >= 8)
1433 mask = 0xff;
1434 bits -= 8;
1436 else
1438 mask = 0xff >> (8 - bits);
1439 bits = 0;
1442 b[byte] = mask;
1443 byte--;
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.
1457 Datum
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.
1469 Datum
1470 inet_merge(PG_FUNCTION_ARGS)
1472 inet *a1 = PG_GETARG_INET_PP(0),
1473 *a2 = PG_GETARG_INET_PP(1);
1474 int commonbits;
1476 if (ip_family(a1) != ip_family(a2))
1477 ereport(ERROR,
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.
1495 double
1496 convert_network_to_scalar(Datum value, Oid typid, bool *failure)
1498 switch (typid)
1500 case INETOID:
1501 case CIDROID:
1503 inet *ip = DatumGetInetPP(value);
1504 int len;
1505 double res;
1506 int i;
1509 * Note that we don't use the full address for IPv6.
1511 if (ip_family(ip) == PGSQL_AF_INET)
1512 len = 4;
1513 else
1514 len = 5;
1516 res = ip_family(ip);
1517 for (i = 0; i < len; i++)
1519 res *= 256;
1520 res += ip_addr(ip)[i];
1522 return res;
1524 case MACADDROID:
1526 macaddr *mac = DatumGetMacaddrP(value);
1527 double res;
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);
1532 return res;
1534 case MACADDR8OID:
1536 macaddr8 *mac = DatumGetMacaddr8P(value);
1537 double res;
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);
1542 return res;
1546 *failure = true;
1547 return 0;
1551 * int
1552 * bitncmp(l, r, n)
1553 * compare bit masks l and r, for n bits.
1554 * return:
1555 * <0, >0, or 0 in the libc tradition.
1556 * note:
1557 * network byte order assumed. this means 192.5.5.240/28 has
1558 * 0x11110000 in its fourth octet.
1559 * author:
1560 * Paul Vixie (ISC), June 1996
1563 bitncmp(const unsigned char *l, const unsigned char *r, int n)
1565 unsigned int lb,
1567 int x,
1570 b = n / 8;
1571 x = memcmp(l, r, b);
1572 if (x || (n % 8) == 0)
1573 return x;
1575 lb = l[b];
1576 rb = r[b];
1577 for (b = n % 8; b > 0; b--)
1579 if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
1581 if (IS_HIGHBIT_SET(lb))
1582 return 1;
1583 return -1;
1585 lb <<= 1;
1586 rb <<= 1;
1588 return 0;
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)
1599 int byte,
1600 nbits;
1602 /* number of bits to examine in last byte */
1603 nbits = n % 8;
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 */
1611 nbits = 7;
1612 break;
1616 /* check bits in last partial byte */
1617 if (nbits != 0)
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)
1624 nbits--;
1627 return (8 * byte) + nbits;
1632 * Verify a CIDR address is OK (doesn't have bits set past the masklen)
1634 static bool
1635 addressOK(unsigned char *a, int bits, int family)
1637 int byte;
1638 int nbits;
1639 int maxbits;
1640 int maxbytes;
1641 unsigned char mask;
1643 if (family == PGSQL_AF_INET)
1645 maxbits = 32;
1646 maxbytes = 4;
1648 else
1650 maxbits = 128;
1651 maxbytes = 16;
1653 Assert(bits <= maxbits);
1655 if (bits == maxbits)
1656 return true;
1658 byte = bits / 8;
1660 nbits = bits % 8;
1661 mask = 0xff;
1662 if (bits != 0)
1663 mask >>= nbits;
1665 while (byte < maxbytes)
1667 if ((a[byte] & mask) != 0)
1668 return false;
1669 mask = 0xff;
1670 byte++;
1673 return true;
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 */
1683 Datum
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.
1697 Datum
1698 network_scan_last(Datum in)
1700 return DirectFunctionCall2(inet_set_masklen,
1701 DirectFunctionCall1(network_broadcast, in),
1702 Int32GetDatum(-1));
1707 * IP address that the client is connecting from (NULL if Unix socket)
1709 Datum
1710 inet_client_addr(PG_FUNCTION_ARGS)
1712 Port *port = MyProcPort;
1713 char remote_host[NI_MAXHOST];
1714 int ret;
1716 if (port == NULL)
1717 PG_RETURN_NULL();
1719 switch (port->raddr.addr.ss_family)
1721 case AF_INET:
1722 case AF_INET6:
1723 break;
1724 default:
1725 PG_RETURN_NULL();
1728 remote_host[0] = '\0';
1730 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1731 remote_host, sizeof(remote_host),
1732 NULL, 0,
1733 NI_NUMERICHOST | NI_NUMERICSERV);
1734 if (ret != 0)
1735 PG_RETURN_NULL();
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)
1746 Datum
1747 inet_client_port(PG_FUNCTION_ARGS)
1749 Port *port = MyProcPort;
1750 char remote_port[NI_MAXSERV];
1751 int ret;
1753 if (port == NULL)
1754 PG_RETURN_NULL();
1756 switch (port->raddr.addr.ss_family)
1758 case AF_INET:
1759 case AF_INET6:
1760 break;
1761 default:
1762 PG_RETURN_NULL();
1765 remote_port[0] = '\0';
1767 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1768 NULL, 0,
1769 remote_port, sizeof(remote_port),
1770 NI_NUMERICHOST | NI_NUMERICSERV);
1771 if (ret != 0)
1772 PG_RETURN_NULL();
1774 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
1779 * IP address that the server accepted the connection on (NULL if Unix socket)
1781 Datum
1782 inet_server_addr(PG_FUNCTION_ARGS)
1784 Port *port = MyProcPort;
1785 char local_host[NI_MAXHOST];
1786 int ret;
1788 if (port == NULL)
1789 PG_RETURN_NULL();
1791 switch (port->laddr.addr.ss_family)
1793 case AF_INET:
1794 case AF_INET6:
1795 break;
1796 default:
1797 PG_RETURN_NULL();
1800 local_host[0] = '\0';
1802 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1803 local_host, sizeof(local_host),
1804 NULL, 0,
1805 NI_NUMERICHOST | NI_NUMERICSERV);
1806 if (ret != 0)
1807 PG_RETURN_NULL();
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)
1818 Datum
1819 inet_server_port(PG_FUNCTION_ARGS)
1821 Port *port = MyProcPort;
1822 char local_port[NI_MAXSERV];
1823 int ret;
1825 if (port == NULL)
1826 PG_RETURN_NULL();
1828 switch (port->laddr.addr.ss_family)
1830 case AF_INET:
1831 case AF_INET6:
1832 break;
1833 default:
1834 PG_RETURN_NULL();
1837 local_port[0] = '\0';
1839 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1840 NULL, 0,
1841 local_port, sizeof(local_port),
1842 NI_NUMERICHOST | NI_NUMERICSERV);
1843 if (ret != 0)
1844 PG_RETURN_NULL();
1846 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));
1850 Datum
1851 inetnot(PG_FUNCTION_ARGS)
1853 inet *ip = PG_GETARG_INET_PP(0);
1854 inet *dst;
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);
1863 while (--nb >= 0)
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);
1875 Datum
1876 inetand(PG_FUNCTION_ARGS)
1878 inet *ip = PG_GETARG_INET_PP(0);
1879 inet *ip2 = PG_GETARG_INET_PP(1);
1880 inet *dst;
1882 dst = (inet *) palloc0(sizeof(inet));
1884 if (ip_family(ip) != ip_family(ip2))
1885 ereport(ERROR,
1886 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1887 errmsg("cannot AND inet values of different sizes")));
1888 else
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);
1895 while (--nb >= 0)
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);
1907 Datum
1908 inetor(PG_FUNCTION_ARGS)
1910 inet *ip = PG_GETARG_INET_PP(0);
1911 inet *ip2 = PG_GETARG_INET_PP(1);
1912 inet *dst;
1914 dst = (inet *) palloc0(sizeof(inet));
1916 if (ip_family(ip) != ip_family(ip2))
1917 ereport(ERROR,
1918 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1919 errmsg("cannot OR inet values of different sizes")));
1920 else
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);
1927 while (--nb >= 0)
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);
1939 static inet *
1940 internal_inetpl(inet *ip, int64 addend)
1942 inet *dst;
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);
1950 int carry = 0;
1952 while (--nb >= 0)
1954 carry = pip[nb] + (int) (addend & 0xFF) + carry;
1955 pdst[nb] = (unsigned char) (carry & 0xFF);
1956 carry >>= 8;
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);
1968 addend /= 0x100;
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)))
1978 ereport(ERROR,
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);
1987 return dst;
1991 Datum
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));
2001 Datum
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));
2011 Datum
2012 inetmi(PG_FUNCTION_ARGS)
2014 inet *ip = PG_GETARG_INET_PP(0);
2015 inet *ip2 = PG_GETARG_INET_PP(1);
2016 int64 res = 0;
2018 if (ip_family(ip) != ip_family(ip2))
2019 ereport(ERROR,
2020 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2021 errmsg("cannot subtract inet values of different sizes")));
2022 else
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);
2031 int byte = 0;
2032 unsigned char *pip = ip_addr(ip);
2033 unsigned char *pip2 = ip_addr(ip2);
2034 int carry = 1;
2036 while (--nb >= 0)
2038 int lobyte;
2040 carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
2041 lobyte = carry & 0xFF;
2042 if (byte < sizeof(int64))
2044 res |= ((int64) lobyte) << (byte * 8);
2046 else
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))
2054 ereport(ERROR,
2055 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2056 errmsg("result is out of range")));
2058 carry >>= 8;
2059 byte++;
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.
2088 void
2089 clean_ipv6_addr(int addr_family, char *addr)
2091 if (addr_family == AF_INET6)
2093 char *pct = strchr(addr, '%');
2095 if (pct)
2096 *pct = '\0';