Line data Source code
1 : /*
2 : * contrib/btree_gist/btree_inet.c
3 : */
4 : #include "postgres.h"
5 :
6 : #include "btree_gist.h"
7 : #include "btree_utils_num.h"
8 : #include "catalog/pg_type.h"
9 : #include "utils/builtins.h"
10 :
11 : typedef struct inetkey
12 : {
13 : double lower;
14 : double upper;
15 : } inetKEY;
16 :
17 : /*
18 : ** inet ops
19 : */
20 6 : PG_FUNCTION_INFO_V1(gbt_inet_compress);
21 6 : PG_FUNCTION_INFO_V1(gbt_inet_union);
22 6 : PG_FUNCTION_INFO_V1(gbt_inet_picksplit);
23 6 : PG_FUNCTION_INFO_V1(gbt_inet_consistent);
24 6 : PG_FUNCTION_INFO_V1(gbt_inet_penalty);
25 6 : PG_FUNCTION_INFO_V1(gbt_inet_same);
26 :
27 :
28 : static bool
29 10390 : gbt_inetgt(const void *a, const void *b, FmgrInfo *flinfo)
30 : {
31 10390 : return (*((const double *) a) > *((const double *) b));
32 : }
33 : static bool
34 1284 : gbt_inetge(const void *a, const void *b, FmgrInfo *flinfo)
35 : {
36 1284 : return (*((const double *) a) >= *((const double *) b));
37 : }
38 : static bool
39 5672 : gbt_ineteq(const void *a, const void *b, FmgrInfo *flinfo)
40 : {
41 5672 : return (*((const double *) a) == *((const double *) b));
42 : }
43 : static bool
44 1820 : gbt_inetle(const void *a, const void *b, FmgrInfo *flinfo)
45 : {
46 1820 : return (*((const double *) a) <= *((const double *) b));
47 : }
48 : static bool
49 10878 : gbt_inetlt(const void *a, const void *b, FmgrInfo *flinfo)
50 : {
51 10878 : return (*((const double *) a) < *((const double *) b));
52 : }
53 :
54 : static int
55 37916 : gbt_inetkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
56 : {
57 37916 : inetKEY *ia = (inetKEY *) (((const Nsrt *) a)->t);
58 37916 : inetKEY *ib = (inetKEY *) (((const Nsrt *) b)->t);
59 :
60 37916 : if (ia->lower == ib->lower)
61 : {
62 0 : if (ia->upper == ib->upper)
63 0 : return 0;
64 :
65 0 : return (ia->upper > ib->upper) ? 1 : -1;
66 : }
67 :
68 37916 : return (ia->lower > ib->lower) ? 1 : -1;
69 : }
70 :
71 :
72 : static const gbtree_ninfo tinfo =
73 : {
74 : gbt_t_inet,
75 : sizeof(double),
76 : 16, /* sizeof(gbtreekey16) */
77 : gbt_inetgt,
78 : gbt_inetge,
79 : gbt_ineteq,
80 : gbt_inetle,
81 : gbt_inetlt,
82 : gbt_inetkey_cmp,
83 : NULL
84 : };
85 :
86 :
87 : /**************************************************
88 : * inet ops
89 : **************************************************/
90 :
91 :
92 : Datum
93 3666 : gbt_inet_compress(PG_FUNCTION_ARGS)
94 : {
95 3666 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
96 : GISTENTRY *retval;
97 :
98 3666 : if (entry->leafkey)
99 : {
100 3600 : inetKEY *r = (inetKEY *) palloc(sizeof(inetKEY));
101 3600 : bool failure = false;
102 :
103 3600 : retval = palloc(sizeof(GISTENTRY));
104 3600 : r->lower = convert_network_to_scalar(entry->key, INETOID, &failure);
105 : Assert(!failure);
106 3600 : r->upper = r->lower;
107 3600 : gistentryinit(*retval, PointerGetDatum(r),
108 : entry->rel, entry->page,
109 : entry->offset, false);
110 : }
111 : else
112 66 : retval = entry;
113 :
114 3666 : PG_RETURN_POINTER(retval);
115 : }
116 :
117 :
118 : Datum
119 7280 : gbt_inet_consistent(PG_FUNCTION_ARGS)
120 : {
121 7280 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
122 7280 : Datum dquery = PG_GETARG_DATUM(1);
123 7280 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
124 :
125 : /* Oid subtype = PG_GETARG_OID(3); */
126 7280 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
127 7280 : inetKEY *kkk = (inetKEY *) DatumGetPointer(entry->key);
128 : GBT_NUMKEY_R key;
129 : double query;
130 7280 : bool failure = false;
131 :
132 7280 : query = convert_network_to_scalar(dquery, INETOID, &failure);
133 : Assert(!failure);
134 :
135 : /* All cases served by this function are inexact */
136 7280 : *recheck = true;
137 :
138 7280 : key.lower = (GBT_NUMKEY *) &kkk->lower;
139 7280 : key.upper = (GBT_NUMKEY *) &kkk->upper;
140 :
141 7280 : PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query,
142 : &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
143 : }
144 :
145 :
146 : Datum
147 2258 : gbt_inet_union(PG_FUNCTION_ARGS)
148 : {
149 2258 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
150 2258 : void *out = palloc(sizeof(inetKEY));
151 :
152 2258 : *(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
153 2258 : PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
154 : }
155 :
156 :
157 : Datum
158 6396 : gbt_inet_penalty(PG_FUNCTION_ARGS)
159 : {
160 6396 : inetKEY *origentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
161 6396 : inetKEY *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
162 6396 : float *result = (float *) PG_GETARG_POINTER(2);
163 :
164 6396 : penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
165 :
166 6396 : PG_RETURN_POINTER(result);
167 : }
168 :
169 : Datum
170 18 : gbt_inet_picksplit(PG_FUNCTION_ARGS)
171 : {
172 18 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
173 : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
174 : &tinfo, fcinfo->flinfo));
175 : }
176 :
177 : Datum
178 2246 : gbt_inet_same(PG_FUNCTION_ARGS)
179 : {
180 2246 : inetKEY *b1 = (inetKEY *) PG_GETARG_POINTER(0);
181 2246 : inetKEY *b2 = (inetKEY *) PG_GETARG_POINTER(1);
182 2246 : bool *result = (bool *) PG_GETARG_POINTER(2);
183 :
184 2246 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
185 2246 : PG_RETURN_POINTER(result);
186 : }
|