Commit 6477b4df authored by monty@mysql.com's avatar monty@mysql.com

Merge with global tree

Fixed some found bugs in BIT fields
Added more test cases for BIT fields and varchar
parent 2a215c17
......@@ -187,7 +187,7 @@ enum ha_base_keytype {
/* Varchar (0-65535 bytes) with length packed with 2 bytes */
HA_KEYTYPE_VARTEXT2=17, /* Key is sorted as letters */
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 */
......@@ -237,6 +237,7 @@ enum ha_base_keytype {
Only needed for internal temporary tables.
*/
#define HA_END_SPACE_ARE_EQUAL 512
#define HA_BIT_PART 1024
/* optionbits for database */
#define HA_OPTION_PACK_RECORD 1
......
......@@ -565,7 +565,7 @@ os_mem_alloc_large(
if (ptr) {
if (set_to_zero) {
#ifdef UNIV_SET_MEM_TO_ZERO
memset(ret, '\0', size);
memset(ptr, '\0', size);
#endif
}
......
......@@ -131,6 +131,16 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
key=end;
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
case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */
case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */
......
......@@ -314,57 +314,57 @@ insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
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
t1 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 2 9 # # # 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 # # # # 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 t2 values (3),(4);
insert into t3 values (3,3),(4,4);
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
t1 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 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 # # # # 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 t2 values (5);
insert into t3 values (5,5);
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
t1 HEAP 9 Fixed 5 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
t3 HEAP 9 Fixed 5 9 # # # 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 # # # # 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 t2 where b=3;
delete from t3 where a=3;
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
t1 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 9 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 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 t2;
delete from t3;
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
t1 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 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 # # # # 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 t2 values (5);
insert into t3 values (5,5);
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
t1 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 1 9 # # # 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 # # # # 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 t2 where b=5;
delete from t3 where a=5;
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
t1 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 9 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 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;
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;
a+0 b+0 c+0
4 0 3
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;
a+0 b+0 c+0
2 1 4
......
This diff is collapsed.
......@@ -236,37 +236,37 @@ CREATE TABLE t3 (
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
delete from t1;
delete from t2;
delete from t3;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
drop table t1, t2, t3;
......
......@@ -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(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 = 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 c;
drop table t1;
......@@ -101,6 +103,6 @@ drop table t1;
# Some magic numbers
create table t1 (a bit(7), key(a));
insert into t1 values (44), (57);
insert into t1 values (44), (57);
select a+0 from t1;
drop table t1;
......@@ -32,3 +32,68 @@ create table t1 (v varbinary(20));
insert into t1 values('a');
insert into t1 values('a ');
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)
}
/*
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
** This is an unpacked number.
......@@ -500,6 +521,22 @@ Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table)
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
****************************************************************************/
......@@ -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,
struct st_table *new_table)
{
Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table);
/* Keys length prefixes are always packed with 2 bytes */
if (res)
struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit)
{
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 */
res->length_bytes= 2;
}
return res;
}
......@@ -6210,6 +6255,43 @@ bool Field_num::eq_def(Field *field)
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)
{
/* table_cache_key is not set for temp tables */
......@@ -6331,7 +6413,7 @@ int Field_bit::key_cmp(const byte *str, uint length)
{
int flag;
uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
if ((flag= (int) (bits - *str)))
if ((flag= (int) (bits - *(uchar*) str)))
return flag;
str++;
length--;
......@@ -6426,6 +6508,11 @@ void create_field::create_length_to_internal_length(void)
length*= charset->mbmaxlen;
key_length= pack_length;
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:
key_length= pack_length= calc_pack_length(sql_type, length);
break;
......
......@@ -113,9 +113,14 @@ public:
This trickery is used to decrease a number of malloc calls.
*/
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 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 uint32 pack_length() const { return (uint32) field_length; }
virtual void reset(void) { bzero(ptr,pack_length()); }
......@@ -184,11 +189,10 @@ public:
virtual bool can_be_compared_as_longlong() const { return FALSE; }
virtual void free() {}
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)
{
return new_field(root, new_table);
}
inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr,
uint new_null_bit);
virtual 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;
}
......@@ -994,7 +998,9 @@ public:
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
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 @@ public:
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)
{ }
struct st_table *table_arg);
enum_field_types type() const { return FIELD_TYPE_BIT; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
uint32 key_length() const { return (uint32) field_length + (bit_len > 0); }
......@@ -1235,6 +1237,9 @@ public:
field_cast_enum field_cast_type() { return FIELD_CAST_BIT; }
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
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,
keydef[i].seg[j].type= (int) type;
keydef[i].seg[j].start= pos->key_part[j].offset;
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;
if (field->null_ptr)
......
......@@ -250,54 +250,54 @@ 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)
{
uint length;
uint store_length;
KEY_PART_INFO *key_part;
const byte *key_end= key + key_length;;
for (key_part=table->key_info[idx].key_part;
(int) key_length > 0;
key_part++, key+=length, key_length-=length)
key < key_end ;
key_part++, key+= store_length)
{
uint length;
store_length= key_part->store_length;
if (key_part->null_bit)
{
key_length--;
if (*key != test(table->record[0][key_part->null_offset] &
key_part->null_bit))
return 1;
if (*key)
{
length=key_part->store_length;
continue;
}
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))
return 1;
length=key_part->length+HA_KEY_BLOB_LENGTH;
continue;
}
else
length= min((uint) (key_end-key), store_length);
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
FIELDFLAG_PACK)))
{
length=min(key_length,key_part->length);
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
FIELDFLAG_PACK)))
CHARSET_INFO *cs= key_part->field->charset();
uint char_length= key_part->length / cs->mbmaxlen;
const byte *pos= table->record[0] + key_part->offset;
if (length > char_length)
{
CHARSET_INFO *cs= key_part->field->charset();
uint char_length= key_part->length / cs->mbmaxlen;
const byte *pos= table->record[0] + key_part->offset;
if (length > char_length)
{
char_length= my_charpos(cs, pos, pos + length, char_length);
set_if_smaller(char_length, length);
}
if (cs->coll->strnncollsp(cs,
(const uchar*) key, length,
(const uchar*) pos, char_length, 0))
return 1;
char_length= my_charpos(cs, pos, pos + length, char_length);
set_if_smaller(char_length, length);
}
else if (memcmp(key,table->record[0]+key_part->offset,length))
return 1;
if (cs->coll->strnncollsp(cs,
(const uchar*) key, length,
(const uchar*) pos, char_length, 0))
return 1;
continue;
}
if (memcmp(key,table->record[0]+key_part->offset,length))
return 1;
}
return 0;
}
......
......@@ -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,
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);
if (key_tree->left != &null_element)
......@@ -5018,13 +5020,12 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
return records;
}
uint tmp_min_flag,tmp_max_flag,keynr;
char *tmp_min_key=min_key,*tmp_max_key=max_key;
tmp_min_key= min_key;
tmp_max_key= max_key;
key_tree->store(param->key[idx][key_tree->part].store_length,
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
uint min_key_length= (uint) (tmp_min_key- param->min_key);
uint max_key_length= (uint) (tmp_max_key- param->max_key);
min_key_length= (uint) (tmp_min_key- param->min_key);
max_key_length= (uint) (tmp_max_key- param->max_key);
if (param->is_ror_scan)
{
......@@ -8448,7 +8449,10 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
store_length--;
}
field->set_key_image((char*) key, key_part->length);
field->val_str(&tmp);
if (field->type() == MYSQL_TYPE_BIT)
(void) field->val_int_as_str(&tmp, 1);
else
field->val_str(&tmp);
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
if (key+store_length < key_end)
fputc('/',DBUG_FILE);
......
......@@ -2041,10 +2041,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
thd->cleanup_after_query();
if (stmt->state == Item_arena::PREPARED)
{
thd->current_arena= thd;
stmt->state= Item_arena::EXECUTED;
}
DBUG_VOID_RETURN;
}
......
......@@ -8159,25 +8159,27 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!using_unique_constraint)
{
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 */
if (maybe_null)
{
/*
To be able to group on NULL, we reserve place in group_buff
for the NULL flag just before the column.
To be able to group on NULL, we reserved place in group_buff
for the NULL flag just before the column. (see above).
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
key_part_info->null_bit=field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) table->record[0]);
group->field->move_field((char*) ++group->buff);
group_buff++;
group->buff++; // Pointer to field data
group_buff++; // Skipp null flag
}
else
group->field->move_field((char*) group_buff);
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
group_buff+= group->field->pack_length();
......
......@@ -427,11 +427,8 @@ class store_key :public Sql_alloc
field_arg->table, field_arg->charset());
}
else
{
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table);
if (to_field)
to_field->move_field(ptr, (uchar*) null, 1);
}
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
ptr, (uchar*) null, 1);
}
virtual ~store_key() {} /* Not actually needed */
virtual bool copy()=0;
......
......@@ -74,7 +74,7 @@ typedef struct st_key_part_info { /* Info about a key part */
uint16 store_length;
uint16 key_type;
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 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
......
......@@ -631,6 +631,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (!(field->flags & BINARY_FLAG))
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)
field->flags |=
((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