summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--BitKeeper/etc/logging_ok1
-rwxr-xr-xBuild-tools/Do-rpm67
-rwxr-xr-xBuild-tools/my_md5sum124
-rw-r--r--acinclude.m45
-rw-r--r--include/mysql.h2
-rw-r--r--innobase/include/mach0data.h6
-rw-r--r--innobase/include/mach0data.ic4
-rw-r--r--innobase/include/mtr0log.h4
-rw-r--r--innobase/include/mtr0log.ic4
-rw-r--r--innobase/mem/mem0dbg.c1
-rw-r--r--innobase/pars/lexyy.c244
-rw-r--r--innobase/pars/pars0lex.l27
-rw-r--r--libmysql/libmysql.c3
-rw-r--r--man/mysqlaccess.1.in3
-rw-r--r--man/mysqldump.1.in2
-rw-r--r--mysql-test/mysql-test-run.sh2
-rw-r--r--mysql-test/r/bdb.result34
-rw-r--r--mysql-test/r/flush_table.result120
-rw-r--r--mysql-test/r/innodb_cache.result21
-rw-r--r--mysql-test/r/lowercase_table2.result10
-rw-r--r--mysql-test/r/range.result2
-rw-r--r--mysql-test/t/bdb.test36
-rw-r--r--mysql-test/t/flush_table.test115
-rw-r--r--mysql-test/t/innodb_cache.test23
-rw-r--r--mysql-test/t/lowercase_table2.test11
-rw-r--r--mysys/hash.c3
-rw-r--r--scripts/make_win_binary_distribution.sh5
-rw-r--r--scripts/make_win_src_distribution.sh6
-rw-r--r--sql/field.cc80
-rw-r--r--sql/field.h6
-rw-r--r--sql/ha_berkeley.cc35
-rw-r--r--sql/handler.cc5
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_handler.cc181
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_table.cc13
-rw-r--r--vio/test-sslserver.c5
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, &current_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]);