2002-04-25 10:36:55 +02:00
|
|
|
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
After merge fixes
Added more DBUG statements
Ensure that we are comparing end space with BINARY strings
Use 'any_db' instead of '' to mean any database. (For HANDLER command)
Only strip ' ' when comparing CHAR, not other space-like characters (like \t)
BitKeeper/deleted/.del-ctype_tis620.result-old~3578ceb0b8284685:
Delete: mysql-test/r/ctype_tis620.result-old
BitKeeper/deleted/.del-ctype_tis620.test-old~ffb1bbd2935d1aba:
Delete: mysql-test/t/ctype_tis620.test-old
client/mysqlbinlog.cc:
Added DBUG statements
Added call of my_end() to free all used memory on exit
heap/hp_info.c:
After merge fixes
heap/hp_open.c:
After merge fixes
include/heap.h:
After merge fixes
include/m_ctype.h:
Use pchar instead of 'int' for character parameters.
Added 'my_binary_compare()'
include/m_string.h:
Fixed wrong define
innobase/ibuf/ibuf0ibuf.c:
After merge fixes
innobase/srv/srv0start.c:
After merge fixes
mysql-test/r/alter_table.result:
Fixed results after merge
mysql-test/r/auto_increment.result:
Fixed results after merge
mysql-test/r/bdb.result:
Fixed results after merge
mysql-test/r/binary.result:
Fixed results after merge
mysql-test/r/create.result:
Fixed results after merge
mysql-test/r/ctype_mb.result:
Fixed results after merge
mysql-test/r/ctype_tis620.result:
Fixed results after merge
mysql-test/r/ctype_utf8.result:
Fixed results after merge
mysql-test/r/delete.result:
Fixed results after merge
mysql-test/r/func_compress.result:
Fixed results after merge
mysql-test/r/func_gconcat.result:
Fixed results after merge
mysql-test/r/func_group.result:
Fixed results after merge
mysql-test/r/func_str.result:
Fixed results after merge
mysql-test/r/innodb.result:
Fixed results after merge
mysql-test/r/insert.result:
Fixed results after merge
mysql-test/r/insert_select.result:
Fixed results after merge
mysql-test/r/key.result:
Fixed results after merge
mysql-test/r/loaddata.result:
Fixed results after merge
mysql-test/r/lock.result:
Fixed results after merge
mysql-test/r/myisam.result:
Fixed results after merge
mysql-test/r/null.result:
Fixed results after merge
mysql-test/r/null_key.result:
Fixed results after merge
mysql-test/r/order_by.result:
Fixed results after merge
mysql-test/r/query_cache.result:
Fixed results after merge
mysql-test/r/range.result:
Fixed results after merge
mysql-test/r/rpl_multi_delete.result:
Fixed results after merge
mysql-test/r/rpl_until.result:
Fixed results after merge
mysql-test/r/subselect.result:
Fixed results after merge
mysql-test/r/subselect_innodb.result:
Fixed results after merge
mysql-test/r/type_blob.result:
Fixed results after merge
mysql-test/r/type_datetime.result:
Fixed results after merge
mysql-test/r/type_decimal.result:
Fixed results after merge
mysql-test/r/type_enum.result:
Fixed results after merge
mysql-test/r/type_float.result:
Fixed results after merge
mysql-test/r/type_ranges.result:
Fixed results after merge
mysql-test/r/type_time.result:
Fixed results after merge
mysql-test/r/type_timestamp.result:
Fixed results after merge
mysql-test/r/type_uint.result:
Fixed results after merge
mysql-test/r/type_year.result:
Fixed results after merge
mysql-test/r/variables.result:
Fixed results after merge
mysql-test/r/warnings.result:
Fixed results after merge
mysql-test/t/case.test:
Fixed shifted error messages
mysql-test/t/create.test:
Fixed shifted error messages
mysql-test/t/ctype_collate.test:
Fixed shifted error messages
mysql-test/t/ctype_tis620.test:
Merge with 4.0 ctype_tis620 test
mysql-test/t/delete.test:
Fixed shifted error messages
mysql-test/t/derived.test:
Fixed shifted error messages
mysql-test/t/fulltext.test:
Fixed shifted error messages
mysql-test/t/func_in.test:
Fixed shifted error messages
mysql-test/t/func_str.test:
Fixed shifted error messages
mysql-test/t/func_test.test:
Fixed shifted error messages
mysql-test/t/grant.test:
Fixed shifted error messages
mysql-test/t/innodb.test:
Change to 4.1 syntax
mysql-test/t/key_cache.test:
Fixed shifted error messages
mysql-test/t/myisam.test:
New test of blob and end space
mysql-test/t/row.test:
Fixed shifted error messages
mysql-test/t/rpl_until.test:
Fixed shifted error messages
mysql-test/t/subselect.test:
Fixed shifted error messages
mysql-test/t/subselect_innodb.test:
Fix test to take into account foreign key constraints
mysql-test/t/union.test:
Fixed shifted error messages
mysql-test/t/user_var.test:
Fixed shifted error messages
mysql-test/t/variables.test:
Fixed shifted error messages
mysys/my_handler.c:
Merge with 4.0 code
sql/ha_heap.cc:
After merge fixes
sql/handler.cc:
After merge fixes
sql/item.cc:
After merge fixes
sql/item_cmpfunc.cc:
Ensure that we are comparing end space with BINARY strings
sql/item_cmpfunc.h:
Ensure that we are comparing end space with BINARY strings
sql/log_event.cc:
More DBUG statements
Ensure that we use all options to LOAD DATA in replication
sql/opt_range.cc:
After merge fixes
sql/sql_db.cc:
After merge fixes
sql/sql_handler.cc:
After merge fixes
Use 'any_db' instead of '' to mean 'no database comparison'
sql/sql_parse.cc:
After merge fixes
sql/sql_select.cc:
After merge fixes
Added function comment for setup_group()
sql/sql_string.cc:
Added stringcmp() for binary comparison.
Added function comments for sortcmp() and stringcmp()
sql/sql_string.h:
Added stringcmp()
sql/sql_table.cc:
After merge fixes
sql/sql_update.cc:
After merge fixes
sql/sql_yacc.yy:
Use 'any_db' instead of '' to mean any database. Using "" causes a 'wrong db name' error.
strings/ctype-big5.c:
Strip only end space, not other space characters.
strings/ctype-bin.c:
Removed some not needed functions.
Added function comments
Don't remove end space in comparisons
Change my_wildcmp_bin() to be 'identical' with other similar code
strings/ctype-czech.c:
Strip only end space, not other space characters.
strings/ctype-gbk.c:
Strip only end space, not other space characters.
strings/ctype-latin1.c:
Strip only end space, not other space characters.
strings/ctype-mb.c:
Strip only end space, not other space characters.
strings/ctype-simple.c:
Strip only end space, not other space characters.
strings/ctype-sjis.c:
Strip only end space, not other space characters.
strings/ctype-tis620.c:
Added usage of my_instr_simple. This needs to be cleaned up!
strings/ctype-utf8.c:
Strip only end space, not other space characters.
strings/ctype-win1250ch.c:
Strip only end space, not other space characters.
Fixed indentation
strings/strto.c:
Code cleanup
2004-02-16 09:03:25 +01:00
|
|
|
|
2002-04-25 10:36:55 +02:00
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
|
|
MA 02111-1307, USA */
|
|
|
|
|
|
|
|
#include "my_handler.h"
|
|
|
|
|
2002-05-21 18:54:08 +02:00
|
|
|
int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
2004-03-25 14:05:01 +01:00
|
|
|
uchar *b, uint b_length, my_bool part_key,
|
|
|
|
my_bool skip_end_space)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
2004-12-06 01:00:37 +01:00
|
|
|
if (!part_key)
|
2004-03-25 14:05:01 +01:00
|
|
|
return charset_info->coll->strnncollsp(charset_info, a, a_length,
|
2004-12-06 01:00:37 +01:00
|
|
|
b, b_length, !skip_end_space);
|
2004-03-25 14:05:01 +01:00
|
|
|
return charset_info->coll->strnncoll(charset_info, a, a_length,
|
2004-12-06 01:00:37 +01:00
|
|
|
b, b_length, part_key);
|
2002-04-25 10:36:55 +02:00
|
|
|
}
|
|
|
|
|
2004-03-25 14:05:01 +01:00
|
|
|
|
2002-04-25 10:36:55 +02:00
|
|
|
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
2004-03-25 14:05:01 +01:00
|
|
|
my_bool part_key, my_bool skip_end_space)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
|
|
|
uint length= min(a_length,b_length);
|
|
|
|
uchar *end= a+ length;
|
|
|
|
int flag;
|
|
|
|
|
|
|
|
while (a < end)
|
|
|
|
if ((flag= (int) *a++ - (int) *b++))
|
|
|
|
return flag;
|
|
|
|
if (part_key && b_length < a_length)
|
|
|
|
return 0;
|
2004-03-25 14:05:01 +01:00
|
|
|
if (skip_end_space && a_length != b_length)
|
|
|
|
{
|
|
|
|
int swap= 0;
|
|
|
|
/*
|
|
|
|
We are using space compression. We have to check if longer key
|
|
|
|
has next character < ' ', in which case it's less than the shorter
|
|
|
|
key that has an implicite space afterwards.
|
|
|
|
|
|
|
|
This code is identical to the one in
|
|
|
|
strings/ctype-simple.c:my_strnncollsp_simple
|
|
|
|
*/
|
|
|
|
if (a_length < b_length)
|
|
|
|
{
|
|
|
|
/* put shorter key in a */
|
|
|
|
a_length= b_length;
|
|
|
|
a= b;
|
|
|
|
swap= -1; /* swap sign of result */
|
|
|
|
}
|
|
|
|
for (end= a + a_length-length; a < end ; a++)
|
|
|
|
{
|
|
|
|
if (*a != ' ')
|
|
|
|
return ((int) *a - (int) ' ') ^ swap;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2002-04-25 10:36:55 +02:00
|
|
|
return (int) (a_length-b_length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2002-05-22 17:51:21 +02:00
|
|
|
Compare two keys
|
2003-01-09 21:42:31 +01:00
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
ha_key_cmp()
|
|
|
|
keyseg Key segments of key to compare
|
|
|
|
a First key to compare, in format from _mi_pack_key()
|
|
|
|
This is normally key specified by user
|
|
|
|
b Second key to compare. This is always from a row
|
|
|
|
key_length Length of key to compare. This can be shorter than
|
|
|
|
a to just compare sub keys
|
|
|
|
next_flag How keys should be compared
|
|
|
|
If bit SEARCH_FIND is not set the keys includes the row
|
|
|
|
position and this should also be compared
|
|
|
|
|
|
|
|
NOTES
|
|
|
|
Number-keys can't be splited
|
|
|
|
|
|
|
|
RETURN VALUES
|
|
|
|
<0 If a < b
|
|
|
|
0 If a == b
|
|
|
|
>0 If a > b
|
2002-04-25 10:36:55 +02:00
|
|
|
*/
|
2002-05-22 17:51:21 +02:00
|
|
|
|
2003-01-09 21:42:31 +01:00
|
|
|
#define FCMP(A,B) ((int) (A) - (int) (B))
|
|
|
|
|
2002-04-25 12:10:29 +02:00
|
|
|
int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
2002-05-22 17:51:21 +02:00
|
|
|
register uchar *b, uint key_length, uint nextflag,
|
|
|
|
uint *diff_pos)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
|
|
|
int flag;
|
|
|
|
int16 s_1,s_2;
|
|
|
|
int32 l_1,l_2;
|
|
|
|
uint32 u_1,u_2;
|
|
|
|
float f_1,f_2;
|
|
|
|
double d_1,d_2;
|
2003-01-09 21:42:31 +01:00
|
|
|
uint next_key_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
|
|
|
*diff_pos=0;
|
2003-01-09 21:42:31 +01:00
|
|
|
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
|
|
|
uchar *end;
|
2002-05-22 17:51:21 +02:00
|
|
|
uint piks=! (keyseg->flag & HA_NO_SORT);
|
2002-04-25 10:36:55 +02:00
|
|
|
(*diff_pos)++;
|
|
|
|
|
|
|
|
/* Handle NULL part */
|
|
|
|
if (keyseg->null_bit)
|
|
|
|
{
|
|
|
|
key_length--;
|
2002-05-22 17:51:21 +02:00
|
|
|
if (*a != *b && piks)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
|
|
|
flag = (int) *a - (int) *b;
|
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
}
|
|
|
|
b++;
|
|
|
|
if (!*a++) /* If key was NULL */
|
|
|
|
{
|
|
|
|
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
|
|
|
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
2003-01-09 21:42:31 +01:00
|
|
|
else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
This is only used from mi_check() to calculate cardinality.
|
|
|
|
It can't be used when searching for a key as this would cause
|
|
|
|
compare of (a,b) and (b,a) to return the same value.
|
|
|
|
*/
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
next_key_length=key_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
continue; /* To next key part */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end= a+ min(keyseg->length,key_length);
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-keyseg->length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
|
|
|
switch ((enum ha_base_keytype) keyseg->type) {
|
|
|
|
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
|
|
|
|
if (keyseg->flag & HA_SPACE_PACK)
|
|
|
|
{
|
|
|
|
int a_length,b_length,pack_length;
|
|
|
|
get_key_length(a_length,a);
|
|
|
|
get_key_pack_length(b_length,pack_length,b);
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-b_length-pack_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
2003-01-09 21:42:31 +01:00
|
|
|
(flag=mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0),
|
2004-08-24 17:24:05 +02:00
|
|
|
(my_bool)!(nextflag & SEARCH_PREFIX))))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a+=a_length;
|
|
|
|
b+=b_length;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint length=(uint) (end-a), a_length=length, b_length=length;
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
2003-01-09 21:42:31 +01:00
|
|
|
(flag= mi_compare_text(keyseg->charset, a, a_length, b, b_length,
|
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0),
|
2004-08-24 17:24:05 +02:00
|
|
|
(my_bool)!(nextflag & SEARCH_PREFIX))))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a=end;
|
|
|
|
b+=length;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_BINARY:
|
|
|
|
if (keyseg->flag & HA_SPACE_PACK)
|
|
|
|
{
|
|
|
|
int a_length,b_length,pack_length;
|
|
|
|
get_key_length(a_length,a);
|
|
|
|
get_key_pack_length(b_length,pack_length,b);
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-b_length-pack_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
|
|
|
(flag=compare_bin(a,a_length,b,b_length,
|
2002-04-25 10:36:55 +02:00
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0),1)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a+=a_length;
|
|
|
|
b+=b_length;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint length=keyseg->length;
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
|
|
|
(flag=compare_bin(a,length,b,length,
|
2002-04-25 10:36:55 +02:00
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0),0)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a+=length;
|
|
|
|
b+=length;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_VARTEXT:
|
|
|
|
{
|
2004-12-06 01:00:37 +01:00
|
|
|
int a_length,b_length,pack_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
get_key_length(a_length,a);
|
|
|
|
get_key_pack_length(b_length,pack_length,b);
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-b_length-pack_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
|
|
|
(flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
2002-04-25 10:36:55 +02:00
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0),
|
|
|
|
(my_bool) ((nextflag & (SEARCH_FIND |
|
|
|
|
SEARCH_UPDATE)) ==
|
2004-12-06 01:00:37 +01:00
|
|
|
SEARCH_FIND &&
|
|
|
|
! (keyseg->flag &
|
|
|
|
HA_END_SPACE_ARE_EQUAL)))))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
2004-12-06 01:00:37 +01:00
|
|
|
a+= a_length;
|
|
|
|
b+= b_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_VARBINARY:
|
|
|
|
{
|
|
|
|
int a_length,b_length,pack_length;
|
|
|
|
get_key_length(a_length,a);
|
|
|
|
get_key_pack_length(b_length,pack_length,b);
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-b_length-pack_length;
|
2002-04-25 10:36:55 +02:00
|
|
|
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks &&
|
|
|
|
(flag=compare_bin(a,a_length,b,b_length,
|
2002-04-25 10:36:55 +02:00
|
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
2004-03-25 14:05:01 +01:00
|
|
|
next_key_length <= 0), 0)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a+=a_length;
|
|
|
|
b+=b_length;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_INT8:
|
|
|
|
{
|
|
|
|
int i_1= (int) *((signed char*) a);
|
|
|
|
int i_2= (int) *((signed char*) b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(i_1,i_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HA_KEYTYPE_SHORT_INT:
|
|
|
|
s_1= mi_sint2korr(a);
|
|
|
|
s_2= mi_sint2korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(s_1,s_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 2; /* sizeof(short int); */
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_USHORT_INT:
|
|
|
|
{
|
|
|
|
uint16 us_1,us_2;
|
|
|
|
us_1= mi_sint2korr(a);
|
|
|
|
us_2= mi_sint2korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(us_1,us_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+=2; /* sizeof(short int); */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HA_KEYTYPE_LONG_INT:
|
|
|
|
l_1= mi_sint4korr(a);
|
|
|
|
l_2= mi_sint4korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 4; /* sizeof(long int); */
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_ULONG_INT:
|
|
|
|
u_1= mi_sint4korr(a);
|
|
|
|
u_2= mi_sint4korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(u_1,u_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 4; /* sizeof(long int); */
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_INT24:
|
|
|
|
l_1=mi_sint3korr(a);
|
|
|
|
l_2=mi_sint3korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 3;
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_UINT24:
|
|
|
|
l_1=mi_uint3korr(a);
|
|
|
|
l_2=mi_uint3korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 3;
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_FLOAT:
|
|
|
|
mi_float4get(f_1,a);
|
|
|
|
mi_float4get(f_2,b);
|
2004-10-22 17:44:51 +02:00
|
|
|
/*
|
|
|
|
The following may give a compiler warning about floating point
|
|
|
|
comparison not being safe, but this is ok in this context as
|
|
|
|
we are bascily doing sorting
|
|
|
|
*/
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(f_1,f_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 4; /* sizeof(float); */
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_DOUBLE:
|
|
|
|
mi_float8get(d_1,a);
|
|
|
|
mi_float8get(d_2,b);
|
2004-10-22 17:44:51 +02:00
|
|
|
/*
|
|
|
|
The following may give a compiler warning about floating point
|
|
|
|
comparison not being safe, but this is ok in this context as
|
|
|
|
we are bascily doing sorting
|
|
|
|
*/
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(d_1,d_2)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 8; /* sizeof(double); */
|
|
|
|
break;
|
|
|
|
case HA_KEYTYPE_NUM: /* Numeric key */
|
|
|
|
{
|
|
|
|
int swap_flag= 0;
|
|
|
|
int alength,blength;
|
2003-01-09 21:42:31 +01:00
|
|
|
|
2002-04-25 10:36:55 +02:00
|
|
|
if (keyseg->flag & HA_REVERSE_SORT)
|
|
|
|
{
|
2004-05-25 00:03:49 +02:00
|
|
|
swap_variables(uchar*, a, b);
|
2002-04-25 10:36:55 +02:00
|
|
|
swap_flag=1; /* Remember swap of a & b */
|
|
|
|
end= a+ (int) (end-b);
|
|
|
|
}
|
|
|
|
if (keyseg->flag & HA_SPACE_PACK)
|
|
|
|
{
|
|
|
|
alength= *a++; blength= *b++;
|
|
|
|
end=a+alength;
|
2003-01-09 21:42:31 +01:00
|
|
|
next_key_length=key_length-blength-1;
|
2002-04-25 10:36:55 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
alength= (int) (end-a);
|
|
|
|
blength=keyseg->length;
|
|
|
|
/* remove pre space from keys */
|
|
|
|
for ( ; alength && *a == ' ' ; a++, alength--) ;
|
|
|
|
for ( ; blength && *b == ' ' ; b++, blength--) ;
|
|
|
|
}
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks)
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
2002-05-22 17:51:21 +02:00
|
|
|
if (*a == '-')
|
|
|
|
{
|
|
|
|
if (*b != '-')
|
|
|
|
return -1;
|
|
|
|
a++; b++;
|
2004-05-25 00:03:49 +02:00
|
|
|
swap_variables(uchar*, a, b);
|
|
|
|
swap_variables(int, alength, blength);
|
2002-05-22 17:51:21 +02:00
|
|
|
swap_flag=1-swap_flag;
|
|
|
|
alength--; blength--;
|
|
|
|
end=a+alength;
|
|
|
|
}
|
|
|
|
else if (*b == '-')
|
|
|
|
return 1;
|
|
|
|
while (alength && (*a == '+' || *a == '0'))
|
|
|
|
{
|
|
|
|
a++; alength--;
|
|
|
|
}
|
|
|
|
while (blength && (*b == '+' || *b == '0'))
|
|
|
|
{
|
|
|
|
b++; blength--;
|
|
|
|
}
|
|
|
|
if (alength != blength)
|
|
|
|
return (alength < blength) ? -1 : 1;
|
|
|
|
while (a < end)
|
|
|
|
if (*a++ != *b++)
|
|
|
|
return ((int) a[-1] - (int) b[-1]);
|
2002-04-25 10:36:55 +02:00
|
|
|
}
|
2002-05-22 17:51:21 +02:00
|
|
|
else
|
2002-04-25 10:36:55 +02:00
|
|
|
{
|
2002-05-22 17:51:21 +02:00
|
|
|
b+=(end-a);
|
|
|
|
a=end;
|
2002-04-25 10:36:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (swap_flag) /* Restore pointers */
|
2004-05-25 00:03:49 +02:00
|
|
|
swap_variables(uchar*, a, b);
|
2002-04-25 10:36:55 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_LONG_LONG
|
|
|
|
case HA_KEYTYPE_LONGLONG:
|
|
|
|
{
|
|
|
|
longlong ll_a,ll_b;
|
|
|
|
ll_a= mi_sint8korr(a);
|
|
|
|
ll_b= mi_sint8korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HA_KEYTYPE_ULONGLONG:
|
|
|
|
{
|
|
|
|
ulonglong ll_a,ll_b;
|
|
|
|
ll_a= mi_uint8korr(a);
|
|
|
|
ll_b= mi_uint8korr(b);
|
2002-05-22 17:51:21 +02:00
|
|
|
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
2002-04-25 10:36:55 +02:00
|
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
|
|
a= end;
|
|
|
|
b+= 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
case HA_KEYTYPE_END: /* Ready */
|
|
|
|
goto end; /* diff_pos is incremented */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*diff_pos)++;
|
|
|
|
end:
|
|
|
|
if (!(nextflag & SEARCH_FIND))
|
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
|
|
|
|
return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
|
|
|
|
flag=0;
|
|
|
|
for (i=keyseg->length ; i-- > 0 ; )
|
|
|
|
{
|
|
|
|
if (*a++ != *b++)
|
|
|
|
{
|
|
|
|
flag= FCMP(a[-1],b[-1]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nextflag & SEARCH_SAME)
|
|
|
|
return (flag); /* read same */
|
|
|
|
if (nextflag & SEARCH_BIGGER)
|
|
|
|
return (flag <= 0 ? -1 : 1); /* read next */
|
|
|
|
return (flag < 0 ? -1 : 1); /* read previous */
|
|
|
|
}
|
|
|
|
return 0;
|
2002-05-21 18:54:08 +02:00
|
|
|
} /* ha_key_cmp */
|