22 #include <drizzled/charset.h>
23 #include <drizzled/base.h>
24 #include <plugin/myisam/my_handler.h>
25 #include <drizzled/internal/my_sys.h>
34 int CMP_NUM(
const T& a,
const T&b)
36 return (a < b) ? -1 : (a == b) ? 0 : 1;
40 int ha_compare_text(
const charset_info_st *
const charset_info,
unsigned char *a, uint32_t a_length,
41 unsigned char *b, uint32_t b_length,
bool part_key,
45 return charset_info->coll->strnncollsp(charset_info, a, a_length,
46 b, b_length, (
bool)!skip_end_space);
47 return charset_info->coll->strnncoll(charset_info, a, a_length,
48 b, b_length, part_key);
52 static int compare_bin(
unsigned char *a, uint32_t a_length,
unsigned char *b, uint32_t b_length,
53 bool part_key,
bool skip_end_space)
55 uint32_t length= min(a_length,b_length);
56 unsigned char *end= a+ length;
60 if ((flag= (
int) *a++ - (
int) *b++))
62 if (part_key && b_length < a_length)
64 if (skip_end_space && a_length != b_length)
75 if (a_length < b_length)
82 for (end= a + a_length-length; a < end ; a++)
85 return (*a <
' ') ? -swap : swap;
89 return (
int) (a_length-b_length);
133 #define FCMP(A,B) ((int) (A) - (int) (B))
135 int ha_key_cmp(
register HA_KEYSEG *keyseg,
register unsigned char *a,
136 register unsigned char *b, uint32_t key_length, uint32_t nextflag,
143 uint32_t next_key_length;
144 unsigned char *orig_b= b;
147 for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
150 uint32_t piks=! (keyseg->flag & HA_NO_SORT);
152 diff_pos[1]= (uint)(b - orig_b);
155 if (keyseg->null_bit)
158 if (*a != *b && piks)
160 flag = (int) *a - (
int) *b;
161 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
166 if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
167 nextflag=SEARCH_SAME;
168 else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
177 next_key_length=key_length;
181 end= a+ min((uint32_t)keyseg->length,key_length);
182 next_key_length=key_length-keyseg->length;
184 switch ((
enum ha_base_keytype) keyseg->type) {
185 case HA_KEYTYPE_TEXT:
186 if (keyseg->flag & HA_SPACE_PACK)
188 int a_length,b_length,pack_length;
189 get_key_length(a_length,a);
190 get_key_pack_length(b_length,pack_length,b);
191 next_key_length=key_length-b_length-pack_length;
194 (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length,
195 (
bool) ((nextflag & SEARCH_PREFIX) &&
196 next_key_length <= 0),
197 (
bool)!(nextflag & SEARCH_PREFIX))))
198 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
205 uint32_t length=(uint) (end-a), a_length=length, b_length=length;
207 (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length,
208 (
bool) ((nextflag & SEARCH_PREFIX) &&
209 next_key_length <= 0),
210 (
bool)!(nextflag & SEARCH_PREFIX))))
211 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
216 case HA_KEYTYPE_BINARY:
217 if (keyseg->flag & HA_SPACE_PACK)
219 int a_length,b_length,pack_length;
220 get_key_length(a_length,a);
221 get_key_pack_length(b_length,pack_length,b);
222 next_key_length=key_length-b_length-pack_length;
225 (flag=compare_bin(a,a_length,b,b_length,
226 (
bool) ((nextflag & SEARCH_PREFIX) &&
227 next_key_length <= 0),1)))
228 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
235 uint32_t length=keyseg->length;
237 (flag=compare_bin(a,length,b,length,
238 (
bool) ((nextflag & SEARCH_PREFIX) &&
239 next_key_length <= 0),0)))
240 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
245 case HA_KEYTYPE_VARTEXT1:
246 case HA_KEYTYPE_VARTEXT2:
248 int a_length,b_length,pack_length;
249 get_key_length(a_length,a);
250 get_key_pack_length(b_length,pack_length,b);
251 next_key_length=key_length-b_length-pack_length;
254 (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length,
255 (
bool) ((nextflag & SEARCH_PREFIX) &&
256 next_key_length <= 0),
257 (
bool) ((nextflag & (SEARCH_FIND |
261 HA_END_SPACE_ARE_EQUAL)))))
262 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
267 case HA_KEYTYPE_VARBINARY1:
268 case HA_KEYTYPE_VARBINARY2:
270 int a_length,b_length,pack_length;
271 get_key_length(a_length,a);
272 get_key_pack_length(b_length,pack_length,b);
273 next_key_length=key_length-b_length-pack_length;
276 (flag=compare_bin(a,a_length,b,b_length,
277 (
bool) ((nextflag & SEARCH_PREFIX) &&
278 next_key_length <= 0), 0)))
279 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
284 case HA_KEYTYPE_LONG_INT:
285 l_1= mi_sint4korr(a);
286 l_2= mi_sint4korr(b);
287 if (piks && (flag = CMP_NUM(l_1,l_2)))
288 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
292 case HA_KEYTYPE_ULONG_INT:
293 u_1= mi_sint4korr(a);
294 u_2= mi_sint4korr(b);
295 if (piks && (flag = CMP_NUM(u_1,u_2)))
296 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
300 case HA_KEYTYPE_DOUBLE:
308 if (piks && (flag = CMP_NUM(d_1,d_2)))
309 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
313 case HA_KEYTYPE_LONGLONG:
316 ll_a= mi_sint8korr(a);
317 ll_b= mi_sint8korr(b);
318 if (piks && (flag = CMP_NUM(ll_a,ll_b)))
319 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
324 case HA_KEYTYPE_ULONGLONG:
327 ll_a= mi_uint8korr(a);
328 ll_b= mi_uint8korr(b);
329 if (piks && (flag = CMP_NUM(ll_a,ll_b)))
330 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
341 if (!(nextflag & SEARCH_FIND))
344 if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
345 return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
347 for (i=keyseg->length ; i-- > 0 ; )
351 flag= FCMP(a[-1],b[-1]);
355 if (nextflag & SEARCH_SAME)
357 if (nextflag & SEARCH_BIGGER)
358 return (flag <= 0 ? -1 : 1);
359 return (flag < 0 ? -1 : 1);
388 for (; (
enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++)
391 if (keyseg->null_bit)
396 end= a+ keyseg->length;
398 switch ((
enum ha_base_keytype) keyseg->type) {
399 case HA_KEYTYPE_TEXT:
400 case HA_KEYTYPE_BINARY:
401 if (keyseg->flag & HA_SPACE_PACK)
404 get_key_length(a_length, a);
411 case HA_KEYTYPE_VARTEXT1:
412 case HA_KEYTYPE_VARTEXT2:
413 case HA_KEYTYPE_VARBINARY1:
414 case HA_KEYTYPE_VARBINARY2:
417 get_key_length(a_length, a);
421 case HA_KEYTYPE_LONG_INT:
422 case HA_KEYTYPE_ULONG_INT:
423 case HA_KEYTYPE_LONGLONG:
424 case HA_KEYTYPE_ULONGLONG:
425 case HA_KEYTYPE_DOUBLE:
TODO: Rename this file - func.h is stupid.