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