PostgreSQL Source Code git master
Loading...
Searching...
No Matches
network_gist.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * network_gist.c
4 * GiST support for network types.
5 *
6 * The key thing to understand about this code is the definition of the
7 * "union" of a set of INET/CIDR values. It works like this:
8 * 1. If the values are not all of the same IP address family, the "union"
9 * is a dummy value with family number zero, minbits zero, commonbits zero,
10 * address all zeroes. Otherwise:
11 * 2. The union has the common IP address family number.
12 * 3. The union's minbits value is the smallest netmask length ("ip_bits")
13 * of all the input values.
14 * 4. Let C be the number of leading address bits that are in common among
15 * all the input values (C ranges from 0 to ip_maxbits for the family).
16 * 5. The union's commonbits value is C.
17 * 6. The union's address value is the same as the common prefix for its
18 * first C bits, and is zeroes to the right of that. The physical width
19 * of the address value is ip_maxbits for the address family.
20 *
21 * In a leaf index entry (representing a single key), commonbits is equal to
22 * ip_maxbits for the address family, minbits is the same as the represented
23 * value's ip_bits, and the address is equal to the represented address.
24 * Although it may appear that we're wasting a byte by storing the union
25 * format and not just the represented INET/CIDR value in leaf keys, the
26 * extra byte is actually "free" because of alignment considerations.
27 *
28 * Note that this design tracks minbits and commonbits independently; in any
29 * given union value, either might be smaller than the other. This does not
30 * help us much when descending the tree, because of the way inet comparison
31 * is defined: at non-leaf nodes we can't compare more than minbits bits
32 * even if we know them. However, it greatly improves the quality of split
33 * decisions. Preliminary testing suggests that searches are as much as
34 * twice as fast as for a simpler design in which a single field doubles as
35 * the common prefix length and the minimum ip_bits value.
36 *
37 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
38 * Portions Copyright (c) 1994, Regents of the University of California
39 *
40 *
41 * IDENTIFICATION
42 * src/backend/utils/adt/network_gist.c
43 *
44 *-------------------------------------------------------------------------
45 */
46#include "postgres.h"
47
48#include <sys/socket.h>
49
50#include "access/gist.h"
51#include "access/stratnum.h"
52#include "utils/fmgrprotos.h"
53#include "utils/inet.h"
54#include "varatt.h"
55
56/*
57 * Operator strategy numbers used in the GiST inet_ops opclass
58 */
59#define INETSTRAT_OVERLAPS RTOverlapStrategyNumber
60#define INETSTRAT_EQ RTEqualStrategyNumber
61#define INETSTRAT_NE RTNotEqualStrategyNumber
62#define INETSTRAT_LT RTLessStrategyNumber
63#define INETSTRAT_LE RTLessEqualStrategyNumber
64#define INETSTRAT_GT RTGreaterStrategyNumber
65#define INETSTRAT_GE RTGreaterEqualStrategyNumber
66#define INETSTRAT_SUB RTSubStrategyNumber
67#define INETSTRAT_SUBEQ RTSubEqualStrategyNumber
68#define INETSTRAT_SUP RTSuperStrategyNumber
69#define INETSTRAT_SUPEQ RTSuperEqualStrategyNumber
70
71
72/*
73 * Representation of a GiST INET/CIDR index key. This is not identical to
74 * INET/CIDR because we need to keep track of the length of the common address
75 * prefix as well as the minimum netmask length. However, as long as it
76 * follows varlena header rules, the core GiST code won't know the difference.
77 * For simplicity we always use 1-byte-header varlena format.
78 */
79typedef struct GistInetKey
80{
81 uint8 va_header; /* varlena header --- don't touch directly */
82 unsigned char family; /* PGSQL_AF_INET, PGSQL_AF_INET6, or zero */
83 unsigned char minbits; /* minimum number of bits in netmask */
84 unsigned char commonbits; /* number of common prefix bits in addresses */
85 unsigned char ipaddr[16]; /* up to 128 bits of common address */
87
88#define DatumGetInetKeyP(X) ((GistInetKey *) DatumGetPointer(X))
89#define InetKeyPGetDatum(X) PointerGetDatum(X)
90
91/*
92 * Access macros; not really exciting, but we use these for notational
93 * consistency with access to INET/CIDR values. Note that family-zero values
94 * are stored with 4 bytes of address, not 16.
95 */
96#define gk_ip_family(gkptr) ((gkptr)->family)
97#define gk_ip_minbits(gkptr) ((gkptr)->minbits)
98#define gk_ip_commonbits(gkptr) ((gkptr)->commonbits)
99#define gk_ip_addr(gkptr) ((gkptr)->ipaddr)
100#define ip_family_maxbits(fam) ((fam) == PGSQL_AF_INET6 ? 128 : 32)
101
102/* These require that the family field has been set: */
103#define gk_ip_addrsize(gkptr) \
104 (gk_ip_family(gkptr) == PGSQL_AF_INET6 ? 16 : 4)
105#define gk_ip_maxbits(gkptr) \
106 ip_family_maxbits(gk_ip_family(gkptr))
107#define SET_GK_VARSIZE(dst) \
108 SET_VARSIZE_SHORT(dst, offsetof(GistInetKey, ipaddr) + gk_ip_addrsize(dst))
109
110
111/*
112 * The GiST query consistency check
113 */
114Datum
116{
118 inet *query = PG_GETARG_INET_PP(1);
120#ifdef NOT_USED
121 Oid subtype = PG_GETARG_OID(3);
122#endif
123 bool *recheck = (bool *) PG_GETARG_POINTER(4);
124 GistInetKey *key = DatumGetInetKeyP(ent->key);
125 int minbits,
126 order;
127
128 /* All operators served by this function are exact. */
129 *recheck = false;
130
131 /*
132 * Check 0: different families
133 *
134 * If key represents multiple address families, its children could match
135 * anything. This can only happen on an inner index page.
136 */
137 if (gk_ip_family(key) == 0)
138 {
140 PG_RETURN_BOOL(true);
141 }
142
143 /*
144 * Check 1: different families
145 *
146 * Matching families do not help any of the strategies.
147 */
148 if (gk_ip_family(key) != ip_family(query))
149 {
150 switch (strategy)
151 {
152 case INETSTRAT_LT:
153 case INETSTRAT_LE:
154 if (gk_ip_family(key) < ip_family(query))
155 PG_RETURN_BOOL(true);
156 break;
157
158 case INETSTRAT_GE:
159 case INETSTRAT_GT:
160 if (gk_ip_family(key) > ip_family(query))
161 PG_RETURN_BOOL(true);
162 break;
163
164 case INETSTRAT_NE:
165 PG_RETURN_BOOL(true);
166 }
167 /* For all other cases, we can be sure there is no match */
168 PG_RETURN_BOOL(false);
169 }
170
171 /*
172 * Check 2: network bit count
173 *
174 * Network bit count (ip_bits) helps to check leaves for sub network and
175 * sup network operators. At non-leaf nodes, we know every child value
176 * has ip_bits >= gk_ip_minbits(key), so we can avoid descending in some
177 * cases too.
178 */
179 switch (strategy)
180 {
181 case INETSTRAT_SUB:
182 if (GIST_LEAF(ent) && gk_ip_minbits(key) <= ip_bits(query))
183 PG_RETURN_BOOL(false);
184 break;
185
186 case INETSTRAT_SUBEQ:
187 if (GIST_LEAF(ent) && gk_ip_minbits(key) < ip_bits(query))
188 PG_RETURN_BOOL(false);
189 break;
190
191 case INETSTRAT_SUPEQ:
192 case INETSTRAT_EQ:
193 if (gk_ip_minbits(key) > ip_bits(query))
194 PG_RETURN_BOOL(false);
195 break;
196
197 case INETSTRAT_SUP:
198 if (gk_ip_minbits(key) >= ip_bits(query))
199 PG_RETURN_BOOL(false);
200 break;
201 }
202
203 /*
204 * Check 3: common network bits
205 *
206 * Compare available common prefix bits to the query, but not beyond
207 * either the query's netmask or the minimum netmask among the represented
208 * values. If these bits don't match the query, we have our answer (and
209 * may or may not need to descend, depending on the operator). If they do
210 * match, and we are not at a leaf, we descend in all cases.
211 *
212 * Note this is the final check for operators that only consider the
213 * network part of the address.
214 */
215 minbits = Min(gk_ip_commonbits(key), gk_ip_minbits(key));
216 minbits = Min(minbits, ip_bits(query));
217
218 order = bitncmp(gk_ip_addr(key), ip_addr(query), minbits);
219
220 switch (strategy)
221 {
222 case INETSTRAT_SUB:
223 case INETSTRAT_SUBEQ:
225 case INETSTRAT_SUPEQ:
226 case INETSTRAT_SUP:
227 PG_RETURN_BOOL(order == 0);
228
229 case INETSTRAT_LT:
230 case INETSTRAT_LE:
231 if (order > 0)
232 PG_RETURN_BOOL(false);
233 if (order < 0 || !GIST_LEAF(ent))
234 PG_RETURN_BOOL(true);
235 break;
236
237 case INETSTRAT_EQ:
238 if (order != 0)
239 PG_RETURN_BOOL(false);
240 if (!GIST_LEAF(ent))
241 PG_RETURN_BOOL(true);
242 break;
243
244 case INETSTRAT_GE:
245 case INETSTRAT_GT:
246 if (order < 0)
247 PG_RETURN_BOOL(false);
248 if (order > 0 || !GIST_LEAF(ent))
249 PG_RETURN_BOOL(true);
250 break;
251
252 case INETSTRAT_NE:
253 if (order != 0 || !GIST_LEAF(ent))
254 PG_RETURN_BOOL(true);
255 break;
256 }
257
258 /*
259 * Remaining checks are only for leaves and basic comparison strategies.
260 * See network_cmp_internal() in network.c for the implementation we need
261 * to match. Note that in a leaf key, commonbits should equal the address
262 * length, so we compared the whole network parts above.
263 */
265
266 /*
267 * Check 4: network bit count
268 *
269 * Next step is to compare netmask widths.
270 */
271 switch (strategy)
272 {
273 case INETSTRAT_LT:
274 case INETSTRAT_LE:
275 if (gk_ip_minbits(key) < ip_bits(query))
276 PG_RETURN_BOOL(true);
277 if (gk_ip_minbits(key) > ip_bits(query))
278 PG_RETURN_BOOL(false);
279 break;
280
281 case INETSTRAT_EQ:
282 if (gk_ip_minbits(key) != ip_bits(query))
283 PG_RETURN_BOOL(false);
284 break;
285
286 case INETSTRAT_GE:
287 case INETSTRAT_GT:
288 if (gk_ip_minbits(key) > ip_bits(query))
289 PG_RETURN_BOOL(true);
290 if (gk_ip_minbits(key) < ip_bits(query))
291 PG_RETURN_BOOL(false);
292 break;
293
294 case INETSTRAT_NE:
295 if (gk_ip_minbits(key) != ip_bits(query))
296 PG_RETURN_BOOL(true);
297 break;
298 }
299
300 /*
301 * Check 5: whole address
302 *
303 * Netmask bit counts are the same, so check all the address bits.
304 */
305 order = bitncmp(gk_ip_addr(key), ip_addr(query), gk_ip_maxbits(key));
306
307 switch (strategy)
308 {
309 case INETSTRAT_LT:
310 PG_RETURN_BOOL(order < 0);
311
312 case INETSTRAT_LE:
313 PG_RETURN_BOOL(order <= 0);
314
315 case INETSTRAT_EQ:
316 PG_RETURN_BOOL(order == 0);
317
318 case INETSTRAT_GE:
319 PG_RETURN_BOOL(order >= 0);
320
321 case INETSTRAT_GT:
322 PG_RETURN_BOOL(order > 0);
323
324 case INETSTRAT_NE:
325 PG_RETURN_BOOL(order != 0);
326 }
327
328 elog(ERROR, "unknown strategy for inet GiST");
329 PG_RETURN_BOOL(false); /* keep compiler quiet */
330}
331
332/*
333 * Calculate parameters of the union of some GistInetKeys.
334 *
335 * Examine the keys in elements m..n inclusive of the GISTENTRY array,
336 * and compute these output parameters:
337 * *minfamily_p = minimum IP address family number
338 * *maxfamily_p = maximum IP address family number
339 * *minbits_p = minimum netmask width
340 * *commonbits_p = number of leading bits in common among the addresses
341 *
342 * minbits and commonbits are forced to zero if there's more than one
343 * address family.
344 */
345static void
347 int m, int n,
348 int *minfamily_p,
349 int *maxfamily_p,
350 int *minbits_p,
351 int *commonbits_p)
352{
353 int minfamily,
354 maxfamily,
355 minbits,
356 commonbits;
357 unsigned char *addr;
358 GistInetKey *tmp;
359 int i;
360
361 /* Must be at least one key. */
362 Assert(m <= n);
363
364 /* Initialize variables using the first key. */
365 tmp = DatumGetInetKeyP(ent[m].key);
367 minbits = gk_ip_minbits(tmp);
368 commonbits = gk_ip_commonbits(tmp);
369 addr = gk_ip_addr(tmp);
370
371 /* Scan remaining keys. */
372 for (i = m + 1; i <= n; i++)
373 {
374 tmp = DatumGetInetKeyP(ent[i].key);
375
376 /* Determine range of family numbers */
377 if (minfamily > gk_ip_family(tmp))
378 minfamily = gk_ip_family(tmp);
379 if (maxfamily < gk_ip_family(tmp))
380 maxfamily = gk_ip_family(tmp);
381
382 /* Find minimum minbits */
383 if (minbits > gk_ip_minbits(tmp))
384 minbits = gk_ip_minbits(tmp);
385
386 /* Find minimum number of bits in common */
387 if (commonbits > gk_ip_commonbits(tmp))
388 commonbits = gk_ip_commonbits(tmp);
389 if (commonbits > 0)
390 commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
391 }
392
393 /* Force minbits/commonbits to zero if more than one family. */
394 if (minfamily != maxfamily)
395 minbits = commonbits = 0;
396
399 *minbits_p = minbits;
400 *commonbits_p = commonbits;
401}
402
403/*
404 * Same as above, but the GISTENTRY elements to examine are those with
405 * indices listed in the offsets[] array.
406 */
407static void
409 OffsetNumber *offsets, int noffsets,
410 int *minfamily_p,
411 int *maxfamily_p,
412 int *minbits_p,
413 int *commonbits_p)
414{
415 int minfamily,
416 maxfamily,
417 minbits,
418 commonbits;
419 unsigned char *addr;
420 GistInetKey *tmp;
421 int i;
422
423 /* Must be at least one key. */
424 Assert(noffsets > 0);
425
426 /* Initialize variables using the first key. */
427 tmp = DatumGetInetKeyP(ent[offsets[0]].key);
429 minbits = gk_ip_minbits(tmp);
430 commonbits = gk_ip_commonbits(tmp);
431 addr = gk_ip_addr(tmp);
432
433 /* Scan remaining keys. */
434 for (i = 1; i < noffsets; i++)
435 {
436 tmp = DatumGetInetKeyP(ent[offsets[i]].key);
437
438 /* Determine range of family numbers */
439 if (minfamily > gk_ip_family(tmp))
440 minfamily = gk_ip_family(tmp);
441 if (maxfamily < gk_ip_family(tmp))
442 maxfamily = gk_ip_family(tmp);
443
444 /* Find minimum minbits */
445 if (minbits > gk_ip_minbits(tmp))
446 minbits = gk_ip_minbits(tmp);
447
448 /* Find minimum number of bits in common */
449 if (commonbits > gk_ip_commonbits(tmp))
450 commonbits = gk_ip_commonbits(tmp);
451 if (commonbits > 0)
452 commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
453 }
454
455 /* Force minbits/commonbits to zero if more than one family. */
456 if (minfamily != maxfamily)
457 minbits = commonbits = 0;
458
461 *minbits_p = minbits;
462 *commonbits_p = commonbits;
463}
464
465/*
466 * Construct a GistInetKey representing a union value.
467 *
468 * Inputs are the family/minbits/commonbits values to use, plus a pointer to
469 * the address field of one of the union inputs. (Since we're going to copy
470 * just the bits-in-common, it doesn't matter which one.)
471 */
472static GistInetKey *
473build_inet_union_key(int family, int minbits, int commonbits,
474 unsigned char *addr)
475{
476 GistInetKey *result;
477
478 /* Make sure any unused bits are zeroed. */
479 result = palloc0_object(GistInetKey);
480
481 gk_ip_family(result) = family;
482 gk_ip_minbits(result) = minbits;
483 gk_ip_commonbits(result) = commonbits;
484
485 /* Clone appropriate bytes of the address. */
486 if (commonbits > 0)
487 memcpy(gk_ip_addr(result), addr, (commonbits + 7) / 8);
488
489 /* Clean any unwanted bits in the last partial byte. */
490 if (commonbits % 8 != 0)
491 gk_ip_addr(result)[commonbits / 8] &= ~(0xFF >> (commonbits % 8));
492
493 /* Set varlena header correctly. */
494 SET_GK_VARSIZE(result);
495
496 return result;
497}
498
499
500/*
501 * The GiST union function
502 *
503 * See comments at head of file for the definition of the union.
504 */
505Datum
507{
509 GISTENTRY *ent = entryvec->vector;
510 int minfamily,
511 maxfamily,
512 minbits,
513 commonbits;
514 unsigned char *addr;
515 GistInetKey *tmp,
516 *result;
517
518 /* Determine parameters of the union. */
521 &minbits, &commonbits);
522
523 /* If more than one family, emit family number zero. */
524 if (minfamily != maxfamily)
525 minfamily = 0;
526
527 /* Initialize address using the first key. */
528 tmp = DatumGetInetKeyP(ent[0].key);
529 addr = gk_ip_addr(tmp);
530
531 /* Construct the union value. */
532 result = build_inet_union_key(minfamily, minbits, commonbits, addr);
533
534 PG_RETURN_POINTER(result);
535}
536
537/*
538 * The GiST compress function
539 *
540 * Convert an inet value to GistInetKey.
541 */
542Datum
544{
545 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
546 GISTENTRY *retval;
547
548 if (entry->leafkey)
549 {
550 retval = palloc_object(GISTENTRY);
551 if (DatumGetPointer(entry->key) != NULL)
552 {
553 inet *in = DatumGetInetPP(entry->key);
554 GistInetKey *r;
555
557
558 gk_ip_family(r) = ip_family(in);
559 gk_ip_minbits(r) = ip_bits(in);
563
564 gistentryinit(*retval, PointerGetDatum(r),
565 entry->rel, entry->page,
566 entry->offset, false);
567 }
568 else
569 {
570 gistentryinit(*retval, (Datum) 0,
571 entry->rel, entry->page,
572 entry->offset, false);
573 }
574 }
575 else
576 retval = entry;
577 PG_RETURN_POINTER(retval);
578}
579
580/*
581 * We do not need a decompress function, because the other GiST inet
582 * support functions work with the GistInetKey representation.
583 */
584
585/*
586 * The GiST fetch function
587 *
588 * Reconstruct the original inet datum from a GistInetKey.
589 */
590Datum
592{
593 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
594 GistInetKey *key = DatumGetInetKeyP(entry->key);
595 GISTENTRY *retval;
596 inet *dst;
597
599
600 ip_family(dst) = gk_ip_family(key);
601 ip_bits(dst) = gk_ip_minbits(key);
604
605 retval = palloc_object(GISTENTRY);
606 gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page,
607 entry->offset, false);
608
609 PG_RETURN_POINTER(retval);
610}
611
612/*
613 * The GiST page split penalty function
614 *
615 * Charge a large penalty if address family doesn't match, or a somewhat
616 * smaller one if the new value would degrade the union's minbits
617 * (minimum netmask width). Otherwise, penalty is inverse of the
618 * new number of common address bits.
619 */
620Datum
622{
625 float *penalty = (float *) PG_GETARG_POINTER(2);
627 *new = DatumGetInetKeyP(newent->key);
628 int commonbits;
629
630 if (gk_ip_family(orig) == gk_ip_family(new))
631 {
632 if (gk_ip_minbits(orig) <= gk_ip_minbits(new))
633 {
634 commonbits = bitncommon(gk_ip_addr(orig), gk_ip_addr(new),
636 gk_ip_commonbits(new)));
637 if (commonbits > 0)
638 *penalty = 1.0f / commonbits;
639 else
640 *penalty = 2;
641 }
642 else
643 *penalty = 3;
644 }
645 else
646 *penalty = 4;
647
648 PG_RETURN_POINTER(penalty);
649}
650
651/*
652 * The GiST PickSplit method
653 *
654 * There are two ways to split. First one is to split by address families,
655 * if there are multiple families appearing in the input.
656 *
657 * The second and more common way is to split by addresses. To achieve this,
658 * determine the number of leading bits shared by all the keys, then split on
659 * the next bit. (We don't currently consider the netmask widths while doing
660 * this; should we?) If we fail to get a nontrivial split that way, split
661 * 50-50.
662 */
663Datum
665{
668 GISTENTRY *ent = entryvec->vector;
669 int minfamily,
670 maxfamily,
671 minbits,
672 commonbits;
673 unsigned char *addr;
674 GistInetKey *tmp,
675 *left_union,
677 int maxoff,
678 nbytes;
680 *left,
681 *right;
682
683 maxoff = entryvec->n - 1;
684 nbytes = (maxoff + 1) * sizeof(OffsetNumber);
685
686 left = (OffsetNumber *) palloc(nbytes);
687 right = (OffsetNumber *) palloc(nbytes);
688
689 splitvec->spl_left = left;
690 splitvec->spl_right = right;
691
692 splitvec->spl_nleft = 0;
693 splitvec->spl_nright = 0;
694
695 /* Determine parameters of the union of all the inputs. */
698 &minbits, &commonbits);
699
700 if (minfamily != maxfamily)
701 {
702 /* Multiple families, so split by family. */
703 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
704 {
705 /*
706 * If there's more than 2 families, all but maxfamily go into the
707 * left union. This could only happen if the inputs include some
708 * IPv4, some IPv6, and some already-multiple-family unions.
709 */
710 tmp = DatumGetInetKeyP(ent[i].key);
711 if (gk_ip_family(tmp) != maxfamily)
712 left[splitvec->spl_nleft++] = i;
713 else
714 right[splitvec->spl_nright++] = i;
715 }
716 }
717 else
718 {
719 /*
720 * Split on the next bit after the common bits. If that yields a
721 * trivial split, try the next bit position to the right. Repeat till
722 * success; or if we run out of bits, do an arbitrary 50-50 split.
723 */
725
726 while (commonbits < maxbits)
727 {
728 /* Split using the commonbits'th bit position. */
729 int bitbyte = commonbits / 8;
730 int bitmask = 0x80 >> (commonbits % 8);
731
732 splitvec->spl_nleft = splitvec->spl_nright = 0;
733
734 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
735 {
736 tmp = DatumGetInetKeyP(ent[i].key);
737 addr = gk_ip_addr(tmp);
738 if ((addr[bitbyte] & bitmask) == 0)
739 left[splitvec->spl_nleft++] = i;
740 else
741 right[splitvec->spl_nright++] = i;
742 }
743
744 if (splitvec->spl_nleft > 0 && splitvec->spl_nright > 0)
745 break; /* success */
746 commonbits++;
747 }
748
749 if (commonbits >= maxbits)
750 {
751 /* Failed ... do a 50-50 split. */
752 splitvec->spl_nleft = splitvec->spl_nright = 0;
753
754 for (i = FirstOffsetNumber; i <= maxoff / 2; i = OffsetNumberNext(i))
755 {
756 left[splitvec->spl_nleft++] = i;
757 }
758 for (; i <= maxoff; i = OffsetNumberNext(i))
759 {
760 right[splitvec->spl_nright++] = i;
761 }
762 }
763 }
764
765 /*
766 * Compute the union value for each side from scratch. In most cases we
767 * could approximate the union values with what we already know, but this
768 * ensures that each side has minbits and commonbits set as high as
769 * possible.
770 */
773 &minbits, &commonbits);
774 if (minfamily != maxfamily)
775 minfamily = 0;
776 tmp = DatumGetInetKeyP(ent[left[0]].key);
777 addr = gk_ip_addr(tmp);
778 left_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
779 splitvec->spl_ldatum = PointerGetDatum(left_union);
780
781 calc_inet_union_params_indexed(ent, right, splitvec->spl_nright,
783 &minbits, &commonbits);
784 if (minfamily != maxfamily)
785 minfamily = 0;
786 tmp = DatumGetInetKeyP(ent[right[0]].key);
787 addr = gk_ip_addr(tmp);
788 right_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
789 splitvec->spl_rdatum = PointerGetDatum(right_union);
790
792}
793
794/*
795 * The GiST equality function
796 */
797Datum
799{
802 bool *result = (bool *) PG_GETARG_POINTER(2);
803
804 *result = (gk_ip_family(left) == gk_ip_family(right) &&
805 gk_ip_minbits(left) == gk_ip_minbits(right) &&
806 gk_ip_commonbits(left) == gk_ip_commonbits(right) &&
807 memcmp(gk_ip_addr(left), gk_ip_addr(right),
808 gk_ip_addrsize(left)) == 0);
809
810 PG_RETURN_POINTER(result);
811}
#define Min(x, y)
Definition c.h:997
uint8_t uint8
Definition c.h:544
#define Assert(condition)
Definition c.h:873
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define palloc_object(type)
Definition fe_memutils.h:74
#define palloc0_object(type)
Definition fe_memutils.h:75
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_UINT16(n)
Definition fmgr.h:272
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define GIST_LEAF(entry)
Definition gist.h:171
#define gistentryinit(e, k, r, pg, o, l)
Definition gist.h:245
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1387
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition network.c:1536
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Definition network.c:1502
#define INETSTRAT_NE
#define INETSTRAT_SUPEQ
#define gk_ip_commonbits(gkptr)
#define INETSTRAT_LT
static void calc_inet_union_params(GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
Datum inet_gist_fetch(PG_FUNCTION_ARGS)
#define DatumGetInetKeyP(X)
static void calc_inet_union_params_indexed(GISTENTRY *ent, OffsetNumber *offsets, int noffsets, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
#define INETSTRAT_SUBEQ
#define gk_ip_maxbits(gkptr)
Datum inet_gist_compress(PG_FUNCTION_ARGS)
#define INETSTRAT_SUP
#define INETSTRAT_GT
#define gk_ip_family(gkptr)
#define gk_ip_addr(gkptr)
#define INETSTRAT_EQ
#define gk_ip_addrsize(gkptr)
static GistInetKey * build_inet_union_key(int family, int minbits, int commonbits, unsigned char *addr)
#define SET_GK_VARSIZE(dst)
#define INETSTRAT_SUB
Datum inet_gist_consistent(PG_FUNCTION_ARGS)
#define ip_family_maxbits(fam)
Datum inet_gist_union(PG_FUNCTION_ARGS)
#define INETSTRAT_GE
Datum inet_gist_picksplit(PG_FUNCTION_ARGS)
Datum inet_gist_penalty(PG_FUNCTION_ARGS)
Datum inet_gist_same(PG_FUNCTION_ARGS)
#define INETSTRAT_OVERLAPS
#define INETSTRAT_LE
#define gk_ip_minbits(gkptr)
#define OffsetNumberNext(offsetNumber)
Definition off.h:52
uint16 OffsetNumber
Definition off.h:24
#define FirstOffsetNumber
Definition off.h:27
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
unsigned int Oid
static int fb(int x)
uint16 StrategyNumber
Definition stratnum.h:22
OffsetNumber offset
Definition gist.h:164
Datum key
Definition gist.h:161
Page page
Definition gist.h:163
Relation rel
Definition gist.h:162
bool leafkey
Definition gist.h:165
unsigned char family
uint8 va_header
unsigned char ipaddr[16]
unsigned char minbits
unsigned char commonbits
Definition inet.h:53
static Datum InetPGetDatum(const inet *X)
Definition inet.h:129
static inet * DatumGetInetPP(Datum X)
Definition inet.h:123
#define ip_addr(inetptr)
Definition inet.h:77
#define SET_INET_VARSIZE(dst)
Definition inet.h:86
#define PG_GETARG_INET_PP(n)
Definition inet.h:134
#define ip_family(inetptr)
Definition inet.h:71
#define ip_addrsize(inetptr)
Definition inet.h:80
#define ip_bits(inetptr)
Definition inet.h:74