diff options
39 files changed, 1015 insertions, 208 deletions
diff --git a/.bzrignore b/.bzrignore index 1f9a067990c..080b46f1e3d 100644 --- a/.bzrignore +++ b/.bzrignore @@ -790,3 +790,4 @@ sql/mysql_tzinfo_to_sql_tztime.cc sql/my_time.c libmysql/my_time.c libmysqld/my_time.c +sql/mysql_tzinfo_to_sql diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 991707a2ba8..b64b4638f6c 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -90,6 +90,7 @@ marko@hundin.mysql.fi miguel@hegel.(none) miguel@hegel.br miguel@hegel.local +miguel@hegel.txg miguel@light. miguel@light.local miguel@sartre.local diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index 7da8b022031..da06e1f58e4 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -22,6 +22,7 @@ use Getopt::Long; Getopt::Long::Configure ("bundling"); use Sys::Hostname; +$opt_nobuild = undef; $opt_cc= undef; $opt_cflags= undef; $opt_clean= undef; @@ -48,6 +49,7 @@ GetOptions( "help|h", "log|l:s", "mail|m=s", + "nobuild", "verbose|v", ) || &print_help; @@ -79,7 +81,10 @@ foreach (@spec) if (m/^%define\s*mysql_version\s*(.*)/) { $VERSION= $1; + $VERSION_SRPM=$VERSION; ($MAJOR, $MINOR, $RELEASE)= split(/\./,$VERSION); + $VERSION_SRPM= $MAJOR . '.' . $MINOR . '.' . $RELEASE; + $VERSION_SRPM =~ s/\-\w+$//; ($RELEASE, $SUFFIX)= split(/\-/,$RELEASE); $SUFFIX= "-" . $SUFFIX if ($SUFFIX); } @@ -143,60 +148,64 @@ chomp($SRCRPMDIR= `$RPM --eval "%{_srcrpmdir}" 2> /dev/null`); $SOURCEFILE= glob "mysql*-$VERSION.tar.gz"; -&logger("Starting RPM build of MySQL-$VERSION on $HOST"); +unless($opt_nobuild) { -foreach $file ($SOURCEFILE, $SPECFILE) -{ - &abort("Unable to find $file!") unless (-f "$file"); -} + &logger("Starting RPM build of MySQL-$VERSION on $HOST"); + + foreach $file ($SOURCEFILE, $SPECFILE) + { + &abort("Unable to find $file!") unless (-f "$file"); + } # # Install source and spec file # -&logger("Copying SOURCE and SPEC file to build directories."); -unless ($opt_dry_run) -{ - copy($SOURCEFILE, $SOURCEDIR) - or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); - copy($SPECFILE, $SPECDIR) - or &abort("Unable to copy $SPECFILE to $SPECDIR!"); -} + &logger("Copying SOURCE and SPEC file to build directories."); + unless ($opt_dry_run) + { + copy($SOURCEFILE, $SOURCEDIR) + or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); + copy($SPECFILE, $SPECDIR) + or &abort("Unable to copy $SPECFILE to $SPECDIR!"); + } # # Set environment variables - these are being used in the # official MySQL RPM spec file # -&logger("Setting special build environment variables") -if ($opt_cc) or ($opt_cflags) or ($opt_cxxflags) or ($opt_cxx); -$ENV{MYSQL_BUILD_CC}=$opt_cc if ($opt_cc); -$ENV{MYSQL_BUILD_CFLAGS}=$opt_cflags if ($opt_cflags); -$ENV{MYSQL_BUILD_CXXFLAGS}=$opt_cxxflags if ($opt_cxxflags); -$ENV{MYSQL_BUILD_CXX}=$opt_cxx if ($opt_cxx); + &logger("Setting special build environment variables") + if ($opt_cc) or ($opt_cflags) or ($opt_cxxflags) or ($opt_cxx); + $ENV{MYSQL_BUILD_CC}=$opt_cc if ($opt_cc); + $ENV{MYSQL_BUILD_CFLAGS}=$opt_cflags if ($opt_cflags); + $ENV{MYSQL_BUILD_CXXFLAGS}=$opt_cxxflags if ($opt_cxxflags); + $ENV{MYSQL_BUILD_CXX}=$opt_cxx if ($opt_cxx); # # Build the RPMs # -$command= "$RPM"; -$command.= " -v" if ($opt_verbose); -$command.= " -ba"; -$command.= " --clean $RMSOURCE" if $opt_clean; -$command.= " $SPECDIR/"; -$command.= basename($SPECFILE); -&logger("Building RPM."); -&run_command($command, "Error while building the RPMs!"); + $command= "$RPM"; + $command.= " -v" if ($opt_verbose); + $command.= " -ba"; + $command.= " --clean $RMSOURCE" if $opt_clean; + $command.= " $SPECDIR/"; + $command.= basename($SPECFILE); + &logger("Building RPM."); + &run_command($command, "Error while building the RPMs!"); +} # # Move the resulting RPMs into the pwd # $command= "mv"; $command.= " -v " if ($opt_verbose); -$command.= " $SRCRPMDIR/MySQL*$VERSION*.src.rpm $PWD"; +$command.= " $SRCRPMDIR/MySQL*$VERSION_SRPM*.src.rpm $PWD"; &logger("Moving source RPM to current dir."); &run_command($command, "Error moving source RPM!"); $command= "mv"; $command.= " -v " if ($opt_verbose); -$command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; +# $command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; +$command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION_SRPM*.$RPMARCH.rpm $PWD"; &logger("Moving binary RPMs to current dir."); &run_command($command, "Error moving binary RPMs!"); diff --git a/Build-tools/my_md5sum b/Build-tools/my_md5sum new file mode 100755 index 00000000000..20742ee2ed0 --- /dev/null +++ b/Build-tools/my_md5sum @@ -0,0 +1,124 @@ +#!/usr/bin/perl +# +# my_md5sum +# +# Script to clone the 'md5sum' command found on modern systems, since that +# command is not always found on all systems. +# +# Use the "--help" option for more info! +# +# Written by Matt Wagner <matt@mysql.com> +# +use strict; +use Digest::MD5; +use Getopt::Long; + +my $VER= "1.1"; + +# +# Strip the leading path info off the program name ($0). We want 'my_md5sum' +# not './my_md5sum'. +# +$0=~ s/^.*\/(.+)$/$1/; + +my ($opt_check, $opt_help)= undef; + +GetOptions( + "check|c" => \$opt_check, + "help|h" => \$opt_help, + ) || usage(); + +# +# Put all the [file1 file2 file3 ...]'s into an array +# +my @files = @ARGV; + +# +# Give the "--help" text if: +# - "--help|-h" was specified +# - The number of files given as arguments is nil +# - The "--check|-c" option is used with more than one [file] argument +# +usage() if $opt_help || $#files == -1 || ($opt_check && $#files > 0); + +# If "--check|-c", then go into checking +if ($opt_check) +{ + open (CHECKFILE, $files[0]) or die "$files[0]: $!"; + + while (<CHECKFILE>) + { + # + # Goto the next line in the file if it does not match a typical + # digest line like: + # + # f1007efa2c72daa693981ec764cdeaca Bootstrap + # + next if $_!~ m/^([a-z0-9]{32})\s+(.+)$/; + + # Collect the trappings from the above regex + my $checksum= $1; + my $checkfile= $2; + + # Generate a fresh MD5 for the file in question + my $digest= &mkmd5($checkfile); + + # Check the fresh MD5 against what is recorded in the file + # Print an error message if they don't match, else print OK + print "$checkfile: FAILED\n" if $digest ne $checksum; + print "$checkfile: OK\n" if $digest eq $checksum; + } +} +# Else generate the MD5 digest to STDOUT +else +{ + foreach my $file (@files) + { + my $digest= &mkmd5($file); + + print "$digest $file\n"; + } +} + + +# +# This routine generates the MD5 digest of a file +# +sub mkmd5 +{ + my $file= shift; + + open (FILE, $file) or die "$file: $!"; + binmode(FILE); + + my $digest= Digest::MD5->new->addfile(*FILE)->hexdigest; + + close FILE; + + return $digest; +} + +# +# Print the help text +# +sub usage +{ + print <<EOF; + +$0 version $VER by Matt Wagner <matt\@mysql.com> + +Usage: +$0 [-c [file]] | [file1...] +Generates or checks MD5 message digests. + +Options: +-c, --check Check message digests (default is generate) +-h, --help Display this text and exit + +The input for -c should be the list of message digests and file names that is +printed on STDOUT by this program when it generates digests. + +EOF + + exit(0); +} diff --git a/acinclude.m4 b/acinclude.m4 index 30bb1549715..5e642c547c3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -777,14 +777,15 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ ---) for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ /usr/include/ssl /opt/ssl/include /opt/openssl/include \ -/usr/local/ssl/include /usr/local/include ; do +/usr/local/ssl/include /usr/local/include /usr/freeware/include ; do if test -f $d/openssl/ssl.h ; then OPENSSL_INCLUDE=-I$d fi done for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ -/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do +/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \ +/usr/freeware/lib32 /usr/local/lib/ ; do if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl.dylib ; then OPENSSL_LIB=$d fi diff --git a/include/mysql.h b/include/mysql.h index 9eedb849ec4..cd1226fb272 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -323,7 +323,7 @@ typedef struct st_mysql_parameters unsigned long *p_net_buffer_length; } MYSQL_PARAMETERS; -#if !defined(MYSQL_CLIENT) && !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) +#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) #define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) #define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) #endif diff --git a/innobase/include/mach0data.h b/innobase/include/mach0data.h index f28c9422670..7ad760cd60f 100644 --- a/innobase/include/mach0data.h +++ b/innobase/include/mach0data.h @@ -89,7 +89,7 @@ mach_read_from_4( /* out: ulint integer */ byte* b); /* in: pointer to four bytes */ /************************************************************* -Writes a ulint in a compressed form. */ +Writes a ulint in a compressed form (1..5 bytes). */ UNIV_INLINE ulint mach_write_compressed( @@ -168,7 +168,7 @@ mach_read_from_8( /* out: dulint integer */ byte* b); /* in: pointer to 8 bytes */ /************************************************************* -Writes a dulint in a compressed form. */ +Writes a dulint in a compressed form (5..9 bytes). */ UNIV_INLINE ulint mach_dulint_write_compressed( @@ -193,7 +193,7 @@ mach_dulint_read_compressed( /* out: read dulint */ byte* b); /* in: pointer to memory from where to read */ /************************************************************* -Writes a dulint in a compressed form. */ +Writes a dulint in a compressed form (1..11 bytes). */ UNIV_INLINE ulint mach_dulint_write_much_compressed( diff --git a/innobase/include/mach0data.ic b/innobase/include/mach0data.ic index 3ccdcf1dc0a..3ffb9baa344 100644 --- a/innobase/include/mach0data.ic +++ b/innobase/include/mach0data.ic @@ -366,7 +366,7 @@ mach_read_from_6( } /************************************************************* -Writes a dulint in a compressed form. */ +Writes a dulint in a compressed form (5..9 bytes). */ UNIV_INLINE ulint mach_dulint_write_compressed( @@ -422,7 +422,7 @@ mach_dulint_read_compressed( } /************************************************************* -Writes a dulint in a compressed form. */ +Writes a dulint in a compressed form (1..11 bytes). */ UNIV_INLINE ulint mach_dulint_write_much_compressed( diff --git a/innobase/include/mtr0log.h b/innobase/include/mtr0log.h index f50c1dfcb6a..41be168a371 100644 --- a/innobase/include/mtr0log.h +++ b/innobase/include/mtr0log.h @@ -121,7 +121,9 @@ mlog_close( mtr_t* mtr, /* in: mtr */ byte* ptr); /* in: buffer space from ptr up was not used */ /************************************************************ -Writes the initial part of a log record. */ +Writes the initial part of a log record (3..11 bytes). +If the implementation of this function is changed, all +size parameters to mlog_open() should be adjusted accordingly! */ UNIV_INLINE byte* mlog_write_initial_log_record_fast( diff --git a/innobase/include/mtr0log.ic b/innobase/include/mtr0log.ic index c02e0a96a81..aa3f945c202 100644 --- a/innobase/include/mtr0log.ic +++ b/innobase/include/mtr0log.ic @@ -137,7 +137,9 @@ mlog_catenate_dulint_compressed( } /************************************************************ -Writes the initial part of a log record. */ +Writes the initial part of a log record (3..11 bytes). +If the implementation of this function is changed, all +size parameters to mlog_open() should be adjusted accordingly! */ UNIV_INLINE byte* mlog_write_initial_log_record_fast( diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c index f46984f6bb3..ea8c296f8cf 100644 --- a/innobase/mem/mem0dbg.c +++ b/innobase/mem/mem0dbg.c @@ -22,6 +22,7 @@ static ulint mem_n_allocations = 0; static ulint mem_total_allocated_memory = 0; ulint mem_current_allocated_memory = 0; static ulint mem_max_allocated_memory = 0; +static ulint mem_last_print_info = 0; /* Size of the hash table for memory management tracking */ #define MEM_HASH_SIZE 997 diff --git a/innobase/pars/lexyy.c b/innobase/pars/lexyy.c index d98d3c9b945..0112f618533 100644 --- a/innobase/pars/lexyy.c +++ b/innobase/pars/lexyy.c @@ -25,7 +25,6 @@ #ifdef __cplusplus #include <stdlib.h> -#include <unistd.h> /* Use prototypes in function declarations. */ #define YY_USE_PROTOS @@ -934,31 +933,54 @@ case 3: YY_RULE_SETUP #line 116 "pars0lex.l" { +/* Quoted character string literals are handled in an explicit +start state 'quoted'. This state is entered and the buffer for +the scanned string is emptied upon encountering a starting quote. + +In the state 'quoted', only two actions are possible (defined below). */ BEGIN(quoted); stringbuf_len = 0; } YY_BREAK case 4: YY_RULE_SETUP -#line 120 "pars0lex.l" -string_append(yytext, yyleng); +#line 125 "pars0lex.l" +{ + /* Got a sequence of characters other than "'": + append to string buffer */ + string_append(yytext, yyleng); +} YY_BREAK case 5: YY_RULE_SETUP -#line 121 "pars0lex.l" -{ string_append(yytext, yyleng / 2); +#line 130 "pars0lex.l" +{ + /* Got a sequence of "'" characters: + append half of them to string buffer, + as "''" represents a single "'". + We apply truncating division, + so that "'''" will result in "'". */ + + string_append(yytext, yyleng / 2); + + /* If we got an odd number of quotes, then the + last quote we got is the terminating quote. + At the end of the string, we return to the + initial start state and report the scanned + string literal. */ + if (yyleng % 2) { BEGIN(INITIAL); yylval = sym_tab_add_str_lit( pars_sym_tab_global, - stringbuf, stringbuf_len); + (byte*) stringbuf, stringbuf_len); return(PARS_STR_LIT); } } YY_BREAK case 6: YY_RULE_SETUP -#line 131 "pars0lex.l" +#line 154 "pars0lex.l" { yylval = sym_tab_add_null_lit(pars_sym_tab_global); @@ -967,521 +989,521 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 137 "pars0lex.l" +#line 160 "pars0lex.l" { /* Implicit cursor name */ yylval = sym_tab_add_str_lit(pars_sym_tab_global, - yytext, yyleng); + (byte*) yytext, yyleng); return(PARS_SQL_TOKEN); } YY_BREAK case 8: YY_RULE_SETUP -#line 144 "pars0lex.l" +#line 167 "pars0lex.l" { return(PARS_AND_TOKEN); } YY_BREAK case 9: YY_RULE_SETUP -#line 148 "pars0lex.l" +#line 171 "pars0lex.l" { return(PARS_OR_TOKEN); } YY_BREAK case 10: YY_RULE_SETUP -#line 152 "pars0lex.l" +#line 175 "pars0lex.l" { return(PARS_NOT_TOKEN); } YY_BREAK case 11: YY_RULE_SETUP -#line 156 "pars0lex.l" +#line 179 "pars0lex.l" { return(PARS_PROCEDURE_TOKEN); } YY_BREAK case 12: YY_RULE_SETUP -#line 160 "pars0lex.l" +#line 183 "pars0lex.l" { return(PARS_IN_TOKEN); } YY_BREAK case 13: YY_RULE_SETUP -#line 164 "pars0lex.l" +#line 187 "pars0lex.l" { return(PARS_OUT_TOKEN); } YY_BREAK case 14: YY_RULE_SETUP -#line 168 "pars0lex.l" +#line 191 "pars0lex.l" { return(PARS_INT_TOKEN); } YY_BREAK case 15: YY_RULE_SETUP -#line 172 "pars0lex.l" +#line 195 "pars0lex.l" { return(PARS_INT_TOKEN); } YY_BREAK case 16: YY_RULE_SETUP -#line 176 "pars0lex.l" +#line 199 "pars0lex.l" { return(PARS_FLOAT_TOKEN); } YY_BREAK case 17: YY_RULE_SETUP -#line 180 "pars0lex.l" +#line 203 "pars0lex.l" { return(PARS_CHAR_TOKEN); } YY_BREAK case 18: YY_RULE_SETUP -#line 184 "pars0lex.l" +#line 207 "pars0lex.l" { return(PARS_IS_TOKEN); } YY_BREAK case 19: YY_RULE_SETUP -#line 188 "pars0lex.l" +#line 211 "pars0lex.l" { return(PARS_BEGIN_TOKEN); } YY_BREAK case 20: YY_RULE_SETUP -#line 192 "pars0lex.l" +#line 215 "pars0lex.l" { return(PARS_END_TOKEN); } YY_BREAK case 21: YY_RULE_SETUP -#line 196 "pars0lex.l" +#line 219 "pars0lex.l" { return(PARS_IF_TOKEN); } YY_BREAK case 22: YY_RULE_SETUP -#line 200 "pars0lex.l" +#line 223 "pars0lex.l" { return(PARS_THEN_TOKEN); } YY_BREAK case 23: YY_RULE_SETUP -#line 204 "pars0lex.l" +#line 227 "pars0lex.l" { return(PARS_ELSE_TOKEN); } YY_BREAK case 24: YY_RULE_SETUP -#line 208 "pars0lex.l" +#line 231 "pars0lex.l" { return(PARS_ELSIF_TOKEN); } YY_BREAK case 25: YY_RULE_SETUP -#line 212 "pars0lex.l" +#line 235 "pars0lex.l" { return(PARS_LOOP_TOKEN); } YY_BREAK case 26: YY_RULE_SETUP -#line 216 "pars0lex.l" +#line 239 "pars0lex.l" { return(PARS_WHILE_TOKEN); } YY_BREAK case 27: YY_RULE_SETUP -#line 220 "pars0lex.l" +#line 243 "pars0lex.l" { return(PARS_RETURN_TOKEN); } YY_BREAK case 28: YY_RULE_SETUP -#line 224 "pars0lex.l" +#line 247 "pars0lex.l" { return(PARS_SELECT_TOKEN); } YY_BREAK case 29: YY_RULE_SETUP -#line 228 "pars0lex.l" +#line 251 "pars0lex.l" { return(PARS_SUM_TOKEN); } YY_BREAK case 30: YY_RULE_SETUP -#line 232 "pars0lex.l" +#line 255 "pars0lex.l" { return(PARS_COUNT_TOKEN); } YY_BREAK case 31: YY_RULE_SETUP -#line 236 "pars0lex.l" +#line 259 "pars0lex.l" { return(PARS_DISTINCT_TOKEN); } YY_BREAK case 32: YY_RULE_SETUP -#line 240 "pars0lex.l" +#line 263 "pars0lex.l" { return(PARS_FROM_TOKEN); } YY_BREAK case 33: YY_RULE_SETUP -#line 244 "pars0lex.l" +#line 267 "pars0lex.l" { return(PARS_WHERE_TOKEN); } YY_BREAK case 34: YY_RULE_SETUP -#line 248 "pars0lex.l" +#line 271 "pars0lex.l" { return(PARS_FOR_TOKEN); } YY_BREAK case 35: YY_RULE_SETUP -#line 252 "pars0lex.l" +#line 275 "pars0lex.l" { return(PARS_CONSISTENT_TOKEN); } YY_BREAK case 36: YY_RULE_SETUP -#line 256 "pars0lex.l" +#line 279 "pars0lex.l" { return(PARS_READ_TOKEN); } YY_BREAK case 37: YY_RULE_SETUP -#line 260 "pars0lex.l" +#line 283 "pars0lex.l" { return(PARS_ORDER_TOKEN); } YY_BREAK case 38: YY_RULE_SETUP -#line 264 "pars0lex.l" +#line 287 "pars0lex.l" { return(PARS_BY_TOKEN); } YY_BREAK case 39: YY_RULE_SETUP -#line 268 "pars0lex.l" +#line 291 "pars0lex.l" { return(PARS_ASC_TOKEN); } YY_BREAK case 40: YY_RULE_SETUP -#line 272 "pars0lex.l" +#line 295 "pars0lex.l" { return(PARS_DESC_TOKEN); } YY_BREAK case 41: YY_RULE_SETUP -#line 276 "pars0lex.l" +#line 299 "pars0lex.l" { return(PARS_INSERT_TOKEN); } YY_BREAK case 42: YY_RULE_SETUP -#line 280 "pars0lex.l" +#line 303 "pars0lex.l" { return(PARS_INTO_TOKEN); } YY_BREAK case 43: YY_RULE_SETUP -#line 284 "pars0lex.l" +#line 307 "pars0lex.l" { return(PARS_VALUES_TOKEN); } YY_BREAK case 44: YY_RULE_SETUP -#line 288 "pars0lex.l" +#line 311 "pars0lex.l" { return(PARS_UPDATE_TOKEN); } YY_BREAK case 45: YY_RULE_SETUP -#line 292 "pars0lex.l" +#line 315 "pars0lex.l" { return(PARS_SET_TOKEN); } YY_BREAK case 46: YY_RULE_SETUP -#line 296 "pars0lex.l" +#line 319 "pars0lex.l" { return(PARS_DELETE_TOKEN); } YY_BREAK case 47: YY_RULE_SETUP -#line 300 "pars0lex.l" +#line 323 "pars0lex.l" { return(PARS_CURRENT_TOKEN); } YY_BREAK case 48: YY_RULE_SETUP -#line 304 "pars0lex.l" +#line 327 "pars0lex.l" { return(PARS_OF_TOKEN); } YY_BREAK case 49: YY_RULE_SETUP -#line 308 "pars0lex.l" +#line 331 "pars0lex.l" { return(PARS_CREATE_TOKEN); } YY_BREAK case 50: YY_RULE_SETUP -#line 312 "pars0lex.l" +#line 335 "pars0lex.l" { return(PARS_TABLE_TOKEN); } YY_BREAK case 51: YY_RULE_SETUP -#line 316 "pars0lex.l" +#line 339 "pars0lex.l" { return(PARS_INDEX_TOKEN); } YY_BREAK case 52: YY_RULE_SETUP -#line 320 "pars0lex.l" +#line 343 "pars0lex.l" { return(PARS_UNIQUE_TOKEN); } YY_BREAK case 53: YY_RULE_SETUP -#line 324 "pars0lex.l" +#line 347 "pars0lex.l" { return(PARS_CLUSTERED_TOKEN); } YY_BREAK case 54: YY_RULE_SETUP -#line 328 "pars0lex.l" +#line 351 "pars0lex.l" { return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); } YY_BREAK case 55: YY_RULE_SETUP -#line 332 "pars0lex.l" +#line 355 "pars0lex.l" { return(PARS_ON_TOKEN); } YY_BREAK case 56: YY_RULE_SETUP -#line 336 "pars0lex.l" +#line 359 "pars0lex.l" { return(PARS_DECLARE_TOKEN); } YY_BREAK case 57: YY_RULE_SETUP -#line 340 "pars0lex.l" +#line 363 "pars0lex.l" { return(PARS_CURSOR_TOKEN); } YY_BREAK case 58: YY_RULE_SETUP -#line 344 "pars0lex.l" +#line 367 "pars0lex.l" { return(PARS_OPEN_TOKEN); } YY_BREAK case 59: YY_RULE_SETUP -#line 348 "pars0lex.l" +#line 371 "pars0lex.l" { return(PARS_FETCH_TOKEN); } YY_BREAK case 60: YY_RULE_SETUP -#line 352 "pars0lex.l" +#line 375 "pars0lex.l" { return(PARS_CLOSE_TOKEN); } YY_BREAK case 61: YY_RULE_SETUP -#line 356 "pars0lex.l" +#line 379 "pars0lex.l" { return(PARS_NOTFOUND_TOKEN); } YY_BREAK case 62: YY_RULE_SETUP -#line 360 "pars0lex.l" +#line 383 "pars0lex.l" { return(PARS_TO_CHAR_TOKEN); } YY_BREAK case 63: YY_RULE_SETUP -#line 364 "pars0lex.l" +#line 387 "pars0lex.l" { return(PARS_TO_NUMBER_TOKEN); } YY_BREAK case 64: YY_RULE_SETUP -#line 368 "pars0lex.l" +#line 391 "pars0lex.l" { return(PARS_TO_BINARY_TOKEN); } YY_BREAK case 65: YY_RULE_SETUP -#line 372 "pars0lex.l" +#line 395 "pars0lex.l" { return(PARS_BINARY_TO_NUMBER_TOKEN); } YY_BREAK case 66: YY_RULE_SETUP -#line 376 "pars0lex.l" +#line 399 "pars0lex.l" { return(PARS_SUBSTR_TOKEN); } YY_BREAK case 67: YY_RULE_SETUP -#line 380 "pars0lex.l" +#line 403 "pars0lex.l" { return(PARS_REPLSTR_TOKEN); } YY_BREAK case 68: YY_RULE_SETUP -#line 384 "pars0lex.l" +#line 407 "pars0lex.l" { return(PARS_CONCAT_TOKEN); } YY_BREAK case 69: YY_RULE_SETUP -#line 388 "pars0lex.l" +#line 411 "pars0lex.l" { return(PARS_INSTR_TOKEN); } YY_BREAK case 70: YY_RULE_SETUP -#line 392 "pars0lex.l" +#line 415 "pars0lex.l" { return(PARS_LENGTH_TOKEN); } YY_BREAK case 71: YY_RULE_SETUP -#line 396 "pars0lex.l" +#line 419 "pars0lex.l" { return(PARS_SYSDATE_TOKEN); } YY_BREAK case 72: YY_RULE_SETUP -#line 400 "pars0lex.l" +#line 423 "pars0lex.l" { return(PARS_PRINTF_TOKEN); } YY_BREAK case 73: YY_RULE_SETUP -#line 404 "pars0lex.l" +#line 427 "pars0lex.l" { return(PARS_ASSERT_TOKEN); } YY_BREAK case 74: YY_RULE_SETUP -#line 408 "pars0lex.l" +#line 431 "pars0lex.l" { return(PARS_RND_TOKEN); } YY_BREAK case 75: YY_RULE_SETUP -#line 412 "pars0lex.l" +#line 435 "pars0lex.l" { return(PARS_RND_STR_TOKEN); } YY_BREAK case 76: YY_RULE_SETUP -#line 416 "pars0lex.l" +#line 439 "pars0lex.l" { return(PARS_ROW_PRINTF_TOKEN); } YY_BREAK case 77: YY_RULE_SETUP -#line 420 "pars0lex.l" +#line 443 "pars0lex.l" { return(PARS_COMMIT_TOKEN); } YY_BREAK case 78: YY_RULE_SETUP -#line 424 "pars0lex.l" +#line 447 "pars0lex.l" { return(PARS_ROLLBACK_TOKEN); } YY_BREAK case 79: YY_RULE_SETUP -#line 428 "pars0lex.l" +#line 451 "pars0lex.l" { return(PARS_WORK_TOKEN); } YY_BREAK case 80: YY_RULE_SETUP -#line 432 "pars0lex.l" +#line 455 "pars0lex.l" { yylval = sym_tab_add_id(pars_sym_tab_global, (byte*)yytext, @@ -1491,42 +1513,42 @@ YY_RULE_SETUP YY_BREAK case 81: YY_RULE_SETUP -#line 439 "pars0lex.l" +#line 462 "pars0lex.l" { return(PARS_DDOT_TOKEN); } YY_BREAK case 82: YY_RULE_SETUP -#line 443 "pars0lex.l" +#line 466 "pars0lex.l" { return(PARS_ASSIGN_TOKEN); } YY_BREAK case 83: YY_RULE_SETUP -#line 447 "pars0lex.l" +#line 470 "pars0lex.l" { return(PARS_LE_TOKEN); } YY_BREAK case 84: YY_RULE_SETUP -#line 451 "pars0lex.l" +#line 474 "pars0lex.l" { return(PARS_GE_TOKEN); } YY_BREAK case 85: YY_RULE_SETUP -#line 455 "pars0lex.l" +#line 478 "pars0lex.l" { return(PARS_NE_TOKEN); } YY_BREAK case 86: YY_RULE_SETUP -#line 459 "pars0lex.l" +#line 482 "pars0lex.l" { return((int)(*yytext)); @@ -1534,7 +1556,7 @@ YY_RULE_SETUP YY_BREAK case 87: YY_RULE_SETUP -#line 464 "pars0lex.l" +#line 487 "pars0lex.l" { return((int)(*yytext)); @@ -1542,7 +1564,7 @@ YY_RULE_SETUP YY_BREAK case 88: YY_RULE_SETUP -#line 469 "pars0lex.l" +#line 492 "pars0lex.l" { return((int)(*yytext)); @@ -1550,7 +1572,7 @@ YY_RULE_SETUP YY_BREAK case 89: YY_RULE_SETUP -#line 474 "pars0lex.l" +#line 497 "pars0lex.l" { return((int)(*yytext)); @@ -1558,7 +1580,7 @@ YY_RULE_SETUP YY_BREAK case 90: YY_RULE_SETUP -#line 479 "pars0lex.l" +#line 502 "pars0lex.l" { return((int)(*yytext)); @@ -1566,7 +1588,7 @@ YY_RULE_SETUP YY_BREAK case 91: YY_RULE_SETUP -#line 484 "pars0lex.l" +#line 507 "pars0lex.l" { return((int)(*yytext)); @@ -1574,7 +1596,7 @@ YY_RULE_SETUP YY_BREAK case 92: YY_RULE_SETUP -#line 489 "pars0lex.l" +#line 512 "pars0lex.l" { return((int)(*yytext)); @@ -1582,7 +1604,7 @@ YY_RULE_SETUP YY_BREAK case 93: YY_RULE_SETUP -#line 494 "pars0lex.l" +#line 517 "pars0lex.l" { return((int)(*yytext)); @@ -1590,7 +1612,7 @@ YY_RULE_SETUP YY_BREAK case 94: YY_RULE_SETUP -#line 499 "pars0lex.l" +#line 522 "pars0lex.l" { return((int)(*yytext)); @@ -1598,7 +1620,7 @@ YY_RULE_SETUP YY_BREAK case 95: YY_RULE_SETUP -#line 504 "pars0lex.l" +#line 527 "pars0lex.l" { return((int)(*yytext)); @@ -1606,7 +1628,7 @@ YY_RULE_SETUP YY_BREAK case 96: YY_RULE_SETUP -#line 509 "pars0lex.l" +#line 532 "pars0lex.l" { return((int)(*yytext)); @@ -1614,7 +1636,7 @@ YY_RULE_SETUP YY_BREAK case 97: YY_RULE_SETUP -#line 514 "pars0lex.l" +#line 537 "pars0lex.l" { return((int)(*yytext)); @@ -1622,7 +1644,7 @@ YY_RULE_SETUP YY_BREAK case 98: YY_RULE_SETUP -#line 519 "pars0lex.l" +#line 542 "pars0lex.l" { return((int)(*yytext)); @@ -1630,7 +1652,7 @@ YY_RULE_SETUP YY_BREAK case 99: YY_RULE_SETUP -#line 524 "pars0lex.l" +#line 547 "pars0lex.l" { return((int)(*yytext)); @@ -1638,7 +1660,7 @@ YY_RULE_SETUP YY_BREAK case 100: YY_RULE_SETUP -#line 529 "pars0lex.l" +#line 552 "pars0lex.l" { return((int)(*yytext)); @@ -1646,32 +1668,32 @@ YY_RULE_SETUP YY_BREAK case 101: YY_RULE_SETUP -#line 534 "pars0lex.l" +#line 557 "pars0lex.l" BEGIN(comment); /* eat up comment */ YY_BREAK case 102: YY_RULE_SETUP -#line 536 "pars0lex.l" +#line 559 "pars0lex.l" YY_BREAK case 103: YY_RULE_SETUP -#line 537 "pars0lex.l" +#line 560 "pars0lex.l" YY_BREAK case 104: YY_RULE_SETUP -#line 538 "pars0lex.l" +#line 561 "pars0lex.l" BEGIN(INITIAL); YY_BREAK case 105: YY_RULE_SETUP -#line 540 "pars0lex.l" +#line 563 "pars0lex.l" /* eat up whitespace */ YY_BREAK case 106: YY_RULE_SETUP -#line 543 "pars0lex.l" +#line 566 "pars0lex.l" { fprintf(stderr,"Unrecognized character: %02x\n", *yytext); @@ -1683,10 +1705,10 @@ YY_RULE_SETUP YY_BREAK case 107: YY_RULE_SETUP -#line 552 "pars0lex.l" +#line 575 "pars0lex.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1687 "lex.yy.c" +#line 1710 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(comment): case YY_STATE_EOF(quoted): @@ -2574,5 +2596,5 @@ int main() return 0; } #endif -#line 552 "pars0lex.l" +#line 575 "pars0lex.l" diff --git a/innobase/pars/pars0lex.l b/innobase/pars/pars0lex.l index 4e2399613cb..811057d48a1 100644 --- a/innobase/pars/pars0lex.l +++ b/innobase/pars/pars0lex.l @@ -114,11 +114,34 @@ ID [a-z_A-Z][a-z_A-Z0-9]* } "'" { +/* Quoted character string literals are handled in an explicit +start state 'quoted'. This state is entered and the buffer for +the scanned string is emptied upon encountering a starting quote. + +In the state 'quoted', only two actions are possible (defined below). */ BEGIN(quoted); stringbuf_len = 0; } -<quoted>[^\']+ string_append(yytext, yyleng); -<quoted>"'"+ { string_append(yytext, yyleng / 2); +<quoted>[^\']+ { + /* Got a sequence of characters other than "'": + append to string buffer */ + string_append(yytext, yyleng); +} +<quoted>"'"+ { + /* Got a sequence of "'" characters: + append half of them to string buffer, + as "''" represents a single "'". + We apply truncating division, + so that "'''" will result in "'". */ + + string_append(yytext, yyleng / 2); + + /* If we got an odd number of quotes, then the + last quote we got is the terminating quote. + At the end of the string, we return to the + initial start state and report the scanned + string literal. */ + if (yyleng % 2) { BEGIN(INITIAL); yylval = sym_tab_add_str_lit( diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 26ca9543d97..d1ae334b0aa 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -59,6 +59,9 @@ #include <sql_common.h> #include "client_settings.h" +#undef net_buffer_length +#undef max_allowed_packet + ulong net_buffer_length=8192; ulong max_allowed_packet= 1024L*1024L*1024L; ulong net_read_timeout= CLIENT_NET_READ_TIMEOUT; diff --git a/man/mysqlaccess.1.in b/man/mysqlaccess.1.in index 9a5e58541d2..cf2e0658a1c 100644 --- a/man/mysqlaccess.1.in +++ b/man/mysqlaccess.1.in @@ -1,7 +1,6 @@ .TH mysqlaccess 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" .SH NAME -.BR mysqlaccess - \- Create new users to mysql. +.BR mysqlaccess \- Create new users to mysql. .SH USAGE mysqlaccess [host [user [db]]] OPTIONS .SH SYNOPSIS diff --git a/man/mysqldump.1.in b/man/mysqldump.1.in index 34d83dbe0b3..6d1cc80c837 100644 --- a/man/mysqldump.1.in +++ b/man/mysqldump.1.in @@ -1,6 +1,6 @@ .TH mysqldump 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" .SH NAME -mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data. +mysqldump \- text\-based client for dumping or backing up mysql databases, tables and or data. .SH USAGE .BR "mysqldump [\fP\fIOPTIONS\fP] database [\fP\fItables\fP]" diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 6b007fb121e..52938c8a2ee 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -691,7 +691,7 @@ report_stats () { # $RM -f $MY_LOG_DIR/warnings $MY_LOG_DIR/warnings.tmp # Remove some non fatal warnings from the log files - $SED -e 's!Warning: Table:.* on delete!!g' \ + $SED -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \ $MY_LOG_DIR/*.err \ | $SED -e 's!Warning: Table:.* on rename!!g' \ > $MY_LOG_DIR/warnings.tmp diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index cc6a974b192..f2846e238e3 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1181,6 +1181,40 @@ a A a drop table t1; +create table t1( +pk1 text not null, pk2 text not null, pk3 char(4), +key1 int, key2 int, +primary key(pk1(4), pk2(4), pk3), key(key1), key(key2) +) engine=bdb; +insert into t1 values (concat('aaa-', repeat('A', 4000)), +concat('eee-', repeat('e', 4000)), 'a++a', 1, 1); +insert into t1 values (concat('bbb-', repeat('B', 4000)), +concat('ggg-', repeat('G', 4000)), 'b++b', 1, 1); +select substring(pk1, 1, 4), substring(pk1, 4001), +substring(pk2, 1, 4), substring(pk2, 4001), pk3, key1, key2 +from t1 force index(key1, key2) where key1 < 3 or key2 < 3; +substring(pk1, 1, 4) substring(pk1, 4001) substring(pk2, 1, 4) substring(pk2, 4001) pk3 key1 key2 +aaa- AAAA eee- eeee a++a 1 1 +bbb- BBBB ggg- GGGG b++b 1 1 +drop table t1; +create table t1 ( +pk1 varchar(8) not null default '', +pk2 varchar(4) not null default '', +key1 int(11) default null, +key2 int(11) default null, +primary key (pk1,pk2), +key key1 (key1), +key key2 (key2)) engine=bdb; +insert into t1 values ('','empt',2,2), ('a','a--a',2,2), +('bb','b--b',2,2), ('ccc','c--c',2,2), ('dddd','d--d',2,2); +select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3; +pk1 pk2 key1 key2 + empt 2 2 +a a--a 2 2 +bb b--b 2 2 +ccc c--c 2 2 +dddd d--d 2 2 +drop table t1; set autocommit=0; create table t1(b varchar(30)) engine=bdb; insert into t1 values ('one'); diff --git a/mysql-test/r/flush_table.result b/mysql-test/r/flush_table.result new file mode 100644 index 00000000000..cfba428e2e8 --- /dev/null +++ b/mysql-test/r/flush_table.result @@ -0,0 +1,120 @@ +drop table if exists t1; +create table t1 (a int not null auto_increment primary key); +insert into t1 values(0); +lock table t1 read; +flush table t1; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +drop database if exists test_test; +create database test_test; +use test_test; +create table t1(table_id char(20) primary key); +insert into t1 values ('test_test.t1'); +insert into t1 values (''); +handler t1 open; +handler t1 read first limit 9; +table_id +test_test.t1 + +create table t2(table_id char(20) primary key); +insert into t2 values ('test_test.t2'); +insert into t2 values (''); +handler t2 open; +handler t2 read first limit 9; +table_id +test_test.t2 + +use test; +drop table if exists t1; +create table t1(table_id char(20) primary key); +insert into t1 values ('test.t1'); +insert into t1 values (''); +handler t1 open; +handler t1 read first limit 9; +table_id +test.t1 + +use test; +handler test.t1 read first limit 9; +table_id +test.t1 + +handler test.t2 read first limit 9; +Unknown table 't2' in HANDLER +handler test_test.t1 read first limit 9; +table_id +test_test.t1 + +handler test_test.t2 read first limit 9; +table_id +test_test.t2 + +handler test_test.t1 close; +drop table test_test.t1; +handler test_test.t2 close; +drop table test_test.t2; +drop database test_test; +use test; +handler test.t1 close; +drop table test.t1; +drop table if exists t1; +drop table if exists t2; +create table t1(table_id char(20) primary key); +create table t2(table_id char(20) primary key); +insert into t1 values ('test.t1'); +insert into t1 values (''); +insert into t2 values ('test.t2'); +insert into t2 values (''); +handler t1 open as a1; +handler t1 open as a2; +handler t2 open; +handler a1 read first limit 9; +table_id +test.t1 + +handler a2 read first limit 9; +table_id +test.t1 + +handler t2 read first limit 9; +table_id +test.t2 + +flush tables; +handler a1 read first limit 9; +Unknown table 'a1' in HANDLER +handler a2 read first limit 9; +Unknown table 'a2' in HANDLER +handler t2 read first limit 9; +Unknown table 't2' in HANDLER +handler t1 open as a1; +handler t1 open as a2; +handler t2 open; +handler a1 read first limit 9; +table_id +test.t1 + +handler a2 read first limit 9; +table_id +test.t1 + +handler t2 read first limit 9; +table_id +test.t2 + +flush table t1; +handler a1 read first limit 9; +Unknown table 'a1' in HANDLER +handler a2 read first limit 9; +Unknown table 'a2' in HANDLER +handler t2 read first limit 9; +table_id +test.t2 + +flush table t2; +handler t2 close; +Unknown table 't2' in HANDLER +drop table t1; +drop table t2; diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result index 5c5e0bb6dfe..bf981170f7d 100644 --- a/mysql-test/r/innodb_cache.result +++ b/mysql-test/r/innodb_cache.result @@ -98,7 +98,7 @@ commit; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 1 -drop table if exists t1; +drop table t3,t2,t1; CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=InnoDB; select count(*) from t1; count(*) @@ -108,3 +108,22 @@ select count(*) from t1; count(*) 1 drop table t1; +set GLOBAL query_cache_size=1355776; +CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a)) TYPE=innodb; +CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b)) TYPE=innodb; +CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`)) TYPE=innodb; +INSERT INTO t1 VALUES (1,'me'); +INSERT INTO t2 VALUES (1,'you'); +INSERT INTO t3 VALUES (2,1,1,2); +delete from t3 where t1_id = 1 and t2_id = 1; +select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc; +id a +begin; +insert into t3 VALUES ( NULL, 1, 1, 2 ); +insert into t3 VALUES ( NULL, 1, 1, 2 ); +Duplicate entry '1-1' for key 2 +commit; +select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc; +id a +1 me +drop table t3,t2,t1; diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index d43a18c6a96..7e6c244bcd8 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -121,3 +121,13 @@ LOCATION Mic-5 Mic-6 drop table T1; +create table T1 (A int); +alter table T1 add index (A); +show tables like 'T1%'; +Tables_in_test (T1%) +T1 +alter table t1 add index (A); +show tables like 't1%'; +Tables_in_test (t1%) +t1 +drop table t1; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 06a479c964c..2f98b05779e 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -244,7 +244,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range x x 5 NULL 2 Using where explain select count(*) from t1 where x in (1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range x x 5 NULL 1 Using where; Using index +1 SIMPLE t1 ref x x 5 NULL 1 Using where; Using index explain select count(*) from t1 where x in (1,2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range x x 5 NULL 2 Using where; Using index diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 42729034d41..32ea0662534 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -824,6 +824,42 @@ select a from t1; drop table t1; # +# bug#2686 - index_merge select on BerkeleyDB table with varchar PK causes mysqld to crash +# + +create table t1( + pk1 text not null, pk2 text not null, pk3 char(4), + key1 int, key2 int, + primary key(pk1(4), pk2(4), pk3), key(key1), key(key2) +) engine=bdb; +insert into t1 values (concat('aaa-', repeat('A', 4000)), + concat('eee-', repeat('e', 4000)), 'a++a', 1, 1); +insert into t1 values (concat('bbb-', repeat('B', 4000)), + concat('ggg-', repeat('G', 4000)), 'b++b', 1, 1); +select substring(pk1, 1, 4), substring(pk1, 4001), + substring(pk2, 1, 4), substring(pk2, 4001), pk3, key1, key2 + from t1 force index(key1, key2) where key1 < 3 or key2 < 3; +drop table t1; + +# +# bug#2688 - Wrong index_merge query results for BDB table with variable length primary key +# + +create table t1 ( + pk1 varchar(8) not null default '', + pk2 varchar(4) not null default '', + key1 int(11) default null, + key2 int(11) default null, + primary key (pk1,pk2), + key key1 (key1), + key key2 (key2)) engine=bdb; +insert into t1 values ('','empt',2,2), ('a','a--a',2,2), + ('bb','b--b',2,2), ('ccc','c--c',2,2), ('dddd','d--d',2,2); +select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3; +drop table t1; + + +# # Bug #4000: problem with active cursor. # diff --git a/mysql-test/t/flush_table.test b/mysql-test/t/flush_table.test index 4ddcd53d5c8..ad81f266afc 100644 --- a/mysql-test/t/flush_table.test +++ b/mysql-test/t/flush_table.test @@ -4,10 +4,111 @@ # Test of flush table # -#drop table if exists t1; -#create table t1 (a int not null auto_increment primary key); -#insert into t1 values(0); -#lock table t1 read; -#flush table t1; -#check table t1; -#drop table t1; +drop table if exists t1; +create table t1 (a int not null auto_increment primary key); +insert into t1 values(0); +lock table t1 read; +flush table t1; +check table t1; +drop table t1; + +# +# Check if two database names beginning the same are seen as different. +# +# This database begins like the usual 'test' database. +# +--disable_warnings +drop database if exists test_test; +--enable_warnings +create database test_test; +use test_test; +create table t1(table_id char(20) primary key); +insert into t1 values ('test_test.t1'); +insert into t1 values (''); +handler t1 open; +handler t1 read first limit 9; +create table t2(table_id char(20) primary key); +insert into t2 values ('test_test.t2'); +insert into t2 values (''); +handler t2 open; +handler t2 read first limit 9; +# +# This is the usual 'test' database. +# +use test; +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1(table_id char(20) primary key); +insert into t1 values ('test.t1'); +insert into t1 values (''); +handler t1 open; +handler t1 read first limit 9; +# +# Check accesibility of all the tables. +# +use test; +handler test.t1 read first limit 9; +--error 1109; +handler test.t2 read first limit 9; +handler test_test.t1 read first limit 9; +handler test_test.t2 read first limit 9; +# +# Cleanup. +# +handler test_test.t1 close; +drop table test_test.t1; +handler test_test.t2 close; +drop table test_test.t2; +drop database test_test; +# +use test; +handler test.t1 close; +drop table test.t1; + +# +# In the following test FLUSH TABLES produces a deadlock +# (hang forever) if the fix for bug#3565 is missing. +# +--disable_warnings +drop table if exists t1; +drop table if exists t2; +--enable_warnings +create table t1(table_id char(20) primary key); +create table t2(table_id char(20) primary key); +insert into t1 values ('test.t1'); +insert into t1 values (''); +insert into t2 values ('test.t2'); +insert into t2 values (''); +handler t1 open as a1; +handler t1 open as a2; +handler t2 open; +handler a1 read first limit 9; +handler a2 read first limit 9; +handler t2 read first limit 9; +flush tables; +--error 1109; +handler a1 read first limit 9; +--error 1109; +handler a2 read first limit 9; +--error 1109; +handler t2 read first limit 9; +# +handler t1 open as a1; +handler t1 open as a2; +handler t2 open; +handler a1 read first limit 9; +handler a2 read first limit 9; +handler t2 read first limit 9; +flush table t1; +--error 1109; +handler a1 read first limit 9; +--error 1109; +handler a2 read first limit 9; +handler t2 read first limit 9; +flush table t2; +--error 1109; +handler t2 close; +drop table t1; +drop table t2; + diff --git a/mysql-test/t/innodb_cache.test b/mysql-test/t/innodb_cache.test index 8568fce7d97..a81aca9b494 100644 --- a/mysql-test/t/innodb_cache.test +++ b/mysql-test/t/innodb_cache.test @@ -52,10 +52,31 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_hits"; commit; show status like "Qcache_queries_in_cache"; +drop table t3,t2,t1; -drop table if exists t1; CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=InnoDB; select count(*) from t1; insert into t1 (id) values (0); select count(*) from t1; drop table t1; + +# +# one statement roll back inside transation +# +set GLOBAL query_cache_size=1355776; +CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a)) TYPE=innodb; +CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b)) TYPE=innodb; +CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`)) TYPE=innodb; +INSERT INTO t1 VALUES (1,'me'); +INSERT INTO t2 VALUES (1,'you'); +INSERT INTO t3 VALUES (2,1,1,2); +delete from t3 where t1_id = 1 and t2_id = 1; +select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc; +begin; +insert into t3 VALUES ( NULL, 1, 1, 2 ); +-- error 1062 +insert into t3 VALUES ( NULL, 1, 1, 2 ); +commit; +select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc; +drop table t3,t2,t1; + diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test index 5c479391916..a4eaeac4ef4 100644 --- a/mysql-test/t/lowercase_table2.test +++ b/mysql-test/t/lowercase_table2.test @@ -89,3 +89,14 @@ SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHER SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; drop table T1; + +# +# Test name conversion with ALTER TABLE / CREATE INDEX (Bug #3109) +# + +create table T1 (A int); +alter table T1 add index (A); +show tables like 'T1%'; +alter table t1 add index (A); +show tables like 't1%'; +drop table t1; diff --git a/mysys/hash.c b/mysys/hash.c index b7be41a9058..11cbbd6b898 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -122,7 +122,8 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, -#if !defined(__SUNPRO_C) && !defined(__USLC__) /* broken compilers */ +/* for compilers which can not handle inline */ +#if !defined(__SUNPRO_C) && !defined(__USLC__) && !defined(__sgi) inline #endif unsigned int rec_hashnr(HASH *hash,const byte *record) diff --git a/scripts/make_win_binary_distribution.sh b/scripts/make_win_binary_distribution.sh index e5893c1eb1e..9b2cc2d7d22 100644 --- a/scripts/make_win_binary_distribution.sh +++ b/scripts/make_win_binary_distribution.sh @@ -110,6 +110,9 @@ print_debug "Copying sql-bench to $DIRNAME/bench" mkdir $DIRNAME/bench cp -fr sql-bench/* $DIRNAME/bench +print_debug "Copying support-files to $DIRNAME" +cp support-files/* $DIRNAME + # Files for bin for i in client_release/* client_debug/mysqld.exe lib_release/libmySQL.dll do @@ -124,7 +127,7 @@ do cp $i $DIRNAME/include done -# Windows users are used to having dbug.h +# Windows users are used to having dbug.h ? cp include/my_dbug.h $DIRNAME/include/dbug.h # Libraries found in lib_release and lib_debug diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index e50fbf9f024..856324074d9 100644 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -288,6 +288,12 @@ do done # +# support files +# +mkdir $BASE/support-files +cp support-files/*.cnf $BASE/support-files + +# # Raw dirs from source tree # diff --git a/sql/field.cc b/sql/field.cc index 75b3e0add3d..2d3729817b7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4684,6 +4684,42 @@ uint32 Field_blob::get_length(const char *pos) } +/* + Put a blob length field into a record buffer. + + SYNOPSIS + Field_blob::put_length() + pos Pointer into the record buffer. + length The length value to put. + + DESCRIPTION + Depending on the maximum length of a blob, its length field is + put into 1 to 4 bytes. This is a property of the blob object, + described by 'packlength'. + + RETURN + nothing +*/ + +void Field_blob::put_length(char *pos, uint32 length) +{ + switch (packlength) { + case 1: + *pos= (char) length; + break; + case 2: + int2store(pos, length); + break; + case 3: + int3store(pos, length); + break; + case 4: + int4store(pos, length); + break; + } +} + + int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) { if (!length) @@ -5058,6 +5094,50 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length) return to+length; } + +/* + Unpack a blob key into a record buffer. + + SYNOPSIS + Field_blob::unpack_key() + to Pointer into the record buffer. + from Pointer to the packed key. + max_length Key length limit from key description. + + DESCRIPTION + A blob key has a maximum size of 64K-1. + In its packed form, the length field is one or two bytes long, + depending on 'max_length'. + Depending on the maximum length of a blob, its length field is + put into 1 to 4 bytes. This is a property of the blob object, + described by 'packlength'. + Blobs are internally stored apart from the record buffer, which + contains a pointer to the blob buffer. + + RETURN + Pointer into 'from' past the last byte copied from packed key. +*/ + +const char *Field_blob::unpack_key(char *to, const char *from, uint max_length) +{ + /* get length of the blob key */ + uint32 length= *((uchar*) from++); + if (max_length > 255) + length+= (*((uchar*) from++)) << 8; + + /* put the length into the record buffer */ + put_length(to, length); + + /* put the address of the blob buffer or NULL */ + if (length) + memcpy_fixed(to + packlength, &from, sizeof(from)); + else + bzero(to + packlength, sizeof(from)); + + /* point to first byte of next field in 'from' */ + return from + length; +} + /* Create a packed key that will be used for storage from a MySQL key */ char *Field_blob::pack_key_from_key_image(char *to, const char *from, diff --git a/sql/field.h b/sql/field.h index e7a30372e43..a2fe77e18a3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -251,6 +251,10 @@ public: { return pack(to,from,max_length); } + virtual const char *unpack_key(char* to, const char *from, uint max_length) + { + return unpack(to,from); + } virtual uint packed_col_length(const char *to, uint length) { return length;} virtual uint max_packed_col_length(uint max_length) @@ -1017,6 +1021,7 @@ public: inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } uint32 get_length(const char *ptr); + void put_length(char *pos, uint32 length); inline void get_ptr(char **str) { memcpy_fixed(str,ptr+packlength,sizeof(char*)); @@ -1049,6 +1054,7 @@ public: const char *unpack(char *to, const char *from); char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); + const char *unpack_key(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length); int pack_cmp(const char *b, uint key_length); uint packed_col_length(const char *col_ptr, uint length); diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 42ff3d4dca6..ecdf4c60d3e 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -724,8 +724,8 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index) } record[key_part->null_offset]&= ~key_part->null_bit; } - pos= (char*) key_part->field->unpack(record + key_part->field->offset(), - pos); + pos= (char*) key_part->field->unpack_key(record + key_part->field->offset(), + pos, key_part->length); } } @@ -1643,13 +1643,44 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos) (char*) buf, primary_key, ¤t_row, (DBT*) 0, 0)); } +/* + Set a reference to the current record in (ref,ref_length). + + SYNOPSIS + ha_berkeley::position() + record The current record buffer + + DESCRIPTION + The BDB handler stores the primary key in (ref,ref_length). + There is either an explicit primary key, or an implicit (hidden) + primary key. + During open(), 'ref_length' is calculated as the maximum primary + key length. When an actual key is shorter than that, the rest of + the buffer must be cleared out. The row cannot be identified, if + garbage follows behind the end of the key. There is no length + field for the current key, so that the whole ref_length is used + for comparison. + + RETURN + nothing +*/ + void ha_berkeley::position(const byte *record) { DBT key; + DBUG_ENTER("ha_berkeley::position"); if (hidden_primary_key) + { + DBUG_ASSERT(ref_length == BDB_HIDDEN_PRIMARY_KEY_LENGTH); memcpy_fixed(ref, (char*) current_ident, BDB_HIDDEN_PRIMARY_KEY_LENGTH); + } else + { create_key(&key, primary_key, (char*) ref, record); + if (key.size < ref_length) + bzero(ref + key.size, ref_length - key.size); + } + DBUG_VOID_RETURN; } diff --git a/sql/handler.cc b/sql/handler.cc index e278d1a5308..017b9d9d4c8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -625,13 +625,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) reinit_io_cache(&thd->transaction.trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); thd->transaction.trans_log.end_of_file= max_binlog_cache_size; + if (operation_done) + thd->transaction.cleanup(); } thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) - { statistic_increment(ha_rollback_count,&LOCK_status); - thd->transaction.cleanup(); - } } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 03313adf76b..e3ef39fcbf6 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -671,8 +671,9 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); -int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0); -int mysql_ha_closeall(THD *thd, TABLE_LIST *tables); +int mysql_ha_close(THD *thd, TABLE_LIST *tables, + bool dont_send_ok=0, bool dont_lock=0, bool no_alias=0); +int mysql_ha_close_list(THD *thd, TABLE_LIST *tables, bool flushed=0); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f705b592e5a..b6d14092885 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -300,6 +300,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, thd->proc_info="Flushing tables"; close_old_data_files(thd,thd->open_tables,1,1); + mysql_ha_close_list(thd, tables); bool found=1; /* Wait until all threads has closed all the tables we had locked */ DBUG_PRINT("info", @@ -850,6 +851,9 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, DBUG_RETURN(0); } + /* close handler tables which are marked for flush */ + mysql_ha_close_list(thd, (TABLE_LIST*) NULL, /*flushed*/ 1); + for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; table && table->in_use ; table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) @@ -1220,6 +1224,7 @@ bool wait_for_tables(THD *thd) { thd->some_tables_deleted=0; close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0); + mysql_ha_close_list(thd, (TABLE_LIST*) NULL, /*flushed*/ 1); if (!table_is_used(thd->open_tables,1)) break; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 7dfe707a317..c31763d7f1d 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -43,7 +43,9 @@ thd->handler_tables=tmp; } static TABLE **find_table_ptr_by_name(THD *thd,const char *db, - const char *table_name, bool is_alias); + const char *table_name, + bool is_alias, bool dont_lock, + bool *was_flushed); int mysql_ha_open(THD *thd, TABLE_LIST *tables) { @@ -66,25 +68,61 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) return 0; } -int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) + +/* + Close a HANDLER table. + + SYNOPSIS + mysql_ha_close() + thd Thread identifier. + tables A list of tables with the first entry to close. + dont_send_ok Suppresses the commands' ok message and + error message and error return. + dont_lock Suppresses the normal locking of LOCK_open. + + DESCRIPTION + Though this function takes a list of tables, only the first list entry + will be closed. Broadcasts a COND_refresh condition. + If mysql_ha_close() is not called from the parser, 'dont_send_ok' + must be set. + If the caller did already lock LOCK_open, it must set 'dont_lock'. + + IMPLEMENTATION + find_table_ptr_by_name() closes the table, if a FLUSH TABLE is outstanding. + It returns a NULL pointer in this case, but flags the situation in + 'was_flushed'. In that case the normal ER_UNKNOWN_TABLE error messages + is suppressed. + + RETURN + 0 ok + -1 error +*/ + +int mysql_ha_close(THD *thd, TABLE_LIST *tables, + bool dont_send_ok, bool dont_lock, bool no_alias) { - TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->alias, 1); + TABLE **table_ptr; + bool was_flushed; - if (*ptr) + table_ptr= find_table_ptr_by_name(thd, tables->db, tables->alias, + !no_alias, dont_lock, &was_flushed); + if (*table_ptr) { (*ptr)->file->ha_index_or_rnd_end(); - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, ptr)) + if (!dont_lock) + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ VOID(pthread_cond_broadcast(&COND_refresh)); } - VOID(pthread_mutex_unlock(&LOCK_open)); + if (!dont_lock) + VOID(pthread_mutex_unlock(&LOCK_open)); } - else + else if (!was_flushed && !dont_send_ok) { - my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), - tables->alias, "HANDLER"); + my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), + tables->alias, "HANDLER"); return -1; } if (!dont_send_ok) @@ -92,16 +130,64 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) return 0; } -int mysql_ha_closeall(THD *thd, TABLE_LIST *tables) + +/* + Close a list of HANDLER tables. + + SYNOPSIS + mysql_ha_close_list() + thd Thread identifier. + tables The list of tables to close. If NULL, + close all HANDLER tables. + flushed Close only tables which are marked flushed. + Used only if tables is NULL. + + DESCRIPTION + The list of HANDLER tables may be NULL, in which case all HANDLER + tables are closed. Broadcasts a COND_refresh condition, for + every table closed. If 'tables' is NULL and 'flushed' is set, + all HANDLER tables marked for flush are closed. + The caller must lock LOCK_open. + + IMPLEMENTATION + find_table_ptr_by_name() closes the table, if it is marked for flush. + It returns a NULL pointer in this case, but flags the situation in + 'was_flushed'. In that case the normal ER_UNKNOWN_TABLE error messages + is suppressed. + + RETURN + 0 ok +*/ + +int mysql_ha_close_list(THD *thd, TABLE_LIST *tables, bool flushed) { - TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0); - if (*ptr) + TABLE_LIST *tl_item; + TABLE **table_ptr; + + if (tables) { - (*ptr)->file->ha_index_or_rnd_end(); - if (close_thread_table(thd, ptr)) + for (tl_item= tables ; tl_item; tl_item= tl_item->next) { - /* Tell threads waiting for refresh that something has happened */ - VOID(pthread_cond_broadcast(&COND_refresh)); + mysql_ha_close(thd, tl_item, /*dont_send_ok*/ 1, + /*dont_lock*/ 1, /*no_alias*/ 1); + } + } + else + { + table_ptr= &(thd->handler_tables); + while (*table_ptr) + { + if (! flushed || ((*table_ptr)->version != refresh_version)) + { + (*table_ptr)->file->ha_index_or_rnd_end(); + if (close_thread_table(thd, table_ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } + continue; + } + table_ptr= &((*table_ptr)->next); } } return 0; @@ -117,7 +203,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ha_rows select_limit,ha_rows offset_limit) { int err, keyno=-1; - TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->alias, 1); + bool was_flushed; + TABLE *table= *find_table_ptr_by_name(thd, tables->db, tables->alias, + /*is_alias*/ 1, /*dont_lock*/ 0, + &was_flushed); if (!table) { my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), @@ -298,17 +387,51 @@ err0: } +/* + Find a HANDLER table by name. + + SYNOPSIS + find_table_ptr_by_name() + thd Thread identifier. + db Database (schema) name. + table_name Table name ;-). + is_alias Table name may be an alias name. + dont_lock Suppresses the normal locking of LOCK_open. + + DESCRIPTION + Find the table 'db'.'table_name' in the list of HANDLER tables of the + thread 'thd'. If the table has been marked by FLUSH TABLE(S), close it, + flag this situation in '*was_flushed' and broadcast a COND_refresh + condition. + An empty database (schema) name matches all database (schema) names. + If the caller did already lock LOCK_open, it must set 'dont_lock'. + + IMPLEMENTATION + Just in case that the table is twice in 'thd->handler_tables' (!?!), + the loop does not break when the table was flushed. If another table + by that name was found and not flushed, '*was_flushed' is cleared again, + since a pointer to an open HANDLER table is returned. + + RETURN + *was_flushed Table has been closed due to FLUSH TABLE. + NULL A HANDLER Table by that name does not exist (any more). + != NULL Pointer to the TABLE structure. +*/ + static TABLE **find_table_ptr_by_name(THD *thd, const char *db, - const char *table_name, bool is_alias) + const char *table_name, + bool is_alias, bool dont_lock, + bool *was_flushed) { int dblen; - TABLE **ptr; + TABLE **table_ptr; DBUG_ASSERT(db); dblen= strlen(db); - ptr= &(thd->handler_tables); + table_ptr= &(thd->handler_tables); + *was_flushed= FALSE; - for (TABLE *table= *ptr; table ; table= *ptr) + for (TABLE *table= *table_ptr; table ; table= *table_ptr) { if ((db == any_db || !memcmp(table->table_cache_key, db, dblen)) && !my_strcasecmp(system_charset_info, @@ -317,18 +440,22 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, { if (table->version != refresh_version) { - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, ptr)) + if (!dont_lock) + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ VOID(pthread_cond_broadcast(&COND_refresh)); } - VOID(pthread_mutex_unlock(&LOCK_open)); + if (!dont_lock) + VOID(pthread_mutex_unlock(&LOCK_open)); + *was_flushed= TRUE; continue; } + *was_flushed= FALSE; break; } - ptr= &(table->next); + table_ptr= &(table->next); } - return ptr; + return table_ptr; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 932ceff2f43..a5de5397ec8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2283,7 +2283,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) add_key_field(key_fields,*and_level,cond_func, ((Item_field*) (cond_func->key_item()->real_item()))-> - field, 0, + field, cond_func->argument_count() == 2, cond_func->arguments()+1, cond_func->argument_count()-1, usable_tables); break; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6e447271b2e..6c9ec41c728 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -191,7 +191,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, for (table=tables ; table ; table=table->next) { char *db=table->db; - mysql_ha_closeall(thd, table); + mysql_ha_close(thd, table, /*dont_send_ok*/ 1, /*dont_lock*/ 1); if (!close_temporary_table(thd, db, table->real_name)) { tmp_table_deleted=1; @@ -1727,7 +1727,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (protocol->send_fields(&field_list, 1)) DBUG_RETURN(-1); - mysql_ha_closeall(thd, tables); + mysql_ha_close(thd, tables, /*dont_send_ok*/ 1, /*dont_lock*/ 1); for (table = tables; table; table = table->next) { char table_name[NAME_LEN*2+2]; @@ -2254,7 +2254,7 @@ int mysql_discard_or_import_tablespace(THD *thd, thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open and ::external_lock() do not complain when we lock the table */ - mysql_ha_closeall(thd, table_list); + mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1); if (!(table=open_ltable(thd,table_list,TL_WRITE))) { @@ -2533,7 +2533,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, new_db= db; used_fields=create_info->used_fields; - mysql_ha_closeall(thd, table_list); + mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1); /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP) @@ -2588,7 +2588,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } } else - new_alias= new_name= table_name; + { + new_alias= (lower_case_table_names == 2) ? alias : table_name; + new_name= table_name; + } old_db_type=table->db_type; if (create_info->db_type == DB_TYPE_DEFAULT) diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c index 71b194838c7..d05e50af16b 100644 --- a/vio/test-sslserver.c +++ b/vio/test-sslserver.c @@ -91,7 +91,12 @@ main(int argc __attribute__((unused)), char** argv) struct sockaddr_in sa_cli; int listen_sd; int err; + +#if defined(__sgi) && _NO_XOPEN4 && _NO_XOPEN5 + socklen_t client_len; +#else size_t client_len; +#endif int reuseaddr = 1; /* better testing, uh? */ MY_INIT(argv[0]); |