16 #include <my_global.h>
19 #include <my_compare.h>
22 #define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
24 int ha_compare_text(
const CHARSET_INFO *charset_info, uchar *a, uint a_length,
25 uchar *b, uint b_length, my_bool part_key,
26 my_bool skip_end_space)
29 return charset_info->coll->strnncollsp(charset_info, a, a_length,
30 b, b_length, (my_bool)!skip_end_space);
31 return charset_info->coll->strnncoll(charset_info, a, a_length,
32 b, b_length, part_key);
36 static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
37 my_bool part_key, my_bool skip_end_space)
39 uint length= MY_MIN(a_length, b_length);
40 uchar *end= a+ length;
44 if ((flag= (
int) *a++ - (
int) *b++))
46 if (part_key && b_length < a_length)
48 if (skip_end_space && a_length != b_length)
59 if (a_length < b_length)
66 for (end= a + a_length-length; a < end ; a++)
69 return (*a <
' ') ? -swap : swap;
73 return (
int) (a_length-b_length);
117 #define FCMP(A,B) ((int) (A) - (int) (B))
119 int ha_key_cmp(
register HA_KEYSEG *keyseg,
register uchar *a,
120 register uchar *b, uint key_length, uint nextflag,
129 uint next_key_length;
133 for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
136 uint piks=! (keyseg->flag & HA_NO_SORT);
138 diff_pos[1]= (uint)(b - orig_b);
141 if (keyseg->null_bit)
144 if (*a != *b && piks)
146 flag = (int) *a - (
int) *b;
147 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
152 if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
153 nextflag=SEARCH_SAME;
154 else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
163 next_key_length=key_length;
167 end= a + MY_MIN(keyseg->length, key_length);
168 next_key_length=key_length-keyseg->length;
170 switch ((
enum ha_base_keytype) keyseg->type) {
171 case HA_KEYTYPE_TEXT:
172 if (keyseg->flag & HA_SPACE_PACK)
174 int a_length,b_length,pack_length;
175 get_key_length(a_length,a);
176 get_key_pack_length(b_length,pack_length,b);
177 next_key_length=key_length-b_length-pack_length;
180 (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length,
181 (my_bool) ((nextflag & SEARCH_PREFIX) &&
182 next_key_length <= 0),
183 (my_bool)!(nextflag & SEARCH_PREFIX))))
184 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
191 uint length=(uint) (end-a), a_length=length, b_length=length;
193 (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length,
194 (my_bool) ((nextflag & SEARCH_PREFIX) &&
195 next_key_length <= 0),
196 (my_bool)!(nextflag & SEARCH_PREFIX))))
197 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
202 case HA_KEYTYPE_BINARY:
204 if (keyseg->flag & HA_SPACE_PACK)
206 int a_length,b_length,pack_length;
207 get_key_length(a_length,a);
208 get_key_pack_length(b_length,pack_length,b);
209 next_key_length=key_length-b_length-pack_length;
212 (flag=compare_bin(a,a_length,b,b_length,
213 (my_bool) ((nextflag & SEARCH_PREFIX) &&
214 next_key_length <= 0),1)))
215 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
222 uint length=keyseg->length;
224 (flag=compare_bin(a,length,b,length,
225 (my_bool) ((nextflag & SEARCH_PREFIX) &&
226 next_key_length <= 0),0)))
227 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
232 case HA_KEYTYPE_VARTEXT1:
233 case HA_KEYTYPE_VARTEXT2:
235 int a_length,b_length,pack_length;
236 get_key_length(a_length,a);
237 get_key_pack_length(b_length,pack_length,b);
238 next_key_length=key_length-b_length-pack_length;
241 (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length,
242 (my_bool) ((nextflag & SEARCH_PREFIX) &&
243 next_key_length <= 0),
244 (my_bool) ((nextflag & (SEARCH_FIND |
248 HA_END_SPACE_ARE_EQUAL)))))
249 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
255 case HA_KEYTYPE_VARBINARY1:
256 case HA_KEYTYPE_VARBINARY2:
258 int a_length,b_length,pack_length;
259 get_key_length(a_length,a);
260 get_key_pack_length(b_length,pack_length,b);
261 next_key_length=key_length-b_length-pack_length;
264 (flag=compare_bin(a,a_length,b,b_length,
265 (my_bool) ((nextflag & SEARCH_PREFIX) &&
266 next_key_length <= 0), 0)))
267 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
272 case HA_KEYTYPE_INT8:
274 int i_1= (int) *((
signed char*) a);
275 int i_2= (int) *((
signed char*) b);
276 if (piks && (flag = CMP_NUM(i_1,i_2)))
277 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
282 case HA_KEYTYPE_SHORT_INT:
283 s_1= mi_sint2korr(a);
284 s_2= mi_sint2korr(b);
285 if (piks && (flag = CMP_NUM(s_1,s_2)))
286 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
290 case HA_KEYTYPE_USHORT_INT:
293 us_1= mi_sint2korr(a);
294 us_2= mi_sint2korr(b);
295 if (piks && (flag = CMP_NUM(us_1,us_2)))
296 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
301 case HA_KEYTYPE_LONG_INT:
302 l_1= mi_sint4korr(a);
303 l_2= mi_sint4korr(b);
304 if (piks && (flag = CMP_NUM(l_1,l_2)))
305 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
309 case HA_KEYTYPE_ULONG_INT:
310 u_1= mi_sint4korr(a);
311 u_2= mi_sint4korr(b);
312 if (piks && (flag = CMP_NUM(u_1,u_2)))
313 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
317 case HA_KEYTYPE_INT24:
320 if (piks && (flag = CMP_NUM(l_1,l_2)))
321 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
325 case HA_KEYTYPE_UINT24:
328 if (piks && (flag = CMP_NUM(l_1,l_2)))
329 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
333 case HA_KEYTYPE_FLOAT:
341 if (piks && (flag = CMP_NUM(f_1,f_2)))
342 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
346 case HA_KEYTYPE_DOUBLE:
354 if (piks && (flag = CMP_NUM(d_1,d_2)))
355 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
364 if (keyseg->flag & HA_REVERSE_SORT)
366 swap_variables(uchar*, a, b);
368 end= a+ (int) (end-b);
370 if (keyseg->flag & HA_SPACE_PACK)
372 alength= *a++; blength= *b++;
374 next_key_length=key_length-blength-1;
378 alength= (int) (end-a);
379 blength=keyseg->length;
381 for ( ; alength && *a ==
' ' ; a++, alength--) ;
382 for ( ; blength && *b ==
' ' ; b++, blength--) ;
391 swap_variables(uchar*, a, b);
392 swap_variables(
int, alength, blength);
393 swap_flag=1-swap_flag;
394 alength--; blength--;
399 while (alength && (*a ==
'+' || *a ==
'0'))
403 while (blength && (*b ==
'+' || *b ==
'0'))
407 if (alength != blength)
408 return (alength < blength) ? -1 : 1;
411 return ((
int) a[-1] - (
int) b[-1]);
420 swap_variables(uchar*, a, b);
423 #ifdef HAVE_LONG_LONG
424 case HA_KEYTYPE_LONGLONG:
427 ll_a= mi_sint8korr(a);
428 ll_b= mi_sint8korr(b);
429 if (piks && (flag = CMP_NUM(ll_a,ll_b)))
430 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
435 case HA_KEYTYPE_ULONGLONG:
438 ll_a= mi_uint8korr(a);
439 ll_b= mi_uint8korr(b);
440 if (piks && (flag = CMP_NUM(ll_a,ll_b)))
441 return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
453 if (!(nextflag & SEARCH_FIND))
456 if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
457 return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
459 for (i=keyseg->length ; i-- > 0 ; )
463 flag= FCMP(a[-1],b[-1]);
467 if (nextflag & SEARCH_SAME)
469 if (nextflag & SEARCH_BIGGER)
470 return (flag <= 0 ? -1 : 1);
471 return (flag < 0 ? -1 : 1);