Commit e4938933 authored by unknown's avatar unknown
Browse files

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()
parent 2310f00a
Loading
Loading
Loading
Loading
+36 −23
Original line number Diff line number Diff line
@@ -53,6 +53,30 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
/* Identifies generated InnoDB foreign key names */
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. */
static
@@ -2066,7 +2090,7 @@ dict_foreign_find_index(
					break;
				}

				if (0 != ut_cmp_in_lower_case(columns[i],
				if (0 != innobase_strcasecmp(columns[i],
								col_name)) {
				  	break;
				}
@@ -2436,7 +2460,7 @@ dict_scan_col(

			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 */

		    		*success = TRUE;
@@ -2528,30 +2552,19 @@ dict_scan_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);

#ifdef __WIN__
	ut_cpy_in_lower_case(ref, database_name, database_name_len);
#else
	if (srv_lower_case_table_names) {
		ut_cpy_in_lower_case(ref, database_name, database_name_len);
	} else {
	memcpy(ref, database_name, database_name_len);
	}
#endif
	(ref)[database_name_len] = '/';

#ifdef __WIN__
	ut_cpy_in_lower_case(ref + database_name_len + 1,
					table_name, table_name_len + 1);
#else
	ref[database_name_len] = '/';
	memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
#ifndef __WIN__
	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 /* !__WIN__ */
		/* The table name is always put to lower case on Windows. */
		innobase_casedn_str(ref);
#ifndef __WIN__
	}
#endif
#endif /* !__WIN__ */

	*success = TRUE;
	*ref_name = ref;
+0 −19
Original line number Diff line number Diff line
@@ -229,25 +229,6 @@ ut_bit_set_nth(
	ulint	a,	/* in: ulint */
	ulint	n,	/* in: nth bit requested */
	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
#include "ut0byte.ic"
+0 −48
Original line number Diff line number Diff line
@@ -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_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);
}
+35 −12
Original line number Diff line number Diff line
@@ -429,6 +429,36 @@ innobase_mysql_print_thd(
	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. */
extern "C"
@@ -687,14 +717,7 @@ innobase_query_caching_of_table_permitted(
					    separator between db and table */
	norm_name[full_name_len] = '\0';
#ifdef __WIN__
	/* Put to lower case */

	char*	ptr = norm_name;

	while (*ptr != '\0') {
	        *ptr = tolower(*ptr);
	        ptr++;
	}
	innobase_casedn_str(norm_name);
#endif
	/* The call of row_search_.. will start a new transaction if it is
	not yet started */
@@ -3559,9 +3582,9 @@ create_index(

			field = form->field[j];

			if (0 == ut_cmp_in_lower_case(
					(char*)field->field_name,
					(char*)key_part->field->field_name)) {
			if (0 == innobase_strcasecmp(
					field->field_name,
					key_part->field->field_name)) {
				/* Found the corresponding column */

				break;
@@ -4003,7 +4026,7 @@ innobase_drop_database(
	namebuf[len] = '/';
	namebuf[len + 1] = '\0';
#ifdef  __WIN__
	my_casedn_str(system_charset_info, namebuf);
	innobase_casedn_str(namebuf);
#endif
	trx = trx_allocate_for_mysql();
	trx->mysql_thd = current_thd;