Age Owner TLA 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 : */
6890 teodor 16 CBC 3 : PG_FUNCTION_INFO_V1(gbt_bit_compress);
17 3 : PG_FUNCTION_INFO_V1(gbt_bit_union);
18 3 : PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
19 3 : PG_FUNCTION_INFO_V1(gbt_bit_consistent);
20 3 : PG_FUNCTION_INFO_V1(gbt_bit_penalty);
21 3 : PG_FUNCTION_INFO_V1(gbt_bit_same);
22 :
23 :
24 : /* define for comparison */
25 :
26 : static bool
2210 andrew 27 880 : gbt_bitgt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
28 : {
4370 tgl 29 880 : return DatumGetBool(DirectFunctionCall2(bitgt,
30 : PointerGetDatum(a),
31 : PointerGetDatum(b)));
32 : }
33 :
34 : static bool
2210 andrew 35 880 : gbt_bitge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
36 : {
4370 tgl 37 880 : return DatumGetBool(DirectFunctionCall2(bitge,
38 : PointerGetDatum(a),
39 : PointerGetDatum(b)));
40 : }
41 :
42 : static bool
2210 andrew 43 298 : gbt_biteq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
44 : {
4370 tgl 45 298 : return DatumGetBool(DirectFunctionCall2(biteq,
46 : PointerGetDatum(a),
47 : PointerGetDatum(b)));
48 : }
49 :
50 : static bool
2210 andrew 51 618 : gbt_bitle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
52 : {
4370 tgl 53 618 : return DatumGetBool(DirectFunctionCall2(bitle,
54 : PointerGetDatum(a),
55 : PointerGetDatum(b)));
56 : }
57 :
58 : static bool
2210 andrew 59 618 : gbt_bitlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
60 : {
4370 tgl 61 618 : return DatumGetBool(DirectFunctionCall2(bitlt,
62 : PointerGetDatum(a),
63 : PointerGetDatum(b)));
64 : }
65 :
66 : static int32
2210 andrew 67 24055 : gbt_bitcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
68 : {
4370 tgl 69 24055 : return DatumGetInt32(DirectFunctionCall2(byteacmp,
70 : PointerGetDatum(a),
71 : PointerGetDatum(b)));
72 : }
73 :
74 :
75 : static bytea *
6797 bruce 76 5130 : gbt_bit_xfrm(bytea *leaf)
77 : {
78 5130 : bytea *out = leaf;
3253 heikki.linnakangas 79 5130 : int sz = VARBITBYTES(leaf) + VARHDRSZ;
80 5130 : int padded_sz = INTALIGN(sz);
81 :
82 5130 : out = (bytea *) palloc(padded_sz);
83 : /* initialize the padding bytes to zero */
84 16512 : while (sz < padded_sz)
85 11382 : ((char *) out)[sz++] = 0;
86 5130 : SET_VARSIZE(out, padded_sz);
61 peter 87 GNC 5130 : memcpy(VARDATA(out), VARBITS(leaf), VARBITBYTES(leaf));
6797 bruce 88 CBC 5130 : return out;
89 : }
90 :
91 :
92 :
93 :
94 : static GBT_VARKEY *
2210 andrew 95 5090 : gbt_bit_l2n(GBT_VARKEY *leaf, FmgrInfo *flinfo)
96 : {
6797 bruce 97 5090 : GBT_VARKEY *out = leaf;
98 5090 : GBT_VARKEY_R r = gbt_var_key_readable(leaf);
99 : bytea *o;
100 :
101 5090 : o = gbt_bit_xfrm(r.lower);
102 5090 : r.upper = r.lower = o;
2936 heikki.linnakangas 103 5090 : out = gbt_var_key_copy(&r);
6797 bruce 104 5090 : pfree(o);
105 :
106 5090 : 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 1220 : gbt_bit_compress(PG_FUNCTION_ARGS)
130 : {
131 1220 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
132 :
133 1220 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
134 : }
135 :
136 : Datum
6890 teodor 137 3334 : gbt_bit_consistent(PG_FUNCTION_ARGS)
138 : {
6797 bruce 139 3334 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
140 3334 : void *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
141 3334 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
142 :
143 : /* Oid subtype = PG_GETARG_OID(3); */
5473 tgl 144 3334 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
145 : bool retval;
146 3334 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
6797 bruce 147 3334 : GBT_VARKEY_R r = gbt_var_key_readable(key);
148 :
149 : /* All cases served by this function are exact */
5473 tgl 150 3334 : *recheck = false;
151 :
6797 bruce 152 3334 : if (GIST_LEAF(entry))
4370 tgl 153 3294 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
154 : true, &tinfo, fcinfo->flinfo);
155 : else
156 : {
6797 bruce 157 40 : bytea *q = gbt_bit_xfrm((bytea *) query);
158 :
4370 tgl 159 40 : retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
160 : false, &tinfo, fcinfo->flinfo);
161 : }
6797 bruce 162 3334 : PG_RETURN_BOOL(retval);
163 : }
164 :
165 :
166 :
167 : Datum
6890 teodor 168 717 : gbt_bit_union(PG_FUNCTION_ARGS)
169 : {
6797 bruce 170 717 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
171 717 : int32 *size = (int *) PG_GETARG_POINTER(1);
172 :
4370 tgl 173 717 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
174 : &tinfo, fcinfo->flinfo));
175 : }
176 :
177 :
178 : Datum
6890 teodor 179 6 : gbt_bit_picksplit(PG_FUNCTION_ARGS)
180 : {
6797 bruce 181 6 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
182 6 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
183 :
4370 tgl 184 6 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
185 : &tinfo, fcinfo->flinfo);
6797 bruce 186 6 : PG_RETURN_POINTER(v);
187 : }
188 :
189 : Datum
6890 teodor 190 715 : gbt_bit_same(PG_FUNCTION_ARGS)
191 : {
6797 bruce 192 715 : Datum d1 = PG_GETARG_DATUM(0);
193 715 : Datum d2 = PG_GETARG_DATUM(1);
194 715 : bool *result = (bool *) PG_GETARG_POINTER(2);
195 :
2210 andrew 196 715 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
4370 tgl 197 715 : PG_RETURN_POINTER(result);
198 : }
199 :
200 :
201 : Datum
6890 teodor 202 1557 : gbt_bit_penalty(PG_FUNCTION_ARGS)
203 : {
6797 bruce 204 1557 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
205 1557 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
6541 neilc 206 1557 : float *result = (float *) PG_GETARG_POINTER(2);
207 :
4370 tgl 208 1557 : PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
209 : &tinfo, fcinfo->flinfo));
210 : }
|