]> granicus.if.org Git - postgresql/blob - contrib/btree_gist/btree_text.c
New version. Add support for int2, int8, float4, float8, timestamp with/without time...
[postgresql] / contrib / btree_gist / btree_text.c
1 #include "btree_gist.h"
2 #include "btree_utils_var.h"
3 #include "utils/builtins.h"
4
5 /*
6 ** Text ops
7 */
8 PG_FUNCTION_INFO_V1(gbt_text_compress);
9 PG_FUNCTION_INFO_V1(gbt_bpchar_compress);
10 PG_FUNCTION_INFO_V1(gbt_text_union);
11 PG_FUNCTION_INFO_V1(gbt_text_picksplit);
12 PG_FUNCTION_INFO_V1(gbt_text_consistent);
13 PG_FUNCTION_INFO_V1(gbt_bpchar_consistent);
14 PG_FUNCTION_INFO_V1(gbt_text_penalty);
15 PG_FUNCTION_INFO_V1(gbt_text_same);
16
17 Datum    gbt_text_compress(PG_FUNCTION_ARGS);
18 Datum    gbt_bpchar_compress(PG_FUNCTION_ARGS);
19 Datum    gbt_text_union(PG_FUNCTION_ARGS);
20 Datum    gbt_text_picksplit(PG_FUNCTION_ARGS);
21 Datum    gbt_text_consistent(PG_FUNCTION_ARGS);
22 Datum    gbt_bpchar_consistent(PG_FUNCTION_ARGS);
23 Datum    gbt_text_penalty(PG_FUNCTION_ARGS);
24 Datum    gbt_text_same(PG_FUNCTION_ARGS);
25
26
27 /* define for comparison */
28
29 static bool     gbt_textgt     (const void *a, const void *b)
30 {
31   return ( DatumGetBool(DirectFunctionCall2( text_gt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
32 }
33
34 static bool     gbt_textge     (const void *a, const void *b)
35 {
36   return ( DatumGetBool(DirectFunctionCall2( text_ge ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
37 }
38
39 static bool     gbt_texteq     (const void *a, const void *b)
40 {
41   return ( DatumGetBool(DirectFunctionCall2( texteq ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
42 }
43
44 static bool     gbt_textle     (const void *a, const void *b)
45 {
46   return ( DatumGetBool(DirectFunctionCall2( text_le ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
47 }
48
49 static bool     gbt_textlt     (const void *a, const void *b)
50 {
51   return ( DatumGetBool(DirectFunctionCall2( text_lt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
52 }
53
54 static int32 gbt_textcmp ( const bytea * a , const bytea * b )
55 {
56   return strcmp( VARDATA(a), VARDATA(b) );
57 }
58   
59
60 /*
61  * Converts data of leaf using strxfrm ( locale support )
62 */
63
64 static bytea *
65 gbt_text_xfrm ( bytea * leaf )
66 {
67     bytea  * out = leaf;
68
69     int32  ilen = VARSIZE (leaf) - VARHDRSZ;
70     int32  olen ;
71     char   sin[ilen+1]; 
72     char   * sou = NULL;
73     memcpy ( (void*)&sin[0], (void*) VARDATA(leaf) ,ilen );
74     sin[ilen]   = '\0';
75     olen        = strxfrm ( NULL, &sin[0], 0 ) + 1;
76     sou         = palloc ( olen );
77     olen        = strxfrm ( sou , &sin[0] , olen );
78     olen       += VARHDRSZ;
79     out         = palloc ( olen + 1 );
80     out->vl_len = olen+1;
81     memcpy( (void*) VARDATA(out), sou, olen-VARHDRSZ );
82     ((char*)out)[olen]   = '\0';
83     pfree(sou);
84
85     return out;
86 }
87
88
89 static GBT_VARKEY * gbt_text_l2n ( GBT_VARKEY * leaf )
90 {
91  
92   GBT_VARKEY   *out = leaf ;
93   GBT_VARKEY_R r    = gbt_var_key_readable ( leaf );
94   bytea * o ;
95
96   o   = gbt_text_xfrm ( r.lower );
97   r.lower = r.upper = o;
98   out = gbt_var_key_copy ( &r , TRUE );
99   pfree(o);
100
101   return out;
102
103 }
104
105
106
107
108
109 static const gbtree_vinfo tinfo =
110 {
111   gbt_t_text,
112   TRUE,
113   TRUE,
114   gbt_textgt,
115   gbt_textge,
116   gbt_texteq,
117   gbt_textle,
118   gbt_textlt,
119   gbt_textcmp,
120   gbt_text_l2n
121 };
122
123
124
125 /**************************************************
126  * Text ops
127  **************************************************/
128
129
130 Datum
131 gbt_text_compress (PG_FUNCTION_ARGS)
132 {
133   GISTENTRY        *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
134   PG_RETURN_POINTER ( gbt_var_compress( entry, &tinfo ) );
135 }
136
137 Datum
138 gbt_bpchar_compress (PG_FUNCTION_ARGS)
139 {
140
141   GISTENTRY        *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
142   GISTENTRY        * retval ;
143
144   if (entry->leafkey)
145   {
146
147     Datum          d = DirectFunctionCall1 ( rtrim1, entry->key );
148     GISTENTRY * trim = palloc(sizeof(GISTENTRY));
149
150     gistentryinit(*trim, d ,
151               entry->rel, entry->page,
152               entry->offset, VARSIZE(DatumGetPointer(d)), TRUE);
153     retval = gbt_var_compress( trim , &tinfo ) ;
154
155     pfree ( trim );
156     pfree ( DatumGetPointer(d) );
157   } else
158     retval = entry;
159
160   PG_RETURN_POINTER ( retval );
161 }
162
163
164
165 Datum
166 gbt_text_consistent(PG_FUNCTION_ARGS)
167 {
168   GISTENTRY        *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
169   GBT_VARKEY       *ktst  = (GBT_VARKEY   *) DatumGetPointer ( entry->key ) ;
170   GBT_VARKEY        *key  = (GBT_VARKEY   *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
171   void             *qtst  = ( void * ) DatumGetPointer( PG_GETARG_DATUM(1) );
172   void            *query  = ( void * ) DatumGetTextP  ( PG_GETARG_DATUM(1) );
173   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
174   bool    retval          = FALSE;
175   GBT_VARKEY_R          r =  gbt_var_key_readable ( key );
176
177   if ( GIST_LEAF(entry) )
178   {
179     retval = gbt_var_consistent( &r, query, &strategy, TRUE, &tinfo );
180   } else {
181     bytea * q = gbt_text_xfrm ( ( bytea * ) query );
182     retval    = gbt_var_consistent( &r, (void*)q, &strategy, FALSE, &tinfo );
183     if ( q != query )
184       pfree(q);
185   }
186
187   if ( ktst != key ){
188     pfree ( key );
189   }
190   if ( qtst != query ){
191     pfree ( query );
192   }
193
194   PG_RETURN_BOOL(retval);
195 }
196
197
198 Datum
199 gbt_bpchar_consistent(PG_FUNCTION_ARGS)
200 {
201   GISTENTRY        *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
202   GBT_VARKEY       *ktst  = (GBT_VARKEY   *) DatumGetPointer ( entry->key ) ;
203   GBT_VARKEY        *key  = (GBT_VARKEY   *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
204   void             *qtst  = ( void * ) DatumGetPointer ( PG_GETARG_DATUM(1) );
205   void            *query  = ( void * ) DatumGetPointer (PG_DETOAST_DATUM( PG_GETARG_DATUM(1) ) );
206   void             *trim  = ( void * ) DatumGetPointer ( DirectFunctionCall1 ( rtrim1, PointerGetDatum ( query ) ) ) ;
207   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
208   bool    retval          = FALSE;
209   GBT_VARKEY_R          r =  gbt_var_key_readable ( key );
210
211   if ( GIST_LEAF(entry) )
212   {
213     retval = gbt_var_consistent( &r, trim , &strategy, TRUE, &tinfo );
214   } else {
215     bytea * q = gbt_text_xfrm ( ( bytea * ) trim );
216     retval    = gbt_var_consistent( &r, (void*)q, &strategy, FALSE, &tinfo );
217     if ( q != trim )
218       pfree(q);
219   }
220
221   pfree(trim);
222
223   if ( ktst != key ){
224     pfree ( key );
225   }
226   if ( qtst != query ){
227     pfree ( query );
228   }
229   PG_RETURN_BOOL(retval);
230 }
231
232
233
234
235 Datum
236 gbt_text_union(PG_FUNCTION_ARGS)
237 {
238     GistEntryVector   *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
239     int32                 *size = (int *) PG_GETARG_POINTER(1);
240     PG_RETURN_POINTER( gbt_var_union ( entryvec , size , &tinfo ) );
241 }
242  
243
244 Datum
245 gbt_text_picksplit(PG_FUNCTION_ARGS)
246 {
247     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
248     GIST_SPLITVEC          *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
249     gbt_var_picksplit ( entryvec, v, &tinfo );
250     PG_RETURN_POINTER(v);
251 }
252
253 Datum
254 gbt_text_same(PG_FUNCTION_ARGS)
255 {
256     Datum d1 = PG_GETARG_DATUM(0);
257     Datum d2 = PG_GETARG_DATUM(1);
258     bool       *result = (bool *) PG_GETARG_POINTER(2);
259     PG_RETURN_POINTER( gbt_var_same ( result, d1 , d2 , &tinfo ));
260 }
261
262
263 Datum
264 gbt_text_penalty(PG_FUNCTION_ARGS)
265 {
266     float      *result   = (float *)     PG_GETARG_POINTER(2);
267     GISTENTRY *      o   = (GISTENTRY *) PG_GETARG_POINTER(0);
268     GISTENTRY *      n   = (GISTENTRY *) PG_GETARG_POINTER(1);
269     PG_RETURN_POINTER( gbt_var_penalty ( result ,o , n, &tinfo ) );
270 }
271