mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
InnoDB: Treat UTF-8 strings properly in case insensitive operations
innobase/dict/dict0dict.c: Use innobase_strcasecmp() and innobase_casedn_str() instead of ut_cmp_in_lower_case() and ut_cpy_in_lower_case() innobase/include/ut0byte.h: Remove ut_cpy_in_lower_case() and ut_cmp_in_lower_case() innobase/ut/ut0byte.c: Remove ut_cpy_in_lower_case() and ut_cmp_in_lower_case() sql/ha_innodb.cc: Add innobase_strcasecmp() and innobase_casedn_str() Replace tolower() loop with innobase_casedn_str() Replace my_casedn_str() with innobase_casedn_str() Replace ut_cmp_in_lower_case() with innobase_strcasecmp()
This commit is contained in:
@ -53,6 +53,30 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
|
|||||||
/* Identifies generated InnoDB foreign key names */
|
/* Identifies generated InnoDB foreign key names */
|
||||||
static char dict_ibfk[] = "_ibfk_";
|
static char dict_ibfk[] = "_ibfk_";
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Compares NUL-terminated UTF-8 strings case insensitively.
|
||||||
|
|
||||||
|
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||||
|
this function, you MUST change also the prototype here! */
|
||||||
|
extern
|
||||||
|
int
|
||||||
|
innobase_strcasecmp(
|
||||||
|
/*================*/
|
||||||
|
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
|
||||||
|
const char* a, /* in: first string to compare */
|
||||||
|
const char* b); /* in: second string to compare */
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Makes all characters in a NUL-terminated UTF-8 string lower case.
|
||||||
|
|
||||||
|
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||||
|
this function, you MUST change also the prototype here! */
|
||||||
|
extern
|
||||||
|
void
|
||||||
|
innobase_casedn_str(
|
||||||
|
/*================*/
|
||||||
|
char* a); /* in/out: string to put in lower case */
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Adds a column to the data dictionary hash table. */
|
Adds a column to the data dictionary hash table. */
|
||||||
static
|
static
|
||||||
@ -2066,7 +2090,7 @@ dict_foreign_find_index(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != ut_cmp_in_lower_case(columns[i],
|
if (0 != innobase_strcasecmp(columns[i],
|
||||||
col_name)) {
|
col_name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2436,7 +2460,7 @@ dict_scan_col(
|
|||||||
|
|
||||||
col = dict_table_get_nth_col(table, i);
|
col = dict_table_get_nth_col(table, i);
|
||||||
|
|
||||||
if (0 == ut_cmp_in_lower_case(col->name, *name)) {
|
if (0 == innobase_strcasecmp(col->name, *name)) {
|
||||||
/* Found */
|
/* Found */
|
||||||
|
|
||||||
*success = TRUE;
|
*success = TRUE;
|
||||||
@ -2528,30 +2552,19 @@ dict_scan_table_name(
|
|||||||
|
|
||||||
table_name_len = strlen(table_name);
|
table_name_len = strlen(table_name);
|
||||||
|
|
||||||
|
/* Copy database_name, '/', table_name, '\0' */
|
||||||
ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2);
|
ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2);
|
||||||
|
memcpy(ref, database_name, database_name_len);
|
||||||
#ifdef __WIN__
|
ref[database_name_len] = '/';
|
||||||
ut_cpy_in_lower_case(ref, database_name, database_name_len);
|
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
||||||
#else
|
#ifndef __WIN__
|
||||||
if (srv_lower_case_table_names) {
|
if (srv_lower_case_table_names) {
|
||||||
ut_cpy_in_lower_case(ref, database_name, database_name_len);
|
#endif /* !__WIN__ */
|
||||||
} else {
|
/* The table name is always put to lower case on Windows. */
|
||||||
memcpy(ref, database_name, database_name_len);
|
innobase_casedn_str(ref);
|
||||||
|
#ifndef __WIN__
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* !__WIN__ */
|
||||||
(ref)[database_name_len] = '/';
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
|
||||||
ut_cpy_in_lower_case(ref + database_name_len + 1,
|
|
||||||
table_name, table_name_len + 1);
|
|
||||||
#else
|
|
||||||
if (srv_lower_case_table_names) {
|
|
||||||
ut_cpy_in_lower_case(ref + database_name_len + 1,
|
|
||||||
table_name, table_name_len + 1);
|
|
||||||
} else {
|
|
||||||
strcpy(ref + database_name_len + 1, table_name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*success = TRUE;
|
*success = TRUE;
|
||||||
*ref_name = ref;
|
*ref_name = ref;
|
||||||
|
@ -229,25 +229,6 @@ ut_bit_set_nth(
|
|||||||
ulint a, /* in: ulint */
|
ulint a, /* in: ulint */
|
||||||
ulint n, /* in: nth bit requested */
|
ulint n, /* in: nth bit requested */
|
||||||
ibool val); /* in: value for the bit to set */
|
ibool val); /* in: value for the bit to set */
|
||||||
/****************************************************************
|
|
||||||
Copies a string to a memory location, setting characters to lower case. */
|
|
||||||
|
|
||||||
void
|
|
||||||
ut_cpy_in_lower_case(
|
|
||||||
/*=================*/
|
|
||||||
char* dest, /* in: destination */
|
|
||||||
const char* source, /* in: source */
|
|
||||||
ulint len); /* in: string length */
|
|
||||||
/****************************************************************
|
|
||||||
Compares two strings when converted to lower case. */
|
|
||||||
|
|
||||||
int
|
|
||||||
ut_cmp_in_lower_case(
|
|
||||||
/*=================*/
|
|
||||||
/* out: -1, 0, 1 if str1 < str2, str1 == str2,
|
|
||||||
str1 > str2, respectively */
|
|
||||||
const char* str1, /* in: string1 */
|
|
||||||
const char* str2); /* in: string2 */
|
|
||||||
|
|
||||||
#ifndef UNIV_NONINL
|
#ifndef UNIV_NONINL
|
||||||
#include "ut0byte.ic"
|
#include "ut0byte.ic"
|
||||||
|
@ -29,51 +29,3 @@ ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high)
|
|||||||
UT_SORT_FUNCTION_BODY(ut_dulint_sort, arr, aux_arr, low, high,
|
UT_SORT_FUNCTION_BODY(ut_dulint_sort, arr, aux_arr, low, high,
|
||||||
ut_dulint_cmp);
|
ut_dulint_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Copies a string to a memory location, setting characters to lower case. */
|
|
||||||
|
|
||||||
void
|
|
||||||
ut_cpy_in_lower_case(
|
|
||||||
/*=================*/
|
|
||||||
char* dest, /* in: destination */
|
|
||||||
const char* source, /* in: source */
|
|
||||||
ulint len) /* in: string length */
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
dest[i] = tolower(source[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Compares two strings when converted to lower case. */
|
|
||||||
|
|
||||||
int
|
|
||||||
ut_cmp_in_lower_case(
|
|
||||||
/*=================*/
|
|
||||||
/* out: -1, 0, 1 if str1 < str2, str1 == str2,
|
|
||||||
str1 > str2, respectively */
|
|
||||||
const char* str1, /* in: string1 */
|
|
||||||
const char* str2) /* in: string2 */
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
int c1, c2;
|
|
||||||
if (!*str1) {
|
|
||||||
return(*str2 ? -1 : 0);
|
|
||||||
} else if (!*str2) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
c1 = tolower(*str1++);
|
|
||||||
c2 = tolower(*str2++);
|
|
||||||
if (c1 < c2) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
if (c1 > c2) {
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
@ -429,6 +429,36 @@ innobase_mysql_print_thd(
|
|||||||
putc('\n', f);
|
putc('\n', f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Compares NUL-terminated UTF-8 strings case insensitively.
|
||||||
|
|
||||||
|
NOTE that the exact prototype of this function has to be in
|
||||||
|
/innobase/dict/dict0dict.c! */
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
innobase_strcasecmp(
|
||||||
|
/*================*/
|
||||||
|
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
|
||||||
|
const char* a, /* in: first string to compare */
|
||||||
|
const char* b) /* in: second string to compare */
|
||||||
|
{
|
||||||
|
return(my_strcasecmp(system_charset_info, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Makes all characters in a NUL-terminated UTF-8 string lower case.
|
||||||
|
|
||||||
|
NOTE that the exact prototype of this function has to be in
|
||||||
|
/innobase/dict/dict0dict.c! */
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
innobase_casedn_str(
|
||||||
|
/*================*/
|
||||||
|
char* a) /* in/out: string to put in lower case */
|
||||||
|
{
|
||||||
|
my_casedn_str(system_charset_info, a);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates a temporary file. */
|
Creates a temporary file. */
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -687,14 +717,7 @@ innobase_query_caching_of_table_permitted(
|
|||||||
separator between db and table */
|
separator between db and table */
|
||||||
norm_name[full_name_len] = '\0';
|
norm_name[full_name_len] = '\0';
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
/* Put to lower case */
|
innobase_casedn_str(norm_name);
|
||||||
|
|
||||||
char* ptr = norm_name;
|
|
||||||
|
|
||||||
while (*ptr != '\0') {
|
|
||||||
*ptr = tolower(*ptr);
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
/* The call of row_search_.. will start a new transaction if it is
|
/* The call of row_search_.. will start a new transaction if it is
|
||||||
not yet started */
|
not yet started */
|
||||||
@ -3559,9 +3582,9 @@ create_index(
|
|||||||
|
|
||||||
field = form->field[j];
|
field = form->field[j];
|
||||||
|
|
||||||
if (0 == ut_cmp_in_lower_case(
|
if (0 == innobase_strcasecmp(
|
||||||
(char*)field->field_name,
|
field->field_name,
|
||||||
(char*)key_part->field->field_name)) {
|
key_part->field->field_name)) {
|
||||||
/* Found the corresponding column */
|
/* Found the corresponding column */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -4003,7 +4026,7 @@ innobase_drop_database(
|
|||||||
namebuf[len] = '/';
|
namebuf[len] = '/';
|
||||||
namebuf[len + 1] = '\0';
|
namebuf[len + 1] = '\0';
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
my_casedn_str(system_charset_info, namebuf);
|
innobase_casedn_str(namebuf);
|
||||||
#endif
|
#endif
|
||||||
trx = trx_allocate_for_mysql();
|
trx = trx_allocate_for_mysql();
|
||||||
trx->mysql_thd = current_thd;
|
trx->mysql_thd = current_thd;
|
||||||
|
Reference in New Issue
Block a user