mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge jlindstrom@build.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/jan/mysql-4.1 mysql-test/r/ctype_utf8.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged
This commit is contained in:
@ -2400,14 +2400,17 @@ btr_index_rec_validate(
|
|||||||
dtype_t* type = dict_index_get_nth_type(index, i);
|
dtype_t* type = dict_index_get_nth_type(index, i);
|
||||||
|
|
||||||
rec_get_nth_field(rec, i, &len);
|
rec_get_nth_field(rec, i, &len);
|
||||||
|
|
||||||
|
/* Note that prefix indexes are not fixed size even when
|
||||||
|
their type is CHAR. */
|
||||||
|
|
||||||
if ((dict_index_get_nth_field(index, i)->prefix_len == 0
|
if ((dict_index_get_nth_field(index, i)->prefix_len == 0
|
||||||
&& len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
|
&& len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
|
||||||
&& len != dtype_get_fixed_size(type))
|
&& len != dtype_get_fixed_size(type))
|
||||||
||
|
||
|
||||||
(dict_index_get_nth_field(index, i)->prefix_len > 0
|
(dict_index_get_nth_field(index, i)->prefix_len > 0
|
||||||
&& len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
|
&& len != UNIV_SQL_NULL
|
||||||
&& len !=
|
&& len >
|
||||||
dict_index_get_nth_field(index, i)->prefix_len)) {
|
dict_index_get_nth_field(index, i)->prefix_len)) {
|
||||||
|
|
||||||
btr_index_rec_validate_report(page, rec, index);
|
btr_index_rec_validate_report(page, rec, index);
|
||||||
|
@ -756,9 +756,13 @@ lock_rec_has_to_wait(
|
|||||||
ulint type_mode,/* in: precise mode of the new lock to set:
|
ulint type_mode,/* in: precise mode of the new lock to set:
|
||||||
LOCK_S or LOCK_X, possibly ORed to
|
LOCK_S or LOCK_X, possibly ORed to
|
||||||
LOCK_GAP or LOCK_REC_NOT_GAP, LOCK_INSERT_INTENTION */
|
LOCK_GAP or LOCK_REC_NOT_GAP, LOCK_INSERT_INTENTION */
|
||||||
lock_t* lock2) /* in: another record lock; NOTE that it is assumed
|
lock_t* lock2, /* in: another record lock; NOTE that it is assumed
|
||||||
that this has a lock bit set on the same record as
|
that this has a lock bit set on the same record as
|
||||||
in the new lock we are setting */
|
in the new lock we are setting */
|
||||||
|
ibool lock_is_on_supremum) /* in: TRUE if we are setting the lock
|
||||||
|
on the 'supremum' record of an index
|
||||||
|
page: we know then that the lock request
|
||||||
|
is really for a 'gap' type lock */
|
||||||
{
|
{
|
||||||
ut_ad(trx && lock2);
|
ut_ad(trx && lock2);
|
||||||
ut_ad(lock_get_type(lock2) == LOCK_REC);
|
ut_ad(lock_get_type(lock2) == LOCK_REC);
|
||||||
@ -770,10 +774,22 @@ lock_rec_has_to_wait(
|
|||||||
/* We have somewhat complex rules when gap type record locks
|
/* We have somewhat complex rules when gap type record locks
|
||||||
cause waits */
|
cause waits */
|
||||||
|
|
||||||
if ((type_mode & LOCK_REC_NOT_GAP)
|
if ((lock_is_on_supremum || (type_mode & LOCK_GAP))
|
||||||
|
&& !(type_mode & LOCK_INSERT_INTENTION)) {
|
||||||
|
|
||||||
|
/* Gap type locks without LOCK_INSERT_INTENTION flag
|
||||||
|
do not need to wait for anything. This is because
|
||||||
|
different users can have conflicting lock types
|
||||||
|
on gaps. */
|
||||||
|
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(type_mode & LOCK_INSERT_INTENTION)
|
||||||
&& lock_rec_get_gap(lock2)) {
|
&& lock_rec_get_gap(lock2)) {
|
||||||
/* Lock on just the record does not need to wait for
|
|
||||||
a gap type lock */
|
/* Record lock (LOCK_ORDINARY or LOCK_REC_NOT_GAP
|
||||||
|
does not need to wait for a gap type lock */
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
@ -829,9 +845,13 @@ lock_has_to_wait(
|
|||||||
lock_get_mode(lock2))) {
|
lock_get_mode(lock2))) {
|
||||||
if (lock_get_type(lock1) == LOCK_REC) {
|
if (lock_get_type(lock1) == LOCK_REC) {
|
||||||
ut_ad(lock_get_type(lock2) == LOCK_REC);
|
ut_ad(lock_get_type(lock2) == LOCK_REC);
|
||||||
|
|
||||||
|
/* If this lock request is for a supremum record
|
||||||
|
then the second bit on the lock bitmap is set */
|
||||||
|
|
||||||
return(lock_rec_has_to_wait(lock1->trx,
|
return(lock_rec_has_to_wait(lock1->trx,
|
||||||
lock1->type_mode, lock2));
|
lock1->type_mode, lock2,
|
||||||
|
lock_rec_get_nth_bit(lock1,1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
@ -1420,7 +1440,8 @@ lock_rec_other_has_conflicting(
|
|||||||
lock = lock_rec_get_first(rec);
|
lock = lock_rec_get_first(rec);
|
||||||
|
|
||||||
while (lock) {
|
while (lock) {
|
||||||
if (lock_rec_has_to_wait(trx, mode, lock)) {
|
if (lock_rec_has_to_wait(trx, mode, lock,
|
||||||
|
page_rec_is_supremum(rec))) {
|
||||||
|
|
||||||
return(lock);
|
return(lock);
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ cmp_dtuple_rec_with_match(
|
|||||||
ulint cur_bytes; /* number of already matched bytes
|
ulint cur_bytes; /* number of already matched bytes
|
||||||
in current field */
|
in current field */
|
||||||
int ret = 3333; /* return value */
|
int ret = 3333; /* return value */
|
||||||
|
|
||||||
ut_ad(dtuple && rec && matched_fields && matched_bytes);
|
ut_ad(dtuple && rec && matched_fields && matched_bytes);
|
||||||
ut_ad(dtuple_check_typed(dtuple));
|
ut_ad(dtuple_check_typed(dtuple));
|
||||||
|
|
||||||
@ -541,7 +541,8 @@ cmp_dtuple_rec_with_match(
|
|||||||
&& dtype_get_charset_coll(cur_type->prtype) !=
|
&& dtype_get_charset_coll(cur_type->prtype) !=
|
||||||
data_mysql_latin1_swedish_charset_coll)) {
|
data_mysql_latin1_swedish_charset_coll)) {
|
||||||
|
|
||||||
ret = cmp_whole_field(cur_type,
|
ret = cmp_whole_field(
|
||||||
|
cur_type,
|
||||||
dfield_get_data(dtuple_field), dtuple_f_len,
|
dfield_get_data(dtuple_field), dtuple_f_len,
|
||||||
rec_b_ptr, rec_f_len);
|
rec_b_ptr, rec_f_len);
|
||||||
|
|
||||||
|
@ -1022,6 +1022,33 @@ row_ins_set_shared_rec_lock(
|
|||||||
|
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Sets a exclusive lock on a record. Used in locking possible duplicate key
|
||||||
|
records */
|
||||||
|
static
|
||||||
|
ulint
|
||||||
|
row_ins_set_exclusive_rec_lock(
|
||||||
|
/*============================*/
|
||||||
|
/* out: DB_SUCCESS or error code */
|
||||||
|
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
|
||||||
|
LOCK_REC_NOT_GAP type lock */
|
||||||
|
rec_t* rec, /* in: record */
|
||||||
|
dict_index_t* index, /* in: index */
|
||||||
|
que_thr_t* thr) /* in: query thread */
|
||||||
|
{
|
||||||
|
ulint err;
|
||||||
|
|
||||||
|
if (index->type & DICT_CLUSTERED) {
|
||||||
|
err = lock_clust_rec_read_check_and_lock(0, rec, index, LOCK_X,
|
||||||
|
type, thr);
|
||||||
|
} else {
|
||||||
|
err = lock_sec_rec_read_check_and_lock(0, rec, index, LOCK_X,
|
||||||
|
type, thr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(err);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
Checks if foreign key constraint fails for an index entry. Sets shared locks
|
Checks if foreign key constraint fails for an index entry. Sets shared locks
|
||||||
@ -1451,6 +1478,8 @@ row_ins_scan_sec_index_for_duplicate(
|
|||||||
ulint err = DB_SUCCESS;
|
ulint err = DB_SUCCESS;
|
||||||
ibool moved;
|
ibool moved;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
trx_t *trx;
|
||||||
|
ibool success;
|
||||||
|
|
||||||
n_unique = dict_index_get_n_unique(index);
|
n_unique = dict_index_get_n_unique(index);
|
||||||
|
|
||||||
@ -1488,8 +1517,24 @@ row_ins_scan_sec_index_for_duplicate(
|
|||||||
|
|
||||||
/* Try to place a lock on the index record */
|
/* Try to place a lock on the index record */
|
||||||
|
|
||||||
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec, index,
|
trx = thr_get_trx(thr);
|
||||||
thr);
|
ut_ad(trx);
|
||||||
|
dict_accept(*trx->mysql_query_str, "REPLACE", &success);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
|
||||||
|
/* The manual defines the REPLACE semantics that it
|
||||||
|
is either an INSERT or DELETE(s) for duplicate key
|
||||||
|
+ INSERT. Therefore, we should take X-lock for
|
||||||
|
duplicates */
|
||||||
|
|
||||||
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
|
LOCK_ORDINARY,rec,index,thr);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
err = row_ins_set_shared_rec_lock(
|
||||||
|
LOCK_ORDINARY, rec, index,thr);
|
||||||
|
}
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
|
||||||
@ -1556,6 +1601,7 @@ row_ins_duplicate_error_in_clust(
|
|||||||
page_t* page;
|
page_t* page;
|
||||||
ulint n_unique;
|
ulint n_unique;
|
||||||
trx_t* trx = thr_get_trx(thr);
|
trx_t* trx = thr_get_trx(thr);
|
||||||
|
ibool success;
|
||||||
|
|
||||||
UT_NOT_USED(mtr);
|
UT_NOT_USED(mtr);
|
||||||
|
|
||||||
@ -1588,9 +1634,27 @@ row_ins_duplicate_error_in_clust(
|
|||||||
is needed in logical logging of MySQL to make
|
is needed in logical logging of MySQL to make
|
||||||
sure that in roll-forward we get the same duplicate
|
sure that in roll-forward we get the same duplicate
|
||||||
errors as in original execution */
|
errors as in original execution */
|
||||||
|
|
||||||
err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,
|
dict_accept(*trx->mysql_query_str, "REPLACE",
|
||||||
rec, cursor->index, thr);
|
&success);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
|
||||||
|
/* The manual defines the REPLACE semantics
|
||||||
|
that it is either an INSERT or DELETE(s)
|
||||||
|
for duplicate key + INSERT. Therefore, we
|
||||||
|
should take X-lock for duplicates */
|
||||||
|
|
||||||
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
|
LOCK_REC_NOT_GAP,rec,cursor->index,
|
||||||
|
thr);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
err = row_ins_set_shared_rec_lock(
|
||||||
|
LOCK_REC_NOT_GAP,rec, cursor->index,
|
||||||
|
thr);
|
||||||
|
}
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
|
||||||
return(err);
|
return(err);
|
||||||
@ -1611,8 +1675,30 @@ row_ins_duplicate_error_in_clust(
|
|||||||
|
|
||||||
if (rec != page_get_supremum_rec(page)) {
|
if (rec != page_get_supremum_rec(page)) {
|
||||||
|
|
||||||
err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,
|
|
||||||
rec, cursor->index, thr);
|
/* The manual defines the REPLACE semantics that it
|
||||||
|
is either an INSERT or DELETE(s) for duplicate key
|
||||||
|
+ INSERT. Therefore, we should take X-lock for
|
||||||
|
duplicates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Is the first word in MySQL query REPLACE ? */
|
||||||
|
|
||||||
|
dict_accept(*trx->mysql_query_str, "REPLACE",
|
||||||
|
&success);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
|
||||||
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
|
LOCK_REC_NOT_GAP,
|
||||||
|
rec,cursor->index,thr);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
err = row_ins_set_shared_rec_lock(
|
||||||
|
LOCK_REC_NOT_GAP,rec,
|
||||||
|
cursor->index, thr);
|
||||||
|
}
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
|
||||||
return(err);
|
return(err);
|
||||||
@ -1913,6 +1999,7 @@ row_ins_index_entry_set_vals(
|
|||||||
dfield_t* row_field;
|
dfield_t* row_field;
|
||||||
ulint n_fields;
|
ulint n_fields;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
ut_ad(entry && row);
|
ut_ad(entry && row);
|
||||||
|
|
||||||
@ -1926,10 +2013,18 @@ row_ins_index_entry_set_vals(
|
|||||||
|
|
||||||
/* Check column prefix indexes */
|
/* Check column prefix indexes */
|
||||||
if (ind_field->prefix_len > 0
|
if (ind_field->prefix_len > 0
|
||||||
&& dfield_get_len(row_field) != UNIV_SQL_NULL
|
&& dfield_get_len(row_field) != UNIV_SQL_NULL) {
|
||||||
&& dfield_get_len(row_field) > ind_field->prefix_len) {
|
|
||||||
|
/* For prefix keys get the storage length
|
||||||
field->len = ind_field->prefix_len;
|
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);
|
||||||
} else {
|
} else {
|
||||||
field->len = row_field->len;
|
field->len = row_field->len;
|
||||||
}
|
}
|
||||||
@ -2214,4 +2309,4 @@ error_handling:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return(thr);
|
return(thr);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,8 @@ row_build_index_entry(
|
|||||||
dfield_t* dfield2;
|
dfield_t* dfield2;
|
||||||
dict_col_t* col;
|
dict_col_t* col;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
ulint storage_len;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
ut_ad(row && index && heap);
|
ut_ad(row && index && heap);
|
||||||
ut_ad(dtuple_check_typed(row));
|
ut_ad(dtuple_check_typed(row));
|
||||||
@ -139,10 +141,20 @@ row_build_index_entry(
|
|||||||
|
|
||||||
/* If a column prefix index, take only the prefix */
|
/* If a column prefix index, take only the prefix */
|
||||||
if (ind_field->prefix_len > 0
|
if (ind_field->prefix_len > 0
|
||||||
&& dfield_get_len(dfield2) != UNIV_SQL_NULL
|
&& dfield_get_len(dfield2) != UNIV_SQL_NULL) {
|
||||||
&& dfield_get_len(dfield2) > ind_field->prefix_len) {
|
|
||||||
|
|
||||||
dfield_set_len(dfield, ind_field->prefix_len);
|
/* 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),
|
||||||
|
ind_field->prefix_len,
|
||||||
|
dfield_get_len(dfield2),dfield2->data);
|
||||||
|
|
||||||
|
dfield_set_len(dfield,storage_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,6 +472,7 @@ row_build_row_ref_from_row(
|
|||||||
dict_col_t* col;
|
dict_col_t* col;
|
||||||
ulint ref_len;
|
ulint ref_len;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
ut_ad(ref && table && row);
|
ut_ad(ref && table && row);
|
||||||
|
|
||||||
@ -481,10 +494,18 @@ row_build_row_ref_from_row(
|
|||||||
dfield_copy(dfield, dfield2);
|
dfield_copy(dfield, dfield2);
|
||||||
|
|
||||||
if (field->prefix_len > 0
|
if (field->prefix_len > 0
|
||||||
&& dfield->len != UNIV_SQL_NULL
|
&& dfield->len != UNIV_SQL_NULL) {
|
||||||
&& dfield->len > field->prefix_len) {
|
|
||||||
|
|
||||||
dfield->len = field->prefix_len;
|
/* 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,
|
||||||
|
dfield->len,dfield->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ row_sel_sec_rec_is_for_clust_rec(
|
|||||||
ulint clust_len;
|
ulint clust_len;
|
||||||
ulint n;
|
ulint n;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
UT_NOT_USED(clust_index);
|
UT_NOT_USED(clust_index);
|
||||||
|
|
||||||
@ -91,10 +92,18 @@ row_sel_sec_rec_is_for_clust_rec(
|
|||||||
sec_field = rec_get_nth_field(sec_rec, i, &sec_len);
|
sec_field = rec_get_nth_field(sec_rec, i, &sec_len);
|
||||||
|
|
||||||
if (ifield->prefix_len > 0
|
if (ifield->prefix_len > 0
|
||||||
&& clust_len != UNIV_SQL_NULL
|
&& clust_len != UNIV_SQL_NULL) {
|
||||||
&& clust_len > ifield->prefix_len) {
|
|
||||||
|
|
||||||
clust_len = ifield->prefix_len;
|
/* 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),
|
||||||
|
ifield->prefix_len,
|
||||||
|
clust_len,clust_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != cmp_data_data(dict_col_get_type(col),
|
if (0 != cmp_data_data(dict_col_get_type(col),
|
||||||
|
@ -842,6 +842,7 @@ row_upd_index_replace_new_col_vals_index_pos(
|
|||||||
dfield_t* new_val;
|
dfield_t* new_val;
|
||||||
ulint j;
|
ulint j;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
ut_ad(index);
|
ut_ad(index);
|
||||||
|
|
||||||
@ -871,10 +872,19 @@ row_upd_index_replace_new_col_vals_index_pos(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (field->prefix_len > 0
|
if (field->prefix_len > 0
|
||||||
&& new_val->len != UNIV_SQL_NULL
|
&& new_val->len != UNIV_SQL_NULL) {
|
||||||
&& new_val->len > field->prefix_len) {
|
|
||||||
|
|
||||||
dfield->len = field->prefix_len;
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -904,6 +914,7 @@ row_upd_index_replace_new_col_vals(
|
|||||||
dfield_t* new_val;
|
dfield_t* new_val;
|
||||||
ulint j;
|
ulint j;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
dtype_t* cur_type;
|
||||||
|
|
||||||
ut_ad(index);
|
ut_ad(index);
|
||||||
|
|
||||||
@ -933,10 +944,19 @@ row_upd_index_replace_new_col_vals(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (field->prefix_len > 0
|
if (field->prefix_len > 0
|
||||||
&& new_val->len != UNIV_SQL_NULL
|
&& new_val->len != UNIV_SQL_NULL) {
|
||||||
&& new_val->len > field->prefix_len) {
|
|
||||||
|
|
||||||
dfield->len = field->prefix_len;
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,6 +316,39 @@ select c cb20 from t1 where c=repeat('b',20);
|
|||||||
cb20
|
cb20
|
||||||
bbbbbbbbbbbbbbbbbbbb
|
bbbbbbbbbbbbbbbbbbbb
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb;
|
||||||
|
insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z');
|
||||||
|
insert into t1 values ('aaaaaaaaaa');
|
||||||
|
insert into t1 values ('aaaaaaaaaaa');
|
||||||
|
ERROR 23000: Duplicate entry 'aaaaaaaaaaa' for key 1
|
||||||
|
insert into t1 values ('aaaaaaaaaaaa');
|
||||||
|
ERROR 23000: Duplicate entry 'aaaaaaaaaaaa' for key 1
|
||||||
|
insert into t1 values (repeat('b',20));
|
||||||
|
select c c1 from t1 where c='1';
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
select c c2 from t1 where c='2';
|
||||||
|
c2
|
||||||
|
2
|
||||||
|
select c c3 from t1 where c='3';
|
||||||
|
c3
|
||||||
|
3
|
||||||
|
select c cx from t1 where c='x';
|
||||||
|
cx
|
||||||
|
x
|
||||||
|
select c cy from t1 where c='y';
|
||||||
|
cy
|
||||||
|
y
|
||||||
|
select c cz from t1 where c='z';
|
||||||
|
cz
|
||||||
|
z
|
||||||
|
select c ca10 from t1 where c='aaaaaaaaaa';
|
||||||
|
ca10
|
||||||
|
aaaaaaaaaa
|
||||||
|
select c cb20 from t1 where c=repeat('b',20);
|
||||||
|
cb20
|
||||||
|
bbbbbbbbbbbbbbbbbbbb
|
||||||
|
drop table t1;
|
||||||
create table t1 (c char(3) character set utf8, unique (c(2)));
|
create table t1 (c char(3) character set utf8, unique (c(2)));
|
||||||
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
|
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
|
||||||
insert into t1 values ('a');
|
insert into t1 values ('a');
|
||||||
@ -339,6 +372,29 @@ insert into t1 values ('ꪪꪪ');
|
|||||||
insert into t1 values ('ꪪꪪꪪ');
|
insert into t1 values ('ꪪꪪꪪ');
|
||||||
ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1
|
ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb;
|
||||||
|
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
|
||||||
|
insert into t1 values ('a');
|
||||||
|
insert into t1 values ('aa');
|
||||||
|
insert into t1 values ('aaa');
|
||||||
|
ERROR 23000: Duplicate entry 'aaa' for key 1
|
||||||
|
insert into t1 values ('b');
|
||||||
|
insert into t1 values ('bb');
|
||||||
|
insert into t1 values ('bbb');
|
||||||
|
ERROR 23000: Duplicate entry 'bbb' for key 1
|
||||||
|
insert into t1 values ('а');
|
||||||
|
insert into t1 values ('аа');
|
||||||
|
insert into t1 values ('ааа');
|
||||||
|
ERROR 23000: Duplicate entry 'ааа' for key 1
|
||||||
|
insert into t1 values ('б');
|
||||||
|
insert into t1 values ('бб');
|
||||||
|
insert into t1 values ('ббб');
|
||||||
|
ERROR 23000: Duplicate entry 'ббб' for key 1
|
||||||
|
insert into t1 values ('ꪪ');
|
||||||
|
insert into t1 values ('ꪪꪪ');
|
||||||
|
insert into t1 values ('ꪪꪪꪪ');
|
||||||
|
ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1
|
||||||
|
drop table t1;
|
||||||
create table t1 (
|
create table t1 (
|
||||||
c char(10) character set utf8,
|
c char(10) character set utf8,
|
||||||
unique key a using hash (c(1))
|
unique key a using hash (c(1))
|
||||||
@ -611,6 +667,16 @@ str
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (
|
create table t1 (
|
||||||
str varchar(255) character set utf8 not null,
|
str varchar(255) character set utf8 not null,
|
||||||
|
key str (str(2))
|
||||||
|
) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('str');
|
||||||
|
INSERT INTO t1 VALUES ('str2');
|
||||||
|
select * from t1 where str='str';
|
||||||
|
str
|
||||||
|
str
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (
|
||||||
|
str varchar(255) character set utf8 not null,
|
||||||
key str using btree (str(2))
|
key str using btree (str(2))
|
||||||
) engine=heap;
|
) engine=heap;
|
||||||
INSERT INTO t1 VALUES ('str');
|
INSERT INTO t1 VALUES ('str');
|
||||||
|
@ -217,6 +217,27 @@ select c ca10 from t1 where c='aaaaaaaaaa';
|
|||||||
select c cb20 from t1 where c=repeat('b',20);
|
select c cb20 from t1 where c=repeat('b',20);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug 4521: unique key prefix interacts poorly with utf8
|
||||||
|
# InnoDB: keys with prefix compression, case insensitive collation.
|
||||||
|
#
|
||||||
|
create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb;
|
||||||
|
insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z');
|
||||||
|
insert into t1 values ('aaaaaaaaaa');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('aaaaaaaaaaa');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('aaaaaaaaaaaa');
|
||||||
|
insert into t1 values (repeat('b',20));
|
||||||
|
select c c1 from t1 where c='1';
|
||||||
|
select c c2 from t1 where c='2';
|
||||||
|
select c c3 from t1 where c='3';
|
||||||
|
select c cx from t1 where c='x';
|
||||||
|
select c cy from t1 where c='y';
|
||||||
|
select c cz from t1 where c='z';
|
||||||
|
select c ca10 from t1 where c='aaaaaaaaaa';
|
||||||
|
select c cb20 from t1 where c=repeat('b',20);
|
||||||
|
drop table t1;
|
||||||
#
|
#
|
||||||
# Bug 4521: unique key prefix interacts poorly with utf8
|
# Bug 4521: unique key prefix interacts poorly with utf8
|
||||||
# MYISAM: fixed length keys, case insensitive collation
|
# MYISAM: fixed length keys, case insensitive collation
|
||||||
@ -244,7 +265,33 @@ insert into t1 values ('ꪪꪪ');
|
|||||||
--error 1062
|
--error 1062
|
||||||
insert into t1 values ('ꪪꪪꪪ');
|
insert into t1 values ('ꪪꪪꪪ');
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# Bug 4521: unique key prefix interacts poorly with utf8
|
||||||
|
# InnoDB: fixed length keys, case insensitive collation
|
||||||
|
#
|
||||||
|
create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb;
|
||||||
|
insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
|
||||||
|
insert into t1 values ('a');
|
||||||
|
insert into t1 values ('aa');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('aaa');
|
||||||
|
insert into t1 values ('b');
|
||||||
|
insert into t1 values ('bb');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('bbb');
|
||||||
|
insert into t1 values ('а');
|
||||||
|
insert into t1 values ('аа');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('ааа');
|
||||||
|
insert into t1 values ('б');
|
||||||
|
insert into t1 values ('бб');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('ббб');
|
||||||
|
insert into t1 values ('ꪪ');
|
||||||
|
insert into t1 values ('ꪪꪪ');
|
||||||
|
--error 1062
|
||||||
|
insert into t1 values ('ꪪꪪꪪ');
|
||||||
|
drop table t1;
|
||||||
#
|
#
|
||||||
# Bug 4531: unique key prefix interacts poorly with utf8
|
# Bug 4531: unique key prefix interacts poorly with utf8
|
||||||
# Check HEAP+HASH, case insensitive collation
|
# Check HEAP+HASH, case insensitive collation
|
||||||
@ -454,6 +501,18 @@ INSERT INTO t1 VALUES ('str2');
|
|||||||
select * from t1 where str='str';
|
select * from t1 where str='str';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
# Bug#4594: column index make = failed for gbk, but like works
|
||||||
|
# Check InnoDB
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
str varchar(255) character set utf8 not null,
|
||||||
|
key str (str(2))
|
||||||
|
) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('str');
|
||||||
|
INSERT INTO t1 VALUES ('str2');
|
||||||
|
select * from t1 where str='str';
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# the same for HEAP+BTREE
|
# the same for HEAP+BTREE
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ have disables the InnoDB inlining in this file. */
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <myisampack.h>
|
#include <myisampack.h>
|
||||||
#include <mysys_err.h>
|
#include <mysys_err.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
|
||||||
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
|
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
|
||||||
|
|
||||||
@ -5270,4 +5271,61 @@ ulonglong ha_innobase::get_mysql_bin_log_pos()
|
|||||||
return trx_sys_mysql_bin_log_pos;
|
return trx_sys_mysql_bin_log_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
/***********************************************************************
|
||||||
|
This function finds charset information and returns the character
|
||||||
|
length for multibyte character set. */
|
||||||
|
|
||||||
|
ulint innobase_get_charset_mbmaxlen(
|
||||||
|
ulint charset_id) /* in: charset id */
|
||||||
|
{
|
||||||
|
CHARSET_INFO* charset; /* charset used in the field */
|
||||||
|
|
||||||
|
charset = get_charset(charset_id,MYF(MY_WME));
|
||||||
|
|
||||||
|
ut_ad(charset);
|
||||||
|
ut_ad(charset->mbmaxlen);
|
||||||
|
|
||||||
|
return charset->mbmaxlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
/***********************************************************************
|
||||||
|
This function finds charset information and returns position the nth
|
||||||
|
character for multibyte character set.*/
|
||||||
|
|
||||||
|
ulint innobase_get_at_most_n_mbchars(
|
||||||
|
ulint charset_id, /* in: character set id */
|
||||||
|
ulint nth, /* in: nth character */
|
||||||
|
ulint data_len, /* in: length of the sting in bytes */
|
||||||
|
const char *pos) /* in: character string */
|
||||||
|
{
|
||||||
|
ulint byte_length; /* storage length, in bytes. */
|
||||||
|
ulint char_length; /* character length in bytes */
|
||||||
|
CHARSET_INFO* charset; /* charset used in the field */
|
||||||
|
|
||||||
|
ut_ad(pos);
|
||||||
|
byte_length = data_len;
|
||||||
|
|
||||||
|
charset = get_charset(charset_id,MYF(MY_WME));
|
||||||
|
|
||||||
|
ut_ad(charset);
|
||||||
|
ut_ad(charset->mbmaxlen);
|
||||||
|
|
||||||
|
char_length= byte_length / charset->mbmaxlen;
|
||||||
|
nth = nth / charset->mbmaxlen;
|
||||||
|
|
||||||
|
if (byte_length > char_length)
|
||||||
|
{
|
||||||
|
char_length= my_charpos(charset, pos, pos + byte_length, nth);
|
||||||
|
set_if_smaller(char_length, byte_length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
char_length = nth;
|
||||||
|
|
||||||
|
return char_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_INNOBASE_DB */
|
#endif /* HAVE_INNOBASE_DB */
|
||||||
|
@ -229,3 +229,4 @@ my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
|
|||||||
void innobase_release_temporary_latches(void* innobase_tid);
|
void innobase_release_temporary_latches(void* innobase_tid);
|
||||||
|
|
||||||
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
|
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user