Commit 06904103 authored by unknown's avatar unknown

Merge with global tree

Fixed some found bugs in BIT fields
Added more test cases for BIT fields and varchar


include/my_base.h:
  Merge
  Added HA_BIT_PART for easier test in key.cc
innobase/os/os0proc.c:
  Fixed typo
myisam/mi_dbug.c:
  Add printing of BIT types when debugging
mysql-test/r/show_check.result:
  Set 'Avg_row_length' to # as this value is different between 32 and 64 bit machines
mysql-test/r/type_bit.result:
  More tests
mysql-test/r/type_varchar.result:
  More tests
mysql-test/t/show_check.test:
  Set 'Avg_row_length' to # as this value is different between 32 and 64 bit machines
mysql-test/t/type_bit.test:
  More tests
mysql-test/t/type_varchar.test:
  More tests
sql/field.cc:
  Added Field::val_int_as_str() to get better logging of bit fields
  Merged new_key_field with move_field() to fix some problems with bit fields
  Fixed some bugs with bit fields
sql/field.h:
  Added Field::val_int_as_str() to get better logging of bit fields
  Merged new_key_field with move_field() to fix some problems with bit fields
  Fixed some bugs with bit fields
sql/ha_myisam.cc:
  Fixed problem with unintialized memory (not critical)
sql/key.cc:
  Fix so that 'key_cmp_if_same' works with bit fields.
sql/opt_range.cc:
  Move declarations first in function
  Nice printing of bit fields in debug log
sql/sql_prepare.cc:
  Fixed old merge error (not critical)
sql/sql_select.cc:
  Use new interface to new_key_field
sql/sql_select.h:
  Use new interface to new_key_fields()
  This fixes a bug with BIT fields where the upper bit of the data was not stored in the key buffer
sql/structs.h:
  Extend key_part_flag to be able to add HA_BIT_PART to it
sql/table.cc:
  Mark BIT key parts with HA_BIT_PART to make test in key.cc simpler
parent 3fa699ef
...@@ -187,7 +187,7 @@ enum ha_base_keytype { ...@@ -187,7 +187,7 @@ enum ha_base_keytype {
/* Varchar (0-65535 bytes) with length packed with 2 bytes */ /* Varchar (0-65535 bytes) with length packed with 2 bytes */
HA_KEYTYPE_VARTEXT2=17, /* Key is sorted as letters */ HA_KEYTYPE_VARTEXT2=17, /* Key is sorted as letters */
HA_KEYTYPE_VARBINARY2=18, /* Key is sorted as unsigned chars */ HA_KEYTYPE_VARBINARY2=18, /* Key is sorted as unsigned chars */
HA_KEYTYPE_BIT=18 HA_KEYTYPE_BIT=19
}; };
#define HA_MAX_KEYTYPE 31 /* Must be log2-1 */ #define HA_MAX_KEYTYPE 31 /* Must be log2-1 */
...@@ -237,6 +237,7 @@ enum ha_base_keytype { ...@@ -237,6 +237,7 @@ enum ha_base_keytype {
Only needed for internal temporary tables. Only needed for internal temporary tables.
*/ */
#define HA_END_SPACE_ARE_EQUAL 512 #define HA_END_SPACE_ARE_EQUAL 512
#define HA_BIT_PART 1024
/* optionbits for database */ /* optionbits for database */
#define HA_OPTION_PACK_RECORD 1 #define HA_OPTION_PACK_RECORD 1
......
...@@ -565,7 +565,7 @@ os_mem_alloc_large( ...@@ -565,7 +565,7 @@ os_mem_alloc_large(
if (ptr) { if (ptr) {
if (set_to_zero) { if (set_to_zero) {
#ifdef UNIV_SET_MEM_TO_ZERO #ifdef UNIV_SET_MEM_TO_ZERO
memset(ret, '\0', size); memset(ptr, '\0', size);
#endif #endif
} }
......
...@@ -131,6 +131,16 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, ...@@ -131,6 +131,16 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
key=end; key=end;
break; break;
} }
case HA_KEYTYPE_BIT:
{
uint i;
fputs("0x",stream);
for (i=0 ; i < keyseg->length ; i++)
fprintf(stream, "%02x", (uint) *key++);
key= end;
break;
}
#endif #endif
case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */
case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */
......
...@@ -314,57 +314,57 @@ insert into t2 values (1),(2); ...@@ -314,57 +314,57 @@ insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2); insert into t3 values (1,1),(2,2);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 2 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (3),(4); insert into t1 values (3),(4);
insert into t2 values (3),(4); insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4); insert into t3 values (3,3),(4,4);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5); insert into t1 values (5);
insert into t2 values (5); insert into t2 values (5);
insert into t3 values (5,5); insert into t3 values (5,5);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 5 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 5 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 5 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=3; delete from t1 where a=3;
delete from t2 where b=3; delete from t2 where b=3;
delete from t3 where a=3; delete from t3 where a=3;
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 4 # # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 4 # # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 4 # # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1; delete from t1;
delete from t2; delete from t2;
delete from t3; delete from t3;
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5); insert into t1 values (5);
insert into t2 values (5); insert into t2 values (5);
insert into t3 values (5,5); insert into t3 values (5,5);
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 1 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=5; delete from t1 where a=5;
delete from t2 where b=5; delete from t2 where b=5;
delete from t3 where a=5; delete from t3 where a=5;
show table status; show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP 9 Fixed 0 # # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP 9 Fixed 0 # # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP 9 Fixed 0 # # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3; drop table t1, t2, t3;
create database mysqltest; create database mysqltest;
show create database mysqltest; show create database mysqltest;
......
...@@ -321,6 +321,12 @@ select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2; ...@@ -321,6 +321,12 @@ select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2;
a+0 b+0 c+0 a+0 b+0 c+0
4 0 3 4 0 3
4 0 23 4 0 23
select a+0, b+0, c+0 from t1 where a = 4 and b = 1;
a+0 b+0 c+0
4 1 100
select a+0, b+0, c+0 from t1 where a = 4 and b = 1 and c=100;
a+0 b+0 c+0
4 1 100
select a+0, b+0, c+0 from t1 order by b desc; select a+0, b+0, c+0 from t1 order by b desc;
a+0 b+0 c+0 a+0 b+0 c+0
2 1 4 2 1 4
......
This diff is collapsed.
...@@ -236,37 +236,37 @@ CREATE TABLE t3 ( ...@@ -236,37 +236,37 @@ CREATE TABLE t3 (
insert into t1 values (1),(2); insert into t1 values (1),(2);
insert into t2 values (1),(2); insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2); insert into t3 values (1,1),(2,2);
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
insert into t1 values (3),(4); insert into t1 values (3),(4);
insert into t2 values (3),(4); insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4); insert into t3 values (3,3),(4,4);
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
insert into t1 values (5); insert into t1 values (5);
insert into t2 values (5); insert into t2 values (5);
insert into t3 values (5,5); insert into t3 values (5,5);
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
delete from t1 where a=3; delete from t1 where a=3;
delete from t2 where b=3; delete from t2 where b=3;
delete from t3 where a=3; delete from t3 where a=3;
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
delete from t1; delete from t1;
delete from t2; delete from t2;
delete from t3; delete from t3;
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
insert into t1 values (5); insert into t1 values (5);
insert into t2 values (5); insert into t2 values (5);
insert into t3 values (5,5); insert into t3 values (5,5);
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
delete from t1 where a=5; delete from t1 where a=5;
delete from t2 where b=5; delete from t2 where b=5;
delete from t3 where a=5; delete from t3 where a=5;
--replace_column 7 # 8 # 9 # --replace_column 6 # 7 # 8 # 9 #
show table status; show table status;
drop table t1, t2, t3; drop table t1, t2, t3;
......
...@@ -88,6 +88,8 @@ select hex(min(b)) from t1 where a = 4; ...@@ -88,6 +88,8 @@ select hex(min(b)) from t1 where a = 4;
select hex(min(c)) from t1 where a = 4 and b = 0; select hex(min(c)) from t1 where a = 4 and b = 0;
select hex(max(b)) from t1; select hex(max(b)) from t1;
select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2; select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2;
select a+0, b+0, c+0 from t1 where a = 4 and b = 1;
select a+0, b+0, c+0 from t1 where a = 4 and b = 1 and c=100;
select a+0, b+0, c+0 from t1 order by b desc; select a+0, b+0, c+0 from t1 order by b desc;
select a+0, b+0, c+0 from t1 order by c; select a+0, b+0, c+0 from t1 order by c;
drop table t1; drop table t1;
......
...@@ -32,3 +32,68 @@ create table t1 (v varbinary(20)); ...@@ -32,3 +32,68 @@ create table t1 (v varbinary(20));
insert into t1 values('a'); insert into t1 values('a');
insert into t1 values('a '); insert into t1 values('a ');
alter table t1 add primary key (v); alter table t1 add primary key (v);
drop table t1;
#
# Test with varchar of lengths 254,255,256,258 & 258 to ensure we don't
# have any problems with varchar with one or two byte length_bytes
#
create table t1 (v varchar(254), index (v));
insert into t1 values ("This is a test ");
insert into t1 values ("Some sample data");
insert into t1 values (" garbage ");
insert into t1 values (" This is a test ");
insert into t1 values ("This is a test");
insert into t1 values ("Hello world");
insert into t1 values ("Foo bar");
insert into t1 values ("This is a test");
insert into t1 values ("MySQL varchar test");
insert into t1 values ("test MySQL varchar");
insert into t1 values ("This is a long string to have some random length data included");
insert into t1 values ("Short string");
insert into t1 values ("VSS");
insert into t1 values ("Some samples");
insert into t1 values ("Bar foo");
insert into t1 values ("Bye");
let $i= 255;
let $j= 5;
while ($j)
{
select * from t1 where v like 'This is a test' order by v;
select * from t1 where v='This is a test' order by v;
select * from t1 where v like 'S%' order by v;
explain select * from t1 where v like 'This is a test' order by v;
explain select * from t1 where v='This is a test' order by v;
explain select * from t1 where v like 'S%' order by v;
eval alter table t1 change v v varchar($i);
inc $i;
dec $j;
}
let $i= 258;
let $j= 6;
while ($j)
{
select * from t1 where v like 'This is a test' order by v;
select * from t1 where v='This is a test' order by v;
select * from t1 where v like 'S%' order by v;
explain select * from t1 where v like 'This is a test' order by v;
explain select * from t1 where v='This is a test' order by v;
explain select * from t1 where v like 'S%' order by v;
eval alter table t1 change v v varchar($i);
dec $i;
dec $j;
}
alter table t1 change v v varchar(254), drop key v;
# Test with length(varchar) > 256 and key < 256 (to ensure things works with
# different kind of packing
alter table t1 change v v varchar(300), add key (v(10));
select * from t1 where v like 'This is a test' order by v;
select * from t1 where v='This is a test' order by v;
select * from t1 where v like 'S%' order by v;
explain select * from t1 where v like 'This is a test' order by v;
explain select * from t1 where v='This is a test' order by v;
explain select * from t1 where v like 'S%' order by v;
drop table t1;
...@@ -329,6 +329,27 @@ bool Field::field_cast_compatible(Field::field_cast_enum type) ...@@ -329,6 +329,27 @@ bool Field::field_cast_compatible(Field::field_cast_enum type)
} }
/*
Interpret field value as an integer but return the result as a string.
This is used for printing bit_fields as numbers while debugging
*/
String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_flag)
{
CHARSET_INFO *cs= &my_charset_bin;
uint length= 21;
longlong value= val_int();
if (val_buffer->alloc(length))
return 0;
length= (uint) cs->cset->longlong10_to_str(cs, (char*) val_buffer->ptr(),
length, unsigned_flag ? 10 : -10,
value);
val_buffer->length(length);
return val_buffer;
}
/**************************************************************************** /****************************************************************************
** Functions for the base classes ** Functions for the base classes
** This is an unpacked number. ** This is an unpacked number.
...@@ -500,6 +521,22 @@ Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table) ...@@ -500,6 +521,22 @@ Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table)
return tmp; return tmp;
} }
Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit)
{
Field *tmp;
if ((tmp= new_field(root, new_table)))
{
tmp->ptr= new_ptr;
tmp->null_ptr= new_null_ptr;
tmp->null_bit= new_null_bit;
}
return tmp;
}
/**************************************************************************** /****************************************************************************
Field_null, a field that always return NULL Field_null, a field that always return NULL
****************************************************************************/ ****************************************************************************/
...@@ -5116,12 +5153,20 @@ Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table) ...@@ -5116,12 +5153,20 @@ Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table)
Field *Field_varstring::new_key_field(MEM_ROOT *root, Field *Field_varstring::new_key_field(MEM_ROOT *root,
struct st_table *new_table) struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit)
{ {
Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table); Field_varstring *res;
if ((res= (Field_varstring*) Field::new_key_field(root,
new_table,
new_ptr,
new_null_ptr,
new_null_bit)))
{
/* Keys length prefixes are always packed with 2 bytes */ /* Keys length prefixes are always packed with 2 bytes */
if (res)
res->length_bytes= 2; res->length_bytes= 2;
}
return res; return res;
} }
...@@ -6210,6 +6255,43 @@ bool Field_num::eq_def(Field *field) ...@@ -6210,6 +6255,43 @@ bool Field_num::eq_def(Field *field)
11 one byte for 'd' 11 one byte for 'd'
*/ */
Field_bit::Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
: Field(ptr_arg, len_arg >> 3, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7)
{
/*
Ensure that Field::eq() can distinguish between two different bit fields.
(two bit fields that are not null, may have same ptr and null_ptr)
*/
if (!null_ptr_arg)
null_bit= bit_ofs_arg;
}
Field *Field_bit::new_key_field(MEM_ROOT *root,
struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit)
{
Field_bit *res;
if ((res= (Field_bit*) Field::new_key_field(root, new_table,
new_ptr, new_null_ptr,
new_null_bit)))
{
/* Move bits normally stored in null_pointer to new_ptr */
res->bit_ptr= (uchar*) new_ptr;
res->bit_ofs= 0;
if (bit_len)
res->ptr++; // Store rest of data here
}
return res;
}
void Field_bit::make_field(Send_field *field) void Field_bit::make_field(Send_field *field)
{ {
/* table_cache_key is not set for temp tables */ /* table_cache_key is not set for temp tables */
...@@ -6331,7 +6413,7 @@ int Field_bit::key_cmp(const byte *str, uint length) ...@@ -6331,7 +6413,7 @@ int Field_bit::key_cmp(const byte *str, uint length)
{ {
int flag; int flag;
uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
if ((flag= (int) (bits - *str))) if ((flag= (int) (bits - *(uchar*) str)))
return flag; return flag;
str++; str++;
length--; length--;
...@@ -6426,6 +6508,11 @@ void create_field::create_length_to_internal_length(void) ...@@ -6426,6 +6508,11 @@ void create_field::create_length_to_internal_length(void)
length*= charset->mbmaxlen; length*= charset->mbmaxlen;
key_length= pack_length; key_length= pack_length;
break; break;
case MYSQL_TYPE_BIT:
pack_length= calc_pack_length(sql_type, length);
/* We need one extra byte to store the bits we save among the null bits */
key_length= pack_length+ test(length & 7);
break;
default: default:
key_length= pack_length= calc_pack_length(sql_type, length); key_length= pack_length= calc_pack_length(sql_type, length);
break; break;
......
...@@ -113,9 +113,14 @@ class Field ...@@ -113,9 +113,14 @@ class Field
This trickery is used to decrease a number of malloc calls. This trickery is used to decrease a number of malloc calls.
*/ */
virtual String *val_str(String*,String *)=0; virtual String *val_str(String*,String *)=0;
String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_flag);
virtual Item_result result_type () const=0; virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cmp_type () const { return result_type(); }
bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; } bool eq(Field *field)
{
return (ptr == field->ptr && null_ptr == field->null_ptr &&
null_bit == field->null_bit);
}
virtual bool eq_def(Field *field); virtual bool eq_def(Field *field);
virtual uint32 pack_length() const { return (uint32) field_length; } virtual uint32 pack_length() const { return (uint32) field_length; }
virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset(void) { bzero(ptr,pack_length()); }
...@@ -184,11 +189,10 @@ class Field ...@@ -184,11 +189,10 @@ class Field
virtual bool can_be_compared_as_longlong() const { return FALSE; } virtual bool can_be_compared_as_longlong() const { return FALSE; }
virtual void free() {} virtual void free() {}
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table); virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table);
virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table) virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
{ char *new_ptr, uchar *new_null_ptr,
return new_field(root, new_table); uint new_null_bit);
} virtual void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
{ {
ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg; ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
} }
...@@ -994,7 +998,9 @@ class Field_varstring :public Field_str { ...@@ -994,7 +998,9 @@ class Field_varstring :public Field_str {
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; } field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
Field *new_field(MEM_ROOT *root, struct st_table *new_table); Field *new_field(MEM_ROOT *root, struct st_table *new_table);
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table); Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit);
}; };
...@@ -1199,11 +1205,7 @@ class Field_bit :public Field { ...@@ -1199,11 +1205,7 @@ class Field_bit :public Field {
Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
enum utype unireg_check_arg, const char *field_name_arg, enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg) struct st_table *table_arg);
: Field(ptr_arg, len_arg >> 3, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7)
{ }
enum_field_types type() const { return FIELD_TYPE_BIT; } enum_field_types type() const { return FIELD_TYPE_BIT; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
uint32 key_length() const { return (uint32) field_length + (bit_len > 0); } uint32 key_length() const { return (uint32) field_length + (bit_len > 0); }
...@@ -1235,6 +1237,9 @@ class Field_bit :public Field { ...@@ -1235,6 +1237,9 @@ class Field_bit :public Field {
field_cast_enum field_cast_type() { return FIELD_CAST_BIT; } field_cast_enum field_cast_type() { return FIELD_CAST_BIT; }
char *pack(char *to, const char *from, uint max_length=~(uint) 0); char *pack(char *to, const char *from, uint max_length=~(uint) 0);
const char *unpack(char* to, const char *from); const char *unpack(char* to, const char *from);
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit);
}; };
......
...@@ -1409,7 +1409,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, ...@@ -1409,7 +1409,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
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=0; keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end=
keydef[i].seg[j].bit_pos= 0;
keydef[i].seg[j].language = field->charset()->number; keydef[i].seg[j].language = field->charset()->number;
if (field->null_ptr) if (field->null_ptr)
......
...@@ -250,35 +250,35 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, ...@@ -250,35 +250,35 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info,
bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length) bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length)
{ {
uint length; uint store_length;
KEY_PART_INFO *key_part; KEY_PART_INFO *key_part;
const byte *key_end= key + key_length;;
for (key_part=table->key_info[idx].key_part; for (key_part=table->key_info[idx].key_part;
(int) key_length > 0; key < key_end ;
key_part++, key+=length, key_length-=length) key_part++, key+= store_length)
{ {
uint length;
store_length= key_part->store_length;
if (key_part->null_bit) if (key_part->null_bit)
{ {
key_length--;
if (*key != test(table->record[0][key_part->null_offset] & if (*key != test(table->record[0][key_part->null_offset] &
key_part->null_bit)) key_part->null_bit))
return 1; return 1;
if (*key) if (*key)
{
length=key_part->store_length;
continue; continue;
}
key++; key++;
store_length--;
} }
if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART |
HA_BIT_PART))
{ {
if (key_part->field->key_cmp(key, key_part->length)) if (key_part->field->key_cmp(key, key_part->length))
return 1; return 1;
length=key_part->length+HA_KEY_BLOB_LENGTH; continue;
} }
else length= min((uint) (key_end-key), store_length);
{
length=min(key_length,key_part->length);
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
FIELDFLAG_PACK))) FIELDFLAG_PACK)))
{ {
...@@ -294,11 +294,11 @@ bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length) ...@@ -294,11 +294,11 @@ bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length)
(const uchar*) key, length, (const uchar*) key, length,
(const uchar*) pos, char_length, 0)) (const uchar*) pos, char_length, 0))
return 1; return 1;
continue;
} }
else if (memcmp(key,table->record[0]+key_part->offset,length)) if (memcmp(key,table->record[0]+key_part->offset,length))
return 1; return 1;
} }
}
return 0; return 0;
} }
......
...@@ -5000,7 +5000,9 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, ...@@ -5000,7 +5000,9 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
char *min_key,uint min_key_flag, char *max_key, char *min_key,uint min_key_flag, char *max_key,
uint max_key_flag) uint max_key_flag)
{ {
ha_rows records=0,tmp; ha_rows records=0, tmp;
uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
char *tmp_min_key, *tmp_max_key;
param->max_key_part=max(param->max_key_part,key_tree->part); param->max_key_part=max(param->max_key_part,key_tree->part);
if (key_tree->left != &null_element) if (key_tree->left != &null_element)
...@@ -5018,13 +5020,12 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, ...@@ -5018,13 +5020,12 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
return records; return records;
} }
uint tmp_min_flag,tmp_max_flag,keynr; tmp_min_key= min_key;
char *tmp_min_key=min_key,*tmp_max_key=max_key; tmp_max_key= max_key;
key_tree->store(param->key[idx][key_tree->part].store_length, key_tree->store(param->key[idx][key_tree->part].store_length,
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag); &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
uint min_key_length= (uint) (tmp_min_key- param->min_key); min_key_length= (uint) (tmp_min_key- param->min_key);
uint max_key_length= (uint) (tmp_max_key- param->max_key); max_key_length= (uint) (tmp_max_key- param->max_key);
if (param->is_ror_scan) if (param->is_ror_scan)
{ {
...@@ -8448,6 +8449,9 @@ print_key(KEY_PART *key_part,const char *key,uint used_length) ...@@ -8448,6 +8449,9 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
store_length--; store_length--;
} }
field->set_key_image((char*) key, key_part->length); field->set_key_image((char*) key, key_part->length);
if (field->type() == MYSQL_TYPE_BIT)
(void) field->val_int_as_str(&tmp, 1);
else
field->val_str(&tmp); field->val_str(&tmp);
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE); fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
if (key+store_length < key_end) if (key+store_length < key_end)
......
...@@ -2041,10 +2041,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, ...@@ -2041,10 +2041,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
thd->cleanup_after_query(); thd->cleanup_after_query();
if (stmt->state == Item_arena::PREPARED) if (stmt->state == Item_arena::PREPARED)
{
thd->current_arena= thd;
stmt->state= Item_arena::EXECUTED; stmt->state= Item_arena::EXECUTED;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -8159,25 +8159,27 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -8159,25 +8159,27 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!using_unique_constraint) if (!using_unique_constraint)
{ {
group->buff=(char*) group_buff; group->buff=(char*) group_buff;
if (!(group->field=field->new_key_field(thd->mem_root,table))) if (!(group->field= field->new_key_field(thd->mem_root,table,
(char*) group_buff +
test(maybe_null),
field->null_ptr,
field->null_bit)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
if (maybe_null) if (maybe_null)
{ {
/* /*
To be able to group on NULL, we reserve place in group_buff To be able to group on NULL, we reserved place in group_buff
for the NULL flag just before the column. for the NULL flag just before the column. (see above).
The field data is after this flag. The field data is after this flag.
The NULL flag is updated by 'end_update()' and 'end_write()' The NULL flag is updated in 'end_update()' and 'end_write()'
*/ */
keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
key_part_info->null_bit=field->null_bit; key_part_info->null_bit=field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr - key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) table->record[0]); (uchar*) table->record[0]);
group->field->move_field((char*) ++group->buff); group->buff++; // Pointer to field data
group_buff++; group_buff++; // Skipp null flag
} }
else
group->field->move_field((char*) group_buff);
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */ /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
group_buff+= group->field->pack_length(); group_buff+= group->field->pack_length();
......
...@@ -427,11 +427,8 @@ class store_key :public Sql_alloc ...@@ -427,11 +427,8 @@ class store_key :public Sql_alloc
field_arg->table, field_arg->charset()); field_arg->table, field_arg->charset());
} }
else else
{ to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table); ptr, (uchar*) null, 1);
if (to_field)
to_field->move_field(ptr, (uchar*) null, 1);
}
} }
virtual ~store_key() {} /* Not actually needed */ virtual ~store_key() {} /* Not actually needed */
virtual bool copy()=0; virtual bool copy()=0;
......
...@@ -74,7 +74,7 @@ typedef struct st_key_part_info { /* Info about a key part */ ...@@ -74,7 +74,7 @@ typedef struct st_key_part_info { /* Info about a key part */
uint16 store_length; uint16 store_length;
uint16 key_type; uint16 key_type;
uint16 fieldnr; /* Fieldnum in UNIREG */ uint16 fieldnr; /* Fieldnum in UNIREG */
uint8 key_part_flag; /* 0 or HA_REVERSE_SORT */ uint16 key_part_flag; /* 0 or HA_REVERSE_SORT */
uint8 type; uint8 type;
uint8 null_bit; /* Position to null_bit */ uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ; } KEY_PART_INFO ;
......
...@@ -631,6 +631,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, ...@@ -631,6 +631,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (!(field->flags & BINARY_FLAG)) if (!(field->flags & BINARY_FLAG))
keyinfo->flags|= HA_END_SPACE_KEY; keyinfo->flags|= HA_END_SPACE_KEY;
} }
if (field->type() == MYSQL_TYPE_BIT)
key_part->key_part_flag|= HA_BIT_PART;
if (i == 0 && key != primary_key) if (i == 0 && key != primary_key)
field->flags |= field->flags |=
((keyinfo->flags & HA_NOSAME) && ((keyinfo->flags & HA_NOSAME) &&
......
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