mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
BTREE-indexes in HEAP tables can now be used to optimize ORDER BY
Don't read character set files if we are using only the default charset. In most cases the user will not anymore get a warning about missing character set files Compare strings with space extend instead of space strip. Now the following comparisons holds: "a" == "a " and "a\t" < "a". (Bug #3152). Note: Because of the above fix, one has to do a REPAIR on any table that has an ascii character < 32 last in a CHAR/VARCHAR/TEXT columns. heap/hp_hash.c: Comments and DBUG information include/my_handler.h: Updated prototype for mi_compare_text myisam/ft_boolean_search.c: Updated calls to mi_compare_text myisam/ft_nlq_search.c: Updated calls to mi_compare_text myisam/ft_parser.c: Updated calls to mi_compare_text myisam/ft_stopwords.c: Updated calls to mi_compare_text myisam/ft_update.c: Updated calls to mi_compare_text myisam/mi_check.c: Updated calls to mi_compare_text myisam/mi_search.c: Changed all string comparisons that removed end space to instead extend the shorter string with space myisam/mi_unique.c: Updated calls to mi_compare_text myisam/mi_write.c: Updated calls to mi_compare_text myisam/myisam_ftdump.c: Removed compiler warning mysql-test/r/ctype_collate.result: Fixed wrong result mysql-test/r/heap_btree.result: More tests mysql-test/t/heap_btree.test: more tests mysys/charset.c: Don't read charsets if we are only using default charset Don't require 'init_available_charsets' to succeed. mysys/my_handler.c: Compare strings with space extend instead of space strip mysys/tree.c: Fixed code to get better results for range optimzier sql/field.cc: Compare strings with space extend instead of space strip sql/filesort.cc: Compare strings with space extend instead of space strip sql/ha_heap.cc: Created bit map for keys that are using BTREE. This allows the optimzer to use BTREE's for sorting sql/ha_heap.h: Created bit map for keys that are using BTREE. This allows the optimzer to use BTREE's for sorting strings/ctype-big5.c: Compare strings with space extend instead of space strip strings/ctype-czech.c: Indentation cleanup. Should be fixed to use space extend strings/ctype-gbk.c: Compare strings with space extend instead of space strip strings/ctype-latin1.c: Compare strings with space extend instead of space strip Added missing my_hash_sort_latin1_de function strings/ctype-mb.c: For binary strings, don't remove end space when comparing strings/ctype-simple.c: Compare strings with space extend instead of space strip strings/ctype-sjis.c: Compare strings with space extend instead of space strip strings/ctype-tis620.c: Added comments that we should fix end space handling strings/ctype-ucs2.c: indentation fixes strings/ctype-utf8.c: Added comments that we should fix end space handling strings/ctype-win1250ch.c: Added comments that we should fix end space handling
This commit is contained in:
@ -165,169 +165,144 @@ static struct wordvalue doubles[] = {
|
||||
Na konci p<>ipoj<6F>me znak 0
|
||||
*/
|
||||
|
||||
#define ADD_TO_RESULT(dest, len, totlen, value) \
|
||||
if ((totlen) < (len)) { dest[totlen] = value; } (totlen++);
|
||||
|
||||
#define NEXT_CMP_VALUE(src, p, store, pass, value, len) \
|
||||
while (1) /* we will make a loop */ \
|
||||
{ \
|
||||
if (IS_END(p, src, len)) \
|
||||
/* when we are at the end of string */ \
|
||||
{ /* return either 0 for end of string */ \
|
||||
/* or 1 for end of pass */ \
|
||||
if (pass == 3) { value = 0; break; } \
|
||||
if (pass == 0) p = store; \
|
||||
else p = src; \
|
||||
value = 1; pass++; break; \
|
||||
} \
|
||||
/* not at end of string */ \
|
||||
value = CZ_SORT_TABLE[pass][*p]; \
|
||||
\
|
||||
if (value == 0) { p++; continue; } /* ignore value */ \
|
||||
if (value == 2) /* space */ \
|
||||
{ \
|
||||
const uchar * tmp; \
|
||||
const uchar * runner = ++p; \
|
||||
while (!(IS_END(runner, src, len)) && (CZ_SORT_TABLE[pass][*runner] == 2)) \
|
||||
runner++; /* skip all spaces */ \
|
||||
if (IS_END(runner, src, len) && SKIP_TRAILING_SPACES) \
|
||||
p = runner; \
|
||||
if ((pass <= 2) && !(IS_END(runner, src, len))) \
|
||||
p = runner; \
|
||||
if (IS_END(p, src, len)) \
|
||||
continue; \
|
||||
/* we switch passes */ \
|
||||
if (pass > 1) \
|
||||
break; \
|
||||
tmp = p; \
|
||||
if (pass == 0) pass = 1; \
|
||||
else pass = 0; \
|
||||
p = store; store = tmp; \
|
||||
break; \
|
||||
} \
|
||||
if (value == 255) \
|
||||
{ \
|
||||
int i; \
|
||||
for (i = 0; i < (int) sizeof(doubles); i++) \
|
||||
{ \
|
||||
const char * pattern = doubles[i].word; \
|
||||
const char * q = (const char *) p; \
|
||||
int j = 0; \
|
||||
while (pattern[j]) \
|
||||
{ \
|
||||
if (IS_END(q, src, len) || (*q != pattern[j])) \
|
||||
{ break ; } \
|
||||
j++; q++; \
|
||||
} \
|
||||
if (!(pattern[j])) \
|
||||
{ \
|
||||
value = (int)(doubles[i].outvalue[pass]); \
|
||||
p = (const uchar *) q - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
p++; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define IS_END(p, src, len) (!(*p))
|
||||
|
||||
#if 0
|
||||
/* Function strcoll, with Czech sorting, for zero terminated strings */
|
||||
static int my_strcoll_czech(const uchar * s1, const uchar * s2)
|
||||
{
|
||||
int v1, v2;
|
||||
const uchar * p1, * p2, * store1, * store2;
|
||||
int pass1 = 0, pass2 = 0;
|
||||
int diff;
|
||||
|
||||
p1 = s1; p2 = s2;
|
||||
store1 = s1; store2 = s2;
|
||||
|
||||
do
|
||||
{
|
||||
NEXT_CMP_VALUE(s1, p1, store1, pass1, v1, 0);
|
||||
NEXT_CMP_VALUE(s2, p2, store2, pass2, v2, 0);
|
||||
diff = v1 - v2;
|
||||
if (diff != 0) return diff;
|
||||
}
|
||||
while (v1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Function strxfrm, with Czech sorting, for zero terminated strings */
|
||||
static int my_strxfrm_czech(uchar * dest, const uchar * src, int len)
|
||||
{
|
||||
int value;
|
||||
const uchar * p, * store;
|
||||
int pass = 0;
|
||||
int totlen = 0;
|
||||
p = store = src;
|
||||
|
||||
do
|
||||
{
|
||||
NEXT_CMP_VALUE(src, p, store, pass, value, 0);
|
||||
ADD_TO_RESULT(dest, len, totlen, value);
|
||||
}
|
||||
while (value);
|
||||
return totlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef IS_END
|
||||
|
||||
#define ADD_TO_RESULT(dest, len, totlen, value) \
|
||||
if ((totlen) < (len)) { dest[totlen] = value; } (totlen++);
|
||||
#define IS_END(p, src, len) (((char *)p - (char *)src) >= (len))
|
||||
|
||||
/* Function strnncoll, actually strcoll, with Czech sorting, which expect
|
||||
the length of the strings being specified */
|
||||
#define NEXT_CMP_VALUE(src, p, store, pass, value, len) \
|
||||
while (1) \
|
||||
{ \
|
||||
if (IS_END(p, src, len)) \
|
||||
{ \
|
||||
/* when we are at the end of string */ \
|
||||
/* return either 0 for end of string */ \
|
||||
/* or 1 for end of pass */ \
|
||||
value= 0; \
|
||||
if (pass != 3) \
|
||||
{ \
|
||||
p= (pass++ == 0) ? store : src; \
|
||||
value = 1; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
/* not at end of string */ \
|
||||
value = CZ_SORT_TABLE[pass][*p]; \
|
||||
if (value == 0) \
|
||||
{ p++; continue; } /* ignore value */ \
|
||||
if (value == 2) /* space */ \
|
||||
{ \
|
||||
const uchar * tmp; \
|
||||
const uchar * runner = ++p; \
|
||||
while (!(IS_END(runner, src, len)) && (CZ_SORT_TABLE[pass][*runner] == 2)) \
|
||||
runner++; /* skip all spaces */ \
|
||||
if (IS_END(runner, src, len) && SKIP_TRAILING_SPACES) \
|
||||
p = runner; \
|
||||
if ((pass <= 2) && !(IS_END(runner, src, len))) \
|
||||
p = runner; \
|
||||
if (IS_END(p, src, len)) \
|
||||
continue; \
|
||||
/* we switch passes */ \
|
||||
if (pass > 1) \
|
||||
break; \
|
||||
tmp = p; \
|
||||
pass= 1-pass; \
|
||||
p = store; store = tmp; \
|
||||
break; \
|
||||
} \
|
||||
if (value == 255) \
|
||||
{ \
|
||||
int i; \
|
||||
for (i = 0; i < (int) sizeof(doubles); i++) \
|
||||
{ \
|
||||
const char * pattern = doubles[i].word; \
|
||||
const char * q = (const char *) p; \
|
||||
int j = 0; \
|
||||
while (pattern[j]) \
|
||||
{ \
|
||||
if (IS_END(q, src, len) || (*q != pattern[j])) \
|
||||
break; \
|
||||
j++; q++; \
|
||||
} \
|
||||
if (!(pattern[j])) \
|
||||
{ \
|
||||
value = (int)(doubles[i].outvalue[pass]); \
|
||||
p= (const uchar *) q - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
p++; \
|
||||
break; \
|
||||
}
|
||||
|
||||
/*
|
||||
Function strnncoll, actually strcoll, with Czech sorting, which expect
|
||||
the length of the strings being specified
|
||||
*/
|
||||
|
||||
static int my_strnncoll_czech(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar * s1, uint len1,
|
||||
const uchar * s2, uint len2)
|
||||
{
|
||||
int v1, v2;
|
||||
const uchar * p1, * p2, * store1, * store2;
|
||||
int pass1 = 0, pass2 = 0;
|
||||
int diff;
|
||||
const uchar * s1, uint len1,
|
||||
const uchar * s2, uint len2)
|
||||
{
|
||||
int v1, v2;
|
||||
const uchar * p1, * p2, * store1, * store2;
|
||||
int pass1 = 0, pass2 = 0;
|
||||
|
||||
p1 = s1; p2 = s2;
|
||||
store1 = s1; store2 = s2;
|
||||
p1 = s1; p2 = s2;
|
||||
store1 = s1; store2 = s2;
|
||||
|
||||
do
|
||||
{
|
||||
NEXT_CMP_VALUE(s1, p1, store1, pass1, v1, (int)len1);
|
||||
NEXT_CMP_VALUE(s2, p2, store2, pass2, v2, (int)len2);
|
||||
diff = v1 - v2;
|
||||
do
|
||||
{
|
||||
int diff;
|
||||
NEXT_CMP_VALUE(s1, p1, store1, pass1, v1, (int)len1);
|
||||
NEXT_CMP_VALUE(s2, p2, store2, pass2, v2, (int)len2);
|
||||
if ((diff = v1 - v2))
|
||||
return diff;
|
||||
}
|
||||
while (v1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (diff != 0) return diff;
|
||||
}
|
||||
while (v1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function strnxfrm, actually strxfrm, with Czech sorting, which expect
|
||||
the length of the strings being specified */
|
||||
|
||||
/*
|
||||
TODO: Fix this one to compare strings as they are done in ctype-simple1
|
||||
*/
|
||||
|
||||
static
|
||||
int my_strnncollsp_czech(CHARSET_INFO * cs,
|
||||
const uchar *s, uint slen,
|
||||
const uchar *t, uint tlen)
|
||||
{
|
||||
for ( ; slen && s[slen-1] == ' ' ; slen--);
|
||||
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
|
||||
return my_strnncoll_czech(cs,s,slen,t,tlen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Function strnxfrm, actually strxfrm, with Czech sorting, which expect
|
||||
the length of the strings being specified
|
||||
*/
|
||||
|
||||
static int my_strnxfrm_czech(CHARSET_INFO *cs __attribute__((unused)),
|
||||
uchar * dest, uint len,
|
||||
const uchar * src, uint srclen)
|
||||
{
|
||||
int value;
|
||||
const uchar * p, * store;
|
||||
int pass = 0;
|
||||
int totlen = 0;
|
||||
p = src; store = src;
|
||||
uchar * dest, uint len,
|
||||
const uchar * src, uint srclen)
|
||||
{
|
||||
int value;
|
||||
const uchar * p, * store;
|
||||
int pass = 0;
|
||||
int totlen = 0;
|
||||
p = src; store = src;
|
||||
|
||||
do
|
||||
{
|
||||
NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen);
|
||||
ADD_TO_RESULT(dest, (int)len, totlen, value);
|
||||
}
|
||||
while (value);
|
||||
return totlen;
|
||||
}
|
||||
do
|
||||
{
|
||||
NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen);
|
||||
ADD_TO_RESULT(dest, (int)len, totlen, value);
|
||||
}
|
||||
while (value);
|
||||
return totlen;
|
||||
}
|
||||
|
||||
#undef IS_END
|
||||
|
||||
@ -595,16 +570,6 @@ static MY_UNI_IDX idx_uni_8859_2[]={
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
int my_strnncollsp_czech(CHARSET_INFO * cs,
|
||||
const uchar *s, uint slen,
|
||||
const uchar *t, uint tlen)
|
||||
{
|
||||
for ( ; slen && s[slen-1] == ' ' ; slen--);
|
||||
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
|
||||
return my_strnncoll_czech(cs,s,slen,t,tlen);
|
||||
}
|
||||
|
||||
static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler =
|
||||
{
|
||||
my_strnncoll_czech,
|
||||
|
Reference in New Issue
Block a user