Line data Source code
1 : /*
2 : * contrib/btree_gist/btree_bytea.c
3 : */
4 : #include "postgres.h"
5 :
6 : #include "btree_gist.h"
7 : #include "btree_utils_var.h"
8 : #include "utils/fmgrprotos.h"
9 : #include "utils/sortsupport.h"
10 :
11 : /* GiST support functions */
12 8 : PG_FUNCTION_INFO_V1(gbt_bytea_compress);
13 8 : PG_FUNCTION_INFO_V1(gbt_bytea_union);
14 8 : PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
15 8 : PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
16 8 : PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
17 8 : PG_FUNCTION_INFO_V1(gbt_bytea_same);
18 8 : PG_FUNCTION_INFO_V1(gbt_bytea_sortsupport);
19 :
20 :
21 : /* define for comparison */
22 :
23 : static bool
24 1234 : gbt_byteagt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
25 : {
26 1234 : return DatumGetBool(DirectFunctionCall2(byteagt,
27 : PointerGetDatum(a),
28 : PointerGetDatum(b)));
29 : }
30 :
31 : static bool
32 1234 : gbt_byteage(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
33 : {
34 1234 : return DatumGetBool(DirectFunctionCall2(byteage,
35 : PointerGetDatum(a),
36 : PointerGetDatum(b)));
37 : }
38 :
39 : static bool
40 2468 : gbt_byteaeq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
41 : {
42 2468 : return DatumGetBool(DirectFunctionCall2(byteaeq,
43 : PointerGetDatum(a),
44 : PointerGetDatum(b)));
45 : }
46 :
47 : static bool
48 1978 : gbt_byteale(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
49 : {
50 1978 : return DatumGetBool(DirectFunctionCall2(byteale,
51 : PointerGetDatum(a),
52 : PointerGetDatum(b)));
53 : }
54 :
55 : static bool
56 3214 : gbt_bytealt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
57 : {
58 3214 : return DatumGetBool(DirectFunctionCall2(bytealt,
59 : PointerGetDatum(a),
60 : PointerGetDatum(b)));
61 : }
62 :
63 : static int32
64 20872 : gbt_byteacmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
65 : {
66 20872 : return DatumGetInt32(DirectFunctionCall2(byteacmp,
67 : PointerGetDatum(a),
68 : PointerGetDatum(b)));
69 : }
70 :
71 : static const gbtree_vinfo tinfo =
72 : {
73 : gbt_t_bytea,
74 : 0,
75 : true,
76 : gbt_byteagt,
77 : gbt_byteage,
78 : gbt_byteaeq,
79 : gbt_byteale,
80 : gbt_bytealt,
81 : gbt_byteacmp,
82 : NULL
83 : };
84 :
85 :
86 : /**************************************************
87 : * GiST support functions
88 : **************************************************/
89 :
90 : Datum
91 1990 : gbt_bytea_compress(PG_FUNCTION_ARGS)
92 : {
93 1990 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
94 :
95 1990 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
96 : }
97 :
98 : Datum
99 10212 : gbt_bytea_consistent(PG_FUNCTION_ARGS)
100 : {
101 10212 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
102 10212 : void *query = DatumGetByteaP(PG_GETARG_DATUM(1));
103 10212 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
104 : #ifdef NOT_USED
105 : Oid subtype = PG_GETARG_OID(3);
106 : #endif
107 10212 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
108 : bool retval;
109 10212 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
110 10212 : GBT_VARKEY_R r = gbt_var_key_readable(key);
111 :
112 : /* All cases served by this function are exact */
113 10212 : *recheck = false;
114 :
115 20424 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
116 10212 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
117 10212 : PG_RETURN_BOOL(retval);
118 : }
119 :
120 : Datum
121 2 : gbt_bytea_union(PG_FUNCTION_ARGS)
122 : {
123 2 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
124 2 : int32 *size = (int *) PG_GETARG_POINTER(1);
125 :
126 2 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
127 : &tinfo, fcinfo->flinfo));
128 : }
129 :
130 : Datum
131 10 : gbt_bytea_picksplit(PG_FUNCTION_ARGS)
132 : {
133 10 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
134 10 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
135 :
136 10 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
137 : &tinfo, fcinfo->flinfo);
138 10 : PG_RETURN_POINTER(v);
139 : }
140 :
141 : Datum
142 0 : gbt_bytea_same(PG_FUNCTION_ARGS)
143 : {
144 0 : Datum d1 = PG_GETARG_DATUM(0);
145 0 : Datum d2 = PG_GETARG_DATUM(1);
146 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
147 :
148 0 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
149 0 : PG_RETURN_POINTER(result);
150 : }
151 :
152 : Datum
153 0 : gbt_bytea_penalty(PG_FUNCTION_ARGS)
154 : {
155 0 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
156 0 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
157 0 : float *result = (float *) PG_GETARG_POINTER(2);
158 :
159 0 : PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
160 : &tinfo, fcinfo->flinfo));
161 : }
162 :
163 : static int
164 21546 : gbt_bytea_ssup_cmp(Datum x, Datum y, SortSupport ssup)
165 : {
166 21546 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
167 21546 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
168 :
169 21546 : GBT_VARKEY_R xkey = gbt_var_key_readable(key1);
170 21546 : GBT_VARKEY_R ykey = gbt_var_key_readable(key2);
171 : Datum result;
172 :
173 : /* for leaf items we expect lower == upper, so only compare lower */
174 21546 : result = DirectFunctionCall2(byteacmp,
175 : PointerGetDatum(xkey.lower),
176 : PointerGetDatum(ykey.lower));
177 :
178 21546 : GBT_FREE_IF_COPY(key1, x);
179 21546 : GBT_FREE_IF_COPY(key2, y);
180 :
181 21546 : return DatumGetInt32(result);
182 : }
183 :
184 : Datum
185 2 : gbt_bytea_sortsupport(PG_FUNCTION_ARGS)
186 : {
187 2 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
188 :
189 2 : ssup->comparator = gbt_bytea_ssup_cmp;
190 2 : ssup->ssup_extra = NULL;
191 :
192 2 : PG_RETURN_VOID();
193 : }
|