Commit 1877521f authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mashka.mysql.fi:/home/my/mysql-4.1
parents cdaf7fcb 4bed5784
...@@ -12,6 +12,13 @@ Created 1/16/1996 Heikki Tuuri ...@@ -12,6 +12,13 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic" #include "data0type.ic"
#endif #endif
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
column definitions, or records in the insert buffer, we use this
charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999;
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0}; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0};
dtype_t* dtype_binary = &dtype_binary_val; dtype_t* dtype_binary = &dtype_binary_val;
......
...@@ -1315,7 +1315,7 @@ dict_create_add_foreigns_to_dictionary( ...@@ -1315,7 +1315,7 @@ dict_create_add_foreigns_to_dictionary(
if (error == DB_DUPLICATE_KEY) { if (error == DB_DUPLICATE_KEY) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
ut_sprintf_timestamp(dict_foreign_err_buf); ut_sprintf_timestamp(ebuf);
sprintf(ebuf + strlen(ebuf), sprintf(ebuf + strlen(ebuf),
" Error in foreign key constraint creation for table %.500s.\n" " Error in foreign key constraint creation for table %.500s.\n"
"A foreign key constraint of name %.500s\n" "A foreign key constraint of name %.500s\n"
......
...@@ -360,6 +360,15 @@ dict_load_columns( ...@@ -360,6 +360,15 @@ dict_load_columns(
field = rec_get_nth_field(rec, 6, &len); field = rec_get_nth_field(rec, 6, &len);
prtype = mach_read_from_4(field); prtype = mach_read_from_4(field);
if (dtype_is_non_binary_string_type(mtype, prtype)
&& dtype_get_charset_coll(prtype) == 0) {
/* This is a non-binary string type, and the table
was created with < 4.1.2. Use the default charset. */
prtype = dtype_form_prtype(prtype,
data_mysql_default_charset_coll);
}
field = rec_get_nth_field(rec, 7, &len); field = rec_get_nth_field(rec, 7, &len);
col_len = mach_read_from_4(field); col_len = mach_read_from_4(field);
......
...@@ -11,6 +11,8 @@ Created 1/16/1996 Heikki Tuuri ...@@ -11,6 +11,8 @@ Created 1/16/1996 Heikki Tuuri
#include "univ.i" #include "univ.i"
extern ulint data_mysql_default_charset_coll;
/* SQL data type struct */ /* SQL data type struct */
typedef struct dtype_struct dtype_t; typedef struct dtype_struct dtype_t;
...@@ -18,31 +20,62 @@ typedef struct dtype_struct dtype_t; ...@@ -18,31 +20,62 @@ typedef struct dtype_struct dtype_t;
data type */ data type */
extern dtype_t* dtype_binary; extern dtype_t* dtype_binary;
/* Data main types of SQL data */ /*-------------------------------------------*/
#define DATA_VARCHAR 1 /* character varying */ /* The 'MAIN TYPE' of a column */
#define DATA_CHAR 2 /* fixed length character */ #define DATA_VARCHAR 1 /* character varying of the
latin1_swedish_ci charset-collation */
#define DATA_CHAR 2 /* fixed length character of the
latin1_swedish_ci charset-collation */
#define DATA_FIXBINARY 3 /* binary string of fixed length */ #define DATA_FIXBINARY 3 /* binary string of fixed length */
#define DATA_BINARY 4 /* binary string */ #define DATA_BINARY 4 /* binary string */
#define DATA_BLOB 5 /* binary large object, or a TEXT type; if #define DATA_BLOB 5 /* binary large object, or a TEXT type;
prtype & DATA_NONLATIN1 != 0 the data must if prtype & DATA_BINARY_TYPE == 0, then this is
be compared by MySQL as a whole field; if actually a TEXT column; see also below about
prtype & DATA_BINARY_TYPE == 0, then this is the flag DATA_NONLATIN1 */
actually a TEXT column */
#define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */ #define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */
#define DATA_SYS_CHILD 7 /* address of the child page in node pointer */ #define DATA_SYS_CHILD 7 /* address of the child page in node pointer */
#define DATA_SYS 8 /* system column */ #define DATA_SYS 8 /* system column */
/* Data types >= DATA_FLOAT must be compared using the whole field, not as /* Data types >= DATA_FLOAT must be compared using the whole field, not as
binary strings */ binary strings */
#define DATA_FLOAT 9 #define DATA_FLOAT 9
#define DATA_DOUBLE 10 #define DATA_DOUBLE 10
#define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */ #define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */
#define DATA_VARMYSQL 12 /* non-latin1 varying length char */ #define DATA_VARMYSQL 12 /* any charset varying length char */
#define DATA_MYSQL 13 /* non-latin1 fixed length char */ #define DATA_MYSQL 13 /* any charset fixed length char */
/* NOTE that 4.1.1 used DATA_MYSQL and
DATA_VARMYSQL for all character sets, and the
charset-collation for tables created with it
can also be latin1_swedish_ci */
#define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size() #define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size()
requires the values are <= 63 */ requires the values are <= 63 */
/*-------------------------------------------*/ /*-------------------------------------------*/
/* In the lowest byte in the precise type we store the MySQL type code /* The 'PRECISE TYPE' of a column */
(not applicable for system columns). */ /*
Tables created by a MySQL user have the following convention:
- In the least significant byte in the precise type we store the MySQL type
code (not applicable for system columns).
- In the second least significant byte we OR flags DATA_NOT_NULL,
DATA_UNSIGNED, DATA_BINARY_TYPE, DATA_NONLATIN1.
- In the third least significant byte of the precise type of string types we
store the MySQL charset-collation code. In DATA_BLOB columns created with
< 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there
are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no
problem, though.
Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the
precise type, since the charset was always the default charset of the MySQL
installation. If the stored charset code is 0 in the system table SYS_COLUMNS
of InnoDB, that means that the default charset of this MySQL installation
should be used.
InnoDB's own internal system tables have different precise types for their
columns, and for them the precise type is usually not used at all.
*/
#define DATA_ENGLISH 4 /* English language character string: this #define DATA_ENGLISH 4 /* English language character string: this
is a relic from pre-MySQL time and only used is a relic from pre-MySQL time and only used
...@@ -69,7 +102,7 @@ be less than 256 */ ...@@ -69,7 +102,7 @@ be less than 256 */
#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a #define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
compressed dulint form) */ compressed dulint form) */
#define DATA_N_SYS_COLS 4 /* number of system columns defined above */ #define DATA_N_SYS_COLS 4 /* number of system columns defined above */
/*-------------------------------------------*/
/* Flags ORed to the precise data type */ /* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when #define DATA_NOT_NULL 256 /* this is ORed to the precise type when
the column is declared as NOT NULL */ the column is declared as NOT NULL */
...@@ -79,19 +112,57 @@ be less than 256 */ ...@@ -79,19 +112,57 @@ be less than 256 */
string, this is ORed to the precise type: string, this is ORed to the precise type:
this only holds for tables created with this only holds for tables created with
>= MySQL-4.0.14 */ >= MySQL-4.0.14 */
#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually #define DATA_NONLATIN1 2048 /* If the data type is DATA_BLOB with
TEXT) of a non-latin1 type, this is ORed to the prtype & DATA_BINARY_TYPE == 0, that is,
the precise type: this only holds for tables TEXT, then in versions 4.0.14 - 4.0.xx this
created with >= MySQL-4.0.14 */ flag is set to 1, if the charset is not
latin1. In version 4.1.1 this was set
to 1 for all TEXT columns. In versions >= 4.1.2
this is set to 1 if the charset-collation of a
TEXT column is not latin1_swedish_ci. */
/*-------------------------------------------*/ /*-------------------------------------------*/
/* This many bytes we need to store the type information affecting the /* This many bytes we need to store the type information affecting the
alphabetical order for a single field and decide the storage size of an alphabetical order for a single field and decide the storage size of an
SQL null*/ SQL null*/
#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4 #define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
/* In the >= 4.1.x storage format we need 2 bytes more for the charset */ /* In the >= 4.1.x storage format we add 2 bytes more so that we can also
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
UNIV_INLINE
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
/*************************************************************************
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/*************************************************************************
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/************************************************************************* /*************************************************************************
Sets a data type structure. */ Sets a data type structure. */
UNIV_INLINE UNIV_INLINE
...@@ -126,6 +197,22 @@ dtype_get_prtype( ...@@ -126,6 +197,22 @@ dtype_get_prtype(
/*=============*/ /*=============*/
dtype_t* type); dtype_t* type);
/************************************************************************* /*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
ulint prtype);/* in: precise data type */
/*************************************************************************
Forms a precise type from the < 4.1.2 format precise type plus the
charset-collation code. */
ulint
dtype_form_prtype(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
DATA_NONLATIN1 etc. */
ulint charset_coll); /* in: MySQL charset-collation code */
/*************************************************************************
Gets the type length. */ Gets the type length. */
UNIV_INLINE UNIV_INLINE
ulint ulint
...@@ -225,9 +312,8 @@ dtype_print( ...@@ -225,9 +312,8 @@ dtype_print(
struct dtype_struct{ struct dtype_struct{
ulint mtype; /* main data type */ ulint mtype; /* main data type */
ulint prtype; /* precise type; MySQL data type */ ulint prtype; /* precise type; MySQL data type */
ulint chrset; /* MySQL character set code */
/* remaining two fields do not affect alphabetical ordering: */ /* the remaining two fields do not affect alphabetical ordering: */
ulint len; /* length */ ulint len; /* length */
ulint prec; /* precision */ ulint prec; /* precision */
......
...@@ -8,6 +8,70 @@ Created 1/16/1996 Heikki Tuuri ...@@ -8,6 +8,70 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h" #include "mach0data.h"
/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
{
if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL
|| mtype == DATA_VARMYSQL) {
return(TRUE);
}
return(FALSE);
}
/*************************************************************************
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
{
if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY)
|| (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) {
return(TRUE);
}
return(FALSE);
}
/*************************************************************************
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
{
if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
return(TRUE);
}
return(FALSE);
}
/************************************************************************* /*************************************************************************
Sets a data type structure. */ Sets a data type structure. */
UNIV_INLINE UNIV_INLINE
...@@ -27,7 +91,6 @@ dtype_set( ...@@ -27,7 +91,6 @@ dtype_set(
type->prtype = prtype; type->prtype = prtype;
type->len = len; type->len = len;
type->prec = prec; type->prec = prec;
type->chrset = 0;
ut_ad(dtype_validate(type)); ut_ad(dtype_validate(type));
} }
...@@ -72,6 +135,33 @@ dtype_get_prtype( ...@@ -72,6 +135,33 @@ dtype_get_prtype(
return(type->prtype); return(type->prtype);
} }
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
ulint prtype) /* in: precise data type */
{
return((prtype >> 16) & 0xFF);
}
/*************************************************************************
Forms a precise type from the < 4.1.2 format precise type plus the
charset-collation code. */
ulint
dtype_form_prtype(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
DATA_NONLATIN1 etc. */
ulint charset_coll) /* in: MySQL charset-collation code */
{
ut_a(old_prtype < 256 * 256);
ut_a(charset_coll < 256);
return(old_prtype + (charset_coll << 16));
}
/************************************************************************* /*************************************************************************
Gets the type length. */ Gets the type length. */
UNIV_INLINE UNIV_INLINE
...@@ -155,12 +245,16 @@ dtype_new_store_for_order_and_null_size( ...@@ -155,12 +245,16 @@ dtype_new_store_for_order_and_null_size(
mach_write_to_2(buf + 2, type->len & 0xFFFFUL); mach_write_to_2(buf + 2, type->len & 0xFFFFUL);
mach_write_to_2(buf + 4, type->chrset & 0xFFFFUL); mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
/* Note that the second last byte is left unused, because the
charset-collation code is always < 256 */
} }
/************************************************************************** /**************************************************************************
Reads to a type the stored information which determines its alphabetical Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */ ordering and the storage size of an SQL NULL value. This is the < 4.1.x
storage format. */
UNIV_INLINE UNIV_INLINE
void void
dtype_read_for_order_and_null_size( dtype_read_for_order_and_null_size(
...@@ -182,12 +276,15 @@ dtype_read_for_order_and_null_size( ...@@ -182,12 +276,15 @@ dtype_read_for_order_and_null_size(
} }
type->len = mach_read_from_2(buf + 2); type->len = mach_read_from_2(buf + 2);
type->prtype = dtype_form_prtype(type->prtype,
data_mysql_default_charset_coll);
} }
/************************************************************************** /**************************************************************************
Reads to a type the stored information which determines its alphabetical Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
format. */ storage format. */
UNIV_INLINE UNIV_INLINE
void void
dtype_new_read_for_order_and_null_size( dtype_new_read_for_order_and_null_size(
...@@ -195,6 +292,8 @@ dtype_new_read_for_order_and_null_size( ...@@ -195,6 +292,8 @@ dtype_new_read_for_order_and_null_size(
dtype_t* type, /* in: type struct */ dtype_t* type, /* in: type struct */
byte* buf) /* in: buffer for stored type order info */ byte* buf) /* in: buffer for stored type order info */
{ {
ulint charset_coll;
ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
type->mtype = buf[0] & 63; type->mtype = buf[0] & 63;
...@@ -210,7 +309,25 @@ dtype_new_read_for_order_and_null_size( ...@@ -210,7 +309,25 @@ dtype_new_read_for_order_and_null_size(
type->len = mach_read_from_2(buf + 2); type->len = mach_read_from_2(buf + 2);
type->chrset = mach_read_from_2(buf + 4); mach_read_from_2(buf + 4);
charset_coll = mach_read_from_2(buf + 4);
if (dtype_is_string_type(type->mtype)) {
ut_a(charset_coll < 256);
if (charset_coll == 0) {
/* This insert buffer record was inserted with MySQL
version < 4.1.2, and the charset-collation code was not
explicitly stored to dtype->prtype at that time. It
must be the default charset-collation of this MySQL
installation. */
charset_coll = data_mysql_default_charset_coll;
}
type->prtype = dtype_form_prtype(type->prtype, charset_coll);
}
} }
/*************************************************************************** /***************************************************************************
......
...@@ -65,6 +65,7 @@ innobase_mysql_cmp( ...@@ -65,6 +65,7 @@ innobase_mysql_cmp(
/* out: 1, 0, -1, if a is greater, /* out: 1, 0, -1, if a is greater,
equal, less than b, respectively */ equal, less than b, respectively */
int mysql_type, /* in: MySQL type */ int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* a, /* in: data field */ unsigned char* a, /* in: data field */
unsigned int a_length, /* in: data field length, unsigned int a_length, /* in: data field length,
not UNIV_SQL_NULL */ not UNIV_SQL_NULL */
...@@ -97,12 +98,24 @@ cmp_types_are_equal( ...@@ -97,12 +98,24 @@ cmp_types_are_equal(
dtype_t* type1, /* in: type 1 */ dtype_t* type1, /* in: type 1 */
dtype_t* type2) /* in: type 2 */ dtype_t* type2) /* in: type 2 */
{ {
if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR) if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
|| (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR) && dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
|| (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY)
|| (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY) /* Both are non-binary string types: they can be compared if
|| (type1->mtype == DATA_MYSQL && type2->mtype == DATA_VARMYSQL) and only if the charset-collation is the same */
|| (type1->mtype == DATA_VARMYSQL && type2->mtype == DATA_MYSQL)) {
if (dtype_get_charset_coll(type1->prtype)
== dtype_get_charset_coll(type2->prtype)) {
return(TRUE);
}
return(FALSE);
}
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
&& dtype_is_binary_string_type(type2->mtype, type2->prtype)) {
/* Both are binary string types: they can be compared */
return(TRUE); return(TRUE);
} }
...@@ -128,11 +141,6 @@ cmp_types_are_equal( ...@@ -128,11 +141,6 @@ cmp_types_are_equal(
return(FALSE); return(FALSE);
} }
if (type1->mtype == DATA_BLOB && (type1->prtype & DATA_BINARY_TYPE)
!= (type2->prtype & DATA_BINARY_TYPE)) {
return(FALSE);
}
return(TRUE); return(TRUE);
} }
...@@ -269,6 +277,7 @@ cmp_whole_field( ...@@ -269,6 +277,7 @@ cmp_whole_field(
return(innobase_mysql_cmp( return(innobase_mysql_cmp(
(int)(type->prtype & DATA_MYSQL_TYPE_MASK), (int)(type->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(type->prtype),
a, a_length, b, b_length)); a, a_length, b, b_length));
default: default:
fprintf(stderr, fprintf(stderr,
......
...@@ -756,6 +756,11 @@ innobase_init(void) ...@@ -756,6 +756,11 @@ innobase_init(void)
srv_query_thread_priority = QUERY_PRIOR; srv_query_thread_priority = QUERY_PRIOR;
} }
/* Store the default charset-collation number of this MySQL
installation */
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
/* Set InnoDB initialization parameters according to the values /* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */ read from MySQL .cnf file */
...@@ -870,16 +875,14 @@ innobase_init(void) ...@@ -870,16 +875,14 @@ innobase_init(void)
srv_print_verbose_log = mysql_embedded ? 0 : 1; srv_print_verbose_log = mysql_embedded ? 0 : 1;
if (strcmp(default_charset_info->name, "latin1") == 0) { /* Store the latin1_swedish_ci character ordering table to InnoDB. For
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
and consequently we do not need to know the ordering internally in
InnoDB. */
/* Store the character ordering table to InnoDB. ut_a(0 == ut_strcmp((char*)my_charset_latin1.name,
For non-latin1 charsets we use the MySQL comparison (char*)"latin1_swedish_ci"));
functions, and consequently we do not need to know memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256);
the ordering internally in InnoDB. */
memcpy(srv_latin1_ordering,
default_charset_info->sort_order, 256);
}
/* Since we in this module access directly the fields of a trx /* Since we in this module access directly the fields of a trx
struct, and due to different headers and flags it might happen that struct, and due to different headers and flags it might happen that
...@@ -1661,10 +1664,10 @@ reset_null_bits( ...@@ -1661,10 +1664,10 @@ reset_null_bits(
extern "C" { extern "C" {
/***************************************************************** /*****************************************************************
InnoDB uses this function is to compare two data fields for which the InnoDB uses this function to compare two data fields for which the data type
data type is such that we must use MySQL code to compare them. NOTE that the is such that we must use MySQL code to compare them. NOTE that the prototype
prototype of this function is in rem0cmp.c in InnoDB source code! of this function is in rem0cmp.c in InnoDB source code! If you change this
If you change this function, remember to update the prototype there! */ function, remember to update the prototype there! */
int int
innobase_mysql_cmp( innobase_mysql_cmp(
...@@ -1672,6 +1675,7 @@ innobase_mysql_cmp( ...@@ -1672,6 +1675,7 @@ innobase_mysql_cmp(
/* out: 1, 0, -1, if a is greater, /* out: 1, 0, -1, if a is greater,
equal, less than b, respectively */ equal, less than b, respectively */
int mysql_type, /* in: MySQL type */ int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* a, /* in: data field */ unsigned char* a, /* in: data field */
unsigned int a_length, /* in: data field length, unsigned int a_length, /* in: data field length,
not UNIV_SQL_NULL */ not UNIV_SQL_NULL */
...@@ -1679,6 +1683,7 @@ innobase_mysql_cmp( ...@@ -1679,6 +1683,7 @@ innobase_mysql_cmp(
unsigned int b_length) /* in: data field length, unsigned int b_length) /* in: data field length,
not UNIV_SQL_NULL */ not UNIV_SQL_NULL */
{ {
CHARSET_INFO* charset;
enum_field_types mysql_tp; enum_field_types mysql_tp;
int ret; int ret;
...@@ -1695,9 +1700,27 @@ innobase_mysql_cmp( ...@@ -1695,9 +1700,27 @@ innobase_mysql_cmp(
case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_BLOB: case FIELD_TYPE_BLOB:
case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_LONG_BLOB:
// BAR TODO: Discuss with heikki.tuuri@innodb.com /* Use the charset number to pick the right charset struct for
// so that he sends CHARSET_INFO for the field to this function. the comparison. Since the MySQL function get_charset may be
ret = my_strnncoll(default_charset_info, slow before Bar removes the mutex operation there, we first
look at 2 common charsets directly. */
if (charset_number == default_charset_info->number) {
charset = default_charset_info;
} else if (charset_number == my_charset_latin1.number) {
charset = &my_charset_latin1;
} else {
charset = get_charset(charset_number, MYF(MY_WME));
if (charset == NULL) {
fprintf(stderr,
"InnoDB: fatal error: InnoDB needs charset %lu for doing a comparison,\n"
"InnoDB: but MySQL cannot find that charset.\n", (ulong)charset_number);
ut_a(0);
}
}
ret = my_strnncoll(charset,
a, a_length, a, a_length,
b, b_length); b, b_length);
if (ret < 0) { if (ret < 0) {
...@@ -1724,9 +1747,9 @@ get_innobase_type_from_mysql_type( ...@@ -1724,9 +1747,9 @@ get_innobase_type_from_mysql_type(
/* out: DATA_BINARY, DATA_VARCHAR, ... */ /* out: DATA_BINARY, DATA_VARCHAR, ... */
Field* field) /* in: MySQL field */ Field* field) /* in: MySQL field */
{ {
/* The following asserts check that the MySQL type code fits in /* The following asserts try to check that the MySQL type code fits in
8 bits: this is used in ibuf and also when DATA_NOT_NULL is 8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
ORed to the type */ the type */
DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256); DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256); DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
...@@ -1741,8 +1764,8 @@ get_innobase_type_from_mysql_type( ...@@ -1741,8 +1764,8 @@ get_innobase_type_from_mysql_type(
return(DATA_BINARY); return(DATA_BINARY);
} else if (strcmp( } else if (strcmp(
default_charset_info->name, field->charset()->name,
"latin1") == 0) { "latin1_swedish_ci") == 0) {
return(DATA_VARCHAR); return(DATA_VARCHAR);
} else { } else {
return(DATA_VARMYSQL); return(DATA_VARMYSQL);
...@@ -1751,8 +1774,8 @@ get_innobase_type_from_mysql_type( ...@@ -1751,8 +1774,8 @@ get_innobase_type_from_mysql_type(
return(DATA_FIXBINARY); return(DATA_FIXBINARY);
} else if (strcmp( } else if (strcmp(
default_charset_info->name, field->charset()->name,
"latin1") == 0) { "latin1_swedish_ci") == 0) {
return(DATA_CHAR); return(DATA_CHAR);
} else { } else {
return(DATA_MYSQL); return(DATA_MYSQL);
...@@ -3238,6 +3261,7 @@ create_table_def( ...@@ -3238,6 +3261,7 @@ create_table_def(
ulint unsigned_type; ulint unsigned_type;
ulint binary_type; ulint binary_type;
ulint nonlatin1_type; ulint nonlatin1_type;
ulint charset_no;
ulint i; ulint i;
DBUG_ENTER("create_table_def"); DBUG_ENTER("create_table_def");
...@@ -3267,7 +3291,8 @@ create_table_def( ...@@ -3267,7 +3291,8 @@ create_table_def(
} }
if (col_type == DATA_BLOB if (col_type == DATA_BLOB
&& strcmp(default_charset_info->name, "latin1") != 0) { && strcmp(field->charset()->name,
"latin1_swedish_ci") != 0) {
nonlatin1_type = DATA_NONLATIN1; nonlatin1_type = DATA_NONLATIN1;
} else { } else {
nonlatin1_type = 0; nonlatin1_type = 0;
...@@ -3280,10 +3305,22 @@ create_table_def( ...@@ -3280,10 +3305,22 @@ create_table_def(
binary_type = 0; binary_type = 0;
} }
charset_no = 0;
if (dtype_is_string_type(col_type)) {
charset_no = (ulint)field->charset()->number;
ut_a(charset_no < 256); /* in ut0type.h we assume that
the number fits in one byte */
}
dict_mem_table_add_col(table, (char*) field->field_name, dict_mem_table_add_col(table, (char*) field->field_name,
col_type, (ulint)field->type() col_type, dtype_form_prtype(
(ulint)field->type()
| nulls_allowed | unsigned_type | nulls_allowed | unsigned_type
| nonlatin1_type | binary_type, | nonlatin1_type | binary_type,
+ charset_no),
field->pack_length(), 0); field->pack_length(), 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment