summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2000-11-15 18:58:59 -0700
committerunknown <sasha@mysql.sashanet.com>2000-11-15 18:58:59 -0700
commitf44a41f013a8791fc2ddba88a9f23efe5cfb6c99 (patch)
treed78befdf5251596d35567b37ed5edb3edae3f8bd
parent11b725d1a3417e7c9704a2e4d4bde519a513a0fb (diff)
parent3e6dac34cd5b8ef322d375f3af22137822656c8a (diff)
downloadmariadb-git-f44a41f013a8791fc2ddba88a9f23efe5cfb6c99.tar.gz
merged
sql/log_event.h: Auto merged sql/mysqlbinlog.cc: Auto merged sql/mysqld.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/sql_class.h: Auto merged BitKeeper/etc/logging_ok: Auto converge
-rw-r--r--BitKeeper/etc/logging_ok8
-rw-r--r--Docs/manual.texi1421
-rw-r--r--client/mysql.cc14
-rw-r--r--client/mysqladmin.c20
-rw-r--r--client/mysqldump.c20
-rw-r--r--client/mysqlimport.c19
-rw-r--r--client/mysqlshow.c22
-rw-r--r--client/sql_string.cc26
-rw-r--r--client/sql_string.h18
-rw-r--r--configure.in8
-rw-r--r--include/my_pthread.h3
-rw-r--r--include/my_sys.h5
-rw-r--r--include/violite.h3
-rw-r--r--libmysql/libmysql.c36
-rw-r--r--libmysql/violite.c33
-rw-r--r--myisam/mi_create.c1
-rw-r--r--myisam/mi_locking.c6
-rw-r--r--myisam/mi_open.c5
-rw-r--r--myisam/mi_search.c6
-rw-r--r--myisam/myisamdef.h1
-rw-r--r--mysql.projbin176128 -> 184320 bytes
-rw-r--r--mysys/Makefile.am4
-rw-r--r--mysys/hash.c3
-rw-r--r--mysys/mf_cache.c8
-rw-r--r--mysys/mf_iocache.c43
-rw-r--r--mysys/mf_iocache2.c212
-rw-r--r--mysys/my_vsnprintf.c91
-rw-r--r--scripts/safe_mysqld.sh15
-rwxr-xr-xsql-bench/bench-init.pl.sh9
-rwxr-xr-xsql-bench/crash-me.sh7
-rwxr-xr-xsql-bench/test-insert.sh123
-rwxr-xr-xsql-bench/test-select.sh67
-rw-r--r--sql/filesort.cc22
-rw-r--r--sql/ha_berkeley.cc26
-rw-r--r--sql/ha_berkeley.h3
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item_create.cc5
-rw-r--r--sql/item_create.h1
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/lex.h2
-rw-r--r--sql/lock.cc4
-rw-r--r--sql/log.cc598
-rw-r--r--sql/log_event.cc307
-rw-r--r--sql/log_event.h63
-rw-r--r--sql/mf_iocache.cc48
-rw-r--r--sql/mysqlbinlog.cc144
-rw-r--r--sql/mysqld.cc20
-rw-r--r--sql/net_pkg.cc10
-rw-r--r--sql/sql_class.cc13
-rw-r--r--sql/sql_class.h12
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_lex.h24
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_parse.cc36
-rw-r--r--sql/sql_repl.cc538
-rw-r--r--sql/sql_select.cc11
-rw-r--r--sql/sql_string.cc26
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/time.cc10
-rw-r--r--sql/violite.c46
-rw-r--r--strings/strstr-sparc.s5
62 files changed, 2467 insertions, 1797 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index bfd5d8f5b39..2f0845b6997 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -1,8 +1,2 @@
-jcole@tetra.bedford.progress.com
-jcole@tetra.spaceapes.com
-sasha@laptop.slkc.uswest.net
+monty@donna.mysql.com
sasha@mysql.sashanet.com
-sasha@work.mysql.com
-serg@serg.mysql.com
-yfaktoro@nslinuxw2.bedford.progress.com
-mwagner@evoq.home.mwagner.org
diff --git a/Docs/manual.texi b/Docs/manual.texi
index c4bea6e4f73..85a363fac5a 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -373,6 +373,7 @@ MySQL Language Reference
* ANALYZE TABLE:: @code{ANALYZE TABLE} syntax
* REPAIR TABLE:: @code{REPAIR TABLE} syntax
* DELETE:: @code{DELETE} syntax
+* TRUNCATE::
* SELECT:: @code{SELECT} syntax
* JOIN:: @code{JOIN} syntax
* INSERT:: @code{INSERT} syntax
@@ -591,6 +592,7 @@ Speed of queries that access or update data
MySQL Utilites
* Programs:: What do the executables do?
+* safe_mysqld:: safe_mysqld, the wrapper around mysqld
* mysql:: The command line tool
* mysqladmin:: Administering a @strong{MySQL} server
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
@@ -813,7 +815,7 @@ MySQL change history
Changes in release 3.23.x (Recommended; beta)
-* News-3.23.28:: Changes in release 3.23.28
+* News-3.23.28:: Changes in release 3.23.28
* News-3.23.27:: Changes in release 3.23.27
* News-3.23.26:: Changes in release 3.23.26
* News-3.23.25:: Changes in release 3.23.25
@@ -1225,7 +1227,7 @@ pathnames. Example: ``The distribution is installed under the
@item @samp{c}
Constant-width font with surrounding quotes is also used to indicate
-character sequences. Example: ``To specify a wildcard, use the @samp{%}
+character sequences. Example: ``To specify a wild card, use the @samp{%}
character.''
@item @emph{italic}
@@ -1284,7 +1286,7 @@ mysql> SELECT author_name FROM biblio_db.author_list;
@end example
SQL statements may be written in uppercase or lowercase. When this manual
-shows a SQL statement, uppercase is used for particular keywords if those
+shows an SQL statement, uppercase is used for particular keywords if those
keywords are under discussion (to emphasize them) and lowercase is used for
the rest of the statement. For example, you might see the following in a
discussion of the @code{SELECT} statement:
@@ -1943,7 +1945,7 @@ Publisher Sybex 510 523 8233
Alameda, CA USA
@end example
-A SQL tutorial is available on the net at
+An SQL tutorial is available on the net at
http://www.geocities.com/SiliconValley/Vista/2207/sql1.html.
@c A nice german 404 error. (jcole)
@@ -2002,6 +2004,8 @@ Hands on tutorial for @strong{MySQL}.
The Mac OS Xclave. Running @strong{MySQL} on Mac OS X
@item @uref{http://www.prnet.de/RegEx/mysql.html}@*
MySQL for Mac OS X Server.
+@item @uref{http://www.latencyzero.com/macosx/mysql.html}@*
+Bulding MySQL for Mac OS X
@item @uref{http://www.lilback.com/macsql/}@*
Client libraries for the Macintosh.
@end itemize
@@ -2394,7 +2398,7 @@ A Contact Database using @strong{MySQL} and PHP.
Web based interface and Community Calender with PHP.
@item @uref{http://www.odbsoft.com/cook/sources.htm}@*
-Perl package to generate html from a SQL table structure and for generating
+Perl package to generate html from an SQL table structure and for generating
SQL statements from an html form.
@item @uref{http://www.gusnet.cx/proj/telsql/}@*
@@ -3606,10 +3610,13 @@ similar system. In the worst case, we may require access to your system
to be able to create a binary distribution.
@item
-If you can provide accommodations and pay for traveler fares, you can even
-get a @strong{MySQL} developer to visit you and offer you help with your
-troubles. Extended login support entitles you to one personal
-encounter per year, but we are always very flexible towards our customers!
+If you can provide accommodations and pay for traveler fares, you can
+even get a @strong{MySQL} developer to visit you and offer you help with
+your troubles. Extended login support entitles you to one personal
+encounter per year, but we are always very flexible towards our
+customers! If the visit takes 16 hours or more, the first 8 hours is
+without charge. For the hours above 8 hours, you will be charged with a
+rate that is at least 20 % less than our standard rates.
@end itemize
@node Installing, Compatibility, Licensing and Support, Top
@@ -4940,6 +4947,8 @@ You can start the @strong{MySQL} server with the following command:
shell> bin/safe_mysqld --user=mysql &
@end example
+@xref{safe_mysqld}.
+
@xref{Post-installation}.
@cindex RPM file
@@ -5227,7 +5236,8 @@ work. @code{libg++} is not needed when using @code{gcc}. @code{gcc}
C++ files, such as @file{sql/sql_base.cc}. If you only have @code{gcc} 2.7.x,
you must upgrade your @code{gcc} to be able to compile @strong{MySQL}.
-@code{gcc} >= 2.95.2 is recommended when compiling @strong{MySQL} 3.23.x.
+@code{gcc} >= 2.95.2 is recommended when compiling @strong{MySQL}
+Version 3.23.x.
@item
A good @code{make} program. GNU @code{make} is always recommended and is
@@ -6654,7 +6664,7 @@ table. @xref{Crashing}.
To get a core dump on Linux if mysqld dies with a SIGSEGV
signal, you can start mysqld with the @code{--core-file} option. Note
that you also probably need to raise the @code{core file size} by adding
-@code{ulimit -c 1000000} to @code{safe_mysqld}.
+@code{ulimit -c 1000000} to @code{safe_mysqld}. @xref{safe_mysqld}.
If you are using LinuxThreads and @code{mysqladmin shutdown} doesn't work,
you must upgrade to LinuxThreads Version 0.7.1 or newer.
@@ -7016,6 +7026,7 @@ shell> nohup mysqld [options] &
@code{nohup} causes the command following it to ignore any @code{SIGHUP}
signal sent from the terminal. Alternatively, start the server by running
@code{safe_mysqld}, which invokes @code{mysqld} using @code{nohup} for you.
+@xref{safe_mysqld}.
If you get a problem when compiling mysys/get_opt.c, just remove the
line #define _NO_PROTO from the start of that file!
@@ -7270,7 +7281,7 @@ FreeBSD is also known to have a very low default file handle limit.
safe_mysqld or raise the limits for the mysqld user in /etc/login.conf
(and rebuild it witg cap_mkdb /etc/login.conf.) Also be sure you set the
appropriate class for this user in the password file if you are not
-using the default (use: chpass mysqld-user-name)
+using the default (use: chpass mysqld-user-name). @xref{safe_mysqld}.
If you get problems with the current date in @strong{MySQL}, setting the
@code{TZ} variable will probably help. @xref{Environment variables}.
@@ -7357,7 +7368,7 @@ You can change the directory locations if you wish, or just use the
defaults by not specifying any locations.
If you have problems with performance under heavy load, try using the
-@code{--skip-thread-priority} option to @code{safe_mysqld}! This will run
+@code{--skip-thread-priority} option to @code{mysqld}! This will run
all threads with the same priority; on BSDI Version 3.1, this gives better
performance (at least until BSDI fixes their thread scheduler).
@@ -7637,7 +7648,7 @@ the DCE libraries while you compile @code{gcc} 2.95!
@node HP-UX 11.x, Mac OS X, HP-UX 10.20, Source install system issues
@subsection HP-UX Version 11.x Notes
-For HPUX Version 11.x we recommend @strong{MySQL} 3.23.15 or later.
+For HPUX Version 11.x we recommend @strong{MySQL} Version 3.23.15 or later.
If you are using @code{gcc} 2.95.1 on a unpatched HPUX 11.x system,
you will get the error:
@@ -8515,6 +8526,7 @@ mysqld: Can't find file: 'host.frm'
The above may also happen with a binary @strong{MySQL} distribution if you
don't start @strong{MySQL} by executing exactly @code{./bin/safe_mysqld}!
+@xref{safe_mysqld}.
You might need to run @code{mysql_install_db} as @code{root}. However,
if you prefer, you can run the @strong{MySQL} server as an unprivileged
@@ -8828,7 +8840,7 @@ system startup and shutdown, and is described more fully in
@ref{Automatic start}.
@item
By invoking @code{safe_mysqld}, which tries to determine the proper options
-for @code{mysqld} and then runs it with those options.
+for @code{mysqld} and then runs it with those options. @xref{safe_mysqld}.
@item
On NT you should install @code{mysqld} as a service as follows:
@example
@@ -8924,47 +8936,6 @@ the command @code{telnet your-host-name tcp-ip-port-number} and press
something is using the TCP/IP port @code{mysqld} is trying to use.
See @ref{mysql_install_db} and @ref{Multiple servers}.
-The @code{safe_mysqld} script is written so that it normally is able to start
-a server that was installed from either a source or a binary version of
-@strong{MySQL}, even if these install the server in slightly different
-locations. @code{safe_mysqld} expects one of these conditions to be true:
-
-@itemize @bullet
-@item
-The server and databases can be found relative to the directory from which
-@code{safe_mysqld} is invoked. @code{safe_mysqld} looks under its working
-directory for @file{bin} and @file{data} directories (for binary
-distributions) or for @file{libexec} and @file{var} directories (for source
-distributions). This condition should be met if you execute
-@code{safe_mysqld} from your @strong{MySQL} installation directory (for
-example, @file{/usr/local/mysql} for a binary distribution).
-
-@item
-If the server and databases cannot be found relative to the working directory,
-@code{safe_mysqld} attempts to locate them by absolute pathnames. Typical
-locations are @file{/usr/local/libexec} and @file{/usr/local/var}.
-The actual locations are determined when the distribution was built from which
-@code{safe_mysqld} comes. They should be correct if
-@strong{MySQL} was installed in a standard location.
-@end itemize
-
-Because @code{safe_mysqld} will try to find the server and databases relative
-to its own working directory, you can install a binary distribution of
-@strong{MySQL} anywhere, as long as you start @code{safe_mysqld} from the
-@strong{MySQL} installation directory:
-
-@example
-shell> cd mysql_installation_directory
-shell> bin/safe_mysqld &
-@end example
-
-If @code{safe_mysqld} fails, even when invoked from the @strong{MySQL}
-installation directory, you can modify it to use the path to @code{mysqld}
-and the pathname options that are correct for your system. Note that if you
-upgrade @strong{MySQL} in the future, your modified version of
-@code{safe_mysqld} will be overwritten, so you should make a copy of your
-edited version that you can reinstall.
-
If @code{mysqld} is currently running, you can find out what path settings
it is using by executing this command:
@@ -9064,7 +9035,7 @@ The @code{mysql.server} script uses the following variables:
@findex command-line options
@cindex options, command-line
@node Command-line options, Option files, Automatic start, Post-installation
-@subsection Command-line Options
+@subsection mysqld command-line options
@code{mysqld} accepts the following command-line options:
@@ -10108,6 +10079,7 @@ The following will not yet work in @strong{MySQL}:
@example
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
+SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2 where table1.id=table2.id);
@end example
However, in many cases you can rewrite the query without a sub-select:
@@ -10387,6 +10359,11 @@ unless you do so in a very specific order.
It's very easy to do ``allowed'' circular definitions that make the
tables impossible to re-create each table with a single create statement,
even if the definition works and is usable.
+
+@item
+It's very easy to overlook @code{FOREIGN KEY ... ON DELETE} rules when
+one codes an application. It's not unusual that one loses a lot of
+important information just because a wrong or misused @code{ON DELETE} rule.
@end itemize
The only nice aspect of @code{FOREIGN KEY} is that it gives ODBC and some
@@ -10439,7 +10416,7 @@ In @strong{MySQL} Version 3.23 you can, however, use:
The following discussion only concerns you if you are running a @strong{MySQL}
version earlier than Version 3.23:
-If you have a SQL program in a text file that contains @samp{--} comments
+If you have an SQL program in a text file that contains @samp{--} comments
you should use:
@example
@@ -10850,7 +10827,7 @@ mysql> FLUSH PRIVILEGES;
Don't run the @strong{MySQL} daemon as the UNIX @code{root} user.
It is very dangerous as any user with @code{FILE} privileges will be able to
create files
-as @code{root} (e.g. @code{~root/.bashrc}). To prevent this
+as @code{root} (for example, @code{~root/.bashrc}). To prevent this
@code{mysqld} will refuse to run as @code{root} unless it is specified
directly via @code{--user=root} option.
@@ -10989,7 +10966,7 @@ one used during the UNIX login process. See the descriptions of the
@code{PASSWORD()} and @code{ENCRYPT()} functions in @ref{Miscellaneous
functions}. Note that even if the password is stored 'scrambled', and
knowing your 'scrambled' password is enough to be able to connect to
-the the @strong{MySQL} server!
+the @strong{MySQL} server!
@end itemize
@node Connecting, Password security, User names, Privilege system
@@ -11540,7 +11517,7 @@ to indicate the local host.
@item
@cindex wildcards, in @code{mysql.user} table
-You can use the wild card characters @samp{%} and @samp{_} in the @code{Host}
+You can use the wild-card characters @samp{%} and @samp{_} in the @code{Host}
field.
@item
@@ -11569,7 +11546,7 @@ In the above example all IP:s in the interval 192.58.197.0 -
@item
@cindex anonymous user
-Wild card characters are not allowed in the @code{User} field, but you can
+Wild-card characters are not allowed in the @code{User} field, but you can
specify a blank value, which matches any name. If the @code{user} table
entry that matches an incoming connection has a blank user name, the user is
considered to be the anonymous user (the user with no name), rather than the
@@ -11611,14 +11588,14 @@ connections:
@item @code{'144.155.166.0/24'} @tab @code{'fred'} @tab Same as previous example
@end multitable
-Because you can use IP wild card values in the @code{Host} field (for example,
+Because you can use IP wild-card values in the @code{Host} field (for example,
@code{'144.155.166.%'} to match every host on a subnet), there is the
possibility that someone might try to exploit this capability by naming a
host @code{144.155.166.somewhere.com}. To foil such attempts, @strong{MySQL}
disallows matching on hostnames that start with digits and a dot. Thus, if
you have a host named something like @code{1.2.foo.com}, its name will never
match the @code{Host} column of the grant tables. Only an IP number can
-match an IP wild card value.
+match an IP wild-card value.
An incoming connection may be matched by more than one entry in the
@code{user} table. For example, a connection from @code{thomas.loc.gov} by
@@ -11738,7 +11715,7 @@ Values in the scope fields may be specified as follows:
@itemize @bullet
@item
-The wild card characters @samp{%} and @samp{_} can be used in the @code{Host}
+The wild-card characters @samp{%} and @samp{_} can be used in the @code{Host}
and @code{Db} fields of either table.
@item
@@ -11778,7 +11755,7 @@ follows:
@itemize @bullet
@item
-The wild card characters @samp{%} and @samp{_}
+The wild-card characters @samp{%} and @samp{_}
can be used in the @code{Host} field of either table.
@item
@@ -12611,6 +12588,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
* ANALYZE TABLE:: @code{ANALYZE TABLE} syntax
* REPAIR TABLE:: @code{REPAIR TABLE} syntax
* DELETE:: @code{DELETE} syntax
+* TRUNCATE::
* SELECT:: @code{SELECT} syntax
* JOIN:: @code{JOIN} syntax
* INSERT:: @code{INSERT} syntax
@@ -12715,14 +12693,14 @@ A backslash (@samp{\}) character.
@item \%
A @samp{%} character. This is used to search for literal instances of
@samp{%} in contexts where @samp{%} would otherwise be interpreted
-as a wild card character. @xref{String comparison functions}.
+as a wild-card character. @xref{String comparison functions}.
@findex _ (wild card character)
@findex Wild card character (_)
@item \_
A @samp{_} character. This is used to search for literal instances of
@samp{_} in contexts where @samp{_} would otherwise be interpreted
-as a wild card character. @xref{String comparison functions}.
+as a wild-card character. @xref{String comparison functions}.
@end table
Note that if you use @samp{\%} or @samp{\_} in some string contexts, these
@@ -13264,8 +13242,8 @@ numbers.
@tindex YEAR
@item YEAR[(2|4)]
-A year in 2- or 4- digit formats (default is 4-digit). The allowable values
-are @code{1901} to @code{2155}, and @code{0000} in the 4-digit year format,
+A year in 2- or 4-digit format (default is 4-digit). The allowable values
+are @code{1901} to @code{2155}, @code{0000} in the 4-digit year format,
and 1970-2069 if you use the 2-digit format (70-69). @strong{MySQL} displays
@code{YEAR} values in @code{YYYY} format, but allows you to assign values to
@code{YEAR} columns using either strings or numbers. (The @code{YEAR} type is
@@ -13527,7 +13505,7 @@ of an integral value in parentheses following the base keyword for the
type (for example, @code{INT(4)}). This optional width specification is
used to left-pad the display of values whose width is less than the
width specified for the column, but does not constrain the range of
-values which can be stored in the column, nor the number of digits that
+values that can be stored in the column, nor the number of digits that
will be displayed for values whose width exceeds that specified for the
column. When used in conjunction with the optional extension attribute
@code{ZEROFILL}, the default padding of spaces is replaced with zeroes.
@@ -14231,9 +14209,10 @@ communications buffers. You can change the message buffer size, but you must
do so on both the server and client ends. @xref{Server parameters}.
@end itemize
-Note that each @code{BLOB} or @code{TEXT} value is represented internally by
-a separately allocated object. This is in contrast to all other column types,
-for which storage is allocated once per column when the table is opened.
+Note that each @code{BLOB} or @code{TEXT} value is represented
+internally by a separately allocated object. This is in contrast to all
+other column types, for which storage is allocated once per column when
+the table is opened.
@tindex ENUM
@node ENUM, SET, BLOB, String types
@@ -14563,7 +14542,7 @@ statement, @strong{MySQL} reports the table structure using the equivalent
@node Functions, CREATE DATABASE, Column types, Reference
@section Functions for Use in @code{SELECT} and @code{WHERE} Clauses
-A @code{select_expression} or @code{where_definition} in a SQL statement
+A @code{select_expression} or @code{where_definition} in an SQL statement
can consist of any expression using the functions described below.
An expression that contains @code{NULL} always produces a @code{NULL} value
@@ -14636,8 +14615,8 @@ mysql> select (1+2)*3;
@subsection Normal Arithmetic Operations
The usual arithmetic operators are available. Note that in the case of
-@samp{-}, @samp{+}, and @samp{*}, the result is calculated with @code{BIGINT}
-(64-bit) precision if both arguments are integers!
+@samp{-}, @samp{+}, and @samp{*}, the result is calculated with
+@code{BIGINT} (64-bit) precision if both arguments are integers!
@cindex operations, arithmetic
@cindex arithmetic expressions
@@ -15081,7 +15060,7 @@ comparison is performed in case-sensitive fashion.
@item expr LIKE pat [ESCAPE 'escape-char']
Pattern matching using
SQL simple regular expression comparison. Returns @code{1} (TRUE) or @code{0}
-(FALSE). With @code{LIKE} you can use the following two wild card characters
+(FALSE). With @code{LIKE} you can use the following two wild-card characters
in the pattern:
@multitable @columnfractions .1 .9
@@ -15096,7 +15075,7 @@ mysql> select 'David!' LIKE '%D%v%';
-> 1
@end example
-To test for literal instances of a wild card character, precede the character
+To test for literal instances of a wild-card character, precede the character
with the escape character. If you don't specify the @code{ESCAPE} character,
@samp{\} is assumed:
@@ -15221,7 +15200,10 @@ mysql> select BINARY "a" = "A";
-> 0
@end example
-@code{BINARY} was introduced in @strong{MySQL} 3.23.0.
+@code{BINARY} was introduced in @strong{MySQL} Version 3.23.0.
+
+Note that in some context @strong{MySQL} will not be able to use the
+index efficiently when you cast an indexed column to @code{BINARY}.
@end table
@findex control flow functions
@@ -15293,8 +15275,9 @@ may not be what you expect. In the second case, the comparison tests the
original floating-point value to see whether it is non-zero. The result
of the comparison is used as an integer.
-The default return type of @code{IF()} (which may matter when it is stored into
-a temporary table) is calculated in @strong{MySQL} Version 3.23 as follows:
+The default return type of @code{IF()} (which may matter when it is
+stored into a temporary table) is calculated in @strong{MySQL} Version
+3.23 as follows:
@multitable @columnfractions .55 .45
@item @strong{Expression} @tab @strong{Return value}
@@ -16267,8 +16250,9 @@ mysql> SELECT something FROM table
@findex DAYOFWEEK()
@item DAYOFWEEK(date)
Returns the weekday index
-for @code{date} (@code{1} = Sunday, @code{2} = Monday, ... @code{7} = Saturday).
-These index values correspond to the ODBC standard:
+
+for @code{date} (@code{1} = Sunday, @code{2} = Monday, ... @code{7} =
+Saturday). These index values correspond to the ODBC standard:
@example
mysql> select DAYOFWEEK('1998-02-03');
@@ -17698,6 +17682,8 @@ alter_specification:
or ADD PRIMARY KEY (index_col_name,...)
or ADD UNIQUE [index_name] (index_col_name,...)
or ADD FULLTEXT [index_name] (index_col_name,...)
+ or ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
+ [reference_definition]
or ALTER [COLUMN] col_name @{SET DEFAULT literal | DROP DEFAULT@}
or CHANGE [COLUMN] old_col_name create_definition
or MODIFY [COLUMN] create_definition
@@ -17757,6 +17743,9 @@ INDEX} are @strong{MySQL} extensions to ANSI SQL92.
@code{MODIFY} is an Oracle extension to @code{ALTER TABLE}.
@item
+@code{TRUNCATE} is an Oracle extension. @xref{TRUNCATE}.
+
+@item
The optional word @code{COLUMN} is a pure noise word and can be omitted.
@item
@@ -18112,7 +18101,6 @@ as they are being backed up. If you want to backup several tables as
a snapshot, you must first issue @code{LOCK TABLES} obtaining a read
lock for each table in the group.
-
The command returns a table with the following columns:
@multitable @columnfractions .35 .65
@@ -18123,6 +18111,8 @@ The command returns a table with the following columns:
@item Msg_text @tab The message.
@end multitable
+Note that @code{BACKUP TABLE} is only available in @strong{MySQL}
+version 3.23.25 and later.
@findex RESTORE TABLE
@node RESTORE TABLE, ANALYZE TABLE, BACKUP TABLE, Reference
@@ -18221,7 +18211,7 @@ better than sorting on fixed length keys if you have long @code{char()}
keys that compress very good.
@findex DELETE
-@node DELETE, SELECT, REPAIR TABLE, Reference
+@node DELETE, TRUNCATE, REPAIR TABLE, Reference
@section @code{DELETE} syntax
@example
@@ -18233,14 +18223,10 @@ DELETE [LOW_PRIORITY] FROM tbl_name
given by @code{where_definition}, and returns the number of records deleted.
If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are
-deleted. If you do this in @code{AUTOCOMMIT} mode, @strong{MySQL} does
-this by recreating the table as an empty table, which is much faster
-than deleting each row. In this case, @code{DELETE} returns zero as the
-number of affected records. (@strong{MySQL} can't return the number of
-rows that were actually deleted, because the recreate is done without
-opening the data files. As long as the table definition file
-@file{tbl_name.frm} is valid, the table can be recreated this way, even
-if the data or index files have become corrupted.).
+deleted. If you do this in @code{AUTOCOMMIT} mode, this works as
+@code{TRUNCATE}. @xref{TRUNCATE}. One problem with this is that
+@code{DELETE} will return zero as the number of affected records, but
+this will be fixed in 4.0.
If you really want to know how many records are deleted when you are deleting
all rows, and are willing to suffer a speed penalty, you can use a
@@ -18271,8 +18257,34 @@ returned to the client. This can be used to ensure that a specific
the @code{DELETE} command until the number of affected rows is less than
the @code{LIMIT} value.
+@findex TRUNCATE
+@node TRUNCATE, SELECT, DELETE, Reference
+@section @code{TRUNCATE} syntax
+
+@example
+TRUNCATE TABLE table_name
+@end example
+
+Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}.
+The differences are:
+
+@table @bullet
+@item
+Implemented as a drop and recreate of the table, which makes this
+much faster when deleting many rows.
+@item
+Not transaction safe; @code{TRUNCATE} will automaticly end the current
+transaction as if @code{COMMIT} would have been called.
+@item
+Doesn't return the number of deleted rows.
+@item
+As long as the table definition file @file{table_name.frm} is
+valid, the table can be recreated this way, even if the data or index
+files have become corrupted..
+@end table
+
@findex SELECT
-@node SELECT, JOIN, DELETE, Reference
+@node SELECT, JOIN, TRUNCATE, Reference
@section @code{SELECT} syntax
@c help SELECT
@@ -18423,7 +18435,7 @@ in cases where it takes a long time to send the result set to the client.
with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the
result set will be small. In this case, @strong{MySQL} will use fast
temporary tables to store the resulting table instead of using sorting. In
-@strong{MySQL} 3.23 this shouldn't normally be needed.
+@strong{MySQL} Version 3.23 this shouldn't normally be needed.
@item
@code{STRAIGHT_JOIN} forces the optimizer to join the tables in the order in
@@ -18614,7 +18626,7 @@ is always read before the right table. This can be used for those (few)
cases where the join optimizer puts the tables in the wrong order.
@item
-As of @strong{MySQL} 3.23.12, you can give hints about which
+As of @strong{MySQL} Version 3.23.12, you can give hints about which
index @strong{MySQL} should use when retrieving information from a
table. This is useful if @code{EXPLAIN} shows that @strong{MySQL} is
using the wrong index. By specifying @code{USE INDEX (key_list)}, you
@@ -18914,6 +18926,9 @@ record in the table has the same value as a new record on a unique index,
the old record is deleted before the new record is inserted.
@xref{INSERT, , @code{INSERT}}.
+In other words, you can't access the values of the old row from a
+@code{REPLACE} statement.
+
@findex LOAD DATA INFILE
@node LOAD DATA, UPDATE, REPLACE, Reference
@section @code{LOAD DATA INFILE} syntax
@@ -18953,7 +18968,7 @@ host to the server host. On the other hand, you do not need the
@strong{file} privilege to load local files.
@c old version
-If you are using @strong{MySQL} before 3.23.24 you can't read from a
+If you are using @strong{MySQL} before Version 3.23.24 you can't read from a
FIFO with @code{LOAD DATA INFILE}; If you need to read from a FIFO (for
example the output from gunzip), use @code{LOAD DATA LOCAL INFILE}
instead.
@@ -19218,7 +19233,7 @@ the list just given.
For input, if the @code{FIELDS ESCAPED BY} character is not empty, occurrences
of that character are stripped and the following character is taken literally
as part of a field value. The exceptions are an escaped @samp{0} or
-@samp{N} (e.g., @code{\0} or @code{\N} if the escape character is
+@samp{N} (for example, @code{\0} or @code{\N} if the escape character is
@samp{\}). These sequences are interpreted as ASCII @code{0} (a zero-valued
byte) and @code{NULL}. See below for the rules on @code{NULL} handling.
@@ -19433,8 +19448,8 @@ In @strong{MySQL} 3.22 or later, the C API function @code{mysql_info()}
returns the number of rows that were matched and updated and the number of
warnings that occurred during the @code{UPDATE}.
-In @strong{MySQL} 3.23 you can use @code{LIMIT #} to ensure that only a given
-number of rows are changed.
+In @strong{MySQL} Version 3.23 you can use @code{LIMIT #} to ensure that
+only a given number of rows are changed.
@findex USE
@node USE, FLUSH, UPDATE, Reference
@@ -19572,7 +19587,7 @@ or SHOW CREATE TABLE table_name
@code{SHOW} provides information about databases, tables, columns or
status information about the server. If the @code{LIKE wild} part is
used, the @code{wild} string can be a string that uses the SQL @samp{%}
-and @samp{_} wild card characters.
+and @samp{_} wild-card characters.
@findex SHOW DATABASES
@findex SHOW TABLES
@@ -19738,8 +19753,8 @@ The status variables listed above have the following meaning:
@item @strong{Variable} @tab @strong{Meaning}
@item @code{Aborted_clients} @tab Number of connections that has been aborted because the client has died without closing the connection properly.
@item @code{Aborted_connects} @tab Number of tries to connect to the @strong{MySQL} server that has failed.
-@item @code{Bytes_received} @tab Number of bytes received from the client
-@item @code{Bytes_sent} @tab Number of bytes received from the client
+@item @code{Bytes_received} @tab Number of bytes received from all clients
+@item @code{Bytes_sent} @tab Number of bytes sent to all clients
@item @code{Connections} @tab Number of connection attempts to the @strong{MySQL} server.
@item @code{Created_tmp_disk_tables} @tab Number of implicit temporary tables on disk that have been created while executing statements.
@item @code{Created_tmp_tables} @tab Number of implicit temporary tables in memory that have been created while executing statements.
@@ -19916,11 +19931,17 @@ call should have more details. Check your OS documentation for the
maximum value for this variable. Attempting to set @code{back_log}
higher than your operating system limit will be ineffective.
+@item @code{basedir}
+The value of the @code{--basedir} option.
+
@item @code{bdb_cache_size}
The buffer that is allocated to cache index and rows for @code{BDB} tables.
If you don't use @code{BDB} tables, you should set this to 0 or
start @code{mysqld} with @code{--skip-bdb} o not waste memory for this cache.
+@item @code{bdb_home}
+The value of the @code{--bdb-home} option.
+
@item @code{bdb_lock_max}
The maximum number of locks (1000 by default) you can have active on a BDB
table. You should increase this if you get errors of type
@@ -19928,6 +19949,18 @@ table. You should increase this if you get errors of type
transactions or when mysqld has to examine a lot of rows to calculate
the query.
+@item @code{bdb_logdir}
+The value of the @code{--bdb-logdir} option.
+
+@item @code{bdb_tmpdir}
+The value of the @code{--bdb-tmpdir} option.
+
+@item @code{character_set}
+The default character set.
+
+@item @code{character_sets}
+The supported character sets.
+
@item @code{concurrent_inserts}
If @code{ON} (the default), @strong{MySQL} will allow you to use @code{INSERT}
on @code{MyISAM} tables at the same time as you run @code{SELECT} queries
@@ -19938,14 +19971,8 @@ or @code{--skip-new}.
The number of seconds the @code{mysqld} server is waiting for a connect
packet before responding with @code{Bad handshake}.
-@item @code{delayed_insert_timeout}
-How long a @code{INSERT DELAYED} thread should wait for @code{INSERT}
-statements before terminating.
-
-@item @code{delayed_insert_limit}
-After inserting @code{delayed_insert_limit} rows, the @code{INSERT
-DELAYED} handler will check if there are any @code{SELECT} statements
-pending. If so, it allows these to execute before continuing.
+@item @code{datadir}
+The value of the @code{--datadir} option.
@item @code{delay_key_write}
If enabled (is on by default), @strong{MySQL} will honor the
@@ -19959,14 +19986,22 @@ option this means that all tables will be treated as if they were
created with the @code{delay_key_write} option. You can clear this flag
by starting @code{mysqld} with @code{--skip-new} or @code{--safe-mode}.
+@item @code{delayed_insert_limit}
+After inserting @code{delayed_insert_limit} rows, the @code{INSERT
+DELAYED} handler will check if there are any @code{SELECT} statements
+pending. If so, it allows these to execute before continuing.
+
+@item @code{delayed_insert_timeout}
+How long a @code{INSERT DELAYED} thread should wait for @code{INSERT}
+statements before terminating.
+
@item @code{delayed_queue_size}
What size queue (in rows) should be allocated for handling @code{INSERT
DELAYED}. If the queue becomes full, any client that does @code{INSERT
DELAYED} will wait until there is room in the queue again.
@item @code{flush}
-This is @code{ON} if you have started @strong{MySQL} with the @code{--flush}
-option.
+This is @code{ON} if you started @code{mysqld} with @code{--flush}.
@item @code{flush_time}
If this is set to a non-zero value, then every @code{flush_time} seconds all
@@ -20019,14 +20054,35 @@ using @code{delay_key_write}. @xref{SHOW}.
To get even more speed when writing many rows at the same time use
@code{LOCK TABLES}. @xref{LOCK TABLES, , @code{LOCK TABLES}}.
-@item @code{lower_case_table_names}
-Change all table names to lower case on disk.
+@item @code{language}
+The language used for error messages.
+
+@item @code{large_file_support}
+If @code{mysqld} was compiled with options for big file support.
+
+@item @code{locked_in_memory}
+If @code{mysqld} was locked in memory with @code{--memlock}
+
+@item @code{log}
+If logging of all queries is enabled.
+
+@item @code{log_update}
+If the update log is enabled.
+
+@item @code{log_bin}
+If the binary log is enabled.
+
+@item @code{log_slave_updates}
+If the updates from the slave should be logged.
@item @code{long_query_time}
If a query takes longer than this (in seconds), the @code{Slow_queries} counter
will be incremented. If you are using @code{--log-slow-queries}, the query
will be logged to the slow query logfile. @xref{Slow query log}.
+@item @code{lower_case_table_names}
+Table names are stored in lower case on disk.
+
@item @code{max_allowed_packet}
The maximum size of one packet. The message buffer is initialized to
@code{net_buffer_length} bytes, but can grow up to @code{max_allowed_packet}
@@ -20051,15 +20107,15 @@ statements. If you try to insert data into a new table after all @code{INSERT
DELAYED} threads are in use, the row will be inserted as if the
@code{DELAYED} attribute wasn't specified.
+@item @code{max_heap_table_size}
+Don't allow creation of heap tables bigger than this.
+
@item @code{max_join_size}
Joins that are probably going to read more than @code{max_join_size}
records return an error. Set this value if your users tend to perform joins
without a @code{WHERE} clause that take a long time and return
millions of rows.
-@item @code{max_heap_table_size}
-Don't allow creation of heap tables bigger than this.
-
@item @code{max_sort_length}
The number of bytes to use when sorting @code{BLOB} or @code{TEXT}
values (only the first @code{max_sort_length} bytes of each value
@@ -20072,6 +20128,9 @@ Maximum number of temporary tables a client can keep open at the same time.
@item @code{max_write_lock_count}
After this many write locks, allow some read locks to run in between.
+@item @code{myisam_recover_options}
+The value of the @code{--myisam-recover} option.
+
@item @code{myisam_sort_buffer_size}
The buffer that is allocated when sorting the index when doing a
@code{REPAIR} or when creating indexes with @code{CREATE INDEX} or
@@ -20084,20 +20143,29 @@ can set it to the expected size of a query. (That is, the expected length of
SQL statements sent by clients. If statements exceed this length, the buffer
is automatically enlarged, up to @code{max_allowed_packet} bytes.)
-@item @code{net_retry_count}
-If a read on a communication port is interrupted, retry this many times
-before giving up. This value should be quite high on @code{FreeBSD} as
-internal interrupts is sent to all threads.
-
@item @code{net_read_timeout}
Number of seconds to wait for more data from a connection before aborting
the read. Note that when we don't expect data from a connection, the timeout
is defined by @code{write_timeout}.
+@item @code{net_retry_count}
+If a read on a communication port is interrupted, retry this many times
+before giving up. This value should be quite high on @code{FreeBSD} as
+internal interrupts is sent to all threads.
+
@item @code{net_write_timeout}
Number of seconds to wait for a block to be written to a connection before
aborting the write.
+@item @code{pid_file}
+The value of the @code{--pid-file} option.
+
+@item @code{port}
+The value of the @code{--port} option.
+
+@item @code{protocol_version}
+The protocol version used by the @code{MySQL} server.
+
@item @code{record_buffer}
Each thread that does a sequential scan allocates a buffer of this
size for each table it scans. If you do many sequential scans, you may
@@ -20107,6 +20175,15 @@ want to increase this value.
The initial allocation of the query buffer. If most of your queries are
long (like when inserting blobs), you should increase this!
+@item @code{server_id}
+The value of the @code{--server-id} option.
+
+@item @code{skip_locking}
+Is OFF if @code{mysqld} uses external locking.
+
+@item @code{skip_networking}
+Is ON if we only allow local (socket) connections.
+
@item @code{skip_show_databases}
This prevents people from doing @code{SHOW DATABASES}, if they don't
have the @code{PROCESS_PRIV} privilege. This can improve security if
@@ -20117,6 +20194,9 @@ tables other users have.
If the creating of the thread longer than this (in seconds), the
@code{Slow_launch_threads} counter will be incremented.
+@item @code{socket}
+The unix socket used by the server.
+
@item @code{sort_buffer}
Each thread that needs to do a sort allocates a buffer of this
size. Increase this value for faster @code{ORDER BY} or @code{GROUP BY}
@@ -20140,6 +20220,9 @@ connections, fail to perform queries, and be very unreliable.
For information about how the table cache works, see @ref{Table cache}.
+@item @code{table_type}
+The default table type
+
@item @code{thread_cache_size}
How many threads we should keep keep in a cache for reuse. When a
client disconnects the clients threads is put in the cache if there
@@ -20161,12 +20244,21 @@ The stack size for each thread. Many of the limits detected by the
@code{crash-me} test are dependent on this value. The default is
large enough for normal operation. @xref{Benchmarks}.
+@item @code{timezone}
+The timezone for the server.
+
@item @code{tmp_table_size}
If an in-memory temporary table exceeds this size, @strong{MySQL}
will automatically convert it to an on-disk @code{MyISAM} table.
Increase the value of @code{tmp_table_size} if you do many advanced
@code{GROUP BY} queries and you have lots of memory.
+@item @code{tmpdir}
+The directory used for temporary files and temporary tables.
+
+@item @code{version}
+The version number for the server.
+
@item @code{wait_timeout}
The number of seconds the server waits for activity on a connection before
closing it. See also @code{interactive_timeout}.
@@ -20186,7 +20278,7 @@ information of how to tune the above variables. @xref{Server parameters}.
also get this information using the @code{mysqladmin processlist}
command. If you have the @strong{process} privilege, you can see all
threads. Otherwise, you can see only your own threads. @xref{KILL, ,
-@code{KILL}}. If you don't use the the @code{FULL} option, then only
+@code{KILL}}. If you don't use the @code{FULL} option, then only
the first 100 characters of each query will be shown.
@cindex privileges, display
@@ -20341,7 +20433,7 @@ BY} on.
@item Where used
A @code{WHERE} clause will be used to restrict which rows will be
matched against the next table or sent to the client. If you don't have
-this information and the the table is of type @code{ALL} or @code{index}
+this information and the table is of type @code{ALL} or @code{index}
you may have something wrong in your query (if you don't intend to
fetch/examine all rows from the table).
@end table
@@ -20569,7 +20661,7 @@ the @code{FROM} clause.
@code{DESCRIBE} provides information about a table's columns. @code{col_name}
may be a column name or a string containing the SQL @samp{%} and @samp{_}
-wild card characters.
+wild-card characters.
If the column types are different than you expect them to be based on a
@code{CREATE TABLE} statement, note that @strong{MySQL} sometimes
@@ -20948,8 +21040,8 @@ In order to accommodate granting rights to users from arbitrary hosts,
@strong{MySQL} supports specifying the @code{user_name} value in the form
@code{user@@host}. If you want to specify a @code{user} string
containing special characters (such as @samp{-}), or a @code{host} string
-containing special characters or wild card characters (such as @samp{%}), you
-can quote the user or host name (e.g., @code{'test-user'@@'test-hostname'}).
+containing special characters or wild-card characters (such as @samp{%}), you
+can quote the user or host name (for example, @code{'test-user'@@'test-hostname'}).
You can specify wild cards in the hostname. For example,
@code{user@@"%.loc.gov"} applies to @code{user} for any host in the
@@ -21018,7 +21110,7 @@ table is created if needed. When all privileges for the database have been
removed with @code{REVOKE}, this entry is deleted.
If a user doesn't have any privileges on a table, the table is not displayed
-when the user requests a list of tables (e.g., with a @code{SHOW TABLES}
+when the user requests a list of tables (for example, with a @code{SHOW TABLES}
statement).
The @code{WITH GRANT OPTION} clause gives the user the ability to give
@@ -21138,7 +21230,7 @@ operations!
Note that you can only add an index on a column that can have @code{NULL}
values or on a @code{BLOB}/@code{TEXT} column if you are using
-@strong{MySQL} version 3.23.2 or newer and are using the @code{MyISAM}
+@strong{MySQL} Version 3.23.2 or newer and are using the @code{MyISAM}
table type.
For more information about how @strong{MySQL} uses indexes, see
@@ -21146,7 +21238,7 @@ For more information about how @strong{MySQL} uses indexes, see
@code{FULLTEXT} indexes can index only @code{VARCHAR} and
@code{TEXT} columns, and only in @code{MyISAM} tables. @code{FULLTEXT} indexes
-are available in @strong{MySQL} 3.23.23 and later.
+are available in @strong{MySQL} Version 3.23.23 and later.
@ref{MySQL full-text search}.
@findex DROP INDEX
@@ -21231,7 +21323,7 @@ A user-definable function (UDF) is a way to extend @strong{MySQL} with a new
function that works like native (built in) @strong{MySQL} functions such as
@code{ABS()} and @code{CONCAT()}.
-@code{AGGREGATE} is a new option for @strong{MySQL} 3.23. An
+@code{AGGREGATE} is a new option for @strong{MySQL} Version 3.23. An
@code{AGGREGATE} function works exactly like a native @strong{MySQL}
@code{GROUP} function like @code{SUM} or @code{COUNT()}.
@@ -21375,7 +21467,7 @@ used them.
@node Table types, Tutorial, Reference, Top
@chapter MySQL table types
-As of @strong{MySQL} 3.23.6, you can choose between three basic
+As of @strong{MySQL} Version 3.23.6, you can choose between three basic
table formats. When you create a new table, you can tell @strong{MySQL}
which table type it should use for the table. @strong{MySQL} will
always create a @code{.frm} file to hold the table and column
@@ -21436,7 +21528,7 @@ of both worlds.
@node MyISAM, MERGE, Table types, Table types
@section MyISAM tables
-@code{MyISAM} is the default table type in @strong{MySQL} 3.23. It's
+@code{MyISAM} is the default table type in @strong{MySQL} Version 3.23. It's
based on the @code{ISAM} code and has a lot of useful extensions.
The index is stored in a file with the @code{.MYI} (MYIndex) extension
@@ -21782,7 +21874,7 @@ Can be uncompressed with @code{myisamchk}.
@node MERGE, ISAM, MyISAM, Table types
@section MERGE tables
-@code{MERGE} tables are new in @strong{MySQL} 3.23.25; The code is still
+@code{MERGE} tables are new in @strong{MySQL} Version 3.23.25; The code is still
in alpha, but should stabilize soon! The one thing that is currently
missing is a way from the SQL prompt to say which tables are part of the
@code{MERGE} table.
@@ -21999,8 +22091,8 @@ reused when you insert new data into the table.
You need enough extra memory for all HEAP tables that you want to use at
the same time.
@item
-To free memory, you should execute @code{DELETE FROM heap_table} or
-@code{DROP TABLE heap_table}.
+To free memory, you should execute @code{DELETE FROM heap_table},
+@code{TRUNCATE TABLE heap_table} or @code{DROP TABLE heap_table}.
@item
@strong{MySQL} cannot find out how approximately many rows there
are between two values (this is used by the range optimizer to decide which
@@ -22027,9 +22119,9 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
Berkeley DB (@uref{http://www.sleepycat.com}) has provided
@strong{MySQL} with a transaction safe table handler. This will survive
crashes and also provides @code{COMMIT} and @code{ROLLBACK} on
-transactions. In order to build MySQL 3.23.x (BDB support first appeared
-in 3.23.15) with support for @code{BDB} tables, you will need Berkeley
-DB 3.1.14 or newer which can be downloaded from
+transactions. In order to build MySQL Version 3.23.x (BDB support first
+appeared in Version 3.23.15) with support for @code{BDB} tables, you
+will need Berkeley DB 3.1.14 or newer which can be downloaded from
@uref{http://www.mysql.com/downloads/mysql-3.23.html}; or also from
Sleepycat's download page at
@uref{http://www.sleepycat.com/download.html}.
@@ -22098,7 +22190,7 @@ you. The hidden key has a length of 5 bytes and is incremented for each
insert attempt.
@item
If all columns you access in a @code{BDB} tables is part of the same index or
-part of the the primary key then @strong{MySQL} can execute the query
+part of the primary key then @strong{MySQL} can execute the query
without having to access the actual row. In a @code{MyISAM} table the
above holds only if the columns are part of the same index.
@item
@@ -22298,7 +22390,7 @@ This query illustrates several things about @code{mysql}:
@itemize @bullet
@item
-A command normally consists of a SQL statement followed by a semicolon.
+A command normally consists of an SQL statement followed by a semicolon.
(There are some exceptions where a semicolon is not needed. @code{QUIT},
mentioned earlier, is one of them. We'll get to others later.)
@@ -22604,7 +22696,7 @@ ORDER BY price DESC
LIMIT 1
@end example
-@strong{Note}: If there are several most expensive articles (e.g. each 19.95)
+@strong{Note}: If there are several most expensive articles (for example, each 19.95)
the @code{LIMIT} solution shows only one of them!
@node example-Maximum-column-group, example-Maximum-column-group-row, example-Maximum-row, Examples
@@ -22944,7 +23036,7 @@ Enter password: ********
Note that @code{menagerie} is not your password on the command just shown.
If you want to supply your password on the command line after the @code{-p}
-option, you must do so with no intervening space (e.g., as
+option, you must do so with no intervening space (for example, as
@code{-pmypassword}, not as @code{-p mypassword}). However, putting your
password on the command line is not recommended, because doing so exposes it
to snooping by other users logged in on your machine.
@@ -23815,7 +23907,7 @@ mysql> SELECT * FROM pet WHERE name REGEXP "[wW]";
Because a regular expression pattern matches if it occurs anywhere in the
value, it is not necessary in the previous query to put a wild card on either
side of the pattern to get it to match the entire value like it would be if
-you used a SQL pattern.
+you used an SQL pattern.
To find names containing exactly five characters, use @samp{^} and @samp{$}
to match the beginning and end of the name, and five instances of @samp{.}
@@ -24111,7 +24203,7 @@ each column reference is associated with.
What if you forget the name of a database or table, or what the structure of
-a given table is (e.g., what its columns are called)? @strong{MySQL}
+a given table is (for example, what its columns are called)? @strong{MySQL}
addresses this problem through several statements that provide information
about the databases and tables it supports.
@@ -24542,7 +24634,7 @@ default character set in use to the client. The client will switch to
use this character set for this connection.
One should use @code{mysql_real_escape_string()} when escaping strings
-for a SQL query. @code{mysql_real_escape_string()} is identical to the
+for an SQL query. @code{mysql_real_escape_string()} is identical to the
old @code{mysql_escape_string()} function, except that it takes the MYSQL
connection handle as the first parameter.
@@ -24732,8 +24824,8 @@ the size in bytes of the largest character in the set.
@section How big MySQL tables can be
@strong{MySQL} 3.22 has a 4G limit on table size. With the new
-@code{MyISAM} in @strong{MySQL} 3.23 the maximum table size is pushed up
-to 8 million terabytes (2 ^ 63 bytes).
+@code{MyISAM} in @strong{MySQL} Version 3.23 the maximum table size is
+pushed up to 8 million terabytes (2 ^ 63 bytes).
Note however that operating systems have their own file size
limits. Here are some examples:
@@ -24804,7 +24896,7 @@ sending a part of the non-updating queries to the replica server. Of
course this only works if non-updating queries dominate, but that is the
normal case.
-Starting in 3.23.15, @strong{MySQL} supports one-way replication
+Starting in Version 3.23.15, @strong{MySQL} supports one-way replication
internally. One server acts as the master, while the other acts as the
slave. Note that one server could play the roles of master in one pair
and slave in the other. The master server keeps a binary log of updates
@@ -24843,9 +24935,9 @@ system:
@itemize @bullet
@item
-Upgrade both slave and master to 3.23.15 or higher. We recommend that
+Upgrade both slave and master to Version 3.23.15 or higher. We recommend that
you always use the latest 3.23 version on both the slave and the
-master. While 3.23 is in beta, the versions may be not backwards
+master. While Version 3.23 is in beta, the versions may be not backwards
compatible. In addition, the newer version will fix some bugs and add
new features. Please, do not report bugs until you have verified that
the problem is present in the latest release.
@@ -24856,9 +24948,9 @@ only doing replication, you don't need to grant him other privileges.
@item
Take a snapshot of all the tables/databases on the master that could
possibly be involved in the update queries before taking the next step.
-Starting in version 3.23.21, there is a command that allows you to
+Starting in Version 3.23.21, there is a command that allows you to
take a snapshot of a table on the master and copy it to the slave, called
-@code{LOAD TABLE FROM MASTER}. Until 3.23.23, though, it has a serious
+@code{LOAD TABLE FROM MASTER}. Until Version 3.23.23, though, it has a serious
bug, and we recommend that you should not use it until you have upgraded .
@item
@@ -24879,7 +24971,7 @@ master-password=<replication user password>
replacting the values in <> with what is relevant to your system.
-Starting in version 3.23.26, you must also have on both master and
+Starting in Version 3.23.26, you must also have on both master and
slave
@example
@@ -24920,20 +25012,20 @@ Temporary tables will not work if the table with the same name
now the only thing you can do is turn off logging of the trouble
queries with @code{SET SQL_LOG_BIN=0}
@item
-Starting in 3.23.26, it is safe to connect servers in a circular
+Starting in Version 3.23.26, it is safe to connect servers in a circular
master-slave relationship with @code{log-slave-updates} enabled.
Note, however, that many queries will not work right in this kind of
setup unless your client code is written to take care of the potential
problems that can happen from updates that occur in different sequence
-on different servers. Note that the log format has changed in 3.23.26
+on different servers. Note that the log format has changed in Version 3.23.26
so that pre-3.23.26 slaves will not be able to read it.
@item
If the query on the slave gets an error, the slave thread will
terminate, and a message will appear in @code{.err} file. You should
then connect to the slave manually, fix the cause of the error
(eg. non-existent table), and then run @code{SLAVE START} sql command (
-available starting in 3.23.16, in 3.23.15 you will have to restart the
-server).
+available starting in Version 3.23.16, in Version, 3.23.15 you will have
+to restart the server).
@item
If connection to the master is lost, the slave will retry immediately,
and then in case of failure every @code{master-connect-retry} (default
@@ -24949,174 +25041,157 @@ tolerance will be greatly increased if you have a good UPS.
If the master is listening on a non-standard port, you will also need to
specify this with @code{master-port} parameter in @code{my.cnf} .
@item
-In 3.23.15,all of the tables and databases will be replicated. Starting
-in 3.23.16, you can restrict replication to a set of databases with
-@code{replicate-do-db} directives in @code{my.cnf} or just excluse a set
-of databases with @code{replicate-ignore-db}. Note that up until
-3.23.23 there was a bug that did not properly deal with @code{LOAD DATA
-INFILE} if you did it in a database that was excluded from replication.
+In Version 3.23.15, all of the tables and databases will be
+replicated. Starting in Version 3.23.16, you can restrict replication to
+a set of databases with @code{replicate-do-db} directives in
+@code{my.cnf} or just excluse a set of databases with
+@code{replicate-ignore-db}. Note that up until Version 3.23.23 there was a bug
+that did not properly deal with @code{LOAD DATA INFILE} if you did it in
+a database that was excluded from replication.
@item
-Starting in 3.23.16, @code{SET SQL_LOG_BIN = 0} will turn off
+Starting in Version 3.23.16, @code{SET SQL_LOG_BIN = 0} will turn off
replication (binary) logging on the master, and @code{SET SQL_LOG_BIN =
1} will turn in back on - you must have the process privilege to do
this.
@item
-Starting in 3.23.19 you can clean up stale replication leftovers when
+Starting in Version 3.23.19 you can clean up stale replication leftovers when
something goes wrong and you want a clean start with @code{FLUSH MASTER}
-and @code{FLUSH SLAVE} commands. In 3.23.26 we have renamed them to
+and @code{FLUSH SLAVE} commands. In Version 3.23.26 we have renamed them to
@code{RESET MASTER} and @code{RESET SLAVE} respectively to clarify
what they do. The old @code{FLUSH} variants still work, though for
compatibility.
@item
-Starting in 3.23.21 you can use LOAD TABLE FROM MASTER for network
-backup and to set up replication initially.
+Starting in Version 3.23.21 you can use @code{LOAD TABLE FROM MASTER} for
+network backup and to set up replication initially.
@item
-Starting in 3.23.23, you can change masters with @code{CHANGE MASTER
-TO }
+Starting in Version 3.23.23, you can change masters with @code{CHANGE MASTER
+TO}.
@item
-Starting in 3.23.23, you tell the master that updates in certain
-databases should not be logged to the binary log with @code{binlog-ignore-db}
+Starting in Version 3.23.23, you tell the master that updates in certain
+databases should not be logged to the binary log with @code{binlog-ignore-db}.
@item
-Starting in 3.23.26, you can use @code{replicate-rewrite-db} to tell
+Starting in Version 3.23.26, you can use @code{replicate-rewrite-db} to tell
the slave to apply updates from one database on the master to the one
-with a different name on the slave
+with a different name on the slave.
@item
-Starting in 3.23.28, you can use @code{PURGE MASTER LOGS TO 'log-name'}
-to get rid of old logs while the slave is running
+Starting in Version 3.23.28, you can use @code{PURGE MASTER LOGS TO 'log-name'}
+to get rid of old logs while the slave is running.
@end itemize
@node Replication Options, Replication SQL, Replication Features, Replication
@section Replication Options in my.cnf
-The table below explains the replications options in @code{my.cnf} . All
-of the are available starting in 3.23.15 unless indicated otherwise.
+If you are using replication, we recommend you to use MySQL Version 3.23.27 or
+later.
+
+On both master and slave you need to use the @code{server-id} option.
+This sets an unique replication id. You should pick a unique value in the
+range between 1 to 2^32-1 for each master and slave.
+Example: @code{server-id=3}
+
+The following table has the options you can use for the @strong{MASTER}:
@multitable @columnfractions .3 .7
@item @strong{Option} @tab @strong{Description}
-@item
-@code{log-bin}
- @tab Should be set on the master. Tells it to keep a binary update log.
-If a parameter is specified, the log will be written to the specified
-location. Note that if you give it a parameter with an extention
-(eg. @code{log-bin=/mysql/logs/replication.log} ) versions up to
-3.23.24 will not work right during replication if you do
-@code{FLUSH LOGS} . The problem is fixed
-in 3.23.25. If you are using this kind of log name, @code{FLUSH LOGS}
-will be ignored on binlog. To clear the log, run @code{FLUSH MASTER},
-and do not forget to run @code{FLUSH SLAVE} on all slaves. In 3.23.26
-and later versions you should use @code{RESET MASTER} and @code{RESET
-SLAVE}
-
-@item
-@code{log-bin-index}
- @tab Because the user could issue @code{FLUSH LOGS} command, we need to
+@item @code{log-bin=filename} @tab
+Write to a binary update log to the specified location. Note that if you
+give it a parameter with an extension
+(eg. @code{log-bin=/mysql/logs/replication.log} ) versions up to 3.23.24
+will not work right during replication if you do @code{FLUSH LOGS} . The
+problem is fixed in 3.23.25. If you are using this kind of log name,
+@code{FLUSH LOGS} will be ignored on binlog. To clear the log, run
+@code{FLUSH MASTER}, and do not forget to run @code{FLUSH SLAVE} on all
+slaves. In 3.23.26 and later versions you should use @code{RESET MASTER}
+and @code{RESET SLAVE}
+
+@item @code{log-bin-index=filename} @tab
+Because the user could issue @code{FLUSH LOGS} command, we need to
know which log is currently active and which ones have been rotated out
and it what sequence. This info is stored in the binary log index file.
-The default is `hostname`.index . You can use this option
-if you want to be a rebel.
-(Set on @strong{Master}, Example: @code{log-bin-index=db.index})
+The default is `hostname`.index . You can use this option if you want to
+be a rebel. (Example: @code{log-bin-index=db.index})
-@item
-@code{master-host}
- @tab Master hostname or IP address for replication. If not set, the slave
-thread will not be started.
-(Set on @strong{Slave}, Example: @code{master-host=db-master.mycompany.com})
+@item @code{sql-bin-update-same} @tab
+If set, setting @code{SQL_LOG_BIN} to a value will automatically set
+@code{SQL_LOG_UPDATE} to the same value and vice versa.
-@item
-@code{master-user}
- @tab The user the slave thread will authenticate as when connecting to
-the master. The user must have @code{FILE} privilige. If the master user
-is not set, user @code{test} is assumed.
-(Set on @strong{Slave}, Example: @code{master-user=scott})
+@item @code{binlog-do-db=database_name} @tab
+Tells the master it should log updates for the specified database, and
+exclude all others not explicitly mentioned.
+(Example: @code{binlog-do-db=some_database})
-@item
-@code{master-password}
- @tab The password the slave thread will authenticate with when connecting
-to the master. If not set, empty password is assumed
-(Set on @strong{Slave}, Example: @code{master-password=tiger})
+@item @code{binlog-ignore-db=database_name} @tab
+Tells the master that updates to the given database should not be logged
+to the binary log (Example: @code{binlog-ignore-db=some_database})
+@end multitable
-@item
-@code{master-port}
- @tab The port the master is listening on. If not set, the compiled setting
-of @code{MYSQL_PORT} is assumed. If you have not tinkered with @code{configure}
-options, this should be 3306.
-(Set on @strong{Slave}, Example: @code{master-port=3306})
+The following table has the options you can use for the @strong{SLAVE}:
-@item
-@code{master-connect-retry}
- @tab The number of seconds the slave thread will sleep before retrying to
-connect to the master in case the master goes down or the connection is lost.
-Default is 60.
-(Set on @strong{Slave}, Example: @code{master-connect-retry=60})
+@multitable @columnfractions .3 .7
-@item
-@code{master-info-file}
- @tab The location of the file that remembers where we left off on the master
+@item @strong{Option} @tab @strong{Description}
+@item @code{master-host=host} @tab
+Master hostname or IP address for replication. If not set, the slave
+thread will not be started.
+(Example: @code{master-host=db-master.mycompany.com})
+
+@item @code{master-user=username} @tab
+The user the slave thread will us for authentication when connecting to
+the master. The user must have @code{FILE} privilege. If the master user
+is not set, user @code{test} is assumed. (Example:
+@code{master-user=scott})
+
+@item @code{master-password=password} @tab
+The password the slave thread will authenticate with when connecting to
+the master. If not set, an empty password is assumed (Example:
+@code{master-password=tiger})
+
+@item @code{master-port=portnumber} @tab
+The port the master is listening on. If not set, the compiled setting of
+@code{MYSQL_PORT} is assumed. If you have not tinkered with
+@code{configure} options, this should be 3306. (Example:
+@code{master-port=3306})
+
+@item @code{master-connect-retry=seconds} @tab
+The number of seconds the slave thread will sleep before retrying to
+connect to the master in case the master goes down or the connection is
+lost. Default is 60. (Example: @code{master-connect-retry=60})
+
+@item @code{master-info-file=filename} @tab
+The location of the file that remembers where we left off on the master
during the replication process. The default is master.info in the data
directory. Sasha: The only reason I see for ever changing the default
-is the desire to be rebelious.
-(Set on @strong{Slave}, Example: @code{master-info-file=master.info})
-
-@item
-@code{replicate-do-db}
- @tab Tells the slave thread to restrict replication to the specified database.
-To specify more than one database, use the directive multiple times, once for
-each database. Note that this will only work if you do not use cross-database
-queries such as @code{UPDATE some_db.some_table SET foo='bar'} while having
-selected a different or no database.
-(Set on @strong{Slave}, Example: @code{replicate-do-db=some_db})
-
-@item
-@code{replicate-ignore-db}
- @tab Tells the slave thread to not replicate to the specified database. To
-specify more than one database to ignore, use the directive multiple times,
-once for each database. You must not use cross database updates for this
-option.
-(Set on @strong{Slave}, Example: @code{replicate-ignore-db=some_db})
-
-@item
-@code{sql-bin-update-same}
- @tab If set, setting @code{SQL_LOG_BIN} to a value will automatically set
-@code{SQL_LOG_UPDATE} to the same value and vice versa.
-(Set on @strong{Master}, Example: @code{sql-bin-update-same})
-
-@item
-@code{log-slave-updates}
- @tab Tells the slave to log the updates from the slave thread to the binary
-log. Off by default. You will need to turn it on if you plan to daisy-chain
-the slaves
-(Set on @strong{Slave}, Example: @code{log-slave-updates})
-
-@item
-@code{binlog-do-db}
- @tab Tells the master it should log updates for the specified database, and
-exclude all others not explicitly mentioned.
-(Set on @strong{Master}, Example: @code{binlog-do-db=some_database})
-
-@item
-@code{binlog-ignore-db}
- @tab Tells the master that updates to the given database should not be logged
-to the binary log
-(Set on @strong{Master}, Example: @code{binlog-ignore-db=some_database})
-
-@item
-@code{replicate-rewrite-db}
- @tab Tells the slave to apply updates to a database with a different
-name than the original ( Set on @strong{Slave}, Example:
+is the desire to be rebelious. (Example:
+@code{master-info-file=master.info})
+
+@item @code{replicate-do-db=database_name} @tab
+Tells the slave thread to restrict replication to the specified database.
+To specify more than one database, use the directive multiple times,
+once for each database. Note that this will only work if you do not use
+cross-database queries such as @code{UPDATE some_db.some_table SET
+foo='bar'} while having selected a different or no database.
+(Example: @code{replicate-do-db=some_db})
+
+@item @code{replicate-ignore-db=database_name} @tab
+Tells the slave thread to not replicate to the specified database. To
+specify more than one database to ignore, use the directive multiple
+times, once for each database. This option will not work if you use cross
+database updates. (Example: @code{replicate-ignore-db=some_db})
+
+@item @code{log-slave-updates} @tab
+Tells the slave to log the updates from the slave thread to the binary
+log. Off by default. You will need to turn it on if you plan to
+daisy-chain the slaves.
+
+@item @code{replicate-rewrite-db=from_name->to_name} @tab
+Updates to a database with a different name than the original (Example:
@code{replicate-rewrite-db=master_db_name->slave_db_name}
-@item
-@code{skip-slave-start}
- @tab Tells the slave server not to start the slave on the startup.
-The user can start it later with @code{SLAVE START}
-
-@item
-@code{server-id}
- @tab Sets the unique replicaiton numeric server id. You should pick one to assign.
-The range is from 1 to 2^32-1. (Set on both @strong{Master} and
-@strong{Slave}. Example: @code{server-id=3})
+@item @code{skip-slave-start} @tab
+Tells the slave server not to start the slave on the startup. The user
+can start it later with @code{SLAVE START}.
@end multitable
@cindex SQL commands, replication
@@ -25192,11 +25267,11 @@ command line. (Slave)
@item @code{SHOW SLAVE STATUS}
@tab Provides status info on essential parameters of the slave thread. (Slave)
@item @code{SHOW MASTER LOGS}
- @tab Only available starting in 3.23.28. Lists the binary logs on the master. You should use this command
+ @tab Only available starting in Version 3.23.28. Lists the binary logs on the master. You should use this command
prior to @code{PURGE MASTER LOGS TO} to find out how far you should go.
@item @code{PURGE MASTER LOGS TO 'logname'}
- @tab Available starting in 3.23.28. Deletes all the
+ @tab Available starting in Version 3.23.28. Deletes all the
replication logs that are listed in the log
index as being prior to the specified log, and removed them from the
log index, so that the given log now becomes first. Example:
@@ -25253,14 +25328,14 @@ it up from @code{pthread_cond_wait()}. In the meantime, the slave
could have opened another connection, which resulted in another
@code{Binlog_Dump} thread.
-The above problem should not be present in 3.23.26 and later versions.
-In 3.23.26 we added @code{server-id} to each replication server, and
+The above problem should not be present in Version 3.23.26 and later versions.
+In Version 3.23.26 we added @code{server-id} to each replication server, and
now all the old zombie threads are killed on the master when a new replication thread
connects from the same slave
@strong{Q}: How do I rotate replication logs?
-@strong{A}: In 3.23.28 you should use @code{PURGE MASTER LOGS TO}
+@strong{A}: In Version 3.23.28 you should use @code{PURGE MASTER LOGS TO}
command after determining which logs can be deleted, and optionally
backing them up first. In earlier versions the process is much more
painful, and cannot be safely done without stopping all the slaves in
@@ -25281,7 +25356,7 @@ all the updates, the slave will be able to catch up once it is up and
can connect.
We plan to make post 3.23.26 versions to be backwards compatible
-for replication down to 3.23.26, so upgrade should be just a matter
+for replication down to Version 3.23.26, so upgrade should be just a matter
of plug and play. Of course, as one joke goes, plug and play works
usually only 50% of the time - just the plug part. We hope to do much
better than that, though.
@@ -26178,7 +26253,7 @@ This can be done with the following code:
@example
mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> insert into real_table select * from insert_table;
-mysql> delete from insert_table;
+mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;
@end example
@@ -26206,7 +26281,7 @@ For @code{BDB} tables, @strong{MySQL} only uses table locking of you
explicitely lock the table with @code{LOCK TABLES} or execute an command that
will modify every row in the table, like @code{ALTER TABLE}.
-In @strong{MySQL} 3.23.7 and above, you can insert rows into
+In @strong{MySQL} Version 3.23.7 and above, you can insert rows into
@code{MyISAM} tables at the same time as other threads are reading from
the table. Note that currently this only works if there are no holes after
deleted rows in the table at the time the insert is made.
@@ -26224,7 +26299,7 @@ queries against a specific table. (You can change this by using
LOW_PRIORITY with the statement that does the update or
@code{HIGH_PRIORITY} with the @code{SELECT} statement.
-Starting from @strong{MySQL 3.23.7} one can use the
+Starting from @strong{MySQL Version 3.23.7} one can use the
@code{max_write_lock_count} variable to force @strong{MySQL} to
temporary give all @code{SELECT} statements, that waits for a table, a
higher priority after a specific number of inserts on a table.
@@ -26394,7 +26469,7 @@ SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10
@item
Sort or group a table if the sorting or grouping is done on a leftmost
-prefix of a usable key (e.g., @code{ORDER BY key_part_1,key_part_2 }). The
+prefix of a usable key (for example, @code{ORDER BY key_part_1,key_part_2 }). The
key is read in reverse order if all key parts are followed by @code{DESC}.
The index can also be used even if the @code{ORDER BY} doesn't match gthe index
@@ -26460,7 +26535,7 @@ leftmost prefixes of @code{(col1,col2,col3)}.
@cindex indexes, and @code{LIKE}
@cindex wildcards, and @code{LIKE}
@strong{MySQL} also uses indexes for @code{LIKE} comparisons if the argument
-to @code{LIKE} is a constant string that doesn't start with a wild card
+to @code{LIKE} is a constant string that doesn't start with a wild-card
character. For example, the following @code{SELECT} statements use indexes:
@example
@@ -26478,8 +26553,9 @@ mysql> select * from tbl_name where key_col LIKE "%Patrick%";
mysql> select * from tbl_name where key_col LIKE other_col;
@end example
-In the first statement, the @code{LIKE} value begins with a wildcard character.
-In the second statement, the @code{LIKE} value is not a constant.
+In the first statement, the @code{LIKE} value begins with a wild-card
+character. In the second statement, the @code{LIKE} value is not a
+constant.
@findex IS NULL, and indexes
@cindex indexes, and @code{IS NULL}
@@ -26489,7 +26565,7 @@ is an index.
@strong{MySQL} normally uses the index that finds least number of rows. An
index is used for columns that you compare with the following operators:
@code{=}, @code{>}, @code{>=}, @code{<}, @code{<=}, @code{BETWEEN} and a
-@code{LIKE} with a non-wildcard prefix like @code{'something%'}.
+@code{LIKE} with a non-wild-card prefix like @code{'something%'}.
Any index that doesn't span all @code{AND} levels in the @code{WHERE} clause
is not used to optimize the query. In other words: To be able to use an
@@ -27031,13 +27107,13 @@ it is very important to @code{OPTIMIZE TABLE} sometimes.
@node Delete speed, , Update speed, Query Speed
@subsection Speed of @code{DELETE} queries
+If you want to delete all rows in the table, you should use
+@code{TRUNCATE TABLE table_name}. @xref{TRUNCATE}.
+
The time to delete a record is exactly proportional to the number of
indexes. To delete records more quickly, you can increase the size of
the index cache. @xref{Server parameters}.
-It's also much faster to remove all rows than to remove a big part of the
-rows from a table.
-
@cindex optimization, tips
@cindex tips, optimization
@node Tips, Benchmarks, Query Speed, Performance
@@ -27068,7 +27144,7 @@ In some cases it may make sense to introduce a column that is 'hashed'
based on information from other columns. If this column is short and
reasonably unique it may be much faster than a big index on many
columns. In @strong{MySQL} its very easy to use this extra column:
-@code{SELECT * FROM table_name WHERE hash=MP5(concat(col1,col2))
+@code{SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2))
AND col_1='constant' AND col_2='constant'}
@item
For tables that changes a lot you should try to avoid all @code{VARCHAR}
@@ -27172,7 +27248,7 @@ information about the last shown banner for users that doesn't have
cookies).
@item
Columns with identical information in different tables should be
-declared identical and have identical names. Before version 3.23 you
+declared identical and have identical names. Before Version 3.23 you
got slow joins otherwise.
Try to keep the names simple (use @code{name} instead of
@@ -27397,7 +27473,7 @@ results. We would have used PHP or mod_perl instead but they were
not available at that time.
For graphical data we wrote a simple tool in @code{C} that can produce
-GIFs based on the result of a SQL query (with some processing of the
+GIFs based on the result of an SQL query (with some processing of the
result). This is also dynamically executed from the Perl script that
parses the @code{HTML} files.
@@ -27420,7 +27496,7 @@ our systems.
We are also experimenting with Intel-Linux to be able to get more CPU
power cheaper. Now that we have the binary portable database format (new
-in 3.23) we will start to use this for some parts of the application.
+in Version 3.23) we will start to use this for some parts of the application.
Our initial feelings are that Linux will perform much better on low to
medium load but Solaris will perform better when you start to get a
@@ -27506,6 +27582,7 @@ How big a @code{VARCHAR} column can be
@menu
* Programs:: What do the executables do?
+* safe_mysqld::
* mysql:: The command line tool
* mysqladmin:: Administering a @strong{MySQL} server
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
@@ -27516,7 +27593,7 @@ How big a @code{VARCHAR} column can be
@cindex environment variables
@cindex programs, list of
-@node Programs, mysql, Tools, Tools
+@node Programs, safe_mysqld, Tools, Tools
@section Overview of the different MySQL programs
All @strong{MySQL} clients that communicate with the server using the
@@ -27637,26 +27714,112 @@ swaps @code{a} and @code{b} in the given files:
@example
shell> replace a b b a -- file1 file2 ...
@end example
+@end table
+@cindex tools, safe_mysqld
+@cindex scripts
@cindex @code{safe_mysqld}
+@node safe_mysqld, mysql, Programs, Tools
+@section safe_mysqld, the wrapper around mysqld
+
+@code{safe_mysqld} is the recommended way to start a @code{mysqld}
+daemon on Unix. @code{safe_mysqld} adds some safety features such as
+restarting the server when an error occurs and logging runtime
+information to a log file.
+
+Normally one should never edit the @code{safe_mysqld} script, but
+instead put the options to @code{safe_mysqld} in the
+@code{[safe_mysqld]} section in the @code{my.cnf}
+file. @code{safe_mysqld} will read all options from the @code{[mysqld]}
+and @code{[safe_mysqld]} sections from the option files.
+@xref{Option files}.
+
+Note that all options on the command line to @code{safe_mysqld} are passed
+to @code{mysqld}. If you wants to use any options in @code{safe_mysqld} that
+@code{mysqld} doesn't support, you must specify these in the option file.
-@item safe_mysqld
-A script that starts the @code{mysqld} daemon with some safety features, such
-as restarting the server when an error occurs and logging runtime information
-to a log file.
+Most of the options to @code{safe_mysqld} are the same as the options to
+@code{mysqld}. @xref{Command-line options}.
+
+@code{safe_mysqld} supports the following options:
+
+@table @code
+@item --basedir=path
+@item --core-file-size=#
+@item --defaults-extra-file=path
+@item --defaults-file=path
+@item --open-files=#
+Size of the core file @code{mysqld} should be able to create. Passed to
+@code{ulimit -c}.
+@item --datadir=path
+@item --err-log=path
+@item --ledir=path
+Path to @code{mysqld}
+@item --log=path
+@item --no-defaults
+@item --open-files=#
+Number of files @code{mysqld} should be able to open. Passed to
+@code{ulimit -n}.
+@item --pid-file=path
+@item --port=#
+@item --socket=path
+@item --timezone=#
+Set the timezone (the @code{TZ}) variable to the value of this parameter.
+@item --user=#
@end table
+The @code{safe_mysqld} script is written so that it normally is able to start
+a server that was installed from either a source or a binary version of
+@strong{MySQL}, even if these install the server in slightly different
+locations. @code{safe_mysqld} expects one of these conditions to be true:
+
+@itemize @bullet
+@item
+The server and databases can be found relative to the directory from which
+@code{safe_mysqld} is invoked. @code{safe_mysqld} looks under its working
+directory for @file{bin} and @file{data} directories (for binary
+distributions) or for @file{libexec} and @file{var} directories (for source
+distributions). This condition should be met if you execute
+@code{safe_mysqld} from your @strong{MySQL} installation directory (for
+example, @file{/usr/local/mysql} for a binary distribution).
+
+@item
+If the server and databases cannot be found relative to the working directory,
+@code{safe_mysqld} attempts to locate them by absolute pathnames. Typical
+locations are @file{/usr/local/libexec} and @file{/usr/local/var}.
+The actual locations are determined when the distribution was built from which
+@code{safe_mysqld} comes. They should be correct if
+@strong{MySQL} was installed in a standard location.
+@end itemize
+
+Because @code{safe_mysqld} will try to find the server and databases relative
+to its own working directory, you can install a binary distribution of
+@strong{MySQL} anywhere, as long as you start @code{safe_mysqld} from the
+@strong{MySQL} installation directory:
+
+@example
+shell> cd mysql_installation_directory
+shell> bin/safe_mysqld &
+@end example
+
+If @code{safe_mysqld} fails, even when invoked from the @strong{MySQL}
+installation directory, you can modify it to use the path to @code{mysqld}
+and the pathname options that are correct for your system. Note that if you
+upgrade @strong{MySQL} in the future, your modified version of
+@code{safe_mysqld} will be overwritten, so you should make a copy of your
+edited version that you can reinstall.
+
@cindex command line tool
@cindex tools, command line
@cindex scripts
@cindex @code{mysql}
-@node mysql, mysqladmin, Programs, Tools
+@node mysql, mysqladmin, safe_mysqld, Tools
@section The command line tool
@code{mysql} is a simple SQL shell (with GNU @code{readline} capabilities).
It supports interactive and non-interactive use. When used interactively,
query results are presented in an ASCII-table format. When used
-non-interactively (e.g., as a filter), the result is presented in
+non-interactively (for example, as a filter), the result is presented in
tab-separated format. (The output format can be changed using command-line
options.) You can run scripts simply like this:
@@ -27670,7 +27833,7 @@ If you have problems due to insufficient memory in the client, use the
retrieve the result set.
Using @code{mysql} is very easy; Just start it as follows
-@code{mysql database} or @code{mysql --user=user_name --password=your_password database}. Type a SQL statement, end it with @samp{;}, @samp{\g} or @samp{\G}
+@code{mysql database} or @code{mysql --user=user_name --password=your_password database}. Type an SQL statement, end it with @samp{;}, @samp{\g} or @samp{\G}
and press return/enter.
@cindex command line options
@@ -27817,7 +27980,7 @@ ego (\G) Send command to mysql server; Display result vertically
print (\p) Print current command
quit (\q) Quit mysql
rehash (\#) Rebuild completion hash
-source (\.) Execute a SQL script file. Takes a file name as an argument
+source (\.) Execute an SQL script file. Takes a file name as an argument
status (\s) Get status information from the server
use (\u) Use another database. Takes database name as argument
@end example
@@ -27829,7 +27992,7 @@ connection and the server you are using. If you are running in the
the @code{mysql} variables that affects your queries.
@cindex @code{safe-mode} command
-A useful startup option for beginners (introduced in @strong{MySQL} 3.23.11) is
+A useful startup option for beginners (introduced in @strong{MySQL} Version 3.23.11) is
@code{--safe-mode} (or @code{--i-am-a-dummy} for users that has at some
time done a @code{DELETE FROM table_name} but forgot the @code{WHERE}
clause. When using this option, @code{mysql} sends the following
@@ -28018,7 +28181,7 @@ meaning as the corresponding clauses for @code{LOAD DATA INFILE}.
@item -F, --flush-logs
Flush log file in the @strong{MySQL} server before starting the dump.
@item -f, --force,
-Continue even if we get a SQL error during a table dump.
+Continue even if we get an SQL error during a table dump.
@item -h, --host=..
Dump data from the @strong{MySQL} server on the named host. The default host
is @code{localhost}.
@@ -28298,8 +28461,8 @@ are shown.
Note that in newer @strong{MySQL} versions you only see those
database/tables/columns for which you have some privileges.
-If the last argument contains a shell or SQL wildcard (@code{*}, @code{?},
-@code{%} or @code{_}) then only what's matched by the wildcard is shown.
+If the last argument contains a shell or SQL wild-card (@code{*}, @code{?},
+@code{%} or @code{_}) then only what's matched by the wild card is shown.
This may cause some confusion when you try to display the columns for a
table with a @code{_} as in this case @code{mysqlshow} only shows you
the table names that matches the pattern. This is easily fixed by
@@ -28706,7 +28869,7 @@ to start using the new table.
@node Table maintenance, Maintenance regimen, Maintenance, Maintenance
@section Using @code{myisamchk} for table maintenance and crash recovery
-Starting with @strong{MySQL} 3.23.13, you can check MyISAM tables with the
+Starting with @strong{MySQL} Version 3.23.13, you can check MyISAM tables with the
@code{CHECK TABLE} command. @xref{CHECK TABLE}. You can repair tables
with the @code{REPAIR TABLE} command. @xref{REPAIR TABLE}.
@@ -28777,7 +28940,7 @@ by specifying the path to the directory:
shell> myisamchk /path/to/database_dir/*.MYI
@end example
-You can even check all tables in all databases by specifying a wildcard
+You can even check all tables in all databases by specifying a wild card
with the path to the @strong{MySQL} data directory:
@example
@@ -28805,7 +28968,7 @@ the file or that has died without closing the file properly.
If you @code{mysqld} is running, you must force a sync/close of all
tables with @code{FLUSH TABLES} and ensure that no one is using the
-tables while you are running @code{myisamchk}. In MySQL 3.23 the easiest
+tables while you are running @code{myisamchk}. In MySQL Version 3.23 the easiest
way to avoid this problem is to use @code{CHECK TABLE} instead of
@code{myisamchk} to check tables.
@@ -29043,7 +29206,7 @@ If you have a problem with disk space during repair, you can try to use
@node Maintenance regimen, Table-info, Table maintenance, Maintenance
@section Setting up a table maintenance regimen
-Starting with @strong{MySQL} 3.23.13, you can check MyISAM tables with the
+Starting with @strong{MySQL} Version 3.23.13, you can check MyISAM tables with the
@code{CHECK TABLE} command. @xref{CHECK TABLE}. You can repair tables
with the @code{REPAIR TABLE} command. @xref{REPAIR TABLE}.
@@ -29578,7 +29741,7 @@ that @code{mysqld} runs as (and to you, because you need to access the files
you are checking). If it turns out you need to modify files, they must also
be writable by you.
-If you are using @strong{MySQL} 3.23.16 and above you can (and should) use the
+If you are using @strong{MySQL} Version 3.23.16 and above you can (and should) use the
@code{CHECK} and @code{REPAIR} commands to check and repair @code{MyISAM}
tables. @xref{CHECK TABLE}. @xref{REPAIR TABLE}.
@@ -29660,10 +29823,13 @@ Use the table description file to create new (empty) data and index files:
@example
shell> mysql db_name
mysql> SET AUTOCOMMIT=1;
-mysql> DELETE FROM tbl_name;
+mysql> TRUNCATE TABLE table_name;
mysql> quit
@end example
+If your SQL version doesn't have @code{TRUNCATE}, use @code{DELETE FROM
+table_name} instead.
+
@item
Copy the old data file back onto the newly created data file.
(Don't just move the old file back onto the new file; you want to retain
@@ -29837,7 +30003,7 @@ functions. Consult this file to see how UDF calling conventions work.
For each function that you want to use in SQL statements, you should define
corresponding C (or C++) functions. In the discussion below, the name
``xxx'' is used for an example function name. To distinquish between SQL and
-C/C++ usage, @code{XXX()} (uppercase) indicates a SQL function call, and
+C/C++ usage, @code{XXX()} (uppercase) indicates an SQL function call, and
@code{xxx()} (lowercase) indicates a C/C++ function call.
The C/C++ functions that you write to implement the inferface for
@@ -29881,7 +30047,7 @@ The deinitialization function for @code{xxx()}. It should deallocate any
memory allocated by the initialization function.
@end table
-When a SQL statement invokes @code{XXX()}, @strong{MySQL} calls the
+When an SQL statement invokes @code{XXX()}, @strong{MySQL} calls the
initialization function @code{xxx_init()} to let it perform any required
setup, such as argument checking or memory allocation. If @code{xxx_init()}
returns an error, the SQL statement is aborted with an error message and the
@@ -30245,7 +30411,7 @@ The procedure for adding a new native function is described below. Note that
you cannot add native functions to a binary distribution because the procedure
involves modifying @strong{MySQL} source code. You must compile
@strong{MySQL} yourself from a source distribution. Also note that if you
-migrate to another version of @strong{MySQL} (e.g., when a new version is
+migrate to another version of @strong{MySQL} (for example, when a new version is
released), you will need to repeat the procedure with the new version.
To add a new native @strong{MySQL} function, follow these steps:
@@ -30310,7 +30476,7 @@ In @strong{MySQL}, you can define a procedure in C++ that can access and
modify the data in a query before it is sent to the client. The modification
can be done on row by row or @code{GROUP BY} level.
-We have created an example procedure in @strong{MySQL} 3.23 to
+We have created an example procedure in @strong{MySQL} Version 3.23 to
show you what can be done.
@menu
@@ -30553,7 +30719,7 @@ Microsoft MDAC (@code{Microsoft Data Access Components}) from
@uref{http://www.microsoft.com/data}. This will fix the bug in Access
that when you export data to @strong{MySQL}, the table and column names
aren't specified. Another way to around this bug is to upgrade to
-MyODBC 2.50.33 and @strong{MySQL} 3.23.x, which together provides a
+MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together provides a
workaround for this bug!
Note that if you are using @strong{MySQL} 3.22, you must to apply the
@@ -31399,7 +31565,7 @@ shell> mysqladmin -h `hostname` version
@end example
@item Someone has removed the Unix socket that @code{mysqld} uses (default
@file{/tmp/mysqld.sock}). You might have a @code{cron} job that removes the
-@strong{MySQL} socket (e.g., a job that removes old files from the @file{/tmp}
+@strong{MySQL} socket (for example, a job that removes old files from the @file{/tmp}
directory). You can always run @code{mysqladmin version} and
check that the socket @code{mysqladmin} is trying to use really exists.
The fix in this case is to change the @code{cron} job to not remove
@@ -31588,7 +31754,7 @@ query. @xref{SET OPTION, , @code{SET OPTION}}.
You can also start @code{mysqld} with the @code{--big-tables} option.
This is exactly the same as using @code{SQL_BIG_TABLES} for all queries.
-In @strong{MySQL} 3.23 in-memory temporary tables will automaticly be
+In @strong{MySQL} Version 3.23 in-memory temporary tables will automatically be
converted to a disk based @code{MyISAM} table after the table size gets
bigger than @code{tmp_table_size}.
@@ -31942,7 +32108,7 @@ shell> /path/to/safe_mysqld &
@tindex Environment variable, UMASK_DIR
By default @strong{MySQL} will create database and @code{RAID}
directories with permission type 0700. You can modify this behaviour by
-setting the the @code{UMASK_DIR} variable. If you set this, new
+setting the @code{UMASK_DIR} variable. If you set this, new
directories are created with the combined @code{UMASK} and
@code{UMASK_DIR}. For example, if you want to give group access to
all new directories, you can do:
@@ -31953,7 +32119,7 @@ shell> export UMASK_DIR
shell> /path/to/safe_mysqld &
@end example
-In @strong{MySQL} 3.23.25 and above, @strong{MySQL} assumes that the
+In @strong{MySQL} Version 3.23.25 and above, @strong{MySQL} assumes that the
value for @code{UMASK} and @code{UMASK_DIR} is in octal if it starts
with a zero.
@@ -32393,7 +32559,7 @@ Drop or rename @code{old_table}
@section Database replication with update log
Now that master-slave internal replication is available starting in
-3.23.15, this is the recommended way. @xref{Replication}.
+Version 3.23.15, this is the recommended way. @xref{Replication}.
However, it is still possible to replicate a database by using the
update log. @xref{Update log}. This requires one database that acts as a
@@ -32439,7 +32605,7 @@ backup. To get a consistent backup, do a @code{LOCK TABLES} on the
relevant tables. @xref{LOCK TABLES, , @code{LOCK TABLES}}. You only need a
read lock; this allows other threads to continue to query the tables while
you are making a copy of the files in the database directory. If you want to
-make a SQL level backup of a table, you can use @code{SELECT INTO OUTFILE}.
+make an SQL level backup of a table, you can use @code{SELECT INTO OUTFILE}.
Another way to backup a database is to use the @code{mysqldump} program:
@xref{mysqldump}.
@@ -32644,7 +32810,7 @@ something like this:
@example
shell> ./configure --with-tcp-port=port_number \
- --with-unix-socket=file_name \
+ --with-unix-socket-path=file_name \
--prefix=/usr/local/mysql-3.22.9
@end example
@@ -33011,11 +33177,11 @@ Returns the error number for the most recently invoked @strong{MySQL} function.
Returns the error message for the most recently invoked @strong{MySQL} function.
@item @strong{mysql_real_escape_string()} @tab
-Escapes special characters in a string for use in a SQL statement taking
+Escapes special characters in a string for use in an SQL statement taking
into account the current charset of the connection.
@item @strong{mysql_escape_string()} @tab
-Escapes special characters in a string for use in a SQL statement.
+Escapes special characters in a string for use in an SQL statement.
@item @strong{mysql_fetch_field()} @tab
Returns the type of the next table field.
@@ -33096,13 +33262,13 @@ Checks whether or not the connection to the server is working, reconnecting
as necessary.
@item @strong{mysql_query()} @tab
-Executes a SQL query specified as a null-terminated string.
+Executes an SQL query specified as a null-terminated string.
@item @strong{mysql_real_connect()} @tab
Connects to a @strong{MySQL} server.
@item @strong{mysql_real_query()} @tab
-Executes a SQL query specified as a counted string.
+Executes an SQL query specified as a counted string.
@item @strong{mysql_reload()} @tab
Tells the server to reload the grant tables.
@@ -33159,7 +33325,7 @@ specified as a null-terminated string whereas @code{mysql_real_query()}
expects a counted string. If the string contains binary data (which may
include null bytes), you must use @code{mysql_real_query()}.
-For each non-@code{SELECT} query (e.g., @code{INSERT}, @code{UPDATE},
+For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE},
@code{DELETE}), you can find out how many rows were affected (changed)
by calling @code{mysql_affected_rows()}.
@@ -33447,7 +33613,7 @@ become the default (current) database on the connection specified by
@code{mysql}. In subsequent queries, this database is the default for
table references that do not include an explicit database specifier.
-This function was introduced in @strong{MySQL} 3.23.3.
+This function was introduced in @strong{MySQL} Version 3.23.3.
@code{mysql_change_user()} fails unless the connected user can be
authenticated or if he doesn't have permission to use the database. In
@@ -33523,7 +33689,7 @@ None.
Creates the database named by the @code{db} parameter.
This function is deprecated. It is preferable to use @code{mysql_query()}
-to issue a SQL @code{CREATE DATABASE} statement instead.
+to issue an SQL @code{CREATE DATABASE} statement instead.
@subsubheading Return values
@@ -33616,7 +33782,7 @@ mysql_debug("d:t:O,/tmp/client.trace");
Drops the database named by the @code{db} parameter.
This function is deprecated. It is preferable to use @code{mysql_query()}
-to issue a SQL @code{DROP DATABASE} statement instead.
+to issue an SQL @code{DROP DATABASE} statement instead.
@subsubheading Return values
@@ -34379,7 +34545,7 @@ An unknown error occurred.
Returns a result set consisting of database names on the server that match
the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all databases. Calling
@code{mysql_list_dbs()} is similar to executing the query @code{SHOW
databases [LIKE wild]}.
@@ -34415,7 +34581,7 @@ An unknown error occurred.
Returns a result set consisting of field names in the given table that match
the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all fields. Calling
@code{mysql_list_fields()} is similar to executing the query @code{SHOW
COLUMNS FROM tbl_name [LIKE wild]}.
@@ -34483,7 +34649,7 @@ An unknown error occurred.
Returns a result set consisting of table names in the current database that
match the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all tables. Calling
@code{mysql_list_tables()} is similar to executing the query @code{SHOW
tables [LIKE wild]}.
@@ -34655,7 +34821,9 @@ The specified group in the option file may contain the following options:
@item @code{port} @tab Default port number.
@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}.
@item @code{socket} @tab Default socket number.
-@item @code{timeout} @tab Connect timeout in seconds.
+@item
+@code{timeout} @tab Connect timeout in seconds. On Linux this timeout also
+is used for waiting for the first answer from the server.
@item @code{user} @tab Default user.
@end multitable
@@ -34865,14 +35033,20 @@ client library that uses a different protocol version. This can happen if you
use a very old client library to connect to a new server that wasn't started
with the @code{--old-protocol} option.
-@item CR_NAMEDPIPEOPEN_ERROR;
+@item CR_NAMEDPIPEOPEN_ERROR
Failed to create a named pipe on Windows.
-@item CR_NAMEDPIPEWAIT_ERROR;
+@item CR_NAMEDPIPEWAIT_ERROR
Failed to wait for a named pipe on Windows.
-@item CR_NAMEDPIPESETSTATE_ERROR;
+@item CR_NAMEDPIPESETSTATE_ERROR
Failed to get a pipe handler on Windows.
+
+@item CR_SERVER_LOST
+If @code{timeout} > 0 and it took longer then @code{timeout} seconds to
+connect to the server or if the server died while executing the
+@code{init-command}.
+
@end table
@subsubheading Example
@@ -34909,7 +35083,7 @@ try reconnecting to the server before giving up.
Encodes the string in @code{from} to an escaped SQL string, taking into
account the current charset of the connection, that can be sent to the
-server in a SQL statement, places the result in @code{to}, and adds a
+server in an SQL statement, places the result in @code{to}, and adds a
terminating null byte. Characters encoded are @code{NUL} (ASCII 0),
@samp{\n}, @samp{\r}, @samp{\}, @samp{'}, @samp{"} and Control-Z
(@pxref{Literals}).
@@ -35008,7 +35182,7 @@ Asks the @strong{MySQL} server to reload the grant tables. The
connected user must have the @strong{reload} privilege.
This function is deprecated. It is preferable to use @code{mysql_query()}
-to issue a SQL @code{FLUSH PRIVILEGES} statement instead.
+to issue an SQL @code{FLUSH PRIVILEGES} statement instead.
@subsubheading Return values
@@ -35333,7 +35507,7 @@ large).
The data couldn't be read (an error occurred on the connection).
@item
-The query returned no data (e.g., it was an @code{INSERT}, @code{UPDATE}
+The query returned no data (for example, it was an @code{INSERT}, @code{UPDATE}
or @code{DELETE}).
@end itemize
@@ -35578,9 +35752,9 @@ Installation instructions for @strong{MySQL} Perl support are given in
@multitable @columnfractions .3 .7
@item @code{connect} @tab Establishes a connection to a database server.
@item @code{disconnect} @tab Disconnects from the database server.
-@item @code{prepare} @tab Prepares a SQL statement for execution.
+@item @code{prepare} @tab Prepares an SQL statement for execution.
@item @code{execute} @tab Executes prepared statements.
-@item @code{do} @tab Prepares and executes a SQL statement.
+@item @code{do} @tab Prepares and executes an SQL statement.
@item @code{quote} @tab Quotes string or @code{BLOB} values to be inserted.
@item @code{fetchrow_array} @tab Fetches the next row as an array of fields.
@item @code{fetchrow_arrayref} @tab Fetches next row as a reference array of fields.
@@ -35713,7 +35887,7 @@ $rc = $dbh->disconnect;
@findex DBI->prepare()
@findex prepare() DBI method
@item prepare($statement)
-Prepares a SQL statement for execution by the database engine
+Prepares an SQL statement for execution by the database engine
and returns a statement handle @code{($sth)} which you can use to invoke
the @code{execute} method.
Typically you handle @code{SELECT} statements (and @code{SELECT}-like statements
@@ -35744,7 +35918,7 @@ $rv = $sth->execute
@findex DBI->do()
@findex do() DBI method
@item do($statement)
-The @code{do} method prepares and executes a SQL statement and returns the
+The @code{do} method prepares and executes an SQL statement and returns the
number of rows affected. If no rows are affected, @code{do} returns
@code{"0E0"}, which Perl treats as zero but regards as true. This method is
generally used for non-@code{SELECT} statements which cannot be prepared in
@@ -36512,7 +36686,7 @@ Create a @code{SEQUENCE} on a table and select the @code{_seq} column.
@table @code
@item @strong{MySQL}
Add a @code{PRIMARY KEY} or @code{UNIQUE} key to the table and use this.
-New in 3.23.11: If the @code{PRIMARY} or @code{UNIQUE} key consists of only one
+New in Version 3.23.11: If the @code{PRIMARY} or @code{UNIQUE} key consists of only one
column and this is of type integer, one can also refer to it as
@code{_rowid}.
@item mSQL
@@ -36568,7 +36742,7 @@ sorting in ASCII order.
@item @strong{MySQL}
@code{LIKE} is a case-insensitive or case-sensitive operator, depending on
the columns involved. If possible, @strong{MySQL} uses indexes if the
-@code{LIKE} argument doesn't start with a wildcard character.
+@code{LIKE} argument doesn't start with a wild-card character.
@item mSQL
Use @code{CLIKE}.
@end table
@@ -36686,7 +36860,7 @@ working on the @strong{MySQL} code.
@node MySQL threads, MySQL full-text search, MySQL internals, MySQL internals
@section MySQL threads
-The @strong{MySQL} server creates the the following threads:
+The @strong{MySQL} server creates the following threads:
@itemize @bullet
@item
@@ -36727,7 +36901,7 @@ DELAYED} threads.
@node MySQL full-text search, , MySQL threads, MySQL internals
@section MySQL full-text search
-Since version 3.23.23, @strong{MySQL} has support for full-text indexing
+Since Version 3.23.23, @strong{MySQL} has support for full-text indexing
and searching. Full-text index in @strong{MySQL} is an
index of type @code{FULLTEXT}. @code{FULLTEXT} indexes can be created from
@code{VARCHAR} and @code{TEXT} columns at @code{CREATE TABLE} time or added
@@ -37488,6 +37662,10 @@ Fernandez Herrero.
@itemize @bullet
@item Graphical clients
@itemize @bullet
+@item @uref{http://www.ideit.com/products/dbvis: DbVisualizer}
+Freeware JDBC client to graphically visualize the data and structure
+of several databases simultaneously. By Innovative-IT Development AB.
+
@item @uref{http://www.mysql.com/download_clients.html, mysqlgui homepage}
The @strong{MySQL} GUI client homepage. By Sinisa at MySQL AB.
@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1.tar.gz, kmysqladmin-0.4.1.tar.gz}
@@ -37513,7 +37691,7 @@ Windows GUI (binary only) to administrate a database, by David B. Mansel,
@item @uref{http://www.mysql.com/Downloads/Win32/netadmin.zip, netadmin.zip}
An administrator tool for @strong{MySQL} on Windows 95/98 and Windows NT
-4.0. Only tested with @strong{MySQL} 3.23.5 - 3.23.7. Written using the
+4.0. Only tested with @strong{MySQL} Version 3.23.5 - 3.23.7. Written using the
Tmysql components.
You can write queries and show tables, indexes, table syntax and
@@ -37634,10 +37812,10 @@ Originally written to implement a simple fast low-overhead banner-rotation syste
By Sasha Pachev.
@item @uref{http://www.odbsoft.com/cook/sources.htm}
-This package has various functions for generating html code from a SQL
+This package has various functions for generating html code from an SQL
table structure and for generating SQL statements (Select, Insert,
Update, Delete) from an html form. You can build a complete forms
-interface to a SQL database (query, add, update, delete) without any
+interface to an SQL database (query, add, update, delete) without any
programming! By Marc Beneteau, @email{marc@@odbsoft.com}.
@item @uref{http://www.mysql.com/Downloads/Contrib/sqlhtml.tar.gz, sqlhtml.tar.gz}
@@ -37646,7 +37824,7 @@ SQL/HTML is an HTML database manager for @strong{MySQL} using @code{DBI} 1.06.
@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.0.21.tar.gz, UdmSearch 3.0.22 (stable version)}
@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.1.3.tar.gz, UdmSearch 3.1.3 (development version)}
@item @uref{http://search.mnoGo.ru, UdmSearch home page}
-A SQL-based search engine for Internet. By
+An SQL-based search engine for Internet. By
Alexander I. Barkov @email{bar@@izhcom.ru}.
@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.doc, wmtcl.doc}
@@ -37812,7 +37990,7 @@ By Steve Shreeve.
@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/emacs-sql-mode.tar.gz, emacs-sql-mode.tar.gz}
-Raw port of a SQL mode for XEmacs. Supports completion. Original by
+Raw port of an SQL mode for XEmacs. Supports completion. Original by
Peter D. Pezaris @email{pez@@atlantic2.sbi.com} and partial
@strong{MySQL} port by David Axmark.
@@ -37908,6 +38086,13 @@ Prints the storage usage of a @strong{MySQL} database.
sprintf() function for SQL queries that can escape blobs. By Chunhua Liu.
@end itemize
+@appendixsec Windows programs
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/LaunchMySQL.zip, LaunchMySQL.zip}
+The program launches the @strong{MySQL} server, shuts it down, and
+display status information. By Bill Thompson
+@end itemize
+
@appendixsec Uncategorized
@itemize @bullet
@@ -38027,7 +38212,7 @@ Win32 port with Borland compiler. @code{mysqlshutdown.exe} and
@item David J. Hughes
For the effort to make a shareware SQL database. We at TcX started with
@code{mSQL}, but found that it couldn't satisfy our purposes so instead we
-wrote a SQL interface to our application builder Unireg. @code{mysqladmin}
+wrote an SQL interface to our application builder Unireg. @code{mysqladmin}
and @code{mysql} are programs that were largely influenced by their
@code{mSQL} counterparts. We have put a lot of effort into making the
@strong{MySQL} syntax a superset of @code{mSQL}. Many of the APIs ideas are
@@ -38258,9 +38443,9 @@ tables. The 3.23 release also includes support for database
replication between a master and many slaves.
We are not adding any more new features that are likely to break any
-old code in @strong{MySQL} 3.23, so we recommend that you use this
+old code in @strong{MySQL} Version 3.23, so we recommend that you use this
version. The replication and BerkeleyDB code is still under development,
-though, so 3.23 is not released as a stable version yet.
+though, so Version 3.23 is not released as a stable version yet.
@menu
* News-3.23.28:: Changes in release 3.23.28
@@ -38298,10 +38483,35 @@ though, so 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.28
@itemize @bullet
@item
+Changed all log files to use our own IO_CACHE mechanism instead of
+FILE:s to avoid OS problems when there is many files open.
+@item
+Added options @code{--open-files} and @code{--timezone} to @code{safe_mysqld}.
+@item
+Fixed fatal bug in @code{CREATE TEMPORARY TABLE ...SELECT ...}.
+@item
+Fixed problem with @code{CREATE TABLE .. SELECT NULL}.
+@item
+Added status variables @code{large_file_support},@code{net_read_timeout},
+@code{net_write_timeout} and @code{query_buffer_size} to @code{SHOW VARIABLES}.
+@item
+Fixed bug where we didn't allow an index name after the
+@code{FOREIGN KEY} definition.
+@item
+Added @code{TRUNCATE TABLE table_name} as a synonym for
+@code{DELETE FROM table_name}.
+@item
Fixed bug in a BDB key compare function when comparing part keys.
@item
Added variable @code{bdb_lock_max} to @code{mysqld}.
@item
+Added more tests to the benchmark suite.
+@item
+Fixed a overflow bug in the client code when using too long database names.
+@item
+@code{mysql_connect()} now aborts on Linux if the server doesn't answer in
+@code{timeout} seconds.
+@item
@code{SLAVE START} did not work if you started with
@code{--skip-slave-start} and had not explicitly run @code{CHANGE
MASTER TO}.
@@ -38319,7 +38529,7 @@ shortage when compiled @code{--with-debug=full}
Fixed several coredumps in out-of-memory conditions
@item
@code{SHOW SLAVE STATUS} was using unititialized mutex if the slave had
-not been started yet
+not been started yet
@item
Fixed bug in @code{ELT()} and @code{MAKE_SET()} when the query used
a temporary table
@@ -38329,7 +38539,6 @@ set it to 0 instead of 4 and hit the magic number in the master binlog.
@item
@code{ALTER TABLE ... ORDER BY ...} syntax added. This will create the
new table with the rows in a specific order.
-
@end itemize
@node News-3.23.27, News-3.23.26, News-3.23.28, News-3.23.x
@@ -40720,8 +40929,8 @@ The @code{mysql_real_connect()} call is changed to:
@example
mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
- const char *passwd, const char *db, uint port,
- const char *unix_socket, uint client_flag)
+ const char *passwd, const char *db, uint port,
+ const char *unix_socket, uint client_flag)
@end example
@item
Each connection is handled by its own thread, rather than by the
@@ -41363,7 +41572,7 @@ New portable benchmark suite with @code{DBD}, with test results from
@code{mSQL} 2.0.3, @strong{MySQL}, PostgreSQL 6.2.1 and Solid server 2.2.
@item
@code{crash-me} is now included with the benchmarks; This is a Perl program
-designed to find as many limits as possible in a SQL server. Tested with
+designed to find as many limits as possible in an SQL server. Tested with
@code{mSQL}, PostgreSQL, Solid and @strong{MySQL}.
@item
Fixed bug in range-optimizer that crashed @strong{MySQL} on some queries.
@@ -41848,7 +42057,7 @@ Fixed bug that you couldn't use @code{tbl_name.field_name} in @code{UPDATE}.
Fixed @code{SELECT DISTINCT} when using 'hidden group'. For example:
@example
mysql> SELECT DISTINCT MOD(some_field,10) FROM test
- GROUP BY some_field;
+ GROUP BY some_field;
@end example
Note: @code{some_field} is normally in the @code{SELECT} part. ANSI SQL should
require it.
@@ -41921,8 +42130,8 @@ New range optimizer that can resolve ranges when some keypart prefix is
constant. Example:
@example
mysql> SELECT * FROM tbl_name
- WHERE key_part_1="customer"
- AND key_part_2>=10 AND key_part_2<=10;
+ WHERE key_part_1="customer"
+ AND key_part_2>=10 AND key_part_2<=10;
@end example
@end itemize
@@ -42362,7 +42571,7 @@ lookups. The column that is used should be a constant for each group because
the value is calculated only once for the first row that is found for a group.
@example
mysql> SELECT id,lookup.text,sum(*) FROM test,lookup
- WHERE test.id=lookup.id GROUP BY id;
+ WHERE test.id=lookup.id GROUP BY id;
@end example
@item
Fixed bug in @code{SUM(function)} (could cause a core dump).
@@ -42629,7 +42838,7 @@ Because @strong{MySQL} allows you to work with table types that doesn't
support transactions (and thus can't @code{rollback} data) some things
behaves a little different in @strong{MySQL} than in other SQL servers:
(This is just to ensure that @strong{MySQL} never need to do a rollback
-for a SQL command). This may be a little akward at times as column
+for an SQL command). This may be a little akward at times as column
values must be checked in the application, but this will actually give
you a nice speed increase as it allows @strong{MySQL} to do some
optimizations that otherwice would be very hard to do.
@@ -42738,6 +42947,8 @@ Allow users to change startup options.
@item
Subqueries. @code{select id from t where grp in (select grp from g where u > 100)}
@item
+Don't allow more than # threads to run MyISAM recover at the same time.
+@item
@code{INSERT SQL_CONCURRENT ...}; This will force the insert to happen at the
end of the data file if the table is in use by an select to allow
concurrent inserts.
@@ -42948,6 +43159,10 @@ insert into t1 values (now());
create table t2 select max(a) from t1;
show columns from t2;
@end example
+@item
+Come up with a nice syntax for a statement that will @code{UPDATE} the row
+if it exists and @code{INSERT} a new row if the row didn't exist.
+(Like @code{REPLACE} works with @code{INSERT} / @code{DELETE})
@end itemize
@node TODO sometime, TODO unplanned, TODO future, TODO
@@ -43833,7 +44048,7 @@ mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
The sequence of characters of that collating element. The sequence is a
single element of the bracket expression's list. A bracket expression
containing a multi-character collating element can thus match more than
-one character, e.g., if the collating sequence includes a @code{ch}
+one character, for example, if the collating sequence includes a @code{ch}
collating element, then the regular expression @code{[[.ch.]]*c} matches the
first five characters of @code{chchcc}.
@@ -43954,17 +44169,17 @@ All new development is concentrated to @strong{MySQL}.
@appendix GNU General Public License
@example
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
- Preamble
+ Preamble
- The licenses for most software are designed to take away your
+The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
@@ -43974,48 +44189,48 @@ using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
- When we speak of free software, we are referring to freedom, not
+When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
- To protect your rights, we need to make restrictions that forbid
+To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
- For example, if you distribute copies of such a program, whether
+For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
- We protect your rights with two steps: (1) copyright the software, and
+We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
- Also, for each author's protection and ours, we want to make certain
+Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
- Finally, any free program is threatened constantly by software
+Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
- The precise terms and conditions for copying, distribution and
+The precise terms and conditions for copying, distribution and
modification follow.
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ GNU GENERAL PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 0. This License applies to any program or other work which contains
+0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
@@ -44032,7 +44247,7 @@ is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
- 1. You may copy and distribute verbatim copies of the Program's
+1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
@@ -44043,29 +44258,29 @@ along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
- 2. You may modify your copy or copies of the Program or any portion
+2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
+a) You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+b) You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+c) If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
@@ -44087,26 +44302,26 @@ with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
- 3. You may copy and distribute the Program (or a work based on it,
+3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
+a) Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
+b) Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
+c) Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
@@ -44125,7 +44340,7 @@ access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
- 4. You may not copy, modify, sublicense, or distribute the Program
+4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
@@ -44133,7 +44348,7 @@ However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
- 5. You are not required to accept this License, since you have not
+5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
@@ -44142,7 +44357,7 @@ Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
- 6. Each time you redistribute the Program (or any work based on the
+6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
@@ -44150,7 +44365,7 @@ restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
- 7. If, as a consequence of a court judgment or allegation of patent
+7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
@@ -44182,7 +44397,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
- 8. If the distribution and/or use of the Program is restricted in
+8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
@@ -44190,7 +44405,7 @@ those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
- 9. The Free Software Foundation may publish revised and/or new versions
+9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
@@ -44203,7 +44418,7 @@ Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
- 10. If you wish to incorporate parts of the Program into other free
+10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
@@ -44211,9 +44426,9 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
- NO WARRANTY
+ NO WARRANTY
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
@@ -44223,7 +44438,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@@ -44233,45 +44448,45 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
- END OF TERMS AND CONDITIONS
+ END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Programs
+Appendix: How to Apply These Terms to Your New Programs
- If you develop a new program, and you want it to be of the greatest
+If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
- To do so, attach the following notices to the program. It is safest
+To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
+<one line to give the program's name and a brief idea of what it does.>
+Copyright (C) 19yy <name of author>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
+Gnomovision version 69, Copyright (C) 19yy name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
@@ -44282,11 +44497,11 @@ You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
+<signature of Ty Coon>, 1 April 1989
+Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
@@ -44302,42 +44517,42 @@ Public License instead of this License.
@appendix GNU Library General Public License
@example
- GNU LIBRARY GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
+numbered 2 because it goes with version 2 of the ordinary GPL.]
- Preamble
+ Preamble
- The licenses for most software are designed to take away your
+The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
- This license, the Library General Public License, applies to some
+This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
- When we speak of free software, we are referring to freedom, not
+When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
- To protect your rights, we need to make restrictions that forbid
+To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
- For example, if you distribute copies of the library, whether gratis
+For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
@@ -44345,32 +44560,32 @@ complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
- Our method of protecting your rights has two steps: (1) copyright
+Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
- Also, for each distributor's protection, we want to make certain
+Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
- Finally, any free program is threatened constantly by software
+Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
- Most GNU software, including some libraries, is covered by the ordinary
+Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
- The reason we have a separate public license for some libraries is that
+The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
@@ -44379,12 +44594,12 @@ a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
- Because of this blurred distinction, using the ordinary General
+Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
- However, unrestricted linking of non-free programs would deprive the
+However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
@@ -44394,29 +44609,29 @@ this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
- The precise terms and conditions for copying, distribution and
+The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
- Note that it is possible for a library to be covered by the ordinary
+Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
- GNU LIBRARY GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 0. This License Agreement applies to any software library which
+0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
- A "library" means a collection of software functions and/or data
+A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
- The "Library", below, refers to any such software library or work
+The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
@@ -44424,13 +44639,13 @@ portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
- "Source code" for a work means the preferred form of the work for
+"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
- Activities other than copying, distribution and modification are not
+Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
@@ -44438,7 +44653,7 @@ on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
- 1. You may copy and distribute verbatim copies of the Library's
+1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
@@ -44446,37 +44661,37 @@ all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
- You may charge a fee for the physical act of transferring a copy,
+You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
- 2. You may modify your copy or copies of the Library or any portion
+2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
- a) The modified work must itself be a software library.
+a) The modified work must itself be a software library.
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
+b) You must cause the files modified to carry prominent notices
+stating that you changed the files and the date of any change.
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
+c) You must cause the whole of the work to be licensed at no
+charge to all third parties under the terms of this License.
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
+d) If a facility in the modified Library refers to a function or a
+table of data to be supplied by an application program that uses
+the facility, other than as an argument passed when the facility
+is invoked, then you must make a good faith effort to ensure that,
+in the event an application does not supply such function or
+table, the facility still operates, and performs whatever part of
+its purpose remains meaningful.
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
+(For example, a function in a library to compute square roots has
+a purpose that is entirely well-defined independent of the
+application. Therefore, Subsection 2d requires that any
+application-supplied function or table used by this function must
+be optional: if the application does not supply it, the square
+root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
@@ -44499,7 +44714,7 @@ with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
- 3. You may opt to apply the terms of the ordinary GNU General Public
+3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
@@ -44508,65 +44723,65 @@ ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
- Once this change is made in a given copy, it is irreversible for
+Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
- This option is useful when you wish to copy part of the code of
+This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
- 4. You may copy and distribute the Library (or a portion or
+4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
- If distribution of object code is made by offering access to copy
+If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
- 5. A program that contains no derivative of any portion of the
+5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
- However, linking a "work that uses the Library" with the Library
+However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
- When a "work that uses the Library" uses material from a header file
+When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
- If such an object file uses only numerical parameters, data
+If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
- Otherwise, if the work is a derivative of the Library, you may
+Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
- 6. As an exception to the Sections above, you may also compile or
+6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
- You must give prominent notice with each copy of the work that the
+You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
@@ -44574,31 +44789,31 @@ copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- c) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- d) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
+a) Accompany the work with the complete corresponding
+machine-readable source code for the Library including whatever
+changes were used in the work (which must be distributed under
+Sections 1 and 2 above); and, if the work is an executable linked
+with the Library, with the complete machine-readable "work that
+uses the Library", as object code and/or source code, so that the
+user can modify the Library and then relink to produce a modified
+executable containing the modified Library. (It is understood
+that the user who changes the contents of definitions files in the
+Library will not necessarily be able to recompile the application
+to use the modified definitions.)
+
+b) Accompany the work with a written offer, valid for at
+least three years, to give the same user the materials
+specified in Subsection 6a, above, for a charge no more
+than the cost of performing this distribution.
+
+c) If distribution of the work is made by offering access to copy
+from a designated place, offer equivalent access to copy the above
+specified materials from the same place.
+
+d) Verify that the user has already received a copy of these
+materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
@@ -44607,29 +44822,29 @@ components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
- It may happen that this requirement contradicts the license
+It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
- 7. You may place library facilities that are a work based on the
+7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
+a) Accompany the combined library with a copy of the same work
+based on the Library, uncombined with any other library
+facilities. This must be distributed under the terms of the
+Sections above.
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
+b) Give prominent notice with the combined library of the fact
+that part of it is a work based on the Library, and explaining
+where to find the accompanying uncombined form of the same work.
- 8. You may not copy, modify, sublicense, link with, or distribute
+8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
@@ -44637,7 +44852,7 @@ rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
- 9. You are not required to accept this License, since you have not
+9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
@@ -44646,7 +44861,7 @@ Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
- 10. Each time you redistribute the Library (or any work based on the
+10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
@@ -44654,7 +44869,7 @@ restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
- 11. If, as a consequence of a court judgment or allegation of patent
+11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
@@ -44685,7 +44900,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
- 12. If the distribution and/or use of the Library is restricted in
+12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
@@ -44693,7 +44908,7 @@ so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
- 13. The Free Software Foundation may publish revised and/or new
+13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
@@ -44706,7 +44921,7 @@ the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
- 14. If you wish to incorporate parts of the Library into other free
+14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
@@ -44715,9 +44930,9 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
- NO WARRANTY
+ NO WARRANTY
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
@@ -44727,7 +44942,7 @@ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
@@ -44738,37 +44953,37 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
- END OF TERMS AND CONDITIONS
+ END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Libraries
+Appendix: How to Apply These Terms to Your New Libraries
- If you develop a new library, and you want it to be of the greatest
+If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
- To apply these terms, attach the following notices to the library. It is
+To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
+<one line to give the library's name and a brief idea of what it does.>
+Copyright (C) <year> <name of author>
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free
+Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
@@ -44776,11 +44991,11 @@ You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+Yoyodyne, Inc., hereby disclaims all copyright interest in the
+library `Frob' (a library for tweaking knobs) written by James Random Hacker.
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
+<signature of Ty Coon>, 1 April 1990
+Ty Coon, President of Vice
That's all there is to it!
@end example
diff --git a/client/mysql.cc b/client/mysql.cc
index 8adb65ab3a6..5494ee6ccb9 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -115,7 +115,7 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
opt_compress=0,
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
no_named_cmds=1; // we want this to be the default
-static uint verbose=0,opt_silent=0,opt_mysql_port=0;
+static uint verbose=0,opt_silent=0,opt_mysql_port=0,opt_connect_timeout=0;
static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
@@ -334,7 +334,7 @@ sig_handler mysql_end(int sig)
exit(status.exit_status);
}
-enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET} ;
+enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_TIMEOUT} ;
static struct option long_options[] =
@@ -374,6 +374,7 @@ static struct option long_options[] =
{"socket", required_argument, 0, 'S'},
#include "sslopt-longopts.h"
{"table", no_argument, 0, 't'},
+ {"timeout", required_argument, 0, OPT_TIMEOUT},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", required_argument, 0, 'u'},
#endif
@@ -545,9 +546,12 @@ static int get_options(int argc, char **argv)
case 'p':
if (optarg)
{
+ char *start=optarg;
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; // Destroy argument
+ if (*start)
+ start[1]=0;
}
else
tty_password=1;
@@ -603,6 +607,9 @@ static int get_options(int argc, char **argv)
opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
#endif
break;
+ case OPT_TIMEOUT:
+ opt_connect_timeout=atoi(optarg);
+ break;
case 'V': usage(1); exit(0);
case 'I':
case '?':
@@ -1772,6 +1779,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
connected= 0;
}
mysql_init(&mysql);
+ if (opt_connect_timeout)
+ mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
+ (char*) &opt_connect_timeout);
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index f8432ec7fb6..d5b2e73451e 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
-#define ADMIN_VERSION "8.9"
+#define ADMIN_VERSION "8.11"
#define MAX_MYSQL_VAR 64
#define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -137,7 +137,7 @@ int main(int argc,char *argv[])
{
int c, error = 0,option_index=0;
MYSQL mysql;
- char *host = NULL,*password=0,*user=0,**commands;
+ char *host = NULL,*opt_password=0,*user=0,**commands;
my_bool tty_password=0;
MY_INIT(argv[0]);
mysql_init(&mysql);
@@ -160,9 +160,12 @@ int main(int argc,char *argv[])
case 'p':
if (optarg)
{
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password=my_strdup(optarg,MYF(MY_FAE));
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
}
else
tty_password=1;
@@ -243,12 +246,11 @@ int main(int argc,char *argv[])
exit(1);
}
if (tty_password)
- password = get_tty_password(NullS);
+ opt_password = get_tty_password(NullS);
VOID(signal(SIGINT,endprog)); /* Here if abort */
VOID(signal(SIGTERM,endprog)); /* Here if abort */
- mysql_init(&mysql);
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
@@ -256,7 +258,7 @@ int main(int argc,char *argv[])
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath);
#endif /* HAVE_OPENSSL */
- if (sql_connect(&mysql,host,user,password,option_wait))
+ if (sql_connect(&mysql,host,user,opt_password,option_wait))
error = 1;
else
{
@@ -269,7 +271,7 @@ int main(int argc,char *argv[])
if (option_wait && !interrupted)
{
mysql_close(&mysql);
- if (!sql_connect(&mysql,host,user,password,option_wait))
+ if (!sql_connect(&mysql,host,user,opt_password,option_wait))
continue; /* Retry */
}
error=1;
@@ -286,7 +288,7 @@ int main(int argc,char *argv[])
}
mysql_close(&mysql);
}
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(argv);
my_end(0);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index b1c77b209aa..019069d81b0 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -37,7 +37,7 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
**/
-#define DUMP_VERSION "8.10"
+#define DUMP_VERSION "8.11"
#include <global.h>
#include <my_sys.h>
@@ -75,7 +75,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_first_slave=0;
static MYSQL mysql_connection,*sock=0;
-static char insert_pat[12 * 1024],*password=0,*current_user=0,
+static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
*where=0, *default_charset;
@@ -333,9 +333,12 @@ static int get_options(int *argc,char ***argv)
case 'p':
if (optarg)
{
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
+ while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
}
else
tty_password=1;
@@ -459,7 +462,7 @@ static int get_options(int *argc,char ***argv)
return 1;
}
if (tty_password)
- password=get_tty_password(NullS);
+ opt_password=get_tty_password(NullS);
return(0);
} /* get_options */
@@ -596,7 +599,6 @@ static uint getTableStructure(char *table, char* db)
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted);
table_name=quote_name(table,table_buff);
-
if (mysql_query(sock,insert_pat))
{
/* using SHOW CREATE statement */
@@ -1318,7 +1320,7 @@ int main(int argc, char **argv)
my_end(0);
exit(EX_USAGE);
}
- if (dbConnect(current_host, current_user, password))
+ if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
if (!path)
write_heder(stdout, *argv);
@@ -1358,7 +1360,7 @@ int main(int argc, char **argv)
}
dbDisconnect(current_host);
puts("");
- my_free(password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
if (extended_insert)
dynstr_free(&extended_row);
my_end(0);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 596b68591b7..d00c99d4061 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -25,7 +25,7 @@
** * *
** *************************
*/
-#define IMPORT_VERSION "2.4"
+#define IMPORT_VERSION "2.6"
#include <global.h>
#include <my_sys.h>
@@ -45,7 +45,7 @@ static my_bool verbose=0,lock_tables=0,ignore_errors=0,delete=0,
replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0;
static MYSQL mysql_connection;
-static char *password=0, *current_user=0,
+static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
*escaped=0, opt_low_priority=0, *opt_columns=0;
@@ -125,7 +125,7 @@ file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
Give the column names in a comma separated list.\n\
This is same as giving columns to LOAD DATA INFILE.\n\
-C, --compress Use compression in server/client protocol\n\
- -d, --delete Deletes first all rows from table.\n\
+ -d, --delete First delete all rows from table.\n\
-f, --force Continue even if we get an sql-error.\n\
-h, --host=... Connect to host.\n\
-i, --ignore If duplicate unique key was found, keep old row.\n\
@@ -202,9 +202,12 @@ static int get_options(int *argc, char ***argv)
case 'p':
if (optarg)
{
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password= my_strdup(optarg,MYF(MY_FAE));
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
}
else
tty_password= 1;
@@ -276,7 +279,7 @@ static int get_options(int *argc, char ***argv)
current_db= *((*argv)++);
(*argc)--;
if (tty_password)
- password=get_tty_password(NullS);
+ opt_password=get_tty_password(NullS);
return(0);
}
@@ -504,7 +507,7 @@ int main(int argc, char **argv)
argv_to_free= argv;
if (get_options(&argc, &argv))
return(1);
- if (!(sock= db_connect(current_host,current_db,current_user,password)))
+ if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
return(1); /* purecov: deadcode */
if (lock_tables)
lock_table(sock, argc, argv);
@@ -513,7 +516,7 @@ int main(int argc, char **argv)
if (exitcode == 0)
exitcode = error;
db_disconnect(current_host, sock);
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(argv_to_free);
my_end(0);
return(exitcode);
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index bf924ddeecd..3c34b2df4b5 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -28,7 +28,7 @@
#include <stdarg.h>
#include <getopt.h>
-static my_string host=0,password=0,user=0;
+static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0;
static void get_options(int *argc,char ***argv);
@@ -88,15 +88,13 @@ int main(int argc, char **argv)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath);
#endif
- if (!(mysql_real_connect(&mysql,host,user,password,
+ if (!(mysql_real_connect(&mysql,host,user,opt_password,
argv[0],opt_mysql_port,opt_mysql_unix_port,
0)))
{
fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
exit(1);
}
- /* if (!(mysql_connect(&mysql,host,user,password))) */
-
switch (argc)
{
@@ -111,11 +109,12 @@ int main(int argc, char **argv)
if (opt_status && ! wild)
error=list_table_status(&mysql,argv[0],argv[1]);
else
- error=list_fields(&mysql,argv[0],argv[1],wild); break;
+ error=list_fields(&mysql,argv[0],argv[1],wild);
+ break;
}
mysql_close(&mysql); /* Close & free connection */
- if (password)
- my_free(password,MYF(0));
+ if (opt_password)
+ my_free(opt_password,MYF(0));
my_end(0);
exit(error ? 1 : 0);
return 0; /* No compiler warnings */
@@ -223,9 +222,12 @@ get_options(int *argc,char ***argv)
case 'p':
if (optarg)
{
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password=my_strdup(optarg,MYF(MY_FAE));
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
}
else
tty_password=1;
@@ -266,7 +268,7 @@ get_options(int *argc,char ***argv)
(*argc)-=optind;
(*argv)+=optind;
if (tty_password)
- password=get_tty_password(NullS);
+ opt_password=get_tty_password(NullS);
return;
}
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 7ca2d3c419e..4b9ebef21f1 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -95,17 +95,6 @@ bool String::realloc(uint32 alloc_length)
return FALSE;
}
-
-#ifdef NOT_NEEDED
-bool String::set(long num)
-{
- if (alloc(14))
- return TRUE;
- str_length=(uint32) (int10_to_str(num,Ptr,-10)-Ptr);
- return FALSE;
-}
-#endif
-
bool String::set(longlong num)
{
if (alloc(21))
@@ -274,6 +263,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE;
}
+#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{
if (realloc(str_length+arg_length))
@@ -286,6 +276,20 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
str_length+=arg_length;
return FALSE;
}
+#endif
+
+bool String::append(IO_CACHE* file, uint32 arg_length)
+{
+ if (realloc(str_length+arg_length))
+ return TRUE;
+ if (my_b_read(file, (byte*) Ptr + str_length, arg_length))
+ {
+ shrink(str_length);
+ return TRUE;
+ }
+ str_length+=arg_length;
+ return FALSE;
+}
uint32 String::numchars()
{
diff --git a/client/sql_string.h b/client/sql_string.h
index 8711cf314ad..74dbc4cc6bd 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -100,16 +100,16 @@ public:
bool set(ulonglong num);
bool set(double num,uint decimals=2);
inline void free()
+ {
+ if (alloced)
{
- if (alloced)
- {
- alloced=0;
- Alloced_length=0;
- my_free(Ptr,MYF(0));
- Ptr=0;
- }
+ alloced=0;
+ Alloced_length=0;
+ my_free(Ptr,MYF(0));
+ Ptr=0;
+ str_length=0; /* Safety */
}
-
+ }
inline bool alloc(uint32 arg_length)
{
if (arg_length < Alloced_length)
@@ -152,7 +152,7 @@ public:
bool copy(const char *s,uint32 arg_length); // Allocate new string
bool append(const String &s);
bool append(const char *s,uint32 arg_length=0);
- bool append(FILE* file, uint32 arg_length, myf my_flags);
+ bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to);
diff --git a/configure.in b/configure.in
index 4a8b5dbfa4c..6811404bc35 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 3.23.27-beta)
+AM_INIT_AUTOMAKE(mysql, 3.23.28-gamma)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -687,6 +687,8 @@ case $SYSTEM_TYPE in
then
CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
+ CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE"
+ CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE"
MAX_C_OPTIMIZE="-O"
with_named_curses=""
fi
@@ -1235,13 +1237,13 @@ AC_FUNC_UTIME_NULL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(alarm bmove \
chsize ftruncate rint finite fpsetmask fpresetsticky\
- cuserid fcntl fconvert \
+ cuserid fcntl fconvert poll \
getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \
perror pread realpath rename \
socket strnlen madvise mkstemp \
strtol strtoul strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \
- bfill bzero bcmp strstr strpbrk strerror\
+ bfill bzero bcmp strstr strpbrk strerror \
tell atod memcpy memmove \
setupterm strcasecmp sighold \
vidattr setupterm lrand48 localtime_r \
diff --git a/include/my_pthread.h b/include/my_pthread.h
index bef7da93451..c7b5831a474 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -351,10 +351,9 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#define pthread_kill(A,B) pthread_dummy(0)
#define pthread_condattr_init(A) pthread_dummy(0)
#define pthread_condattr_destroy(A) pthread_dummy(0)
-#define pthread_cond_init( A, B ) pthread_cond_init( (A), 0 )
#define pthread_signal(A,B) pthread_dummy(0)
#undef pthread_detach_this_thread
-#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
+#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
#undef sigset
#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B))
#endif
diff --git a/include/my_sys.h b/include/my_sys.h
index 3fc4fed3397..32b2d18fb4d 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -59,6 +59,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */
+#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
@@ -506,6 +507,10 @@ extern int my_block_write(IO_CACHE *info, const byte *Buffer,
uint Count, my_off_t pos);
extern int flush_io_cache(IO_CACHE *info);
extern int end_io_cache(IO_CACHE *info);
+extern uint my_b_fill(IO_CACHE *info);
+extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length);
+extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...);
extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
const char *prefix, uint cache_size,
myf cache_myflags);
diff --git a/include/violite.h b/include/violite.h
index e7c3e8ede81..1f44c29ba65 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -108,6 +108,9 @@ my_bool vio_peer_addr(Vio * vio, char *buf);
void vio_in_addr(Vio *vio, struct in_addr *in);
+ /* Return 1 if there is data to be read */
+my_bool vio_poll_read(Vio *vio,uint timeout);
+
#ifdef __cplusplus
}
#endif
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index c7820916c97..5cdbf12dfc4 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -64,6 +64,12 @@ my_string mysql_unix_port=0;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS)
+#ifdef __WIN__
+#define CONNECT_TIMEOUT 20
+#else
+#define CONNECT_TIMEOUT 0
+#endif
+
#if defined(MSDOS) || defined(__WIN__)
#define ERRNO WSAGetLastError()
#define perror(A)
@@ -113,7 +119,7 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
*****************************************************************************/
static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
- uint to)
+ uint timeout)
{
#if defined(__WIN__)
return connect(s, (struct sockaddr*) name, namelen);
@@ -128,7 +134,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
* exactly like the normal connect() call does.
*/
- if (to == 0)
+ if (timeout == 0)
return connect(s, (struct sockaddr*) name, namelen);
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
@@ -175,13 +181,13 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
start_time = time(NULL);
for (;;)
{
- tv.tv_sec = (long) to;
+ tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
break;
now_time=time(NULL);
- to-= (uint) (now_time - start_time);
- if (errno != EINTR || (int) to <= 0)
+ timeout-= (uint) (now_time - start_time);
+ if (errno != EINTR || (int) timeout <= 0)
return -1;
}
@@ -195,7 +201,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
return(-1);
if (s_err)
- { /* getsockopt() could suceed */
+ { /* getsockopt could succeed */
errno = s_err;
return(-1); /* but return an error... */
}
@@ -1001,9 +1007,7 @@ mysql_init(MYSQL *mysql)
}
else
bzero((char*) (mysql),sizeof(*(mysql)));
-#ifdef __WIN__
- mysql->options.connect_timeout=20;
-#endif
+ mysql->options.connect_timeout=CONNECT_TIMEOUT;
#if defined(SIGPIPE) && defined(THREAD)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler);
@@ -1140,7 +1144,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
{
- char buff[100],charset_name_buff[16],*end,*host_info, *charset_name;
+ char buff[NAME_LEN+100],charset_name_buff[16],*end,*host_info,
+ *charset_name;
my_socket sock;
uint32 ip_addr;
struct sockaddr_in sock_addr;
@@ -1342,6 +1347,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Get version info */
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
+ if (mysql->options.connect_timeout &&
+ vio_poll_read(net->vio, mysql->options.connect_timeout))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
if ((pkt_length=net_safe_read(mysql)) == packet_error)
goto error;
@@ -1497,7 +1509,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
int3store(buff+2,max_allowed_packet);
if (user && user[0])
- strmake(buff+5,user,32);
+ strmake(buff+5,user,32); /* Max user name */
else
read_user_name((char*) buff+5);
#ifdef _CUSTOMCONFIG_
@@ -1508,7 +1520,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
(my_bool) (mysql->protocol_version == 9));
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
- end=strmov(end+1,db);
+ end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
diff --git a/libmysql/violite.c b/libmysql/violite.c
index 349a6fbd849..4efda9f3b90 100644
--- a/libmysql/violite.c
+++ b/libmysql/violite.c
@@ -32,6 +32,9 @@
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
#if defined(__EMX__)
#include <sys/ioctl.h>
@@ -98,7 +101,9 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
{
vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc, "socket (%d)", vio->sd);
+ sprintf(vio->desc,
+ (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
+ vio->sd);
#if !defined(___WIN__) && !defined(__EMX__)
#if !defined(NO_FCNTL_NONBLOCK)
vio->fcntl_mode = fcntl(sd, F_GETFL);
@@ -261,7 +266,7 @@ vio_is_blocking(Vio * vio)
}
-int vio_fastsend(Vio * vio, my_bool onoff)
+int vio_fastsend(Vio * vio __attribute__((unused)), my_bool onoff)
{
int r=0;
DBUG_ENTER("vio_fastsend");
@@ -322,7 +327,7 @@ int vio_close(Vio * vio)
if (vio->type == VIO_TYPE_NAMEDPIPE)
{
#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIO(vio->hPipe);
+ CancelIo(vio->hPipe);
DisconnectNamedPipe(vio->hPipe);
#endif
r=CloseHandle(vio->hPipe);
@@ -397,4 +402,26 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
DBUG_VOID_RETURN;
}
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
+
#endif /* HAVE_VIO */
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 048bbb427a2..89bdcdf3fbc 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -417,6 +417,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
share.state.unique= (ulong) 0;
+ share.state.update_count=(ulong) 0;
share.state.version= (ulong) time((time_t*) 0);
share.state.sortkey= (ushort) ~0;
share.state.auto_increment=ci->auto_increment;
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index 4797584627a..45bb2cd7164 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -70,6 +70,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
{
share->state.process= share->last_process=share->this_process;
share->state.unique= info->last_unique= info->this_unique;
+ share->state.update_count= info->last_loop= ++info->this_loop;
if (mi_state_info_write(share->kfile, &share->state, 1))
error=my_errno;
share->changed=0;
@@ -346,6 +347,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
{ /* Two threads can't be here */
share->state.process= share->last_process= share->this_process;
share->state.unique= info->last_unique= info->this_unique;
+ share->state.update_count= info->last_loop= ++info->this_loop;
if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
olderror=my_errno;
#ifdef __WIN__
@@ -377,12 +379,14 @@ int _mi_test_if_changed(register MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
if (share->state.process != share->last_process ||
- share->state.unique != info->last_unique)
+ share->state.unique != info->last_unique ||
+ share->state.update_count != info->last_loop)
{ /* Keyfile has changed */
if (share->state.process != share->this_process)
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
share->last_process=share->state.process;
info->last_unique= share->state.unique;
+ info->last_loop= share->state.update_count;
info->update|= HA_STATE_WRITTEN; /* Must use file on next */
info->data_changed= 1; /* For mi_is_changed */
return 1;
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index aeaf9e5e9b4..c29a4a843ca 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -445,8 +445,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
info.this_unique= (ulong) info.dfile; /* Uniq number in process */
if (share->data_file_type == COMPRESSED_RECORD)
info.this_unique= share->state.unique;
- info.this_loop=0; /* Update counter */
+ info.this_loop=0; /* Update counter */
info.last_unique= share->state.unique;
+ info.last_loop= share->state.update_count;
if (mode == O_RDONLY)
share->options|=HA_OPTION_READ_ONLY_DATA;
info.lock_type=F_UNLCK;
@@ -669,7 +670,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
mi_int4store(ptr,state->process); ptr +=4;
mi_int4store(ptr,state->unique); ptr +=4;
mi_int4store(ptr,state->status); ptr +=4;
- *ptr++=0; *ptr++=0; *ptr++=0; *ptr++=0; /* extra */
+ mi_int4store(ptr,state->update_count); ptr +=4;
ptr+=state->state_diff_length;
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index eead2a84c29..3ffc348ca5c 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -1214,7 +1214,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
/* Force full read if we are at last key or if we are not on a leaf
- and the key tree has changed since we used it last time */
+ and the key tree has changed since we used it last time
+ Note that even if the key tree has changed since last read, we can use
+ the last read data from the leaf if we haven't used the buffer for
+ something else.
+ */
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
info->page_changed ||
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index a65694dbd94..ad153d58b70 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -64,6 +64,7 @@ typedef struct st_mi_state_info
ulonglong auto_increment;
ulong process; /* process that updated table last */
ulong unique; /* Unique number for this process */
+ ulong update_count; /* Updated for each write lock */
ulong status;
my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */
diff --git a/mysql.proj b/mysql.proj
index ed591da265e..a6e5d9c5852 100644
--- a/mysql.proj
+++ b/mysql.proj
Binary files differ
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 6b38d9364f6..9e9b4f8d9ed 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -26,8 +26,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\
my_open.c my_create.c my_seek.c my_read.c \
my_pread.c my_write.c \
- mf_reccache.c mf_keycache.c \
- mf_iocache.c mf_cache.c mf_tempfile.c \
+ mf_keycache.c \
+ mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \
my_alloc.c safemalloc.c my_fopen.c my_fstream.c \
diff --git a/mysys/hash.c b/mysys/hash.c
index a6181443a42..9c6497c7717 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -374,10 +374,11 @@ my_bool hash_delete(HASH *hash,byte *record)
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
DBUG_ENTER("hash_delete");
+ if (!hash->records)
+ DBUG_RETURN(1);
blength=hash->blength;
data=dynamic_element(&hash->array,0,HASH_LINK*);
-
/* Search after record with key */
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
gpos = 0;
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index 2c197f6fd20..ff29926ac50 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -74,7 +74,7 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
}
my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
/* Create the temporary file */
@@ -101,10 +101,12 @@ void close_cached_file(IO_CACHE *cache)
DBUG_ENTER("close_cached_file");
if (my_b_inited(cache))
{
+ File file=cache->file;
+ cache->file= -1; /* Don't flush data */
(void) end_io_cache(cache);
- if (cache->file >= 0)
+ if (file >= 0)
{
- (void) my_close(cache->file,MYF(0));
+ (void) my_close(file,MYF(0));
#ifdef CANT_DELETE_OPEN_FILES
if (cache->file_name)
{
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 86cf5fc65e2..0d1c227c2b2 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -22,10 +22,13 @@
(and get a EOF-error).
Possibly use of asyncronic io.
macros for read and writes for faster io.
- Used instead of FILE when reading or writing hole files.
- This shall make mf_rec_cache obsolite.
- One can change info->pos_in_file to a higer value to skipp bytes in file if
+ Used instead of FILE when reading or writing whole files.
+ This will make mf_rec_cache obsolete.
+ One can change info->pos_in_file to a higher value to skip bytes in file if
also info->rc_pos is set to info->rc_end.
+ If called through open_cached_file(), then the temporary file will
+ only be created if a write exeeds the file buffer or if one calls
+ flush_io_cache().
*/
#define MAP_TO_USE_RAID
@@ -40,7 +43,7 @@ static void my_aiowait(my_aio_result *result);
/*
** if cachesize == 0 then use default cachesize (from s-file)
- ** if file == -1 then real_open_cached_file() will be called to
+ ** if file == -1 then real_open_cached_file() will be called.
** returns 0 if ok
*/
@@ -59,17 +62,24 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE)
{ /* Assume file isn't growing */
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ if (cache_myflags & MY_DONT_CHECK_FILESIZE)
{
- cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
+ cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
+ }
+ else
+ {
+ my_off_t file_pos,end_of_file;
+ if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
+ DBUG_RETURN(1);
+ end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
+ if (end_of_file < seek_offset)
+ end_of_file=seek_offset;
+ VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
+ if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ {
+ cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
+ use_async_io=0; /* No nead to use async */
+ }
}
}
@@ -545,7 +555,6 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
return error;
}
-
/* Flush write cache */
int flush_io_cache(IO_CACHE *info)
@@ -565,7 +574,9 @@ int flush_io_cache(IO_CACHE *info)
length=(uint) (info->rc_pos - info->buffer);
if (info->seek_not_done)
{ /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
+ if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ MY_FILEPOS_ERROR)
+ DBUG_RETURN((info->error= -1));
info->seek_not_done=0;
}
info->rc_pos=info->buffer;
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
new file mode 100644
index 00000000000..80cea47a80f
--- /dev/null
+++ b/mysys/mf_iocache2.c
@@ -0,0 +1,212 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
+
+/*
+ More functions to be used with IO_CACHE files
+*/
+
+#define MAP_TO_USE_RAID
+#include "mysys_priv.h"
+#include <m_string.h>
+#include <stdarg.h>
+#include <m_ctype.h>
+
+/*
+** Fix that next read will be made at certain position
+** This only works with READ_CACHE
+*/
+
+void my_b_seek(IO_CACHE *info,my_off_t pos)
+{
+ info->seek_not_done=0;
+ info->pos_in_file=pos;
+ info->rc_pos=info->rc_end=info->buffer;
+}
+
+/*
+** Fill buffer
+** return: 0 on error or EOF (info->error = -1 on error)
+** number of characters
+*/
+
+uint my_b_fill(IO_CACHE *info)
+{
+ my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
+ my_off_t max_length;
+ uint diff_length,length;
+ if (info->seek_not_done)
+ { /* File touched, do seek */
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ MY_FILEPOS_ERROR)
+ {
+ info->error= 0;
+ return 0;
+ }
+ info->seek_not_done=0;
+ }
+ diff_length=(uint) (pos_in_file & (IO_SIZE-1));
+ max_length= (my_off_t) (info->end_of_file - pos_in_file);
+ if (max_length > (my_off_t) (info->read_length-diff_length))
+ max_length=(my_off_t) (info->read_length-diff_length);
+ if (!max_length)
+ {
+ info->error= 0;
+ return 0; /* EOF */
+ }
+ else if ((length=my_read(info->file,info->buffer,(uint) max_length,
+ info->myflags)) == (uint) -1)
+ {
+ info->error= -1;
+ return 0;
+ }
+ info->rc_pos=info->buffer;
+ info->rc_end=info->buffer+length;
+ info->pos_in_file=pos_in_file;
+ return length;
+}
+
+/*
+** Read a string ended by '\n' into a buffer of 'max_length' size.
+** Returns number of characters read, 0 on error.
+** last byte is set to '\0'
+*/
+
+uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
+{
+ uint length;
+ max_length--; /* Save place for end \0 */
+ /* Calculate number of characters in buffer */
+ if (!(length= (uint) (info->rc_end - info->rc_pos)))
+ if (!(length=my_b_fill(info)))
+ return 0;
+ for (;;)
+ {
+ char *pos,*end;
+ if (length > max_length)
+ length=max_length;
+ for (pos=info->rc_pos,end=pos+length ; pos < end ;)
+ {
+ if ((*to++ = *pos++) == '\n')
+ {
+ length= (uint) (pos-info->rc_pos);
+ info->rc_pos=pos;
+ *to='\0';
+ return length;
+ }
+ }
+ if (!(max_length-=length))
+ {
+ /* Found enough charcters; Return found string */
+ info->rc_pos=pos;
+ *to='\0';
+ return length;
+ }
+ if (!(length=my_b_fill(info)))
+ return 0;
+ }
+}
+
+/*
+ Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
+ Used for logging in MySQL
+ returns number of written character, or (uint) -1 on error
+*/
+
+uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
+{
+ va_list args;
+ reg1 char *to= info->rc_pos;
+ char *end=info->rc_end;
+ uint out_length=0;
+
+ va_start(args,fmt);
+
+ for (; *fmt ; fmt++)
+ {
+ if (fmt[0] != '%')
+ {
+ /* Copy everything until '%' or end of string */
+ const char *start=fmt;
+ uint length;
+ for (fmt++ ; *fmt && *fmt != '%' ; fmt++ ) ;
+ length= (uint) (fmt - start);
+ out_length+=length;
+ if (my_b_write(info, start, length))
+ goto err;
+ if (!*fmt) /* End of format */
+ {
+ va_end(args);
+ return out_length;
+ }
+ /* Found one '%' */
+ }
+ /* Skipp if max size is used (to be compatible with printf) */
+ while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
+ fmt++;
+ if (*fmt == 's') /* String parameter */
+ {
+ reg2 char *par = va_arg(args, char *);
+ uint length = (uint) strlen(par);
+ out_length+=length;
+ if (my_b_write(info, par, length))
+ goto err;
+ }
+ else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
+ {
+ register int iarg;
+ uint length;
+ char buff[17];
+
+ iarg = va_arg(args, int);
+ if (*fmt == 'd')
+ length= (uint) (int10_to_str((long) iarg,buff, -10) - buff);
+ else
+ length= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff);
+ out_length+=length;
+ if (my_b_write(info, buff, length))
+ goto err;
+ }
+ else if (*fmt == 'l' && fmt[1] == 'd' || fmt[1] == 'u')/* long parameter */
+ {
+ register long iarg;
+ uint length;
+ char buff[17];
+
+ iarg = va_arg(args, long);
+ if (*++fmt == 'd')
+ length= (uint) (int10_to_str(iarg,buff, -10) - buff);
+ else
+ length= (uint) (int10_to_str(iarg,buff,10)- buff);
+ out_length+=length;
+ if (my_b_write(info, buff, length))
+ goto err;
+ }
+ else
+ {
+ /* %% or unknown code */
+ if (my_b_write(info, "%", 1))
+ goto err;
+ out_length++;
+ }
+ }
+ va_end(args);
+ return out_length;
+
+err:
+ return (uint) -1;
+ va_end(args);
+}
diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c
index 63730926156..b394adf2a96 100644
--- a/mysys/my_vsnprintf.c
+++ b/mysys/my_vsnprintf.c
@@ -21,74 +21,49 @@
#include <stdarg.h>
#include <m_ctype.h>
-
-
-int my_vsnprintf(char* str, size_t n, const char* fmt, va_list ap)
+int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
{
- uint olen = 0, plen;
- const char *tpos;
- reg1 char *endpos;
- reg2 char * par;
- char* ebuff = str;
-
- endpos=ebuff;
- tpos = fmt;
+ char *start=to, *end=to+n-1;
- while (*tpos)
+ for (; *fmt ; fmt++)
{
- if (tpos[0] != '%')
+ if (fmt[0] != '%')
{
- if(olen + 1 >= n)
+ if (to == end) /* End of buffer */
break;
-
- *endpos++= *tpos++; /* Copy ordinary char */
- olen++;
+ *to++= *fmt; /* Copy ordinary char */
continue;
}
- if (*++tpos == '%') /* test if %% */
- {
- olen--;
- }
- else
+ /* Skipp if max size is used (to be compatible with printf) */
+ while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
+ fmt++;
+ if (*fmt == 's') /* String parameter */
{
- /* Skipp if max size is used (to be compatible with printf) */
- while (isdigit(*tpos) || *tpos == '.' || *tpos == '-')
- tpos++;
- if (*tpos == 's') /* String parameter */
- {
- par = va_arg(ap, char *);
- plen = (uint) strlen(par);
- if (olen + plen < n) /* Replace if possible */
- {
- endpos=strmov(endpos,par);
- tpos++;
- olen+=plen;
- continue;
- }
- }
- else if (*tpos == 'd' || *tpos == 'u') /* Integer parameter */
+ reg2 char *par = va_arg(ap, char *);
+ uint plen = (uint) strlen(par);
+ if ((uint) (end-to) > plen) /* Replace if possible */
{
- register int iarg;
- iarg = va_arg(ap, int);
- if(olen + 16 >= n) break;
-
- if (*tpos == 'd')
- plen= (uint) (int2str((long) iarg,endpos, -10) - endpos);
- else
- plen= (uint) (int2str((long) (uint) iarg,endpos,10)- endpos);
- if (olen + plen < n) /* Replace parameter if possible */
- {
- endpos+=plen;
- tpos++;
- olen+=plen;
- continue;
- }
+ to=strmov(to,par);
+ continue;
}
}
- *endpos++='%'; /* % used as % or unknown code */
+ else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
+ {
+ register int iarg;
+ if ((uint) (end-to) < 16)
+ break;
+ iarg = va_arg(ap, int);
+ if (*fmt == 'd')
+ to=int10_to_str((long) iarg,to, -10);
+ else
+ to=int10_to_str((long) (uint) iarg,to,10);
+ continue;
+ }
+ /* We come here on '%%', unknown code or too long parameter */
+ if (to == end)
+ break;
+ *to++='%'; /* % used as % or unknown code */
}
- *endpos='\0';
- /* End of errmessage */
- return olen;
+ *to='\0'; /* End of errmessage */
+ return (uint) (to - start);
}
-
diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh
index 43023e0fb8b..615670326bb 100644
--- a/scripts/safe_mysqld.sh
+++ b/scripts/safe_mysqld.sh
@@ -28,10 +28,13 @@ parse_arguments() {
--socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;;
--port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;;
--log=*) log=`echo "$arg" | sed -e "s;--log=;;"` ;;
- --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
--basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
- --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
--user=*) user=`echo "$arg" | sed -e "s;--user=;;"` ;;
+ --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
+ --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
+ --open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
+ --core-file-size*) core_file_size=`echo "$arg" | sed -e "s;--core_file_size=;;"` ;;
+ --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
esac
done
}
@@ -105,6 +108,14 @@ if test -w /
then
# If we are root, change the err log to the right user.
touch $err_log; chown $user $err_log
+ if test -n "$open_files"
+ then
+ ulimit -n $open_files
+ fi
+ if test -n "$core_file_size"
+ then
+ ulimit -c $core_file_size
+ fi
fi
#
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index 3f650885c21..ae847c1a28f 100755
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -339,6 +339,15 @@ sub end_benchmark
exit 0;
}
+sub print_time
+{
+ my ($estimated)=@_;
+ if ($estimated)
+ { print "Estimated time"; }
+ else
+ { print "Time"; }
+}
+
#
# Create a filename part for the machine that can be used for log file.
#
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index 6bb3eab63f9..5c993e842bc 100755
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -39,7 +39,7 @@
# "3-byte int" or "same as xxx".
-$version="1.50";
+$version="1.51";
use DBI;
use Getopt::Long;
@@ -289,6 +289,11 @@ report("rename table","rename_table",
$dbh->do("drop table crash_q1");
$dbh->do("drop table crash_q");
+report("truncate table","truncate_table",
+ "create table crash_q (a integer, b integer,c CHAR(10))",
+ "truncate table crash_q",
+ "drop table crash_q1");
+
if ($dbh->do("create table crash_q (a integer, b integer,c CHAR(10))") &&
$dbh->do("create table crash_q1 (a integer, b integer,c CHAR(10) not null)"))
{
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index e6690b043f1..13bcfb2f6a9 100755
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -270,7 +270,7 @@ for ($i=1 ; $i <= $small_loop_count ; $i++)
{
if (!$error++)
{
- print "Warning: Got $found_rows rows when selecting a hole table of " . ($total_rows) . " rows\nContact the database or DBD author!\n";
+ print "Warning: Got $found_rows rows when selecting a whole table of " . ($total_rows) . " rows\nContact the database or DBD author!\n";
}
}
$count+=$found_rows;
@@ -280,44 +280,125 @@ $end_time=new Benchmark;
print "Time for select_big ($small_loop_count:$count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
+#
+# Do a lot of different ORDER BY queries
+#
+
$loop_time=new Benchmark;
-$estimated=0;
-$rows=0;
-$count=0;
-for ($i=1 ; $i <= $small_loop_count/2 ; $i++)
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$rows+=fetch_all_rows($dbh,"select id from bench1 order by id",1);
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
+ $small_loop_count));
+}
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for order_by_big_key ($small_loop_count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+$loop_time=new Benchmark;
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
+{
$rows+=fetch_all_rows($dbh,"select id from bench1 order by id desc",1);
- $count+=2;
$end_time=new Benchmark;
- last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
-print " for order_by_key ($count:$rows): " .
+print " for order_by_big_key_desc ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
-$estimated=0;
-$rows=0;
-$count=0;
-for ($i=1 ; $i <= $small_loop_count/2 ; $i++)
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
{
- $rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id2",1);
- $rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id2 desc",1);
- $count+=2;
+ $rows+=fetch_all_rows($dbh,"select id3 from bench1 order by id3",1);
$end_time=new Benchmark;
- last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
+ $small_loop_count));
+}
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for order_by_big_key2 ($small_loop_count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+$loop_time=new Benchmark;
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
+{
+ $rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id3",1);
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
-print " for order_by ($count:$rows): " .
+print " for order_by_big_key_diff ($small_loop_count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+
+$loop_time=new Benchmark;
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
+{
+ $rows+=fetch_all_rows($dbh,"select id from bench1 order by id2,id3",1);
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
+ $small_loop_count));
+}
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for order_by_big ($small_loop_count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+$loop_time=new Benchmark;
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
+{
+ $start=$opt_loop_count/$small_loop_count*$i;
+ $end=$start+$i;
+ $rows+=fetch_all_rows($dbh,"select dummy1 from bench1 where id>=$start and id <= $end order by id",1);
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
+ $small_loop_count));
+}
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for order_by_key ($small_loop_count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+$loop_time=new Benchmark;
+$estimated=$rows=0;
+for ($i=1 ; $i <= $small_loop_count ; $i++)
+{
+ $start=$opt_loop_count/$small_loop_count*$i;
+ $end=$start+$small_loop_count;
+ $rows+=fetch_all_rows($dbh,"select id2 from bench1 where id3>=$start and id3 <= $end order by id3",1);
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
+ $small_loop_count));
+}
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for order_by_key2_diff ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
#
@@ -417,6 +498,7 @@ if ($limits->{'group_functions'})
$loop_time=new Benchmark;
$count=1;
+ $estimated=0;
for ($tests=0 ; $tests < $small_loop_count ; $tests++)
{
$sth=$dbh->prepare($query="select count(*) from bench1") or die $DBI::errstr;
@@ -492,9 +574,12 @@ if ($limits->{'group_functions'})
print "Warning: '$query' returned wrong number of rows\n";
}
}
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$tests,
+ $small_loop_count));
}
- $end_time=new Benchmark;
- print "Time for select_group ($count): " .
+ print_time($estimated);
+ print " for select_group ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh
index 160a10a1c33..32059d6ac8a 100755
--- a/sql-bench/test-select.sh
+++ b/sql-bench/test-select.sh
@@ -205,10 +205,7 @@ for ($i=0 ; $i < $opt_small_loop_count ; $i++)
$opt_small_loop_count));
}
-if ($estimated)
-{ print "Estimated time"; }
-else
-{ print "Time"; }
+print_time($estimated);
print " for select_range ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
@@ -243,10 +240,7 @@ if ($limits->{'group_functions'})
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,
$tests+1, $opt_loop_count));
}
- if ($estimated)
- { print "Estimated time"; }
- else
- { print "Time"; }
+ print_time($estimated);
print " for min_max_on_key ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
@@ -267,10 +261,7 @@ if ($limits->{'group_functions'})
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,
$tests+1, $opt_loop_count));
}
- if ($estimated)
- { print "Estimated time"; }
- else
- { print "Time"; }
+ print_time($estimated);
print " for count_on_key ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -278,7 +269,7 @@ if ($limits->{'group_functions'})
$rows=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
- fetch_all_rows($dbh,"select grp,count(*) from bench1 group by grp");
+ $rows+=fetch_all_rows($dbh,"select grp,count(*) from bench1 group by grp");
}
$end_time=new Benchmark;
print "Time for count_group_on_key_parts ($i:$rows): " .
@@ -289,54 +280,74 @@ if ($limits->{'group_functions'})
{
print "Testing count(distinct) on the table\n";
$loop_time=new Benchmark;
- $rows=0;
+ $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
+ $count+=2;
$rows+=fetch_all_rows($dbh,"select count(distinct region) from bench1");
$rows+=fetch_all_rows($dbh,"select count(distinct grp) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
}
- $end_time=new Benchmark;
- print "Time for count_distinct ($i:$rows): " .
+ print_time($estimated);
+ print " for count_distinct ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
- $rows=0;
+ $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
+ $count++;
$rows+=fetch_all_rows($dbh,"select region,count(distinct idn) from bench1 group by region");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
}
- $end_time=new Benchmark;
- print "Time for count_distinct_group_on_key ($i:$rows): " .
+ print_time($estimated);
+ print " for count_distinct_group_on_key ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
- $rows=0;
+ $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
+ $count++;
$rows+=fetch_all_rows($dbh,"select grp,count(distinct idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
}
- $end_time=new Benchmark;
- print "Time for count_distinct_group_on_key_parts ($i:$rows): " .
+ print_time($estimated);
+ print " for count_distinct_group_on_key_parts ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
- $rows=0;
+ $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
+ $count++;
$rows+=fetch_all_rows($dbh,"select grp,count(distinct rev_idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
}
- $end_time=new Benchmark;
- print "Time for count_distinct_group ($i:$rows): " .
+ print_time($estimated);
+ print " for count_distinct_group ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
- $rows=0;
+ $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{
+ $count++;
$rows+=fetch_all_rows($dbh,"select idn,count(distinct region) from bench1 group by idn");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
}
- $end_time=new Benchmark;
- print "Time for count_distinct_big ($i:$rows): " .
+ print_time($estimated);
+ print " for count_distinct_big ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 6d6bbe00182..220ff69a3e8 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -38,8 +38,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
my_off_t file_pos; /* Where we are in the sort file */
- ha_rows count; /* Number of rows in table */
uchar *base,*key; /* key pointers */
+ ha_rows count; /* Number of rows in table */
ulong mem_count; /* numbers of keys in memory */
ulong max_keys; /* Max keys in buffert */
} BUFFPEK;
@@ -98,7 +98,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
BUFFPEK *buffpek;
ha_rows records;
uchar **sort_keys;
- gptr save_1,save_2;
IO_CACHE tempfile,*selected_records_file,*outfile;
SORTPARAM param;
DBUG_ENTER("filesort");
@@ -109,7 +108,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
outfile= table[0]->io_cache;
my_b_clear(&tempfile);
- save_1=save_2=0;
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
param.ref_length= table[0]->file->ref_length;
@@ -148,7 +146,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
else
{
table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */
- records=table[0]->file->records+EXTRA_RECORDS;
+ records=table[0]->file->estimate_number_of_rows();
selected_records_file= 0;
}
if (param.sort_length == param.ref_length && records > param.max_rows)
@@ -160,16 +158,11 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
#endif
- /* Reserve memory for IO_CACHE files */
- if (! (save_1=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))) ||
- ! (save_2=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))))
- goto err;
-
memavl=sortbuff_size;
while (memavl >= MIN_SORT_MEMORY)
{
- if ((records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
- (ulong) memavl)
+ if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
+ (ulonglong) memavl)
param.keys=(uint) records+1;
else
{
@@ -207,10 +200,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
goto err;
}
- my_free(save_1,MYF(0)); /* Free for later use */
- my_free(save_2,MYF(0));
- save_1=save_2=0;
-
param.sort_form= table[0];
param.end=(param.local_sortorder=sortorder)+s_length;
if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
@@ -252,8 +241,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#endif
x_free((gptr) sort_keys);
x_free((gptr) buffpek);
- x_free(save_1);
- x_free(save_2);
close_cached_file(&tempfile);
if (my_b_inited(outfile))
{
@@ -382,6 +369,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
if (*killed)
{
+ DBUG_PRINT("info",("Sort killed by user"));
(void) file->extra(HA_EXTRA_NO_CACHE);
file->rnd_end();
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 6cf97f16bb8..490a6db89e5 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -25,8 +25,9 @@
We will need an updated Berkeley DB version for this.
- Killing threads that has got a 'deadlock'
- SHOW TABLE STATUS should give more information about the table.
- - Get a more accurate count of the number of rows.
- We could store the found number of rows when the table is scanned.
+ - Get a more accurate count of the number of rows (estimate_number_of_rows()).
+ We could store the found number of rows when the table is scanned and
+ then increment the counter for each attempted write.
- We will need a manager thread that calls flush_logs, removes old
logs and makes checkpoints at given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort
@@ -42,7 +43,6 @@
- LOCK TABLES
- CHAR keys
- BLOBS
- - delete from t1;
*/
@@ -60,6 +60,7 @@
#define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_BERKELEY_RANGE_COUNT 100
+#define HA_BERKELEY_MAX_ROWS 10000000 /* Max rows in table */
const char *ha_berkeley_ext=".db";
bool berkeley_skip=0;
@@ -1297,7 +1298,7 @@ void ha_berkeley::info(uint flag)
DBUG_ENTER("info");
if (flag & HA_STATUS_VARIABLE)
{
- records = HA_BERKELEY_ROWS_IN_TABLE; // Just to get optimisations right
+ records = estimate_number_of_rows(); // Just to get optimisations right
deleted = 0;
}
else if (flag & HA_STATUS_ERRKEY)
@@ -1607,4 +1608,21 @@ void ha_berkeley::update_auto_primary_key()
pthread_mutex_unlock(&share->mutex);
}
+/*
+ Return an estimated of the number of rows in the table.
+ Used when sorting to allocate buffers and by the optimizer.
+*/
+
+ha_rows ha_berkeley::estimate_number_of_rows()
+{
+ ulonglong max_ident;
+ ulonglong max_rows=table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
+ if (!hidden_primary_key)
+ return (ha_rows) max_rows;
+ pthread_mutex_lock(&share->mutex);
+ max_ident=share->auto_ident+EXTRA_RECORDS;
+ pthread_mutex_unlock(&share->mutex);
+ return (ha_rows) min(max_ident,max_rows);
+}
+
#endif /* HAVE_BERKELEY_DB */
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 84061ae09be..1d1de613ce0 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -91,7 +91,8 @@ class ha_berkeley: public handler
uint max_keys() const { return MAX_KEY-1; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; }
- uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
+ uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
+ ha_rows estimate_number_of_rows();
bool fast_key_read() { return 1;}
bool has_transactions() { return 1;}
diff --git a/sql/handler.h b/sql/handler.h
index 84c14538f4b..bdc58ee7356 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -203,6 +203,7 @@ public:
virtual bool fast_key_read() { return 0;}
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
+ virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; }
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 8c62643b35a..8e6332d4e16 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -352,11 +352,6 @@ Item *create_func_to_days(Item* a)
return new Item_func_to_days(a);
}
-Item *create_func_truncate (Item *a, Item *b)
-{
- return new Item_func_round(a,b,1);
-}
-
Item *create_func_ucase(Item* a)
{
return new Item_func_ucase(a);
diff --git a/sql/item_create.h b/sql/item_create.h
index aa617946d98..de2726b32b0 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -81,7 +81,6 @@ Item *create_func_tan(Item* a);;
Item *create_func_time_format(Item *a, Item *b);
Item *create_func_time_to_sec(Item* a);
Item *create_func_to_days(Item* a);
-Item *create_func_truncate (Item *a, Item *b);
Item *create_func_ucase(Item* a);
Item *create_func_version(void);
Item *create_func_weekday(Item* a);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 6b8b3762aa1..39bbdcaff1f 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1598,7 +1598,7 @@ String *Item_load_file::val_str(String *str)
if (!(file_name= args[0]->val_str(str)) ||
!(current_thd->master_access & FILE_ACL) ||
- !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_FAE)))
+ !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME)))
goto err;
if (!(stat_info.st_mode & S_IROTH))
{
diff --git a/sql/lex.h b/sql/lex.h
index a75fa07c3b7..503ce6998bb 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -302,6 +302,7 @@ static SYMBOL symbols[] = {
{ "TINYTEXT", SYM(TINYTEXT),0,0},
{ "TINYINT", SYM(TINYINT),0,0},
{ "TRAILING", SYM(TRAILING),0,0},
+ { "TRUNCATE", SYM(TRUNCATE_SYM),0,0},
{ "TO", SYM(TO_SYM),0,0},
{ "TYPE", SYM(TYPE_SYM),0,0},
{ "UNION", SYM(UNION_SYM),0,0},
@@ -443,7 +444,6 @@ static SYMBOL sql_functions[] = {
{ "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)},
{ "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)},
{ "TRIM", SYM(TRIM),0,0},
- { "TRUNCATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_truncate )},
{ "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0},
diff --git a/sql/lock.cc b/sql/lock.cc
index 4c7ae8e950b..c85983b65d6 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -70,8 +70,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex);
- while (global_read_lock && ! thd->killed ||
- thd->version != refresh_version)
+ while (global_read_lock && ! thd->killed &&
+ thd->version == refresh_version)
{
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
diff --git a/sql/log.cc b/sql/log.cc
index bf99bb32f09..b3f730ce32a 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -25,8 +25,6 @@
#include <stdarg.h>
#include <m_ctype.h> // For test_if_number
-
-
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
@@ -75,26 +73,25 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(0);
}
-
-
-MYSQL_LOG::MYSQL_LOG(): file(0),index_file(0),last_time(0),query_start(0),
- name(0), log_type(LOG_CLOSED),write_error(0),inited(0),
- no_rotate(0)
+MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),
+ name(0), log_type(LOG_CLOSED),write_error(0),
+ inited(0), opened(0), no_rotate(0)
{
/*
We don't want to intialize LOCK_Log here as the thread system may
not have been initailized yet. We do it instead at 'open'.
*/
- index_file_name[0] = 0;
+ index_file_name[0] = 0;
+ bzero((char*) &log_file,sizeof(log_file));
}
MYSQL_LOG::~MYSQL_LOG()
{
if (inited)
- {
- (void) pthread_mutex_destroy(&LOCK_log);
- (void) pthread_mutex_destroy(&LOCK_index);
- }
+ {
+ (void) pthread_mutex_destroy(&LOCK_log);
+ (void) pthread_mutex_destroy(&LOCK_index);
+ }
}
void MYSQL_LOG::set_index_file_name(const char* index_file_name)
@@ -106,6 +103,7 @@ void MYSQL_LOG::set_index_file_name(const char* index_file_name)
this->index_file_name[0] = 0;
}
+
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{
if (log_type == LOG_NORMAL)
@@ -129,58 +127,60 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
const char *new_name)
{
+ MY_STAT tmp_stat;
+ char buff[512];
+ File file= -1;
+ bool do_magic;
if (!inited)
{
inited=1;
(void) pthread_mutex_init(&LOCK_log,NULL);
(void) pthread_mutex_init(&LOCK_index, NULL);
- if(log_type_arg == LOG_BIN && *fn_ext(log_name))
+ if (log_type_arg == LOG_BIN && *fn_ext(log_name))
no_rotate = 1;
}
-
+
log_type=log_type_arg;
- name=my_strdup(log_name,MYF(0));
+ if (!(name=my_strdup(log_name,MYF(MY_WME))))
+ goto err;
if (new_name)
strmov(log_file_name,new_name);
else if (generate_new_name(log_file_name, name))
- return;
+ goto err;
if (log_type == LOG_BIN && !index_file_name[0])
fn_format(index_file_name, name, mysql_data_home, ".index", 6);
db[0]=0;
- MY_STAT tmp_stat;
- bool do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
- &tmp_stat, MYF(0)));
+ do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
+ &tmp_stat, MYF(0)));
- file=my_fopen(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
- MYF(MY_WME | ME_WAITTANG));
- if (!file)
- {
- my_free(name,MYF(0));
- name=0;
- log_type=LOG_CLOSED;
- return;
- }
+ if ((file=my_open(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
+ MYF(MY_WME | ME_WAITTANG))) < 0 ||
+ init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE,
+ my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
+ goto err;
if (log_type == LOG_NORMAL)
{
+ char *end;
#ifdef __NT__
- fprintf(file, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port);
+ sprintf(buff, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port);
#else
- fprintf(file, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
+ sprintf(buff, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
#endif
- fprintf(file,"Time Id Command Argument\n");
- (void) fflush(file);
+ end=strmov(strend(buff),"Time Id Command Argument\n");
+ if (my_b_write(&log_file,buff,(uint) (end-buff)) ||
+ flush_io_cache(&log_file))
+ goto err;
}
else if (log_type == LOG_NEW)
{
time_t skr=time(NULL);
struct tm tm_tmp;
localtime_r(&skr,&tm_tmp);
-
- fprintf(file,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
+ sprintf(buff,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
my_progname,server_version,
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
@@ -188,45 +188,49 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
- (void) fflush(file);
+ if (my_b_write(&log_file,buff,(uint) strlen(buff)) ||
+ flush_io_cache(&log_file))
+ goto err;
}
else if (log_type == LOG_BIN)
{
-
// Explanation of the boolean black magic:
//
// if we are supposed to write magic number try write
// clean up if failed
// then if index_file has not been previously opened, try to open it
// clean up if failed
- if((do_magic && my_fwrite(file, (byte*)BINLOG_MAGIC, 4,
- MYF(MY_NABP|MY_WME)) ||
- (!index_file &&
- !(index_file = my_fopen(index_file_name,O_APPEND | O_BINARY | O_RDWR,
- MYF(MY_WME))))))
- {
- my_fclose(file,MYF(MY_WME));
- my_free(name,MYF(0));
- name=0;
- file=0;
- log_type=LOG_CLOSED;
- return;
- }
+
+ if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) ||
+ (index_file < 0 &&
+ (index_file = my_open(index_file_name,O_APPEND | O_BINARY | O_RDWR,
+ MYF(MY_WME))) < 0))
+ goto err;
Start_log_event s;
- s.write(file);
+ s.write(&log_file);
pthread_mutex_lock(&LOCK_index);
- my_fseek(index_file, 0L, MY_SEEK_END, MYF(MY_WME));
- fprintf(index_file, "%s\n", log_file_name);
- fflush(index_file);
+ my_write(index_file, log_file_name,strlen(log_file_name), MYF(0));
+ my_write(index_file, "\n",1, MYF(0));
pthread_mutex_unlock(&LOCK_index);
}
+ return;
+
+err:
+ if (file >= 0)
+ my_close(file,MYF(0));
+ end_io_cache(&log_file);
+ x_free(name); name=0;
+ log_type=LOG_CLOSED;
+
+ return;
+
}
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
{
pthread_mutex_lock(&LOCK_log);
- strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name));
- linfo->pos = my_ftell(file, MYF(MY_WME));
+ strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
+ linfo->pos = my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_log);
return 0;
}
@@ -234,54 +238,89 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
// if log_name is "" we stop at the first entry
int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if(!index_file) return LOG_INFO_INVALID;
+ if (index_file < 0)
+ return LOG_INFO_INVALID;
int error = 0;
char* fname = linfo->log_file_name;
int log_name_len = (uint) strlen(log_name);
+ IO_CACHE io_cache;
+ // mutex needed because we need to make sure the file pointer does not move
+ // from under our feet
pthread_mutex_lock(&LOCK_index);
- if(my_fseek(index_file, 0L, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR)
+ if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME)))
+ {
+ error = LOG_INFO_SEEK;
+ goto err;
+ }
+ for(;;)
+ {
+ uint length;
+ if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
- error = LOG_INFO_SEEK;
+ error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
goto err;
}
- for(;;)
+ // if the log entry matches, empty string matching anything
+ if (!log_name_len ||
+ (log_name_len == length+1 && fname[log_name_len] == '\n' &&
+ !memcmp(fname, log_name, log_name_len)))
{
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO;
- goto err;
- }
-
- // if the log entry matches, empty string matching anything
- if(!log_name_len || (fname[log_name_len] == '\n' &&
- !memcmp(fname, log_name, log_name_len)))
- {
- if(log_name_len)
- fname[log_name_len] = 0; // to kill \n
- else
- {
- *(strend(fname) - 1) = 0;
- }
- linfo->index_file_offset = my_ftell(index_file, MYF(MY_WME));
- break;
- }
+ fname[length-1]=0; // remove last \n
+ linfo->index_file_offset = my_b_tell(&io_cache);
+ break;
}
-
+ }
error = 0;
+
err:
pthread_mutex_unlock(&LOCK_index);
+ end_io_cache(&io_cache);
return error;
}
+
+int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
+{
+ // mutex needed because we need to make sure the file pointer does not move
+ // from under our feet
+ if (!index_file) return LOG_INFO_INVALID;
+ int error = 0;
+ char* fname = linfo->log_file_name;
+ IO_CACHE io_cache;
+ uint length;
+
+ pthread_mutex_lock(&LOCK_index);
+ if (init_io_cache(&io_cache, index_file, IO_SIZE,
+ READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
+ MYF(MY_WME)))
+ {
+ error = LOG_INFO_SEEK;
+ goto err;
+ }
+ if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
+ {
+ error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
+ goto err;
+ }
+ fname[length-1]=0; // kill /n
+ linfo->index_file_offset = my_b_tell(&io_cache);
+ error = 0;
+
+err:
+ pthread_mutex_unlock(&LOCK_index);
+ end_io_cache(&io_cache);
+ return error;
+}
+
+
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{
- if(!index_file) return LOG_INFO_INVALID;
- if(no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
+ if (index_file < 0) return LOG_INFO_INVALID;
+ if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
int error;
char fname[FN_REFLEN];
char* fname_end, *p;
@@ -290,159 +329,128 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
DYNAMIC_ARRAY logs_to_purge, logs_to_keep;
my_off_t purge_offset ;
LINT_INIT(purge_offset);
+ IO_CACHE io_cache;
+
pthread_mutex_lock(&LOCK_index);
- if(my_fseek(index_file, 0, MY_SEEK_SET,
- MYF(MY_WME) ) == MY_FILEPOS_ERROR)
- {
- error = LOG_INFO_SEEK;
- goto err;
- }
-
- if(init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
+ if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME)))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
+ if (init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
logs_to_purge_inited = 1;
- if(init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
+ if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
logs_to_keep_inited = 1;
for(;;)
+ {
+ my_off_t init_purge_offset= my_b_tell(&io_cache);
+ if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- if(feof(index_file))
- break;
- else
- error = LOG_INFO_IO;
- goto err;
- }
+ if(!io_cache.error)
+ break;
+ error = LOG_INFO_IO;
+ goto err;
+ }
- *(fname_end = (strend(fname) - 1)) = 0; // kill \n
- fname_len = (uint)(fname_end - fname);
-
- if(!memcmp(fname, to_log, fname_len + 1 ))
- {
- found_log = 1;
- purge_offset = my_ftell(index_file, MYF(MY_WME)) - fname_len - 1;
- }
+ fname[--fname_len]=0; // kill \n
+ if(!memcmp(fname, to_log, fname_len + 1 ))
+ {
+ found_log = 1;
+ purge_offset = init_purge_offset;
+ }
- if(!found_log && log_in_use(fname))
- // if one of the logs before the target is in use
- {
- error = LOG_INFO_IN_USE;
- goto err;
- }
+ // if one of the logs before the target is in use
+ if(!found_log && log_in_use(fname))
+ {
+ error = LOG_INFO_IN_USE;
+ goto err;
+ }
- p = sql_memdup(fname, (uint)(fname_end - fname) + 1);
- if((found_log) ?
- insert_dynamic(&logs_to_keep, (gptr) &p) :
- insert_dynamic(&logs_to_purge, (gptr) &p)
- )
- {
- error = LOG_INFO_MEM;
- goto err;
- }
- }
-
- if(!found_log)
+ if (!(p = sql_memdup(fname, (uint)(fname_end - fname) + 1)) ||
+ insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
+ (gptr) &p))
{
- error = LOG_INFO_EOF;
+ error = LOG_INFO_MEM;
goto err;
}
+ }
+
+ end_io_cache(&io_cache);
+ if(!found_log)
+ {
+ error = LOG_INFO_EOF;
+ goto err;
+ }
for(i = 0; i < logs_to_purge.elements; i++)
- {
- char* l;
- get_dynamic(&logs_to_purge, (gptr)&l, i);
- if(my_delete(l, MYF(MY_WME)))
- sql_print_error("Error deleting %s during purge", l);
- }
+ {
+ char* l;
+ get_dynamic(&logs_to_purge, (gptr)&l, i);
+ if (my_delete(l, MYF(MY_WME)))
+ sql_print_error("Error deleting %s during purge", l);
+ }
// if we get killed -9 here, the sysadmin would have to do a small
// vi job on the log index file after restart - otherwise, this should
// be safe
- my_fclose(index_file, MYF(MY_WME));
- if(!(index_file = my_fopen(index_file_name, O_BINARY|O_WRONLY,
- MYF(MY_WME))))
+#ifdef HAVE_FTRUNCATE
+ if (ftruncate(index_file,0))
+ {
+ sql_print_error("Ouch! Could not truncate the binlog index file \
+during log purge for write");
+ error = LOG_INFO_FATAL;
+ goto err;
+ }
+ my_seek(index_file, 0, MY_SEEK_CUR,MYF(MY_WME));
+#else
+ my_close(index_file, MYF(MY_WME));
+ my_delete(index_file_name, MYF(MY_WME));
+ if(!(index_file = my_open(index_file_name, O_BINARY | O_RDWR | O_APPEND,
+ MYF(MY_WME))))
{
sql_print_error("Ouch! Could not re-open the binlog index file \
during log purge for write");
error = LOG_INFO_FATAL;
goto err;
}
+#endif
for(i = 0; i < logs_to_keep.elements; i++)
+ {
+ char* l;
+ get_dynamic(&logs_to_keep, (gptr)&l, i);
+ if (my_write(index_file, l, strlen(l), MYF(MY_WME)) ||
+ my_write(index_file, "\n", 1, MYF(MY_WME)))
{
- char* l;
- get_dynamic(&logs_to_keep, (gptr)&l, i);
- fprintf(index_file, "%s\n", l);
+ error = LOG_INFO_FATAL;
+ goto err;
}
- my_fclose(index_file, MYF(MY_WME));
-
- if(!(index_file = my_fopen(index_file_name, O_BINARY|O_RDWR|O_APPEND,
- MYF(MY_WME))))
- {
- sql_print_error("Ouch! Could not re-open the binlog index file \
-during log purge for append");
- error = LOG_INFO_FATAL;
- goto err;
}
+
// now update offsets
adjust_linfo_offsets(purge_offset);
error = 0;
+
err:
pthread_mutex_unlock(&LOCK_index);
if(logs_to_purge_inited)
delete_dynamic(&logs_to_purge);
if(logs_to_keep_inited)
delete_dynamic(&logs_to_keep);
-
- return error;
-
-}
-
-int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
-{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if(!index_file) return LOG_INFO_INVALID;
- int error = 0;
- char* fname = linfo->log_file_name;
- char* end ;
-
- pthread_mutex_lock(&LOCK_index);
- if(linfo->fatal)
- {
- error = LOG_INFO_FATAL;
- goto err;
- }
-
- if(my_fseek(index_file, linfo->index_file_offset, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR)
- {
- error = LOG_INFO_SEEK;
- goto err;
- }
-
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO;
- goto err;
- }
-
- end = strend(fname) - 1;
- *end = 0; // kill /n
- linfo->index_file_offset = ftell(index_file);
- error = 0;
-err:
- pthread_mutex_unlock(&LOCK_index);
+ end_io_cache(&io_cache);
return error;
}
@@ -450,22 +458,18 @@ err:
// we assume that buf has at least FN_REFLEN bytes alloced
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{
- if(inited)
- {
- int dir_len = dirname_length(log_file_name);
- int ident_len = (uint) strlen(log_ident);
- if(dir_len + ident_len + 1 > FN_REFLEN)
- {
- buf[0] = 0;
- return; // protection agains malicious buffer overflow
- }
+ buf[0] = 0; // In case of error
+ if (inited)
+ {
+ int dir_len = dirname_length(log_file_name);
+ int ident_len = (uint) strlen(log_ident);
+ if (dir_len + ident_len + 1 > FN_REFLEN)
+ return; // protection agains malicious buffer overflow
- memcpy(buf, log_file_name, dir_len);
- memcpy(buf + dir_len, log_ident, ident_len + 1); // this takes care of \0
- // at the end
- }
- else
- buf[0] = 0;
+ memcpy(buf, log_file_name, dir_len);
+ // copy filename + end null
+ memcpy(buf + dir_len, log_ident, ident_len + 1);
+ }
}
bool MYSQL_LOG::is_active(const char* log_file_name)
@@ -475,15 +479,17 @@ bool MYSQL_LOG::is_active(const char* log_file_name)
void MYSQL_LOG::new_file()
{
- if (file)
+ // only rotate open logs that are marked non-rotatable
+ // (binlog with constant name are non-rotatable)
+ if (is_open() && ! no_rotate)
{
- if(no_rotate) // do not rotate logs that are marked non-rotatable
- return; // ( for binlog with constant name)
-
char new_name[FN_REFLEN], *old_name=name;
VOID(pthread_mutex_lock(&LOCK_log));
if (generate_new_name(new_name, name))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_log));
return; // Something went wrong
+ }
if (log_type == LOG_BIN)
{
/*
@@ -491,15 +497,13 @@ void MYSQL_LOG::new_file()
to change base names at some point.
*/
Rotate_log_event r(new_name+dirname_length(new_name));
- r.write(file);
+ r.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
name=0;
close();
open(old_name, log_type, new_name);
my_free(old_name,MYF(0));
- if (!file) // Something went wrong
- log_type=LOG_CLOSED;
last_time=query_start=0;
write_error=0;
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -514,7 +518,10 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{
va_list args;
va_start(args,format);
+ char buff[32];
VOID(pthread_mutex_lock(&LOCK_log));
+
+ /* Test if someone closed after the is_open test */
if (log_type != LOG_CLOSED)
{
time_t skr;
@@ -544,28 +551,30 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
struct tm *start;
localtime_r(&skr,&tm_tmp);
start=&tm_tmp;
- if (fprintf(file,"%02d%02d%02d %2d:%02d:%02d\t",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec) < 0)
+ /* Note that my_b_write() assumes it knows the length for this */
+ sprintf(buff,"%02d%02d%02d %2d:%02d:%02d\t",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
+ if (my_b_write(&log_file,buff,16))
error=errno;
}
- else if (fputs("\t\t",file) < 0)
+ else if (my_b_write(&log_file,"\t\t",2) < 0)
error=errno;
- if (fprintf(file,"%7ld %-10.10s",
- id,command_name[(uint) command]) < 0)
+ sprintf(buff,"%7ld %-10.10s", id,command_name[(uint) command]);
+ if (my_b_write(&log_file,buff,strlen(buff)))
error=errno;
if (format)
{
- if (fputc(' ',file) < 0 || vfprintf(file,format,args) < 0)
+ if (my_b_write(&log_file," ",1) ||
+ my_b_printf(&log_file,format,args) == (uint) -1)
error=errno;
}
- if (fputc('\n',file) < 0)
- error=errno;
- if (fflush(file) < 0)
+ if (my_b_write(&log_file,"\n",1) ||
+ flush_io_cache(&log_file))
error=errno;
if (error && ! write_error)
{
@@ -585,7 +594,7 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (is_open())
{
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{
THD *thd=event_info->thd;
if ((!(thd->options & OPTION_BIN_LOG) &&
@@ -599,43 +608,38 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (thd->last_insert_id_used)
{
Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
- if (e.write(file))
+ if (e.write(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
}
-
if (thd->insert_id_used)
{
Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
- if(e.write(file))
+ if (e.write(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
}
-
- if(thd->convert_set)
+ if (thd->convert_set)
+ {
+ char buf[1024] = "SET CHARACTER SET ";
+ char* p = strend(buf);
+ p = strmov(p, thd->convert_set->name);
+ int save_query_length = thd->query_length;
+ // just in case somebody wants it later
+ thd->query_length = (uint)(p - buf);
+ Query_log_event e(thd, buf);
+ if (e.write(&log_file))
{
- char buf[1024] = "SET CHARACTER SET ";
- char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
- int save_query_length = thd->query_length;
- // just in case somebody wants it later
- thd->query_length = (uint)(p - buf);
- Query_log_event e(thd, buf);
- if(e.write(file))
- {
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
- }
-
- thd->query_length = save_query_length; // clean up
-
+ sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
+ goto err;
}
-
- if (event_info->write(file))
+ thd->query_length = save_query_length; // clean up
+ }
+ if (event_info->write(&log_file) || flush_io_cache(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
@@ -651,13 +655,13 @@ void MYSQL_LOG::write(Load_log_event* event_info)
if (is_open())
{
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{
THD *thd=event_info->thd;
if ((thd->options & OPTION_BIN_LOG) ||
!(thd->master_access & PROCESS_ACL))
{
- if (event_info->write(file))
+ if (event_info->write(&log_file) || flush_io_cache(&log_file))
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
@@ -676,7 +680,7 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
{
time_t current_time;
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{ // Safety agains reopen
int error=0;
char buff[80],*end;
@@ -695,37 +699,42 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
last_time=current_time;
struct tm tm_tmp;
struct tm *start;
+ char buff[32];
localtime_r(&current_time,&tm_tmp);
start=&tm_tmp;
- if (fprintf(file,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec) < 0)
+ /* Note that my_b_write() assumes it knows the length for this */
+ sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
+ if (my_b_write(&log_file,buff,24))
error=errno;
}
- if (fprintf(file, "# User@Host: %s [%s] @ %s [%s]\n",
- thd->priv_user,
- thd->user,
- thd->host ? thd->host : "",
- thd->ip ? thd->ip : "") < 0)
- error=errno;;
+ if (my_b_printf(&log_file, "# User@Host: %s [%s] @ %s [%s]\n",
+ thd->priv_user,
+ thd->user,
+ thd->host ? thd->host : "",
+ thd->ip ? thd->ip : ""))
+ error=errno;
}
if (query_start)
{
/* For slow query log */
if (!(specialflag & SPECIAL_LONG_LOG_FORMAT))
current_time=time(NULL);
- fprintf(file,"# Time: %lu Lock_time: %lu Rows_sent: %lu\n",
- (ulong) (current_time - query_start),
- (ulong) (thd->time_after_lock - query_start),
- (ulong) thd->sent_row_count);
+ if (my_b_printf(&log_file,
+ "# Time: %lu Lock_time: %lu Rows_sent: %lu\n",
+ (ulong) (current_time - query_start),
+ (ulong) (thd->time_after_lock - query_start),
+ (ulong) thd->sent_row_count))
+ error=errno;
}
if (thd->db && strcmp(thd->db,db))
{ // Database changed
- if (fprintf(file,"use %s;\n",thd->db) < 0)
+ if (my_b_printf(&log_file,"use %s;\n",thd->db))
error=errno;
strmov(db,thd->db);
}
@@ -757,7 +766,8 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
*end++=';';
*end++='\n';
*end=0;
- if (fputs("SET ",file) < 0 || fputs(buff+1,file) < 0)
+ if (my_b_write(&log_file,"SET ",4) ||
+ my_b_write(&log_file,buff+1,(uint) (end-buff)-1))
error=errno;
}
if (!query)
@@ -765,10 +775,9 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
query="#adminstrator command";
query_length=21;
}
- if (my_fwrite(file,(byte*) query,query_length,MYF(MY_NABP)) ||
- fputc(';',file) < 0 || fputc('\n',file) < 0)
- error=errno;
- if (fflush(file) < 0)
+ if (my_b_write(&log_file,(byte*) query,query_length) ||
+ my_b_write(&log_file,";\n",2) ||
+ flush_io_cache(&log_file))
error=errno;
if (error && ! write_error)
{
@@ -780,51 +789,48 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
}
}
-
-
+#ifdef TO_BE_REMOVED
void MYSQL_LOG::flush()
{
- if (file)
- if (fflush(file) < 0 && ! write_error)
+ if (is_open())
+ if (flush_io_cache(log_file) && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
}
+#endif
void MYSQL_LOG::close(bool exiting)
{ // One can't set log_type here!
- if (file)
+ if (is_open())
{
+ File file=log_file.file;
if (log_type == LOG_BIN)
{
Stop_log_event s;
- s.write(file);
+ s.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
- if (my_fclose(file,MYF(0)) < 0 && ! write_error)
+ end_io_cache(&log_file);
+ if (my_close(file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
- file=0;
- }
- if (name)
- {
- my_free(name,MYF(0));
- name=0;
+ log_type=LOG_CLOSED;
}
-
- if (exiting && index_file)
+ if (exiting && index_file >= 0)
{
- if (my_fclose(index_file,MYF(0)) < 0 && ! write_error)
+ if (my_close(index_file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
index_file=0;
}
+ safeFree(name);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fc7ed2c5680..9e739da1c9d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -26,84 +26,78 @@
static void pretty_print_char(FILE* file, int c)
{
fputc('\'', file);
- switch(c)
- {
- case '\n': fprintf(file, "\\n"); break;
- case '\r': fprintf(file, "\\r"); break;
- case '\\': fprintf(file, "\\\\"); break;
- case '\b': fprintf(file, "\\b"); break;
- case '\'': fprintf(file, "\\'"); break;
- case 0 : fprintf(file, "\\0"); break;
- default:
- fputc(c, file);
- break;
- }
- fputc( '\'', file);
+ switch(c) {
+ case '\n': fprintf(file, "\\n"); break;
+ case '\r': fprintf(file, "\\r"); break;
+ case '\\': fprintf(file, "\\\\"); break;
+ case '\b': fprintf(file, "\\b"); break;
+ case '\'': fprintf(file, "\\'"); break;
+ case 0 : fprintf(file, "\\0"); break;
+ default:
+ fputc(c, file);
+ break;
+ }
+ fputc('\'', file);
}
-int Query_log_event::write(FILE* file)
+int Query_log_event::write(IO_CACHE* file)
{
return query ? Log_event::write(file) : -1;
}
-int Log_event::write(FILE* file)
+int Log_event::write(IO_CACHE* file)
{
- if (write_header(file)
- || write_data(file) || fflush(file)) return -1;
- return 0;
+ return (write_header(file) || write_data(file)) ? -1 : 0;
}
-int Log_event::write_header(FILE* file)
+int Log_event::write_header(IO_CACHE* file)
{
- char buf[LOG_EVENT_HEADER_LEN];
// make sure to change this when the header gets bigger
+ char buf[LOG_EVENT_HEADER_LEN];
char* pos = buf;
int4store(pos, when); // timestamp
pos += 4;
*pos++ = get_type_code(); // event type code
int4store(pos, server_id);
pos += 4;
- int4store(pos, get_data_size() + LOG_EVENT_HEADER_LEN);
+ long tmp=get_data_size() + LOG_EVENT_HEADER_LEN;
+ int4store(pos, tmp);
pos += 4;
- return (my_fwrite(file, (byte*) buf, (uint) (pos - buf),
- MYF(MY_NABP | MY_WME)));
+ return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
}
#ifndef MYSQL_CLIENT
-int Log_event::read_log_event(FILE* file, String* packet,
+int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
ulong data_len;
char buf[LOG_EVENT_HEADER_LEN];
- if(log_lock)
+ if (log_lock)
pthread_mutex_lock(log_lock);
- if (my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP)))
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return feof(file) ? LOG_READ_EOF: LOG_READ_IO;
- }
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ }
data_len = uint4korr(buf + EVENT_LEN_OFFSET);
if (data_len < LOG_EVENT_HEADER_LEN || data_len > MAX_EVENT_LEN)
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return LOG_READ_BOGUS;
- }
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return LOG_READ_BOGUS;
+ }
packet->append(buf, sizeof(buf));
data_len -= LOG_EVENT_HEADER_LEN;
- if (!data_len)
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return 0; // the event does not have a data section
- }
- if (packet->append(file, data_len, MYF(MY_WME|MY_NABP)))
+ if (data_len)
+ {
+ if (packet->append(file, data_len))
{
if(log_lock)
pthread_mutex_unlock(log_lock);
- return feof(file) ? LOG_READ_TRUNC: LOG_READ_IO;
+ return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
}
-
- if(log_lock) pthread_mutex_unlock(log_lock);
+ }
+ if (log_lock) pthread_mutex_unlock(log_lock);
return 0;
}
@@ -111,18 +105,18 @@ int Log_event::read_log_event(FILE* file, String* packet,
// allocates memory - the caller is responsible for clean-up
-Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
+Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock)
{
time_t timestamp;
uint32 server_id;
char buf[LOG_EVENT_HEADER_LEN-4];
if(log_lock) pthread_mutex_lock(log_lock);
- if (my_fread(file, (byte *) buf, sizeof(buf), MY_NABP))
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return NULL;
- }
+ if (my_b_read(file, (byte *) buf, sizeof(buf)))
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return NULL;
+ }
timestamp = uint4korr(buf);
server_id = uint4korr(buf + 5);
@@ -132,13 +126,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{
Query_log_event* q = new Query_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock);
-
if (!q->query)
{
delete q;
- return NULL;
+ q=NULL;
}
-
return q;
}
@@ -146,13 +138,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{
Load_log_event* l = new Load_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock);
-
if (!l->table_name)
{
delete l;
- return NULL;
+ l=NULL;
}
-
return l;
}
@@ -165,9 +155,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (!r->new_log_ident)
{
delete r;
- return NULL;
+ r=NULL;
}
-
return r;
}
@@ -179,9 +168,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (e->type == INVALID_INT_EVENT)
{
delete e;
- return NULL;
+ e=NULL;
}
-
return e;
}
@@ -198,12 +186,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
return e;
}
default:
- if(log_lock) pthread_mutex_unlock(log_lock);
- return NULL;
+ break;
}
- //impossible
- if(log_lock) pthread_mutex_unlock(log_lock);
+ // default
+ if (log_lock) pthread_mutex_unlock(log_lock);
return NULL;
}
@@ -264,7 +251,7 @@ void Log_event::print_header(FILE* file)
{
fputc('#', file);
print_timestamp(file);
- fprintf(file, " server id %d ", server_id);
+ fprintf(file, " server id %ld ", server_id);
}
void Log_event::print_timestamp(FILE* file, time_t* ts)
@@ -323,26 +310,24 @@ void Rotate_log_event::print(FILE* file, bool short_form)
fflush(file);
}
-Rotate_log_event::Rotate_log_event(FILE* file, time_t when_arg,
+Rotate_log_event::Rotate_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id):
Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0)
{
char *tmp_ident;
char buf[4];
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return;
-
ulong event_len;
event_len = uint4korr(buf);
- if(event_len < ROTATE_EVENT_OVERHEAD)
+ if (event_len < ROTATE_EVENT_OVERHEAD)
return;
ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
-
if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME))))
return;
- if (my_fread( file, (byte*) tmp_ident, (uint)ident_len, MYF(MY_NABP | MY_WME)))
+ if (my_b_read( file, (byte*) tmp_ident, (uint) ident_len))
{
my_free((gptr) tmp_ident, MYF(0));
return;
@@ -376,21 +361,18 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len):
alloced = 1;
}
-int Rotate_log_event::write_data(FILE* file)
+int Rotate_log_event::write_data(IO_CACHE* file)
{
- if (my_fwrite(file, (byte*) new_log_ident, (uint) ident_len,
- MYF(MY_NABP | MY_WME)))
- return -1;
- return 0;
+ return my_b_write(file, (byte*) new_log_ident, (uint) ident_len) ? -1 :0;
}
-Query_log_event::Query_log_event(FILE* file, time_t when_arg,
+Query_log_event::Query_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id):
Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL)
{
char buf[QUERY_HEADER_LEN + 4];
ulong data_len;
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return; // query == NULL will tell the
// caller there was a problem
data_len = uint4korr(buf);
@@ -402,9 +384,10 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db_len = (uint)buf[12];
error_code = uint2korr(buf + 13);
+ /* Allocate one byte extra for end \0 */
if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
return;
- if (my_fread( file, (byte*) data_buf, data_len, MYF(MY_NABP | MY_WME)))
+ if (my_b_read( file, (byte*) data_buf, data_len))
{
my_free((gptr) data_buf, MYF(0));
data_buf = 0;
@@ -415,21 +398,22 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db = data_buf;
query=data_buf + db_len + 1;
q_len = data_len - 1 - db_len;
- *((char*)query + q_len) = 0;
+ *((char*) query + q_len) = 0; // Safety
}
Query_log_event::Query_log_event(const char* buf, int event_len):
Log_event(buf),data_buf(0), query(NULL), db(NULL)
{
- if ((uint)event_len < QUERY_EVENT_OVERHEAD)
+ if (event_len < QUERY_EVENT_OVERHEAD)
return;
ulong data_len;
buf += EVENT_LEN_OFFSET;
data_len = event_len - QUERY_EVENT_OVERHEAD;
+
exec_time = uint4korr(buf + 8);
error_code = uint2korr(buf + 13);
- if (!(data_buf = (char*) my_malloc( data_len + 1, MYF(MY_WME))))
+ if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME))))
return;
memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len);
@@ -456,9 +440,9 @@ void Query_log_event::print(FILE* file, bool short_form)
fprintf(file, ";\n");
}
-int Query_log_event::write_data(FILE* file)
+int Query_log_event::write_data(IO_CACHE* file)
{
- if(!query) return -1;
+ if (!query) return -1;
char buf[QUERY_HEADER_LEN];
char* pos = buf;
@@ -470,23 +454,21 @@ int Query_log_event::write_data(FILE* file)
int2store(pos, error_code);
pos += 2;
- if (my_fwrite(file, (byte*) buf, (uint)(pos - buf), MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (db) ? (byte*) db : (byte*)"",
- db_len + 1, MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)))
- return -1;
- return 0;
+ return (my_b_write(file, (byte*) buf, (uint)(pos - buf)) ||
+ my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
+ my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
}
-Intvar_log_event:: Intvar_log_event(FILE* file, time_t when_arg,
+Intvar_log_event:: Intvar_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id)
:Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT)
{
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
- char buf[9];
- if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME))) return;
- type = buf[0];
- val = uint8korr(buf+1);
+ char buf[9+4];
+ if (!my_b_read(file, (byte*) buf, sizeof(buf)))
+ {
+ type = buf[4];
+ val = uint8korr(buf+1+4);
+ }
}
Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
@@ -496,12 +478,12 @@ Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
val = uint8korr(buf+1);
}
-int Intvar_log_event::write_data(FILE* file)
+int Intvar_log_event::write_data(IO_CACHE* file)
{
char buf[9];
buf[0] = type;
int8store(buf + 1, val);
- return my_fwrite(file, (byte*) buf, sizeof(buf), MYF(MY_NABP|MY_WME));
+ return my_b_write(file, (byte*) buf, sizeof(buf));
}
void Intvar_log_event::print(FILE* file, bool short_form)
@@ -528,7 +510,7 @@ void Intvar_log_event::print(FILE* file, bool short_form)
}
-int Load_log_event::write_data(FILE* file __attribute__((unused)))
+int Load_log_event::write_data(IO_CACHE* file)
{
char buf[LOAD_HEADER_LEN];
int4store(buf, thread_id);
@@ -538,87 +520,63 @@ int Load_log_event::write_data(FILE* file __attribute__((unused)))
buf[13] = (char)db_len;
int4store(buf + 14, num_fields);
- if(my_fwrite(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME)))
+ if(my_b_write(file, (byte*)buf, sizeof(buf)) ||
+ my_b_write(file, (byte*)&sql_ex, sizeof(sql_ex)))
return 1;
- if(num_fields && fields && field_lens)
- {
- if(my_fwrite(file, (byte*)field_lens, num_fields, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)fields, field_block_len, MYF(MY_NABP|MY_WME)))
- return 1;
- }
-
- if(my_fwrite(file, (byte*)table_name, table_name_len + 1, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)db, db_len + 1, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)fname, fname_len, MYF(MY_NABP|MY_WME)) )
+ if (num_fields && fields && field_lens)
+ {
+ if(my_b_write(file, (byte*)field_lens, num_fields) ||
+ my_b_write(file, (byte*)fields, field_block_len))
+ return 1;
+ }
+ if(my_b_write(file, (byte*)table_name, table_name_len + 1) ||
+ my_b_write(file, (byte*)db, db_len + 1) ||
+ my_b_write(file, (byte*)fname, fname_len))
return 1;
-
-
return 0;
}
-Load_log_event::Load_log_event(FILE* file, time_t when, uint32 server_id):
+Load_log_event::Load_log_event(IO_CACHE* file, time_t when, uint32 server_id):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0),
fields(0),field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
-
{
char buf[LOAD_HEADER_LEN + 4];
ulong data_len;
- if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) ||
- my_fread(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME)))
- return;
-
- data_len = uint4korr(buf);
- thread_id = uint4korr(buf+4);
- exec_time = uint4korr(buf+8);
- skip_lines = uint4korr(buf + 12);
- table_name_len = (uint)buf[16];
- db_len = (uint)buf[17];
- num_fields = uint4korr(buf + 18);
-
- data_len -= LOAD_EVENT_OVERHEAD;
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (my_b_read(file, (byte*)buf, sizeof(buf)) ||
+ my_b_read(file, (byte*)&sql_ex, sizeof(sql_ex)))
return;
- if(my_fread(file, (byte*)data_buf, data_len, MYF(MY_NABP|MY_WME)))
+ data_len = uint4korr(buf) - LOAD_EVENT_OVERHEAD;
+ if (!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
return;
-
- if(num_fields > data_len) // simple sanity check against corruption
+ if (my_b_read(file, (byte*)data_buf, data_len))
return;
-
- field_lens = (uchar*)data_buf;
-
- uint i;
- for(i = 0; i < num_fields; i++)
- {
- field_block_len += (uint)field_lens[i] + 1;
- }
- fields = (char*)field_lens + num_fields;
-
- *((char*)data_buf+data_len) = 0;
- table_name = fields + field_block_len;
- db = table_name + table_name_len + 1;
- fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len;
+ copy_log_event(buf,data_len);
}
Load_log_event::Load_log_event(const char* buf, int event_len):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
-
{
ulong data_len;
- if((uint)event_len < (LOAD_EVENT_OVERHEAD + LOG_EVENT_HEADER_LEN))
+ if(event_len < (LOAD_EVENT_OVERHEAD + LOG_EVENT_HEADER_LEN))
return;
buf += EVENT_LEN_OFFSET;
-
data_len = event_len;
+ if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ return;
+ memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
+ copy_log_event(buf, data_len);
+}
+
+void Load_log_event::copy_log_event(const char *buf, ulong data_len)
+{
thread_id = uint4korr(buf+4);
exec_time = uint4korr(buf+8);
skip_lines = uint4korr(buf + 12);
@@ -626,32 +584,23 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
db_len = (uint)buf[17];
num_fields = uint4korr(buf + 18);
- data_len -= LOAD_EVENT_OVERHEAD;
- memcpy(&sql_ex, buf + 22, sizeof(sql_ex));
-
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (num_fields > data_len) // simple sanity check against corruption
return;
- memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
-
- if(num_fields > data_len) // simple sanity check against corruption
- return;
-
- field_lens = (uchar*)data_buf;
-
+ field_lens = (uchar*) data_buf;
uint i;
- for(i = 0; i < num_fields; i++)
- {
- field_block_len += (uint)field_lens[i] + 1;
- }
+ for (i = 0; i < num_fields; i++)
+ {
+ field_block_len += (uint)field_lens[i] + 1;
+ }
fields = (char*)field_lens + num_fields;
*((char*)data_buf+data_len) = 0;
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len;
-
+ fname_len = data_len - 2 - db_len - table_name_len - num_fields -
+ field_block_len;
}
@@ -708,23 +657,23 @@ void Load_log_event::print(FILE* file, bool short_form)
}
if((int)skip_lines > 0)
- fprintf(file, " IGNORE %d LINES ", skip_lines);
+ fprintf(file, " IGNORE %ld LINES ", skip_lines);
- if(num_fields)
+ if (num_fields)
+ {
+ uint i;
+ const char* field = fields;
+ fprintf( file, " (");
+ for(i = 0; i < num_fields; i++)
{
- uint i;
- const char* field = fields;
- fprintf( file, " (");
- for(i = 0; i < num_fields; i++)
- {
- if(i)
- fputc(',', file);
- fprintf(file, field);
+ if(i)
+ fputc(',', file);
+ fprintf(file, field);
- field += field_lens[i] + 1;
- }
- fputc(')', file);
+ field += field_lens[i] + 1;
}
+ fputc(')', file);
+ }
fprintf(file, ";\n");
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 0e4121eb354..e5b52377f8d 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -65,9 +65,9 @@ public:
int valid_exec_time; // if false, the exec time setting is bogus
uint32 server_id;
- int write(FILE* file);
- int write_header(FILE* file);
- virtual int write_data(FILE* file __attribute__((unused))) { return 0; }
+ int write(IO_CACHE* file);
+ int write_header(IO_CACHE* file);
+ virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
virtual Log_event_type get_type_code() = 0;
Log_event(time_t when_arg, ulong exec_time_arg = 0,
int valid_exec_time_arg = 0, uint32 server_id = 0): when(when_arg),
@@ -92,11 +92,11 @@ public:
void print_header(FILE* file);
// if mutex is 0, the read will proceed without mutex
- static Log_event* read_log_event(FILE* file, pthread_mutex_t* log_lock);
+ static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
static Log_event* read_log_event(const char* buf, int event_len);
#ifndef MYSQL_CLIENT
- static int read_log_event(FILE* file, String* packet,
+ static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock);
#endif
@@ -132,18 +132,18 @@ public:
}
#endif
- Query_log_event(FILE* file, time_t when, uint32 server_id);
+ Query_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Query_log_event(const char* buf, int event_len);
~Query_log_event()
{
if (data_buf)
{
- my_free((gptr)data_buf, MYF(0));
+ my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return QUERY_EVENT; }
- int write(FILE* file);
- int write_data(FILE* file); // returns 0 on success, -1 on error
+ int write(IO_CACHE* file);
+ int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
int get_data_size()
{
return q_len + db_len + 2 +
@@ -183,6 +183,8 @@ class Load_log_event: public Log_event
{
protected:
char* data_buf;
+ void Load_log_event::copy_log_event(const char *buf, ulong data_len);
+
public:
int thread_id;
uint32 table_name_len;
@@ -272,17 +274,17 @@ public:
void set_fields(List<Item> &fields);
#endif
- Load_log_event(FILE* file, time_t when, uint32 server_id);
+ Load_log_event(IO_CACHE * file, time_t when, uint32 server_id);
Load_log_event(const char* buf, int event_len);
~Load_log_event()
{
if (data_buf)
{
- my_free((gptr)data_buf, MYF(0));
+ my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return LOAD_EVENT; }
- int write_data(FILE* file); // returns 0 on success, -1 on error
+ int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
int get_data_size()
{
return table_name_len + 2 + db_len + 2 + fname_len
@@ -311,30 +313,26 @@ public:
created = (uint32) when;
memcpy(server_version, ::server_version, sizeof(server_version));
}
- Start_log_event(FILE* file, time_t when_arg, uint32 server_id) :
+ Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id) :
Log_event(when_arg, 0, 0, server_id)
{
char buf[sizeof(server_version) + sizeof(binlog_version) +
- sizeof(created)];
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ sizeof(created)+4];
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return;
- binlog_version = uint2korr(buf);
- memcpy(server_version, buf + 2, sizeof(server_version));
- created = uint4korr(buf + 2 + sizeof(server_version));
+ binlog_version = uint2korr(buf+4);
+ memcpy(server_version, buf + 6, sizeof(server_version));
+ created = uint4korr(buf + 6 + sizeof(server_version));
}
Start_log_event(const char* buf);
~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;}
- int write_data(FILE* file)
+ int write_data(IO_CACHE* file)
{
- if(my_fwrite(file, (byte*) &binlog_version, sizeof(binlog_version),
- MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) server_version, sizeof(server_version),
- MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) &created, sizeof(created),
- MYF(MY_NABP | MY_WME)))
+ if (my_b_write(file, (byte*) &binlog_version, sizeof(binlog_version)) ||
+ my_b_write(file, (byte*) server_version, sizeof(server_version)) ||
+ my_b_write(file, (byte*) &created, sizeof(created)))
return -1;
return 0;
}
@@ -354,12 +352,12 @@ public:
Intvar_log_event(uchar type_arg, ulonglong val_arg)
:Log_event(time(NULL)),val(val_arg),type(type_arg)
{}
- Intvar_log_event(FILE* file, time_t when, uint32 server_id);
+ Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Intvar_log_event(const char* buf);
~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;}
int get_data_size() { return sizeof(type) + sizeof(val);}
- int write_data(FILE* file);
+ int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0);
@@ -370,10 +368,11 @@ class Stop_log_event: public Log_event
public:
Stop_log_event() :Log_event(time(NULL))
{}
- Stop_log_event(FILE* file, time_t when_arg, uint32 server_id):
+ Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
Log_event(when_arg,0,0,server_id)
{
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
+ char skip[4];
+ my_b_read(file, skip, sizeof(skip)); // skip the event length
}
Stop_log_event(const char* buf):Log_event(buf)
{
@@ -397,7 +396,7 @@ public:
alloced(0)
{}
- Rotate_log_event(FILE* file, time_t when, uint32 server_id) ;
+ Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id) ;
Rotate_log_event(const char* buf, int event_len);
~Rotate_log_event()
{
@@ -406,7 +405,7 @@ public:
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len;}
- int write_data(FILE* file);
+ int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0);
};
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index 49df40adaf6..47c00a8ac00 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -32,17 +32,19 @@
#define MAP_TO_USE_RAID
#include "mysql_priv.h"
-#include <mysys_err.h>
#ifdef HAVE_AIOWAIT
+#include <mysys_err.h>
#include <errno.h>
static void my_aiowait(my_aio_result *result);
#endif
- /* if cachesize == 0 then use default cachesize (from s-file) */
- /* returns 0 if we have enough memory */
-
extern "C" {
+ /*
+ ** if cachesize == 0 then use default cachesize (from s-file)
+ ** if file == -1 then real_open_cached_file() will be called.
+ ** returns 0 if ok
+ */
int init_io_cache(IO_CACHE *info, File file, uint cachesize,
enum cache_type type, my_off_t seek_offset,
@@ -60,20 +62,26 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE)
{ /* Assume file isn't growing */
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ if (cache_myflags & MY_DONT_CHECK_FILESIZE)
+ {
+ cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
+ }
+ else
{
- cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
+ my_off_t file_pos,end_of_file;
+ if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
+ DBUG_RETURN(1);
+ end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
+ if (end_of_file < seek_offset)
+ end_of_file=seek_offset;
+ VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
+ if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ {
+ cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
+ use_async_io=0; /* No nead to use async */
+ }
}
}
-
if ((int) type < (int) READ_NET)
{
for (;;)
@@ -167,7 +175,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
DBUG_ENTER("reinit_io_cache");
info->seek_not_done= test(info->file >= 0); /* Seek not done */
- if (!clear_cache && seek_offset >= info->pos_in_file &&
+ if (! clear_cache &&
+ seek_offset >= info->pos_in_file &&
seek_offset <= info->pos_in_file +
(uint) (info->rc_end - info->rc_request_pos))
{ /* use current buffer */
@@ -231,6 +240,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
uint length,diff_length,left_length;
my_off_t max_length, pos_in_file;
+
memcpy(Buffer,info->rc_pos,
(size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
Buffer+=left_length;
@@ -607,7 +617,9 @@ int flush_io_cache(IO_CACHE *info)
length=(uint) (info->rc_pos - info->buffer);
if (info->seek_not_done)
{ /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
+ if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ MY_FILEPOS_ERROR)
+ DBUG_RETURN((info->error= -1));
info->seek_not_done=0;
}
info->rc_pos=info->buffer;
@@ -644,4 +656,4 @@ int end_io_cache(IO_CACHE *info)
DBUG_RETURN(error);
} /* end_io_cache */
-}
+} /* extern "C" */
diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc
index ee736d72792..fe90a814714 100644
--- a/sql/mysqlbinlog.cc
+++ b/sql/mysqlbinlog.cc
@@ -55,7 +55,7 @@ static struct option long_options[] =
{"password", required_argument,0, 'p'},
{"position", required_argument,0, 'j'},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'}
+ {"debug", optional_argument, 0, '#'}
#endif
};
@@ -151,7 +151,7 @@ static int parse_args(int *argc, char*** argv)
{
int c, opt_index = 0;
- while((c = getopt_long(*argc, *argv, "so:#:h:j:u:p:P:t:?", long_options,
+ while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:t:?", long_options,
&opt_index)) != EOF)
{
switch(c)
@@ -310,86 +310,106 @@ Unfortunately, no sweepstakes today, adjusted position to 4\n");
static void dump_local_log_entries(const char* logname)
{
- FILE* file;
- int rec_count = 0;
-
- if(logname && logname[0] != '-')
- file = my_fopen(logname, O_RDONLY|O_BINARY, MYF(MY_WME));
- else
- file = stdin;
-
- if(!file)
- die("Could not open log file %s", logname);
-
- if(my_fseek(file, position, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR)
- die("failed on my_fseek()");
-
- if(!position)
- {
- char magic[4];
- if (my_fread(file, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- die("I/O error reading binlog magic number");
- if(memcmp(magic, BINLOG_MAGIC, 4))
- die("Bad magic number");
+ File fd;
+ IO_CACHE cache,*file= &cache;
+ int rec_count = 0;
+
+ if (logname && logname[0] != '-')
+ {
+ if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
+ exit(1);
+ if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0,
+ MYF(MY_WME | MY_NABP)))
+ exit(1);
+ }
+ else
+ {
+ if (init_io_cache(file, fileno(stdout), 0, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
+ exit(1);
+ if (position)
+ {
+ /* skip 'position' characters from stdout */
+ char buff[IO_SIZE];
+ my_off_t length,tmp;
+ for (length=position ; length > 0 ; length-=tmp)
+ {
+ tmp=min(length,sizeof(buff));
+ if (my_b_read(file,buff,tmp))
+ exit(1);
+ }
+ }
+ file->pos_in_file=position;
+ file->seek_not_done=0;
+ }
+
+ if (!position)
+ {
+ char magic[4];
+ if (my_b_read(file, (byte*) magic, sizeof(magic)))
+ die("I/O error reading binlog magic number");
+ if(memcmp(magic, BINLOG_MAGIC, 4))
+ die("Bad magic number");
}
- while(1)
- {
- Log_event* ev = Log_event::read_log_event(file, 0);
- if(!ev)
- if(!feof(file))
+ while(1)
+ {
+ Log_event* ev = Log_event::read_log_event(file, 0);
+ if (!ev)
+ {
+ if (file->error)
die("Could not read entry at offset %ld : Error in log format or \
read error",
- my_ftell(file, MYF(MY_WME)));
- else
- break;
-
- if(rec_count >= offset)
- ev->print(stdout, short_form);
- rec_count++;
- delete ev;
- }
-
- my_fclose(file, MYF(MY_WME));
+ my_b_tell(file));
+ break;
+ }
+ if (rec_count >= offset)
+ ev->print(stdout, short_form);
+ rec_count++;
+ delete ev;
+ }
+ my_close(fd, MYF(MY_WME));
+ end_io_cache(file);
}
+
int main(int argc, char** argv)
{
MY_INIT(argv[0]);
parse_args(&argc, (char***)&argv);
if(!argc && !table)
- {
- usage();
- return -1;
- }
+ {
+ usage();
+ return -1;
+ }
if(use_remote)
- {
- init_thr_alarm(10); // need to do this manually
- mysql = safe_connect();
- }
+ {
+ init_thr_alarm(10); // need to do this manually
+ mysql = safe_connect();
+ }
- if(table)
- {
- if(!use_remote)
- die("You must specify connection parameter to get table dump");
- char* db = (char*)table;
- char* tbl = (char*) strchr(table, '.');
- if(!tbl)
- die("You must use database.table syntax to specify the table");
- *tbl++ = 0;
- dump_remote_table(&mysql->net, db, tbl);
- }
+ if (table)
+ {
+ if(!use_remote)
+ die("You must specify connection parameter to get table dump");
+ char* db = (char*)table;
+ char* tbl = (char*) strchr(table, '.');
+ if(!tbl)
+ die("You must use database.table syntax to specify the table");
+ *tbl++ = 0;
+ dump_remote_table(&mysql->net, db, tbl);
+ }
else
- while(--argc >= 0)
+ {
+ while(--argc >= 0)
{
dump_log_entries(*(argv++));
}
-
- if(use_remote)
+ }
+ if (use_remote)
mc_mysql_close(mysql);
-
return 0;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 88a81f0fdeb..e82a7751b43 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -131,7 +131,7 @@ extern "C" int gethostname(char *name, int namelen);
#ifndef DBUG_OFF
static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
- "d:t:i:o,/tmp/mysqld.trace");
+ "d:t:i:o,/tmp/mysqld.trace");
#endif
#ifdef __NT__
@@ -157,7 +157,7 @@ static pthread_t select_thread;
static pthread_t flush_thread; // Used when debugging
static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
- opt_ansi_mode=0,opt_myisam_log=0;
+ opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi);
@@ -579,8 +579,8 @@ void unireg_abort(int exit_code)
{
if (exit_code)
sql_print_error("Aborting\n");
- (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
clean_up(); /* purecov: inspected */
+ (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
exit(exit_code); /* purecov: inspected */
}
@@ -2441,20 +2441,21 @@ struct show_var_st init_vars[]= {
#endif
{"character_set", default_charset, SHOW_CHAR},
{"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
- {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
+ {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"datadir", mysql_real_data_home, SHOW_CHAR},
{"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
{"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
{"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
{"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
- {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
{"flush_time", (char*) &flush_time, SHOW_LONG},
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
{"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
+ {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
{"language", language, SHOW_CHAR},
+ {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
#ifdef HAVE_MLOCKALL
{"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
#endif
@@ -2477,12 +2478,15 @@ struct show_var_st init_vars[]= {
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
+ {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
{"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
+ {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
{"pid_file", (char*) pidfile_name, SHOW_CHAR},
{"port", (char*) &mysql_port, SHOW_INT},
{"protocol_version", (char*) &protocol_version, SHOW_INT},
{"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
- {"server_id", (char*) &server_id, SHOW_LONG},
+ {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
+ {"server_id", (char*) &server_id, SHOW_LONG},
{"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
{"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
{"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
@@ -2491,11 +2495,11 @@ struct show_var_st init_vars[]= {
{"sort_buffer", (char*) &sortbuff_size, SHOW_LONG},
{"table_cache", (char*) &table_cache_size, SHOW_LONG},
{"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
+ {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_THR_SETCONCURRENCY
{"thread_concurrency", (char*) &concurrency, SHOW_LONG},
#endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG},
- {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_TZNAME
{"timezone", time_zone, SHOW_CHAR},
#endif
@@ -3443,7 +3447,7 @@ static int get_service_parameters()
else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 )
{
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
- opt_disable_networking = !(*lpdwValue);
+ opt_skip_show_db = !(*lpdwValue);
}
else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 )
{
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 2308aa40d52..d412b71b363 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -319,11 +319,11 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
i_string* s;
while((s=it++))
- {
- if(tmp.length())
- tmp.append(',');
- tmp.append(s->ptr);
- }
+ {
+ if(tmp.length())
+ tmp.append(',');
+ tmp.append(s->ptr);
+ }
return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5ffe96458f2..1b84f07fd1a 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -115,11 +115,17 @@ THD::THD()
ull=0;
system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root));
+#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
+ if (open_cached_file(&transactions.trans_log,
+ mysql_tempdir,LOG_PREFIX,0,MYF(MY_WME)))
+ killed=1;
+ transaction.bdb_lock_count=0;
+#endif
+ transaction.bdb_tid=0;
+
#ifdef __WIN__
real_id = 0 ;
#endif
- transaction.bdb_lock_count=0;
- transaction.bdb_tid=0;
}
THD::~THD()
@@ -138,6 +144,9 @@ THD::~THD()
close_thread_tables(this);
}
close_temporary_tables(this);
+#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
+ close_cached_file(transactions.trans_log);
+#endif
if (global_read_lock)
{
pthread_mutex_lock(&LOCK_open);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index aef4c2c5c42..bc3681e3170 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -52,16 +52,16 @@ typedef struct st_log_info
class MYSQL_LOG {
- public:
private:
pthread_mutex_t LOCK_log, LOCK_index;
- FILE *file, *index_file;
time_t last_time,query_start;
+ IO_CACHE log_file;
+ File index_file;
char *name;
- enum_log_type log_type;
+ volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
- bool write_error,inited;
+ bool write_error,inited,opened;
bool no_rotate; // for binlog - if log name can never change
// we should not try to rotate it or write any rotation events
// the user should use FLUSH MASTER instead of FLUSH LOGS for
@@ -85,7 +85,6 @@ public:
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
- void flush(void);
void close(bool exiting = 0); // if we are exiting, we also want to close the
// index file
@@ -99,7 +98,7 @@ public:
char* get_log_fname() { return log_file_name; }
void lock_index() { pthread_mutex_lock(&LOCK_index);}
void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
- FILE* get_index_file() { return index_file;}
+ File get_index_file() { return index_file;}
};
/* character conversion tables */
@@ -244,6 +243,7 @@ public:
thr_lock_type update_lock_default;
delayed_insert *di;
struct st_transactions {
+ IO_CACHE trans_log;
void *bdb_tid;
uint bdb_lock_count;
} transaction;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7195caca176..b552479bfe2 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -571,7 +571,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
thread_count++;
pthread_mutex_unlock(&LOCK_thread_count);
if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) ||
- !(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_FAE))))
+ !(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_WME))))
{
delete tmp;
thd->fatal_error=1;
@@ -1325,7 +1325,8 @@ bool select_create::send_eof()
{
VOID(pthread_mutex_lock(&LOCK_open));
mysql_unlock_tables(thd, lock);
- hash_delete(&open_cache,(byte*) table);
+ if (!table->tmp_table)
+ hash_delete(&open_cache,(byte*) table);
lock=0; table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
}
@@ -1343,7 +1344,8 @@ void select_create::abort()
if (table)
{
enum db_type table_type=table->db_type;
- hash_delete(&open_cache,(byte*) table);
+ if (!table->tmp_table)
+ hash_delete(&open_cache,(byte*) table);
quick_rm_table(table_type,db,name);
table=0;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 674da73ba5d..dd7e1cf7b30 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -34,19 +34,23 @@ class LEX_COLUMN;
#endif
enum enum_sql_command {
- SQLCOM_SELECT,SQLCOM_CREATE_TABLE,SQLCOM_CREATE_INDEX,SQLCOM_ALTER_TABLE,
- SQLCOM_UPDATE,SQLCOM_INSERT,SQLCOM_INSERT_SELECT,SQLCOM_DELETE,
- SQLCOM_DROP_TABLE,SQLCOM_DROP_INDEX,SQLCOM_SHOW_DATABASES,
- SQLCOM_SHOW_TABLES,SQLCOM_SHOW_FIELDS,SQLCOM_SHOW_KEYS,
+ SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE,
+ SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT,
+ SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX,
+
+ SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS,
+ SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS,
+ SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
+ SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE,
+
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB,
- SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_SHOW_VARIABLES,
- SQLCOM_SHOW_STATUS, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
- SQLCOM_SHOW_PROCESSLIST,SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
- SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_SHOW_GRANTS, SQLCOM_ANALYZE,
+ SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
+ SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
+ SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
+ SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
- SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_SHOW_CREATE,
- SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_CHANGE_MASTER,
+ SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 633855a18fa..9bf3346e61d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -158,7 +158,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
unpack_filename(name,ex->file_name);
#ifndef __WIN__
MY_STAT stat_info;
- if (!my_stat(name,&stat_info,MYF(MY_FAE)))
+ if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(-1);
// the file must be:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index acf055b5c74..3f21041742d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -71,6 +71,20 @@ static void init_signals(void)
}
#endif
+static inline bool end_active_trans(THD *thd)
+{
+ if (!(thd->options & OPTION_AUTO_COMMIT) ||
+ (thd->options & OPTION_BEGIN))
+ {
+ if (ha_commit(thd))
+ return 1;
+ thd->options&= ~OPTION_BEGIN;
+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
+ }
+ return 0;
+}
+
+
/*
** Check if user is ok
** Updates:
@@ -1155,8 +1169,7 @@ mysql_execute_command(void)
}
}
/* ALTER TABLE ends previous transaction */
- if ((!(thd->options & OPTION_AUTO_COMMIT) ||
- (thd->options & OPTION_BEGIN)) && ha_commit(thd))
+ if (end_active_trans(thd))
res= -1;
else
res= mysql_alter_table(thd, lex->db, lex->name,
@@ -1374,6 +1387,7 @@ mysql_execute_command(void)
break;
}
case SQLCOM_DELETE:
+ case SQLCOM_TRUNCATE:
{
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
@@ -1381,11 +1395,12 @@ mysql_execute_command(void)
goto error;
// Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
- res = mysql_delete(thd,tables,lex->where,lex->select_limit,
- lex->lock_option, lex->options);
-#ifdef DELETE_ITEMS
- delete lex->where;
-#endif
+ /* TRUNCATE ends previous transaction */
+ if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_delete(thd,tables,lex->where,lex->select_limit,
+ lex->lock_option, lex->options);
break;
}
case SQLCOM_DROP_TABLE:
@@ -1727,6 +1742,11 @@ mysql_execute_command(void)
send_ok(&thd->net);
break;
case SQLCOM_COMMIT:
+ /*
+ We don't use end_active_trans() here to ensure that this works
+ even if there is a problem with the OPTION_AUTO_COMMIT flag
+ (Which of course should never happen...)
+ */
thd->options&= ~OPTION_BEGIN;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
@@ -2449,7 +2469,7 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
bool result=0;
select_errors=0; /* Write if more errors */
- mysql_log.flush(); // Flush log
+ // mysql_log.flush(); // Flush log
if (options & REFRESH_GRANT)
{
acl_reload();
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 4142c003d4d..ba155c72e49 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -93,6 +93,40 @@ static int send_file(THD *thd)
DBUG_RETURN(error);
}
+
+static File open_log(IO_CACHE *log, const char *log_file_name,
+ const char **errmsg)
+{
+ File file;
+ char magic[4];
+ if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ *errmsg = "Could not open log file"; // This will not be sent
+ goto err;
+ }
+
+ if (my_b_read(log, (byte*) magic, sizeof(magic)))
+ {
+ *errmsg = "I/O error reading binlog magic number";
+ goto err;
+ }
+ if (memcmp(magic, BINLOG_MAGIC, 4))
+ {
+ *errmsg = "Binlog has bad magic number, fire your magician";
+ goto err;
+ }
+ return file;
+
+err:
+ if (file > 0)
+ my_close(file,MYF(0));
+ end_io_cache(log);
+ return -1;
+}
+
+
void adjust_linfo_offsets(my_off_t purge_offset)
{
THD *tmp;
@@ -119,6 +153,7 @@ void adjust_linfo_offsets(my_off_t purge_offset)
pthread_mutex_unlock(&LOCK_thread_count);
}
+
bool log_in_use(const char* log_name)
{
int log_name_len = strlen(log_name) + 1;
@@ -144,6 +179,7 @@ bool log_in_use(const char* log_name)
return result;
}
+
int purge_master_logs(THD* thd, const char* to_log)
{
char search_file_name[FN_REFLEN];
@@ -179,27 +215,29 @@ binlog purge"; break;
return 0;
}
+
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
{
LOG_INFO linfo;
char *log_file_name = linfo.log_file_name;
char search_file_name[FN_REFLEN];
- char magic[4];
- FILE* log = NULL;
+ IO_CACHE log;
+ File file = -1;
String* packet = &thd->packet;
int error;
const char *errmsg = "Unknown error";
NET* net = &thd->net;
-
DBUG_ENTER("mysql_binlog_send");
+ bzero((char*) &log,sizeof(log));
+
if(!mysql_bin_log.is_open())
- {
- errmsg = "Binary log is not open";
- goto err;
- }
+ {
+ errmsg = "Binary log is not open";
+ goto err;
+ }
- if(log_ident[0])
+ if (log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident);
else
search_file_name[0] = 0;
@@ -207,251 +245,214 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
- if(mysql_bin_log.find_first_log(&linfo, search_file_name))
- {
- errmsg = "Could not find first log";
- goto err;
- }
- log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
+ if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ {
+ errmsg = "Could not find first log";
+ goto err;
+ }
- if(!log)
- {
- errmsg = "Could not open log file";
- goto err;
- }
-
- if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- {
- errmsg = "I/O error reading binlog magic number";
- goto err;
- }
- if(memcmp(magic, BINLOG_MAGIC, 4))
- {
- errmsg = "Binlog has bad magic number, fire your magician";
- goto err;
- }
+ if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
+ goto err;
if(pos < 4)
- {
- errmsg = "Congratulations! You have hit the magic number and can win \
+ {
+ errmsg = "Contratulations! You have hit the magic number and can win \
sweepstakes if you report the bug";
- goto err;
- }
-
- if(my_fseek(log, pos, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR )
- {
- errmsg = "Error on fseek()";
- goto err;
- }
-
-
+ goto err;
+ }
+
+ my_b_seek(&log, pos); // Seek will done on next read
packet->length(0);
packet->append("\0", 1);
// we need to start a packet with something other than 255
// to distiquish it from error
while(!net->error && net->vio != 0 && !thd->killed)
- {
- pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+ {
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
- while(!(error = Log_event::read_log_event(log, packet, log_lock)))
- {
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
- {
- errmsg = "Failed on my_net_write()";
- goto err;
- }
- DBUG_PRINT("info", ("log event code %d",
- (*packet)[LOG_EVENT_OFFSET+1] ));
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if(send_file(thd))
- {
- errmsg = "failed in send_file()";
- goto err;
- }
- }
- packet->length(0);
- packet->append("\0",1);
- }
- if(error != LOG_READ_EOF)
+ while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
+ {
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ {
+ errmsg = "Failed on my_net_write()";
+ goto err;
+ }
+ DBUG_PRINT("info", ("log event code %d",
+ (*packet)[LOG_EVENT_OFFSET+1] ));
+ if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if(send_file(thd))
{
- switch(error)
- {
- case LOG_READ_BOGUS:
- errmsg = "bogus data in log event";
- break;
- case LOG_READ_IO:
- errmsg = "I/O error reading log event";
- break;
- case LOG_READ_MEM:
- errmsg = "memory allocation failed reading log event";
- break;
- case LOG_READ_TRUNC:
- errmsg = "binlog truncated in the middle of event";
- break;
- }
+ errmsg = "failed in send_file()";
goto err;
}
+ }
+ packet->length(0);
+ packet->append("\0",1);
+ }
+ if(error != LOG_READ_EOF)
+ {
+ switch(error)
+ {
+ case LOG_READ_BOGUS:
+ errmsg = "bogus data in log event";
+ break;
+ case LOG_READ_IO:
+ errmsg = "I/O error reading log event";
+ break;
+ case LOG_READ_MEM:
+ errmsg = "memory allocation failed reading log event";
+ break;
+ case LOG_READ_TRUNC:
+ errmsg = "binlog truncated in the middle of event";
+ break;
+ }
+ goto err;
+ }
- if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
- mysql_bin_log.is_active(log_file_name))
- // block until there is more data in the log
- // unless non-blocking mode requested
- {
- if(net_flush(net))
- {
- errmsg = "failed on net_flush()";
- goto err;
- }
+ if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
+ mysql_bin_log.is_active(log_file_name))
+ // block until there is more data in the log
+ // unless non-blocking mode requested
+ {
+ if(net_flush(net))
+ {
+ errmsg = "failed on net_flush()";
+ goto err;
+ }
- // we may have missed the update broadcast from the log
- // that has just happened, let's try to catch it if it did
- // if we did not miss anything, we just wait for other threads
- // to signal us
- {
- clearerr(log);
-
- // tell the kill thread how to wake us up
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex = log_lock;
- thd->mysys_var->current_cond = &COND_binlog_update;
- const char* proc_info = thd->proc_info;
- thd->proc_info = "Waiting for update";
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- bool read_packet = 0, fatal_error = 0;
-
- // no one will update the log while we are reading
- // now, but we'll be quick and just read one record
- switch(Log_event::read_log_event(log, packet, log_lock))
- {
- case 0:
- read_packet = 1;
- // we read successfully, so we'll need to send it to the
- // slave
- break;
- case LOG_READ_EOF:
- pthread_mutex_lock(log_lock);
- pthread_cond_wait(&COND_binlog_update, log_lock);
- pthread_mutex_unlock(log_lock);
- break;
-
- default:
- fatal_error = 1;
- break;
- }
-
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= proc_info;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- if(read_packet)
- {
- thd->proc_info = "sending update to slave";
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
- {
- errmsg = "Failed on my_net_write()";
- goto err;
- }
-
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if(send_file(thd))
- {
- errmsg = "failed in send_file()";
- goto err;
- }
- }
- packet->length(0);
- packet->append("\0",1);
- // no need to net_flush because we will get to flush later when
- // we hit EOF pretty quick
- }
+ // we may have missed the update broadcast from the log
+ // that has just happened, let's try to catch it if it did
+ // if we did not miss anything, we just wait for other threads
+ // to signal us
+ {
+ log.error=0;
- if(fatal_error)
- {
- errmsg = "error reading log entry";
- goto err;
- }
+ // tell the kill thread how to wake us up
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex = log_lock;
+ thd->mysys_var->current_cond = &COND_binlog_update;
+ const char* proc_info = thd->proc_info;
+ thd->proc_info = "Waiting for update";
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
- clearerr(log);
- }
- }
- else
+ bool read_packet = 0, fatal_error = 0;
+
+ // no one will update the log while we are reading
+ // now, but we'll be quick and just read one record
+ switch(Log_event::read_log_event(&log, packet, log_lock))
{
- bool loop_breaker = 0;
- // need this to break out of the for loop from switch
- thd->proc_info = "switching to next log";
- switch(mysql_bin_log.find_next_log(&linfo))
- {
- case LOG_INFO_EOF:
- loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
- break;
- case 0:
- break;
- default:
- errmsg = "could not find next log";
- goto err;
- }
+ case 0:
+ read_packet = 1;
+ // we read successfully, so we'll need to send it to the
+ // slave
+ break;
+ case LOG_READ_EOF:
+ pthread_mutex_lock(log_lock);
+ pthread_cond_wait(&COND_binlog_update, log_lock);
+ pthread_mutex_unlock(log_lock);
+ break;
+
+ default:
+ fatal_error = 1;
+ break;
+ }
- if(loop_breaker)
- break;
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ thd->proc_info= proc_info;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
- (void) my_fclose(log, MYF(MY_WME));
- log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
- if(!log)
- {
- errmsg = "Could not open next log";
- goto err;
- }
+ if(read_packet)
+ {
+ thd->proc_info = "sending update to slave";
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ {
+ errmsg = "Failed on my_net_write()";
+ goto err;
+ }
- //check the magic
- if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- {
- errmsg = "I/O error reading binlog magic number";
- goto err;
- }
- if(memcmp(magic, BINLOG_MAGIC, 4))
+ if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if(send_file(thd))
{
- errmsg = "Binlog has bad magic number, fire your magician";
+ errmsg = "failed in send_file()";
goto err;
}
-
- // fake Rotate_log event just in case it did not make it to the log
- // otherwise the slave make get confused about the offset
- {
- char header[LOG_EVENT_HEADER_LEN];
- memset(header, 0, 4); // when does not matter
- header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
- char* p = strrchr(log_file_name, FN_LIBCHAR);
- // find the last slash
- if(p)
- p++;
- else
- p = log_file_name;
-
- uint ident_len = (uint) strlen(p);
- ulong event_len = ident_len + sizeof(header);
- int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
- int4store(header + EVENT_LEN_OFFSET, event_len);
- packet->append(header, sizeof(header));
- packet->append(p,ident_len);
- if(my_net_write(net, (char*)packet->ptr(), packet->length()))
- {
- errmsg = "failed on my_net_write()";
- goto err;
- }
- packet->length(0);
- packet->append("\0",1);
}
+ packet->length(0);
+ packet->append("\0",1);
+ // no need to net_flush because we will get to flush later when
+ // we hit EOF pretty quick
+ }
+
+ if(fatal_error)
+ {
+ errmsg = "error reading log entry";
+ goto err;
+ }
+ log.error=0;
+ }
+ }
+ else
+ {
+ bool loop_breaker = 0;
+ // need this to break out of the for loop from switch
+ thd->proc_info = "switching to next log";
+ switch(mysql_bin_log.find_next_log(&linfo))
+ {
+ case LOG_INFO_EOF:
+ loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
+ break;
+ case 0:
+ break;
+ default:
+ errmsg = "could not find next log";
+ goto err;
+ }
+
+ if(loop_breaker)
+ break;
+
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
+ goto err;
+
+ // fake Rotate_log event just in case it did not make it to the log
+ // otherwise the slave make get confused about the offset
+ {
+ char header[LOG_EVENT_HEADER_LEN];
+ memset(header, 0, 4); // when does not matter
+ header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
+ char* p = strrchr(log_file_name, FN_LIBCHAR);
+ // find the last slash
+ if(p)
+ p++;
+ else
+ p = log_file_name;
+
+ uint ident_len = (uint) strlen(p);
+ ulong event_len = ident_len + sizeof(header);
+ int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
+ int4store(header + EVENT_LEN_OFFSET, event_len);
+ packet->append(header, sizeof(header));
+ packet->append(p,ident_len);
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ errmsg = "failed on my_net_write()";
+ goto err;
}
+ packet->length(0);
+ packet->append("\0",1);
+ }
}
+ }
- (void)my_fclose(log, MYF(MY_WME));
+ end_io_cache(&log);
+ (void)my_close(file, MYF(MY_WME));
send_eof(&thd->net);
thd->proc_info = "waiting to finalize termination";
@@ -461,6 +462,7 @@ sweepstakes if you report the bug";
DBUG_VOID_RETURN;
err:
thd->proc_info = "waiting to finalize termination";
+ end_io_cache(&log);
pthread_mutex_lock(&LOCK_thread_count);
// exclude iteration through thread list
// this is needed for purge_logs() - it will iterate through
@@ -469,8 +471,8 @@ sweepstakes if you report the bug";
// after we return from this stack frame
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
- if(log)
- (void) my_fclose(log, MYF(MY_WME));
+ if (file >= 0)
+ (void) my_close(file, MYF(MY_WME));
send_error(&thd->net, my_errno, errmsg);
DBUG_VOID_RETURN;
}
@@ -718,66 +720,66 @@ int show_binlog_info(THD* thd)
int show_binlogs(THD* thd)
{
const char* errmsg = 0;
- FILE* index_file;
+ File index_file;
char fname[FN_REFLEN];
NET* net = &thd->net;
List<Item> field_list;
String* packet = &thd->packet;
+ IO_CACHE io_cache;
+ uint length;
if(!mysql_bin_log.is_open())
- {
- errmsg = "binlog is not open";
- goto err;
- }
+ {
+ errmsg = "binlog is not open";
+ goto err;
+ }
field_list.push_back(new Item_empty_string("Log_name", 128));
if(send_fields(thd, field_list, 1))
- {
- sql_print_error("Failed in send_fields");
- return 1;
- }
+ {
+ sql_print_error("Failed in send_fields");
+ return 1;
+ }
mysql_bin_log.lock_index();
index_file = mysql_bin_log.get_index_file();
- if(!index_file)
- {
- errmsg = "Uninitialized index file pointer";
- mysql_bin_log.unlock_index();
- goto err;
- }
- if(my_fseek(index_file, 0, MY_SEEK_SET, MYF(MY_WME)))
- {
- errmsg = "Failed on fseek()";
- mysql_bin_log.unlock_index();
- goto err;
- }
-
- while(fgets(fname, sizeof(fname), index_file))
+ if (index_file < 0)
+ {
+ errmsg = "Uninitialized index file pointer";
+ goto err2;
+ }
+ if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ errmsg = "Failed on init_io_cache()";
+ goto err2;
+ }
+ while ((length=my_b_gets(&io_cache, fname, sizeof(fname))))
+ {
+ fname[--length]=0;
+ int dir_len = dirname_length(fname);
+ packet->length(0);
+ net_store_data(packet, fname + dir_len, length-dir_len);
+ if(my_net_write(net, (char*) packet->ptr(), packet->length()))
{
- char* fname_end;
- *(fname_end = (strend(fname) - 1)) = 0;
- int dir_len = dirname_length(fname);
- packet->length(0);
- net_store_data(packet, fname + dir_len, (fname_end - fname)-dir_len);
- if(my_net_write(net, (char*) packet->ptr(), packet->length()))
- {
- sql_print_error("Failed in my_net_write");
- mysql_bin_log.unlock_index();
- return 1;
- }
+ sql_print_error("Failed in my_net_write");
+ end_io_cache(&io_cache);
+ mysql_bin_log.unlock_index();
+ return 1;
}
+ }
mysql_bin_log.unlock_index();
+ end_io_cache(&io_cache);
send_eof(net);
- err:
- if(errmsg)
- {
- send_error(net, 0, errmsg);
- return 1;
- }
-
- send_ok(net);
return 0;
+
+err2:
+ mysql_bin_log.unlock_index();
+ end_io_cache(&io_cache);
+err:
+ send_error(net, 0, errmsg);
+ return 1;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c9de4998899..f38b1a52b65 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2735,7 +2735,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
{
for (TABLE_LIST *table=tables; table ; table=table->next)
mark_as_null_row(table->table); // All fields are NULL
- if (having && having->val_int() == 0.0)
+ if (having && having->val_int() == 0)
send_row=0;
}
if (!tables || !(result->send_fields(fields,1)))
@@ -3214,6 +3214,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
case Item::REAL_ITEM:
case Item::STRING_ITEM:
case Item::REF_ITEM:
+ case Item::NULL_ITEM:
{
bool maybe_null=item->maybe_null;
Field *new_field;
@@ -4499,7 +4500,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
int error;
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
DBUG_RETURN(0); // Didn't match having
if (join->procedure)
error=join->procedure->send_row(*join->fields);
@@ -4539,7 +4540,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error;
if (join->procedure)
{
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
else
error=join->procedure->send_row(*join->fields) ? 1 : 0;
@@ -4550,7 +4551,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!join->first_record)
clear_tables(join);
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
else
error=join->result->send_data(*join->fields) ? 1 : 0;
@@ -5109,7 +5110,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
goto err; /* purecov: inspected */
/* It's not fatal if the following alloc fails */
table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
- MYF(MY_FAE | MY_ZEROFILL));
+ MYF(MY_WME | MY_ZEROFILL));
table->status=0; // May be wrong if quick_select
// If table has a range, move it to select
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 7ca2d3c419e..4b9ebef21f1 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -95,17 +95,6 @@ bool String::realloc(uint32 alloc_length)
return FALSE;
}
-
-#ifdef NOT_NEEDED
-bool String::set(long num)
-{
- if (alloc(14))
- return TRUE;
- str_length=(uint32) (int10_to_str(num,Ptr,-10)-Ptr);
- return FALSE;
-}
-#endif
-
bool String::set(longlong num)
{
if (alloc(21))
@@ -274,6 +263,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE;
}
+#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{
if (realloc(str_length+arg_length))
@@ -286,6 +276,20 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
str_length+=arg_length;
return FALSE;
}
+#endif
+
+bool String::append(IO_CACHE* file, uint32 arg_length)
+{
+ if (realloc(str_length+arg_length))
+ return TRUE;
+ if (my_b_read(file, (byte*) Ptr + str_length, arg_length))
+ {
+ shrink(str_length);
+ return TRUE;
+ }
+ str_length+=arg_length;
+ return FALSE;
+}
uint32 String::numchars()
{
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 1c9e822cce5..f327618ffdd 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -152,7 +152,7 @@ public:
bool copy(const char *s,uint32 arg_length); // Allocate new string
bool append(const String &s);
bool append(const char *s,uint32 arg_length=0);
- bool append(FILE* file, uint32 arg_length, myf my_flags);
+ bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 26cb50009f7..540ae3e9a3f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -111,6 +111,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SLAVE
%token START_SYM
%token STOP_SYM
+%token TRUNCATE_SYM
%token ROLLBACK_SYM
%token OPTIMIZE
%token SHOW
@@ -493,9 +494,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <NONE>
query verb_clause create change select drop insert replace insert2
- insert_values update delete show describe load alter optimize flush
+ insert_values update delete truncate rename
+ show describe load alter optimize flush
reset purge begin commit rollback slave master_def master_defs
- repair restore backup analyze check rename
+ repair restore backup analyze check
field_list field_list_item field_spec kill
select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values
@@ -562,6 +564,7 @@ verb_clause:
| set
| slave
| show
+ | truncate
| unlock
| update
| use
@@ -789,7 +792,7 @@ field_list_item:
Lex->key_list.push_back(new Key($1,$2,Lex->col_list));
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
- | opt_constraint FOREIGN KEY_SYM '(' key_list ')' references
+ | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
@@ -1559,7 +1562,8 @@ simple_expr:
{ $$= new Item_func_trim($6,$4); }
| TRIM '(' expr FROM expr ')'
{ $$= new Item_func_trim($5,$3); }
-
+ | TRUNCATE_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_round($3,$5,1); }
| UDA_CHAR_SUM '(' udf_expr_list ')'
{
if ($3 != NULL)
@@ -2131,6 +2135,11 @@ opt_delete_option:
QUICK { Lex->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
+truncate:
+ TRUNCATE_SYM TABLE_SYM table
+ { Lex->sql_command= SQLCOM_TRUNCATE; Lex->options=0;
+ Lex->lock_option= current_thd->update_lock_default; }
+
/* Show things */
show: SHOW { Lex->wild=0;} show_param
@@ -2530,6 +2539,7 @@ keyword:
| STRING_SYM {}
| TEMPORARY {}
| TEXT_SYM {}
+ | TRUNCATE_SYM {}
| TIMESTAMP {}
| TIME_SYM {}
| TYPE_SYM {}
diff --git a/sql/time.cc b/sql/time.cc
index 17603d93dd4..ce4b5b0e30c 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -413,16 +413,6 @@ ulong convert_month_to_period(ulong month)
return year*100+month%12+1;
}
-#ifdef NOT_NEEDED
-
-ulong add_to_period(ulong period,int months)
-{
- if (period == 0L)
- return 0L;
- return convert_month_to_period(convert_period_to_month(period)+months);
-}
-#endif
-
/*****************************************************************************
** convert a timestamp string to a TIME value.
diff --git a/sql/violite.c b/sql/violite.c
index b18de053b5a..4efda9f3b90 100644
--- a/sql/violite.c
+++ b/sql/violite.c
@@ -1,18 +1,19 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
/*
Note that we can't have assertion on file descriptors; The reason for
@@ -31,6 +32,9 @@
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
#if defined(__EMX__)
#include <sys/ioctl.h>
@@ -398,4 +402,26 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
DBUG_VOID_RETURN;
}
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
+
#endif /* HAVE_VIO */
diff --git a/strings/strstr-sparc.s b/strings/strstr-sparc.s
index 141c3aa4209..1263236f107 100644
--- a/strings/strstr-sparc.s
+++ b/strings/strstr-sparc.s
@@ -31,7 +31,7 @@ strstr:
! if (*str++ == *search) {
! i=(char*) str; j=(char*) search+1;
- ldsb [%o1],%o2 ! g6= First char of search
+ ldsb [%o1],%o2 ! o2= First char of search
.top:
ldsb [%o0],%g3 ! g3= First char of rest of str
cmp %g3,0
@@ -70,6 +70,3 @@ strstr:
.strstr_end:
.size strstr,.strstr_end-strstr
.ident "Matt Wagner & Monty"
-
-
-