From 3cca6ad8c1f9b15ced9efc28c15b9c25a5c1e624 Mon Sep 17 00:00:00 2001 From: "brian@zim.(none)" <> Date: Fri, 26 Jan 2007 10:17:53 -0800 Subject: [PATCH 1/2] Fixed a warning. Added the -A option so that the autoincrement could be set outside of the file. --- storage/archive/archive_reader.c | 46 ++++++++++++++++++++++++++++---- storage/archive/ha_archive.cc | 4 +-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c index 89cc6740300..66b90130882 100644 --- a/storage/archive/archive_reader.c +++ b/storage/archive/archive_reader.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -15,10 +16,12 @@ static void get_options(int *argc,char * * *argv); static void print_version(void); static void usage(void); static const char *opt_tmpdir; -static const char *new_auto_increment_value; +static const char *new_auto_increment; +unsigned long long new_auto_increment_value; static const char *load_default_groups[]= { "archive_reader", 0 }; static char **default_argv; int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm; +int opt_autoincrement; int main(int argc, char *argv[]) { @@ -40,6 +43,35 @@ int main(int argc, char *argv[]) return 0; } + if (opt_autoincrement) + { + azio_stream writer_handle; + + if (new_auto_increment_value) + { + if (reader_handle.auto_increment >= new_auto_increment_value) + { + printf("Value is lower then current value\n"); + goto end; + } + } + else + { + new_auto_increment_value= reader_handle.auto_increment + 1; + } + + if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY))) + { + printf("Could not open file for update: %s\n", argv[0]); + goto end; + } + + writer_handle.auto_increment= new_auto_increment_value; + + azclose(&writer_handle); + azflush(&reader_handle, Z_SYNC_FLUSH); + } + printf("Version %u\n", reader_handle.version); if (reader_handle.version > 2) { @@ -272,7 +304,11 @@ get_one_option(int optid, printf("Not implemented yet\n"); break; case 'A': - printf("Not implemented yet\n"); + opt_autoincrement= 1; + if (argument) + new_auto_increment_value= strtoull(argument, NULL, 0); + else + new_auto_increment_value= 0; break; case '?': usage(); @@ -317,9 +353,9 @@ static struct my_option my_long_options[] = {"repair", 'r', "Repair a damaged Archive version 3 or above file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"set-auto-increment", 'A', - "Force auto_increment to start at this or higher value.", - (gptr*) &new_auto_increment_value, - (gptr*) &new_auto_increment_value, + "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", + (gptr*) &new_auto_increment, + (gptr*) &new_auto_increment, 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Only print errors. One can use two -s to make archive_reader very silent.", diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 41f3017fdc2..db90c0bfb8d 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -587,7 +587,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, azio_stream create_stream; /* Archive file we are working with */ File frm_file; /* File handler for readers */ MY_STAT file_stat; // Stat information for the data file - char *frm_ptr; + byte *frm_ptr; DBUG_ENTER("ha_archive::create"); @@ -659,7 +659,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, VOID(my_fstat(frm_file, &file_stat, MYF(MY_WME))); frm_ptr= (char *)my_malloc(sizeof(char) * file_stat.st_size , MYF(0)); my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0)); - azwrite_frm(&create_stream, frm_ptr, file_stat.st_size); + azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size); my_close(frm_file, MYF(0)); my_free(frm_ptr, MYF(0)); From 6829b2a5a6c7fc35f4f3025057954680cce54d27 Mon Sep 17 00:00:00 2001 From: "brian@zim.(none)" <> Date: Fri, 26 Jan 2007 11:15:16 -0800 Subject: [PATCH 2/2] This fixes a bug in show create table displaying auto_increment field when it should not. It also refactors the test case for Archive (removed two bad tests). --- mysql-test/r/archive.result | 125 +++++++++++++++++++++------------- mysql-test/t/archive.test | 73 ++++++++++++-------- storage/archive/ha_archive.cc | 47 ++++--------- 3 files changed, 133 insertions(+), 112 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 257b22908d4..d15103be011 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -1,4 +1,5 @@ -drop table if exists t1,t2,t3,t4,t5; +DROP TABLE if exists t1,t2,t3,t4,t5,t6; +SET storage_engine=ARCHIVE; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -184,7 +185,7 @@ fld1 fld3 250503 heaving 250504 population 250505 bomb -create table t3 engine=archive select * FROM t2; +CREATE TABLE t3 engine=archive select * FROM t2; select * FROM t3 where fld3='bonfire'; auto fld1 companynr fld3 fld4 fld5 fld6 1191 068504 00 bonfire corresponds positively @@ -12358,7 +12359,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b char(12), PRIMARY KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); @@ -12391,7 +12392,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b char(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 AUTO_INCREMENT=5; +) DEFAULT CHARSET=latin1 AUTO_INCREMENT=5; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); @@ -12443,7 +12444,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b blob(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "We the people"); INSERT INTO t5 VALUES (NULL, "in order to form a more pefect union"); @@ -12496,7 +12497,7 @@ CREATE TABLE `t5` ( b blob(12), c blob(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo", "grok this!"); INSERT INTO t5 VALUES (NULL, "We the people", NULL); INSERT INTO t5 VALUES (NULL, "in order to form a more peefect union", "secure the blessing of liberty"); @@ -12545,8 +12546,8 @@ SELECT c FROM t5 WHERE a IN (32, 23, 5); c NULL posterity -drop table t1; -create table t1 (v varchar(32)); +DROP TABLE t1; +CREATE TABLE t1 (v varchar(32)) ; insert into t1 values ('def'),('abc'),('hij'),('3r4f'); select * from t1; v @@ -12554,68 +12555,34 @@ def abc hij 3r4f -alter table t1 change v v2 varchar(32); +ALTER TABLE t1 change v v2 varchar(32); select * from t1; v2 def abc hij 3r4f -alter table t1 change v2 v varchar(64); +ALTER TABLE t1 change v2 v varchar(64); select * from t1; v def abc hij 3r4f -update t1 set v = 'lmn' where v = 'hij'; -select * from t1; -v -def -abc -lmn -3r4f -alter table t1 add i int auto_increment not null primary key first; +ALTER TABLE t1 add i int auto_increment not null primary key first; select * from t1; i v 1 def 2 abc -3 lmn +3 hij 4 3r4f -update t1 set i=5 where i=3; -select * from t1; -i v -1 def -2 abc -5 lmn -4 3r4f -alter table t1 change i i bigint; -select * from t1; -i v -1 def -2 abc -5 lmn -4 3r4f -alter table t1 add unique key (i, v); -select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn'); -i v -4 3r4f -alter table t1 data directory="$MYSQLTEST_VARDIR/tmp"; -Warnings: -Warning 0 DATA DIRECTORY option ignored -select * from t1; -i v -1 def -2 abc -4 3r4f -5 lmn DROP TABLE t5; CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b varchar(250), c varchar(800), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo", "grok this!"); INSERT INTO t5 VALUES (NULL, "We the people", NULL); INSERT INTO t5 VALUES (NULL, "in order to form a more peefect union", "secure the blessing of liberty"); @@ -12636,4 +12603,66 @@ a b c 23 provide for the common defense posterity 33 promote the general welfare do ordain 34 abcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyz do ordain -drop table t1, t2, t4, t5; +CREATE TABLE `t6` ( +`a` int(11) NOT NULL auto_increment, +b blob(12), +c int, +KEY (`a`) +) DEFAULT CHARSET=latin1; +SELECT * FROM t6; +a b c +INSERT INTO t6 VALUES (NULL, "foo", NULL); +INSERT INTO t6 VALUES (NULL, "We the people", 5); +INSERT INTO t6 VALUES (NULL, "in order to form a more pefect union", 9); +INSERT INTO t6 VALUES (NULL, "establish justice", NULL); +INSERT INTO t6 VALUES (NULL, NULL, NULL); +INSERT INTO t6 VALUES (32, "ensure domestic tranquility", NULL); +INSERT INTO t6 VALUES (23, "provide for the common defense", 30); +INSERT INTO t6 VALUES (NULL, "fo fooo", 70); +INSERT INTO t6 VALUES (NULL, NULL, 98); +INSERT INTO t6 VALUES (NULL, "promote the general welfare", 50); +SELECT * FROM t6; +a b c +1 foo NULL +2 We the people 5 +3 in order to form a more pefect union 9 +4 establish justice NULL +5 NULL NULL +32 ensure domestic tranquility NULL +23 provide for the common defense 30 +33 fo fooo 70 +34 NULL 98 +35 promote the general welfare 50 +SELECT * FROM t6 ORDER BY a; +a b c +1 foo NULL +2 We the people 5 +3 in order to form a more pefect union 9 +4 establish justice NULL +5 NULL NULL +23 provide for the common defense 30 +32 ensure domestic tranquility NULL +33 fo fooo 70 +34 NULL 98 +35 promote the general welfare 50 +SELECT * FROM t6 ORDER BY a DESC; +a b c +35 promote the general welfare 50 +34 NULL 98 +33 fo fooo 70 +32 ensure domestic tranquility NULL +23 provide for the common defense 30 +5 NULL NULL +4 establish justice NULL +3 in order to form a more pefect union 9 +2 We the people 5 +1 foo NULL +SHOW CREATE TABLE t6; +Table Create Table +t6 CREATE TABLE `t6` ( + `a` int(11) NOT NULL AUTO_INCREMENT, + `b` tinyblob, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`) +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +DROP TABLE t1, t2, t4, t5; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 37542c272a9..ddb313217a6 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -6,9 +6,11 @@ -- source include/have_binlog_format_mixed_or_statement.inc --disable_warnings -drop table if exists t1,t2,t3,t4,t5; +DROP TABLE if exists t1,t2,t3,t4,t5,t6; --enable_warnings +SET storage_engine=ARCHIVE; + CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -1294,7 +1296,7 @@ select fld1,fld3 FROM t2 where fld1 like "25050_"; # # Test rename of table # -create table t3 engine=archive select * FROM t2; +CREATE TABLE t3 engine=archive select * FROM t2; select * FROM t3 where fld3='bonfire'; select count(*) FROM t3; # Clean up path in error message @@ -1356,7 +1358,7 @@ while (`SELECT COUNT(auto)!=1214 FROM t2`) } SELECT COUNT(auto) FROM t2; -# Adding test for alter table +# Adding test for ALTER TABLE ALTER TABLE t2 DROP COLUMN fld6; SHOW CREATE TABLE t2; SELECT * FROM t2; @@ -1369,7 +1371,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b char(12), PRIMARY KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); @@ -1393,7 +1395,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b char(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 AUTO_INCREMENT=5; +) DEFAULT CHARSET=latin1 AUTO_INCREMENT=5; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "foo"); @@ -1419,7 +1421,7 @@ CREATE TABLE `t5` ( `a` int(11) NOT NULL auto_increment, b blob(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo"); INSERT INTO t5 VALUES (NULL, "We the people"); @@ -1447,7 +1449,7 @@ CREATE TABLE `t5` ( b blob(12), c blob(12), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo", "grok this!"); INSERT INTO t5 VALUES (NULL, "We the people", NULL); @@ -1464,35 +1466,24 @@ SELECT c FROM t5; SELECT c FROM t5 WHERE a =3; SELECT c FROM t5 WHERE a IN (32, 23, 5); -# Adding this in case someone tries to add fast alter table and doesn't tes +# Adding this in case someone tries to add fast ALTER TABLE and doesn't tes # it. -# Some additional tests for new, faster alter table. Note that most of the -# whole alter table code is being tested all around the test suite already. +# Some additional tests for new, faster ALTER TABLE. Note that most of the +# whole ALTER TABLE code is being tested all around the test suite already. # -drop table t1; -create table t1 (v varchar(32)); +DROP TABLE t1; +CREATE TABLE t1 (v varchar(32)) ; insert into t1 values ('def'),('abc'),('hij'),('3r4f'); select * from t1; # Fast alter, no copy performed -alter table t1 change v v2 varchar(32); +ALTER TABLE t1 change v v2 varchar(32); select * from t1; # Fast alter, no copy performed -alter table t1 change v2 v varchar(64); +ALTER TABLE t1 change v2 v varchar(64); select * from t1; -update t1 set v = 'lmn' where v = 'hij'; -select * from t1; -# Regular alter table -alter table t1 add i int auto_increment not null primary key first; -select * from t1; -update t1 set i=5 where i=3; -select * from t1; -alter table t1 change i i bigint; -select * from t1; -alter table t1 add unique key (i, v); -select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn'); - -alter table t1 data directory="$MYSQLTEST_VARDIR/tmp"; +# Regular ALTER TABLE +ALTER TABLE t1 add i int auto_increment not null primary key first; select * from t1; # Testing cleared row key @@ -1503,7 +1494,7 @@ CREATE TABLE `t5` ( b varchar(250), c varchar(800), KEY (`a`) -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1; +) DEFAULT CHARSET=latin1; INSERT INTO t5 VALUES (NULL, "foo", "grok this!"); INSERT INTO t5 VALUES (NULL, "We the people", NULL); @@ -1516,11 +1507,35 @@ INSERT INTO t5 VALUES (NULL, "abcdeghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyz SELECT * FROM t5; +CREATE TABLE `t6` ( +`a` int(11) NOT NULL auto_increment, +b blob(12), +c int, +KEY (`a`) +) DEFAULT CHARSET=latin1; +SELECT * FROM t6; +INSERT INTO t6 VALUES (NULL, "foo", NULL); +INSERT INTO t6 VALUES (NULL, "We the people", 5); +INSERT INTO t6 VALUES (NULL, "in order to form a more pefect union", 9); +INSERT INTO t6 VALUES (NULL, "establish justice", NULL); +INSERT INTO t6 VALUES (NULL, NULL, NULL); +INSERT INTO t6 VALUES (32, "ensure domestic tranquility", NULL); +INSERT INTO t6 VALUES (23, "provide for the common defense", 30); +INSERT INTO t6 VALUES (NULL, "fo fooo", 70); +INSERT INTO t6 VALUES (NULL, NULL, 98); +INSERT INTO t6 VALUES (NULL, "promote the general welfare", 50); +SELECT * FROM t6; +SELECT * FROM t6 ORDER BY a; +SELECT * FROM t6 ORDER BY a DESC; + +SHOW CREATE TABLE t6; + + # # Cleanup, test is over # --disable_warnings -drop table t1, t2, t4, t5; +DROP TABLE t1, t2, t4, t5; --enable_warnings diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index db90c0bfb8d..6a03783ac3f 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -28,13 +28,13 @@ /* First, if you want to understand storage engines you should look at ha_example.cc and ha_example.h. + This example was written as a test case for a customer who needed a storage engine without indexes that could compress data very well. So, welcome to a completely compressed storage engine. This storage engine only does inserts. No replace, deletes, or updates. All reads are - complete table scans. Compression is done through azip (bzip compresses - better, but only marginally, if someone asks I could add support for - it too, but beaware that it costs a lot more in CPU time then azip). + complete table scans. Compression is done through a combination of packing + and making use of the zlib library We keep a file pointer open for each instance of ha_archive for each read but for writes we keep one open file handle just for that. We flush it @@ -80,38 +80,17 @@ TODO: - Add bzip optional support. Allow users to set compression level. Implement versioning, should be easy. Allow for errors, find a way to mark bad rows. Add optional feature so that rows can be flushed at interval (which will cause less compression but may speed up ordered searches). Checkpoint the meta file to allow for faster rebuilds. - Dirty open (right now the meta file is repaired if a crash occured). Option to allow for dirty reads, this would lower the sync calls, which would make inserts a lot faster, but would mean highly arbitrary reads. -Brian */ -/* - Notes on file formats. - The Meta file is layed out as: - check - Just an int of 254 to make sure that the the file we are opening was - never corrupted. - version - The current version of the file format. - rows - This is an unsigned long long which is the number of rows in the data - file. - check point - Reserved for future use - auto increment - MAX value for autoincrement - dirty - Status of the file, whether or not its values are the latest. This - flag is what causes a repair to occur - - The data file: - check - Just an int of 254 to make sure that the the file we are opening was - never corrupted. - version - The current version of the file format. - data - The data is stored in a "row +blobs" format. -*/ /* Variables for archive share methods */ pthread_mutex_t archive_mutex; @@ -121,13 +100,6 @@ static HASH archive_open_tables; #define ARZ ".ARZ" // The data file #define ARN ".ARN" // Files used during an optimize call #define ARM ".ARM" // Meta file (deprecated) -/* - uchar + uchar + ulonglong + ulonglong + ulonglong + ulonglong + FN_REFLEN - + uchar -*/ -#define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \ - + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + FN_REFLEN \ - + sizeof(uchar) /* uchar + uchar @@ -761,8 +733,9 @@ unsigned int ha_archive::pack_row(byte *record) for (Field **field=table->field ; *field ; field++) { - ptr=(byte*) (*field)->pack((char*) ptr, - (char*) record + (*field)->offset(record)); + if (!((*field)->is_null())) + ptr=(byte*) (*field)->pack((char*) ptr, + (char*) record + (*field)->offset(record)); } int4store(record_buffer->buffer, (int)(ptr - record_buffer->buffer - @@ -1114,7 +1087,11 @@ int ha_archive::unpack_row(azio_stream *file_to_read, byte *record) memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; for (Field **field=table->field ; *field ; field++) - ptr= (*field)->unpack((char *)record + (*field)->offset(table->record[0]), ptr); + if (!((*field)->is_null())) + { + ptr= (*field)->unpack((char *)record + + (*field)->offset(table->record[0]), ptr); + } DBUG_RETURN(0); } @@ -1439,7 +1416,7 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info) DBUG_ENTER("ha_archive::update_create_info"); ha_archive::info(HA_STATUS_AUTO); - if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) + if (create_info->used_fields & HA_CREATE_USED_AUTO) { /* Internally Archive keeps track of last used, not next used.