Line data Source code
1 : /*
2 : * contrib/btree_gist/btree_bit.c
3 : */
4 : #include "postgres.h"
5 :
6 : #include "btree_gist.h"
7 : #include "btree_utils_var.h"
8 : #include "utils/builtins.h"
9 : #include "utils/bytea.h"
10 : #include "utils/varbit.h"
11 :
12 :
13 : /*
14 : ** Bit ops
15 : */
16 6 : PG_FUNCTION_INFO_V1(gbt_bit_compress);
17 6 : PG_FUNCTION_INFO_V1(gbt_bit_union);
18 6 : PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
19 6 : PG_FUNCTION_INFO_V1(gbt_bit_consistent);
20 6 : PG_FUNCTION_INFO_V1(gbt_bit_penalty);
21 6 : PG_FUNCTION_INFO_V1(gbt_bit_same);
22 :
23 :
24 : /* define for comparison */
25 :
26 : static bool
27 1760 : gbt_bitgt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
28 : {
29 1760 : return DatumGetBool(DirectFunctionCall2(bitgt,
30 : PointerGetDatum(a),
31 : PointerGetDatum(b)));
32 : }
33 :
34 : static bool
35 1760 : gbt_bitge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
36 : {
37 1760 : return DatumGetBool(DirectFunctionCall2(bitge,
38 : PointerGetDatum(a),
39 : PointerGetDatum(b)));
40 : }
41 :
42 : static bool
43 596 : gbt_biteq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
44 : {
45 596 : return DatumGetBool(DirectFunctionCall2(biteq,
46 : PointerGetDatum(a),
47 : PointerGetDatum(b)));
48 : }
49 :
50 : static bool
51 1236 : gbt_bitle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
52 : {
53 1236 : return DatumGetBool(DirectFunctionCall2(bitle,
54 : PointerGetDatum(a),
55 : PointerGetDatum(b)));
56 : }
57 :
58 : static bool
59 1236 : gbt_bitlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
60 : {
61 1236 : return DatumGetBool(DirectFunctionCall2(bitlt,
62 : PointerGetDatum(a),
63 : PointerGetDatum(b)));
64 : }
65 :
66 : static int32
67 48140 : gbt_bitcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
68 : {
69 48140 : return DatumGetInt32(DirectFunctionCall2(byteacmp,
70 : PointerGetDatum(a),
71 : PointerGetDatum(b)));
72 : }
73 :
74 :
75 : static bytea *
76 10272 : gbt_bit_xfrm(bytea *leaf)
77 : {
78 10272 : bytea *out = leaf;
79 10272 : int sz = VARBITBYTES(leaf) + VARHDRSZ;
80 10272 : int padded_sz = INTALIGN(sz);
81 :
82 10272 : out = (bytea *) palloc(padded_sz);
83 : /* initialize the padding bytes to zero */
84 33004 : while (sz < padded_sz)
85 22732 : ((char *) out)[sz++] = 0;
86 10272 : SET_VARSIZE(out, padded_sz);
87 10272 : memcpy(VARDATA(out), VARBITS(leaf), VARBITBYTES(leaf));
88 10272 : return out;
89 : }
90 :
91 :
92 :
93 :
94 : static GBT_VARKEY *
95 10192 : gbt_bit_l2n(GBT_VARKEY *leaf, FmgrInfo *flinfo)
96 : {
97 10192 : GBT_VARKEY *out = leaf;
98 10192 : GBT_VARKEY_R r = gbt_var_key_readable(leaf);
99 : bytea *o;
100 :
101 10192 : o = gbt_bit_xfrm(r.lower);
102 10192 : r.upper = r.lower = o;
103 10192 : out = gbt_var_key_copy(&r);
104 10192 : pfree(o);
105 :
106 10192 : return out;
107 : }
108 :
109 : static const gbtree_vinfo tinfo =
110 : {
111 : gbt_t_bit,
112 : 0,
113 : true,
114 : gbt_bitgt,
115 : gbt_bitge,
116 : gbt_biteq,
117 : gbt_bitle,
118 : gbt_bitlt,
119 : gbt_bitcmp,
120 : gbt_bit_l2n
121 : };
122 :
123 :
124 : /**************************************************
125 : * Bit ops
126 : **************************************************/
127 :
128 : Datum
129 2440 : gbt_bit_compress(PG_FUNCTION_ARGS)
130 : {
131 2440 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
132 :
133 2440 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
134 : }
135 :
136 : Datum
137 6668 : gbt_bit_consistent(PG_FUNCTION_ARGS)
138 : {
139 6668 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
140 6668 : void *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
141 6668 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
142 :
143 : /* Oid subtype = PG_GETARG_OID(3); */
144 6668 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
145 : bool retval;
146 6668 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
147 6668 : GBT_VARKEY_R r = gbt_var_key_readable(key);
148 :
149 : /* All cases served by this function are exact */
150 6668 : *recheck = false;
151 :
152 6668 : if (GIST_LEAF(entry))
153 6588 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
154 : true, &tinfo, fcinfo->flinfo);
155 : else
156 : {
157 80 : bytea *q = gbt_bit_xfrm((bytea *) query);
158 :
159 80 : retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
160 : false, &tinfo, fcinfo->flinfo);
161 : }
162 6668 : PG_RETURN_BOOL(retval);
163 : }
164 :
165 :
166 :
167 : Datum
168 1434 : gbt_bit_union(PG_FUNCTION_ARGS)
169 : {
170 1434 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
171 1434 : int32 *size = (int *) PG_GETARG_POINTER(1);
172 :
173 1434 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
174 : &tinfo, fcinfo->flinfo));
175 : }
176 :
177 :
178 : Datum
179 12 : gbt_bit_picksplit(PG_FUNCTION_ARGS)
180 : {
181 12 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
182 12 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
183 :
184 12 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
185 : &tinfo, fcinfo->flinfo);
186 12 : PG_RETURN_POINTER(v);
187 : }
188 :
189 : Datum
190 1430 : gbt_bit_same(PG_FUNCTION_ARGS)
191 : {
192 1430 : Datum d1 = PG_GETARG_DATUM(0);
193 1430 : Datum d2 = PG_GETARG_DATUM(1);
194 1430 : bool *result = (bool *) PG_GETARG_POINTER(2);
195 :
196 1430 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
197 1430 : PG_RETURN_POINTER(result);
198 : }
199 :
200 :
201 : Datum
202 3120 : gbt_bit_penalty(PG_FUNCTION_ARGS)
203 : {
204 3120 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
205 3120 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
206 3120 : float *result = (float *) PG_GETARG_POINTER(2);
207 :
208 3120 : PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
209 : &tinfo, fcinfo->flinfo));
210 : }
|