diff options
author | unknown <monty@mysql.com> | 2005-05-14 00:01:40 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-05-14 00:01:40 +0300 |
commit | 037b0a7b14288f078bb3e6e75c14b4fc3181b4f0 (patch) | |
tree | f66bb31f8c3bb3a7c23d82b86abf8f0810f05403 | |
parent | 04890a2e20d338a2f1b4b279c6dd6da3cd6d0f95 (diff) | |
parent | cdd6bc9bfeb1a82e7c7cfd8880f8e014ca5d9ff8 (diff) | |
download | mariadb-git-037b0a7b14288f078bb3e6e75c14b4fc3181b4f0.tar.gz |
Merge with 4.0
BitKeeper/etc/logging_ok:
auto-union
mysql-test/r/outfile2.result:
Merge rename: mysql-test/r/outfile.result -> mysql-test/r/outfile2.result
myisam/mi_key.c:
Auto merged
mysql-test/r/alter_table.result:
Auto merged
mysql-test/r/auto_increment.result:
Auto merged
mysql-test/r/innodb.result:
Auto merged
mysql-test/t/auto_increment.test:
Auto merged
mysql-test/t/innodb.test:
Auto merged
sql/handler.h:
Auto merged
mysql-test/t/alter_table.test:
Merge
mysql-test/t/outfile.test:
Merge
sql/item_func.cc:
Merge
sql/share/czech/errmsg.txt:
Merge
sql/share/danish/errmsg.txt:
Merge
sql/share/dutch/errmsg.txt:
Merge
sql/share/english/errmsg.txt:
Merge
sql/share/estonian/errmsg.txt:
Merge
sql/share/french/errmsg.txt:
Merge
sql/share/german/errmsg.txt:
Merge
sql/share/greek/errmsg.txt:
Merge
sql/share/hungarian/errmsg.txt:
Merge
sql/share/italian/errmsg.txt:
Merge
sql/share/japanese/errmsg.txt:
Merge
sql/share/korean/errmsg.txt:
Merge
sql/share/norwegian-ny/errmsg.txt:
Merge
sql/share/norwegian/errmsg.txt:
Merge
sql/share/polish/errmsg.txt:
Merge
sql/share/portuguese/errmsg.txt:
Merge
sql/share/romanian/errmsg.txt:
Merge
sql/share/russian/errmsg.txt:
Merge
sql/share/slovak/errmsg.txt:
Merge
sql/share/spanish/errmsg.txt:
Merge
sql/share/swedish/errmsg.txt:
Merge
sql/share/ukrainian/errmsg.txt:
Merge
sql/sql_table.cc:
Merge
sql/sql_yacc.yy:
Keep old
sql/unireg.cc:
Merge
-rw-r--r-- | man/mysqldump.1.in | 3 | ||||
-rw-r--r-- | myisam/mi_key.c | 31 | ||||
-rw-r--r-- | mysql-test/include/have_outfile.inc | 5 | ||||
-rw-r--r-- | mysql-test/include/test_outfile.inc | 1 | ||||
-rw-r--r-- | mysql-test/r/alter_table.result | 36 | ||||
-rw-r--r-- | mysql-test/r/auto_increment.result | 14 | ||||
-rw-r--r-- | mysql-test/r/have_outfile.require | 3 | ||||
-rw-r--r-- | mysql-test/r/innodb.result | 4 | ||||
-rw-r--r-- | mysql-test/r/outfile.result | bin | 330 -> 683 bytes | |||
-rw-r--r-- | mysql-test/r/outfile2.result | 10 | ||||
-rw-r--r-- | mysql-test/t/alter_table.test | 49 | ||||
-rw-r--r-- | mysql-test/t/auto_increment.test | 12 | ||||
-rw-r--r-- | mysql-test/t/innodb.test | 10 | ||||
-rw-r--r-- | mysql-test/t/outfile.test | 65 | ||||
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 15 | ||||
-rw-r--r-- | sql/unireg.cc | 85 |
18 files changed, 265 insertions, 84 deletions
diff --git a/man/mysqldump.1.in b/man/mysqldump.1.in index 4d841117e59..0f581429af7 100644 --- a/man/mysqldump.1.in +++ b/man/mysqldump.1.in @@ -218,7 +218,8 @@ or ), mysqldump will create rows up to net_buffer_length length. If you increase this variable, you should also ensure that the max_allowed_packet variable in the MySQL server is bigger than the net_buffer_length. .SH EXAMPLES .TP -The most normal use of mysqldump is probably for making a backup of whole databases. See Mysql Manual section 21.2 Database Backups. +The most normal use of mysqldump is probably for making a backup of whole +databases. See the section on Database Backups in the MySQL Reference Manual. .TP mysqldump \-\-opt \fP\fIdatabase\fP > backup-file.sql .TP diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 3545756779f..b7240f34538 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -301,8 +301,25 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, } /* _mi_pack_key */ - /* Put a key in record */ - /* Used when only-keyread is wanted */ + +/* + Store found key in record + + SYNOPSIS + _mi_put_key_in_record() + info MyISAM handler + keynr Key number that was used + record Store key here + + Last read key is in info->lastkey + + NOTES + Used when only-keyread is wanted + + RETURN + 0 ok + 1 error +*/ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, byte *record) @@ -313,14 +330,8 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, byte *blob_ptr; DBUG_ENTER("_mi_put_key_in_record"); - if (info->s->base.blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) - { - if (!(blob_ptr= - mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength, - &info->rec_buff))) - goto err; - } - key=(byte*) info->lastkey; + blob_ptr= info->lastkey2; /* Place to put blob parts */ + key=(byte*) info->lastkey; /* KEy that was read */ key_end=key+info->lastkey_length; for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) { diff --git a/mysql-test/include/have_outfile.inc b/mysql-test/include/have_outfile.inc new file mode 100644 index 00000000000..31e95f4810a --- /dev/null +++ b/mysql-test/include/have_outfile.inc @@ -0,0 +1,5 @@ +-- require r/have_outfile.require +disable_query_log; +select load_file(concat(@tmpdir,"/outfile.test")); +--exec rm $MYSQL_TEST_DIR/var/tmp/outfile.test +enable_query_log; diff --git a/mysql-test/include/test_outfile.inc b/mysql-test/include/test_outfile.inc new file mode 100644 index 00000000000..0bede4938c6 --- /dev/null +++ b/mysql-test/include/test_outfile.inc @@ -0,0 +1 @@ +eval select "Outfile OK" into outfile "$MYSQL_TEST_DIR/var/tmp/outfile.test"; diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 222477cece9..6cada0d5fb2 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -489,3 +489,39 @@ create table t1 ( a timestamp ); alter table t1 add unique ( a(1) ); ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys drop table t1; +drop table if exists t1, t2; +create table t1 ( a varchar(10) not null primary key ) engine=myisam; +create table t2 ( a varchar(10) not null primary key ) engine=merge union=(t1); +flush tables; +alter table t1 modify a varchar(10); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(10) NOT NULL default '', + PRIMARY KEY (`a`) +) TYPE=MRG_MyISAM UNION=(t1) +flush tables; +alter table t1 modify a varchar(10) not null; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(10) NOT NULL default '', + PRIMARY KEY (`a`) +) TYPE=MRG_MyISAM UNION=(t1) +drop table if exists t1, t2; +create table t1 (a int, b int, c int, d int, e int, f int, g int, h int,i int, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM; +insert into t1 (a) values(1); +show table status like 't1'; +Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Create_options Comment +t1 MyISAM Fixed 1 37 37 X X X X X X X X +alter table t1 modify a int; +show table status like 't1'; +Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Create_options Comment +t1 MyISAM Fixed 1 37 37 X X X X X X X X +drop table t1; +create table t1 (a int not null, b int not null, c int not null, d int not null, e int not null, f int not null, g int not null, h int not null,i int not null, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM; +insert into t1 (a) values(1); +show table status like 't1'; +Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Create_options Comment +t1 MyISAM Fixed 1 37 37 X X X X X X X X +drop table t1; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 428b2769fdb..9f3695cb1b1 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -341,3 +341,17 @@ a b 2 3 3 4 drop table t1; +CREATE TABLE t1 ( a INT AUTO_INCREMENT, b BLOB, PRIMARY KEY (a,b(10))); +INSERT INTO t1 (b) VALUES ('aaaa'); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 (b) VALUES (''); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 (b) VALUES ('bbbb'); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/r/have_outfile.require b/mysql-test/r/have_outfile.require new file mode 100644 index 00000000000..9fc2f8fdb5a --- /dev/null +++ b/mysql-test/r/have_outfile.require @@ -0,0 +1,3 @@ +load_file(concat(@tmpdir,"/outfile.test")) +Outfile OK + diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index a8af3f5f658..def462fb521 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1643,3 +1643,7 @@ select distinct concat(a, b) from t1; concat(a, b) 11113333 drop table t1; +CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; +SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); +The used table type doesn't support FULLTEXT indexes +DROP TABLE t1; diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result Binary files differindex 4dc09f65b7c..a7871592241 100644 --- a/mysql-test/r/outfile.result +++ b/mysql-test/r/outfile.result diff --git a/mysql-test/r/outfile2.result b/mysql-test/r/outfile2.result new file mode 100644 index 00000000000..4dc09f65b7c --- /dev/null +++ b/mysql-test/r/outfile2.result @@ -0,0 +1,10 @@ +drop table if exists t1; +CREATE TABLE t1 (a INT); +EXPLAIN +SELECT * +INTO OUTFILE '/tmp/t1.txt' + FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n' + FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 92651442041..d133403f42b 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -278,6 +278,45 @@ SHOW INDEX FROM t1; DROP TABLE t1; # +# BUG#4717 - check for valid table names +# +create table t1 (a int); +--error 1103 +alter table t1 rename to `t1\\`; +--error 1103 +rename table t1 to `t1\\`; +drop table t1; + +# +# BUG#6236 - ALTER TABLE MODIFY should set implicit NOT NULL on PK columns +# +drop table if exists t1, t2; +create table t1 ( a varchar(10) not null primary key ) engine=myisam; +create table t2 ( a varchar(10) not null primary key ) engine=merge union=(t1); +flush tables; +alter table t1 modify a varchar(10); +show create table t2; +flush tables; +alter table t1 modify a varchar(10) not null; +show create table t2; +drop table if exists t1, t2; + +# The following is also part of bug #6236 (CREATE TABLE didn't properly count +# not null columns for primary keys) + +create table t1 (a int, b int, c int, d int, e int, f int, g int, h int,i int, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM; +insert into t1 (a) values(1); +--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X +show table status like 't1'; +alter table t1 modify a int; +--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X +show table status like 't1'; +drop table t1; +create table t1 (a int not null, b int not null, c int not null, d int not null, e int not null, f int not null, g int not null, h int not null,i int not null, primary key (a,b,c,d,e,f,g,i,h)) engine=MyISAM; +insert into t1 (a) values(1); +--replace_column 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X +show table status like 't1'; +drop table t1; # Bug 2361 (Don't drop UNIQUE with DROP PRIMARY KEY) # @@ -297,16 +336,6 @@ alter table t1 drop key a; drop table t1; # -# BUG#4717 - check for valid table names -# -create table t1 (a int); ---error 1103 -alter table t1 rename to `t1\\`; ---error 1103 -rename table t1 to `t1\\`; -drop table t1; - -# # Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns # # The column's character set was changed but the actual data was not diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 8e11a3d68a5..ef344df5fb6 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -206,3 +206,15 @@ alter table t1 modify b varchar(255); insert into t1 values (0,4); select * from t1; drop table t1; + +# +# BUG #10045: Problem with composite AUTO_INCREMENT + BLOB key + +CREATE TABLE t1 ( a INT AUTO_INCREMENT, b BLOB, PRIMARY KEY (a,b(10))); +INSERT INTO t1 (b) VALUES ('aaaa'); +CHECK TABLE t1; +INSERT INTO t1 (b) VALUES (''); +CHECK TABLE t1; +INSERT INTO t1 (b) VALUES ('bbbb'); +CHECK TABLE t1; +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 4e18cfb224b..201489c0ddb 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1177,3 +1177,13 @@ create table t1(a int(1) , b int(1)) engine=innodb; insert into t1 values ('1111', '3333'); select distinct concat(a, b) from t1; drop table t1; + +# +# BUG#7709 test case - Boolean fulltext query against unsupported +# engines does not fail +# + +CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; +--error 1214; +SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); +DROP TABLE t1; diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test index 59ce6cc56fe..b029a65284c 100644 --- a/mysql-test/t/outfile.test +++ b/mysql-test/t/outfile.test @@ -1,3 +1,9 @@ +disable_query_log; +-- source include/test_outfile.inc +eval set @tmpdir="$MYSQL_TEST_DIR/var/tmp"; +enable_query_log; +-- source include/have_outfile.inc + # # test of into outfile|dumpfile # @@ -6,29 +12,44 @@ drop table if exists t1; --enable_warnings -# We need to check that we have 'file' privilege. +create table t1 (`a` blob); +insert into t1 values("hello world"),("Hello mars"),(NULL); +disable_query_log; +eval select * into outfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.1" from t1; +enable_query_log; +select load_file(concat(@tmpdir,"/outfile-test.1")); +disable_query_log; +eval select * into dumpfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.2" from t1 limit 1; +enable_query_log; +select load_file(concat(@tmpdir,"/outfile-test.2")); +disable_query_log; +eval select * into dumpfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.3" from t1 where a is null; +enable_query_log; +select load_file(concat(@tmpdir,"/outfile-test.3")); -#create table t1 (`a` blob); -#insert into t1 values("hello world"),("Hello mars"),(NULL); -#select * into outfile "/tmp/select-test.1" from t1; -#select load_file("/tmp/select-test.1"); -#select * into dumpfile "/tmp/select-test.2" from t1 limit 1; -#select load_file("/tmp/select-test.2"); -#select * into dumpfile "/tmp/select-test.3" from t1 where a is null; -#select load_file("/tmp/select-test.3"); -# -## the following should give errors -# -#select * into outfile "/tmp/select-test.1" from t1; -#select * into dumpfile "/tmp/select-test.1" from t1; -#select * into dumpfile "/tmp/select-test.99" from t1; -#select load_file("/tmp/select-test.not-exist"); -#drop table t1; -#drop table if exists t; -#CREATE TABLE t ( t timestamp NOT NULL, c char(200) character set latin1 NOT NULL default '', i int(11), v varchar(200), b blob, KEY t (t)) ENGINE=MyISAM; -#INSERT INTO t VALUES ('2002-12-20 12:01:20','',1,"aaa","bbb"); -#select * from t into outfile "check"; -#drop table if exists t; +# the following should give errors + +#disabled as error message has variable path +#disable_query_log; +#--error 1086 +#eval select * into outfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.1" from t1; +#--error 1086 +#eval select * into dumpfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.2" from t1; +#--error 1086 +#eval select * into dumpfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.3" from t1; +#enable_query_log; +select load_file(concat(@tmpdir,"/outfile-test.not-exist")); +--exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.1 +--exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.2 +--exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.3 +drop table t1; + +# Bug#8191 +disable_query_log; +eval select 1 into outfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.4"; +enable_query_log; +select load_file(concat(@tmpdir,"/outfile-test.4")); +--exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.4 # # Bug #5382: 'explain select into outfile' crashes the server diff --git a/sql/handler.h b/sql/handler.h index df623afcd79..de932cd51a4 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -204,6 +204,7 @@ typedef struct st_ha_create_information SQL_LIST merge_list; enum db_type db_type; enum row_type row_type; + uint null_bits; /* NULL bits at start of record */ uint options; /* OR of HA_CREATE_ options */ uint raid_type,raid_chunks; uint merge_insert_method; diff --git a/sql/item_func.cc b/sql/item_func.cc index 9c6c19f3ec9..8aa3526bbef 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3174,6 +3174,11 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) return 1; } table=((Item_field *)item)->field->table; + if (!(table->file->table_flags() & HA_CAN_FULLTEXT)) + { + my_error(ER_TABLE_CANT_HANDLE_FULLTEXT, MYF(0)); + return 1; + } table->fulltext_searched=1; return agg_arg_collations_for_comparison(cmp_collation, args+1, arg_count-1); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c03edfdb012..7b0f24bcc45 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -451,7 +451,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, const char *key_name; create_field *sql_field,*dup_field; uint field,null_fields,blob_columns; - ulong pos; + ulong record_offset= 0; KEY *key_info; KEY_PART_INFO *key_part_info; int timestamps= 0, timestamps_with_niladic= 0; @@ -629,10 +629,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } it2.rewind(); } - /* If fixed row records, we need one bit to check for deleted rows */ - if (!(db_options & HA_OPTION_PACK_RECORD)) - null_fields++; - pos=(null_fields+7)/8; + + /* record_offset will be increased with 'length-of-null-bits' later */ + record_offset= 0; it.rewind(); while ((sql_field=it++)) @@ -737,10 +736,10 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (!(sql_field->flags & NOT_NULL_FLAG)) sql_field->pack_flag|=FIELDFLAG_MAYBE_NULL; - sql_field->offset= pos; + sql_field->offset= record_offset; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; - pos+=sql_field->pack_length; + record_offset+= sql_field->pack_length; } if (timestamps_with_niladic > 1) { @@ -1048,6 +1047,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* Implicitly set primary key fields to NOT NULL for ISO conf. */ sql_field->flags|= NOT_NULL_FLAG; sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; + null_fields--; } else key_info->flags|= HA_NULL_PART_KEY; @@ -1392,6 +1392,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) create_info->data_file_name= create_info->index_file_name= 0; create_info->table_options=db_options; + create_info->null_bits= null_fields; if (rea_create_table(thd, path, create_info, fields, key_count, key_info_buffer)) diff --git a/sql/unireg.cc b/sql/unireg.cc index a550b06a466..72960640b1b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -32,18 +32,21 @@ static uchar * pack_screens(List<create_field> &create_fields, uint *info_length, uint *screens, bool small_file); -static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info); +static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info, + ulong data_offset); static bool pack_header(uchar *forminfo,enum db_type table_type, List<create_field> &create_fields, uint info_length, uint screens, uint table_options, - handler *file); + ulong data_offset, handler *file); static uint get_interval_id(uint *int_count,List<create_field> &create_fields, create_field *last_field); -static bool pack_fields(File file, List<create_field> &create_fields); +static bool pack_fields(File file, List<create_field> &create_fields, + ulong data_offset); static bool make_empty_rec(int file, enum db_type table_type, uint table_options, List<create_field> &create_fields, - uint reclength,uint null_fields); + uint reclength, uint null_fields, + ulong data_offset); /* Create a frm (table definition) file @@ -71,7 +74,7 @@ bool mysql_create_frm(THD *thd, my_string file_name, { uint reclength,info_length,screens,key_info_length,maxlength,null_fields; File file; - ulong filepos; + ulong filepos, data_offset; uchar fileinfo[64],forminfo[288],*keybuff; TYPELIB formnames; uchar *screen_buff; @@ -81,9 +84,16 @@ bool mysql_create_frm(THD *thd, my_string file_name, if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0))) DBUG_RETURN(1); if (db_file == NULL) - db_file=get_new_handler((TABLE*) 0, create_info->db_type); + db_file= get_new_handler((TABLE*) 0, create_info->db_type); + + /* If fixed row records, we need one bit to check for deleted rows */ + if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) + create_info->null_bits++; + data_offset= (create_info->null_bits + 7) / 8; + if (pack_header(forminfo, create_info->db_type,create_fields,info_length, - screens, create_info->table_options, db_file)) + screens, create_info->table_options, + data_offset, db_file)) { my_free((gptr) screen_buff,MYF(0)); if (thd->net.last_errno != ER_TOO_MANY_FIELDS) @@ -94,7 +104,7 @@ bool mysql_create_frm(THD *thd, my_string file_name, if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1))) DBUG_RETURN(1); if (pack_header(forminfo, create_info->db_type, create_fields,info_length, - screens, create_info->table_options, db_file)) + screens, create_info->table_options, data_offset, db_file)) { my_free((gptr) screen_buff,MYF(0)); DBUG_RETURN(1); @@ -112,7 +122,7 @@ bool mysql_create_frm(THD *thd, my_string file_name, uint key_buff_length=keys*(7+NAME_LEN+MAX_REF_PARTS*9)+16; keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); - key_info_length=pack_keys(keybuff,keys,key_info); + key_info_length= pack_keys(keybuff, keys, key_info, data_offset); VOID(get_form_pos(file,fileinfo,&formnames)); if (!(filepos=make_new_entry(file,fileinfo,&formnames,""))) goto err; @@ -135,13 +145,13 @@ bool mysql_create_frm(THD *thd, my_string file_name, (ulong) uint2korr(fileinfo+6)+ (ulong) key_buff_length, MY_SEEK_SET,MYF(0))); if (make_empty_rec(file,create_info->db_type,create_info->table_options, - create_fields,reclength,null_fields)) + create_fields,reclength, null_fields, data_offset)) goto err; VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); if (my_write(file,(byte*) forminfo,288,MYF_RW) || my_write(file,(byte*) screen_buff,info_length,MYF_RW) || - pack_fields(file,create_fields)) + pack_fields(file, create_fields, data_offset)) goto err; #ifdef HAVE_CRYPTED_FRM @@ -313,7 +323,8 @@ static uchar * pack_screens(List<create_field> &create_fields, /* Pack keyinfo and keynames to keybuff for save in form-file. */ -static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) +static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, + ulong data_offset) { uint key_parts,length; uchar *pos, *keyname_pos; @@ -340,10 +351,13 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) key_part++) { - DBUG_PRINT("loop",("field: %d startpos: %ld length: %ld", - key_part->fieldnr,key_part->offset,key_part->length)); + uint offset; + DBUG_PRINT("loop",("field: %d startpos: %lu length: %ld", + key_part->fieldnr, key_part->offset + data_offset, + key_part->length)); int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED); - int2store(pos+2,key_part->offset+1); + offset= (uint) (key_part->offset+data_offset+1); + int2store(pos+2, offset); pos[4]=0; // Sort order int2store(pos+5,key_part->key_type); int2store(pos+7,key_part->length); @@ -384,8 +398,8 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) static bool pack_header(uchar *forminfo, enum db_type table_type, List<create_field> &create_fields, - uint info_length, uint screens,uint table_options, - handler *file) + uint info_length, uint screens, uint table_options, + ulong data_offset, handler *file) { uint length,int_count,int_length,no_empty, int_parts; uint time_stamp_pos,null_fields; @@ -425,10 +439,10 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, if (field->sql_type == FIELD_TYPE_TIMESTAMP && MTYP_TYPENR(field->unireg_check) != Field::NONE && !time_stamp_pos) - time_stamp_pos=(int) field->offset+1; + time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1; length=field->pack_length; - if ((int) field->offset+length > reclength) - reclength=(int) field->offset+length; + if ((uint) field->offset+ (uint) data_offset+ length > reclength) + reclength=(uint) (field->offset+ data_offset + length); n_length+= (ulong) strlen(field->field_name)+1; field->interval_id=0; if (field->interval) @@ -538,7 +552,8 @@ static uint get_interval_id(uint *int_count,List<create_field> &create_fields, /* Save fields, fieldnames and intervals */ -static bool pack_fields(File file,List<create_field> &create_fields) +static bool pack_fields(File file, List<create_field> &create_fields, + ulong data_offset) { reg2 uint i; uint int_count, comment_length=0; @@ -553,11 +568,13 @@ static bool pack_fields(File file,List<create_field> &create_fields) int_count=0; while ((field=it++)) { + uint recpos; buff[0]= (uchar) field->row; buff[1]= (uchar) field->col; buff[2]= (uchar) field->sc_length; int2store(buff+3, field->length); - uint recpos=(uint) field->offset+1; + /* The +1 is here becasue the col offset in .frm file have offset 1 */ + recpos= field->offset+1 + (uint) data_offset; int3store(buff+5,recpos); int2store(buff+8,field->pack_flag); int2store(buff+10,field->unireg_check); @@ -643,11 +660,12 @@ static bool pack_fields(File file,List<create_field> &create_fields) static bool make_empty_rec(File file,enum db_type table_type, uint table_options, List<create_field> &create_fields, - uint reclength, uint null_fields) + uint reclength, uint null_fields, + ulong data_offset) { int error; Field::utype type; - uint firstpos,null_count,null_length; + uint firstpos,null_count; uchar *buff,*null_pos; TABLE table; create_field *field; @@ -672,17 +690,16 @@ static bool make_empty_rec(File file,enum db_type table_type, firstpos=reclength; null_count=0; if (!(table_options & HA_OPTION_PACK_RECORD)) - { - null_fields++; // Need one bit for delete mark - null_count++; - } - bfill(buff,(null_length=(null_fields+7)/8),255); + null_count++; // Need one bit for delete mark + DBUG_ASSERT(data_offset == ((null_fields + null_count + 7) / 8)); + bfill(buff, (uint) data_offset, 255); null_pos=buff; List_iterator<create_field> it(create_fields); while ((field=it++)) { - Field *regfield=make_field((char*) buff+field->offset,field->length, + Field *regfield=make_field((char*) buff+field->offset + data_offset, + field->length, field->flags & NOT_NULL_FLAG ? 0: null_pos+null_count/8, 1 << (null_count & 7), @@ -698,9 +715,9 @@ static bool make_empty_rec(File file,enum db_type table_type, if (!(field->flags & NOT_NULL_FLAG)) null_count++; - if ((uint) field->offset < firstpos && + if ((uint) (field->offset + data_offset) < firstpos && regfield->type() != FIELD_TYPE_NULL) - firstpos= field->offset; + firstpos= field->offset + data_offset; type= (Field::utype) MTYP_TYPENR(field->unireg_check); @@ -724,8 +741,8 @@ static bool make_empty_rec(File file,enum db_type table_type, } /* Fill not used startpos */ - bfill((byte*) buff+null_length,firstpos-null_length,255); - error=(int) my_write(file,(byte*) buff,(uint) reclength,MYF_RW); + bfill((byte*) buff+data_offset, firstpos- (uint) data_offset, 255); + error=(int) my_write(file,(byte*) buff, (uint) reclength,MYF_RW); my_free((gptr) buff,MYF(MY_FAE)); delete handler; DBUG_RETURN(error); |