[Commits] Rev 2836: merged with 5.1 in http://bazaar.launchpad.net/~maria-captains/maria/5.2/

At http://bazaar.launchpad.net/~maria-captains/maria/5.2/ ------------------------------------------------------------ revno: 2836 [merge] revision-id: sergii@pisem.net-20100826064007-s1n1c01g1qa2e8xv parent: sergii@pisem.net-20100824164858-ycioywdcm9t82e3l parent: sergii@pisem.net-20100825202233-4qzsmupiyxz6o6rt committer: Sergei Golubchik <sergii@pisem.net> branch nick: 5.2 timestamp: Thu 2010-08-26 08:40:07 +0200 message: merged with 5.1 removed: mysql-test/suite/federated/federated_innodb-slave.opt sp1f-federated_innodbslav-20070628230258-f3ed5aixn7f66srzz5hy53jfyxb75ffv mysql-test/suite/federated/federated_transactions-slave.opt sp1f-federated_transactio-20060727180154-75v3t7oje76l5ofifwxzxgwsc3qoaipm added: mysql-test/include/have_archive.opt have_archive.opt-20100825153034-hp5eoooc13g1eyzj-1 mysql-test/include/have_blackhole.opt have_blackhole.opt-20100825153034-hp5eoooc13g1eyzj-2 mysql-test/suite/federated/suite.opt suite.opt-20100825153034-hp5eoooc13g1eyzj-3 modified: client/mysql.cc sp1f-mysql.cc-19700101030959-5sipizk7ehvbsi3tywrkdords5qy5zdl include/my_global.h sp1f-my_global.h-20010915021246-4vawdgfw4vg3tuxq6mejt7lrchcnceha mysql-test/README.suites readme.suites-20100811074703-jfs335bbu32sdrpy-1 mysql-test/include/have_archive.inc sp1f-have_archive.inc-20040525194737-y4dmzku2drx4axo3jj4crhl5w7q7iiee mysql-test/include/have_innodb.opt have_innodb.opt-20100811123311-vs0iwshnx21dye31-1 mysql-test/include/have_pbxt.inc have_pbxt.inc-20090408133348-au36idguotknighe-1 mysql-test/lib/mtr_cases.pm sp1f-mtr_cases.pl-20050203205008-rrteoawyobvgq6u7zeyce4tmuu334ayg mysql-test/mysql-test-run.pl sp1f-mysqltestrun.pl-20041230152716-xjnn5ndv4rr4by6ijmj5a4ysubxc7qh3 mysql-test/r/group_by.result sp1f-group_by.result-20001228015633-bgjibbiwynctdjq73ms5muj5g6hfpv4d mysql-test/r/subselect4.result subselect4.result-20090903150316-1sul3u8k29ooxm3r-2 mysql-test/suite/federated/my.cnf sp1f-my.cnf-20071212171904-j7gg67dkfqjo4f5yirx3nscdzpxieqyv mysql-test/suite/maria/r/maria3.result maria3.result-20080701120735-95p69v855sl5nh1m-1 mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result vcol_ins_upd_innodb.-20091016212105-1lx2muao9vwbl1c1-31 mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result vcol_ins_upd_myisam.-20091016212105-1lx2muao9vwbl1c1-32 mysql-test/t/group_by.test sp1f-group_by.test-20001228015636-5zwfyi7n5e5jsbyby7a7fvitybcefqwu mysql-test/t/mysqltest_ps.test mysqltest_ps.test-20091009074042-4ptmxutygql3xe53-2 mysql-test/t/subselect4.test subselect4.test-20090903150316-1sul3u8k29ooxm3r-1 scripts/convert-debug-for-diff.sh convertdebugfordiff.-20100818073931-f41fwq5uqxvbuexu-1 sql/item.h sp1f-item.h-19700101030959-rrkb43htudd62batmoteashkebcwykpa sql/item_func.h sp1f-item_func.h-19700101030959-fbjcbwkg66qubbzptqwh5w5evhnpukze sql/item_sum.cc sp1f-item_sum.cc-19700101030959-4woo23bi3am2t2zvsddqbpxk7xbttdkm sql/item_sum.h sp1f-item_sum.h-19700101030959-ecgohlekwm355wxl5fv4zzq3alalbwyl sql/sql_select.cc sp1f-sql_select.cc-19700101030959-egb7whpkh76zzvikycs5nsnuviu4fdlb sql/sql_select.h sp1f-sql_select.h-19700101030959-oqegfxr76xlgmrzd6qlevonoibfnwzoz storage/maria/ha_maria.cc sp1f-ha_maria.cc-20060411134405-dmngb4v5x5fxlxhff527ud3etiutxuxk storage/maria/ma_bitmap.c sp1f-ma_bitmap.c-20070118193810-dcdqg6iu32wkt3pqyio4lqdqmaff2m7g storage/maria/ma_blockrec.c sp1f-ma_blockrec.c-20070118193810-5wtbfa4irhu4voa3diiuus5km2j6jvlv storage/maria/ma_key_recover.c sp1f-ma_key_recover.c-20071114170804-cbdaseyghv3iw5ug5d7alebhyo36hl7u storage/maria/ma_recovery.c sp1f-recovery.c-20060427140636-kkuwrxyvjp42wmupdfbxuaro456oprrg storage/maria/maria_def.h sp1f-maria_def.h-20060411134454-urdx4joxwcwzxbmltpzejn53y2rgjs44 === modified file 'client/mysql.cc' --- a/client/mysql.cc 2010-08-24 12:47:26 +0000 +++ b/client/mysql.cc 2010-08-26 06:40:07 +0000 @@ -156,6 +156,7 @@ static my_bool ignore_errors=0,wait_flag static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; static my_bool preserve_comments= 0; +static my_bool in_com_source, aborted= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint my_end_arg; @@ -1088,6 +1089,7 @@ int main(int argc,char *argv[]) "\\N [\\d]> ",MYF(MY_WME)); current_prompt = my_strdup(default_prompt,MYF(MY_WME)); prompt_counter=0; + aborted= 0; outfile[0]=0; // no (default) outfile strmov(pager, "stdout"); // the default, if --pager wasn't given @@ -1282,8 +1284,10 @@ sig_handler mysql_end(int sig) /* This function handles sigint calls If query is in process, kill query + If 'source' is executed, abort source command no query in process, terminate like previous behavior */ + sig_handler handle_sigint(int sig) { char kill_buffer[40]; @@ -1322,7 +1326,8 @@ sig_handler handle_sigint(int sig) mysql_close(kill_mysql); tee_fprintf(stdout, "Ctrl-C -- query killed. Continuing normally.\n"); interrupted_query= 0; - + if (in_com_source) + aborted= 1; // Abort source command return; err: @@ -1886,7 +1891,7 @@ static int read_and_execute(bool interac String buffer; #endif - char *line; + char *line= 0; char in_string=0; ulong line_number=0; bool ml_comment= 0; @@ -1894,7 +1899,7 @@ static int read_and_execute(bool interac bool truncated= 0; status.exit_status=1; - for (;;) + while (!aborted) { if (!interactive) { @@ -4074,17 +4079,19 @@ static int com_source(String *buffer, ch status.file_name=source_name; glob_buffer.length(0); // Empty command buffer ignore_errors= !batch_abort_on_error; + in_com_source= 1; error= read_and_execute(false); ignore_errors= save_ignore_errors; status=old_status; // Continue as before + in_com_source= aborted= 0; my_fclose(sql_file,MYF(0)); batch_readline_end(line_buff); /* If we got an error during source operation, don't abort the client if ignore_errors is set */ - if (error && batch_abort_on_error && ignore_errors) - error= -1; + if (error && !batch_abort_on_error && ignore_errors) + error= -1; // Ignore error return error; } === modified file 'include/my_global.h' --- a/include/my_global.h 2010-08-24 12:47:26 +0000 +++ b/include/my_global.h 2010-08-26 06:40:07 +0000 @@ -807,10 +807,10 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif /* get memory in huncs */ #define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD) - /* Typical record cash */ -#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD) - /* Typical key cash */ -#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD) + /* Typical record cache */ +#define RECORD_CACHE_SIZE (uint) (128*1024-MALLOC_OVERHEAD) + /* Typical key cache */ +#define KEY_CACHE_SIZE (uint) (128L*1024L*1024L-MALLOC_OVERHEAD) /* Default size of a key cache block */ #define KEY_CACHE_BLOCK_SIZE (uint) 1024 === modified file 'mysql-test/README.suites' --- a/mysql-test/README.suites 2010-08-24 12:33:34 +0000 +++ b/mysql-test/README.suites 2010-08-25 20:22:33 +0000 @@ -20,11 +20,18 @@ subdirectories under the suitedir or dir (that is suitedir/t/*.test or suitedir/*.test, same for *.result)) ========================== -A suite can contain a suite.opt file - at the same location where .test -files are. As usual, the .opt file can use $-substitutions for the -environment variables. +A suite can contain a suite.opt file - at the same location where .test files +are or in the suite directory. As usual, the .opt file can use $-substitutions +for the environment variables. Usually, using my.cnf template (see below) is preferrable. + +But command line options (.opt files and combinations file) get special +treatment - they can have special options that affect mtr behavior. cnf +files cannot. Special options are + --timezone, --plugin-load, --result-file, --config-file-template, + --default-time-zone, --force-restart + ========================== A suite can have suite.pm file in the suitedir. It must declare a package that inherits from My::Suite. @@ -108,8 +115,8 @@ Most probably a suite my.cnf will need t !include include/default_my.cnf and then modify the configuration as necessary. -========================== +========================== A suite can have combinations file in the suitedir. It uses my.cnf syntax but it cannot use @-substitutions. Instead, it can use $-substitutions for the environment variables. Because the combination options will not be === modified file 'mysql-test/include/have_archive.inc' --- a/mysql-test/include/have_archive.inc 2008-07-04 18:48:25 +0000 +++ b/mysql-test/include/have_archive.inc 2010-08-25 20:22:33 +0000 @@ -1,4 +1,5 @@ ---disable_query_log ---require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'archive'; ---enable_query_log +if (!`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'archive'`){ + skip Need archive engine; +} === added file 'mysql-test/include/have_archive.opt' --- a/mysql-test/include/have_archive.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_archive.opt 2010-08-25 20:22:33 +0000 @@ -0,0 +1,2 @@ +--loose-archive +--plugin-load=$HA_ARCHIVE_SO === added file 'mysql-test/include/have_blackhole.opt' --- a/mysql-test/include/have_blackhole.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/include/have_blackhole.opt 2010-08-25 20:22:33 +0000 @@ -0,0 +1,2 @@ +--loose-blackhole +--plugin-load=$HA_BLACKHOLE_SO === modified file 'mysql-test/include/have_innodb.opt' --- a/mysql-test/include/have_innodb.opt 2010-08-17 07:14:46 +0000 +++ b/mysql-test/include/have_innodb.opt 2010-08-25 20:22:33 +0000 @@ -1 +1,2 @@ --loose-innodb +--plugin-load=$HA_XTRADB_SO === modified file 'mysql-test/include/have_pbxt.inc' --- a/mysql-test/include/have_pbxt.inc 2009-04-08 16:55:26 +0000 +++ b/mysql-test/include/have_pbxt.inc 2010-08-25 20:22:33 +0000 @@ -1,4 +1,5 @@ -disable_query_log; ---require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'pbxt'; -enable_query_log; +if (!`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'pbxt'`){ + skip Need PBXT engine; +} === modified file 'mysql-test/lib/mtr_cases.pm' --- a/mysql-test/lib/mtr_cases.pm 2010-08-24 12:47:26 +0000 +++ b/mysql-test/lib/mtr_cases.pm 2010-08-26 06:40:07 +0000 @@ -325,12 +325,8 @@ sub collect_one_suite } # Read suite.opt file - my $suite_opt_file= "$testdir/suite.opt"; - my $suite_opts= []; - if ( -f $suite_opt_file ) - { - $suite_opts= opts_from_file($suite_opt_file); - } + my $suite_opts= [ opts_from_file("$testdir/suite.opt") ]; + $suite_opts = [ opts_from_file("$suitedir/suite.opt") ] unless @$suite_opts; if ( @$opt_cases ) { @@ -618,67 +614,78 @@ sub optimize_cases { # Read options from the given opt file and append them as an array # to $tinfo->{$opt_name} # -sub process_opts_file { - my ($tinfo, $opt_file, $opt_name)= @_; +sub process_opts { + my ($tinfo, $opt_name)= @_; + + my @opts= @{$tinfo->{$opt_name}}; + $tinfo->{$opt_name} = []; + + my @plugins; - if ( -f $opt_file ) + foreach my $opt (@opts) { - my $opts= opts_from_file($opt_file); + my $value; - foreach my $opt ( @$opts ) + # The opt file is used both to send special options to the mysqld + # as well as pass special test case specific options to this + # script + + $value= mtr_match_prefix($opt, "--timezone="); + if ( defined $value ) { - my $value; + $tinfo->{'timezone'}= $value; + next; + } - # The opt file is used both to send special options to the mysqld - # as well as pass special test case specific options to this - # script + $value= mtr_match_prefix($opt, "--plugin-load="); + if (defined $value) + { + push @plugins, $value; + next; + } - $value= mtr_match_prefix($opt, "--timezone="); - if ( defined $value ) - { - $tinfo->{'timezone'}= $value; - next; - } + $value= mtr_match_prefix($opt, "--result-file="); + if ( defined $value ) + { + # Specifies the file mysqltest should compare + # output against + $tinfo->{'result_file'}= "r/$value.result"; + next; + } - $value= mtr_match_prefix($opt, "--result-file="); - if ( defined $value ) - { - # Specifies the file mysqltest should compare - # output against - $tinfo->{'result_file'}= "r/$value.result"; - next; - } + $value= mtr_match_prefix($opt, "--config-file-template="); + if ( defined $value) + { + # Specifies the configuration file to use for this test + $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value"; + next; + } - $value= mtr_match_prefix($opt, "--config-file-template="); - if ( defined $value) - { - # Specifies the configuration file to use for this test - $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value"; - next; - } + # If we set default time zone, remove the one we have + $value= mtr_match_prefix($opt, "--default-time-zone="); + if ( defined $value ) + { + # Set timezone for this test case to something different + $tinfo->{'timezone'}= "GMT-8"; + # Fallthrough, add the --default-time-zone option + } - # If we set default time zone, remove the one we have - $value= mtr_match_prefix($opt, "--default-time-zone="); - if ( defined $value ) - { - # Set timezone for this test case to something different - $tinfo->{'timezone'}= "GMT-8"; - # Fallthrough, add the --default-time-zone option - } + # The --restart option forces a restart even if no special + # option is set. If the options are the same as next testcase + # there is no need to restart after the testcase + # has completed + if ( $opt eq "--force-restart" ) + { + $tinfo->{'force_restart'}= 1; + next; + } - # The --restart option forces a restart even if no special - # option is set. If the options are the same as next testcase - # there is no need to restart after the testcase - # has completed - if ( $opt eq "--force-restart" ) - { - $tinfo->{'force_restart'}= 1; - next; - } + # Ok, this was a real option, add it + push(@{$tinfo->{$opt_name}}, $opt); + } - # Ok, this was a real option, add it - push(@{$tinfo->{$opt_name}}, $opt); - } + if (@plugins) { + push @{$tinfo->{$opt_name}}, "--plugin-load=" . join(':', @plugins); } } @@ -1009,15 +1016,17 @@ sub collect_one_test_case { # ---------------------------------------------------------------------- for (@source_files) { s/\.\w+$//; - process_opts_file($tinfo, "$_.opt", 'master_opt'); - process_opts_file($tinfo, "$_.opt", 'slave_opt'); - process_opts_file($tinfo, "$_-master.opt", 'master_opt'); - process_opts_file($tinfo, "$_-slave.opt", 'slave_opt'); + push @{$tinfo->{master_opt}}, opts_from_file("$_.opt"); + push @{$tinfo->{slave_opt}}, opts_from_file("$_.opt"); + push @{$tinfo->{master_opt}}, opts_from_file("$_-master.opt"); + push @{$tinfo->{slave_opt}}, opts_from_file("$_-slave.opt"); } push(@{$tinfo->{'master_opt'}}, @::opt_extra_mysqld_opt); push(@{$tinfo->{'slave_opt'}}, @::opt_extra_mysqld_opt); + process_opts($tinfo, 'master_opt'); + process_opts($tinfo, 'slave_opt'); return $tinfo; } @@ -1103,6 +1112,8 @@ sub opts_from_file ($) { my $file= shift; local $_; + return () unless -f $file; + open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!"); my @args; while ( <FILE> ) @@ -1143,7 +1154,7 @@ sub opts_from_file ($) { } } close FILE; - return \@args; + return @args; } sub print_testcases { === modified file 'mysql-test/mysql-test-run.pl' --- a/mysql-test/mysql-test-run.pl 2010-08-24 16:48:58 +0000 +++ b/mysql-test/mysql-test-run.pl 2010-08-26 06:40:07 +0000 @@ -3561,8 +3561,9 @@ sub timezone { my ($tinfo)= @_; local $_ = $tinfo->{timezone}; return 'DEFAULT' unless defined $_; - s/\$\{(\w+)\}/envsubst($1)/ge; - s/\$(\w+)/envsubst($1)/ge; + no warnings 'uninitialized'; + s/\$\{(\w+)\}/$ENV{$1}/ge; + s/\$(\w+)/$ENV{$1}/ge; $_; } @@ -5068,18 +5069,6 @@ sub started { return grep(defined $_, ma sub stopped { return grep(!defined $_, map($_->{proc}, @_)); } -sub envsubst { - my $string= shift; - - if ( ! defined $ENV{$string} ) - { - mtr_error(".opt file references '$string' which is not set"); - } - - return $ENV{$string}; -} - - sub get_extra_opts { my ($mysqld, $tinfo)= @_; @@ -5090,8 +5079,9 @@ sub get_extra_opts { # Expand environment variables foreach my $opt ( @$opts ) { - $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge; - $opt =~ s/\$(\w+)/envsubst($1)/ge; + no warnings 'uninitialized'; + $opt =~ s/\$\{(\w+)\}/$ENV{$1}/ge; + $opt =~ s/\$(\w+)/$ENV{$1}/ge; } return $opts; } === modified file 'mysql-test/r/group_by.result' --- a/mysql-test/r/group_by.result 2010-05-12 16:10:33 +0000 +++ b/mysql-test/r/group_by.result 2010-08-23 09:46:25 +0000 @@ -1809,5 +1809,22 @@ SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON MAX(t2.a) 2 DROP TABLE t1, t2; +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 ( +key_col int(11) NOT NULL, +KEY (key_col) +); +INSERT INTO t2 VALUES (1),(2); +select min(t2.key_col) from t1,t2 where t1.a=1; +min(t2.key_col) +1 +select min(t2.key_col) from t1,t2 where t1.a > 1000; +min(t2.key_col) +NULL +select min(t2.key_col)+1 from t1,t2 where t1.a> 1000; +min(t2.key_col)+1 +NULL +drop table t1,t2; # # End of 5.1 tests === modified file 'mysql-test/r/subselect4.result' --- a/mysql-test/r/subselect4.result 2009-09-28 13:48:40 +0000 +++ b/mysql-test/r/subselect4.result 2010-08-23 09:46:25 +0000 @@ -59,3 +59,26 @@ FROM t3 WHERE 1 = 0 GROUP BY 1; (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b) DROP TABLE t1,t2,t3; End of 5.0 tests. +CREATE TABLE t1 (col_int_nokey int(11) NOT NULL, col_varchar_nokey varchar(1) NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (2,'s'),(0,'v'),(2,'s'); +CREATE TABLE t2 ( +pk int(11) NOT NULL AUTO_INCREMENT, +`col_int_key` int(11) NOT NULL, +col_varchar_key varchar(1) NOT NULL, +PRIMARY KEY (pk), +KEY `col_int_key` (`col_int_key`), +KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,10,'g'), (5,20,'v'); +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; +col_int_nokey sub +2 10 +0 NULL +2 10 +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; +col_int_nokey sub +2 11 +0 NULL +2 11 +DROP TABLE t1,t2; +End of 5.1 tests. === removed file 'mysql-test/suite/federated/federated_innodb-slave.opt' --- a/mysql-test/suite/federated/federated_innodb-slave.opt 2010-08-17 07:14:46 +0000 +++ b/mysql-test/suite/federated/federated_innodb-slave.opt 1970-01-01 00:00:00 +0000 @@ -1 +0,0 @@ ---loose-innodb === removed file 'mysql-test/suite/federated/federated_transactions-slave.opt' --- a/mysql-test/suite/federated/federated_transactions-slave.opt 2007-12-12 17:19:24 +0000 +++ b/mysql-test/suite/federated/federated_transactions-slave.opt 1970-01-01 00:00:00 +0000 @@ -1 +0,0 @@ ---loose-innodb === modified file 'mysql-test/suite/federated/my.cnf' --- a/mysql-test/suite/federated/my.cnf 2010-08-17 07:14:46 +0000 +++ b/mysql-test/suite/federated/my.cnf 2010-08-25 20:22:33 +0000 @@ -3,10 +3,8 @@ [mysqld.1] log-bin= master-bin -loose-federated [mysqld.2] -loose-federated [ENV] MASTER_MYPORT= @mysqld.1.port === added file 'mysql-test/suite/federated/suite.opt' --- a/mysql-test/suite/federated/suite.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/federated/suite.opt 2010-08-25 20:22:33 +0000 @@ -0,0 +1,2 @@ +--federated +--plugin-load=$HA_FEDERATEDX_SO === modified file 'mysql-test/suite/maria/r/maria3.result' --- a/mysql-test/suite/maria/r/maria3.result 2010-06-16 10:58:56 +0000 +++ b/mysql-test/suite/maria/r/maria3.result 2010-08-26 06:40:07 +0000 @@ -312,12 +312,12 @@ maria_log_file_size 4294959104 maria_log_purge_type immediate maria_max_sort_file_size 9223372036853727232 maria_pagecache_age_threshold 300 -maria_pagecache_buffer_size 8384512 +maria_pagecache_buffer_size 134213632 maria_pagecache_division_limit 100 maria_page_checksum OFF maria_recover NORMAL maria_repair_threads 1 -maria_sort_buffer_size 8388608 +maria_sort_buffer_size 134217728 maria_stats_method nulls_unequal maria_sync_log_dir NEWFILE show status like 'maria%'; === modified file 'mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result' --- a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result 2010-07-13 14:34:14 +0000 +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result 2010-08-26 06:40:07 +0000 @@ -25,8 +25,8 @@ a b c # INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols insert into t1 values (1,2,3); Warnings: -Warning 1645 The value specified for computed column 'b' in table 't1' ignored -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -65,8 +65,8 @@ a b c # against vcols insert into t1 (a,b) values (1,3), (2,4); Warnings: -Warning 1645 The value specified for computed column 'b' in table 't1' ignored -Warning 1645 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -107,8 +107,8 @@ a b c create table t2 like t1; insert into t2 select * from t1; Warnings: -Warning 1645 The value specified for computed column 'b' in table 't2' ignored -Warning 1645 The value specified for computed column 'c' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'c' in table 't2' ignored select * from t1; a b c 2 -2 -2 @@ -123,8 +123,8 @@ a b c create table t2 like t1; insert into t2 (a,b) select a,b from t1; Warnings: -Warning 1645 The value specified for computed column 'b' in table 't2' ignored -Warning 1645 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored select * from t2; a b c 2 -2 -2 @@ -159,7 +159,7 @@ a b c 2 -2 -2 update t1 set c=3 where a=2; Warnings: -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -189,7 +189,7 @@ a b c 2 -2 -2 update t1 set c=3 where b=-2; Warnings: -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 === modified file 'mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result' --- a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result 2010-07-13 14:34:14 +0000 +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result 2010-08-26 06:40:07 +0000 @@ -25,8 +25,8 @@ a b c # INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols insert into t1 values (1,2,3); Warnings: -Warning 1645 The value specified for computed column 'b' in table 't1' ignored -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -65,8 +65,8 @@ a b c # against vcols insert into t1 (a,b) values (1,3), (2,4); Warnings: -Warning 1645 The value specified for computed column 'b' in table 't1' ignored -Warning 1645 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -107,8 +107,8 @@ a b c create table t2 like t1; insert into t2 select * from t1; Warnings: -Warning 1645 The value specified for computed column 'b' in table 't2' ignored -Warning 1645 The value specified for computed column 'c' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'c' in table 't2' ignored select * from t1; a b c 2 -2 -2 @@ -123,8 +123,8 @@ a b c create table t2 like t1; insert into t2 (a,b) select a,b from t1; Warnings: -Warning 1645 The value specified for computed column 'b' in table 't2' ignored -Warning 1645 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored select * from t2; a b c 2 -2 -2 @@ -159,7 +159,7 @@ a b c 2 -2 -2 update t1 set c=3 where a=2; Warnings: -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 @@ -189,7 +189,7 @@ a b c 2 -2 -2 update t1 set c=3 where b=-2; Warnings: -Warning 1645 The value specified for computed column 'c' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored select * from t1; a b c 1 -1 -1 === modified file 'mysql-test/t/group_by.test' --- a/mysql-test/t/group_by.test 2010-05-12 16:10:33 +0000 +++ b/mysql-test/t/group_by.test 2010-08-23 09:46:25 +0000 @@ -1219,6 +1219,23 @@ EXPLAIN SELECT MAX(t2.a) FROM t2 LEFT JO SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a; DROP TABLE t1, t2; +# +# min() returns wrong value when used in expression when there is no matching +# rows +# + +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 ( + key_col int(11) NOT NULL, + KEY (key_col) +); +INSERT INTO t2 VALUES (1),(2); + +select min(t2.key_col) from t1,t2 where t1.a=1; +select min(t2.key_col) from t1,t2 where t1.a > 1000; +select min(t2.key_col)+1 from t1,t2 where t1.a> 1000; +drop table t1,t2; --echo # === modified file 'mysql-test/t/mysqltest_ps.test' --- a/mysql-test/t/mysqltest_ps.test 2009-10-09 08:09:24 +0000 +++ b/mysql-test/t/mysqltest_ps.test 2010-08-25 20:22:33 +0000 @@ -4,7 +4,7 @@ if (`SELECT $PS_PROTOCOL = 0`) { - --skip Need prepared statement protocol + --skip Need ps-protocol } # === modified file 'mysql-test/t/subselect4.test' --- a/mysql-test/t/subselect4.test 2009-09-18 09:34:08 +0000 +++ b/mysql-test/t/subselect4.test 2010-08-23 09:46:25 +0000 @@ -62,3 +62,29 @@ FROM t3 WHERE 1 = 0 GROUP BY 1; DROP TABLE t1,t2,t3; --echo End of 5.0 tests. + +# +# Fix for LP#612894 +# Some aggregate functions (such as MIN MAX) work incorrectly in subqueries +# after getting NULL value +# + +CREATE TABLE t1 (col_int_nokey int(11) NOT NULL, col_varchar_nokey varchar(1) NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (2,'s'),(0,'v'),(2,'s'); +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + `col_int_key` int(11) NOT NULL, + col_varchar_key varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY `col_int_key` (`col_int_key`), + KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,10,'g'), (5,20,'v'); + +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; + +SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1; + +DROP TABLE t1,t2; + +--echo End of 5.1 tests. === modified file 'scripts/convert-debug-for-diff.sh' --- a/scripts/convert-debug-for-diff.sh 2010-08-18 07:52:57 +0000 +++ b/scripts/convert-debug-for-diff.sh 2010-08-23 09:52:57 +0000 @@ -18,7 +18,7 @@ while (<>) { - s/^T@[0-9]+://g; + s/^T@[0-9]+\s*://g; s/0x[0-9a-f]+(\s|\n|\))/#$1/g; s/size: [0-9]+/size: #/g; print $_; === modified file 'sql/item.h' --- a/sql/item.h 2010-08-24 12:47:26 +0000 +++ b/sql/item.h 2010-08-26 06:40:07 +0000 @@ -870,6 +870,7 @@ public: set value of aggregate function in case of no rows for grouping were found */ virtual void no_rows_in_result() {} + virtual void restore_to_before_no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } virtual Item *copy_andor_structure(THD *thd) { return this; } virtual Item *real_item() { return this; } @@ -926,6 +927,21 @@ public: virtual bool register_field_in_read_map(uchar *arg) { return 0; } virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; } virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; } + + /* To call bool function for all arguments */ + struct bool_func_call_args + { + Item *original_func_item; + void (Item::*bool_function)(); + }; + bool call_bool_func_processor(uchar *org_item) + { + bool_func_call_args *info= (bool_func_call_args*) org_item; + /* Avoid recursion, as walk also calls for original item */ + if (info->original_func_item != this) + (this->*(info->bool_function))(); + return FALSE; + } /* The next function differs from the previous one that a bitmap to be updated is passed as uchar *arg. @@ -2404,6 +2420,14 @@ public: return (*ref)->walk(processor, walk_subquery, arg) || (this->*processor)(arg); } + void no_rows_in_result() + { + (*ref)->no_rows_in_result(); + } + void restore_to_before_no_rows_in_result() + { + (*ref)->restore_to_before_no_rows_in_result(); + } virtual void print(String *str, enum_query_type query_type); bool result_as_longlong() { === modified file 'sql/item_func.h' --- a/sql/item_func.h 2010-03-15 11:51:23 +0000 +++ b/sql/item_func.h 2010-08-26 06:40:07 +0000 @@ -217,6 +217,21 @@ public: { return functype() == *(Functype *) arg; } + + void no_rows_in_result() + { + bool_func_call_args info; + info.original_func_item= this; + info.bool_function= &Item::no_rows_in_result; + walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); + } + void restore_to_before_no_rows_in_result() + { + bool_func_call_args info; + info.original_func_item= this; + info.bool_function= &Item::restore_to_before_no_rows_in_result; + walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); + } }; === modified file 'sql/item_sum.cc' --- a/sql/item_sum.cc 2010-08-02 09:01:24 +0000 +++ b/sql/item_sum.cc 2010-08-23 09:46:25 +0000 @@ -1638,8 +1638,22 @@ void Item_sum_hybrid::cleanup() void Item_sum_hybrid::no_rows_in_result() { - was_values= FALSE; - clear(); + /* We may be called here twice in case of ref field in function */ + if (was_values) + { + was_values= FALSE; + was_null_value= value->null_value; + clear(); + } +} + +void Item_sum_hybrid::restore_to_before_no_rows_in_result() +{ + if (!was_values) + { + was_values= TRUE; + null_value= value->null_value= was_null_value; + } } === modified file 'sql/item_sum.h' --- a/sql/item_sum.h 2010-08-24 12:47:26 +0000 +++ b/sql/item_sum.h 2010-08-26 06:40:07 +0000 @@ -500,7 +500,7 @@ public: enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; } void reset_field() {} // not used void update_field() {} // not used - virtual void no_rows_in_result() {} + void no_rows_in_result() {} void fix_length_and_dec(); enum Item_result result_type () const { return val.traits->type(); } virtual void calculate_val_and_count(); @@ -857,6 +857,7 @@ protected: enum_field_types hybrid_field_type; int cmp_sign; bool was_values; // Set if we have found at least one row (for max/min only) + bool was_null_value; public: Item_sum_hybrid(Item *item_par,int sign) @@ -888,6 +889,7 @@ protected: void cleanup(); bool any_value() { return was_values; } void no_rows_in_result(); + void restore_to_before_no_rows_in_result(); Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); }; === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2010-08-24 12:47:26 +0000 +++ b/sql/sql_select.cc 2010-08-26 06:40:07 +0000 @@ -1688,6 +1688,16 @@ JOIN::reinit() func->clear(); } + if (no_rows_in_result_called) + { + /* Reset effect of possible no_rows_in_result() */ + List_iterator_fast<Item> it(fields_list); + Item *item; + + no_rows_in_result_called= 0; + while ((item= it++)) + item->restore_to_before_no_rows_in_result(); + } DBUG_RETURN(0); } @@ -12699,8 +12709,11 @@ end_send_group(JOIN *join, JOIN_TAB *joi { List_iterator_fast<Item> it(*join->fields); Item *item; + DBUG_PRINT("info", ("no matching rows")); + /* No matching rows for group function */ join->clear(); + join->no_rows_in_result_called= 1; while ((item= it++)) item->no_rows_in_result(); === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2010-04-28 12:52:24 +0000 +++ b/sql/sql_select.h 2010-08-24 17:17:17 +0000 @@ -365,24 +365,31 @@ public: the number of rows in it may vary from one subquery execution to another. */ bool no_const_tables; + /* + This flag is set if we call no_rows_in_result() as par of end_group(). + This is used as a simple speed optimization to avoiding calling + restore_no_rows_in_result() in ::reinit() + */ + bool no_rows_in_result_called; /** Copy of this JOIN to be used with temporary tables. - tmp_join is used when the JOIN needs to be "reusable" (e.g. in a subquery - that gets re-executed several times) and we know will use temporary tables - for materialization. The materialization to a temporary table overwrites the - JOIN structure to point to the temporary table after the materialization is - done. This is where tmp_join is used : it's a copy of the JOIN before the - materialization and is used in restoring before re-execution by overwriting - the current JOIN structure with the saved copy. - Because of this we should pay extra care of not freeing up helper structures - that are referenced by the original contents of the JOIN. We can check for - this by making sure the "current" join is not the temporary copy, e.g. - !tmp_join || tmp_join != join + tmp_join is used when the JOIN needs to be "reusable" (e.g. in a + subquery that gets re-executed several times) and we know will use + temporary tables for materialization. The materialization to a + temporary table overwrites the JOIN structure to point to the + temporary table after the materialization is done. This is where + tmp_join is used : it's a copy of the JOIN before the + materialization and is used in restoring before re-execution by + overwriting the current JOIN structure with the saved copy. + Because of this we should pay extra care of not freeing up helper + structures that are referenced by the original contents of the + JOIN. We can check for this by making sure the "current" join is + not the temporary copy, e.g. !tmp_join || tmp_join != join - We should free these sub-structures at JOIN::destroy() if the "current" join - has a copy is not that copy. + We should free these sub-structures at JOIN::destroy() if the + "current" join has a copy is not that copy. */ JOIN *tmp_join; ROLLUP rollup; ///< Used with rollup @@ -512,6 +519,7 @@ public: optimized= 0; cond_equal= 0; group_optimized_away= 0; + no_rows_in_result_called= 0; all_fields= fields_arg; if (&fields_list != &fields_arg) /* Avoid valgrind-warning */ === modified file 'storage/maria/ha_maria.cc' --- a/storage/maria/ha_maria.cc 2010-08-24 12:47:26 +0000 +++ b/storage/maria/ha_maria.cc 2010-08-26 06:40:07 +0000 @@ -248,7 +248,7 @@ static MYSQL_THDVAR_ULONG(repair_threads static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, "The buffer that is allocated when sorting the index when doing a " "REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", - 0, 0, 8192*1024, 4, ~0L, 1); + 0, 0, 128L*1024L*1024L, 4, ~0L, 1); static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG, "Specifies how maria index statistics collection code should treat " @@ -1850,7 +1850,7 @@ int ha_maria::enable_indexes(uint mode) "retrying", my_errno, param.db_name, param.table_name); /* This should never fail normally */ - DBUG_ASSERT(0); + DBUG_ASSERT(thd->killed != 0); /* Repairing by sort failed. Now try standard repair method. */ param.testflag &= ~T_REP_BY_SORT; error= (repair(thd, ¶m, 0) != HA_ADMIN_OK); === modified file 'storage/maria/ma_bitmap.c' --- a/storage/maria/ma_bitmap.c 2010-08-12 17:55:00 +0000 +++ b/storage/maria/ma_bitmap.c 2010-08-23 09:52:57 +0000 @@ -2063,6 +2063,13 @@ my_bool _ma_bitmap_set_full_page_bits(MA safe_mutex_assert_owner(&info->s->bitmap.bitmap_lock); bitmap_page= page - page % bitmap->pages_covered; + if (page == bitmap_page || + page + page_count >= bitmap_page + bitmap->pages_covered) + { + DBUG_ASSERT(0); /* Wrong in data */ + DBUG_RETURN(1); + } + if (bitmap_page != bitmap->page && _ma_change_bitmap_page(info, bitmap, bitmap_page)) DBUG_RETURN(1); === modified file 'storage/maria/ma_blockrec.c' --- a/storage/maria/ma_blockrec.c 2010-08-20 13:16:47 +0000 +++ b/storage/maria/ma_blockrec.c 2010-08-24 17:17:17 +0000 @@ -1850,16 +1851,11 @@ static my_bool get_rowpos_in_head_or_tai goto err; } + /* + The following dir entry is unused in case of insert / update but + not in case of undo_update / undo_delete + */ dir= dir_entry_pos(buff, block_size, rownr); -#ifdef SANITY_CHECKS - /* Tail's should always be unused */ - if (page_type == TAIL_PAGE && max_entry > rownr && - (dir[0] != 0 || dir[1] != 0)) - { - DBUG_ASSERT(0); - goto err; - } -#endif if (extend_area_on_page(page_type == HEAD_PAGE ? info : 0, buff, dir, rownr, block_size, length, @@ -2236,6 +2232,8 @@ static void store_extent_info(uchar *to, MARIA_BITMAP_BLOCK *block, *end_block; uint copy_length; my_bool first_found= 0; + DBUG_ENTER("store_extent_info"); + DBUG_PRINT("enter", ("count: %u", count)); for (block= first_block, end_block= first_block+count ; block < end_block; block++) @@ -2255,6 +2253,7 @@ static void store_extent_info(uchar *to, page_count|= START_EXTENT_BIT; } pagerange_store(to + PAGE_STORE_SIZE, page_count); + DBUG_DUMP("extent", to, ROW_EXTENT_SIZE); to+= ROW_EXTENT_SIZE; if (!first_found) { @@ -2269,6 +2268,7 @@ static void store_extent_info(uchar *to, data. */ bzero(to, (size_t) (row_extents_second_part + copy_length - to)); + DBUG_VOID_RETURN; } @@ -2287,7 +2287,8 @@ static void store_extent_info(uchar *to, @return @retval 0 ok - @retval 1 Error (out of memory or disk error changing bitmap) + @retval 1 Error (out of memory or disk error changing bitmap) or + wrong information in extent information */ static my_bool extent_to_bitmap_blocks(MARIA_HA *info, @@ -2298,7 +2299,7 @@ static my_bool extent_to_bitmap_blocks(M { MARIA_BITMAP_BLOCK *block, *start_block; MARIA_SHARE *share= info->s; - uint i; + uint i, tail_page; DBUG_ENTER("extent_to_bitmap_blocks"); if (allocate_dynamic(&info->bitmap_blocks, extent_count + 2)) @@ -2329,8 +2329,32 @@ static my_bool extent_to_bitmap_blocks(M block->page= page_korr(extent_info); block->page_count= page_count; block->sub_blocks= 0; + if (block->page_count == 0) + { + /* Extend allocated but not used by write_block_record() */ + DBUG_ASSERT(block->page == 0); + /* This is the last block */ + blocks->count= i; + break; + } + if ((tail_page= page_count & TAIL_BIT)) + page_count= 1; - if (page_count & TAIL_BIT) + /* Check if wrong data */ + if (block->page == 0 || page_count == 0 || + (block->page + page_count) * share->block_size > + share->state.state.data_file_length) + { + DBUG_PRINT("error", ("page: %lu page_count: %u tail: %u length: %ld data_length: %ld", + (ulong) block->page, + (block->page_count & ~TAIL_BIT), + (uint) test(block->page_count & TAIL_BIT), + (ulong) ((block->page + (page_count & ~TAIL_BIT)) * + share->block_size), + (ulong) share->state.state.data_file_length)); + DBUG_RETURN(1); + } + if (tail_page) { block->org_bitmap_value= _ma_bitmap_get_page_bits(info, &share->bitmap, block->page); @@ -2342,7 +2366,7 @@ static my_bool extent_to_bitmap_blocks(M my_bool res; pthread_mutex_lock(&share->bitmap.bitmap_lock); res= _ma_bitmap_set_full_page_bits(info, &share->bitmap, - block->page, block->page_count); + block->page, page_count); pthread_mutex_unlock(&share->bitmap.bitmap_lock); if (res) DBUG_RETURN(1); @@ -2764,9 +2788,16 @@ static my_bool write_block_record(MARIA_ sizeof(char*)); memcpy(data, tmp_pos, *blob_lengths); data+= *blob_lengths; - /* Skip over tail page that was to be used to store blob */ - block++; - bitmap_blocks->tail_page_skipped= 1; + /* + The following is not true when we want to insert data into original + place. In this case we don't have any extra blocks allocated + */ + if (likely(undo_lsn == LSN_ERROR)) + { + /* Skip over tail page that was prepared for storing blob */ + block++; + bitmap_blocks->tail_page_skipped= 1; + } } if (head_block->sub_blocks > 1) { @@ -2779,7 +2810,9 @@ static my_bool write_block_record(MARIA_ /* Update page directory */ head_length= (uint) (data - row_pos->data); - DBUG_PRINT("info", ("Used head length on page: %u", head_length)); + DBUG_PRINT("info", ("Used head length on page: %u header_length: %u", + head_length, + (uint) (flag & ROW_FLAG_TRANSID ? TRANSID_SIZE : 0))); DBUG_ASSERT(data <= end_of_data); if (head_length < share->base.min_block_length) { @@ -2789,6 +2822,7 @@ static my_bool write_block_record(MARIA_ data+= diff_length; head_length= share->base.min_block_length; } + DBUG_ASSERT(undo_lsn == LSN_ERROR || head_length == row_pos->length); int2store(row_pos->dir + 2, head_length); /* update empty space at start of block */ row_pos->empty_space-= head_length; @@ -2852,11 +2886,13 @@ static my_bool write_block_record(MARIA_ { /* Set only a bit, to not cause bitmap code to believe a block is full - when there is still a lot of entries in it + when there is still a lot of entries in it. */ block->used|= BLOCKUSED_USED; } } + DBUG_ASSERT((undo_lsn == LSN_ERROR || + block == bitmap_blocks->block + bitmap_blocks->count)); column= save_column; block= save_block; blob_lengths= save_blob_lengths; @@ -3250,9 +3286,10 @@ static my_bool write_block_record(MARIA_ else { uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + - PAGE_STORE_SIZE + DIRPOS_STORE_SIZE + + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE + 2 + HA_CHECKSUM_STORE_SIZE + 2 + PAGERANGE_STORE_SIZE + ROW_EXTENT_SIZE]; + uchar *log_pos; ha_checksum checksum_delta; /* LOGREC_UNDO_ROW_INSERT & LOGREC_UNDO_ROW_UPDATE share same header */ @@ -3262,18 +3299,17 @@ static my_bool write_block_record(MARIA_ dirpos_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE, row_pos->rownr); - - log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; - log_array[TRANSLOG_INTERNAL_PARTS + 0].length= - (LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + - DIRPOS_STORE_SIZE); + log_pos= (log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE); store_checksum_in_rec(share, checksum_delta, row->checksum - old_record_checksum, - log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + - PAGE_STORE_SIZE + DIRPOS_STORE_SIZE, - log_array[TRANSLOG_INTERNAL_PARTS + 0].length); + log_pos, log_pos); compile_time_assert(sizeof(ha_checksum) == HA_CHECKSUM_STORE_SIZE); + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; + log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - + log_data); + if (!old_record) { /* Store undo_lsn in case we are aborting the insert */ @@ -3292,16 +3328,18 @@ static my_bool write_block_record(MARIA_ else { /* Write UNDO log record for the UPDATE */ - uchar *log_pos= (log_data + - log_array[TRANSLOG_INTERNAL_PARTS + 0].length); size_t row_length, extents_length; - uint row_parts_count; + uint row_parts_count, cur_head_length; /* Write head length and extents of the original row so that we - during UNDO can put it back in the original position + during UNDO can put it back in the original position. + We don't store size for TRANSID, as we don't write this during + UNDO. */ - int2store(log_pos, info->cur_row.head_length); + cur_head_length= (info->cur_row.head_length - + info->cur_row.header_length); + int2store(log_pos, cur_head_length); pagerange_store(log_pos + 2, info->cur_row.extents_count); log_pos+= 2 + PAGERANGE_STORE_SIZE; log_array[TRANSLOG_INTERNAL_PARTS + 0].length+= (2 + @@ -3783,6 +3821,8 @@ err: This is the main reason we don't make a lot of subfunctions that are common between _ma_update_block_record2() and this function. + + Note: If something goes wrong we mark the file crashed */ static my_bool _ma_update_at_original_place(MARIA_HA *info, @@ -3838,6 +3878,10 @@ static my_bool _ma_update_at_original_pl if ((org_empty_size + cur_row->head_length) < length_on_head_page) { + DBUG_PRINT("error", + ("org_empty_size: %u head_length: %u length_on_page: %u", + org_empty_size, (uint) cur_row->head_length, + length_on_head_page)); my_errno= HA_ERR_WRONG_IN_RECORD; goto err; } @@ -3857,7 +3901,6 @@ static my_bool _ma_update_at_original_pl row_pos.empty_space= empty_size; row_pos.dir= dir; row_pos.data= buff + rec_offset; - row_pos.length= length_on_head_page; /* Delete old row */ if (*cur_row->tail_positions && @@ -3887,12 +3930,17 @@ static my_bool _ma_update_at_original_pl max(new_row->total_length, share->base.min_block_length) <= length_on_head_page); + /* Store same amount of data on head page as on original page */ + row_pos.length= (length_on_head_page - + (extent_count + 1 - blocks->count) * ROW_EXTENT_SIZE); + set_if_bigger(row_pos.length, share->base.min_block_length); if ((res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos, undo_lsn, old_checksum))) goto err; DBUG_RETURN(0); err: + _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); @@ -4223,7 +4271,8 @@ my_bool _ma_delete_block_record(MARIA_HA log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE; dirpos_store(log_pos, record_number); log_pos+= DIRPOS_STORE_SIZE; - int2store(log_pos, info->cur_row.head_length); + int2store(log_pos, info->cur_row.head_length - + info->cur_row.header_length); log_pos+= 2; pagerange_store(log_pos, info->cur_row.extents_count); log_pos+= PAGERANGE_STORE_SIZE; @@ -4601,6 +4650,8 @@ int _ma_read_block_record2(MARIA_HA *inf cur_row->head_length= (uint) (end_of_data - data); cur_row->full_page_count= cur_row->tail_count= 0; cur_row->blob_length= 0; + /* Number of bytes in header that we don't need to write during undo */ + cur_row->header_length= total_header_size[(flag & PRECALC_HEADER_BITMASK)]-1; if (flag & ROW_FLAG_TRANSID) { @@ -4612,7 +4663,7 @@ int _ma_read_block_record2(MARIA_HA *inf } /* Skip trans header (for now, until we have MVCC csupport) */ - data+= total_header_size[(flag & PRECALC_HEADER_BITMASK)]; + data+= cur_row->header_length + 1 ; if (flag & ROW_FLAG_NULLS_EXTENDED) cur_null_bytes+= data[-1]; @@ -5008,7 +5059,10 @@ int _ma_read_block_record(MARIA_HA *info uint offset; uint block_size= share->block_size; DBUG_ENTER("_ma_read_block_record"); - DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos)); + DBUG_PRINT("enter", ("rowid: %lu page: %lu rownr: %u", + (ulong) record_pos, + (ulong) ma_recordpos_to_page(record_pos), + ma_recordpos_to_dir_entry(record_pos))); offset= ma_recordpos_to_dir_entry(record_pos); @@ -6756,7 +6810,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_ pgcache_page_no_t page; uint rownr; uchar *buff; - my_bool res= 1; + my_bool res; MARIA_PINNED_PAGE page_link; MARIA_SHARE *share= info->s; ha_checksum checksum; @@ -6802,11 +6856,16 @@ my_bool _ma_apply_undo_row_insert(MARIA_ goto err; res= 0; -err: +end: if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, lsn); DBUG_RETURN(res); + +err: + res= 1; + _ma_mark_file_crashed(share); + goto end; } @@ -7029,6 +7088,10 @@ my_bool _ma_apply_undo_row_delete(MARIA_ { DBUG_ASSERT(row.checksum == (share->calc_checksum)(info, record)); } + /* Store same amount of data on head page as on original page */ + row_pos.length= (length_on_head_page - + (extent_count + 1 - blocks->count) * ROW_EXTENT_SIZE); + set_if_bigger(row_pos.length, share->base.min_block_length); if (write_block_record(info, (uchar*) 0, record, &row, blocks, blocks->block->org_bitmap_value != 0, &row_pos, undo_lsn, 0)) @@ -7038,6 +7101,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_ DBUG_RETURN(0); err: + _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); @@ -7068,7 +7132,7 @@ my_bool _ma_apply_undo_row_update(MARIA_ pgcache_page_no_t page; ha_checksum checksum_delta; uint rownr, field_length_header, extent_count, length_on_head_page; - int error= 1; + int error; DBUG_ENTER("_ma_apply_undo_row_update"); LINT_INIT(checksum_delta); @@ -7205,9 +7270,14 @@ my_bool _ma_apply_undo_row_update(MARIA_ goto err; error= 0; -err: +end: my_free(current_record, MYF(0)); DBUG_RETURN(error); + +err: + error= 1; + _ma_mark_file_crashed(share); + goto end; } === modified file 'storage/maria/ma_key_recover.c' --- a/storage/maria/ma_key_recover.c 2010-08-20 07:29:26 +0000 +++ b/storage/maria/ma_key_recover.c 2010-08-23 09:52:57 +0000 @@ -64,8 +64,9 @@ void _ma_unpin_all_pages(MARIA_HA *info, builds. */ #ifdef EXTRA_DEBUG - DBUG_ASSERT(!pinned_page->changed || - undo_lsn != LSN_IMPOSSIBLE || !info->s->now_transactional); + DBUG_ASSERT((!pinned_page->changed || + undo_lsn != LSN_IMPOSSIBLE || !info->s->now_transactional) || + (info->s->state.changed & STATE_CRASHED)); #endif pagecache_unlock_by_link(info->s->pagecache, pinned_page->link, pinned_page->unlock, PAGECACHE_UNPIN, === modified file 'storage/maria/ma_recovery.c' --- a/storage/maria/ma_recovery.c 2010-08-20 07:29:26 +0000 +++ b/storage/maria/ma_recovery.c 2010-08-23 09:52:57 +0000 @@ -2397,6 +2397,7 @@ static int run_redo_phase(LSN lsn, LSN l struct st_translog_scanner_data scanner; int len; uint i; + DBUG_ENTER("run_redo_phase"); /* install hooks for execution */ #define install_redo_exec_hook(R) \ @@ -2461,7 +2462,7 @@ static int run_redo_phase(LSN lsn, LSN l { tprint(tracef, "checkpoint address refers to the log end log or " "log is empty, nothing to do.\n"); - return 0; + DBUG_RETURN(0); } len= translog_read_record_header(lsn, &rec); @@ -2469,12 +2470,12 @@ static int run_redo_phase(LSN lsn, LSN l if (len == RECHEADER_READ_ERROR) { eprint(tracef, "Failed to read header of the first record."); - return 1; + DBUG_RETURN(1); } if (translog_scanner_init(lsn, 1, &scanner, 1)) { tprint(tracef, "Scanner init failed\n"); - return 1; + DBUG_RETURN(1); } for (i= 1;;i++) { @@ -2527,7 +2528,7 @@ static int run_redo_phase(LSN lsn, LSN l LSN_IN_PARTS(rec2.lsn)); translog_destroy_scanner(&scanner); translog_free_record_header(&rec); - return(0); + DBUG_RETURN(0); } if (translog_scanner_init(rec2.lsn, 1, &scanner2, 1)) @@ -2625,12 +2626,12 @@ static int run_redo_phase(LSN lsn, LSN l fflush(stderr); procent_printed= 1; } - return 0; + DBUG_RETURN(0); err: translog_destroy_scanner(&scanner); translog_free_record_header(&rec); - return 1; + DBUG_RETURN(1); } === modified file 'storage/maria/maria_def.h' --- a/storage/maria/maria_def.h 2010-08-18 07:52:57 +0000 +++ b/storage/maria/maria_def.h 2010-08-24 22:18:01 +0000 @@ -459,8 +459,9 @@ typedef struct st_maria_row uint *null_field_lengths; /* All null field lengths */ ulong *blob_lengths; /* Length for each blob */ ulong min_length, normal_length, char_length, varchar_length; - ulong blob_length, head_length, total_length; + ulong blob_length, total_length; size_t extents_buffer_length; /* Size of 'extents' buffer */ + uint head_length, header_length; uint field_lengths_length; /* Length of data in field_lengths */ uint extents_count; /* number of extents in 'extents' */ uint full_page_count, tail_count; /* For maria_chk */ @@ -1082,7 +1083,7 @@ typedef struct st_maria_block_info #define USE_BUFFER_INIT (((1024L*1024L*128-MALLOC_OVERHEAD)/8192)*8192) #define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD) -#define SORT_BUFFER_INIT (1024L*1024L*64-MALLOC_OVERHEAD) +#define SORT_BUFFER_INIT (1024L*1024L*256-MALLOC_OVERHEAD) #define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD) #define fast_ma_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _ma_writeinfo((INFO),0)
participants (1)
-
serg@askmonty.org