Commit 7a4bd76a authored by unknown's avatar unknown

Fixes for the remaining 'not-yet-fixed' bugs found by Guilhem when running all...

Fixes for the remaining 'not-yet-fixed' bugs found by Guilhem when running all tests with maria engine and one bug in maria_pack reported by Martin:
- Fix that query cache works with Maria
- Fixed wrong calculation if min_key_length which casued some tables to assert in insert if key contained NULL
- Restore auto_increment value if insert statement fails
- Fixed rare bug that caused crash in maria_pack if buffer was flushed at wrong point in time


configure.in:
  Added maria extension to distribution
mysql-test/r/maria.result:
  More test cases to cover bugs found by Guilhem
mysql-test/t/maria.test:
  More test cases to cover bugs found by Guilhem
storage/maria/ha_maria.cc:
  Fix that query cache works with Maria
storage/maria/ma_blockrec.c:
  Removed duplicate functionallity (already done in ma_pagecrc.c)
storage/maria/ma_create.c:
  Fixed wrong calculation if min_key_length which casued some tables to assert in insert if key contained NULL
storage/maria/ma_key_recover.c:
  Restore auto_increment value if insert statement fails
storage/maria/maria_def.h:
  Added variables to track auto_increment changes to be able to restore it in case of duplicate key
storage/maria/maria_pack.c:
  Fixed rare bug that caused crash if buffer was flushed at wrong point in time
storage/maria/unittest/ma_test_all-t:
  Added option --abort-on-error
  Ordered help message
parent 5ffc919b
...@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM ...@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
# #
# When changing major version number please also check switch statement # When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version(). # in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.23-rc) AM_INIT_AUTOMAKE(mysql, 5.1.23-maria-alpha)
AM_CONFIG_HEADER([include/config.h:config.h.in]) AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
......
...@@ -2102,6 +2102,30 @@ NULL NULL ...@@ -2102,6 +2102,30 @@ NULL NULL
alter table t1 add column d char(0) not null, add key (d); alter table t1 add column d char(0) not null, add key (d);
ERROR 42000: The used storage engine can't index column 'd' ERROR 42000: The used storage engine can't index column 'd'
drop table t1; drop table t1;
CREATE TABLE t1 (a bit(3));
insert into t1 values (NULL),(0),(1),(2),(3),(4),(5),(6),(7);
select hex(a) from t1;
hex(a)
NULL
0
1
2
3
4
5
6
7
drop table t1;
create table t1(a bit not null);
insert into t1 values(0),(1);
select a+0 from t1;
a+0
0
1
drop table t1;
CREATE TABLE t1 (col1 int, s1 char(16) DEFAULT NULL, s2 char(16) DEFAULT NULL, KEY (s1,s2));
insert into t1 (col1) values(0);
drop table t1;
set global maria_page_checksum=1; set global maria_page_checksum=1;
create table t1 (a int); create table t1 (a int);
show create table t1; show create table t1;
...@@ -2165,3 +2189,14 @@ check table t1; ...@@ -2165,3 +2189,14 @@ check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; drop table t1;
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE t1 (id int(11) PRIMARY KEY auto_increment,f1 varchar(10) NOT NULL UNIQUE);
INSERT IGNORE INTO t1 (f1) VALUES ("test1");
INSERT IGNORE INTO t1 (f1) VALUES ("test1");
INSERT IGNORE INTO t1 (f1) VALUES ("test2");
SELECT * FROM t1;
id f1
1 test1
2 test2
drop table t1;
SET SQL_MODE = 'TRADITIONAL';
...@@ -1332,6 +1332,23 @@ select length(b),length(c) from t1 order by c; ...@@ -1332,6 +1332,23 @@ select length(b),length(c) from t1 order by c;
alter table t1 add column d char(0) not null, add key (d); alter table t1 add column d char(0) not null, add key (d);
drop table t1; drop table t1;
CREATE TABLE t1 (a bit(3));
insert into t1 values (NULL),(0),(1),(2),(3),(4),(5),(6),(7);
select hex(a) from t1;
drop table t1;
create table t1(a bit not null);
insert into t1 values(0),(1);
select a+0 from t1;
drop table t1;
#
# Test of min_key_length
#
CREATE TABLE t1 (col1 int, s1 char(16) DEFAULT NULL, s2 char(16) DEFAULT NULL, KEY (s1,s2));
insert into t1 (col1) values(0);
drop table t1;
# #
# Show that page_checksum is remembered # Show that page_checksum is remembered
# #
...@@ -1396,6 +1413,19 @@ optimize table t1; ...@@ -1396,6 +1413,19 @@ optimize table t1;
check table t1; check table t1;
drop table t1; drop table t1;
#
# Test auto-increment
#
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE t1 (id int(11) PRIMARY KEY auto_increment,f1 varchar(10) NOT NULL UNIQUE);
INSERT IGNORE INTO t1 (f1) VALUES ("test1");
INSERT IGNORE INTO t1 (f1) VALUES ("test1");
INSERT IGNORE INTO t1 (f1) VALUES ("test2");
SELECT * FROM t1;
drop table t1;
SET SQL_MODE = 'TRADITIONAL';
# End of 5.2 tests # End of 5.2 tests
--disable_result_log --disable_result_log
......
...@@ -2802,6 +2802,9 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name, ...@@ -2802,6 +2802,9 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
*engine_callback, *engine_callback,
ulonglong *engine_data) ulonglong *engine_data)
{ {
ulonglong actual_data_file_length;
ulonglong current_data_file_length;
/* /*
No call back function is needed to determine if a cached statement No call back function is needed to determine if a cached statement
is valid or not. is valid or not.
...@@ -2822,8 +2825,6 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name, ...@@ -2822,8 +2825,6 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
If the table size is unknown the SELECT statement can't be cached. If the table size is unknown the SELECT statement can't be cached.
*/ */
ulonglong actual_data_file_length;
ulonglong current_data_file_length;
/* /*
POSIX visibility rules specify that "2. Whatever memory values a POSIX visibility rules specify that "2. Whatever memory values a
...@@ -2839,7 +2840,8 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name, ...@@ -2839,7 +2840,8 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
actual_data_file_length= file->s->state.state.data_file_length; actual_data_file_length= file->s->state.state.data_file_length;
current_data_file_length= file->save_state.data_file_length; current_data_file_length= file->save_state.data_file_length;
if (current_data_file_length != actual_data_file_length) if (!file->s->now_transactional &&
current_data_file_length != actual_data_file_length)
{ {
/* Don't cache current statement. */ /* Don't cache current statement. */
return FALSE; return FALSE;
......
...@@ -1936,10 +1936,6 @@ static my_bool write_full_pages(MARIA_HA *info, ...@@ -1936,10 +1936,6 @@ static my_bool write_full_pages(MARIA_HA *info,
bzero(buff + block_size - PAGE_SUFFIX_SIZE - (data_size - copy_length), bzero(buff + block_size - PAGE_SUFFIX_SIZE - (data_size - copy_length),
(data_size - copy_length) + PAGE_SUFFIX_SIZE); (data_size - copy_length) + PAGE_SUFFIX_SIZE);
#ifdef HAVE_purify /* avoid warning about writing uninitialized CRC to disk */
int4store_aligned(buff + block_size - CRC_SIZE,
MARIA_NO_CRC_NORMAL_PAGE);
#endif
if (pagecache_write(share->pagecache, if (pagecache_write(share->pagecache,
&info->dfile, page, 0, &info->dfile, page, 0,
buff, share->page_type, buff, share->page_type,
......
...@@ -567,6 +567,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -567,6 +567,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY; keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
length++; /* At least one length uchar */ length++; /* At least one length uchar */
if (!keyseg->null_bit)
min_key_length++; min_key_length++;
key_length+= keyseg->length; key_length+= keyseg->length;
if (keyseg->length >= 255) if (keyseg->length >= 255)
...@@ -581,6 +582,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -581,6 +582,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
(HA_VAR_LENGTH_PART | HA_BLOB_PART))); (HA_VAR_LENGTH_PART | HA_BLOB_PART)));
keydef->flag|=HA_VAR_LENGTH_KEY; keydef->flag|=HA_VAR_LENGTH_KEY;
length++; /* At least one length uchar */ length++; /* At least one length uchar */
if (!keyseg->null_bit)
min_key_length++; min_key_length++;
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
key_length+= keyseg->length; key_length+= keyseg->length;
......
...@@ -140,8 +140,7 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn, ...@@ -140,8 +140,7 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
my_bool write_hook_for_clr_end(enum translog_record_type type my_bool write_hook_for_clr_end(enum translog_record_type type
__attribute__ ((unused)), __attribute__ ((unused)),
TRN *trn, MARIA_HA *tbl_info TRN *trn, MARIA_HA *tbl_info,
__attribute__ ((unused)),
LSN *lsn __attribute__ ((unused)), LSN *lsn __attribute__ ((unused)),
void *hook_arg) void *hook_arg)
{ {
...@@ -160,6 +159,10 @@ my_bool write_hook_for_clr_end(enum translog_record_type type ...@@ -160,6 +159,10 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
case LOGREC_UNDO_ROW_INSERT: case LOGREC_UNDO_ROW_INSERT:
share->state.state.records--; share->state.state.records--;
share->state.state.checksum+= msg->checksum_delta; share->state.state.checksum+= msg->checksum_delta;
/* Restore auto increment if no one has changed it in between */
if (share->last_auto_increment == tbl_info->last_auto_increment)
share->state.auto_increment= tbl_info->last_auto_increment;
break;
break; break;
case LOGREC_UNDO_ROW_UPDATE: case LOGREC_UNDO_ROW_UPDATE:
share->state.state.checksum+= msg->checksum_delta; share->state.state.checksum+= msg->checksum_delta;
...@@ -226,11 +229,36 @@ my_bool write_hook_for_undo_key_insert(enum translog_record_type type, ...@@ -226,11 +229,36 @@ my_bool write_hook_for_undo_key_insert(enum translog_record_type type,
/* /*
Only reason to set it here is to have a mutex protect from checkpoint Only reason to set it here is to have a mutex protect from checkpoint
reading at the same time (would see a corrupted value). reading at the same time (would see a corrupted value).
The purpose of the following code is to set auto_increment if the row
has a with auto_increment value higher than the current one. We also
want to be able to restore the old value, in case of rollback,
if no one else has tried to set the value.
The logic used is that we only restore the auto_increment value if
tbl_info->last_auto_increment == share->last_auto_increment
when it's time to do the rollback.
*/ */
DBUG_PRINT("info",("auto_inc: %lu new auto_inc: %lu", DBUG_PRINT("info",("auto_inc: %lu new auto_inc: %lu",
(ulong)share->state.auto_increment, (ulong)share->state.auto_increment,
(ulong)msg->auto_increment)); (ulong)msg->auto_increment));
set_if_bigger(share->state.auto_increment, msg->auto_increment); if (share->state.auto_increment < msg->auto_increment)
{
/* Remember the original value, in case of rollback */
tbl_info->last_auto_increment= share->last_auto_increment=
share->state.auto_increment;
share->state.auto_increment= msg->auto_increment;
}
else
{
/*
If the current value would have affected the original auto_increment
value, set it to an impossible value so that it's not restored on
rollback
*/
if (msg->auto_increment > share->last_auto_increment)
share->last_auto_increment= ~(ulonglong) 0;
}
} }
return write_hook_for_undo_key(type, trn, tbl_info, lsn, hook_arg); return write_hook_for_undo_key(type, trn, tbl_info, lsn, hook_arg);
} }
......
...@@ -285,6 +285,7 @@ typedef struct st_maria_share ...@@ -285,6 +285,7 @@ typedef struct st_maria_share
uchar *file_map; /* mem-map of file if possible */ uchar *file_map; /* mem-map of file if possible */
PAGECACHE *pagecache; /* ref to the current key cache */ PAGECACHE *pagecache; /* ref to the current key cache */
MARIA_DECODE_TREE *decode_trees; MARIA_DECODE_TREE *decode_trees;
ulonglong last_auto_increment;
uint16 *decode_tables; uint16 *decode_tables;
uint16 id; /**< 2-byte id by which log records refer to the table */ uint16 id; /**< 2-byte id by which log records refer to the table */
/* Called the first time the table instance is opened */ /* Called the first time the table instance is opened */
...@@ -484,6 +485,7 @@ struct st_maria_handler ...@@ -484,6 +485,7 @@ struct st_maria_handler
uint32 int_keytree_version; /* -""- */ uint32 int_keytree_version; /* -""- */
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS); int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
invalidator_by_filename invalidator; /* query cache invalidator */ invalidator_by_filename invalidator; /* query cache invalidator */
ulonglong last_auto_increment;
ulong this_unique; /* uniq filenumber or thread */ ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */ ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */ ulong this_loop; /* counter for this open */
......
...@@ -2480,7 +2480,8 @@ static int compress_maria_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) ...@@ -2480,7 +2480,8 @@ static int compress_maria_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
ulong tot_blob_length=0; ulong tot_blob_length=0;
if (! error) if (! error)
{ {
if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length)) if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length +
null_bytes))
break; break;
record_pos= (uchar*) file_buffer.pos; record_pos= (uchar*) file_buffer.pos;
file_buffer.pos+= max_pack_length; file_buffer.pos+= max_pack_length;
......
...@@ -6,11 +6,12 @@ ...@@ -6,11 +6,12 @@
use Getopt::Long; use Getopt::Long;
$|= 1; $|= 1;
$VER= "1.2"; $VER= "1.3";
$opt_version= 0; $opt_version= 0;
$opt_help= 0; $opt_help= 0;
$opt_verbose= 0; $opt_verbose= 0;
$opt_abort_on_error= 0;
$opt_maria_path= undef(); $opt_maria_path= undef();
$opt_valgrind= "valgrind --alignment=8 --leak-check=yes"; $opt_valgrind= "valgrind --alignment=8 --leak-check=yes";
$opt_suffix= ""; $opt_suffix= "";
...@@ -38,7 +39,7 @@ sub run_tests ...@@ -38,7 +39,7 @@ sub run_tests
my $nr_tests= 0; my $nr_tests= 0;
my $flag_exit= 0; my $flag_exit= 0;
if (!GetOptions("help", "version", "verbose", "maria-path=s", if (!GetOptions("help", "version", "verbose", "abort-on-error", "maria-path=s",
"valgrind=s", "suffix=s", "silent=s", "number-of-tests", "valgrind=s", "suffix=s", "silent=s", "number-of-tests",
"run-tests=s")) "run-tests=s"))
{ {
...@@ -544,7 +545,10 @@ sub ok ...@@ -544,7 +545,10 @@ sub ok
} }
warn $msg; warn $msg;
$runtime_error= 1; $runtime_error= 1;
if ($opt_abort_on_error)
{
exit 1;
}
return 0; return 0;
} }
...@@ -606,23 +610,24 @@ ma_test_recovery etc. files are. ...@@ -606,23 +610,24 @@ ma_test_recovery etc. files are.
Options Options
--help Show this help and exit. --help Show this help and exit.
--version Show version number and exit. --abort-on-error Abort at once in case of error.
--verbose Be more verbose. Will print each unittest on a line --number-of-tests Print the total number of tests and exit.
and result after. This mode cannot be used with unit.pl
when running in normal unit test mode.
--maria-path=... Path to maria test files. You can set this as an --maria-path=... Path to maria test files. You can set this as an
environment variable 'maria_path' also. environment variable 'maria_path' also.
(maria_path: '$maria_path') (maria_path: '$maria_path')
--valgrind=... Options for valgrind.
('$opt_valgrind')
--suffix=... Suffix for test files (ma_test1, ma_test2 etc.),
if they have one ('$opt_suffix')
--silent=... Silent option passed to ma_test* tests ('$opt_silent')
--number-of-tests Print the total number of tests and exit.
--run-tests=... Test number(s) that should be run. You can give just --run-tests=... Test number(s) that should be run. You can give just
one number or a range. For example 45..89 one number or a range. For example 45..89
Use this with caution, because some of the tests Use this with caution, because some of the tests
might depend on previous ones. might depend on previous ones.
--silent=... Silent option passed to ma_test* tests ('$opt_silent')
--suffix=... Suffix for test files (ma_test1, ma_test2 etc.),
if they have one ('$opt_suffix')
--valgrind=... Options for valgrind.
('$opt_valgrind')
--verbose Be more verbose. Will print each unittest on a line
and result after. This mode cannot be used with unit.pl
when running in normal unit test mode.
--version Show version number and exit.
EOF EOF
exit(0); exit(0);
} }
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