PostgreSQL Source Code  git master
network_gist.c File Reference
#include "postgres.h"
#include <sys/socket.h>
#include "access/gist.h"
#include "access/stratnum.h"
#include "utils/fmgrprotos.h"
#include "utils/inet.h"
#include "varatt.h"
Include dependency graph for network_gist.c:

Go to the source code of this file.

Data Structures

struct  GistInetKey
 

Macros

#define INETSTRAT_OVERLAPS   RTOverlapStrategyNumber
 
#define INETSTRAT_EQ   RTEqualStrategyNumber
 
#define INETSTRAT_NE   RTNotEqualStrategyNumber
 
#define INETSTRAT_LT   RTLessStrategyNumber
 
#define INETSTRAT_LE   RTLessEqualStrategyNumber
 
#define INETSTRAT_GT   RTGreaterStrategyNumber
 
#define INETSTRAT_GE   RTGreaterEqualStrategyNumber
 
#define INETSTRAT_SUB   RTSubStrategyNumber
 
#define INETSTRAT_SUBEQ   RTSubEqualStrategyNumber
 
#define INETSTRAT_SUP   RTSuperStrategyNumber
 
#define INETSTRAT_SUPEQ   RTSuperEqualStrategyNumber
 
#define DatumGetInetKeyP(X)   ((GistInetKey *) DatumGetPointer(X))
 
#define InetKeyPGetDatum(X)   PointerGetDatum(X)
 
#define gk_ip_family(gkptr)   ((gkptr)->family)
 
#define gk_ip_minbits(gkptr)   ((gkptr)->minbits)
 
#define gk_ip_commonbits(gkptr)   ((gkptr)->commonbits)
 
#define gk_ip_addr(gkptr)   ((gkptr)->ipaddr)
 
#define ip_family_maxbits(fam)   ((fam) == PGSQL_AF_INET6 ? 128 : 32)
 
#define gk_ip_addrsize(gkptr)    (gk_ip_family(gkptr) == PGSQL_AF_INET6 ? 16 : 4)
 
#define gk_ip_maxbits(gkptr)    ip_family_maxbits(gk_ip_family(gkptr))
 
#define SET_GK_VARSIZE(dst)    SET_VARSIZE_SHORT(dst, offsetof(GistInetKey, ipaddr) + gk_ip_addrsize(dst))
 

Typedefs

typedef struct GistInetKey GistInetKey
 

Functions

Datum inet_gist_consistent (PG_FUNCTION_ARGS)
 
static void calc_inet_union_params (GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
 
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)
 
static GistInetKeybuild_inet_union_key (int family, int minbits, int commonbits, unsigned char *addr)
 
Datum inet_gist_union (PG_FUNCTION_ARGS)
 
Datum inet_gist_compress (PG_FUNCTION_ARGS)
 
Datum inet_gist_fetch (PG_FUNCTION_ARGS)
 
Datum inet_gist_penalty (PG_FUNCTION_ARGS)
 
Datum inet_gist_picksplit (PG_FUNCTION_ARGS)
 
Datum inet_gist_same (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ DatumGetInetKeyP

#define DatumGetInetKeyP (   X)    ((GistInetKey *) DatumGetPointer(X))

Definition at line 88 of file network_gist.c.

◆ gk_ip_addr

#define gk_ip_addr (   gkptr)    ((gkptr)->ipaddr)

Definition at line 99 of file network_gist.c.

◆ gk_ip_addrsize

#define gk_ip_addrsize (   gkptr)     (gk_ip_family(gkptr) == PGSQL_AF_INET6 ? 16 : 4)

Definition at line 103 of file network_gist.c.

◆ gk_ip_commonbits

#define gk_ip_commonbits (   gkptr)    ((gkptr)->commonbits)

Definition at line 98 of file network_gist.c.

◆ gk_ip_family

#define gk_ip_family (   gkptr)    ((gkptr)->family)

Definition at line 96 of file network_gist.c.

◆ gk_ip_maxbits

#define gk_ip_maxbits (   gkptr)     ip_family_maxbits(gk_ip_family(gkptr))

Definition at line 105 of file network_gist.c.

◆ gk_ip_minbits

#define gk_ip_minbits (   gkptr)    ((gkptr)->minbits)

Definition at line 97 of file network_gist.c.

◆ InetKeyPGetDatum

#define InetKeyPGetDatum (   X)    PointerGetDatum(X)

Definition at line 89 of file network_gist.c.

◆ INETSTRAT_EQ

#define INETSTRAT_EQ   RTEqualStrategyNumber

Definition at line 60 of file network_gist.c.

◆ INETSTRAT_GE

#define INETSTRAT_GE   RTGreaterEqualStrategyNumber

Definition at line 65 of file network_gist.c.

◆ INETSTRAT_GT

#define INETSTRAT_GT   RTGreaterStrategyNumber

Definition at line 64 of file network_gist.c.

◆ INETSTRAT_LE

#define INETSTRAT_LE   RTLessEqualStrategyNumber

Definition at line 63 of file network_gist.c.

◆ INETSTRAT_LT

#define INETSTRAT_LT   RTLessStrategyNumber

Definition at line 62 of file network_gist.c.

◆ INETSTRAT_NE

#define INETSTRAT_NE   RTNotEqualStrategyNumber

Definition at line 61 of file network_gist.c.

◆ INETSTRAT_OVERLAPS

#define INETSTRAT_OVERLAPS   RTOverlapStrategyNumber

Definition at line 59 of file network_gist.c.

◆ INETSTRAT_SUB

#define INETSTRAT_SUB   RTSubStrategyNumber

Definition at line 66 of file network_gist.c.

◆ INETSTRAT_SUBEQ

#define INETSTRAT_SUBEQ   RTSubEqualStrategyNumber

Definition at line 67 of file network_gist.c.

◆ INETSTRAT_SUP

#define INETSTRAT_SUP   RTSuperStrategyNumber

Definition at line 68 of file network_gist.c.

◆ INETSTRAT_SUPEQ

#define INETSTRAT_SUPEQ   RTSuperEqualStrategyNumber

Definition at line 69 of file network_gist.c.

◆ ip_family_maxbits

#define ip_family_maxbits (   fam)    ((fam) == PGSQL_AF_INET6 ? 128 : 32)

Definition at line 100 of file network_gist.c.

◆ SET_GK_VARSIZE

#define SET_GK_VARSIZE (   dst)     SET_VARSIZE_SHORT(dst, offsetof(GistInetKey, ipaddr) + gk_ip_addrsize(dst))

Definition at line 107 of file network_gist.c.

Typedef Documentation

◆ GistInetKey

typedef struct GistInetKey GistInetKey

Function Documentation

◆ build_inet_union_key()

static GistInetKey* build_inet_union_key ( int  family,
int  minbits,
int  commonbits,
unsigned char *  addr 
)
static

Definition at line 472 of file network_gist.c.

474 {
475  GistInetKey *result;
476 
477  /* Make sure any unused bits are zeroed. */
478  result = (GistInetKey *) palloc0(sizeof(GistInetKey));
479 
480  gk_ip_family(result) = family;
481  gk_ip_minbits(result) = minbits;
482  gk_ip_commonbits(result) = commonbits;
483 
484  /* Clone appropriate bytes of the address. */
485  if (commonbits > 0)
486  memcpy(gk_ip_addr(result), addr, (commonbits + 7) / 8);
487 
488  /* Clean any unwanted bits in the last partial byte. */
489  if (commonbits % 8 != 0)
490  gk_ip_addr(result)[commonbits / 8] &= ~(0xFF >> (commonbits % 8));
491 
492  /* Set varlena header correctly. */
493  SET_GK_VARSIZE(result);
494 
495  return result;
496 }
void * palloc0(Size size)
Definition: mcxt.c:1346
#define gk_ip_commonbits(gkptr)
Definition: network_gist.c:98
#define gk_ip_family(gkptr)
Definition: network_gist.c:96
#define gk_ip_addr(gkptr)
Definition: network_gist.c:99
#define SET_GK_VARSIZE(dst)
Definition: network_gist.c:107
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:97

References gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, palloc0(), and SET_GK_VARSIZE.

Referenced by inet_gist_picksplit(), and inet_gist_union().

◆ calc_inet_union_params()

static void calc_inet_union_params ( GISTENTRY ent,
int  m,
int  n,
int *  minfamily_p,
int *  maxfamily_p,
int *  minbits_p,
int *  commonbits_p 
)
static

Definition at line 345 of file network_gist.c.

351 {
352  int minfamily,
353  maxfamily,
354  minbits,
355  commonbits;
356  unsigned char *addr;
357  GistInetKey *tmp;
358  int i;
359 
360  /* Must be at least one key. */
361  Assert(m <= n);
362 
363  /* Initialize variables using the first key. */
364  tmp = DatumGetInetKeyP(ent[m].key);
365  minfamily = maxfamily = gk_ip_family(tmp);
366  minbits = gk_ip_minbits(tmp);
367  commonbits = gk_ip_commonbits(tmp);
368  addr = gk_ip_addr(tmp);
369 
370  /* Scan remaining keys. */
371  for (i = m + 1; i <= n; i++)
372  {
373  tmp = DatumGetInetKeyP(ent[i].key);
374 
375  /* Determine range of family numbers */
376  if (minfamily > gk_ip_family(tmp))
377  minfamily = gk_ip_family(tmp);
378  if (maxfamily < gk_ip_family(tmp))
379  maxfamily = gk_ip_family(tmp);
380 
381  /* Find minimum minbits */
382  if (minbits > gk_ip_minbits(tmp))
383  minbits = gk_ip_minbits(tmp);
384 
385  /* Find minimum number of bits in common */
386  if (commonbits > gk_ip_commonbits(tmp))
387  commonbits = gk_ip_commonbits(tmp);
388  if (commonbits > 0)
389  commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
390  }
391 
392  /* Force minbits/commonbits to zero if more than one family. */
393  if (minfamily != maxfamily)
394  minbits = commonbits = 0;
395 
396  *minfamily_p = minfamily;
397  *maxfamily_p = maxfamily;
398  *minbits_p = minbits;
399  *commonbits_p = commonbits;
400 }
#define Assert(condition)
Definition: c.h:858
int i
Definition: isn.c:73
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1603
#define DatumGetInetKeyP(X)
Definition: network_gist.c:88

References Assert, bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, i, and sort-test::key.

Referenced by inet_gist_picksplit(), and inet_gist_union().

◆ calc_inet_union_params_indexed()

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 
)
static

Definition at line 407 of file network_gist.c.

413 {
414  int minfamily,
415  maxfamily,
416  minbits,
417  commonbits;
418  unsigned char *addr;
419  GistInetKey *tmp;
420  int i;
421 
422  /* Must be at least one key. */
423  Assert(noffsets > 0);
424 
425  /* Initialize variables using the first key. */
426  tmp = DatumGetInetKeyP(ent[offsets[0]].key);
427  minfamily = maxfamily = gk_ip_family(tmp);
428  minbits = gk_ip_minbits(tmp);
429  commonbits = gk_ip_commonbits(tmp);
430  addr = gk_ip_addr(tmp);
431 
432  /* Scan remaining keys. */
433  for (i = 1; i < noffsets; i++)
434  {
435  tmp = DatumGetInetKeyP(ent[offsets[i]].key);
436 
437  /* Determine range of family numbers */
438  if (minfamily > gk_ip_family(tmp))
439  minfamily = gk_ip_family(tmp);
440  if (maxfamily < gk_ip_family(tmp))
441  maxfamily = gk_ip_family(tmp);
442 
443  /* Find minimum minbits */
444  if (minbits > gk_ip_minbits(tmp))
445  minbits = gk_ip_minbits(tmp);
446 
447  /* Find minimum number of bits in common */
448  if (commonbits > gk_ip_commonbits(tmp))
449  commonbits = gk_ip_commonbits(tmp);
450  if (commonbits > 0)
451  commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
452  }
453 
454  /* Force minbits/commonbits to zero if more than one family. */
455  if (minfamily != maxfamily)
456  minbits = commonbits = 0;
457 
458  *minfamily_p = minfamily;
459  *maxfamily_p = maxfamily;
460  *minbits_p = minbits;
461  *commonbits_p = commonbits;
462 }

References Assert, bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, i, and sort-test::key.

Referenced by inet_gist_picksplit().

◆ inet_gist_compress()

Datum inet_gist_compress ( PG_FUNCTION_ARGS  )

Definition at line 542 of file network_gist.c.

543 {
544  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
545  GISTENTRY *retval;
546 
547  if (entry->leafkey)
548  {
549  retval = palloc(sizeof(GISTENTRY));
550  if (DatumGetPointer(entry->key) != NULL)
551  {
552  inet *in = DatumGetInetPP(entry->key);
553  GistInetKey *r;
554 
555  r = (GistInetKey *) palloc0(sizeof(GistInetKey));
556 
557  gk_ip_family(r) = ip_family(in);
558  gk_ip_minbits(r) = ip_bits(in);
560  memcpy(gk_ip_addr(r), ip_addr(in), gk_ip_addrsize(r));
561  SET_GK_VARSIZE(r);
562 
563  gistentryinit(*retval, PointerGetDatum(r),
564  entry->rel, entry->page,
565  entry->offset, false);
566  }
567  else
568  {
569  gistentryinit(*retval, (Datum) 0,
570  entry->rel, entry->page,
571  entry->offset, false);
572  }
573  }
574  else
575  retval = entry;
576  PG_RETURN_POINTER(retval);
577 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:244
void * palloc(Size size)
Definition: mcxt.c:1316
#define gk_ip_maxbits(gkptr)
Definition: network_gist.c:105
#define gk_ip_addrsize(gkptr)
Definition: network_gist.c:103
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
OffsetNumber offset
Definition: gist.h:163
Datum key
Definition: gist.h:160
Page page
Definition: gist.h:162
Relation rel
Definition: gist.h:161
bool leafkey
Definition: gist.h:164
Definition: inet.h:53
#define ip_addr(inetptr)
Definition: inet.h:77
#define ip_family(inetptr)
Definition: inet.h:71
static inet * DatumGetInetPP(Datum X)
Definition: inet.h:123
#define ip_bits(inetptr)
Definition: inet.h:74

References DatumGetInetPP(), DatumGetPointer(), gistentryinit, gk_ip_addr, gk_ip_addrsize, gk_ip_commonbits, gk_ip_family, gk_ip_maxbits, gk_ip_minbits, ip_addr, ip_bits, ip_family, GISTENTRY::key, GISTENTRY::leafkey, GISTENTRY::offset, GISTENTRY::page, palloc(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), GISTENTRY::rel, and SET_GK_VARSIZE.

◆ inet_gist_consistent()

Datum inet_gist_consistent ( PG_FUNCTION_ARGS  )

Definition at line 115 of file network_gist.c.

116 {
117  GISTENTRY *ent = (GISTENTRY *) PG_GETARG_POINTER(0);
118  inet *query = PG_GETARG_INET_PP(1);
120 
121  /* Oid subtype = PG_GETARG_OID(3); */
122  bool *recheck = (bool *) PG_GETARG_POINTER(4);
124  int minbits,
125  order;
126 
127  /* All operators served by this function are exact. */
128  *recheck = false;
129 
130  /*
131  * Check 0: different families
132  *
133  * If key represents multiple address families, its children could match
134  * anything. This can only happen on an inner index page.
135  */
136  if (gk_ip_family(key) == 0)
137  {
138  Assert(!GIST_LEAF(ent));
139  PG_RETURN_BOOL(true);
140  }
141 
142  /*
143  * Check 1: different families
144  *
145  * Matching families do not help any of the strategies.
146  */
147  if (gk_ip_family(key) != ip_family(query))
148  {
149  switch (strategy)
150  {
151  case INETSTRAT_LT:
152  case INETSTRAT_LE:
153  if (gk_ip_family(key) < ip_family(query))
154  PG_RETURN_BOOL(true);
155  break;
156 
157  case INETSTRAT_GE:
158  case INETSTRAT_GT:
159  if (gk_ip_family(key) > ip_family(query))
160  PG_RETURN_BOOL(true);
161  break;
162 
163  case INETSTRAT_NE:
164  PG_RETURN_BOOL(true);
165  }
166  /* For all other cases, we can be sure there is no match */
167  PG_RETURN_BOOL(false);
168  }
169 
170  /*
171  * Check 2: network bit count
172  *
173  * Network bit count (ip_bits) helps to check leaves for sub network and
174  * sup network operators. At non-leaf nodes, we know every child value
175  * has ip_bits >= gk_ip_minbits(key), so we can avoid descending in some
176  * cases too.
177  */
178  switch (strategy)
179  {
180  case INETSTRAT_SUB:
181  if (GIST_LEAF(ent) && gk_ip_minbits(key) <= ip_bits(query))
182  PG_RETURN_BOOL(false);
183  break;
184 
185  case INETSTRAT_SUBEQ:
186  if (GIST_LEAF(ent) && gk_ip_minbits(key) < ip_bits(query))
187  PG_RETURN_BOOL(false);
188  break;
189 
190  case INETSTRAT_SUPEQ:
191  case INETSTRAT_EQ:
192  if (gk_ip_minbits(key) > ip_bits(query))
193  PG_RETURN_BOOL(false);
194  break;
195 
196  case INETSTRAT_SUP:
197  if (gk_ip_minbits(key) >= ip_bits(query))
198  PG_RETURN_BOOL(false);
199  break;
200  }
201 
202  /*
203  * Check 3: common network bits
204  *
205  * Compare available common prefix bits to the query, but not beyond
206  * either the query's netmask or the minimum netmask among the represented
207  * values. If these bits don't match the query, we have our answer (and
208  * may or may not need to descend, depending on the operator). If they do
209  * match, and we are not at a leaf, we descend in all cases.
210  *
211  * Note this is the final check for operators that only consider the
212  * network part of the address.
213  */
214  minbits = Min(gk_ip_commonbits(key), gk_ip_minbits(key));
215  minbits = Min(minbits, ip_bits(query));
216 
217  order = bitncmp(gk_ip_addr(key), ip_addr(query), minbits);
218 
219  switch (strategy)
220  {
221  case INETSTRAT_SUB:
222  case INETSTRAT_SUBEQ:
223  case INETSTRAT_OVERLAPS:
224  case INETSTRAT_SUPEQ:
225  case INETSTRAT_SUP:
226  PG_RETURN_BOOL(order == 0);
227 
228  case INETSTRAT_LT:
229  case INETSTRAT_LE:
230  if (order > 0)
231  PG_RETURN_BOOL(false);
232  if (order < 0 || !GIST_LEAF(ent))
233  PG_RETURN_BOOL(true);
234  break;
235 
236  case INETSTRAT_EQ:
237  if (order != 0)
238  PG_RETURN_BOOL(false);
239  if (!GIST_LEAF(ent))
240  PG_RETURN_BOOL(true);
241  break;
242 
243  case INETSTRAT_GE:
244  case INETSTRAT_GT:
245  if (order < 0)
246  PG_RETURN_BOOL(false);
247  if (order > 0 || !GIST_LEAF(ent))
248  PG_RETURN_BOOL(true);
249  break;
250 
251  case INETSTRAT_NE:
252  if (order != 0 || !GIST_LEAF(ent))
253  PG_RETURN_BOOL(true);
254  break;
255  }
256 
257  /*
258  * Remaining checks are only for leaves and basic comparison strategies.
259  * See network_cmp_internal() in network.c for the implementation we need
260  * to match. Note that in a leaf key, commonbits should equal the address
261  * length, so we compared the whole network parts above.
262  */
263  Assert(GIST_LEAF(ent));
264 
265  /*
266  * Check 4: network bit count
267  *
268  * Next step is to compare netmask widths.
269  */
270  switch (strategy)
271  {
272  case INETSTRAT_LT:
273  case INETSTRAT_LE:
274  if (gk_ip_minbits(key) < ip_bits(query))
275  PG_RETURN_BOOL(true);
276  if (gk_ip_minbits(key) > ip_bits(query))
277  PG_RETURN_BOOL(false);
278  break;
279 
280  case INETSTRAT_EQ:
281  if (gk_ip_minbits(key) != ip_bits(query))
282  PG_RETURN_BOOL(false);
283  break;
284 
285  case INETSTRAT_GE:
286  case INETSTRAT_GT:
287  if (gk_ip_minbits(key) > ip_bits(query))
288  PG_RETURN_BOOL(true);
289  if (gk_ip_minbits(key) < ip_bits(query))
290  PG_RETURN_BOOL(false);
291  break;
292 
293  case INETSTRAT_NE:
294  if (gk_ip_minbits(key) != ip_bits(query))
295  PG_RETURN_BOOL(true);
296  break;
297  }
298 
299  /*
300  * Check 5: whole address
301  *
302  * Netmask bit counts are the same, so check all the address bits.
303  */
304  order = bitncmp(gk_ip_addr(key), ip_addr(query), gk_ip_maxbits(key));
305 
306  switch (strategy)
307  {
308  case INETSTRAT_LT:
309  PG_RETURN_BOOL(order < 0);
310 
311  case INETSTRAT_LE:
312  PG_RETURN_BOOL(order <= 0);
313 
314  case INETSTRAT_EQ:
315  PG_RETURN_BOOL(order == 0);
316 
317  case INETSTRAT_GE:
318  PG_RETURN_BOOL(order >= 0);
319 
320  case INETSTRAT_GT:
321  PG_RETURN_BOOL(order > 0);
322 
323  case INETSTRAT_NE:
324  PG_RETURN_BOOL(order != 0);
325  }
326 
327  elog(ERROR, "unknown strategy for inet GiST");
328  PG_RETURN_BOOL(false); /* keep compiler quiet */
329 }
#define Min(x, y)
Definition: c.h:1004
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:170
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1569
#define INETSTRAT_NE
Definition: network_gist.c:61
#define INETSTRAT_SUPEQ
Definition: network_gist.c:69
#define INETSTRAT_LT
Definition: network_gist.c:62
#define INETSTRAT_SUBEQ
Definition: network_gist.c:67
#define INETSTRAT_SUP
Definition: network_gist.c:68
#define INETSTRAT_GT
Definition: network_gist.c:64
#define INETSTRAT_EQ
Definition: network_gist.c:60
#define INETSTRAT_SUB
Definition: network_gist.c:66
#define INETSTRAT_GE
Definition: network_gist.c:65
#define INETSTRAT_OVERLAPS
Definition: network_gist.c:59
#define INETSTRAT_LE
Definition: network_gist.c:63
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_INET_PP(n)
Definition: inet.h:134

References Assert, bitncmp(), DatumGetInetKeyP, elog, ERROR, GIST_LEAF, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_maxbits, gk_ip_minbits, INETSTRAT_EQ, INETSTRAT_GE, INETSTRAT_GT, INETSTRAT_LE, INETSTRAT_LT, INETSTRAT_NE, INETSTRAT_OVERLAPS, INETSTRAT_SUB, INETSTRAT_SUBEQ, INETSTRAT_SUP, INETSTRAT_SUPEQ, ip_addr, ip_bits, ip_family, GISTENTRY::key, sort-test::key, Min, PG_GETARG_INET_PP, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

◆ inet_gist_fetch()

Datum inet_gist_fetch ( PG_FUNCTION_ARGS  )

Definition at line 590 of file network_gist.c.

591 {
592  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
593  GistInetKey *key = DatumGetInetKeyP(entry->key);
594  GISTENTRY *retval;
595  inet *dst;
596 
597  dst = (inet *) palloc0(sizeof(inet));
598 
599  ip_family(dst) = gk_ip_family(key);
600  ip_bits(dst) = gk_ip_minbits(key);
601  memcpy(ip_addr(dst), gk_ip_addr(key), ip_addrsize(dst));
602  SET_INET_VARSIZE(dst);
603 
604  retval = palloc(sizeof(GISTENTRY));
605  gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page,
606  entry->offset, false);
607 
608  PG_RETURN_POINTER(retval);
609 }
static Datum InetPGetDatum(const inet *X)
Definition: inet.h:129
#define SET_INET_VARSIZE(dst)
Definition: inet.h:86
#define ip_addrsize(inetptr)
Definition: inet.h:80

References DatumGetInetKeyP, gistentryinit, gk_ip_addr, gk_ip_family, gk_ip_minbits, InetPGetDatum(), ip_addr, ip_addrsize, ip_bits, ip_family, GISTENTRY::key, sort-test::key, GISTENTRY::offset, GISTENTRY::page, palloc(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, GISTENTRY::rel, and SET_INET_VARSIZE.

◆ inet_gist_penalty()

Datum inet_gist_penalty ( PG_FUNCTION_ARGS  )

Definition at line 620 of file network_gist.c.

621 {
622  GISTENTRY *origent = (GISTENTRY *) PG_GETARG_POINTER(0);
623  GISTENTRY *newent = (GISTENTRY *) PG_GETARG_POINTER(1);
624  float *penalty = (float *) PG_GETARG_POINTER(2);
625  GistInetKey *orig = DatumGetInetKeyP(origent->key),
626  *new = DatumGetInetKeyP(newent->key);
627  int commonbits;
628 
629  if (gk_ip_family(orig) == gk_ip_family(new))
630  {
631  if (gk_ip_minbits(orig) <= gk_ip_minbits(new))
632  {
633  commonbits = bitncommon(gk_ip_addr(orig), gk_ip_addr(new),
634  Min(gk_ip_commonbits(orig),
635  gk_ip_commonbits(new)));
636  if (commonbits > 0)
637  *penalty = 1.0f / commonbits;
638  else
639  *penalty = 2;
640  }
641  else
642  *penalty = 3;
643  }
644  else
645  *penalty = 4;
646 
647  PG_RETURN_POINTER(penalty);
648 }

References bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, GISTENTRY::key, Min, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ inet_gist_picksplit()

Datum inet_gist_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 663 of file network_gist.c.

664 {
666  GIST_SPLITVEC *splitvec = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
667  GISTENTRY *ent = entryvec->vector;
668  int minfamily,
669  maxfamily,
670  minbits,
671  commonbits;
672  unsigned char *addr;
673  GistInetKey *tmp,
674  *left_union,
675  *right_union;
676  int maxoff,
677  nbytes;
678  OffsetNumber i,
679  *left,
680  *right;
681 
682  maxoff = entryvec->n - 1;
683  nbytes = (maxoff + 1) * sizeof(OffsetNumber);
684 
685  left = (OffsetNumber *) palloc(nbytes);
686  right = (OffsetNumber *) palloc(nbytes);
687 
688  splitvec->spl_left = left;
689  splitvec->spl_right = right;
690 
691  splitvec->spl_nleft = 0;
692  splitvec->spl_nright = 0;
693 
694  /* Determine parameters of the union of all the inputs. */
696  &minfamily, &maxfamily,
697  &minbits, &commonbits);
698 
699  if (minfamily != maxfamily)
700  {
701  /* Multiple families, so split by family. */
702  for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
703  {
704  /*
705  * If there's more than 2 families, all but maxfamily go into the
706  * left union. This could only happen if the inputs include some
707  * IPv4, some IPv6, and some already-multiple-family unions.
708  */
709  tmp = DatumGetInetKeyP(ent[i].key);
710  if (gk_ip_family(tmp) != maxfamily)
711  left[splitvec->spl_nleft++] = i;
712  else
713  right[splitvec->spl_nright++] = i;
714  }
715  }
716  else
717  {
718  /*
719  * Split on the next bit after the common bits. If that yields a
720  * trivial split, try the next bit position to the right. Repeat till
721  * success; or if we run out of bits, do an arbitrary 50-50 split.
722  */
723  int maxbits = ip_family_maxbits(minfamily);
724 
725  while (commonbits < maxbits)
726  {
727  /* Split using the commonbits'th bit position. */
728  int bitbyte = commonbits / 8;
729  int bitmask = 0x80 >> (commonbits % 8);
730 
731  splitvec->spl_nleft = splitvec->spl_nright = 0;
732 
733  for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
734  {
735  tmp = DatumGetInetKeyP(ent[i].key);
736  addr = gk_ip_addr(tmp);
737  if ((addr[bitbyte] & bitmask) == 0)
738  left[splitvec->spl_nleft++] = i;
739  else
740  right[splitvec->spl_nright++] = i;
741  }
742 
743  if (splitvec->spl_nleft > 0 && splitvec->spl_nright > 0)
744  break; /* success */
745  commonbits++;
746  }
747 
748  if (commonbits >= maxbits)
749  {
750  /* Failed ... do a 50-50 split. */
751  splitvec->spl_nleft = splitvec->spl_nright = 0;
752 
753  for (i = FirstOffsetNumber; i <= maxoff / 2; i = OffsetNumberNext(i))
754  {
755  left[splitvec->spl_nleft++] = i;
756  }
757  for (; i <= maxoff; i = OffsetNumberNext(i))
758  {
759  right[splitvec->spl_nright++] = i;
760  }
761  }
762  }
763 
764  /*
765  * Compute the union value for each side from scratch. In most cases we
766  * could approximate the union values with what we already know, but this
767  * ensures that each side has minbits and commonbits set as high as
768  * possible.
769  */
770  calc_inet_union_params_indexed(ent, left, splitvec->spl_nleft,
771  &minfamily, &maxfamily,
772  &minbits, &commonbits);
773  if (minfamily != maxfamily)
774  minfamily = 0;
775  tmp = DatumGetInetKeyP(ent[left[0]].key);
776  addr = gk_ip_addr(tmp);
777  left_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
778  splitvec->spl_ldatum = PointerGetDatum(left_union);
779 
780  calc_inet_union_params_indexed(ent, right, splitvec->spl_nright,
781  &minfamily, &maxfamily,
782  &minbits, &commonbits);
783  if (minfamily != maxfamily)
784  minfamily = 0;
785  tmp = DatumGetInetKeyP(ent[right[0]].key);
786  addr = gk_ip_addr(tmp);
787  right_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
788  splitvec->spl_rdatum = PointerGetDatum(right_union);
789 
790  PG_RETURN_POINTER(splitvec);
791 }
static void calc_inet_union_params(GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
Definition: network_gist.c:345
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)
Definition: network_gist.c:407
#define ip_family_maxbits(fam)
Definition: network_gist.c:100
static GistInetKey * build_inet_union_key(int family, int minbits, int commonbits, unsigned char *addr)
Definition: network_gist.c:472
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
int spl_nleft
Definition: gist.h:143
OffsetNumber * spl_right
Definition: gist.h:147
Datum spl_ldatum
Definition: gist.h:144
Datum spl_rdatum
Definition: gist.h:149
int spl_nright
Definition: gist.h:148
OffsetNumber * spl_left
Definition: gist.h:142
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:236
int32 n
Definition: gist.h:235

References build_inet_union_key(), calc_inet_union_params(), calc_inet_union_params_indexed(), DatumGetInetKeyP, FirstOffsetNumber, gk_ip_addr, gk_ip_family, i, ip_family_maxbits, sort-test::key, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and GistEntryVector::vector.

◆ inet_gist_same()

Datum inet_gist_same ( PG_FUNCTION_ARGS  )

Definition at line 797 of file network_gist.c.

798 {
801  bool *result = (bool *) PG_GETARG_POINTER(2);
802 
803  *result = (gk_ip_family(left) == gk_ip_family(right) &&
804  gk_ip_minbits(left) == gk_ip_minbits(right) &&
805  gk_ip_commonbits(left) == gk_ip_commonbits(right) &&
806  memcmp(gk_ip_addr(left), gk_ip_addr(right),
807  gk_ip_addrsize(left)) == 0);
808 
809  PG_RETURN_POINTER(result);
810 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268

References DatumGetInetKeyP, gk_ip_addr, gk_ip_addrsize, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, PG_GETARG_DATUM, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ inet_gist_union()

Datum inet_gist_union ( PG_FUNCTION_ARGS  )

Definition at line 505 of file network_gist.c.

506 {
508  GISTENTRY *ent = entryvec->vector;
509  int minfamily,
510  maxfamily,
511  minbits,
512  commonbits;
513  unsigned char *addr;
514  GistInetKey *tmp,
515  *result;
516 
517  /* Determine parameters of the union. */
518  calc_inet_union_params(ent, 0, entryvec->n - 1,
519  &minfamily, &maxfamily,
520  &minbits, &commonbits);
521 
522  /* If more than one family, emit family number zero. */
523  if (minfamily != maxfamily)
524  minfamily = 0;
525 
526  /* Initialize address using the first key. */
527  tmp = DatumGetInetKeyP(ent[0].key);
528  addr = gk_ip_addr(tmp);
529 
530  /* Construct the union value. */
531  result = build_inet_union_key(minfamily, minbits, commonbits, addr);
532 
533  PG_RETURN_POINTER(result);
534 }

References build_inet_union_key(), calc_inet_union_params(), DatumGetInetKeyP, gk_ip_addr, sort-test::key, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_POINTER, and GistEntryVector::vector.