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 0 : PG_FUNCTION_INFO_V1(gbt_bytea_compress);
13 0 : PG_FUNCTION_INFO_V1(gbt_bytea_union);
14 0 : PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
15 0 : PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
16 0 : PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
17 0 : PG_FUNCTION_INFO_V1(gbt_bytea_same);
18 0 : PG_FUNCTION_INFO_V1(gbt_bytea_sortsupport);
19 :
20 :
21 : /* define for comparison */
22 :
23 : static bool
24 0 : gbt_byteagt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
25 : {
26 0 : return DatumGetBool(DirectFunctionCall2(byteagt,
27 : PointerGetDatum(a),
28 : PointerGetDatum(b)));
29 : }
30 :
31 : static bool
32 0 : gbt_byteage(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
33 : {
34 0 : return DatumGetBool(DirectFunctionCall2(byteage,
35 : PointerGetDatum(a),
36 : PointerGetDatum(b)));
37 : }
38 :
39 : static bool
40 0 : gbt_byteaeq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
41 : {
42 0 : return DatumGetBool(DirectFunctionCall2(byteaeq,
43 : PointerGetDatum(a),
44 : PointerGetDatum(b)));
45 : }
46 :
47 : static bool
48 0 : gbt_byteale(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
49 : {
50 0 : return DatumGetBool(DirectFunctionCall2(byteale,
51 : PointerGetDatum(a),
52 : PointerGetDatum(b)));
53 : }
54 :
55 : static bool
56 0 : gbt_bytealt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
57 : {
58 0 : return DatumGetBool(DirectFunctionCall2(bytealt,
59 : PointerGetDatum(a),
60 : PointerGetDatum(b)));
61 : }
62 :
63 : static int32
64 0 : gbt_byteacmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
65 : {
66 0 : 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 0 : gbt_bytea_compress(PG_FUNCTION_ARGS)
92 : {
93 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
94 :
95 0 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
96 0 : }
97 :
98 : Datum
99 0 : gbt_bytea_consistent(PG_FUNCTION_ARGS)
100 : {
101 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
102 0 : void *query = DatumGetByteaP(PG_GETARG_DATUM(1));
103 0 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
104 : #ifdef NOT_USED
105 : Oid subtype = PG_GETARG_OID(3);
106 : #endif
107 0 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
108 0 : bool retval;
109 0 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
110 0 : GBT_VARKEY_R r = gbt_var_key_readable(key);
111 :
112 : /* All cases served by this function are exact */
113 0 : *recheck = false;
114 :
115 0 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
116 0 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
117 0 : PG_RETURN_BOOL(retval);
118 0 : }
119 :
120 : Datum
121 0 : gbt_bytea_union(PG_FUNCTION_ARGS)
122 : {
123 0 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
124 0 : int32 *size = (int *) PG_GETARG_POINTER(1);
125 :
126 0 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
127 : &tinfo, fcinfo->flinfo));
128 0 : }
129 :
130 : Datum
131 0 : gbt_bytea_picksplit(PG_FUNCTION_ARGS)
132 : {
133 0 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
134 0 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
135 :
136 0 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
137 0 : &tinfo, fcinfo->flinfo);
138 0 : PG_RETURN_POINTER(v);
139 0 : }
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 0 : }
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 0 : }
162 :
163 : static int
164 0 : gbt_bytea_ssup_cmp(Datum x, Datum y, SortSupport ssup)
165 : {
166 0 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
167 0 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
168 :
169 0 : GBT_VARKEY_R xkey = gbt_var_key_readable(key1);
170 0 : GBT_VARKEY_R ykey = gbt_var_key_readable(key2);
171 0 : Datum result;
172 :
173 : /* for leaf items we expect lower == upper, so only compare lower */
174 0 : result = DirectFunctionCall2(byteacmp,
175 : PointerGetDatum(xkey.lower),
176 : PointerGetDatum(ykey.lower));
177 :
178 0 : GBT_FREE_IF_COPY(key1, x);
179 0 : GBT_FREE_IF_COPY(key2, y);
180 :
181 0 : return DatumGetInt32(result);
182 0 : }
183 :
184 : Datum
185 0 : gbt_bytea_sortsupport(PG_FUNCTION_ARGS)
186 : {
187 0 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
188 :
189 0 : ssup->comparator = gbt_bytea_ssup_cmp;
190 0 : ssup->ssup_extra = NULL;
191 :
192 0 : PG_RETURN_VOID();
193 0 : }
|