mirror of
https://github.com/MariaDB/server.git
synced 2025-09-06 19:08:06 +03:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into poseidon.ndb.mysql.com:/home/tomas/mysql-4.1-ndb2
This commit is contained in:
@@ -151,7 +151,12 @@ struct dict_col_struct{
|
|||||||
in some of the functions below */
|
in some of the functions below */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DICT_MAX_COL_PREFIX_LEN 512
|
/* DICT_MAX_COL_PREFIX_LEN is measured in bytes. Starting from 4.1.6, we
|
||||||
|
set max col prefix len to < 3 * 256, so that one can create a column prefix
|
||||||
|
index on 255 characters of a TEXT field also in the UTF-8 charset. In that
|
||||||
|
charset, a character may take at most 3 bytes. */
|
||||||
|
|
||||||
|
#define DICT_MAX_COL_PREFIX_LEN 768
|
||||||
|
|
||||||
/* Data structure for a field in an index */
|
/* Data structure for a field in an index */
|
||||||
struct dict_field_struct{
|
struct dict_field_struct{
|
||||||
@@ -160,9 +165,12 @@ struct dict_field_struct{
|
|||||||
ulint order; /* flags for ordering this field:
|
ulint order; /* flags for ordering this field:
|
||||||
DICT_DESCEND, ... */
|
DICT_DESCEND, ... */
|
||||||
ulint prefix_len; /* 0 or the length of the column
|
ulint prefix_len; /* 0 or the length of the column
|
||||||
prefix in a MySQL index of type, e.g.,
|
prefix in bytes in a MySQL index of
|
||||||
INDEX (textcol(25)); must be smaller
|
type, e.g., INDEX (textcol(25));
|
||||||
than DICT_MAX_COL_PREFIX_LEN */
|
must be smaller than
|
||||||
|
DICT_MAX_COL_PREFIX_LEN; NOTE that
|
||||||
|
in the UTF-8 charset, MySQL sets this
|
||||||
|
to 3 * the prefix len in UTF-8 chars */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Data structure for an index tree */
|
/* Data structure for an index tree */
|
||||||
|
@@ -117,7 +117,7 @@ int
|
|||||||
ut_strcmp(const void* str1, const void* str2);
|
ut_strcmp(const void* str1, const void* str2);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Determine the length of a string when it is quoted with ut_strcpyq(). */
|
Compute strlen(ut_strcpyq(str, q)). */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
ut_strlenq(
|
ut_strlenq(
|
||||||
@@ -127,7 +127,9 @@ ut_strlenq(
|
|||||||
char q); /* in: the quote character */
|
char q); /* in: the quote character */
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Make a quoted copy of a string. */
|
Make a quoted copy of a NUL-terminated string. Leading and trailing
|
||||||
|
quotes will not be included; only embedded quotes will be escaped.
|
||||||
|
See also ut_strlenq() and ut_memcpyq(). */
|
||||||
|
|
||||||
char*
|
char*
|
||||||
ut_strcpyq(
|
ut_strcpyq(
|
||||||
@@ -138,7 +140,9 @@ ut_strcpyq(
|
|||||||
const char* src); /* in: null-terminated string */
|
const char* src); /* in: null-terminated string */
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Make a quoted copy of a fixed-length string. */
|
Make a quoted copy of a fixed-length string. Leading and trailing
|
||||||
|
quotes will not be included; only embedded quotes will be escaped.
|
||||||
|
See also ut_strlenq() and ut_strcpyq(). */
|
||||||
|
|
||||||
char*
|
char*
|
||||||
ut_memcpyq(
|
ut_memcpyq(
|
||||||
|
@@ -49,7 +49,7 @@ ut_strcmp(const void* str1, const void* str2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Determine the length of a string when it is quoted with ut_strcpyq(). */
|
Compute strlen(ut_strcpyq(str, q)). */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
ut_strlenq(
|
ut_strlenq(
|
||||||
|
@@ -1630,6 +1630,8 @@ row_create_index_for_mysql(
|
|||||||
|
|
||||||
trx->op_info = "creating index";
|
trx->op_info = "creating index";
|
||||||
|
|
||||||
|
trx_start_if_not_started(trx);
|
||||||
|
|
||||||
/* Check that the same column does not appear twice in the index.
|
/* Check that the same column does not appear twice in the index.
|
||||||
Starting from 4.0.14, InnoDB should be able to cope with that, but
|
Starting from 4.0.14, InnoDB should be able to cope with that, but
|
||||||
safer not to allow them. */
|
safer not to allow them. */
|
||||||
@@ -1656,9 +1658,16 @@ row_create_index_for_mysql(
|
|||||||
goto error_handling;
|
goto error_handling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/* Check also that prefix_len < DICT_MAX_COL_PREFIX_LEN */
|
||||||
|
|
||||||
trx_start_if_not_started(trx);
|
if (dict_index_get_nth_field(index, i)->prefix_len
|
||||||
|
>= DICT_MAX_COL_PREFIX_LEN) {
|
||||||
|
err = DB_TOO_BIG_RECORD;
|
||||||
|
|
||||||
|
goto error_handling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (row_mysql_is_recovered_tmp_table(index->table_name)) {
|
if (row_mysql_is_recovered_tmp_table(index->table_name)) {
|
||||||
|
|
||||||
@@ -1988,9 +1997,9 @@ row_discard_tablespace_for_mysql(
|
|||||||
"new_id_high INT;\n"
|
"new_id_high INT;\n"
|
||||||
"table_name CHAR;\n"
|
"table_name CHAR;\n"
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"table_name := ";
|
"table_name := '";
|
||||||
static const char discard_tablespace_proc2[] =
|
static const char discard_tablespace_proc2[] =
|
||||||
";\n"
|
"';\n"
|
||||||
"new_id_high := %lu;\n"
|
"new_id_high := %lu;\n"
|
||||||
"new_id_low := %lu;\n"
|
"new_id_low := %lu;\n"
|
||||||
"new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n"
|
"new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n"
|
||||||
|
@@ -313,7 +313,9 @@ ut_free_all_mem(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Make a quoted copy of a string. */
|
Make a quoted copy of a NUL-terminated string. Leading and trailing
|
||||||
|
quotes will not be included; only embedded quotes will be escaped.
|
||||||
|
See also ut_strlenq() and ut_memcpyq(). */
|
||||||
|
|
||||||
char*
|
char*
|
||||||
ut_strcpyq(
|
ut_strcpyq(
|
||||||
@@ -333,7 +335,9 @@ ut_strcpyq(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Make a quoted copy of a fixed-length string. */
|
Make a quoted copy of a fixed-length string. Leading and trailing
|
||||||
|
quotes will not be included; only embedded quotes will be escaped.
|
||||||
|
See also ut_strlenq() and ut_strcpyq(). */
|
||||||
|
|
||||||
char*
|
char*
|
||||||
ut_memcpyq(
|
ut_memcpyq(
|
||||||
|
@@ -1260,3 +1260,27 @@ a length(a) char_length(a)
|
|||||||
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 510 255
|
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 510 255
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int unsigned NOT NULL auto_increment,
|
||||||
|
list_id smallint unsigned NOT NULL,
|
||||||
|
term TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
INDEX(list_id, term(4))
|
||||||
|
) ENGINE=BDB CHARSET=utf8;
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterc";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterb";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "lettera";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterd";
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterc");
|
||||||
|
id
|
||||||
|
1
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterb");
|
||||||
|
id
|
||||||
|
2
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
|
||||||
|
id
|
||||||
|
3
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
||||||
|
id
|
||||||
|
4
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -726,3 +726,27 @@ length(subject)
|
|||||||
3
|
3
|
||||||
432
|
432
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int unsigned NOT NULL auto_increment,
|
||||||
|
list_id smallint unsigned NOT NULL,
|
||||||
|
term TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
INDEX(list_id, term(4))
|
||||||
|
) ENGINE=MYISAM CHARSET=utf8;
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterc";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterb";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "lettera";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterd";
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterc");
|
||||||
|
id
|
||||||
|
1
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterb");
|
||||||
|
id
|
||||||
|
2
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
|
||||||
|
id
|
||||||
|
3
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
||||||
|
id
|
||||||
|
4
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -909,3 +909,23 @@ insert into t1 values (@a);
|
|||||||
select a, length(a), char_length(a) from t1;
|
select a, length(a), char_length(a) from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #5832 SELECT doesn't return records in some cases
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int unsigned NOT NULL auto_increment,
|
||||||
|
list_id smallint unsigned NOT NULL,
|
||||||
|
term TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
INDEX(list_id, term(4))
|
||||||
|
) ENGINE=BDB CHARSET=utf8;
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterc";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterb";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "lettera";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterd";
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterc");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterb");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -572,3 +572,23 @@ INSERT INTO t1 VALUES ('aaa','bbb');
|
|||||||
SELECT length(subject) FROM t1;
|
SELECT length(subject) FROM t1;
|
||||||
SELECT length(subject) FROM t1 ORDER BY 1;
|
SELECT length(subject) FROM t1 ORDER BY 1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #5832 SELECT doesn't return records in some cases
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int unsigned NOT NULL auto_increment,
|
||||||
|
list_id smallint unsigned NOT NULL,
|
||||||
|
term TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
INDEX(list_id, term(4))
|
||||||
|
) ENGINE=MYISAM CHARSET=utf8;
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterc";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterb";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "lettera";
|
||||||
|
INSERT INTO t1 SET list_id = 1, term = "letterd";
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterc");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterb");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera");
|
||||||
|
SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd");
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#-- source include/have_ndb.inc
|
-- source include/have_ndb.inc
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
@@ -3501,6 +3501,8 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
|
|||||||
BaseString node_group_warning, arbitration_warning;
|
BaseString node_group_warning, arbitration_warning;
|
||||||
const char *arbit_warn_fmt=
|
const char *arbit_warn_fmt=
|
||||||
"\n arbitrator with id %d and db node with id %d on same host %s";
|
"\n arbitrator with id %d and db node with id %d on same host %s";
|
||||||
|
const char *arbit_warn_fmt2=
|
||||||
|
"\n arbitrator with id %d has no hostname specified";
|
||||||
|
|
||||||
ctx.m_userProperties.get("NoOfNodes", &n_nodes);
|
ctx.m_userProperties.get("NoOfNodes", &n_nodes);
|
||||||
for (i= 0, n= 0; n < n_nodes; i++){
|
for (i= 0, n= 0; n < n_nodes; i++){
|
||||||
@@ -3583,13 +3585,19 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
|
|||||||
arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
|
arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arbitration_warning.appfmt(arbit_warn_fmt2, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (db_host_count > 1 && node_group_warning.length() > 0)
|
if (db_host_count > 1 && node_group_warning.length() > 0)
|
||||||
ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str());
|
ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str());
|
||||||
if (db_host_count > 1 && arbitration_warning.length() > 0)
|
if (db_host_count > 1 && arbitration_warning.length() > 0)
|
||||||
ndbout_c("Cluster configuration warning:%s",arbitration_warning.c_str());
|
ndbout_c("Cluster configuration warning:%s%s",arbitration_warning.c_str(),
|
||||||
|
"\n Running arbitrator on the same host as a database node may"
|
||||||
|
"\n cause complete cluster shutdown in case of host failure.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
18
sql/field.cc
18
sql/field.cc
@@ -2970,6 +2970,14 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
|
|||||||
return TIMESTAMP_AUTO_SET_ON_INSERT;
|
return TIMESTAMP_AUTO_SET_ON_INSERT;
|
||||||
case TIMESTAMP_UN_FIELD:
|
case TIMESTAMP_UN_FIELD:
|
||||||
return TIMESTAMP_AUTO_SET_ON_UPDATE;
|
return TIMESTAMP_AUTO_SET_ON_UPDATE;
|
||||||
|
case TIMESTAMP_OLD_FIELD:
|
||||||
|
/*
|
||||||
|
Altough we can have several such columns in legacy tables this
|
||||||
|
function should be called only for first of them (i.e. the one
|
||||||
|
having auto-set property).
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(table->timestamp_field == this);
|
||||||
|
/* Fall-through */
|
||||||
case TIMESTAMP_DNUN_FIELD:
|
case TIMESTAMP_DNUN_FIELD:
|
||||||
return TIMESTAMP_AUTO_SET_ON_BOTH;
|
return TIMESTAMP_AUTO_SET_ON_BOTH;
|
||||||
default:
|
default:
|
||||||
@@ -5077,6 +5085,11 @@ void Field_blob::get_key_image(char *buff,uint length,
|
|||||||
}
|
}
|
||||||
#endif /*HAVE_SPATIAL*/
|
#endif /*HAVE_SPATIAL*/
|
||||||
|
|
||||||
|
get_ptr(&blob);
|
||||||
|
uint char_length= length / cs->mbmaxlen;
|
||||||
|
char_length= my_charpos(cs, blob, blob + length, char_length);
|
||||||
|
set_if_smaller(length, char_length);
|
||||||
|
|
||||||
if ((uint32) length > blob_length)
|
if ((uint32) length > blob_length)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -5087,7 +5100,6 @@ void Field_blob::get_key_image(char *buff,uint length,
|
|||||||
length=(uint) blob_length;
|
length=(uint) blob_length;
|
||||||
}
|
}
|
||||||
int2store(buff,length);
|
int2store(buff,length);
|
||||||
get_ptr(&blob);
|
|
||||||
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5103,6 +5115,10 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
|
|||||||
char *blob1;
|
char *blob1;
|
||||||
uint blob_length=get_length(ptr);
|
uint blob_length=get_length(ptr);
|
||||||
memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
|
memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
|
||||||
|
CHARSET_INFO *cs= charset();
|
||||||
|
uint char_length= max_key_length / cs->mbmaxlen;
|
||||||
|
char_length= my_charpos(cs, blob1, blob1+blob_length, char_length);
|
||||||
|
set_if_smaller(blob_length, char_length);
|
||||||
return Field_blob::cmp(blob1,min(blob_length, max_key_length),
|
return Field_blob::cmp(blob1,min(blob_length, max_key_length),
|
||||||
(char*) key_ptr+HA_KEY_BLOB_LENGTH,
|
(char*) key_ptr+HA_KEY_BLOB_LENGTH,
|
||||||
uint2korr(key_ptr));
|
uint2korr(key_ptr));
|
||||||
|
@@ -3525,10 +3525,6 @@ create_index(
|
|||||||
prefix_len = 0;
|
prefix_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix_len >= DICT_MAX_COL_PREFIX_LEN) {
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We assume all fields should be sorted in ascending
|
/* We assume all fields should be sorted in ascending
|
||||||
order, hence the '0': */
|
order, hence the '0': */
|
||||||
|
|
||||||
@@ -5333,39 +5329,32 @@ innobase_get_at_most_n_mbchars(
|
|||||||
/* If the charset is multi-byte, then we must find the length of the
|
/* 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
|
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
|
characters than n, then we return the length to the end of the last
|
||||||
full character. */
|
character. */
|
||||||
|
|
||||||
if (charset->mbmaxlen > 1) {
|
if (charset->mbmaxlen > 1) {
|
||||||
/* ulint right_value; */
|
|
||||||
|
|
||||||
/* my_charpos() returns the byte length of the first n_chars
|
/* my_charpos() returns the byte length of the first n_chars
|
||||||
characters, or the end of the last full character */
|
characters, or a value bigger than the length of str, if
|
||||||
|
there were not enough full characters in str.
|
||||||
|
|
||||||
|
Why does the code below work:
|
||||||
|
Suppose that we are looking for n UTF-8 characters.
|
||||||
|
|
||||||
|
1) If the string is long enough, then the prefix contains at
|
||||||
|
least n complete UTF-8 characters + maybe some extra
|
||||||
|
characters + an incomplete UTF-8 character. No problem in
|
||||||
|
this case. The function returns the pointer to the
|
||||||
|
end of the nth character.
|
||||||
|
|
||||||
|
2) If the string is not long enough, then the string contains
|
||||||
|
the complete value of a column, that is, only complete UTF-8
|
||||||
|
characters, and we can store in the column prefix index the
|
||||||
|
whole string. */
|
||||||
|
|
||||||
char_length = my_charpos(charset, str,
|
char_length = my_charpos(charset, str,
|
||||||
str + data_len, n_chars);
|
str + data_len, n_chars);
|
||||||
|
|
||||||
/*################################################*/
|
|
||||||
/* TODO: my_charpos sometimes returns a non-sensical value
|
|
||||||
that is BIGGER than data_len: try to fix this bug partly with
|
|
||||||
these heuristics. This is NOT a complete bug fix! */
|
|
||||||
|
|
||||||
if (char_length > data_len) {
|
if (char_length > data_len) {
|
||||||
char_length = data_len;
|
char_length = data_len;
|
||||||
}
|
}
|
||||||
/*################################################*/
|
|
||||||
|
|
||||||
/* printf("data_len %lu, n_chars %lu, char_len %lu\n",
|
|
||||||
data_len, n_chars, char_length);
|
|
||||||
if (data_len < n_chars) {
|
|
||||||
right_value = data_len;
|
|
||||||
} else {
|
|
||||||
right_value = n_chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (right_value != char_length) {
|
|
||||||
printf("ERRRRRROOORRRRRRRRRRRR!!!!!!!!!\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
if (data_len < prefix_len) {
|
if (data_len < prefix_len) {
|
||||||
char_length = data_len;
|
char_length = data_len;
|
||||||
|
@@ -1953,55 +1953,55 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
|
|||||||
{
|
{
|
||||||
ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
|
ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
|
||||||
ALIGN_SIZE(sizeof(Query_cache_result)));
|
ALIGN_SIZE(sizeof(Query_cache_result)));
|
||||||
ulong len= data_len + all_headers_len;
|
|
||||||
ulong align_len= ALIGN_SIZE(len);
|
|
||||||
DBUG_ENTER("Query_cache::allocate_data_chain");
|
|
||||||
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
|
|
||||||
data_len, all_headers_len));
|
|
||||||
|
|
||||||
ulong min_size = (first_block_arg ?
|
ulong min_size = (first_block_arg ?
|
||||||
get_min_first_result_data_size():
|
get_min_first_result_data_size():
|
||||||
get_min_append_result_data_size());
|
get_min_append_result_data_size());
|
||||||
*result_block = allocate_block(max(min_size, align_len),
|
Query_cache_block *prev_block= NULL;
|
||||||
min_result_data_size == 0,
|
Query_cache_block *new_block;
|
||||||
all_headers_len + min_result_data_size,
|
DBUG_ENTER("Query_cache::allocate_data_chain");
|
||||||
1);
|
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
|
||||||
my_bool success = (*result_block != 0);
|
data_len, all_headers_len));
|
||||||
if (success)
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
Query_cache_block *new_block= *result_block;
|
ulong len= data_len + all_headers_len;
|
||||||
|
ulong align_len= ALIGN_SIZE(len);
|
||||||
|
|
||||||
|
if (!(new_block= allocate_block(max(min_size, align_len),
|
||||||
|
min_result_data_size == 0,
|
||||||
|
all_headers_len + min_result_data_size,
|
||||||
|
1)))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("warning", ("Can't allocate block for results"));
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
new_block->n_tables = 0;
|
new_block->n_tables = 0;
|
||||||
new_block->used = 0;
|
new_block->used = min(len, new_block->length);
|
||||||
new_block->type = Query_cache_block::RES_INCOMPLETE;
|
new_block->type = Query_cache_block::RES_INCOMPLETE;
|
||||||
new_block->next = new_block->prev = new_block;
|
new_block->next = new_block->prev = new_block;
|
||||||
Query_cache_result *header = new_block->result();
|
Query_cache_result *header = new_block->result();
|
||||||
header->parent(query_block);
|
header->parent(query_block);
|
||||||
|
|
||||||
if (new_block->length < len)
|
DBUG_PRINT("qcache", ("Block len %lu used %lu",
|
||||||
{
|
|
||||||
/*
|
|
||||||
We got less memory then we need (no big memory blocks) =>
|
|
||||||
Continue to allocated more blocks until we got everything we need.
|
|
||||||
*/
|
|
||||||
Query_cache_block *next_block;
|
|
||||||
if ((success = allocate_data_chain(&next_block,
|
|
||||||
len - new_block->length,
|
|
||||||
query_block, first_block_arg)))
|
|
||||||
double_linked_list_join(new_block, next_block);
|
|
||||||
}
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
new_block->used = min(len, new_block->length);
|
|
||||||
|
|
||||||
DBUG_PRINT("qcache", ("Block len %lu used %lu",
|
|
||||||
new_block->length, new_block->used));
|
new_block->length, new_block->used));
|
||||||
}
|
|
||||||
|
if (prev_block)
|
||||||
|
double_linked_list_join(prev_block, new_block);
|
||||||
else
|
else
|
||||||
DBUG_PRINT("warning", ("Can't allocate block for continue"));
|
*result_block= new_block;
|
||||||
}
|
if (new_block->length >= len)
|
||||||
else
|
break;
|
||||||
DBUG_PRINT("warning", ("Can't allocate block for results"));
|
|
||||||
DBUG_RETURN(success);
|
/*
|
||||||
|
We got less memory then we need (no big memory blocks) =>
|
||||||
|
Continue to allocated more blocks until we got everything we need.
|
||||||
|
*/
|
||||||
|
data_len= len - new_block->length;
|
||||||
|
prev_block= new_block;
|
||||||
|
} while(1);
|
||||||
|
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
Reference in New Issue
Block a user