mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
633 lines
19 KiB
C
633 lines
19 KiB
C
/* Copyright (c) 2011, Oracle and/or its affiliates.
|
|
Copyright (c) 2009, 2020, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
|
|
|
|
#include <my_global.h>
|
|
#include <m_ctype.h>
|
|
#include <my_base.h>
|
|
#include <my_compare.h>
|
|
#include <my_sys.h>
|
|
|
|
|
|
static int compare_bin(const uchar *a, uint a_length,
|
|
const uchar *b, uint b_length,
|
|
my_bool part_key, my_bool skip_end_space)
|
|
{
|
|
uint length= MY_MIN(a_length,b_length);
|
|
const 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;
|
|
if (skip_end_space && a_length != b_length)
|
|
{
|
|
int swap= 1;
|
|
/*
|
|
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 (*a < ' ') ? -swap : swap;
|
|
}
|
|
return 0;
|
|
}
|
|
return (int) (a_length-b_length);
|
|
}
|
|
|
|
|
|
/*
|
|
Compare two keys
|
|
|
|
SYNOPSIS
|
|
ha_key_cmp()
|
|
keyseg Array of key segments of key to compare
|
|
a First key to compare, in format from _mi_pack_key()
|
|
This is always from the row
|
|
b Second key to compare. This is from the row or the user
|
|
key_length Length of key to compare, based on key b. This can be shorter
|
|
than b 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
|
|
If SEARCH_PAGE_KEY_HAS_TRANSID is set then 'a' has transid
|
|
If SEARCH_USER_KEY_HAS_TRANSID is set then 'b' has transid
|
|
diff_pos OUT Number of first keypart where values differ, counting
|
|
from one.
|
|
diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b
|
|
that is different from corresponding value in tuple a.
|
|
|
|
EXAMPLES
|
|
Example1: if the function is called for tuples
|
|
('aaa','bbb') and ('eee','fff'), then
|
|
diff_pos[0] = 1 (as 'aaa' != 'eee')
|
|
diff_pos[1] = 0 (offset from beginning of tuple b to 'eee' keypart).
|
|
|
|
Example2: if the index function is called for tuples
|
|
('aaa','bbb') and ('aaa','fff'),
|
|
diff_pos[0] = 2 (as 'aaa' != 'eee')
|
|
diff_pos[1] = 3 (offset from beginning of tuple b to 'fff' keypart,
|
|
here we assume that first key part is CHAR(3) NOT NULL)
|
|
|
|
NOTES
|
|
Number-keys can't be splited
|
|
|
|
RETURN VALUES
|
|
<0 If a < b
|
|
0 If a == b
|
|
>0 If a > b
|
|
*/
|
|
|
|
#define FCMP(A,B) ((int) (A) - (int) (B))
|
|
|
|
int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a,
|
|
const uchar *b, uint key_length, uint32 nextflag,
|
|
uint *diff_pos)
|
|
{
|
|
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;
|
|
uint next_key_length;
|
|
const uchar *orig_b= b;
|
|
|
|
*diff_pos=0;
|
|
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
|
{
|
|
const uchar *end;
|
|
uint piks=! (keyseg->flag & HA_NO_SORT);
|
|
(*diff_pos)++;
|
|
diff_pos[1]= (uint)(b - orig_b);
|
|
|
|
/* Handle NULL part */
|
|
if (keyseg->null_bit)
|
|
{
|
|
key_length--;
|
|
if (*a != *b && piks)
|
|
{
|
|
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 | SEARCH_INSERT |
|
|
SEARCH_NULL_ARE_EQUAL)) ==
|
|
(SEARCH_FIND | SEARCH_UPDATE | SEARCH_INSERT))
|
|
{
|
|
/* Allow duplicate keys */
|
|
nextflag= (nextflag & ~(SEARCH_FIND | SEARCH_UPDATE)) | SEARCH_SAME;
|
|
}
|
|
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;
|
|
continue; /* To next key part */
|
|
}
|
|
}
|
|
end= a+ MY_MIN(keyseg->length,key_length);
|
|
next_key_length=key_length-keyseg->length;
|
|
|
|
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);
|
|
next_key_length=key_length-b_length-pack_length;
|
|
|
|
if (piks &&
|
|
(flag= ha_compare_char_fixed(keyseg->charset,
|
|
a, a_length,
|
|
b, b_length,
|
|
keyseg->length / keyseg->charset->mbmaxlen,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0))))
|
|
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;
|
|
if (piks &&
|
|
(flag= ha_compare_char_fixed(keyseg->charset,
|
|
a, a_length,
|
|
b, b_length,
|
|
keyseg->length / keyseg->charset->mbmaxlen,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0))))
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
a=end;
|
|
b+=length;
|
|
}
|
|
break;
|
|
case HA_KEYTYPE_BINARY:
|
|
case HA_KEYTYPE_BIT:
|
|
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);
|
|
next_key_length=key_length-b_length-pack_length;
|
|
|
|
if (piks &&
|
|
(flag=compare_bin(a,a_length,b,b_length,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0),1)))
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
a+=a_length;
|
|
b+=b_length;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
uint length=keyseg->length;
|
|
if (piks &&
|
|
(flag=compare_bin(a,length,b,length,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0),0)))
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
a+=length;
|
|
b+=length;
|
|
}
|
|
break;
|
|
case HA_KEYTYPE_VARTEXT1:
|
|
case HA_KEYTYPE_VARTEXT2:
|
|
{
|
|
int a_length,b_length,pack_length;
|
|
get_key_length(a_length,a);
|
|
get_key_pack_length(b_length,pack_length,b);
|
|
next_key_length=key_length-b_length-pack_length;
|
|
|
|
if (piks &&
|
|
(flag= ha_compare_char_varying(keyseg->charset,
|
|
a, a_length,
|
|
b, b_length,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0))))
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
a+= a_length;
|
|
b+= b_length;
|
|
break;
|
|
}
|
|
break;
|
|
case HA_KEYTYPE_VARBINARY1:
|
|
case HA_KEYTYPE_VARBINARY2:
|
|
{
|
|
int a_length,b_length,pack_length;
|
|
get_key_length(a_length,a);
|
|
get_key_pack_length(b_length,pack_length,b);
|
|
next_key_length=key_length-b_length-pack_length;
|
|
|
|
if (piks &&
|
|
(flag=compare_bin(a,a_length,b,b_length,
|
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
next_key_length <= 0), 0)))
|
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
a+=a_length;
|
|
b+=b_length;
|
|
}
|
|
break;
|
|
case HA_KEYTYPE_INT8:
|
|
{
|
|
int i_1= (int) *((signed char*) a);
|
|
int i_2= (int) *((signed char*) b);
|
|
if (piks && (flag = CMP_NUM(i_1,i_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(s_1,s_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(us_1,us_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(u_1,u_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
|
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);
|
|
/*
|
|
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
|
|
*/
|
|
if (piks && (flag = CMP_NUM(f_1,f_2)))
|
|
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);
|
|
/*
|
|
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
|
|
*/
|
|
if (piks && (flag = CMP_NUM(d_1,d_2)))
|
|
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;
|
|
|
|
if (keyseg->flag & HA_REVERSE_SORT)
|
|
{
|
|
swap_variables(const uchar*, a, b);
|
|
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;
|
|
next_key_length=key_length-blength-1;
|
|
}
|
|
else
|
|
{
|
|
alength= (int) (end-a);
|
|
blength=keyseg->length;
|
|
/* remove pre space from keys */
|
|
for ( ; alength && *a == ' ' ; a++, alength--) ;
|
|
for ( ; blength && *b == ' ' ; b++, blength--) ;
|
|
}
|
|
if (piks)
|
|
{
|
|
if (*a == '-')
|
|
{
|
|
if (*b != '-')
|
|
return -1;
|
|
a++; b++;
|
|
swap_variables(const uchar*, a, b);
|
|
swap_variables(int, alength, blength);
|
|
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]);
|
|
}
|
|
else
|
|
{
|
|
b+=(end-a);
|
|
a=end;
|
|
}
|
|
|
|
if (swap_flag) /* Restore pointers */
|
|
swap_variables(const uchar*, a, b);
|
|
break;
|
|
}
|
|
#ifdef HAVE_LONG_LONG
|
|
case HA_KEYTYPE_LONGLONG:
|
|
{
|
|
longlong ll_a,ll_b;
|
|
ll_a= mi_sint8korr(a);
|
|
ll_b= mi_sint8korr(b);
|
|
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
|
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);
|
|
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
|
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))
|
|
{
|
|
/*
|
|
Compare rowid and possible transid
|
|
This happens in the following case:
|
|
- INSERT, UPDATE, DELETE when we have not unique keys or
|
|
are using versioning
|
|
- SEARCH_NEXT, SEARCH_PREVIOUS when we need to restart search
|
|
|
|
The logic for comparing transid are as follows:
|
|
Keys with have a transid have lowest bit in the rowidt. This means that
|
|
if we are comparing a key with a transid with another key that doesn't
|
|
have a tranid, we must reset the lowest bit for both keys.
|
|
|
|
When we have transid, the keys are compared in transid order.
|
|
A key without a transid is regared to be smaller than a key with
|
|
a transid.
|
|
*/
|
|
|
|
uint i;
|
|
uchar key_mask, tmp_a, tmp_b;
|
|
|
|
if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
|
|
return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
|
|
key_mask= (uchar) 255;
|
|
|
|
if (!(nextflag & (SEARCH_USER_KEY_HAS_TRANSID |
|
|
SEARCH_PAGE_KEY_HAS_TRANSID)))
|
|
{
|
|
/*
|
|
Neither key has a trid. Only compare row id's and don't
|
|
try to store rows in trid order
|
|
*/
|
|
key_length= keyseg->length;
|
|
nextflag&= ~SEARCH_INSERT;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
Set key_mask so that we reset the last bit in the rowid before
|
|
we compare it. This is needed as the lowest bit in the rowid is
|
|
used to mark if the key has a transid or not.
|
|
*/
|
|
key_mask= (uchar) 254;
|
|
if (!test_all_bits(nextflag, (SEARCH_USER_KEY_HAS_TRANSID |
|
|
SEARCH_PAGE_KEY_HAS_TRANSID)))
|
|
{
|
|
/*
|
|
No transaction id for user key or for key on page
|
|
Ignore transid as at least one of the keys are visible for all
|
|
*/
|
|
key_length= keyseg->length;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
Both keys have trids. No need of special handling of incomplete
|
|
trids below.
|
|
*/
|
|
nextflag&= ~SEARCH_INSERT;
|
|
}
|
|
}
|
|
DBUG_ASSERT(key_length > 0);
|
|
|
|
for (i= key_length-1 ; (int) i-- > 0 ; )
|
|
{
|
|
if (*a++ != *b++)
|
|
{
|
|
flag= FCMP(a[-1],b[-1]);
|
|
goto found;
|
|
}
|
|
}
|
|
tmp_a= *a & key_mask;
|
|
tmp_b= *b & key_mask;
|
|
flag= FCMP(tmp_a, tmp_b);
|
|
|
|
if (flag == 0 && (nextflag & SEARCH_INSERT))
|
|
{
|
|
/*
|
|
Ensure that on insert we get rows stored in trid order.
|
|
If one of the parts doesn't have a trid, this should be regarded
|
|
as smaller than the other
|
|
*/
|
|
return (nextflag & SEARCH_USER_KEY_HAS_TRANSID) ? -1 : 1;
|
|
}
|
|
found:
|
|
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;
|
|
} /* ha_key_cmp */
|
|
|
|
/*
|
|
Find the first NULL value in index-suffix values tuple
|
|
|
|
SYNOPSIS
|
|
ha_find_null()
|
|
keyseg Array of keyparts for key suffix
|
|
a Key suffix value tuple
|
|
|
|
DESCRIPTION
|
|
Find the first NULL value in index-suffix values tuple.
|
|
|
|
TODO
|
|
Consider optimizing this function or its use so we don't search for
|
|
NULL values in completely NOT NULL index suffixes.
|
|
|
|
RETURN
|
|
First key part that has NULL as value in values tuple, or the last key
|
|
part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain
|
|
NULLs.
|
|
*/
|
|
|
|
HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a)
|
|
{
|
|
for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++)
|
|
{
|
|
const uchar *end;
|
|
if (keyseg->null_bit)
|
|
{
|
|
if (!*a++)
|
|
return keyseg;
|
|
}
|
|
end= a+ keyseg->length;
|
|
|
|
switch ((enum ha_base_keytype) keyseg->type) {
|
|
case HA_KEYTYPE_TEXT:
|
|
case HA_KEYTYPE_BINARY:
|
|
case HA_KEYTYPE_BIT:
|
|
if (keyseg->flag & HA_SPACE_PACK)
|
|
{
|
|
int a_length;
|
|
get_key_length(a_length, a);
|
|
a += a_length;
|
|
break;
|
|
}
|
|
else
|
|
a= end;
|
|
break;
|
|
case HA_KEYTYPE_VARTEXT1:
|
|
case HA_KEYTYPE_VARTEXT2:
|
|
case HA_KEYTYPE_VARBINARY1:
|
|
case HA_KEYTYPE_VARBINARY2:
|
|
{
|
|
int a_length;
|
|
get_key_length(a_length, a);
|
|
a+= a_length;
|
|
break;
|
|
}
|
|
case HA_KEYTYPE_NUM:
|
|
if (keyseg->flag & HA_SPACE_PACK)
|
|
{
|
|
int alength= *a++;
|
|
end= a+alength;
|
|
}
|
|
a= end;
|
|
break;
|
|
case HA_KEYTYPE_INT8:
|
|
case HA_KEYTYPE_SHORT_INT:
|
|
case HA_KEYTYPE_USHORT_INT:
|
|
case HA_KEYTYPE_LONG_INT:
|
|
case HA_KEYTYPE_ULONG_INT:
|
|
case HA_KEYTYPE_INT24:
|
|
case HA_KEYTYPE_UINT24:
|
|
#ifdef HAVE_LONG_LONG
|
|
case HA_KEYTYPE_LONGLONG:
|
|
case HA_KEYTYPE_ULONGLONG:
|
|
#endif
|
|
case HA_KEYTYPE_FLOAT:
|
|
case HA_KEYTYPE_DOUBLE:
|
|
a= end;
|
|
break;
|
|
case HA_KEYTYPE_END: /* purecov: inspected */
|
|
/* keep compiler happy */
|
|
DBUG_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
return keyseg;
|
|
}
|
|
|