mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge gshchepa.loc:/home/uchum/work/bk-trees/mysql-4.1-opt
into gshchepa.loc:/home/uchum/work/bk-trees/mysql-5.0-opt-13191
This commit is contained in:
@ -111,6 +111,39 @@ c1
|
|||||||
Before and after comparison
|
Before and after comparison
|
||||||
0
|
0
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 1
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 1
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 1
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 cnt
|
||||||
|
1a 2
|
||||||
|
DROP TABLE t1;
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
create table t1m (a int) engine=myisam;
|
create table t1m (a int) engine=myisam;
|
||||||
create table t1i (a int) engine=innodb;
|
create table t1i (a int) engine=innodb;
|
||||||
|
@ -139,6 +139,36 @@ eval select STRCMP("$before", "$after") as "Before and after comparison";
|
|||||||
connection default;
|
connection default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #13191: INSERT...ON DUPLICATE KEY UPDATE of UTF-8 string fields
|
||||||
|
# used in partial unique indices.
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1)
|
||||||
|
ENGINE=INNODB CHARACTER SET UTF8;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1a');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
#
|
#
|
||||||
# Bug #12882 min/max inconsistent on empty table
|
# Bug #12882 min/max inconsistent on empty table
|
||||||
|
42
sql/field.cc
42
sql/field.cc
@ -6221,6 +6221,15 @@ uint Field_string::max_packed_col_length(uint max_length)
|
|||||||
return (max_length > 255 ? 2 : 1)+max_length;
|
return (max_length > 255 ? 2 : 1)+max_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint Field_string::get_key_image(char *buff, uint length, imagetype type_arg)
|
||||||
|
{
|
||||||
|
uint bytes = my_charpos(field_charset, ptr, ptr + field_length,
|
||||||
|
length / field_charset->mbmaxlen);
|
||||||
|
memcpy(buff, ptr, bytes);
|
||||||
|
if (bytes < length)
|
||||||
|
bzero(buff + bytes, length - bytes);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
|
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
bool keep_type)
|
bool keep_type)
|
||||||
@ -6672,9 +6681,7 @@ uint Field_varstring::max_packed_col_length(uint max_length)
|
|||||||
return (max_length > 255 ? 2 : 1)+max_length;
|
return (max_length > 255 ? 2 : 1)+max_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint Field_varstring::get_key_image(char *buff, uint length, imagetype type)
|
||||||
void Field_varstring::get_key_image(char *buff, uint length,
|
|
||||||
imagetype type_arg)
|
|
||||||
{
|
{
|
||||||
uint f_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
|
uint f_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
|
||||||
uint local_char_length= length / field_charset->mbmaxlen;
|
uint local_char_length= length / field_charset->mbmaxlen;
|
||||||
@ -6693,6 +6700,7 @@ void Field_varstring::get_key_image(char *buff, uint length,
|
|||||||
*/
|
*/
|
||||||
bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
|
bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
|
||||||
}
|
}
|
||||||
|
return HA_KEY_BLOB_LENGTH+f_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7064,7 +7072,7 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
|
|||||||
|
|
||||||
/* The following is used only when comparing a key */
|
/* The following is used only when comparing a key */
|
||||||
|
|
||||||
void Field_blob::get_key_image(char *buff, uint length, imagetype type_arg)
|
uint Field_blob::get_key_image(char *buff,uint length, imagetype type_arg)
|
||||||
{
|
{
|
||||||
uint32 blob_length= get_length(ptr);
|
uint32 blob_length= get_length(ptr);
|
||||||
char *blob;
|
char *blob;
|
||||||
@ -7076,16 +7084,17 @@ void Field_blob::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
MBR mbr;
|
MBR mbr;
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *gobj;
|
Geometry *gobj;
|
||||||
|
const uint image_length= SIZEOF_STORED_DOUBLE*4;
|
||||||
|
|
||||||
if (blob_length < SRID_SIZE)
|
if (blob_length < SRID_SIZE)
|
||||||
{
|
{
|
||||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
bzero(buff, image_length);
|
||||||
return;
|
return image_length;
|
||||||
}
|
}
|
||||||
get_ptr(&blob);
|
get_ptr(&blob);
|
||||||
gobj= Geometry::construct(&buffer, blob, blob_length);
|
gobj= Geometry::construct(&buffer, blob, blob_length);
|
||||||
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
||||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
bzero(buff, image_length);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float8store(buff, mbr.xmin);
|
float8store(buff, mbr.xmin);
|
||||||
@ -7093,7 +7102,7 @@ void Field_blob::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
float8store(buff+16, mbr.ymin);
|
float8store(buff+16, mbr.ymin);
|
||||||
float8store(buff+24, mbr.ymax);
|
float8store(buff+24, mbr.ymax);
|
||||||
}
|
}
|
||||||
return;
|
return image_length;
|
||||||
}
|
}
|
||||||
#endif /*HAVE_SPATIAL*/
|
#endif /*HAVE_SPATIAL*/
|
||||||
|
|
||||||
@ -7114,6 +7123,7 @@ void Field_blob::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
}
|
}
|
||||||
int2store(buff,length);
|
int2store(buff,length);
|
||||||
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
||||||
|
return HA_KEY_BLOB_LENGTH+length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7399,7 +7409,7 @@ uint Field_blob::max_packed_col_length(uint max_length)
|
|||||||
|
|
||||||
#ifdef HAVE_SPATIAL
|
#ifdef HAVE_SPATIAL
|
||||||
|
|
||||||
void Field_geom::get_key_image(char *buff, uint length, imagetype type_arg)
|
uint Field_geom::get_key_image(char *buff, uint length, imagetype type)
|
||||||
{
|
{
|
||||||
char *blob;
|
char *blob;
|
||||||
const char *dummy;
|
const char *dummy;
|
||||||
@ -7407,16 +7417,17 @@ void Field_geom::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
ulong blob_length= get_length(ptr);
|
ulong blob_length= get_length(ptr);
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *gobj;
|
Geometry *gobj;
|
||||||
|
const uint image_length= SIZEOF_STORED_DOUBLE*4;
|
||||||
|
|
||||||
if (blob_length < SRID_SIZE)
|
if (blob_length < SRID_SIZE)
|
||||||
{
|
{
|
||||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
bzero(buff, image_length);
|
||||||
return;
|
return image_length;
|
||||||
}
|
}
|
||||||
get_ptr(&blob);
|
get_ptr(&blob);
|
||||||
gobj= Geometry::construct(&buffer, blob, blob_length);
|
gobj= Geometry::construct(&buffer, blob, blob_length);
|
||||||
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
||||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
bzero(buff, image_length);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float8store(buff, mbr.xmin);
|
float8store(buff, mbr.xmin);
|
||||||
@ -7424,6 +7435,7 @@ void Field_geom::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
float8store(buff + 16, mbr.ymin);
|
float8store(buff + 16, mbr.ymin);
|
||||||
float8store(buff + 24, mbr.ymax);
|
float8store(buff + 24, mbr.ymax);
|
||||||
}
|
}
|
||||||
|
return image_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -8132,7 +8144,7 @@ int Field_bit::cmp_offset(uint row_offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field_bit::get_key_image(char *buff, uint length, imagetype type_arg)
|
uint Field_bit::get_key_image(char *buff, uint length, imagetype type_arg)
|
||||||
{
|
{
|
||||||
if (bit_len)
|
if (bit_len)
|
||||||
{
|
{
|
||||||
@ -8140,7 +8152,9 @@ void Field_bit::get_key_image(char *buff, uint length, imagetype type_arg)
|
|||||||
*buff++= bits;
|
*buff++= bits;
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
memcpy(buff, ptr, min(length, bytes_in_rec));
|
uint data_length = min(length, bytes_in_rec);
|
||||||
|
memcpy(buff, ptr, data_length);
|
||||||
|
return data_length + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
44
sql/field.h
44
sql/field.h
@ -235,8 +235,39 @@ public:
|
|||||||
{ memcpy(buff,ptr,length); }
|
{ memcpy(buff,ptr,length); }
|
||||||
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
|
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
|
||||||
{ memcpy(ptr,buff,length); }
|
{ memcpy(ptr,buff,length); }
|
||||||
virtual void get_key_image(char *buff, uint length, imagetype type_arg)
|
|
||||||
{ get_image(buff,length, &my_charset_bin); }
|
|
||||||
|
/*
|
||||||
|
Copy a field part into an output buffer.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Field::get_key_image()
|
||||||
|
buff [out] output buffer
|
||||||
|
length output buffer size
|
||||||
|
type itMBR for geometry blobs, otherwise itRAW
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function makes a copy of field part of size equal to or
|
||||||
|
less than "length" parameter value.
|
||||||
|
For fields of string types (CHAR, VARCHAR, TEXT) the rest of buffer
|
||||||
|
is padded by zero byte.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
For variable length character fields (i.e. UTF-8) the "length"
|
||||||
|
parameter means a number of output buffer bytes as if all field
|
||||||
|
characters have maximal possible size (mbmaxlen). In the other words,
|
||||||
|
"length" parameter is a number of characters multiplied by
|
||||||
|
field_charset->mbmaxlen.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
Number of copied bytes (excluding padded zero bytes -- see above).
|
||||||
|
*/
|
||||||
|
|
||||||
|
virtual uint get_key_image(char *buff, uint length, imagetype type)
|
||||||
|
{
|
||||||
|
get_image(buff, length, &my_charset_bin);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
virtual void set_key_image(char *buff,uint length)
|
virtual void set_key_image(char *buff,uint length)
|
||||||
{ set_image(buff,length, &my_charset_bin); }
|
{ set_image(buff,length, &my_charset_bin); }
|
||||||
inline longlong val_int_offset(uint row_offset)
|
inline longlong val_int_offset(uint row_offset)
|
||||||
@ -1071,6 +1102,7 @@ public:
|
|||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
|
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
|
||||||
|
virtual uint get_key_image(char *buff,uint length, imagetype type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1122,7 +1154,7 @@ public:
|
|||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
int cmp(const char *,const char*);
|
int cmp(const char *,const char*);
|
||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
void get_key_image(char *buff,uint length, imagetype type);
|
uint get_key_image(char *buff,uint length, imagetype type);
|
||||||
void set_key_image(char *buff,uint length);
|
void set_key_image(char *buff,uint length);
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
||||||
@ -1227,7 +1259,7 @@ public:
|
|||||||
store_length(length);
|
store_length(length);
|
||||||
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
|
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
|
||||||
}
|
}
|
||||||
void get_key_image(char *buff,uint length, imagetype type);
|
uint get_key_image(char *buff,uint length, imagetype type);
|
||||||
void set_key_image(char *buff,uint length);
|
void set_key_image(char *buff,uint length);
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
inline bool copy()
|
inline bool copy()
|
||||||
@ -1285,7 +1317,7 @@ public:
|
|||||||
int store(double nr);
|
int store(double nr);
|
||||||
int store(longlong nr, bool unsigned_val);
|
int store(longlong nr, bool unsigned_val);
|
||||||
int store_decimal(const my_decimal *);
|
int store_decimal(const my_decimal *);
|
||||||
void get_key_image(char *buff,uint length,imagetype type);
|
uint get_key_image(char *buff,uint length,imagetype type);
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
int reset(void) { return !maybe_null() || Field_blob::reset(); }
|
int reset(void) { return !maybe_null() || Field_blob::reset(); }
|
||||||
};
|
};
|
||||||
@ -1395,7 +1427,7 @@ public:
|
|||||||
int cmp_offset(uint row_offset);
|
int cmp_offset(uint row_offset);
|
||||||
int cmp_binary_offset(uint row_offset)
|
int cmp_binary_offset(uint row_offset)
|
||||||
{ return cmp_offset(row_offset); }
|
{ return cmp_offset(row_offset); }
|
||||||
void get_key_image(char *buff, uint length, imagetype type);
|
uint get_key_image(char *buff, uint length, imagetype type);
|
||||||
void set_key_image(char *buff, uint length)
|
void set_key_image(char *buff, uint length)
|
||||||
{ Field_bit::store(buff, length, &my_charset_bin); }
|
{ Field_bit::store(buff, length, &my_charset_bin); }
|
||||||
void sort_string(char *buff, uint length)
|
void sort_string(char *buff, uint length)
|
||||||
|
23
sql/key.cc
23
sql/key.cc
@ -119,29 +119,22 @@ void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length)
|
|||||||
key_length--;
|
key_length--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key_part->key_part_flag & HA_BLOB_PART)
|
if (key_part->key_part_flag & HA_BLOB_PART ||
|
||||||
{
|
key_part->key_part_flag & HA_VAR_LENGTH_PART)
|
||||||
char *pos;
|
|
||||||
ulong blob_length= ((Field_blob*) key_part->field)->get_length();
|
|
||||||
key_length-= HA_KEY_BLOB_LENGTH;
|
|
||||||
((Field_blob*) key_part->field)->get_ptr(&pos);
|
|
||||||
length=min(key_length, key_part->length);
|
|
||||||
set_if_smaller(blob_length, length);
|
|
||||||
int2store(to_key, (uint) blob_length);
|
|
||||||
to_key+= HA_KEY_BLOB_LENGTH; // Skip length info
|
|
||||||
memcpy(to_key, pos, blob_length);
|
|
||||||
}
|
|
||||||
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
|
|
||||||
{
|
{
|
||||||
key_length-= HA_KEY_BLOB_LENGTH;
|
key_length-= HA_KEY_BLOB_LENGTH;
|
||||||
length= min(key_length, key_part->length);
|
length= min(key_length, key_part->length);
|
||||||
key_part->field->get_key_image((char *) to_key, length, Field::itRAW);
|
key_part->field->get_key_image(to_key, length, Field::itRAW);
|
||||||
to_key+= HA_KEY_BLOB_LENGTH;
|
to_key+= HA_KEY_BLOB_LENGTH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
length= min(key_length, key_part->length);
|
length= min(key_length, key_part->length);
|
||||||
memcpy(to_key, from_record + key_part->offset, (size_t) length);
|
Field *field= key_part->field;
|
||||||
|
CHARSET_INFO *cs= field->charset();
|
||||||
|
uint bytes= field->get_key_image(to_key, length, Field::itRAW);
|
||||||
|
if (bytes < length)
|
||||||
|
cs->cset->fill(cs, to_key + bytes, length - bytes, ' ');
|
||||||
}
|
}
|
||||||
to_key+= length;
|
to_key+= length;
|
||||||
key_length-= length;
|
key_length-= length;
|
||||||
|
Reference in New Issue
Block a user