Commit 97b21a19 authored by Monty's avatar Monty

MDEV-10759 Fix Aria to support 2-byte collation IDs

- Used same fix as for MyISAM: High level collation byte stored in unused
  bit_end position.
- Moved language from header to base_info
- Removed unused bit_end part in HA_KEY_SEG
parent 2996f9aa
...@@ -149,7 +149,7 @@ typedef struct st_maria_create_info ...@@ -149,7 +149,7 @@ typedef struct st_maria_create_info
uint null_bytes; uint null_bytes;
uint old_options; uint old_options;
enum data_file_type org_data_file_type; enum data_file_type org_data_file_type;
uint8 language; uint16 language;
my_bool with_auto_increment, transactional; my_bool with_auto_increment, transactional;
} MARIA_CREATE_INFO; } MARIA_CREATE_INFO;
......
...@@ -57,7 +57,7 @@ typedef struct st_HA_KEYSEG /* Key-portion */ ...@@ -57,7 +57,7 @@ typedef struct st_HA_KEYSEG /* Key-portion */
uint16 language; uint16 language;
uint8 type; /* Type of key (for sort) */ uint8 type; /* Type of key (for sort) */
uint8 null_bit; /* bitmask to test for NULL */ uint8 null_bit; /* bitmask to test for NULL */
uint8 bit_start,bit_end; /* if bit field */ uint8 bit_start;
uint8 bit_length; /* Length of bit part */ uint8 bit_length; /* Length of bit part */
} HA_KEYSEG; } HA_KEYSEG;
......
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 'test.t1'
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_croatian_ci, KEY(a)) ENGINE=ARIA;
INSERT INTO t1 VALUES ('na'),('nj'),('nz'),('Z');
explain SELECT a FROM t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 33 NULL 4 Using index
SELECT a FROM t1 ORDER BY a;
a
na
nz
nj
Z
ALTER TABLE t1 engine=myisam;
explain SELECT a FROM t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 33 NULL 4 Using index
SELECT a FROM t1 ORDER BY a;
a
na
nz
nj
Z
drop table t1;
#
# Test 2-byte collations
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_croatian_ci, KEY(a)) ENGINE=ARIA;
INSERT INTO t1 VALUES ('na'),('nj'),('nz'),('Z');
explain SELECT a FROM t1 ORDER BY a;
SELECT a FROM t1 ORDER BY a;
ALTER TABLE t1 engine=myisam;
explain SELECT a FROM t1 ORDER BY a;
SELECT a FROM t1 ORDER BY a;
drop table t1;
...@@ -549,8 +549,7 @@ static int table2maria(TABLE *table_arg, data_file_type row_type, ...@@ -549,8 +549,7 @@ static int table2maria(TABLE *table_arg, data_file_type row_type,
keydef[i].seg[j].type= (int) type; keydef[i].seg[j].type= (int) type;
keydef[i].seg[j].start= pos->key_part[j].offset; keydef[i].seg[j].start= pos->key_part[j].offset;
keydef[i].seg[j].length= pos->key_part[j].length; keydef[i].seg[j].length= pos->key_part[j].length;
keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end= keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_length= 0;
keydef[i].seg[j].bit_length= 0;
keydef[i].seg[j].bit_pos= 0; keydef[i].seg[j].bit_pos= 0;
keydef[i].seg[j].language= field->charset()->number; keydef[i].seg[j].language= field->charset()->number;
......
...@@ -6103,7 +6103,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename) ...@@ -6103,7 +6103,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
create_info.data_file_length=file_length; create_info.data_file_length=file_length;
create_info.auto_increment=share.state.auto_increment; create_info.auto_increment=share.state.auto_increment;
create_info.language = (param->language ? param->language : create_info.language = (param->language ? param->language :
share.state.header.language); share.base.language);
create_info.key_file_length= status_info.key_file_length; create_info.key_file_length= status_info.key_file_length;
create_info.org_data_file_type= ((enum data_file_type) create_info.org_data_file_type= ((enum data_file_type)
share.state.header.org_data_file_type); share.state.header.org_data_file_type);
......
...@@ -725,8 +725,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -725,8 +725,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
mi_int2store(share.state.header.base_pos,base_pos); mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.data_file_type= share.data_file_type= datafile_type; share.state.header.data_file_type= share.data_file_type= datafile_type;
share.state.header.org_data_file_type= org_datafile_type; share.state.header.org_data_file_type= org_datafile_type;
share.state.header.language= (ci->language ? share.state.header.not_used= 0;
ci->language : default_charset_info->number);
share.state.dellink = HA_OFFSET_ERROR; share.state.dellink = HA_OFFSET_ERROR;
share.state.first_bitmap_with_space= 0; share.state.first_bitmap_with_space= 0;
...@@ -739,6 +738,8 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -739,6 +738,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.options=options; share.options=options;
share.base.rec_reflength=pointer; share.base.rec_reflength=pointer;
share.base.block_size= maria_block_size; share.base.block_size= maria_block_size;
share.base.language= (ci->language ? ci->language :
default_charset_info->number);
/* /*
Get estimate for index file length (this may be wrong for FT keys) Get estimate for index file length (this may be wrong for FT keys)
...@@ -937,7 +938,6 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -937,7 +938,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
sseg.language= 7; /* Binary */ sseg.language= 7; /* Binary */
sseg.null_bit=0; sseg.null_bit=0;
sseg.bit_start=0; sseg.bit_start=0;
sseg.bit_end=0;
sseg.bit_length= 0; sseg.bit_length= 0;
sseg.bit_pos= 0; sseg.bit_pos= 0;
sseg.length=SPLEN; sseg.length=SPLEN;
......
...@@ -276,6 +276,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -276,6 +276,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
uint i,j,len,errpos,head_length,base_pos,keys, realpath_err, uint i,j,len,errpos,head_length,base_pos,keys, realpath_err,
key_parts,unique_key_parts,fulltext_keys,uniques; key_parts,unique_key_parts,fulltext_keys,uniques;
uint internal_table= MY_TEST(open_flags & HA_OPEN_INTERNAL_TABLE); uint internal_table= MY_TEST(open_flags & HA_OPEN_INTERNAL_TABLE);
uint file_version;
size_t info_length; size_t info_length;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN]; data_name[FN_REFLEN];
...@@ -335,8 +336,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -335,8 +336,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
} }
share->mode=open_mode; share->mode=open_mode;
errpos= 1; errpos= 1;
if (mysql_file_pread(kfile,share->state.header.file_version, head_length, 0, if (mysql_file_pread(kfile,share->state.header.file_version, head_length,
MYF(MY_NABP))) 0, MYF(MY_NABP)))
{ {
my_errno= HA_ERR_NOT_A_TABLE; my_errno= HA_ERR_NOT_A_TABLE;
goto err; goto err;
...@@ -429,6 +430,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -429,6 +430,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
len,MARIA_BASE_INFO_SIZE)); len,MARIA_BASE_INFO_SIZE));
} }
disk_pos= _ma_base_info_read(disk_cache + base_pos, &share->base); disk_pos= _ma_base_info_read(disk_cache + base_pos, &share->base);
/*
Check if old version of Aria file. Version 0 has language
stored in header.not_used
*/
file_version= (share->state.header.not_used == 0);
if (file_version == 0)
share->base.language= share->state.header.not_used;
share->state.state_length=base_pos; share->state.state_length=base_pos;
/* For newly opened tables we reset the error-has-been-printed flag */ /* For newly opened tables we reset the error-has-been-printed flag */
share->state.changed&= ~STATE_CRASHED_PRINTED; share->state.changed&= ~STATE_CRASHED_PRINTED;
...@@ -1581,7 +1590,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base) ...@@ -1581,7 +1590,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
mi_int2store(ptr,base->null_bytes); ptr+= 2; mi_int2store(ptr,base->null_bytes); ptr+= 2;
mi_int2store(ptr,base->original_null_bytes); ptr+= 2; mi_int2store(ptr,base->original_null_bytes); ptr+= 2;
mi_int2store(ptr,base->field_offsets); ptr+= 2; mi_int2store(ptr,base->field_offsets); ptr+= 2;
mi_int2store(ptr,0); ptr+= 2; /* reserved */ mi_int2store(ptr,base->language); ptr+= 2;
mi_int2store(ptr,base->block_size); ptr+= 2; mi_int2store(ptr,base->block_size); ptr+= 2;
*ptr++= base->rec_reflength; *ptr++= base->rec_reflength;
*ptr++= base->key_reflength; *ptr++= base->key_reflength;
...@@ -1624,7 +1633,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base) ...@@ -1624,7 +1633,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
base->null_bytes= mi_uint2korr(ptr); ptr+= 2; base->null_bytes= mi_uint2korr(ptr); ptr+= 2;
base->original_null_bytes= mi_uint2korr(ptr); ptr+= 2; base->original_null_bytes= mi_uint2korr(ptr); ptr+= 2;
base->field_offsets= mi_uint2korr(ptr); ptr+= 2; base->field_offsets= mi_uint2korr(ptr); ptr+= 2;
ptr+= 2; base->language= mi_uint2korr(ptr); ptr+= 2;
base->block_size= mi_uint2korr(ptr); ptr+= 2; base->block_size= mi_uint2korr(ptr); ptr+= 2;
base->rec_reflength= *ptr++; base->rec_reflength= *ptr++;
...@@ -1689,10 +1698,10 @@ my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg) ...@@ -1689,10 +1698,10 @@ my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
ulong pos; ulong pos;
*ptr++= keyseg->type; *ptr++= keyseg->type;
*ptr++= keyseg->language; *ptr++= keyseg->language & 0xFF; /* Collation ID, low byte */
*ptr++= keyseg->null_bit; *ptr++= keyseg->null_bit;
*ptr++= keyseg->bit_start; *ptr++= keyseg->bit_start;
*ptr++= keyseg->bit_end; *ptr++= keyseg->language >> 8; /* Collation ID, high byte */
*ptr++= keyseg->bit_length; *ptr++= keyseg->bit_length;
mi_int2store(ptr,keyseg->flag); ptr+= 2; mi_int2store(ptr,keyseg->flag); ptr+= 2;
mi_int2store(ptr,keyseg->length); ptr+= 2; mi_int2store(ptr,keyseg->length); ptr+= 2;
...@@ -1711,7 +1720,7 @@ uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg) ...@@ -1711,7 +1720,7 @@ uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
keyseg->language = *ptr++; keyseg->language = *ptr++;
keyseg->null_bit = *ptr++; keyseg->null_bit = *ptr++;
keyseg->bit_start = *ptr++; keyseg->bit_start = *ptr++;
keyseg->bit_end = *ptr++; keyseg->language += ((uint16) (*ptr++)) << 8;
keyseg->bit_length = *ptr++; keyseg->bit_length = *ptr++;
keyseg->flag = mi_uint2korr(ptr); ptr+= 2; keyseg->flag = mi_uint2korr(ptr); ptr+= 2;
keyseg->length = mi_uint2korr(ptr); ptr+= 2; keyseg->length = mi_uint2korr(ptr); ptr+= 2;
......
...@@ -1120,7 +1120,7 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -1120,7 +1120,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
maria_test_if_almost_full(info) || maria_test_if_almost_full(info) ||
info->s->state.header.file_version[3] != maria_file_magic[3] || info->s->state.header.file_version[3] != maria_file_magic[3] ||
(set_collation && (set_collation &&
set_collation->number != share->state.header.language))) set_collation->number != share->base.language)))
{ {
if (set_collation) if (set_collation)
param->language= set_collation->number; param->language= set_collation->number;
...@@ -1507,8 +1507,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) ...@@ -1507,8 +1507,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
printf("Crashsafe: %s\n", printf("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no"); share->base.born_transactional ? "yes" : "no");
printf("Character set: %s (%d)\n", printf("Character set: %s (%d)\n",
get_charset_name(share->state.header.language), get_charset_name(share->base.language),
share->state.header.language); (int) share->base.language);
if (param->testflag & T_VERBOSE) if (param->testflag & T_VERBOSE)
{ {
......
...@@ -139,7 +139,7 @@ typedef struct st_maria_state_info ...@@ -139,7 +139,7 @@ typedef struct st_maria_state_info
uchar unique_key_parts[2]; /* Key parts + unique parts */ uchar unique_key_parts[2]; /* Key parts + unique parts */
uchar keys; /* number of keys in file */ uchar keys; /* number of keys in file */
uchar uniques; /* number of UNIQUE definitions */ uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */ uchar not_used; /* Language for indexes */
uchar fulltext_keys; uchar fulltext_keys;
uchar data_file_type; uchar data_file_type;
/* Used by mariapack to store the original data_file_type */ /* Used by mariapack to store the original data_file_type */
...@@ -209,6 +209,7 @@ typedef struct st_maria_state_info ...@@ -209,6 +209,7 @@ typedef struct st_maria_state_info
} MARIA_STATE_INFO; } MARIA_STATE_INFO;
/* Number of bytes written be _ma_state_info_write_sub() */
#define MARIA_STATE_INFO_SIZE \ #define MARIA_STATE_INFO_SIZE \
(24 + 2 + LSN_STORE_SIZE*3 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8) (24 + 2 + LSN_STORE_SIZE*3 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8)
#define MARIA_FILE_OPEN_COUNT_OFFSET 0 #define MARIA_FILE_OPEN_COUNT_OFFSET 0
...@@ -291,6 +292,8 @@ typedef struct st_ma_base_info ...@@ -291,6 +292,8 @@ typedef struct st_ma_base_info
uint extra_rec_buff_size; uint extra_rec_buff_size;
/* Tuning flags that can be ignored by older Maria versions */ /* Tuning flags that can be ignored by older Maria versions */
uint extra_options; uint extra_options;
/* default language, not really used but displayed by maria_chk */
uint language;
/* The following are from the header */ /* The following are from the header */
uint key_parts, all_key_parts; uint key_parts, all_key_parts;
...@@ -916,7 +919,6 @@ extern mysql_mutex_t THR_LOCK_maria; ...@@ -916,7 +919,6 @@ extern mysql_mutex_t THR_LOCK_maria;
#define MARIA_SMALL_BLOB_BUFFER 1024 #define MARIA_SMALL_BLOB_BUFFER 1024
#define MARIA_MAX_CONTROL_FILE_LOCK_RETRY 30 /* Retry this many times */ #define MARIA_MAX_CONTROL_FILE_LOCK_RETRY 30 /* Retry this many times */
/* Some extern variables */ /* Some extern variables */
extern LIST *maria_open_list; extern LIST *maria_open_list;
extern uchar maria_file_magic[], maria_pack_file_magic[]; extern uchar maria_file_magic[], maria_pack_file_magic[];
......
...@@ -34,7 +34,7 @@ const HA_KEYSEG ft_keysegs[FT_SEGS]= { ...@@ -34,7 +34,7 @@ const HA_KEYSEG ft_keysegs[FT_SEGS]= {
63, /* language (will be overwritten) */ 63, /* language (will be overwritten) */
HA_KEYTYPE_VARTEXT2, /* type */ HA_KEYTYPE_VARTEXT2, /* type */
0, /* null_bit */ 0, /* null_bit */
2, 0, 0 /* bit_start, bit_end, bit_length */ 2, 0 /* bit_start, bit_length */
}, },
{ {
/* /*
...@@ -42,7 +42,7 @@ const HA_KEYSEG ft_keysegs[FT_SEGS]= { ...@@ -42,7 +42,7 @@ const HA_KEYSEG ft_keysegs[FT_SEGS]= {
be packed in any way, otherwise w_search() won't be able to be packed in any way, otherwise w_search() won't be able to
update key entry 'in vivo' update key entry 'in vivo'
*/ */
0, 0, 0, 0, HA_NO_SORT, HA_FT_WLEN, 63, HA_FT_WTYPE, 0, 0, 0, 0 0, 0, 0, 0, HA_NO_SORT, HA_FT_WLEN, 63, HA_FT_WTYPE, 0, 0, 0
} }
}; };
......
...@@ -279,8 +279,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, ...@@ -279,8 +279,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
keydef[i].seg[j].type= (int) type; keydef[i].seg[j].type= (int) type;
keydef[i].seg[j].start= pos->key_part[j].offset; keydef[i].seg[j].start= pos->key_part[j].offset;
keydef[i].seg[j].length= pos->key_part[j].length; keydef[i].seg[j].length= pos->key_part[j].length;
keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end= keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_length= 0;
keydef[i].seg[j].bit_length= 0;
keydef[i].seg[j].bit_pos= 0; keydef[i].seg[j].bit_pos= 0;
keydef[i].seg[j].language= field->charset_for_protocol()->number; keydef[i].seg[j].language= field->charset_for_protocol()->number;
......
...@@ -729,7 +729,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -729,7 +729,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
sseg.language= 7; /* Binary */ sseg.language= 7; /* Binary */
sseg.null_bit=0; sseg.null_bit=0;
sseg.bit_start=0; sseg.bit_start=0;
sseg.bit_end=0;
sseg.bit_length= 0; sseg.bit_length= 0;
sseg.bit_pos= 0; sseg.bit_pos= 0;
sseg.length=SPLEN; sseg.length=SPLEN;
......
...@@ -1183,7 +1183,6 @@ uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg) ...@@ -1183,7 +1183,6 @@ uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
keyseg->length = mi_uint2korr(ptr); ptr +=2; keyseg->length = mi_uint2korr(ptr); ptr +=2;
keyseg->start = mi_uint4korr(ptr); ptr +=4; keyseg->start = mi_uint4korr(ptr); ptr +=4;
keyseg->null_pos = mi_uint4korr(ptr); ptr +=4; keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
keyseg->bit_end= 0;
keyseg->charset=0; /* Will be filled in later */ keyseg->charset=0; /* Will be filled in later */
if (keyseg->null_bit) if (keyseg->null_bit)
/* We adjust bit_pos if null_bit is last in the byte */ /* We adjust bit_pos if null_bit is last in the byte */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment