diff options
author | unknown <monty@mysql.com> | 2004-12-19 20:25:19 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-12-19 20:25:19 +0200 |
commit | 50ceaacac71b11ebb8a83631a6cfdfa21951921d (patch) | |
tree | edce84855fbf08b0328dae28794074f565be89e6 | |
parent | 0b661d5505541ff7424ee8a83c5160ce6067e714 (diff) | |
download | mariadb-git-50ceaacac71b11ebb8a83631a6cfdfa21951921d.tar.gz |
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
-rw-r--r-- | include/my_base.h | 3 | ||||
-rw-r--r-- | innobase/os/os0proc.c | 2 | ||||
-rw-r--r-- | myisam/mi_dbug.c | 10 | ||||
-rw-r--r-- | mysql-test/r/show_check.result | 42 | ||||
-rw-r--r-- | mysql-test/r/type_bit.result | 6 | ||||
-rw-r--r-- | mysql-test/r/type_varchar.result | 308 | ||||
-rw-r--r-- | mysql-test/t/show_check.test | 14 | ||||
-rw-r--r-- | mysql-test/t/type_bit.test | 4 | ||||
-rw-r--r-- | mysql-test/t/type_varchar.test | 65 | ||||
-rw-r--r-- | sql/field.cc | 99 | ||||
-rw-r--r-- | sql/field.h | 29 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 3 | ||||
-rw-r--r-- | sql/key.cc | 54 | ||||
-rw-r--r-- | sql/opt_range.cc | 18 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 18 | ||||
-rw-r--r-- | sql/sql_select.h | 7 | ||||
-rw-r--r-- | sql/structs.h | 2 | ||||
-rw-r--r-- | sql/table.cc | 3 |
19 files changed, 589 insertions, 101 deletions
diff --git a/include/my_base.h b/include/my_base.h index 9c860c7eebd..4d043cf6b5b 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -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 diff --git a/innobase/os/os0proc.c b/innobase/os/os0proc.c index 98254ae1055..dd2037695b7 100644 --- a/innobase/os/os0proc.c +++ b/innobase/os/os0proc.c @@ -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 } diff --git a/myisam/mi_dbug.c b/myisam/mi_dbug.c index 531d0b9ddba..e782d21afe7 100644 --- a/myisam/mi_dbug.c +++ b/myisam/mi_dbug.c @@ -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 */ diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index dab35262e0a..ec9bd33d301 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -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; diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 41d84584870..45f887461e7 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -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 diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index 31fbe7b7b5d..1c2653bd225 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -68,3 +68,311 @@ 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; +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"); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using index +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where; Using index +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using index +alter table t1 change v v varchar(255); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(256); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(257); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(258); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(259); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(258); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(257); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(256); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(255); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +alter table t1 change v v varchar(254); +select * from t1 where v like 'This is a test' order by v; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 3 Using where; Using index +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 257 const 3 Using where; Using index +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 257 NULL 2 Using where; Using index +alter table t1 change v v varchar(253); +alter table t1 change v v varchar(254), drop key v; +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; +v +This is a test +This is a test +select * from t1 where v='This is a test' order by v; +v +This is a test +This is a test +This is a test +select * from t1 where v like 'S%' order by v; +v +Short string +Some sample data +Some samples +explain select * from t1 where v like 'This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 4 Using where; Using filesort +explain select * from t1 where v='This is a test' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref v v 13 const 4 Using where +explain select * from t1 where v like 'S%' order by v; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 13 NULL 2 Using where; Using filesort +drop table t1; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index b09d7240721..8680da9b31a 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -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; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 075fd5bce07..0c1c22099f9 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -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; diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test index f6e9bb24087..0168128d513 100644 --- a/mysql-test/t/type_varchar.test +++ b/mysql-test/t/type_varchar.test @@ -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; diff --git a/sql/field.cc b/sql/field.cc index ee12ce5ea68..ebeee476985 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -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; diff --git a/sql/field.h b/sql/field.h index 2d84d240839..6ce5cf2a526 100644 --- a/sql/field.h +++ b/sql/field.h @@ -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); }; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index ce3287d8745..c23a728b715 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -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) diff --git a/sql/key.cc b/sql/key.cc index fe35638608d..d54b8721cab 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -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; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0f54f06a22b..80237766d29 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -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); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6d59d465445..8afefe3cae8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -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; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5425ddfb64b..44412cdc43a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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(); diff --git a/sql/sql_select.h b/sql/sql_select.h index be3a72836b4..0f26207b391 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -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; diff --git a/sql/structs.h b/sql/structs.h index 5d0c7bc4f1f..0b59c3abeb3 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -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 ; diff --git a/sql/table.cc b/sql/table.cc index 610de9e4e9b..c18a2557337 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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) && |