mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Many files:
Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again sql/ha_innodb.cc: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/data/data0type.c: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/dict/dict0crea.c: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/dict/dict0load.c: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/include/data0type.h: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/include/data0type.ic: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again innobase/rem/rem0cmp.c: Multiple charset support for InnoDB; note that if you create tables and the default charset-collation is not latin1_swedish_ci, then you cannot use those tables if you downgrade to 4.0 again
This commit is contained in:
@ -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 @@ loop:
|
|||||||
|
|
||||||
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(
|
|||||||
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
|
|||||||
|
|
||||||
#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;
|
|||||||
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 */
|
|||||||
#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 */
|
|||||||
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(
|
|||||||
/*=============*/
|
/*=============*/
|
||||||
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(
|
|||||||
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
|
|||||||
|
|
||||||
#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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(
|
|||||||
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,8 +309,26 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Returns the size of a fixed size data type, 0 if not a fixed size type. */
|
Returns the size of a fixed size data type, 0 if not a fixed size type. */
|
||||||
|
@ -61,10 +61,11 @@ must be a copy of the the one in ha_innobase.cc! */
|
|||||||
|
|
||||||
int
|
int
|
||||||
innobase_mysql_cmp(
|
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,16 +98,28 @@ 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)
|
|
||||||
|| (type1->mtype == DATA_MYSQL && type2->mtype == DATA_VARMYSQL)
|
|
||||||
|| (type1->mtype == DATA_VARMYSQL && type2->mtype == DATA_MYSQL)) {
|
|
||||||
|
|
||||||
return(TRUE);
|
/* Both are non-binary string types: they can be compared if
|
||||||
|
and only if the charset-collation is the same */
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if (type1->mtype != type2->mtype) {
|
if (type1->mtype != type2->mtype) {
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
@ -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(
|
|||||||
|
|
||||||
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,
|
||||||
|
101
sql/ha_innodb.cc
101
sql/ha_innodb.cc
@ -290,7 +290,7 @@ convert_error_code_to_mysql(
|
|||||||
|
|
||||||
} else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
|
} else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
|
||||||
|
|
||||||
return(HA_ERR_ROW_IS_REFERENCED);
|
return(HA_ERR_ROW_IS_REFERENCED);
|
||||||
|
|
||||||
} else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
|
} else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
|
||||||
|
|
||||||
@ -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)
|
|||||||
|
|
||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
/* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
/* 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(
|
|||||||
|
|
||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3467,7 +3504,7 @@ ha_innobase::create(
|
|||||||
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
|
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
|
||||||
but we play safe here */
|
but we play safe here */
|
||||||
|
|
||||||
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the transaction associated with the current thd, or create one
|
/* Get the transaction associated with the current thd, or create one
|
||||||
@ -3681,7 +3718,7 @@ ha_innobase::delete_table(
|
|||||||
int error;
|
int error;
|
||||||
trx_t* parent_trx;
|
trx_t* parent_trx;
|
||||||
trx_t* trx;
|
trx_t* trx;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
char norm_name[1000];
|
char norm_name[1000];
|
||||||
|
|
||||||
DBUG_ENTER("ha_innobase::delete_table");
|
DBUG_ENTER("ha_innobase::delete_table");
|
||||||
@ -4408,7 +4445,7 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||||||
prebuilt->trx->op_info = (char*)"";
|
prebuilt->trx->op_info = (char*)"";
|
||||||
|
|
||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Checks if a table is referenced by a foreign key. The MySQL manual states that
|
Checks if a table is referenced by a foreign key. The MySQL manual states that
|
||||||
@ -4649,10 +4686,10 @@ ha_innobase::external_lock(
|
|||||||
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
|
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
|
||||||
&& prebuilt->select_lock_type == LOCK_NONE
|
&& prebuilt->select_lock_type == LOCK_NONE
|
||||||
&& (thd->options
|
&& (thd->options
|
||||||
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
||||||
|
|
||||||
/* To get serializable execution, we let InnoDB
|
/* To get serializable execution, we let InnoDB
|
||||||
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
|
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
|
||||||
which otherwise would have been consistent reads. An
|
which otherwise would have been consistent reads. An
|
||||||
exception is consistent reads in the AUTOCOMMIT=1 mode:
|
exception is consistent reads in the AUTOCOMMIT=1 mode:
|
||||||
we know that they are read-only transactions, and they
|
we know that they are read-only transactions, and they
|
||||||
|
Reference in New Issue
Block a user