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 4 : PG_FUNCTION_INFO_V1(gbt_bytea_compress);
13 4 : PG_FUNCTION_INFO_V1(gbt_bytea_union);
14 4 : PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
15 4 : PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
16 4 : PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
17 4 : PG_FUNCTION_INFO_V1(gbt_bytea_same);
18 4 : 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 :
105 : /* Oid subtype = PG_GETARG_OID(3); */
106 10212 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
107 : bool retval;
108 10212 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
109 10212 : GBT_VARKEY_R r = gbt_var_key_readable(key);
110 :
111 : /* All cases served by this function are exact */
112 10212 : *recheck = false;
113 :
114 20424 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
115 10212 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
116 10212 : PG_RETURN_BOOL(retval);
117 : }
118 :
119 : Datum
120 2 : gbt_bytea_union(PG_FUNCTION_ARGS)
121 : {
122 2 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
123 2 : int32 *size = (int *) PG_GETARG_POINTER(1);
124 :
125 2 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
126 : &tinfo, fcinfo->flinfo));
127 : }
128 :
129 : Datum
130 10 : gbt_bytea_picksplit(PG_FUNCTION_ARGS)
131 : {
132 10 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
133 10 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
134 :
135 10 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
136 : &tinfo, fcinfo->flinfo);
137 10 : PG_RETURN_POINTER(v);
138 : }
139 :
140 : Datum
141 0 : gbt_bytea_same(PG_FUNCTION_ARGS)
142 : {
143 0 : Datum d1 = PG_GETARG_DATUM(0);
144 0 : Datum d2 = PG_GETARG_DATUM(1);
145 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
146 :
147 0 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
148 0 : PG_RETURN_POINTER(result);
149 : }
150 :
151 : Datum
152 0 : gbt_bytea_penalty(PG_FUNCTION_ARGS)
153 : {
154 0 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
155 0 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
156 0 : float *result = (float *) PG_GETARG_POINTER(2);
157 :
158 0 : PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
159 : &tinfo, fcinfo->flinfo));
160 : }
161 :
162 : static int
163 21546 : gbt_bytea_ssup_cmp(Datum x, Datum y, SortSupport ssup)
164 : {
165 21546 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
166 21546 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
167 :
168 21546 : GBT_VARKEY_R xkey = gbt_var_key_readable(key1);
169 21546 : GBT_VARKEY_R ykey = gbt_var_key_readable(key2);
170 : Datum result;
171 :
172 : /* for leaf items we expect lower == upper, so only compare lower */
173 21546 : result = DirectFunctionCall2(byteacmp,
174 : PointerGetDatum(xkey.lower),
175 : PointerGetDatum(ykey.lower));
176 :
177 21546 : GBT_FREE_IF_COPY(key1, x);
178 21546 : GBT_FREE_IF_COPY(key2, y);
179 :
180 21546 : return DatumGetInt32(result);
181 : }
182 :
183 : Datum
184 2 : gbt_bytea_sortsupport(PG_FUNCTION_ARGS)
185 : {
186 2 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
187 :
188 2 : ssup->comparator = gbt_bytea_ssup_cmp;
189 2 : ssup->ssup_extra = NULL;
190 :
191 2 : PG_RETURN_VOID();
192 : }
|