mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
data0type.h, row0sel.c:
Fix a crash in a simple search with a key: the dtype->len of a true VARCHAR is the payload maximum len in bytes: it does not include the 2 bytes MySQL uses to store the string length ha_innodb.cc: Fix a crash in true VARCHARs in test-innodb: we passed a wrong pointer to the column conversion in an UPDATE rowid_order_innodb.result, ps_3innodb.result, innodb.result, endspace.result: Edit InnoDB test results to reflect the arrival of true VARCHARs mysql-test/r/endspace.result: Edit InnoDB test results to reflect the arrival of true VARCHARs mysql-test/r/innodb.result: Edit InnoDB test results to reflect the arrival of true VARCHARs mysql-test/r/ps_3innodb.result: Edit InnoDB test results to reflect the arrival of true VARCHARs mysql-test/r/rowid_order_innodb.result: Edit InnoDB test results to reflect the arrival of true VARCHARs sql/ha_innodb.cc: Fix a crash in true VARCHARs in test-innodb: we passed a wrong pointer to the column conversion in an UPDATE innobase/row/row0sel.c: Fix a crash in a simple search with a key: the dtype->len of a true VARCHAR is the payload maximum len in bytes: it does not include the 2 bytes MySQL uses to store the string length innobase/include/data0type.h: Fix a crash in a simple search with a key: the dtype->len of a true VARCHAR is the payload maximum len in bytes: it does not include the 2 bytes MySQL uses to store the string length
This commit is contained in:
@ -401,11 +401,20 @@ sym_tab_add_null_lit() */
|
|||||||
|
|
||||||
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, charset code,
|
||||||
|
flags to indicate nullability, signedness,
|
||||||
|
whether this is a binary string, whether this
|
||||||
|
is a true VARCHAR where MySQL uses 2 bytes to
|
||||||
|
store the length */
|
||||||
|
|
||||||
/* the remaining fields do not affect alphabetical ordering: */
|
/* the remaining fields do not affect alphabetical ordering: */
|
||||||
|
|
||||||
ulint len; /* length */
|
ulint len; /* length; for MySQL data this is
|
||||||
|
field->pack_length(), except that for a
|
||||||
|
>= 5.0.3 type true VARCHAR this is the
|
||||||
|
maximum byte length of the string data
|
||||||
|
(in addition to the string, MySQL uses 1 or
|
||||||
|
2 bytes to store the string length) */
|
||||||
ulint prec; /* precision */
|
ulint prec; /* precision */
|
||||||
|
|
||||||
ulint mbminlen; /* minimum length of a character, in bytes */
|
ulint mbminlen; /* minimum length of a character, in bytes */
|
||||||
|
@ -2018,7 +2018,8 @@ Converts a key value stored in MySQL format to an Innobase dtuple. The last
|
|||||||
field of the key value may be just a prefix of a fixed length field: hence
|
field of the key value may be just a prefix of a fixed length field: hence
|
||||||
the parameter key_len. But currently we do not allow search keys where the
|
the parameter key_len. But currently we do not allow search keys where the
|
||||||
last field is only a prefix of the full key field len and print a warning if
|
last field is only a prefix of the full key field len and print a warning if
|
||||||
such appears. */
|
such appears. A counterpart of this function is
|
||||||
|
ha_innobase::store_key_val_for_row() in ha_innodb.cc. */
|
||||||
|
|
||||||
void
|
void
|
||||||
row_sel_convert_mysql_key_to_innobase(
|
row_sel_convert_mysql_key_to_innobase(
|
||||||
@ -2099,13 +2100,10 @@ row_sel_convert_mysql_key_to_innobase(
|
|||||||
type = dfield_get_type(dfield)->mtype;
|
type = dfield_get_type(dfield)->mtype;
|
||||||
|
|
||||||
/* Calculate data length and data field total length */
|
/* Calculate data length and data field total length */
|
||||||
|
|
||||||
if (type == DATA_BLOB ||
|
if (type == DATA_BLOB) {
|
||||||
dtype_get_mysql_type(dfield_get_type(dfield))
|
/* The key field is a column prefix of a BLOB or
|
||||||
== DATA_MYSQL_TRUE_VARCHAR) {
|
TEXT */
|
||||||
|
|
||||||
/* The key field is a column prefix of a BLOB,
|
|
||||||
TEXT, OR TRUE VARCHAR type column */
|
|
||||||
|
|
||||||
ut_a(field->prefix_len > 0);
|
ut_a(field->prefix_len > 0);
|
||||||
|
|
||||||
@ -2122,11 +2120,9 @@ row_sel_convert_mysql_key_to_innobase(
|
|||||||
+ 256 * key_ptr[data_offset + 1];
|
+ 256 * key_ptr[data_offset + 1];
|
||||||
data_field_len = data_offset + 2 + field->prefix_len;
|
data_field_len = data_offset + 2 + field->prefix_len;
|
||||||
|
|
||||||
if (type == DATA_BLOB) {
|
data_offset += 2;
|
||||||
data_offset += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now that we know the length, we store the column
|
/* Now that we know the length, we store the column
|
||||||
value like it would be a fixed char field */
|
value like it would be a fixed char field */
|
||||||
|
|
||||||
} else if (field->prefix_len > 0) {
|
} else if (field->prefix_len > 0) {
|
||||||
@ -2148,6 +2144,18 @@ row_sel_convert_mysql_key_to_innobase(
|
|||||||
data_field_len = data_offset + data_len;
|
data_field_len = data_offset + data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dtype_get_mysql_type(dfield_get_type(dfield))
|
||||||
|
== DATA_MYSQL_TRUE_VARCHAR) {
|
||||||
|
/* In a MySQL key value format, a true VARCHAR is
|
||||||
|
always preceded by 2 bytes of a length field.
|
||||||
|
dfield_get_type(dfield)->len returns the maximum
|
||||||
|
'payload' len in bytes. That does not include the
|
||||||
|
2 bytes that tell the actual data length. */
|
||||||
|
|
||||||
|
data_len += 2;
|
||||||
|
data_field_len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Storing may use at most data_len bytes of buf */
|
/* Storing may use at most data_len bytes of buf */
|
||||||
|
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
|
@ -178,7 +178,7 @@ teststring
|
|||||||
teststring
|
teststring
|
||||||
explain select * from t1 order by text1;
|
explain select * from t1 order by text1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index NULL key1 32 NULL 3 Using index
|
1 SIMPLE t1 index NULL key1 34 NULL 3 Using index
|
||||||
alter table t1 modify text1 char(32) binary not null;
|
alter table t1 modify text1 char(32) binary not null;
|
||||||
select * from t1 order by text1;
|
select * from t1 order by text1;
|
||||||
text1
|
text1
|
||||||
|
@ -1466,13 +1466,13 @@ Error 1146 Table 'test.t4' doesn't exist
|
|||||||
checksum table t1, t2, t3;
|
checksum table t1, t2, t3;
|
||||||
Table Checksum
|
Table Checksum
|
||||||
test.t1 2948697075
|
test.t1 2948697075
|
||||||
test.t2 968604391
|
test.t2 1157260244
|
||||||
test.t3 968604391
|
test.t3 1157260244
|
||||||
checksum table t1, t2, t3 extended;
|
checksum table t1, t2, t3 extended;
|
||||||
Table Checksum
|
Table Checksum
|
||||||
test.t1 3092701434
|
test.t1 3092701434
|
||||||
test.t2 968604391
|
test.t2 1157260244
|
||||||
test.t3 968604391
|
test.t3 1157260244
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb;
|
create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb;
|
||||||
insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt');
|
insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt');
|
||||||
@ -1809,6 +1809,5 @@ show variables like "innodb_thread_sleep_delay";
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
innodb_thread_sleep_delay 10000
|
innodb_thread_sleep_delay 10000
|
||||||
create table t1 (v varchar(16384)) engine=innodb;
|
create table t1 (v varchar(16384)) engine=innodb;
|
||||||
ERROR 42000: Column length too big for column 'v' (max = 255); use BLOB instead
|
|
||||||
create table t1 (a bit, key(a)) engine=innodb;
|
create table t1 (a bit, key(a)) engine=innodb;
|
||||||
ERROR 42000: The storage engine for the table doesn't support BIT FIELD
|
ERROR 42000: The storage engine for the table doesn't support BIT FIELD
|
||||||
|
@ -70,7 +70,7 @@ def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
|
|||||||
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
|
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
|
||||||
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
|
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
|
||||||
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
|
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
|
||||||
def test t9 t9 c22 c22 254 30 30 Y 0 0 8
|
def test t9 t9 c22 c22 253 30 30 Y 0 0 8
|
||||||
def test t9 t9 c23 c23 252 255 8 Y 144 0 63
|
def test t9 t9 c23 c23 252 255 8 Y 144 0 63
|
||||||
def test t9 t9 c24 c24 252 255 8 Y 16 0 8
|
def test t9 t9 c24 c24 252 255 8 Y 16 0 8
|
||||||
def test t9 t9 c25 c25 252 65535 4 Y 144 0 63
|
def test t9 t9 c25 c25 252 65535 4 Y 144 0 63
|
||||||
@ -1691,8 +1691,8 @@ affected rows: 3
|
|||||||
info: Records: 3 Duplicates: 0 Warnings: 0
|
info: Records: 3 Duplicates: 0 Warnings: 0
|
||||||
select a,b from t2 order by a ;
|
select a,b from t2 order by a ;
|
||||||
a b
|
a b
|
||||||
3 duplicate
|
3 duplicate
|
||||||
4 duplicate
|
4 duplicate
|
||||||
103 three
|
103 three
|
||||||
delete from t2 ;
|
delete from t2 ;
|
||||||
prepare stmt1 from ' insert into t2 (b,a)
|
prepare stmt1 from ' insert into t2 (b,a)
|
||||||
@ -1710,8 +1710,8 @@ affected rows: 3
|
|||||||
info: Records: 3 Duplicates: 0 Warnings: 0
|
info: Records: 3 Duplicates: 0 Warnings: 0
|
||||||
select a,b from t2 order by a ;
|
select a,b from t2 order by a ;
|
||||||
a b
|
a b
|
||||||
3 duplicate
|
3 duplicate
|
||||||
4 duplicate
|
4 duplicate
|
||||||
103 three
|
103 three
|
||||||
drop table t2;
|
drop table t2;
|
||||||
drop table if exists t5 ;
|
drop table if exists t5 ;
|
||||||
|
@ -178,9 +178,9 @@ insert into t1 values ('','empt',2,2),
|
|||||||
('dddd','d--d',2,2);
|
('dddd','d--d',2,2);
|
||||||
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
|
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
|
||||||
pk1 pk2 key1 key2
|
pk1 pk2 key1 key2
|
||||||
empt 2 2
|
|
||||||
a a--a 2 2
|
a a--a 2 2
|
||||||
bb b--b 2 2
|
bb b--b 2 2
|
||||||
ccc c--c 2 2
|
ccc c--c 2 2
|
||||||
dddd d--d 2 2
|
dddd d--d 2 2
|
||||||
|
empt 2 2
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -2920,6 +2920,7 @@ calc_row_difference(
|
|||||||
ulint o_len;
|
ulint o_len;
|
||||||
ulint n_len;
|
ulint n_len;
|
||||||
ulint col_pack_len;
|
ulint col_pack_len;
|
||||||
|
byte* new_mysql_row_col;
|
||||||
byte* o_ptr;
|
byte* o_ptr;
|
||||||
byte* n_ptr;
|
byte* n_ptr;
|
||||||
byte* buf;
|
byte* buf;
|
||||||
@ -2948,10 +2949,17 @@ calc_row_difference(
|
|||||||
o_ptr = (byte*) old_row + get_field_offset(table, field);
|
o_ptr = (byte*) old_row + get_field_offset(table, field);
|
||||||
n_ptr = (byte*) new_row + get_field_offset(table, field);
|
n_ptr = (byte*) new_row + get_field_offset(table, field);
|
||||||
|
|
||||||
|
/* Use new_mysql_row_col and col_pack_len save the values */
|
||||||
|
|
||||||
|
new_mysql_row_col = n_ptr;
|
||||||
col_pack_len = field->pack_length();
|
col_pack_len = field->pack_length();
|
||||||
|
|
||||||
o_len = col_pack_len;
|
o_len = col_pack_len;
|
||||||
n_len = col_pack_len;
|
n_len = col_pack_len;
|
||||||
|
|
||||||
|
/* We use o_ptr and n_ptr to dig up the actual data for
|
||||||
|
comparison. */
|
||||||
|
|
||||||
field_mysql_type = field->type();
|
field_mysql_type = field->type();
|
||||||
|
|
||||||
col_type = get_innobase_type_from_mysql_type(field);
|
col_type = get_innobase_type_from_mysql_type(field);
|
||||||
@ -3017,15 +3025,11 @@ calc_row_difference(
|
|||||||
&dfield,
|
&dfield,
|
||||||
(byte*)buf,
|
(byte*)buf,
|
||||||
TRUE,
|
TRUE,
|
||||||
n_ptr,
|
new_mysql_row_col,
|
||||||
col_pack_len,
|
col_pack_len,
|
||||||
prebuilt->table->comp);
|
prebuilt->table->comp);
|
||||||
ufield->new_val.data =
|
ufield->new_val.data = dfield.data;
|
||||||
dfield_get_data_noninline(
|
ufield->new_val.len = dfield.len;
|
||||||
&dfield);
|
|
||||||
ufield->new_val.len =
|
|
||||||
dfield_get_len_noninline(
|
|
||||||
&dfield);
|
|
||||||
} else {
|
} else {
|
||||||
ufield->new_val.data = NULL;
|
ufield->new_val.data = NULL;
|
||||||
ufield->new_val.len = UNIV_SQL_NULL;
|
ufield->new_val.len = UNIV_SQL_NULL;
|
||||||
|
Reference in New Issue
Block a user