mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Move handling of suffix_length from strnxfrm_bin() to filesort to ensure proper sorting of all kind of binary objects
field::sort_key() now adds length last for varbinary/blob VARBINARY/BLOB is now sorted by filesort so that shorter strings comes before longer ones Fixed issues in test cases from last merge mysql-test/r/select.result: Change column name in test to get GROUP BY to use the alias mysql-test/r/type_blob.result: Test BLOB and VARCHAR sorting mysql-test/t/select.test: Change column name in test to get GROUP BY to use the alias Drop used tables at start of test Don't use table names 'a', 'b' or 'c' mysql-test/t/type_blob.test: Test BLOB and VARCHAR sorting sql/field.cc: Store length last in VARBINARY() and BLOB() columns to get shorter strings sorted before longer onces sql/field.h: Added method 'sort_length()' to allow one to have length bytes last for VARBINARY/BLOB to get these to sort properly sql/filesort.cc: Use 'sort_length()' instead of 'pack_length()' to get length of field. Store suffix_length last for varbinary (blob) objects. The above ensures that BLOB/VARBINARY are correctly sorted (shorter strings before longer ones) sql/sql_class.h: Added sort suffix length (to get varbinary/blob to sort correctly) sql/sql_select.cc: Use sort_length() instead of pack_lengths() strings/ctype-bin.c: Don't let strnxfrm_bin store length last Better to do it in MySQL field object to ensure it's done properly for all cases
This commit is contained in:
43
sql/field.cc
43
sql/field.cc
@@ -6402,6 +6402,17 @@ int Field_varstring::key_cmp(const byte *a,const byte *b)
|
||||
void Field_varstring::sort_string(char *to,uint length)
|
||||
{
|
||||
uint tot_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
|
||||
|
||||
if (field_charset == &my_charset_bin)
|
||||
{
|
||||
/* Store length last in high-byte order to sort longer strings first */
|
||||
if (length_bytes == 1)
|
||||
to[length-1]= tot_length;
|
||||
else
|
||||
mi_int2store(to+length-2, tot_length);
|
||||
length-= length_bytes;
|
||||
}
|
||||
|
||||
tot_length= my_strnxfrm(field_charset,
|
||||
(uchar*) to, length,
|
||||
(uchar*) ptr + length_bytes,
|
||||
@@ -7093,6 +7104,13 @@ int Field_blob::key_cmp(const byte *a,const byte *b)
|
||||
}
|
||||
|
||||
|
||||
uint32 Field_blob::sort_length() const
|
||||
{
|
||||
return (uint32) (current_thd->variables.max_sort_length +
|
||||
(field_charset == &my_charset_bin ? 0 : packlength));
|
||||
}
|
||||
|
||||
|
||||
void Field_blob::sort_string(char *to,uint length)
|
||||
{
|
||||
char *blob;
|
||||
@@ -7102,6 +7120,31 @@ void Field_blob::sort_string(char *to,uint length)
|
||||
bzero(to,length);
|
||||
else
|
||||
{
|
||||
if (field_charset == &my_charset_bin)
|
||||
{
|
||||
char *pos;
|
||||
|
||||
/*
|
||||
Store length of blob last in blob to shorter blobs before longer blobs
|
||||
*/
|
||||
length-= packlength;
|
||||
pos= to+length;
|
||||
|
||||
switch (packlength) {
|
||||
case 1:
|
||||
*pos= (char) blob_length;
|
||||
break;
|
||||
case 2:
|
||||
mi_int2store(pos, blob_length);
|
||||
break;
|
||||
case 3:
|
||||
mi_int3store(pos, blob_length);
|
||||
break;
|
||||
case 4:
|
||||
mi_int4store(pos, blob_length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
|
||||
|
||||
blob_length=my_strnxfrm(field_charset,
|
||||
|
||||
Reference in New Issue
Block a user