PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
network_gist.c File Reference
#include "postgres.h"
#include <sys/socket.h>
#include "access/gist.h"
#include "access/stratnum.h"
#include "utils/builtins.h"
#include "utils/inet.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

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

Definition at line 102 of file network_gist.c.

Referenced by inet_gist_compress(), and inet_gist_same().

#define gk_ip_commonbits (   gkptr)    ((gkptr)->commonbits)
#define gk_ip_maxbits (   gkptr)    ip_family_maxbits(gk_ip_family(gkptr))

Definition at line 104 of file network_gist.c.

Referenced by inet_gist_compress(), and inet_gist_consistent().

#define InetKeyPGetDatum (   X)    PointerGetDatum(X)

Definition at line 88 of file network_gist.c.

#define INETSTRAT_EQ   RTEqualStrategyNumber

Definition at line 59 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_GE   RTGreaterEqualStrategyNumber

Definition at line 64 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_GT   RTGreaterStrategyNumber

Definition at line 63 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_LE   RTLessEqualStrategyNumber

Definition at line 62 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_LT   RTLessStrategyNumber

Definition at line 61 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_NE   RTNotEqualStrategyNumber

Definition at line 60 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_OVERLAPS   RTOverlapStrategyNumber

Definition at line 58 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_SUB   RTSubStrategyNumber

Definition at line 65 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_SUBEQ   RTSubEqualStrategyNumber

Definition at line 66 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_SUP   RTSuperStrategyNumber

Definition at line 67 of file network_gist.c.

Referenced by inet_gist_consistent().

#define INETSTRAT_SUPEQ   RTSuperEqualStrategyNumber

Definition at line 68 of file network_gist.c.

Referenced by inet_gist_consistent().

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

Definition at line 99 of file network_gist.c.

Referenced by inet_gist_picksplit().

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

Definition at line 106 of file network_gist.c.

Referenced by build_inet_union_key(), and inet_gist_compress().

Typedef Documentation

Function Documentation

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

Definition at line 471 of file network_gist.c.

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().

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

References Assert, bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, and i.

Referenced by inet_gist_picksplit(), and inet_gist_union().

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

References Assert, bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, and i.

Referenced by inet_gist_picksplit().

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

Definition at line 541 of file network_gist.c.

References DatumGetInetPP, DatumGetPointer, FALSE, 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.

542 {
543  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
544  GISTENTRY *retval;
545 
546  if (entry->leafkey)
547  {
548  retval = palloc(sizeof(GISTENTRY));
549  if (DatumGetPointer(entry->key) != NULL)
550  {
551  inet *in = DatumGetInetPP(entry->key);
552  GistInetKey *r;
553 
554  r = (GistInetKey *) palloc0(sizeof(GistInetKey));
555 
556  gk_ip_family(r) = ip_family(in);
557  gk_ip_minbits(r) = ip_bits(in);
559  memcpy(gk_ip_addr(r), ip_addr(in), gk_ip_addrsize(r));
560  SET_GK_VARSIZE(r);
561 
562  gistentryinit(*retval, PointerGetDatum(r),
563  entry->rel, entry->page,
564  entry->offset, FALSE);
565  }
566  else
567  {
568  gistentryinit(*retval, (Datum) 0,
569  entry->rel, entry->page,
570  entry->offset, FALSE);
571  }
572  }
573  else
574  retval = entry;
575  PG_RETURN_POINTER(retval);
576 }
Relation rel
Definition: gist.h:124
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define ip_bits(inetptr)
Definition: inet.h:74
#define SET_GK_VARSIZE(dst)
Definition: network_gist.c:106
#define ip_family(inetptr)
Definition: inet.h:71
#define gk_ip_maxbits(gkptr)
Definition: network_gist.c:104
#define PointerGetDatum(X)
Definition: postgres.h:562
#define DatumGetInetPP(X)
Definition: inet.h:122
#define ip_addr(inetptr)
Definition: inet.h:77
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Page page
Definition: gist.h:125
#define gk_ip_addr(gkptr)
Definition: network_gist.c:98
#define FALSE
Definition: c.h:219
Datum key
Definition: gist.h:123
Definition: inet.h:52
bool leafkey
Definition: gist.h:127
void * palloc0(Size size)
Definition: mcxt.c:877
#define gk_ip_family(gkptr)
Definition: network_gist.c:95
uintptr_t Datum
Definition: postgres.h:372
#define gk_ip_commonbits(gkptr)
Definition: network_gist.c:97
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
#define DatumGetPointer(X)
Definition: postgres.h:555
void * palloc(Size size)
Definition: mcxt.c:848
#define gk_ip_addrsize(gkptr)
Definition: network_gist.c:102
OffsetNumber offset
Definition: gist.h:126
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:96
Datum inet_gist_consistent ( PG_FUNCTION_ARGS  )

Definition at line 114 of file network_gist.c.

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, Min, PG_GETARG_INET_PP, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

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

Definition at line 589 of file network_gist.c.

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

590 {
591  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
592  GistInetKey *key = DatumGetInetKeyP(entry->key);
593  GISTENTRY *retval;
594  inet *dst;
595 
596  dst = (inet *) palloc0(sizeof(inet));
597 
598  ip_family(dst) = gk_ip_family(key);
599  ip_bits(dst) = gk_ip_minbits(key);
600  memcpy(ip_addr(dst), gk_ip_addr(key), ip_addrsize(dst));
601  SET_INET_VARSIZE(dst);
602 
603  retval = palloc(sizeof(GISTENTRY));
604  gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page,
605  entry->offset, FALSE);
606 
607  PG_RETURN_POINTER(retval);
608 }
Relation rel
Definition: gist.h:124
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define ip_bits(inetptr)
Definition: inet.h:74
#define ip_family(inetptr)
Definition: inet.h:71
#define ip_addr(inetptr)
Definition: inet.h:77
#define SET_INET_VARSIZE(dst)
Definition: inet.h:86
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define ip_addrsize(inetptr)
Definition: inet.h:80
Page page
Definition: gist.h:125
#define gk_ip_addr(gkptr)
Definition: network_gist.c:98
#define FALSE
Definition: c.h:219
Datum key
Definition: gist.h:123
Definition: inet.h:52
#define DatumGetInetKeyP(X)
Definition: network_gist.c:87
#define InetPGetDatum(X)
Definition: inet.h:123
void * palloc0(Size size)
Definition: mcxt.c:877
#define gk_ip_family(gkptr)
Definition: network_gist.c:95
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
void * palloc(Size size)
Definition: mcxt.c:848
OffsetNumber offset
Definition: gist.h:126
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:96
Datum inet_gist_penalty ( PG_FUNCTION_ARGS  )

Definition at line 619 of file network_gist.c.

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.

620 {
621  GISTENTRY *origent = (GISTENTRY *) PG_GETARG_POINTER(0);
622  GISTENTRY *newent = (GISTENTRY *) PG_GETARG_POINTER(1);
623  float *penalty = (float *) PG_GETARG_POINTER(2);
624  GistInetKey *orig = DatumGetInetKeyP(origent->key),
625  *new = DatumGetInetKeyP(newent->key);
626  int commonbits;
627 
628  if (gk_ip_family(orig) == gk_ip_family(new))
629  {
630  if (gk_ip_minbits(orig) <= gk_ip_minbits(new))
631  {
632  commonbits = bitncommon(gk_ip_addr(orig), gk_ip_addr(new),
633  Min(gk_ip_commonbits(orig),
634  gk_ip_commonbits(new)));
635  if (commonbits > 0)
636  *penalty = 1.0f / commonbits;
637  else
638  *penalty = 2;
639  }
640  else
641  *penalty = 3;
642  }
643  else
644  *penalty = 4;
645 
646  PG_RETURN_POINTER(penalty);
647 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define Min(x, y)
Definition: c.h:812
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1014
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define gk_ip_addr(gkptr)
Definition: network_gist.c:98
Datum key
Definition: gist.h:123
#define DatumGetInetKeyP(X)
Definition: network_gist.c:87
#define gk_ip_family(gkptr)
Definition: network_gist.c:95
#define gk_ip_commonbits(gkptr)
Definition: network_gist.c:97
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:96
Datum inet_gist_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 662 of file network_gist.c.

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, 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.

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

Definition at line 796 of file network_gist.c.

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.

797 {
800  bool *result = (bool *) PG_GETARG_POINTER(2);
801 
802  *result = (gk_ip_family(left) == gk_ip_family(right) &&
803  gk_ip_minbits(left) == gk_ip_minbits(right) &&
804  gk_ip_commonbits(left) == gk_ip_commonbits(right) &&
805  memcmp(gk_ip_addr(left), gk_ip_addr(right),
806  gk_ip_addrsize(left)) == 0);
807 
808  PG_RETURN_POINTER(result);
809 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define gk_ip_addr(gkptr)
Definition: network_gist.c:98
#define DatumGetInetKeyP(X)
Definition: network_gist.c:87
#define gk_ip_family(gkptr)
Definition: network_gist.c:95
#define gk_ip_commonbits(gkptr)
Definition: network_gist.c:97
#define gk_ip_addrsize(gkptr)
Definition: network_gist.c:102
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:96
Datum inet_gist_union ( PG_FUNCTION_ARGS  )

Definition at line 504 of file network_gist.c.

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

505 {
507  GISTENTRY *ent = entryvec->vector;
508  int minfamily,
509  maxfamily,
510  minbits,
511  commonbits;
512  unsigned char *addr;
513  GistInetKey *tmp,
514  *result;
515 
516  /* Determine parameters of the union. */
517  calc_inet_union_params(ent, 0, entryvec->n - 1,
518  &minfamily, &maxfamily,
519  &minbits, &commonbits);
520 
521  /* If more than one family, emit family number zero. */
522  if (minfamily != maxfamily)
523  minfamily = 0;
524 
525  /* Initialize address using the first key. */
526  tmp = DatumGetInetKeyP(ent[0].key);
527  addr = gk_ip_addr(tmp);
528 
529  /* Construct the union value. */
530  result = build_inet_union_key(minfamily, minbits, commonbits, addr);
531 
532  PG_RETURN_POINTER(result);
533 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
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:344
int32 n
Definition: gist.h:160
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:161
#define gk_ip_addr(gkptr)
Definition: network_gist.c:98
static GistInetKey * build_inet_union_key(int family, int minbits, int commonbits, unsigned char *addr)
Definition: network_gist.c:471
#define DatumGetInetKeyP(X)
Definition: network_gist.c:87