summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-10-01 20:01:25 +0300
committerunknown <heikki@hundin.mysql.fi>2004-10-01 20:01:25 +0300
commitd822c6f7efbf01a3c7dc257b2e65aab8187b6098 (patch)
treeb99f5669c6448da9932bab0ed49e52fe9d08db47
parent0db72d6e335d89a734bceff5f2d1a8617f5557e6 (diff)
downloadmariadb-git-d822c6f7efbf01a3c7dc257b2e65aab8187b6098.tar.gz
Many files:
Fix bug introduced by the prefix key + multibyte charsets patch today sql/ha_innodb.cc: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/include/data0type.h: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/include/fsp0fsp.h: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/data/data0type.c: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/row/row0ins.c: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/row/row0row.c: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/row/row0sel.c: Fix bug introduced by the prefix key + multibyte charsets patch today innobase/row/row0upd.c: Fix bug introduced by the prefix key + multibyte charsets patch today
-rw-r--r--innobase/data/data0type.c78
-rw-r--r--innobase/include/data0type.h23
-rw-r--r--innobase/include/fsp0fsp.h34
-rw-r--r--innobase/row/row0ins.c10
-rw-r--r--innobase/row/row0row.c20
-rw-r--r--innobase/row/row0sel.c9
-rw-r--r--innobase/row/row0upd.c38
-rw-r--r--sql/ha_innodb.cc63
8 files changed, 200 insertions, 75 deletions
diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c
index 97d93b1b0ec..714cf92bc65 100644
--- a/innobase/data/data0type.c
+++ b/innobase/data/data0type.c
@@ -12,6 +12,27 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic"
#endif
+/**********************************************************************
+This function is used to find the storage length in bytes of the first n
+characters for prefix indexes using a multibyte character set. The function
+finds charset information and returns length of prefix_len characters in the
+index field in bytes.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+
+ulint
+innobase_get_at_most_n_mbchars(
+/*===========================*/
+ /* out: number of bytes occupied by the first
+ n characters */
+ ulint charset_id, /* in: character set id */
+ ulint prefix_len, /* in: prefix length in bytes of the index
+ (this has to be divided by mbmaxlen to get the
+ number of CHARACTERS n in the prefix) */
+ ulint data_len, /* in: length of the string in bytes */
+ const char* str); /* in: character string */
+
/* 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
@@ -24,6 +45,63 @@ dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0};
dtype_t* dtype_binary = &dtype_binary_val;
/*************************************************************************
+Checks if a string type has to be compared by the MySQL comparison functions.
+InnoDB internally only handles binary byte string comparisons, as well as
+latin1_swedish_ci strings. For example, UTF-8 strings have to be compared
+by MySQL. */
+
+ibool
+dtype_str_needs_mysql_cmp(
+/*======================*/
+ /* out: TRUE if a string type that requires
+ comparison with MySQL functions */
+ dtype_t* dtype) /* in: type struct */
+{
+ if (dtype->mtype == DATA_MYSQL
+ || dtype->mtype == DATA_VARMYSQL
+ || (dtype->mtype == DATA_BLOB
+ && 0 == (dtype->prtype & DATA_BINARY_TYPE)
+ && dtype_get_charset_coll(dtype->prtype) !=
+ data_mysql_latin1_swedish_charset_coll)) {
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+/*************************************************************************
+For the documentation of this function, see innobase_get_at_most_n_mbchars()
+in ha_innodb.cc. */
+
+ulint
+dtype_get_at_most_n_mbchars(
+/*========================*/
+ dtype_t* dtype,
+ ulint prefix_len,
+ ulint data_len,
+ const char* str)
+{
+ ut_a(data_len != UNIV_SQL_NULL);
+
+ if (dtype_str_needs_mysql_cmp(dtype)) {
+ return(innobase_get_at_most_n_mbchars(
+ dtype_get_charset_coll(dtype->prtype),
+ prefix_len, data_len, str));
+ }
+
+ /* We assume here that the string types that InnoDB itself can compare
+ are single-byte charsets! */
+
+ if (prefix_len < data_len) {
+
+ return(prefix_len);
+
+ }
+
+ return(data_len);
+}
+
+/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h
index fe38a224a66..c263d2bf613 100644
--- a/innobase/include/data0type.h
+++ b/innobase/include/data0type.h
@@ -145,6 +145,29 @@ store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/*************************************************************************
+Checks if a string type has to be compared by the MySQL comparison functions.
+InnoDB internally only handles binary byte string comparisons, as well as
+latin1_swedish_ci strings. For example, UTF-8 strings have to be compared
+by MySQL. */
+
+ibool
+dtype_str_needs_mysql_cmp(
+/*======================*/
+ /* out: TRUE if a string type that requires
+ comparison with MySQL functions */
+ dtype_t* dtype); /* in: type struct */
+/*************************************************************************
+For the documentation of this function, see innobase_get_at_most_n_mbchars()
+in ha_innodb.cc. */
+
+ulint
+dtype_get_at_most_n_mbchars(
+/*========================*/
+ dtype_t* dtype,
+ ulint prefix_len,
+ ulint data_len,
+ const char* str);
+/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h
index 2fcde882df7..cebfb9ea2dd 100644
--- a/innobase/include/fsp0fsp.h
+++ b/innobase/include/fsp0fsp.h
@@ -16,6 +16,40 @@ Created 12/18/1995 Heikki Tuuri
#include "ut0byte.h"
#include "page0types.h"
+typedef byte xdes_t;
+
+/************************************************************************
+Gets pointer to a the extent descriptor of a page. The page where the
+extent descriptor resides is x-locked. If the page offset is equal to
+the free limit of the space, adds new extents from above the free limit
+to the space free list, if not free limit == space size. This adding
+is necessary to make the descriptor defined, as they are uninitialized
+above the free limit. */
+
+xdes_t*
+xdes_get_descriptor(
+/*================*/
+ /* out: pointer to the extent descriptor, NULL if the
+ page does not exist in the space or if offset > free
+ limit */
+ ulint space, /* in: space id */
+ ulint offset, /* in: page offset; if equal to the free limit,
+ we try to add new extents to the space free list */
+ mtr_t* mtr); /* in: mtr handle */
+
+/**************************************************************************
+Gets a descriptor bit of a page. */
+
+ibool
+xdes_get_bit(
+/*=========*/
+ /* out: TRUE if free */
+ xdes_t* descr, /* in: descriptor */
+ ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ulint offset, /* in: page offset within extent:
+ 0 ... FSP_EXTENT_SIZE - 1 */
+ mtr_t* mtr); /* in: mtr */
+
/* If records are inserted in order, there are the following
flags to tell this (their type is made byte for the compiler
to warn if direction and hint parameters are switched in
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index c5d90524fdd..7b0beb9d183 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -2019,16 +2019,12 @@ row_ins_index_entry_set_vals(
if (ind_field->prefix_len > 0
&& dfield_get_len(row_field) != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
cur_type = dict_col_get_type(
dict_field_get_col(ind_field));
- field->len = innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
- ind_field->prefix_len,
- dfield_get_len(row_field),row_field->data);
+ field->len = dtype_get_at_most_n_mbchars(cur_type,
+ ind_field->prefix_len,
+ dfield_get_len(row_field), row_field->data);
} else {
field->len = row_field->len;
}
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index a02fbe67f73..e7b39f0fe52 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -143,18 +143,15 @@ row_build_index_entry(
if (ind_field->prefix_len > 0
&& dfield_get_len(dfield2) != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
cur_type = dict_col_get_type(
dict_field_get_col(ind_field));
- storage_len = innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
+ storage_len = dtype_get_at_most_n_mbchars(
+ cur_type,
ind_field->prefix_len,
- dfield_get_len(dfield2),dfield2->data);
+ dfield_get_len(dfield2), dfield2->data);
- dfield_set_len(dfield,storage_len);
+ dfield_set_len(dfield, storage_len);
}
}
@@ -497,16 +494,13 @@ row_build_row_ref_from_row(
if (field->prefix_len > 0
&& dfield->len != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
cur_type = dict_col_get_type(
dict_field_get_col(field));
- dfield->len = innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
+ dfield->len = dtype_get_at_most_n_mbchars(
+ cur_type,
field->prefix_len,
- dfield->len,dfield->data);
+ dfield->len, dfield->data);
}
}
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 8e011047dad..16c0a1eaa32 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -94,16 +94,13 @@ row_sel_sec_rec_is_for_clust_rec(
if (ifield->prefix_len > 0
&& clust_len != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
cur_type = dict_col_get_type(
dict_field_get_col(ifield));
- clust_len = innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
+ clust_len = dtype_get_at_most_n_mbchars(
+ cur_type,
ifield->prefix_len,
- clust_len,clust_field);
+ clust_len, clust_field);
}
if (0 != cmp_data_data(dict_col_get_type(col),
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 34c45204167..a449b9f1736 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -876,17 +876,15 @@ row_upd_index_replace_new_col_vals_index_pos(
if (field->prefix_len > 0
&& new_val->len != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
- cur_type = dict_col_get_type(
- dict_field_get_col(field));
-
- dfield->len =
- innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
- field->prefix_len,
- new_val->len,new_val->data);
+ cur_type = dict_col_get_type(
+ dict_field_get_col(field));
+
+ dfield->len =
+ dtype_get_at_most_n_mbchars(
+ cur_type,
+ field->prefix_len,
+ new_val->len,
+ new_val->data);
}
}
}
@@ -948,17 +946,15 @@ row_upd_index_replace_new_col_vals(
if (field->prefix_len > 0
&& new_val->len != UNIV_SQL_NULL) {
- /* For prefix keys get the storage length
- for the prefix_len characters. */
-
- cur_type = dict_col_get_type(
- dict_field_get_col(field));
+ cur_type = dict_col_get_type(
+ dict_field_get_col(field));
- dfield->len =
- innobase_get_at_most_n_mbchars(
- dtype_get_charset_coll(cur_type->prtype),
- field->prefix_len,
- new_val->len,new_val->data);
+ dfield->len =
+ dtype_get_at_most_n_mbchars(
+ cur_type,
+ field->prefix_len,
+ new_val->len,
+ new_val->data);
}
}
}
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index de0ba0d31ee..8e2a7c2190a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -5258,8 +5258,7 @@ innobase_store_binlog_offset_and_flush_log(
/*=============================*/
char *binlog_name, /* in: binlog name */
longlong offset /* in: binlog offset */
-)
-{
+) {
mtr_t mtr;
assert(binlog_name != NULL);
@@ -5298,50 +5297,58 @@ ulonglong ha_innobase::get_mysql_bin_log_pos()
extern "C" {
/**********************************************************************
-This function is used to find storage length of prefix_len characters
-in bytes for prefix indexes using multibyte character set.
-Function finds charset information and returns length of
-prefix_len characters in the index field in bytes. */
+This function is used to find the storage length in bytes of the first n
+characters for prefix indexes using a multibyte character set. The function
+finds charset information and returns length of prefix_len characters in the
+index field in bytes.
+
+NOTE: the prototype of this function is copied to data0type.c! If you change
+this function, you MUST change also data0type.c! */
-ulint innobase_get_at_most_n_mbchars(
-/*=================================*/
+ulint
+innobase_get_at_most_n_mbchars(
+/*===========================*/
+ /* out: number of bytes occupied by the first
+ n characters */
ulint charset_id, /* in: character set id */
- ulint prefix_len, /* in: prefix length of the index */
- ulint data_len, /* in: length of the sting in bytes */
- const char *pos) /* in: character string */
+ ulint prefix_len, /* in: prefix length in bytes of the index
+ (this has to be divided by mbmaxlen to get the
+ number of CHARACTERS n in the prefix) */
+ ulint data_len, /* in: length of the string in bytes */
+ const char* str) /* in: character string */
{
- ulint byte_length; /* storage length, in bytes. */
+ ulint byte_length; /* string length in bytes. */
ulint char_length; /* character length in bytes */
+ ulint n_chars; /* number of characters in prefix */
CHARSET_INFO* charset; /* charset used in the field */
- ut_ad(pos);
byte_length = data_len;
- charset = get_charset(charset_id,MYF(MY_WME));
+ charset = get_charset(charset_id, MYF(MY_WME));
ut_ad(charset);
ut_ad(charset->mbmaxlen);
- /* Calculate the storage length of the one character in bytes and
- how many characters the prefix index contains */
+ /* Calculate how many characters at most the prefix index contains */
- char_length = byte_length / charset->mbmaxlen;
- prefix_len = prefix_len / charset->mbmaxlen;
+ n_chars = prefix_len / charset->mbmaxlen;
- /* If length of the string is greater than storage length of the
- one character, we have to find the storage position of the
- prefix_len character in the string */
+ /* If the charset is multi-byte, then we must find the length of the
+ first at most n chars in the string. If the string contains less
+ characters than n, then we return the length to the end of the last
+ full character. */
- if (byte_length > char_length) {
- char_length = my_charpos(charset, pos,
- pos + byte_length, prefix_len);
- set_if_smaller(char_length, byte_length);
- }
- else {
+ if (charset->mbmaxlen > 1) {
+ /* my_charpos() returns the byte length of the first n_chars
+ characters, or the end of the last full character */
+
+ char_length = my_charpos(charset, str,
+ str + byte_length, n_chars);
+ } else {
char_length = prefix_len;
}
- return char_length;
+ return(char_length);
}
}