\input texinfo  @c -*-texinfo-*-
@c Copyright 1997 TcX AB, Detron HB and Monty Program KB
@c
@c *********************************************************
@c Note that @node names are used on our Website.
@c So do not change node names without checking there first.
@c *********************************************************
@c
@c %**start of header
@setfilename mysql.info
@c We want the types in the same index
@synindex tp fn
@iftex
@c Well this is normal in Europe. Maybe this shold go into the include.texi?
@afourpaper
@end iftex
@c This removes the black squares in the right margin (after debugging)
@c @finalout
@c Set background for HTML
@set _body_tags BGCOLOR=#FFFFFF TEXT=#000000 LINK=#101090 VLINK=#7030B0
@c Get version and other info
@include include.texi
@settitle @strong{MySQL} Reference Manual for version @value{mysql_version}.
@setchapternewpage off
@c %**end of header

@ifinfo
@format
START-INFO-DIR-ENTRY
* mysql: (mysql).               @strong{MySQL} documenatation.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@titlepage
@sp 10
@center @titlefont{@strong{MySQL} Reference Manual.}
@sp 10
@center Copyright @copyright{} 1997 Detron HB, TcX AB and Monty Program KB
@end titlepage

@node Top, Introduction, (dir), (dir)

@ifhtml
<IMG SRC="Images/mysql5.gif">
@end ifhtml

@ifinfo
This is a manual for @strong{MySQL}. This version is about the
@value{mysql_version} version of @strong{MySQL}. For a @strong{3.20}
version see the relevant distribution.
@end ifinfo

@menu
* Introduction::                General Information about @strong{MySQL}
* Questions::                   @strong{MySQL} mailing lists and how to ask questions/give error (bug) reports
* Licensing and Support::       Licensing or When do I have/want to pay for @strong{MySQL}?
* Installing::                  Compiling and installing @strong{MySQL}
* Compatibility::               How standards compatible are @strong{MySQL}
* Privilege system::            How does @strong{MySQL} privileges work
* Syntax::                      @strong{MySQL} language reference
* Stabilty::                    How safe/stable is @strong{MySQL}
* Server::                      @strong{MySQL} Server
* Common problems::             Solving some common problems with @strong{MySQL}
* Performance::                 How to get maximum performance out of @strong{MySQL}
* Benchmarks::                  @strong{MySQL} benchmark suite
* Tools::                       @strong{MySQL} Utilites
* Changing MySQL::              Adding functions to @strong{MySQL}
* ODBC::                        ODBC
* Problems::                    Problems
* Clients::                     @strong{MySQL} client tools and API's
* Comparasions::                How does @strong{MySQL} compare with other databases
* Users::                       
* Credits::                     Who has helped to make @strong{MySQL}.
* News::                        @strong{MySQL} change history
* Bugs::                        Known errors and design deficiencies in @strong{MySQL}
* Todo::                        List of thing we want to add to @strong{MySQL} in the future.
* Porting::                     Comments on porting to other systems.
* Regexp::                      Description of @strong{MySQL} regular expression syntax.
* Unireg::                      What is UNIREG ?
* Public::                      The @strong{MySQL} server license
* Function Index::              SQL commands and function index.
* Concept Index::               Concept Index

 --- The Detailed Node Listing ---

General Information about @strong{MySQL}

* Manual-info::                 About this manual
* What-is::                     What is @strong{MySQL}?
* History::                     History of @strong{MySQL}
* Features::                    The most important features of @strong{MySQL}
* General-SQL::                 General SQL information and tutorials
* Useful Links::                
* SQL-Words::                   What are stored procedurs and triggers and so on

@strong{MySQL} mailing lists and how to ask questions/give error (bug) reports

* Mailing-list::                Subscribing/un-subscribing from the @strong{MySQL} mailing list.
* Asking questions::            Asking questions of the mailing list.
* Bug reports::                 I think I have found a bug. What information do you need to help me?
* Answering questions::         Guidelines for answering questions on the mailing list.

I think I have found a bug. What information do you need to help me?

* Crashing::                    

Licensing or When do I have/want to pay for @strong{MySQL}?

* Cost::                        How much does @strong{MySQL} cost?
* Support ::                    How do I get support?
* Paying::                      How do I pay for a license?
* Contacting us::               Who do I contact when I want more information about licensing/support
* Copyright::                   What Copyright does @strong{MySQL} use?
* Commercial use::              When may I distribute @strong{MySQL} commercially without a fee
* User adding MySQL::           I'm selling a product that can be configured to use @strong{MySQL}
* Web server::                  I am running a commercial web server using @strong{MySQL}.
* Commercial_scripts::          Do I need a license to sell commercial perl/tcl/PHP etc applications?
* Possible license changes.::   Possible future changes in the licensing.

Compiling and installing @strong{MySQL}

* Getting it::                  How do I get @strong{MySQL}?
* Which version::               Which @strong{MySQL} version should I use?
* Many versions::               How/when will you release updates?
* Which OS::                    Which operating systems does @strong{MySQL} support?
* Installing-source::           Compiling @strong{MySQL} from source code.
* Installation problems::       Problems compiling ?
* Compilation-notes::           General compilation notes
* MIT-pthreads::                MIT-pthreads notes. (FreeBSD)
* Perl-installation::           Perl installation comments.
* Machine-OS::                  Special thing to consider with some machine/OS combinations.
* Install-binary::              Installation instructions for @strong{MySQL} binary release
* Starting MySQL::              Problems starting @strong{MySQL}
* Automatic start::             Automatic start/stop of @strong{MySQL}

Compiling @strong{MySQL} from source code.

* Quick-install::               Quick installation overview.
* Appying patches::             Applying a patch

Special thing to consider with some machine/OS combinations.

* Solaris::                     Solaris notes.
* SunOS::                       SunOS 4 notes.
* Linux::                       
* Alpha-DEC-Unix::              Alpha-DEC-Unix notes.
* Alpha-DEC-OSF1::              Alpha-DEC-OSF1 notes.
* SGI-IRIX::                    SGI-IRIX notes.
* FreeBSD::                     FreeBSD notes.
* BSDI2::                       BSDI 2.# notes
* SCO::                         SCO notes.
* IBM-AIX::                     IBM-AIX notes.

Linux notes for all versions

* Linux-x86::                   
* Linux-Sparc::                 
* Linux-Alpha::                 

FreeBSD notes.

* FreeBSD-3.0::                 FreeBSD-3.0 notes.

BSDI 2.# notes

* BSDI3::                       BSDI 3.# notes.

How standards compatible are @strong{MySQL}

* Extensions to ANSI::          What extension has @strong{MySQL} to ANSI SQL92?
* Missing functions::           What functionality is missing in @strong{MySQL}.
* Standards::                   What standards does @strong{MySQL} follow?
* Compatibility functions::     What functions exist only for compatibility?
* BLOB Limitations::            Limitations of BLOB and TEXT types
* Commit-rollback::             How to go cope without COMMIT-ROLLBACK

What functionality is missing in @strong{MySQL}.

* Missing Sub-selects::         
* Missing SELECT INTO TABLE::   
* Missing Transactions::        
* Missing Triggers::            
* Missing Foreign Keys::        
* Missing Views::               
* Missing comments::            

Foreign Keys

* Broken Foreign KEY::          

How does @strong{MySQL} privileges work

* What Privileges::             
* Privileges::                  How does the privilege system work?
* Privilege tables::            
* Adding users::                Adding new user privileges to @strong{MySQL}
* Security::                    Default privileges.
* Security example::            A example of permission setup.
* Access denied::               

@strong{MySQL} language reference

* Base Syntax::                 Literals. That is how are strings and numbers written?
* Column types::                Column types.
* Functions::                   Functions
* Create database::             Create database syntax.
* Drop database::               Drop database syntax.
* Create table::                CREATE TABLE syntax.
* Alter table::                 ALTER TABLE syntax
* Delete table::                DROP TABLE syntax.
* Delete::                      DELETE syntax.
* Select::                      SELECT syntax
* Join::                        Join syntax
* Insert::                      INSERT syntax
* Replace::                     REPLACE syntax
* Load::                        LOAD DATA INFILE syntax
* Update::                      UPDATE syntax
* Show::                        SHOW syntax. Get information about named of columns.
* Explain::                     EXPLAIN syntax. Get information about a SELECT.
* Describe::                    DESCRIBE syntax. Get information about names of columns.
* Lock tables::                 LOCK TABLES syntax.
* Set option::                  SET OPTION syntax.
* Grant::                       GRANT syntax. (Compatibility function).
* Create Index::                Create index syntax. (Compatibility function).
* Drop Index::                  Drop index syntax. (Compatibility function).
* Reserved words::              Is @strong{MySQL} picky about reserved words?

@code{NULL}

* Legal names::                 

Column types.

* Type details::                More about data types
* Choosing types::              Choosing the right type for a column.
* Indexes::                     Column indexes

Functions for use in @code{SELECT} and @code{WHERE} clauses 

* Grouping functions::          Grouping functions.
* Arithmetic functions::        Normal arithmetic operations.
* Bit functions::               Bit functions.
* Logical functions::           Logical operations.
* Comparison functions::        Comparison operators.
* String comparison functions::  String comparison functions.
* Control flow functions::      Control flow functions.
* Mathematical functions::      Mathematical functions.
* String functions::            String functions.
* Date and time functions::     Date and time functions
* Miscellaneous functions::     Miscellaneous functions.
* Group by functions::          Functions for @code{GROUP BY} clause.

How safe/stable is @strong{MySQL}

* Stability::                   How stable is @strong{MySQL}?
* Releases::                    Why are there is so many release of @strong{MySQL}?
* Check::                       How often should one check the databases.
* Repair::                      How do you check/repair/reconstruct an @strong{MySQL} table?
* Upgrade::                     Is there anything special to do when upgrading/downgrading @strong{MySQL}?

Is there anything special to do when upgrading/downgrading @strong{MySQL}?

* Upgrading-from-3.20::         

@strong{MySQL} Server functions

* Languages::                   Which languages are supported by @strong{MySQL}?
* Update log::                  The Update log
* Table size::                  How big can @strong{MySQL} tables be.

Solving some common problems with @strong{MySQL}

* Replication::                 Database replication
* Backup::                      Backup of databases

How to get maximum performance out of @strong{MySQL}

* MySQL parameters::            How does one change the size of @strong{MySQL} buffers?
* Memory use::                  How does @strong{MySQL} use memory?
* MySQL indexes::               How does @strong{MySQL} use keys?
* Where optimisations ::        What kind of optimisation is done on the WHERE clause?
* Table cache::                 How does MySQL open & close tables?
* Table efficiency::            How should I arrange my table to be as fast/small as possible?
* Insert speed::                What factors @strong{MySQL} insert statement speeds.
* Delete speed::                What affects the speed of DELETE statement?
* Optimise::                    What options to use to get @strong{MySQL} to run at full speed?
* Row format::                  What is the different row formats? Or when to use VARCHAR/CHAR?
* Open tables::                 Why so many open tables?

@strong{MySQL} Utilites

* Programs::                    What does the executables do?
* isamchk::                     The @strong{MySQL} table check, optimize and repair program
* pack_isam::                   The @strong{MySQL} compressed read only table generator

The @strong{MySQL} table check, optimize and repair program

* isamchk memory use::          
* Low-level-table-info::        Getting low level table information

Adding functions to @strong{MySQL}

* Adding functions::            Adding new functions to @strong{MySQL}

ODBC

* Which ODBC OS::               Which operating systems does @strong{MySQL} ODBC support?
* ODBC Problems::               How should I report problems with @strong{MySQL} ODBC?
* MyODBC clients::              Programs known to work with MyODBC.
* ODBC administrator::          How do I fill in the various fields in the ODBC administrator program.
* ODBC and last_insert_id::     How to get the value of a AUTO_INCREMENT column in ODBC

Problems and common errors

* Common errors::               Some common errors when using @strong{MySQL}
* Full disk::                   
* Error Access denied::         
* Changing MySQL user ::        How to run MysQL as a normal user.
* File permissions ::           Problems with file permissions.
* Using DATE::                  Problems using DATE columns.
* Case sensitivity::            Case sensitivity in searches.

Some common errors when using @strong{MySQL}

* Gone away::                   @code{MySQL server has gone away} error.
* Out of memory::               Out of memory errors
* Packet to large::             
* Full table::                  The table is full

@strong{MySQL} client tools and API's

* C API::                       @strong{MySQL} C API
* Perl::                        @strong{MySQL} Perl API's
* JAVA::                        @strong{MySQL} JAVA connectivity (JDBC)
* PHP::                         @strong{MySQL} PHP API's
* C++::                         
* Python::                      @strong{MySQL} Python API's
* TCL::                         @strong{MySQL} TCL API's

@strong{MySQL} C API

* Query Results::               After @code{mysql_query()} returns success, @code{mysql_store_result()} sometimes returns NULL.
* Result values::               What results can I get from a query?
* mysql_insert_id::             How can get the unique ID for the last row?
* mysql_use_result::            What is the difference between @code{mysql_use_result()} and @code{mysql_store_result()} modes?
* linking::                     Problems linking with C API.
* threadsafe::                  How to make a threadsafe client
* Threadsafe client::           Making a threadsafe client

@strong{MySQL} Perl API's

* Perl DBI Class::              The DBI interface
* DBI-info::                    More DBI/DBD information

How does @strong{MySQL} compare with other databases

* Compare mSQL::                How does @strong{MySQL} compare with mSQL Using mSQL
* Compare PostgreSQL::          How does @strong{MySQL} compare with PostgreSQL

How does @strong{MySQL} compare with @code{mSQL}

* Using mSQL tools::            How about mSQL tools like msql-tcl, msqljava?
* Protocol differences::        How different from @code{mSQL} are the @strong{MySQL} client/server communications protocols?
* Syntax differences::          What are the differences in the SQL syntax between @strong{MySQL} & @code{mSQL} 2.0?

@strong{MySQL} change history

* News-3.21.x::                 Changes in release 3.21.x
* News-3.20.x::                 Changes in release 3.20.x
* News-3.19.x::                 Changes in release 3.19.x

Changes in release 3.21.x

* News-3.21.19::                Changes in release 3.21.19
* News-3.21.18::                Changes in release 3.21.18
* News-3.21.17::                Changes in release 3.21.17
* News-3.21.16::                Changes in release 3.21.16
* News-3.21.15::                Changes in release 3.21.15
* News-3.21.14b::               Changes in release 3.21.14b
* News-3.21.14a::               Changes in release 3.21.14a
* News-3.21.13::                Changes in release 3.21.13
* News-3.21.12::                Changes in release 3.21.12
* News-3.21.11::                Changes in release 3.21.11
* News-3.21.10::                Changes in release 3.21.10
* News-3.21.9::                 Changes in release 3.21.9
* News-3.21.8::                 Changes in release 3.21.8
* News-3.21.7::                 Changes in release 3.21.7
* News-3.21.6::                 Changes in release 3.21.6
* News-3.21.5::                 Changes in release 3.21.5
* News-3.21.4::                 Changes in release 3.21.4
* News-3.21.3::                 Changes in release 3.21.3
* News-3.21.2::                 Changes in release 3.21.2
* News-3.21.0::                 Changes in release 3.21.0

Changes in release 3.20.x

* News-3.20.18::                Changes in release 3.20.18
* News-3.20.17::                Changes in release 3.20.17
* News-3.20.16::                Changes in release 3.20.16
* News-3.20.15::                Changes in release 3.20.15
* News-3.20.14::                Changes in release 3.20.14
* News-3.20.13::                Changes in release 3.20.13
* News-3.20.11::                Changes in release 3.20.11
* News-3.20.10::                Changes in release 3.20.10
* News-3.20.9::                 Changes in release 3.20.9
* News-3.20.8::                 Changes in release 3.20.8
* News-3.20.7::                 Changes in release 3.20.7
* News-3.20.6::                 Changes in release 3.20.6
* News-3.20.3::                 Changes in release 3.20.3
* News-3.20.0::                 Changes in releases 3.20.0

Changes in release 3.19.x

* News-3.19.5::                 Changes in release 3.19.5
* News-3.19.4::                 Changes in release 3.19.4
* News-3.19.3::                 Changes in release 3.19.3

Comments on porting to other systems.

* Debugging::                   Debugging @strong{MySQL}
* RTS-threads::                 Comments about RTS threads:
* Thread packages::             What is the difference between different thread packages?
@end menu

@cindex Overview
@cindex General Information
@node Introduction, Questions, Top, Top
@chapter General Information about @strong{MySQL}

@menu
* Manual-info::                 About this manual
* What-is::                     What is @strong{MySQL}?
* History::                     History of @strong{MySQL}
* Features::                    The most important features of @strong{MySQL}
* General-SQL::                 General SQL information and tutorials
* Useful Links::                
* SQL-Words::                   What are stored procedurs and triggers and so on
@end menu

This is the @strong{MySQL} reference manual. This version documents the
@value{mysql_version} version of @strong{MySQL}.

@strong{MySQL} is a basically free SQL database server. @xref{Licensing
and Support}.

The latest information about @strong{MySQL} is found at
@uref{http://www.tcx.se, the @strong{MySQL} Home page}

To see what it can do. @xref{Features}.

For installation instructions @xref{Installing}. For tips on how to port
@strong{MySQL} to new machines/operating systems @xref{Porting}.

If you have any suggestions concerning additions or corrections to this
manual, please send them to the @strong{MySQL} mailing list
@email{mysql@@tcx.se} with a subject line like: @code{doc: [Insert Topic
Here]}. @xref{Mailing-list}.

@xref{Upgrading-from-3.20}, for information about upgrading from a 3.20
release.

For examples of SQL and benchmarking information see the @file{bench}
directory.

For future plans @xref{Todo}.

A history of new features/bug fixes @xref{News}.

For the currently known bugs/misfeatures (known errors) @xref{Bugs}.

For A list of all the contributors to this product @xref{Credits}.

@strong{IMPORTANT:}

Send bug (error) reports, questions and comments to the mailing list at
@email{mysql@@tcx.se}

Please use the @code{mysqlbug} script when posting bug reports or
questions about @strong{MySQL}. @code{mysqlbug} will gather some
information about your system and start your editor with a form in which
you can describe your problem. Bug reports might be silently ignored by
the @strong{MySQL} maintainers if there is not a good reason included in
the report as to why mysqlbug has not been used. A report that says
'MySQL does not work for me. Why?'  is not consider a valid bug report.

The mysqlbug script can be found in the @file{scripts} directory in the
distribution, that is @file{there-you-installed-mysql/scripts}.

@cindex Manual information
@node Manual-info, What-is, Introduction, Introduction
@section About this manual

This manual is currently available in @TeX{}Info, Raw text, Info,
PostScript and HTML versions.

The primary document is the @TeX{}Info file. The HTML version is
automatically produced with a modified @code{texi2html}. The ASCII and
info version are produced with @code{makeinfo}. The Postscript version
is produced using @code{texi2dvi} and @code{dvips}.

This manual was written and is maintained by David Axmark, Michael
(Monty) Widenius and Kim Aldale. The DBI chapter was original written by
Jay Flaherty.

@cindex @strong{MySQL}
@node What-is, History, Manual-info, Introduction
@section What is @strong{MySQL}?

@strong{MySQL} is a SQL (Structured Query Language) database server.
SQL is the most popular database language in the world. @strong{MySQL}
is a client server implementation that consists of a server daemon
@code{mysqld} and many different client programs/libraries.

The main goals of @strong{MySQL} are speed and robustness.

The base upon which @strong{MySQL} is built is a set of routines that
have been used in a highly demanding production environment for many
years.  While @strong{MySQL} is still in development it already offers a
rich and highly useful function set.

@cindex How to pronounce @strong{MySQL}
The official way to pronounce @strong{MySQL} is 'My Ess Que Ell' (Not
MY-SEQUAL).

@cindex @strong{MySQL} version
@node History, Features, What-is, Introduction
@section History of @strong{MySQL}

We once started off with the intention to use @code{mSQL} to connect to
our own fast low level (ISAM) tables. However, after some testing we
came to the conclusion that @code{mSQL} was not fast or flexible enough
for our needs. This resulted in a new SQL interface to our database but
with almost the same API interface as @code{mSQL}. This API was chosen
to ease porting of third party code.

It is not perfectly clear where the name @strong{MySQL} derives
from. Our base directory and a large amount of our libraries and tools
have had the prefix 'my' for well over 10 years. However, Monty's
daughter (some years younger) is also named My. So which of the two gave
its name to @strong{MySQL} is still a mystery, even for us.

@node Features, General-SQL, History, Introduction
@section The main features of @strong{MySQL}

@c This list is to technical and should be divided into one feature
@c list comparable to comercial competition and a very technical on
@c with max limits (from crash-me) and so on.
@itemize @bullet
@item
Fully multi-threaded using kernel threads. That means that it easily can
use multiple CPUs if availably.
@item
C, C++, JAVA, Perl, Python and TCL API's. @xref{Clients}
@item
Lots of column types like: signed/unsigned integers 1,2,3,4 and 8 bytes
long, @code{FLOAT}, @code{DOUBLE}, @code{CHAR}, @code{VARCHAR},
@code{TEXT}, @code{BLOB}, @code{DATE}, @code{SET} and @code{ENUM}
types. @xref{Column types}
@item
Very fast joins using a optimized one-sweep multi-join.
@item
Full function support in the SELECT and WHERE parts. Example:
@code{select column1 + column2 from table where column1/column2 > 0}
@item
SQL functions are implemented through a very optimised class library and
should be as fast as they can get! Usually there shouldn't be any memory
allocation at all after the query initialisation.
@item
Full support for SQL @code{GROUP BY} and @code{ORDER BY}. Support for
group functions (@code{COUNT}, @code{AVG}, @code{SUM}, @code{MAX} and
@code{MIN}).
@item
Support for @code{LEFT OUTER JOIN} with ANSI SQL and ODBC syntax.
@item
A privilege and password system with is very flexible and secure. Allows
host based verification.
@item
Secure passwords since all password traffic on the net is encrypted.
@item
ODBC Open-DataBase-Connectivity for Windows95 (with source). All ODBC
2.5 functions and lots of others. So you can for exapmple use Access to
connect to your @strong{MySQL} server. @xref{ODBC}
@item
Very fast B-tree disk tables with index compression.
@item
16 indexes/table. Each index may consist of 1 to 15 columns/parts of
columns. Max index length is 127 bytes. A index may be a prefix of a
CHAR field.
@item
Fixed and variable length records.
@item
In memory hash tables always used as temporary tables.
@item
Can handle big databases (we are using @strong{MySQL} with some
databases that contain 50,000,000 records).
@item
All columns have default values. One can always use INSERT on any subset
of columns.
@item
Uses GNU autoconf for portability.
@item
Written in C and C++. Tested with gcc 2.7.2.
@item
A very fast thread based memory allocation system.
@item
No memory leaks. Tested with a commercial memory leakage detector
(purify).
@item
A very fast table check,optimize and repair utility. @xref{isamchk}
@item
All data saved in ISO8859_1 format. All comparisons for normal string
columns are case insensitive.
@item
Full ISO8859_1 (Latin1) support. For example Scandinavian едц is allowed
in table and column names.
@item
Sorts by ISO8859_1 Latin1 (the Swedish way at the moment). It is
possible to change this in the source by adding new sort order
arrays. To see a example of a very advanced sorting look at the Czeck
sorting code.
@item
Alias on tables and columns as in the SQL92 standard.
@item
@code{DELETE}, @code{INSERT}, @code{REPLACE}, and @code{UPDATE} returns
how many rows were affected.
@item
Function names do not clash with table or column names. For example ABS
is a valid column name. @xref{Reserved words}
@item
All @strong{MySQL} commands have @code{--help} or @code{-?} for help.
@item
The server currently supports error messages to clients in many
languages. @xref{Languages}.
@item
The clients uses a TCP connection or unix socket when connecting to the
@strong{MySQL} server.
@item
User commands as @code{show tables}, @code{show index from table} and
@code{show columns from table}
@end itemize

@node General-SQL, Useful Links, Features, Introduction
@section General SQL information and tutorials

There is one @uref{http://w3.one.net/~jhoffman/sqltut.htm, SQL tutor} on
the net.

This book has been recommended by a lot of people on the @strong{MySQL}
mailing list.

@example
Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
"The Practical SQL Handbook: Using Structured Query Language"
Second Edition
Addison Wesley
ISBN 0-201-62623-3
http://www.awl.com
@end example

And another book also recommended by people on the @strong{MySQL}
mailing list.

@example
Understanding SQL
ISBN 0-89588-644-8
Publisher Sybex 510 523 8233
Alameda CA USA
@end example

@node Useful Links, SQL-Words, General-SQL, Introduction
@section Usefull MySQL related links

@subheading Some web development tools what supports @strong{MySQL}

@itemize @bullet
@item
@uref{http://php.iquest.net, PHP A server-side HTML-embedded scripting
language}
@item
@uref{http://www.wernhart.priv.at/php/, @strong{MySQL} + PHP demos}
@item
@uref{http://www.daa.com.au/~james/www-sql/, WWW-SQL display databases
information}
@item
@uref{http://www.minivend.com/minivend/, Web shopping cart}
@item
@uref{http://www.metahtml.com, Metahtml A Dynamic Programming Language
for WWW Applications}
@end itemize

@subheading Web servers with @strong{MySQL} tools

@itemize @bullet
@item
@uref{http://bourbon.netvision.net.il/mysql/mod_auth_mysql/, A Apache
authentication module}
@item
@uref{http://www.roxen.com, The Roxen Challenger Web server}
@end itemize

@subheading Other @strong{MySQL} related links.

@itemize @bullet
@item
@uref{http://www.open.com.au/products.html, Comercial Web defect tracking system}
@item
@uref{http://www.homeport.org/~shevett/pts/, PTS - Project Tracking System}
@item
@uref{http://www.seawood.org/msql_bind/, Support for BIND (The Internet
Domain Name Server)}
@item
@uref{http://www.lightlink.com/hessling/rexxsql.html, A REXX interface to SQL databases}
@item
@uref{http://www.wix.com/mysql-hosting, Registry over Web providers who
supports @strong{MySQL}}
@item
@uref{http://www.gagme.com/mysql, @strong{MySQL} TCL patch homepage}
@item
@uref{http://www.pi.net/~hverbeek/mysql/, Full text search engine for
@strong{MySQL}}
@item
@uref{http://www.lava.net/beowulf/programming/wdb/,
WDB; Web browser as a universal front end to databases}
@item
@uref{http://www.amsoft.ru/easysql/, EasySQL; An ODBC like driver manager}
@item
@uref{http://www.fastflow.com/, Network Database Connection For Linux}
@item
@uref{http://www.cynergi.net/non-secure/exportsql/, ExportSQL A script
to export data from Access}
@item
@uref{http://SAL.KachinaTech.COM/H/1/MYSQL.html, SAL (Scientific
Applications on Linux) @strong{MySQL} entry}
@item
@uref{http://www.cgishop.com/bin/mysqllist, @strong{MySQL} Apps and
Utilities Listing}
@item
@uref{http://www.luth.se/~goggi/proj/mysql/man/mysql.pdf, The
@strong{MySQL} reference manual in Adobe PDF format}
@item
@uref{http://www.infotech-nj.com/itech/index.shtml, A consulting company
who mentions @strong{MySQL} in the right company.}
@end itemize

@subheading General database links.
@itemize @bullet
@item
@uref{http://www.pcslink.com/~ej/dbweb.html, Database Jump Site}
@item
@uref{http://java.sun.com/products/jdbc/, The JDBC database access API}
@item
@uref{http://black.hole-in-the.net/guy/webdb/, Homepage of the webdb-l
(Web Databases) mailing list.}
@end itemize

There are also a lot of web pages that uses
@strong{MySQL}. @xref{Users}.

@node SQL-Words,  , Useful Links, Introduction
@section What are stored procedures and triggers and so on?

A stored procedure is some code that is stored and run in the
server. After this the client doesn't have to issue the whole query but
can refer to the stored procedure. This gives more speed because the
query only has to be parsed once and less data has to be sent between
the server and the client. You can also raise the conceptual level by
having libraries of functions in the server.

A trigger is a stored procedure that is invoked when something happens.
For example one can install a stored procedure that checks every delete
to a transaction table and does a automatic delete on the corresponding
customer when all his transactions are deleted.

To se when @strong{MySQL} migth get theese function set the
todo. @xref{Todo}.

@cindex Reporting errors
@cindex @strong{MySQL} mailing lists
@cindex @strong{MySQL} mailing lists, un/subscribing to
@node Questions, Licensing and Support, Introduction, Top
@chapter @strong{MySQL} mailing lists and how to ask questions/give error (bug) reports

@menu
* Mailing-list::                Subscribing/un-subscribing from the @strong{MySQL} mailing list.
* Asking questions::            Asking questions of the mailing list.
* Bug reports::                 I think I have found a bug. What information do you need to help me?
* Answering questions::         Guidelines for answering questions on the mailing list.
@end menu

@node Mailing-list, Asking questions, Questions, Questions
@section Subscribing to/un-subscribing from the @strong{MySQL} mailing list.

Requests to be added or dropped from the @strong{MySQL} list should be
sent to the electronic mail address @email{mdomo@@tcx.se}. Sending a one
line message saying either @code{subscribe mysql} or @code{unsubscribe
mysql} will suffice. If your reply address is not valid you may use
@code{subscribe mysql your@@address.your-domain} or @code{unsubscribe
mysql your@@address.your-domain}.

Please @emph{do not} send mail about [un]subscribing to
@email{mysql@@tcx.se} since any mail sent to this address is
automatically forwarded to hundreds of other users.

Your local site may have many subscribers to @strong{MySQL}. In that
case, it may have a local mailing list, so that a single message from
@code{tcx.se} is sent to the site and propagated to the local list. In
such cases, please contact your system administrator to be added to or
dropped from the local @strong{MySQL} list.

Mail to @code{mdomo} is handled automatically by majordomo.

@cindex Net etiquette
@node Asking questions, Bug reports, Mailing-list, Questions
@section Asking questions or reporting bugs.

Before you ask a question on the mailing list it is a good idea to check
this manual. If you can't find an answer here, check with your local
@strong{MySQL} expert. If you still can't find an answer to your
question go ahead and read the next section about how to send mail to
@email{mysql@@tcx.se}.

@cindex Bug reports
@node Bug reports, Answering questions, Asking questions, Questions
@section I think I have found a bug. What information do you need to help me?

If you can, please use the @file{mysqlbug} script that can be found in
the scripts directory in the distribution. If that is not possible,
remember to specify (if relevant) the following. Note that it is
possible to answer a letter with to much information but not one with to
little.

@enumerate
@item
State which version of @strong{MySQL} you are using (for example
mysql-3.21..tgz). You can find out which version you are running by
typing @code{mysqladmin version}.
@item
The manufacturer and model of machine you are working on.
@item
The operating system. For most operating systems you can get this from
@code{uname -a}.
@item
Sometimes the amount of memory (real and virtual) is also relevant.
@item
If this is a bug when compiling: Include the exact error messages and
also a few lines around the offending code in the file from which you
got the error.
@item
If this is a run time bug, please describe exactly how you got the
error. If you can include a test program which shows the error you can
get a more explicit answer.
@end enumerate

If you are a support customer, please post the bug report to the
specified mailing list for higher priority treatment.

When answers are sent to you individually and not to the mailing list,
it is considered good etiquette to summarise the answers and mail them
to the mailing list.

@menu
* Crashing::                    
@end menu

@node Crashing,  , Bug reports, Bug reports
@subsection @strong{MySQL} keeps crashing

Since it is very hard to now why something crashing please do one of the
following things.

First try to check if thigs that work for other crash for you:

@itemize @bullet
@item
Have you tried the benchmarks?  This should test MySQL rather well. You
can also add code that simulates your application!
@item
Try also fork_test.pl and fork2_test.pl
@item
Check the reference manual about debugging mysqld.
@item
Recompile @strong{MySQL} with @code{--with-debug} switch to
configure. This will include a safe memory allocator that can find some
errors. This also gives a lot of output about what is happening.
@item
Use mysqld --log and try to find if it some specific query that kills
it. 95% of all bugs is related to some specific query!
@item
Have you applied the latest patches for your Operatying System ?
@item
Use --skip-locking
@item
Have you tried 'mysqladmin proc' when it 'dies' ?
@item
Put in some window the following command to output statistics:
mysqladmin -i 5 status
@item
@enumerate
@item
Start mysqld with gdb (or another debugger).
@item
Run your test scripts.
@item
Do @code{back} (or the backtrace command in your debugger) when
@code{mysqld} core dumps.
@end enumerate
@item
Try to simulate your application with a perl script to force
@strong{MySQL} to crash/misbehave.
@item
Or send a normal bug report. @xref{Bug reports}. But be even more
detailed than normally. Since @strong{MySQL} works for a lot of people
it may that the crash comes from something that only exists on your
computer. For example A system library error.
@end itemize

@cindex Net etiquette
@node Answering questions,  , Bug reports, Questions
@section Guidelines for answering questions on the mailing list.

Try to make your answer broad enough that people other than the original
poster may benefit from it. If you consider your answer to have broad
interest, you may want to post it to the mailing list instead of
replying directly to the individual who asked. In such cases, please
make sure that your answer is not a duplication of a previous answer.

Try to summarise the essential part of the question in your reply, but
don't feel obliged to quote the whole question.

@node Licensing and Support, Installing, Questions, Top
@chapter Licensing or When do I have/want to pay for @strong{MySQL}?

Basic licensing issues:

@itemize @bullet
@item
The easiest way to pay for @strong{MySQL} is to use
@uref{https://www.tcx.se/license.htmy, TcX's secure license form}.
@item
You only have to pay if you are selling @strong{MySQL} directly or
selling a product which includes the @strong{MySQL} server.  Unless you
pay for a license, you may not include @strong{MySQL} in a distribution
if you charge for some part of it.  For internal use you do not have to
pay us if you do not want to.
@item
The client code is in the Public Domain or under the GPL (read-line).
You do not need a license to include client code in commercial programs.
@item
We may add some additional functionality in the commercial version. The
likely test candidate for this is fast compressed read only
databases. The current server includes support to read such databases
but not the packing tool. If we get enough revenue from support we will
probably release this under the same license as the other stuff.
@item
But if you like @strong{MySQL} and want to encourage further development
you are welcome to purchase a license or support.
@end itemize

@xref{Public}.

@menu
* Cost::                        How much does @strong{MySQL} cost?
* Support ::                    How do I get support?
* Paying::                      How do I pay for a license?
* Contacting us::               Who do I contact when I want more information about licensing/support
* Copyright::                   What Copyright does @strong{MySQL} use?
* Commercial use::              When may I distribute @strong{MySQL} commercially without a fee
* User adding MySQL::           I'm selling a product that can be configured to use @strong{MySQL}
* Web server::                  I am running a commercial web server using @strong{MySQL}.
* Commercial_scripts::          Do I need a license to sell commercial perl/tcl/PHP etc applications?
* Possible license changes.::   Possible future changes in the licensing.
@end menu

@cindex Cost
@node Cost, Support , Licensing and Support, Licensing and Support
@section How much does @strong{MySQL} cost?

For normal use @strong{MySQL} costs nothing. When you sell
@strong{MySQL} directly or as a part of another product you have to pay
for it. @xref{Public}.

The client access part of @strong{MySQL} is in the public domain. The command
line client includes parts that is under the GNU Public License
(readline).

These are our current license prices. All prices in US Dollars. If you
pay by credit card the currency is FIM (Finish Marks) so the prices will
differ slightly.

@multitable @columnfractions .4 .3 .3
@item Number of licenses @tab Price/Copy @tab Total
@item 1                  @tab US $200 @tab US $200
@item 10 pack            @tab US $150 @tab US $1500
@item 50 pack            @tab US $120 @tab US $6000
@end multitable

For high volume (OEM) purchases the following apply:

@multitable @columnfractions .3 .2 .2 .3
@item licenses  @tab Price/Copy @tab Minimum at one time        @tab Minimum Payment
@item 100-1000  @tab $40        @tab 100                        @tab $4000
@item 1000-2500 @tab $25        @tab 200                        @tab $5000
@item 2500-5000 @tab $20        @tab 400                        @tab $8000
@end multitable

The OEM prices require that you act as a middle-man for eventual
problems/extension requests from users. We also require that the OEM
customer has a support contract.

If you have a low margin high volume product you can always talk to us
about other terms (for example a percent of the sale price). If you do,
please be informative about your product, pricing, market and any other
information that may be relevant.

@cindex Support
@node Support , Paying, Cost, Licensing and Support
@section How do I get commercial support

A full price license includes really basic support. This means that we
are trying to answer any relevant question. If the answer is in the
documentation, we are going to direct you to the relevant
documentation. If you do not have a license/support we will probably not
answer at all.

If you discover what we consider a real bug, we are likely to fix it in
any case. But if you pay for support we will notify you about the fix
status instead of just fixing it in a later release.

More comprehensive support is sold separately:

@subsection Types of commercial support

@subsubsection Basic email support
One year of basic email support costs $200 (USD).

It includes:
@enumerate
@item
For @strong{MySQL} specific questions that does not belong to the
@strong{MySQL} mailing list (@email{mysql@@tcx.se}) you can contact
@email{mysql-support@@tcx.se}. Remember to give your registration number
and expiration date when mailing any list to ensure a quick response.
@item
We guarantee a timely answer for your mails.  We can't guarantee that we
can solve all problems, but at least you will receive an answer if we can
contact you by email.
@item
Your suggestions for the further development of @strong{MySQL} will be
taken into consideration. By taking email support you have already
helped the further development of @strong{MySQL}. If you want to have
more input upgrade to a higher level of support.
@item
Helping with unexpected problems when installing @strong{MySQL} from a
binary distribution on a supported platforms.
@item
We will help you with bugs and missing features. All found bugs are
fixed for the next @strong{MySQL} release. If the bug is critical for
your project, we will mail you a patch for it as soon the bug is fixed.  Critical
bugs always have the highest priority for us, to ensure that they are
fixed as soon as possible.
@item
This level of support does not cover installing @strong{MySQL} from a
source distribution.
@item
If you want us to help to optimize your system you have to upgrade to a
higher level of support.
@item
You are entitled to upgrade to other support options for the difference
between the prices.
@end enumerate


@subsubsection Extended email support
One year of extended email support costs $1000 (USD).

Extended basic supports contains everything in basic email support with
these additions:
@enumerate 
@item
Your email will be dealt with before normal email support users and
non-registered users.
@item
Your suggestions for the further development of @strong{MySQL} will be
taken into high consideration. Simple extensions that suit the basic
goals of @strong{MySQL} are implemented in a matter of days. By taking
extended email support you have already helped the further development
of @strong{MySQL}.
@item
In this we include a binary version of the pack_isam tool that supports
fast compressed read only databases (no @code{BLOB} or @code{TEXT} types
yet). The current server includes support to read such databases but not
the packing tool.
@item
Typical questions that are covered by extended email support are:
@itemize @bullet
@item
Answer and solving (within reason) questions that relates to (possibly)
bugs in @strong{MySQL}.  As soon as the bug is found and corrected, we
will mail a patch of it.
@item
Helping with unexpected problems when installing @strong{MySQL} from a
source/binary distribution on supported platforms.
@item
Questions about missing features and offer hints how to go around them.
@item
How to set up mysqld optimized for your situation.
@end itemize
@item
You are allowed to slightly alter @strong{MySQL} TODO. This will ensure
that the features you really need will be implemented sooner than
otherwise.
@item
You are entitled to upgrade to login support for the difference between
the different support prices.
@end enumerate


@subsubsection Login support
One year of email/phone/telnet support costs $2000 (USD).

Login supports contains everything in extended basic email support with
these additions:

@enumerate
@item
Your email will be dealt with even before that of extended support users.
@item
Your suggestions for the further development of @strong{MySQL} will be
taken into very high consideration. Realistic extensions that can be
implemented in a a couple of hours and suit the basic goals of
@strong{MySQL} will be implemented as soon as possible.
@item
If you have a very specific problem we can try to log in on your system
and try to solve it 'in place'.
@item
As any database vendor, we can't guarantee that we can rescue any data
from crashed tables, but if the worst happens we will help you rescue as
much as possible. @strong{MySQL} has proven itself very reliable, but
because of outside interference anything is possible.
@item
We will give you hints on how to optimize your system and your queries.
@item
You are allowed to call a @strong{MySQL} developer (in moderation) and
discuss your @strong{MySQL} related problems.
@end enumerate


@subsubsection Extended login support
One year of extended email/phone/telnet support costs $5000 (USD).

Extended login supports contains everything in login support with these
additions:

@enumerate
@item
Your email has the highest possible priority.
@item
We will actively examine your system and help you optimize it and your
queries. We may also optimize and/or extend @strong{MySQL} to better
suite your needs.
@item
You may also request special extensions just for you. For example
@example
select my_calculation(column1,column2) from database;
@end example
@item
We will provide a binary version of all important @strong{MySQL}
distributions for your system, as long as we can get a account on a
similar system. In the worst case we may require access to your system
to be able to make a binary version.
@item
If you can provide accommodation and pay for traveler fares you can even
get a @strong{MySQL} developer to visit you and offer you help with your
troubles. The extended login support entitles you to one personal
encounter, but we are (as always) very flexible towards our customers!
@end enumerate

@cindex Paying
@node Paying, Contacting us, Support , Licensing and Support
@section How do I pay for licenses/support ?

Currently we can take SWIFT payments, cheques or credit cards.

Payment should be made to: 
@example
Postgirot Bank AB
105 06 STOCKHOLM, SWEDEN

T.C.X DataKonsult AB
BOX 6434
11382 STOCKHOLM, SWEDEN

SWIFT address: PGSI SESS
Account number: 96 77 06 - 3

Specify: license and/or support and your name and email address.
@end example

In Europe and Japan you can use EuroGiro (that should be cheaper) to the
same account.

If you want to pay by cheque make it payable to "Monty Program KB". And
mail it to the address below.

@example
Monty Program KB
Michael Widenius
Gamla Skomakarbolev. 1 E 11
00740 Helsingfors
Finland
@end example

If you want to pay with credit card over the Internet you can use
@uref{https://www.tcx.se/license.htmy, TcX's secure license form}

@node Contacting us, Copyright, Paying, Licensing and Support
@section Who do I contact when I want more information about licensing/support?

For commercial licensing, or if you have any questions about any of the
information in this section, please contact:

@example
David Axmark
Detron HB
Kungsgatan 65 B
753 21 UPPSALA
SWEDEN
Voice Phone +46-18-10 22 80     (Swedish and English spoken)
Fax +46-8-729 69 05             (Email *much* preferred)
E-Mail: mysql-licensing@@tcx.se
@end example

@cindex Copyright
@node Copyright, Commercial use, Contacting us, Licensing and Support
@section What Copyright does @strong{MySQL} use?

There are (at least) four different copyrights on the @strong{MySQL}
distribution.

@enumerate
@item
The @strong{MySQL} specific source needed to make the @code{mysqlclient}
library and programs in the @file{client} directory is in the public
domain. Each file which is in the public domain has a header which clearly
states so. This is everything in @file{client} directory and some parts of
mysys, mystring and dbug libraries.
@item
Some small parts of the source (GNU getopt) are covered by the "GNU
LIBRARY GENERAL PUBLIC LICENSE". See the @file{mysys/COPYING.LIB} file.
@item
Some parts of the source (GNU readline) are covered by the "GNU GENERAL
PUBLIC LICENSE". See the @file{readline/COPYING} file.
@item
Some parts of the source (the regexp library) are covered by a Berkeley
style copyright.
@item
The other source needed for the @strong{MySQL} server is AGPL. See the file
PUBLIC for more info.
@end enumerate

Our philosophy behind this is:

@itemize -
@item
The SQL client library should be totally free so it can be included in
commercial products without limitations.
@item
People who want free access to the software we have put a lot of work into
can have it so long they do not try to make money directly by distributing
it for profit.
@item
People who want the right to keep their own software proprietary, but also
want the value from our work, can pay for the privilege.
@item
That means that normal in-house use is FREE. But if you use it for something
important to you, you may want to support further development of @strong{MySQL}
by purchasing a support license.
@end itemize

@node Commercial use, User adding MySQL, Copyright, Licensing and Support
@section When may I distribute @strong{MySQL} commercially without a fee?

This is a clarification of the information in the '@strong{MySQL} FREE
PUBLIC LICENSE'. @xref{Public}.

@strong{MySQL} may be @strong{used} freely, including by commercial
entities for evaluation or unsupported internal use. However,
@strong{distribution} for commercial purposes of @strong{MySQL}, or
anything containing or derived from @strong{MySQL} in whole or in part,
requires a written commercial license from TcX AB, the sole entity
authorised by to grant such licenses.

You may not include @strong{MySQL} "free" in a package containing anything for
which a charge is being made except as noted below.

The intent of the exception provided in the second clause is to allow
commercial organisations operating an FTP server or a bulletin board to
distribute @strong{MySQL} freely from it, provided that:

@enumerate
@item
The organisation complies with the other provisions of the FPL, which
include among other things a requirement to distribute the full source
code of @strong{MySQL} and of any derived work, and to distribute the FPL itself
along with @strong{MySQL};
@item
The only charge for downloading @strong{MySQL} is a charge based on the
distribution service and not one based on the content of the information
being retrieved (i.e., the charge would be the same for retrieving a
random collection of bits of the same size);
@item
The server or BBS is accessible to the general public, i.e., the phone
number or IP address is not kept secret, and anyone may obtain access to
the information (possibly by paying a subscription or access fee that is
not dependent on or related to purchasing anything else).
@end enumerate

If you want to distribute software in a commercial context that
incorporates @strong{MySQL} and you do @strong{not} want to meet these
conditions, you should contact TcX AB to find out about commercial
licensing.  Commercial licenses involve a payment, and include support
and other benefits. These are the only ways you legally can distribute
@strong{MySQL} or anything containing @strong{MySQL}: either by
distributing @strong{MySQL} under the requirements of the FPL, or by
getting a commercial license from TcX AB.

@node User adding MySQL, Web server, Commercial use, Licensing and Support
@section I'm want to sell a product that can be configured to use @strong{MySQL}.

I want to sell a product that can be configured to use @strong{MySQL}
although my customer is responsible for obtaining/installing
@strong{MySQL} (or some other supported alternative). Does one of us owe
you money if my customer chooses to use @strong{MySQL}?

If your product REQUIRED @strong{MySQL} to work you would have to pay a
license. If @strong{MySQL} just added some new features it should fall
inside normal use. For example, if using @strong{MySQL} added logging to
a database instead of a text file it would not require a license.  This
would, of course, mean that the user has to fetch and install
@strong{MySQL} by himself.  If the program is (almost) useless without
@strong{MySQL} you would have to get a @strong{MySQL} license to sell
your product.

@node Web server, Commercial_scripts, User adding MySQL, Licensing and Support
@section I am running a commercial web server using @strong{MySQL}. 

Do I have to get a license for my copy?

No you are not selling @strong{MySQL} itself. But is this case we would
like you to purchase @strong{MySQL} support. That is either your support
of @strong{MySQL} or our support of you (the later is more expensive
since our time is limited).

@node Commercial_scripts, Possible license changes., Web server, Licensing and Support
@section Do I need a license to sell commercial perl/tcl/PHP etc applications?

Is your script designed for @strong{MySQL} alone? Does it require
@strong{MySQL} to function at all? Or is it designed for `a database'
and can run under @strong{MySQL}, PostgreSQL, or something else?

If you've designed it strictly around @strong{MySQL} then you've really
made a commercial product that requires the engine, so yes, I would
think you have to pay.

If, however, you can support any database with a base level of
functionality (and you don't rely on anything that only @strong{MySQL}
supports) you probably DO NOT have to pay.

It also depends on what you're doing for the client. Are you tying into
a database you expect to already exist by the time your software is
purchased?  Then you again probably don't have to pay. Or do you plan to
distribute @strong{MySQL} or give them detailed instructions on
installing it with your software? Then you probably do.

One thing I'd like to suggest, folks. Look, development won't last
forever if nobody pays. I agree that buying a copy for every software
user is prohibitive compared to other products available but would it
not be courtesy for commercial developers to register their OWN copy
that they develop with?

@node Possible license changes.,  , Commercial_scripts, Licensing and Support
@section Possible future changes in the licensing.

We may choose to distribute older versions of @strong{MySQL} with the
GPL in the future. However these versions will be identified as
@strong{GNU MySQL}. Also all copyright notices in the relevant files
will be changed to the GPL.

@node Installing, Compatibility, Licensing and Support, Top
@chapter Compiling and installing @strong{MySQL}

@menu
* Getting it::                  How do I get @strong{MySQL}?
* Which version::               Which @strong{MySQL} version should I use?
* Many versions::               How/when will you release updates?
* Which OS::                    Which operating systems does @strong{MySQL} support?
* Installing-source::           Compiling @strong{MySQL} from source code.
* Installation problems::       Problems compiling ?
* Compilation-notes::           General compilation notes
* MIT-pthreads::                MIT-pthreads notes. (FreeBSD)
* Perl-installation::           Perl installation comments.
* Machine-OS::                  Special thing to consider with some machine/OS combinations.
* Install-binary::              Installation instructions for @strong{MySQL} binary release
* Starting MySQL::              Problems starting @strong{MySQL}
* Automatic start::             Automatic start/stop of @strong{MySQL}
@end menu

@cindex Downloading
@cindex @strong{MySQL} version
@cindex Version, Latest 
@cindex Getting @strong{MySQL}
@node Getting it, Which version, Installing, Installing
@section How do I get @strong{MySQL}?

You can always check @uref{http://www.tcx.se/, @strong{MySQL}'s home
page} to see what the latest news.

But since the Internet connection at tcx is not to fast we would prefer
if you do the actual downloading from one of the mirrors below.

Europe:
@itemize @bullet
@item
@uref{http://www.matrice.it/risorse/mysql, Mirror at Matrice (Italy)}
@item
@uref{http://ftp.sunet.se/pub/unix/databases/relational/mysql/index.html,
Mirror at Sunet (Sweden)}
@item
@uref{http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/Welcome.html, Mirror at Wolfenbuettel (Germany)}
@item
@uref{http://mysql.staufen.de, Mirror at Staufen (Germany)}
@item
@uref{http://xenia.sote.hu/ftp/mirrors/www.tcx.se-mysql/Welcome.html, Mirror at Xenia (Hungary)}
@item
@uref{http://mysql.netvision.net.il, Mirror at Netvision (Israeli)}
@item
@uref{http://online.garant.ru/mysql, Mirror at Garant (Russia)}
@item
@uref{http://gd.tuwien.ac.at/db/mysql, Mirror at Univ. of Technology Vienna (Austria)}
@item
@uref{http://mirror.opf.slu.cz/mysql, Mirror at CESNET (Czech Republic)}
@item
@uref{ftp://ftp.micromuse.co.uk/pub/packages/unix/databases/mysql, FTP to MicroMuse (UK)}
@item
@uref{ftp://mysql.netvision.net.il/mirrors/mysql, FTP to Netvision (Israeli)}
@item
@uref{ftp://ftp1.garant.ru/pub/MySQL, FTP to Garant (Moscow/Russia)}
@item
@uref{ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql, FTP to Wolfenbuettel (Germany)}
@item
@uref{ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/index.html,
FTP at Sunet (Sweden)}
@item
@uref{ftp://www.tcx.se/pub/mysql/, FTP to www.tcx.se (Sweden)}.
@end itemize

North America:
@itemize @bullet
@item
@uref{http://www.buoy.com/mysql, Mirror at Buoy (USA/NY)}
@item
@uref{http://mirrors.iquest.net/mysql, Mirror at IQuest (USA/Indiana)}
@item
@uref{http://web.tryc.on.ca/mysql, Mirror at Tryc (Canada)}
@item
@uref{ftp://ftp.id.wustl.edu/pub/database/mysql, FTP at St. Louis (USA)}
@item
@uref{ftp://ftp.netcasting.net/pub/mysql, FTP at Seattle (USA/West Coast)}
@end itemize

Asia:
@itemize @bullet
@item
@uref{http://mysql.acer.net, Mirror at Acer (Taiwan)}
@item
@uref{http://linux.kreonet.re.kr/mysql, Mirror at KREONet (Korea)}
@item
@uref{http://www.happysize.co.jp/mysql, Mirror at HappySize (Japan)}
@item
@uref{ftp://ftp.wownet.net/mysql, FTP at Wownet (Taiwan)}
@item
@uref{ftp://ftp.oneway.com.tw/pub/mysql, FTP at Oneway (Taiwan)}
@item
@uref{http://linux.kreonet.re.kr/pub/tools/db/mysql, FTP at KREONet (Korea)}
@item
@uref{ftp://ftp.happysize.co.jp/pub/mysql, FTP at HappySize (Japan)}
@end itemize

Australia:
@itemize @bullet
@item
@uref{http://mysql.bluep.com, Mirror at Blue Planet NET (Australia/Melbourne)}
@item
@uref{ftp://mysql.bluep.com/pub/mysql, FTP at Blue Planet NET (Australia/Melbourne)}
@end itemize

@cindex @strong{MySQL} binary
@cindex @strong{MySQL} source
@cindex Release numbers
@cindex Version, Choosing
@cindex Choosing version
@node Which version, Many versions, Getting it, Installing
@section Which @strong{MySQL} version should I use?

The first decision is if you want to use the latest development release
or the last stable release.

Normally if you are starting with development we recommend going with
the development release. This is because there are usually no realy bad
bugs in the development release and if you can easily test it on you
machine with the crash-me and benchmark tests. @xref{Benchmarks}.

The second decision is if you want a source of a binary release.

If you want to run @strong{MySQL} on a platform that has a current
binary release use that. A binary version of @strong{MySQL} is easier to
install.

If you want to read (and/or modify) the C and C++ code that makes up
@strong{MySQL} you should always get a source distribution. The code is
always the ultimate manual. The source distribution also contains more
tests and examples than the binary distribution.

To clarify our naming schema:

All @strong{MySQL} versions is run trough our standard test and the
benchmarks to ensure that they are relatively safe to use.  The standard
test is also extended the whole time to test for all previously found
bugs, so it's gets better the whole time.

The @strong{MySQL} release numbers consists of 3 numbers and a suffix.

So a release name like @code{mysql-3.21.17-beta} means.

@table @asis
@item The first number. In this case 3
This describes the file format. So all version 3 releases has the same
file format. And when a version 4 appears every table has to be
converted to the new format (Nice tools for this will of cource be
included).
@item The second number. In this case 21
This is the release level. Normaly where is two of these to choose
from. One is the release/stable branch and the other is the development
branch. Normaly both are stable but the development version may have
quirks, missing documentation and fail to compile on some systems.
@item The third number. In this case 17
This is the version number. This is incremented for each
release. Usually you want the latest version for the release you have
choosen.
@item The suffix. In this case beta 
@itemize @bullet
@item
Alpha means that there exists some new large code section that hasn't
been tested to 100%, known bugs should be documented in the News section
(usually there are none). There is also new commands and extensions in
most alpha releases.
@item
Beta means that all new code has been tested. No major new things are
added anymore. There should be no known bugs.
@item
Gamma is a beta that has been around a while and seems to work fine.
This is what many other companies call a release.
@item
Release (no extension) means that the version has been run for a while
at many different sites without any bug reports (Exept platform specific
bugs).
@end itemize
@end table

Note that all releases has at least been tested with:

@table @asis
@item A internal testsuite
This is part of a production system for a customer. It has many tables
and with many mega bytes of data and lots of tables.
@item The @strong{MySQL} benchmark suite
This runs a range of common queries. It is also a test to see that the
latest batch of optimizations actually made the code
faster. @xref{Benchmarks}.
@item The crash-me test
This tries to find what the database supports and which limitation it
has. @xref{Benchmarks}.
@end table

Another test is our internal production. We usually use the latest
version for this (at least on one machine) and we have more than 100
giga byte of data to work with.

@node Many versions, Which OS, Which version, Installing
@section How/when will you release updates?

We are going to use the following policy when updating @strong{MySQL}:

Each minor version will increment the last number in the version
string. When there are major new features or minor incompatibilities
with previous versions, the second number in the version string will be
incremented. When the file format changes the first number will be
increased.

@itemize @bullet
@item
Stable tested releases are meant to appear about 1-2 times a year. But
if small bugs are found a release with only bug fixes will be released.
@item
Working releases are meant to appear about every 1-8 weeks.
@item
Binary releases for some platforms will be make for major releases by
us. Other people may make binary releases for other systems but probably
less frequently.
@item
We usually make patches available as soon as we have located and fixed
small bugs.
@item
For non-crucial but annoying bugs we will make patches available if they
are sent to us, otherwise we will combine many of them into a bigger
patch.
@end itemize

@node Which OS, Installing-source, Many versions, Installing
@section Which operating systems does @strong{MySQL} support?

We use GNU autoconf so it will be possible to port to all modern systems
with working Posix threads and a C++ compiler. The client code requires
C++ but not threads. We use/develop the software ourselves primarily on
Sun Solaris (version 2.5 & 2.6) and some on RedHat Linux 5.0.

The following OS/thread package's has been reported to compile
@strong{MySQL} successfully. Note that for many OSes the native thread
support only works in the latest versions.

@itemize @bullet
@item
Solaris 2.5 & 2.6 with native threads.
@item
BSDI 3.1 native threads.
@item
SGI IRIX 6.x with native threads.
@item
AIX 4.x whith native threads.
@item
DEC UNIX 4.x with native threads.
@item
Linux 2.0+ with LinuxThreads 0.5,0.6 and 0.7.
@item
FreeBSD x.x with the included MIT threads package.
@item
SCO OpenServer with a recent port of the FSU-threads package.
@end itemize

@node Installing-source, Installation problems, Which OS, Installing
@section Compiling @strong{MySQL} from source code.

What you need:

@enumerate
@item
GNU @code{gzip} to uncompress the distribution.
@item
A reasonable @code{tar} to unpack the distribution. GNU @code{tar} is
known to work.
@item
A working ANSI @code{C++} compiler. gcc >= 2.7, SGI C++, SunPro C++ are
some of the compilers that are known to work. @code{libg++} is not
needed when using @code{gcc}.
@item
A good make program. If you have problems we recommend trying GNU
@code{make}.
@end enumerate

@menu
* Quick-install::               Quick installation overview.
* Appying patches::             Applying a patch
@end menu

@node Quick-install, Appying patches, Installing-source, Installing-source
@subsection Quick installation overview.

Unpack tar archive in a directory. The tar file should be named like
mysql-VERSION.tar.gz (VERSION is a number like @value{mysql_version}). A
directory named mysql-VERSION should be created.

@table @code
@item zcat mysql-VERSION.tar.gz | tar xvf -
Unpack the distribution into the current directory.
@item cd mysql-VERSION
Change directory.
@item ./configure
Configure the release. Here you might want to add some options. For a
list of configure options use @file{./configure --help}.
@item make
Compile everything.
@item make install
Install everything.
@item ./scripts/mysql_install_db
Set up the @strong{MySQL} privilige tables. This only needs to be done
the first time you install @strong{MySQL}. You may want to edit this
script before running it to get right initial permissions for users to
connect to the database.
@item 'installation_directory'/bin/mysqladmin version
Check to see if the server is running. Unless you added some options to
@file{./configure} 'installation_directory' is @file{/usr/local}. Here
is a example of the output you should get (You will not get this
exactly!):
@example
mysqladmin  Ver 6.3 Distrib 3.21.17, for pc-linux-gnu on i686
TCX Datakonsult AB, by Monty

Server version          3.21.17-alpha
Protocol version        10
Connection              Localhost via UNIX socket
TCP port                3306
UNIX socket             /tmp/mysql.sock
Uptime:                 16 sec

Running threads: 1  Questions: 20  Reloads: 2  Open tables: 3
@end example
@end table

Usual configure switches:
@itemize @bullet
@item
To compile only the client use @code{--without-server}
@item
If you don't want to have your data under @file{/usr/local/var} use
something like: @code{--prefix=/usr/local} or @code{--prefix=/usr/local
--localstatedir=/usr/local/data/mysql}
@item
If you don't want to have your sockets in the default place (Default is
@file{/tmp} or @file{/var/run}) use
@code{--with-unix-socket-path=absolute_file_name}
@item
Changing the default character set.

By default @strong{MySQL} will use the ISO8859-1 (Latin1) character
set. You may change this at compile time by the configure swithc
@code{--with-charset=charset}.

Where [charset] may be one of: @code{big5}, @code{czech}, @code{dec8},
@code{dos}, @code{german1}, @code{hp8}, @code{koi8_ru}, @code{latin1},
@code{latin2}, @code{swe7} or @code{usa7}.

If you want to add another character set to @strong{MySQL} you must:
@itemize @bullet
@item
Choose a name. CHARSET_NAME
@item
Create the file
@code{mysql_source_directory/strings/ctype-$CHARSET_NAME.c}. 
@item
Look at one of the existing ctype files to see what needs to be
defined. Note that the arrays in this file must have names like
ctype_$CHARSET_NAME, to_lower_$CHARSET_NAME and so on.
@item
Add charset name to @code{CHARSETS_AVAILABLE} list in
@code{configure}.in
@item
Recompile and test
@end itemize

@emph{Warning:} If you change character sets after having created a
table you will have to run @code{isamchk -r -q} on every
table. Otherwise things will be sorted incorecctly in some cases (but
not all!).

@item
For computer/OS specific switches see the menu later in this chapter.
@end itemize

GNU @code{make} is always recommended and sometimes required.

About creating the grants database @file{mysql_install_db}:

The default priviliges is that anybody may create/use the databases
named @code{test} or starting with @code{test_}. @code{root} can do
anyting. @xref{Privileges}.

To change the defaults edit the script before running it.  If this is
the first time you install @strong{MySQL} you must run this command. If
you don't do it you will get the error: @code{Can't find file:
'./mysql/host.frm'}. This script also starts the mysqld daemon the first
time.

Normal start of the @strong{MySQL} server demon (not needed the first
time): @code{'installation_directory'/bin/safe_mysqld --log}

@node Appying patches,  , Quick-install, Installing-source
@subsection Applying a patch

Some times patches appear on the mailing-list. To apply on do something
like this:

@example
cd 'old-mysql-source-distribution-path'
gunzip < patch-file-name.gz | patch -p1

rm config.cache
make clean
@end example

And then follow the instructions for a normal source install from the
@code{./configure} step.

And the restart your @strong{MySQL} server.

@node Installation problems, Compilation-notes, Installing-source, Installing
@section Problems compiling ?

If your compile fails with something like:

@example
configure: error: installation or configuration problem: C++ compiler
cannot create executables.
@end example

Try setting the environment variable @code{CXX} to @code{"gcc -O3"} (If
you are using @code{gcc}).  For example @code{CXX="gcc -O3"
./configure}. If you use this you don't nead to have libg++ installed!

You can also install libg++. By default @file{configure} picks
@code{c++} as a compiler name and GNU @code{c++} links with
@code{-lg++}.

@enumerate
@item
@example
making all in mit-pthreads
make: Fatal error in reader: Makefile, line 18: Badly formed macro assignment
@end example
This means you have to upgrade your make to GNU make.
@item
If you want to add flags to your C or C++ compiler add the flags to the
CC and CXX environment variables. For example:

@example
CC="gcc -O4"
CXX="gcc -O4"
export CC CXX
@end example

@item
If your make stops with @code{Can't find Makefile.PL} when making
mysqlperl you should try using GNUx make. At least Solaris and FreeBSD
is known to have troublesome make programs.

@item
If you get error messages from make or error message of type:
@code{pthread.h: No such file or directory}

This means you have to upgrade your make to GNU make (At least GNU make
version 3.75 works).

@item
If you get a error message like: @code{client/libmysql.c:273: parse
error before `__attribute__'}

This means you need to upgrade your gcc compiler (2.7.2 is known to work).
@item
If configure fails, and you are going to mail @email{mysql@@tcx.se},
please include any lines from config.log that you think can help solve
the problem.  Include also a couple of lines of the last output from
configure if configure aborts. Post the bug with the script 'mysqlbug'.

@c texi2html fails to split chapters if I use strong for all of this.
@strong{PLEASE ALWAYS USE @code{mysqlbug}}
when posting questions to @email{mysql@@tcx.se}. @xref{Bug reports}.

Even if the problem isn't a bug, mysqlbug gathers some system
information that will help other solve your problem!

@item
If you need to debug mysqld or a @strong{MySQL} client, run configure
with: @code{configure --with-debug=yes}

Before running a client you should do:
@example
MYSQL_DEBUG=d:t:o,/tmp/client.trace
export MYSQL_DEBUG
@end example

You will now get a trace file in @file{/tmp/client.trace}.
@item
If you have problem with your own client code, test first with
@code{mysql --debug=d:t:o,/tmp/client.trace} before mailing a bug
report. @xref{Bug reports}.
@item

If you get three errors when compiling mysqld like:
@example
  cxx: Error: mysqld.cc, line 645: In this statement, the referenced type of
       the pointer value "&length" is "unsigned long", which is not compatible
       with "int".
  new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
@end example

Then configure didn't detect the type of the last argument to
@code{accept()}, @code{getsockname()} and @code{getpeername()}.  Search
after the line:

@example
/* Define as the base type of the last arg to accept */
#define SOCKET_SIZE_TYPE ###
@end example

and change ### to size_t or int depending on your operating system.
@end enumerate

@node Compilation-notes, MIT-pthreads, Installation problems, Installing
@section General compilation notes

All @strong{MySQL} programs compile clean (no warnings) for us (on
Solaris using gcc). But warning may appear because of different system
include files. Se below for warnings that may occur when using
mit-pthreads.

When compiling sql_yacc.yy you should probably get:
@example
conflicts:  4 reduce/reduce
@end example

You probably have to use bison to compile sql_yacc.yy. If you get an
error like:
@example
"sql_yacc.yy", line xxx fatal: default action causes potential... 
@end example
you have to install bison (the gnu yacc).

If you want to have static linked code, use (with gcc):
@code{LDFLAGS="-static" ./configure ...}

@node MIT-pthreads, Perl-installation, Compilation-notes, Installing
@section MIT-pthreads notes. (FreeBSD)

Building in a non source directory is not supported when using
MIT-threads. This is because we want to keep our changes to this code
minimal.

MIT-pthreads doesn't support the @code{AF_UNIX} protocol so we must use
the TCP/IP protocol for all connections (which is a little slower).  If
you can't connect to a table, try using the host (@code{-h} or
@code{--host}) switch to @code{mysql}.  This must be done if you have
compiled the client code @code{--without-server} because the default
connection is to use Unix sockets.

@strong{MySQL} compiled with MIT threads has as default system locking
disabled for performance reasons. One can start the server with system
locking with the @code{--use-locking}.

Sometimes (at least on Solaris) the pthread @code{bind()} command fails
to bind to a socket without any error message. The result of this is
that all connections to server fails.  

@example
> mysqladmin ver mysqladmin: connect to server at '' failed;
    error: 'Can't connect to mysql server on localhost (146)'
@end example

The solution to this is to kill the @code{mysqld} demon and restart it.
This has only happened to us when we have forced the demon down and done
an restart directly.

@code{sleep()} isn't interruptible with @code{SIGINT} (break) with
MIT-threads. This is only notable in @code{mysqladmin --sleep}. One have
to wait for the end of the sleep before the interrupt is served and the
process stops.

We haven't got readline to work with MIT threads. (This isn't needed,
but may be interesting for someone)

When linking (at least on Solaris) you will receive warning messages
like:

@example
ld: warning: symbol `_iob' has differing sizes:
	(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
	/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
ld: warning: symbol `__iob' has differing sizes:
	(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
	/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
@end example

Some other warnings which also can be ignored:

@example
implicit declaration of function `int strtoll(...)'
implicit declaration of function `int strtoul(...)'
@end example

@node Perl-installation, Machine-OS, MIT-pthreads, Installing
@section Perl installation comments.

The included perl client code requires perl5.004 or later.

If you got a the following error (from mysqlperl or DBD-mysql):

@example
/usr/bin/perl: can't resolve symbol '__moddi3'
/usr/bin/perl: can't resolve symbol '__divdi3'
@end example

You are probably using gcc (or using a old binary compiled with
gcc). Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command where
@code{-L/...}  is the path to the directory where @code{libgcc.a}
exists.

@node Machine-OS, Install-binary, Perl-installation, Installing
@section Special thing to consider with some machine/OS combinations.

@menu
* Solaris::                     Solaris notes.
* SunOS::                       SunOS 4 notes.
* Linux::                       
* Alpha-DEC-Unix::              Alpha-DEC-Unix notes.
* Alpha-DEC-OSF1::              Alpha-DEC-OSF1 notes.
* SGI-IRIX::                    SGI-IRIX notes.
* FreeBSD::                     FreeBSD notes.
* BSDI2::                       BSDI 2.# notes
* SCO::                         SCO notes.
* IBM-AIX::                     IBM-AIX notes.
@end menu

@node Solaris, SunOS, Machine-OS, Machine-OS
@subsection Solaris notes.

Sun native threads only works on Solaris 2.5 and higher. For 2.4 and
earlier versions you can use MIT-pthreads. @xref{MIT-pthreads}.

If there is too many processes that tries to connect very rapidly to the
@code{mysqld} one will get @code{Error in accept : Protocol error} in
the mysql log.

If you have the Sun Workshop 4.2 compiler you can configure with:
@code{CC="cc -Xa -fast -xstrconst" CXX="CC -xsb -noex -fast"
./configure}

You may also have to change the row in configure:

@code{#if !defined(__STDC__) || __STDC__ != 1} to @code{#if
!defined(__STDC__)} because if you turn on @code{__STDC__} with the
@code{-Xc} switch, the Sun compiler can't compile with the Solaris
@file{pthread.h} header files anymore. This is a Sun bug (Broken
compiler or broken include file).

@node SunOS, Linux, Solaris, Machine-OS
@subsection SunOS 4 notes.

On SunOS 4 MIT-pthreads is needed. You must have gnu make to compile
(because of MIT-pthreads).

In readline you may get warnings about duplicated defines. These may be
ignored.

When compiling mysqld there will be some warnings about @code{implicit
declaration of function}. These may be ignored.

@node Linux, Alpha-DEC-Unix, SunOS, Machine-OS
@subsection Linux notes for all versions

On Linux you should (it is added automatically by @code{safe_mysqld})
use the @code{--skip-locking} flag to @code{mysqld}. This is because a
bug in Linux file locking calls. This error has been verified to still
exists in Linux version 2.0.32.

When using LinuxThreads you will see a minimum of three processes
running. These are in fact threads. There will be one thread for the
Linux Threads manager, one thread to handle connections, and one thread
to handle alarms and signals.

@menu
* Linux-x86::                   
* Linux-Sparc::                 
* Linux-Alpha::                 
@end menu

@node Linux-x86, Linux-Sparc, Linux, Linux
@subsubsection Linux-x86 notes.

LinuxThreads should be installed before configuring @strong{MySQL}!

@strong{MySQL} libc version 5.4.12 or newer. glibc version 2.0.6 and
later should also work.

On some older Linux distributions @code{configure} may give a error
about: @code{Syntax error in sched.h. Change _P to __P in the
/usr/include/sched.h file.\
 See the Installation chapter in the Reference Manual}. Just do what the
error says and add a extra underscore to the @code{_P} macro that only
has one underscore. And then try again.

You will get some warnings when compiling: (these can be ignored)

@example
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'
@end example

When using glibc 2 you must also execute the configure with
@code{CXX=gcc ./configure ...} because if you compile with g++, you
will link with libg++ which dosen't work with LinuxThreads.

If you want in Debian GNU/Linux to get @strong{MySQL} to auto start when
system boots, do the following:

@example
> cp scripts/mysql.server /etc/init.d/mysql.server
> /usr/sbin/update-rc.d mysql.server defaults 99
@end example

There is a bug in glibc 2.0.5 in how pthread_key_create variables are
freed.  With glibc2 2.0.5 (For example on RedHat 5.0 systems) you have
to use the staticly linked @strong{MySQL} binary distribution.

If mysqld always does a core dump when starting, the problem may be that
you have and old @file{/lib/libc.a}.  Try renaming this, remove
sql/mysqld and do a new make install and try again.  This problem has
been reported on some Slackware installations.

@node Linux-Sparc, Linux-Alpha, Linux-x86, Linux
@subsubsection  Linux-Sparc notes.

In some implementations @code{readdir_r} is broken.  This will be
notised by that @code{SHOW DATABASES} always return an empty set.  This
can be fixed by removing @code{HAVE_READDIR_R} from @file{config.h}.

If you get problems you probably have to apply a patch to your Linux
installation.  The patch can be got at
@uref{http://www.tcx.se/patches/Linux-sparc-2.0.30.diff}. This patch is
against the linux distribution @file{sparclinux-2.0.30.tar.gz}, that is
available at vger.rutgers.edu.  This is a version of linux which was
never merged with the official 2.0.30.  You also have to install
linuxthreads 0.6 or newer.

Thanks to jacques@@solucorp.qc.ca for the above information.

@node Linux-Alpha,  , Linux-Sparc, Linux
@subsubsection Linux-Alpha notes.

The first problem is linuxthreads.  You must patch linuxthreads for
alpha because the RedHat distribution uses an old (broken) linuxthread
version.

@enumerate
@item
Get hold of the glibc2.5c source from any gnu ftp site.
@item
Get the file
@uref{ftp://www.tcx.se/pub/mysql/linux/patched-glibc-linuxthreads-0.6.tgz}.
This includes a fixed .c file.  Copy this to the glibc
@file{./linuxthreads} directory.
@item
Configure and compile glibc (You have to read the manual how to do this
together with linuxthreads). Don't install this!
@item
Rename your old version of /usr/lib/libpthread.a to /usr/lib/libpthread.a-old
@item
@item
Copy the file glibc.../linuxthreads/libpthread.a to /usr/lib.
@item
Try to compile mysys/thr_lock and mysys/thr_alarm.  Test that these
works!
@item
Recompile mysqld.
@end enumerate

Note that Alpha-Linux is still an alpha platform for MySQL.  With RedHat
5.0 and the patched linuxthreads you have a very good change to get this
to work.

@node Alpha-DEC-Unix, Alpha-DEC-OSF1, Linux, Machine-OS
@subsection Alpha-DEC-Unix notes.

When compiling threaded programs under Digital UNIX using CC / CXX the
documentation recommends the switch to cc and cxx and the libraries
@code{-lmach -lexc} (in addition to @code{-lpthread}).

So you have to configure with something like this:

@code{CC="cc -pthread" CXX="cxx -pthread -O" ./configure
-with-named-thread-libs="-lpthread -lmach -lexc -lc"}

When compiling mysqld you will may this warning for mysqld for a couple
of lines:

@example
mysqld.cc: In function void handle_connections()':
mysqld.cc:626: passing long unsigned int *' as argument 3 of accept(int,sockad
ddr *, int *)'
@end example

You can safely ignore these. This is because configure can't detect
warnings, only errors.

You may get problems with the server exiting directly. If so try
starting it with @code{nohup safe_mysqld [options]}

@code{nohup} is a command that ignores any @code{SIGHUP} sent from the
terminal.

@node Alpha-DEC-OSF1, SGI-IRIX, Alpha-DEC-Unix, Machine-OS
@subsection Alpha-DEC-OSF1 notes.

In some versions of OSF1 the @code{alloca()} functions is broken. Fix
this by remove @code{'HAVE_ALLOCA'} from config.h.

When using the Digital C++ you could try
@code{-with-named-thread-libs="-lpthread -lmach -lexc -lc"}

@node SGI-IRIX, FreeBSD, Alpha-DEC-OSF1, Machine-OS
@subsection SGI-IRIX notes.

You may have to undefine some things in @file{config.h} (generated by
@file{./configure}).

In some Irix implementations the @code{alloca()} function is broken. If
the mysqld server dies on some selects remove @code{HAVE_ALLOC} &
@code{HAVE_ALLOCA_H} from @file{config.h}.  If mysqladmin create doesn't
work, remove @code{HAVE_READDIR_R} from config.h. Also you may have to
remove @code{HAVE_TERM_H}.

Irix 6.2 doesn't support POSIX threads out of of the box.  You have
install these patches, available from SGI if you have support:

1403, 1404, 1644, 1717, 1918, 2000, 2044

If you get the something like the following error when compiling mysql.cc:

@example
"/usr/include/curses.h", line 82: error(1084): invalid combination of type
@end example

type the following in the mysql installation directory:

@example
> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
> make
@end example

There has also been reports about scheduling problems. This is if only
one thread is running things go slow. Avoid this by starting another
client. This may lead to a 2-10 fold increase in execution speed
hereafter for the other thread.

This is a badly understood problem with IRIS threads so you may have to
improvise to find solutions until it can be fixed.

@node FreeBSD, BSDI2, SGI-IRIX, Machine-OS
@subsection FreeBSD notes.

If you get link errors when compiling mysqlperl (Type
@code{ient.a(my_getwd.o): RRS text relocation at 0x9a9f for
"__db_pargs_"})

You must recompile the Perl code with @code{-DPIC -fpic}.

Do the following:

@enumerate
@item
First install everything.
@item
Change in @file{client/Makefile} the line: @code{CFLAGS = -g -O2} to
@code{CFLAGS = -O2 -DPIC -fpic}
@item
@code{cd client}
@item
@code{rm *.o}
@item
@code{make libmysqlclient.a}
@item
@code{cd ../perl/mysqlperl}
@item
@code{make}
@end enumerate

This shall hopefully be handled automatically in the future.

The FreeBSD make behaviour is slightly different from GNU makes. If you
have a problem that @file{mysqlperl/Makefile.PL}x doesn't get generated
you should install GNU make.

Other (temporary) solution:
@example
> cd perl
> make mysqlperl/Makefile.PL
> make mysqlperl/mysql_test
@end example

If you get @code{ERROR Can't create/write to file 'xxx.ISD' error 23}
from @strong{MySQL} this means that you haven't allocated enough file
descriptors for @strong{MySQL}. @code{perror #} will give you the error
message in a more readable form.

There is commented line @code{ulimit -n 256} in @file{safe_mysqld}. You
can remove this comment and of course increase or decrease the value if
you want. You can also make the table cache smaller with:
@code{safe_mysqld -O table_cache=32} (the default is 64).

If mysql or mysqladmin takes a long time to respond a user said the
following.

Are you running the ppp user process? On my FreeBSD box (2.2.5) MySQL
clients takes a couple of seconds to connect to mysqld if the ppp
process is running.

@menu
* FreeBSD-3.0::                 FreeBSD-3.0 notes.
@end menu

@node FreeBSD-3.0,  , FreeBSD, FreeBSD
@subsubsection FreeBSD-3.0 notes.

You have to configure with:

@code{--with-named-thread-libs=-lc_r}

The pthreads library for FreeBSD doesn't contain the @code{sigwait}
function and there is some bugs in it.  To fix this, get the
@file{FreeBSD-3.0-libc_r-1.0.diff} file and apply this in the
@file{/usr/src/lib/libc_r/uthread} directory. Follow after this the
instructions that can be found with @code{man pthread} about how to
recompile the @code{libc_r} library.

You can test if you have a 'modern' @code{libpthread.a} with:

@example
> nm /usr/lib/libc_r.a | grep sigwait.
@end example

If the above doesn't find @code{sigwait} you have to use the above patch
and recompile @code{libc_r}.

@node BSDI2, SCO, FreeBSD, Machine-OS
@subsection BSDI 2.# notes

From Jan Legenhausen @email{jleg@@csl-gmbh.net}.

I finally got mysqlperl working on BSDI2.1.

What i did was almost nothing:
@enumerate
@item
cd client
@item
Leave the Makefile as it is! (i use @code{GCC="shlicc2"} per default;
perl5 automagically uses shlicc2 - you should use _one_ version (either
@code{gcc} or @code{shlicc2}) for both @code{Mysql.c} and
@code{libmysqlclient.a}!)
@item
@code{rm *.o}
@item
@code{gmake libmysqlclient.a}
@item
@code{cd ../perl/mysqlperl}
@item
@code{make clean}
@item
add @code{$sysliblist=" -L$tmp -lgcc -lcompat";} to Makefile.PL line 45
(just to be sure - i didn't check if one could leave out this one)
@item
@code{perl Makefile.PL}
@item
remove all old @code{libmysqlclient.a}'s in @code{/usr/lib} and
@code{/usr/contrib/lib}
@item
@code{make install}
@end enumerate

If you can't run the @code{mysql_install_db} script because the script
can't connect to the server you should check that you have an entry in
/etc/hosts like:

127.0.0.1		localhost

If you get the following error when compiling @strong{MySQL}:

@example
item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)':
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1
@end example

Then your ulimit for virtual memory is too low. Try using: @code{ulimit
-v 30000} and do @code{make} again.

@menu
* BSDI3::                       BSDI 3.# notes.
@end menu

@node BSDI3,  , BSDI2, BSDI2
@subsubsection BSDI 3.# notes.

@enumerate
@item
Upgrade to BSD/OS 3.1. If that is not possible, install BSDIpatch M300-038.
@item
Use the following configuration when installing @strong{MySQL}:
@example
env CXX=shlicc++ CC=shlicc2 ./configure --prefix=/usr/local
--localstatedir=/var/mysql --without-perl
--with-unix-socket-path=/var/mysql/mysql.sock 
@end example
@end enumerate

You can change the directory locations if you wish, or just use their
defaults by not specifying them.

@node SCO, IBM-AIX, BSDI2, Machine-OS
@subsection SCO notes.

The current port is only tested on a 'sco3.2v5.0.4' system.

@enumerate
@item
For OpenServer 5.0.X You need to use GDS in Skunkware 95 (95q4c).  This
is necessary because GNU gcc 2.7.2 in Skunkware 97 do not have the GNU
as.
@item
You need the port of GCC 2.5.? for this product and the Developement
system.  They are required on this version of SCO UNIX.  You can not
just use the GCC Dev system.
@item
One should get FSU thread package and install this first.  This can be
found at:
@uref{http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-threads.tar.gz}
You can also get a precompiled package from:
@uref{ftp://www.tcx.se/pub/mysql/SCO/fsu-threads.tar.gz}
@item
FSU pthreads can be compiled with SCO UNIX 4.2 with tcpip.  Or
OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0), with the SCO
Developement System installed using a good port of GCC 2.5.X ODT or OS
3.0 you will need a good port of GCC 2.5.? There are a lot of problems
with out a good port.  The port for this product requires the SCO UNIX
Developement system.  You are missing the libraries and the linker that
is needed.
@item
To build FSU pthreads in your system do the following:
@enumerate
@item
Run ./configure in threads/src directory and select the SCO OpenServer
option. This command copy Makefile.SCO5 to Makefile.
@item
Run make.
@item
To install in default /usr/include directory, login as root and cd to
thread/src directory, run make install.
@end enumerate
@item
Remember to use gnu make when making @strong{MySQL}.
@item
If you don't start safe_mysqld as root, you vill probably only get the
default 110 open files per process.  mysqld will write a note about this
in the log file.
@end enumerate

SCO development notes:

@itemize @bullet
@item
@strong{MySQL} configure will automaticly adds the -belf flag to CC and
CXX if you are using gcc.
@item
@strong{MySQL} should automaticly detect FPU-threads and link mysqld
with: @code{-lgthreads -lsocket -lgthreads}
@item
The SCO development libraries are reentrant in FSU pthreads. SCO claims
that its libraries function are reentrant so they must be reentrant with
FSU pthreads. FSU pthreads on OpenServer tries to use the SCO scheme to
make reentrant library.
@item
FSU threads (at least the version at www.tcx.se) comes linked with
gnu-malloc.  If you get problems with memory usage, check that gmalloc.o
is included in libgthreads.a and libgthreads.so
@item
In FSU pthreads the following system calls are pthread aware: read,
write, getmsg, connect, accept, select and wait.
@end itemize

@node IBM-AIX,  , SCO, Machine-OS
@subsection IBM-AIX notes.

When using THE IBM compiler something like this is needed.

@example
CC="xlc_r -ma -O3 -qstrict" CXX="xlC_r -ma -O3 -qstrict" ./configure
@end example

Automatic detection of xlC is missing from autoconf. 

@node Install-binary, Starting MySQL, Machine-OS, Installing
@section Installation instructions for @strong{MySQL} binary release

PLEASE always use the mysqlbug script when posting questions to the
mailinglist (@email{mysql@@tcx.se}). Even if the problem isn't a bug,
mysqlbug gathers some system information that will help other solve your
problem! @xref{Bug reports}.

@enumerate
@item
Get a distribution. That is a file called something like
mysql-version-OS.tgz. For example a file holding a @strong{MySQL}
version 3.21.15 for a intel linux machine is called
@file{mysql-3.21.15-alpha-pc-linux-gnu-i586.tgz}.
@item

Pick a directory to put @strong{MySQL} in: In the following we will use
@file{/usr/local/mysql} as the installation directory and @strong{MySQL}
version VERSION (something like 3.21.15) for SunOS5 (Solaris) as an
example.
@item

All of the following instructions assume you have permission to create
files in @file{/usr/local}.

Use the following commands to create the directory and unpack the
distribution:

@example
> cd /usr/local
> zcat /<where ever you put it>/mysql-3.20.0-SunOS5.tgz | tar xvf -
> ln -s mysql-VERSION mysql
@end example

@item
After this you should install the @strong{MySQL} privilige tables.

In some binary versions the grant tables may already be created, for
others distributions you should edit the @file{scripts/mysql_install_db}
script to have the privileges you want and run it. The default
privileges is that anybody may create/use the databases named 'test' or
starting with "test_". The @strong{MySQL} user root can do
anything. Note that you do not have to run the @strong{MySQL} server as
root. Any user is ok as long as it can read and write in the installtion
directories/files.

If you want to recreate the privilege tables remove all the *.ISM and
 *.ISD files in the mysql database directory, edit the
scripts/mysql_install_db script to have the privileges you want and run
it.

This creates the privilige tables if they don't exist:
@example
> scripts/mysql_install_db
@end example

The @code{mysql_install_db} script also starts the @code{mysqld} demon.

@item
Normal start the @strong{MySQL} server demon (not needed the first
time):

@example
> bin/safe_mysqld --log &
@end example

@item
You can test that the demon is running by running this:

@example
> bin/mysqladmin ver
@end example

That should print something like this. The exact output depends on you
platfrom and use.
@example
bin/mysqladmin  Ver 6.3 Distrib 3.21.15-alpha, for SOLARIS 2.5 on SPARCstation
TCX Datakonsult AB, by Monty

Server version          3.21.15-alpha
Protocol version        9
Connection              Localhost via UNIX socket
TCP port                3306
UNIX socket             /tmp/mysql.sock
Uptime:                 2 days 1 hour 42 min 3 sec

Running threads: 2  Questions: 450378  Reloads: 17  Open tables: 64
@end example
@end enumerate

@subsection To get perl work do the following:

@example
> cd mysqlperl
> perl Makefile.PL
> make
> make install
@end example

You should use the @code{safe_mysqld} script to the server.
@code{safe_mysqld} expects one of two conditions to be true:

@enumerate
@item
You're executing the script from the base mysql installation directory
(for example @code{/usr/local/mysql})
@item
The server should resides in @code{/my/}.  To get it to run correctly,
you should cd to @code{/usr/local/mysql} and then execute
@code{safe_mysqld} or modify the script so that it expected the base
mysql directory to be @file{/usr/local/mysql} rather than the default
@file{/my/}.
@end enumerate

By executing

@example
> bin/mysqld --help
@end example

you will get the options for mysqld (and safe_mysqld) and the current
paths. Normally you only should need to change the
@code{--basedir=path}. You can test the path switches by executing:

@example
> bin/mysqld --basedir=/usr/local --help
@end example

If you would like to use mysqlaccess and have the mysql distribution in
some nonstandard place you have to change the path to mysql in
mysqlaccess. @code{bin/mysqlaccess} about line 308:

@example
$MYSQL = '/usr/local/bin/mysql --batch --unbuffered';
@end example

If you don't change the path you will get a 'broken pipe' error when
using mysqlaccess.

If you would like @strong{MySQL} to start when you boot your machine,
you can copy @code{bin/mysql.server} to where your system has it startup
files. More information can be bound in the bin/mysql.server script
itself.

@subsection LINUX notes.

@itemize @bullet
@item
MySQL needs at least Linux 2.0.
@item
The binary distribution may need LinuxThread.
If you get an error like: 'libpthread.so.0 not found',
you have to install LinuxThreads.
You can find a copy of linuxthreads at: http://www.tcx.se//
@item
The perl distribution needs perl5.003
@end itemize

@subsection HPUX notes.

The binary distribution of @strong{MySQL} for HP-UX is distributed as an
HP depot file.  This means that you must be running at least HP-UX 10.x
to have access to HP's software depot tools.

This version of @strong{MySQL} was compiled on an HPUX 9000/8xx server
under HP-UX 10.20, and uses MIT Pthreads. It is known to work, and work
well under this configuration. This version does *not* use HP's native
thread package. It is highly unlikely that @strong{MySQL} will use HP native
threads on anything but HP-UX 10.30 or later.

Other configurations that may work:

9000/7xx - HP-UX 10.20+
9000/8xx - HP-UX 10.30 (does not use HP native threads)

The following configurations almost definately wont work:

9000/7xx or 8xx - HP-UX 10.x where x < 2
9000/7xx or 8xx - HP-UX 9.x

To install (everything, incl server, client and devel tools):

/usr/sbin/swinstall -s <full path to the depot file> mysql.full

To install server only:

/usr/sbin/swinstall -s <full path to the depot file> mysql.server

To install client pack only:

/usr/sbin/swinstall -s <full path to the depot file> mysql.client

To install developers tools only:

/usr/sbin/swinstall -s <full path to the depot file> mysql.developer

The depot will place binaries/libraries in /opt/mysql and data in
/var/opt/mysql. The depot will also create the appropriate entries in
/sbin/init.d and /sbin/rc2.d to automatically start the server on boot. This
would obviously entail being root to install.

@cindex Client libraries
@cindex Linking
@subsection Linking client libraries

Clients have to be linked with: @code{-lmysqlclient}

@node Starting MySQL, Automatic start, Install-binary, Installing
@section Problems starting @strong{MySQL}

Check the log file to see if mysqld started up correctly.

@code{mysqld} demon starts with a cd to 'mysql-data-dir'. After this, mysqld-data-dir
is changed to './' (current dir). All paths (databases, pid file, and log file) have this
directory as base path './'. If you have any problems with wrong paths, 
try @code{mysqld --help} to see your current paths. Every path can be changed by a startup
option to @code{safe_mysqld} or @code{mysqld}

@example
cd <localstatedir default /usr/local/var>
tail <your host name>.log
@end example

To verify that @strong{MySQL} is working run the following tests:

@example
> cd /usr/local/bin
> ./mysqlshow
+-----------+
| Databases |
+-----------+
| mysql     |
+-----------+

> ./mysqlshow mysql
Database: mysql
+--------+
| Tables |
+--------+
| db     |
| host   |
| user   |
+--------+

> ./mysql -e "select host,db,user from db" mysql
+------+--------+------+
| host | db     | user |
+------+--------+------+
| %    | test   |      |
| %    | test_% |      |
+------+--------+------+
@end example

There is also a benchmark suite so you can compare how @strong{MySQL}
perform on different platforms. In the near future this will also be used to
comapre @strong{MySQL} to other SQL databases.

@example
> cd bench
> run-auto-increment-test
@end example

You can also run the tests in the test subdirectory. To run
@file{auto_increment.tst}:

@example
./mysql -vf test < ./tests/auto_increment.tst
@end example

Expected results are shown in the file
@file{./tests/auto_increment.res}.

@node Automatic start,  , Starting MySQL, Installing
@section Automatic start/stop of @strong{MySQL}

To start or stop @strong{MySQL} use the following commands:

@example
scripts/mysql.server stop
scripts/mysql.server start
@end example

You might want to add these start and stop commands in the appropriate
places in your @file{/etc/rc*} files when you start using @strong{MySQL}
for production applications.

@node Compatibility, Privilege system, Installing, Top
@chapter How standards compatible are @strong{MySQL}

@menu
* Extensions to ANSI::          What extension has @strong{MySQL} to ANSI SQL92?
* Missing functions::           What functionality is missing in @strong{MySQL}.
* Standards::                   What standards does @strong{MySQL} follow?
* Compatibility functions::     What functions exist only for compatibility?
* BLOB Limitations::            Limitations of BLOB and TEXT types
* Commit-rollback::             How to go cope without COMMIT-ROLLBACK
@end menu

@node Extensions to ANSI, Missing functions, Compatibility, Compatibility
@section What extension has @strong{MySQL} to ANSI SQL92?

The following are useful extensions in @strong{MySQL} that you probably
will not find in other SQL's.  Be warned that if you use them, your code
will not be portable to other SQL servers.

@itemize @bullet
@item
The field types @code{MEDIUMINT}, @code{SET}, @code{ENUM} and the
different @code{BLOB} and @code{TEXT} types.

@item
The field attributes @code{AUTO_INCREMENT}, @code{BINARY},
@code{UNSIGNED} and @code{ZEROFILL}.

@item
@strong{MySQL} maps all tables to filenames and with @strong{MySQL} one
can use standard system tools to backup, rename, move, delete and copy
tables.  This forces @strong{MySQL} to be case sensitive on table names
on operating systems that have case sensitive filenames (like most Unix
systems). If you have a problem remembering table names, create
everything in lowercase.

@item
Use of @code{INTO OUTFILE} and @code{STRAIGHT_JOIN} in a @code{SELECT}
statement. @xref{Select}.

@item
@code{EXPLAIN SELECT} to get a description on how tables are joined.

@item
Use of index names, indexes on a subpart of a field, and use of
@code{INDEX} or @code{KEY} in a @code{CREATE TABLE}
statement. @xref{Create table}

@item
Use of @code{DROP column} or @code{CHANGE column} in a @code{ALTER TABLE}
statement. @xref{Alter table}.

@item
Use of @code{LOAD DATA INFILE}. This syntax is in many cases compatible with
Oracles @code{LOAD DATA INFILE}. @xref{Load}.

@item
Using @code{"} instead of @code{'} to enclose strings.

@item
Using the escape @code{\} character.

@item
The @code{SET OPTION} statement. @xref{Set option}

@item
Using, in the @code{SELECT} part of a @code{GROUP BY} statement, fields
or functions that do not appear in the @code{GROUP BY} list.  In
@strong{MySQL} this means 'any matching value'. By using this one can
get a much higher performance by avoiding sorting and grouping
unnecessary items.  This is often used in this context:
@example
SELECT order.custid,customer.name,max(payments) from order,customer
WHERE order.custid = customer.custid GROUP BY order.custid;
@end example
In ANSI SQL you would have to add the customer.name in the @code{GROUP BY}
clause which is redundant in @strong{MySQL}.

@item
To make it easier for user that comes from different SQL environments
mysql supports a lot of aliases for many functions. For example all
string functions support both the ANSI SQL and the ODBC syntax.

@item
The @code{||} and @code{&&} operators is in @strong{MySQL} synonyms for
@code{OR} and @code{AND}, like in the C programming language.  Likewise
@code{|} and @code{&} stands for bitwise @code{OR} and @code{AND}.
Because if this nice syntax, @strong{MySQL} doesn't support the ANSI SQL
operator @code{||} for string concatenation, and one has to use
@code{CONCAT()} instead. As @code{CONCAT()} takes any number of
arguments it's easy to convert use of the @code{||} operator to
@strong{MySQL}.

@item
Use of any of the following functions or commands:
@itemize @bullet

@item
@code{CREATE DATABASE} or @code{DROP DATABASE}.
@xref{Create database}

@item
@code{%} instead of mod().  @code{%} is supported for C programmers and
for compatibility with postgreSQL.

@item
@code{=}, @code{<>}, @code{<=} ,@code{<}, @code{>=},@code{>}, @code{AND},
@code{OR}, or @code{LIKE} in a column statement

@item
@code{LAST_INSERT_ID}.
@xref{mysql_insert_id}

@item
@code{REGEXP} or @code{NOT REGEXP}.

@item
@code{CONCAT()} or @code{CHAR()} with 1 or more than 2 arguments.  In
@strong{MySQL} they can take any number of arguments.

@item
@code{BIT_COUNT()}, @code{ELT()}, @code{FROM_DAYS()}, @code{FORMAT()},
@code{IF()}, @code{PASSWORD()}, @code{ENCRYPT()},
@code{PERIOD_ADD()}, @code{PERIOD_DIFF()}, @code{TO_DAYS()},
or @code{WEEKDAY()}.

@item
Use of @code{TRIM} to trim substrings. ANSI SQL only supports removal
of single characters.

@item
The @code{STD()}, @code{BIT_OR} and @code{BIT_AND} group functions.
@item
Use of @code{MIN()} or @code{MAX()} as normal functions, not only group
functions.

@item
Use of @code{REPLACE} instead of @code{DELETE} + @code{INSERT}.
@xref{Replace}
@end itemize
@end itemize

@node Missing functions, Standards, Extensions to ANSI, Compatibility
@section What functionality is missing in @strong{MySQL}.

The following functionality is missing in the current version of
@strong{MySQL}.  For the priority of new extensions you should consult:
@uref{http://www.tcx.se/Manual_split/manual_Todo.html, The
@strong{MySQL} Todo list}. That is the latest version of the Todo list
in this manual. @xref{Todo}.

@menu
* Missing Sub-selects::         
* Missing SELECT INTO TABLE::   
* Missing Transactions::        
* Missing Triggers::            
* Missing Foreign Keys::        
* Missing Views::               
* Missing comments::            
@end menu

@node Missing Sub-selects, Missing SELECT INTO TABLE, Missing functions, Missing functions
@subsection Sub-selects

The following will not work in @strong{MySQL}:

@example
SELECT * from table WHERE id IN (SELECT id from table2)
@end example

MySQL only supports @code{INSERT ... SELECT...} and @code{REPLACE
... SELECT...}. Independent sub-selects will be probably be availably in
3.22.0.  One can now use the function @code{IN()} in other context
thought.

@node Missing SELECT INTO TABLE, Missing Transactions, Missing Sub-selects, Missing functions
@subsection SELECT INTO TABLE

MySQL doesn't yet support @code{SELECT ... INTO TABLE...}. Currently
MySQL only supports @code{SELECT ... INTO OUTFILE...}.

@node Missing Transactions, Missing Triggers, Missing SELECT INTO TABLE, Missing functions
@subsection Transactions

Transactions are not supported. @strong{MySQL} will shortly support
atomic operations which are like transactions without rollback. With
atomic operations you can make a bunch of insert/select/whatever
commands and be guaranteed that no other thread will interfere. In this
context you won't usually need rollback. Currently you can do this with
the help of the @code{LOCK TABLES/UNLOCK TABLES} command. @xref{Lock
tables}

@node Missing Triggers, Missing Foreign Keys, Missing Transactions, Missing functions
@subsection Triggers
Triggers are not supported. The planned update language will be able to
handle stored procedures, but without triggers. Triggers usually slow
down everything, even for queries when they aren't needed.

@node Missing Foreign Keys, Missing Views, Missing Triggers, Missing functions
@subsection Foreign Keys
The @code{FOREIGN KEY} syntax in @strong{MySQL} exists only for compatibility
with other SQL vendors @code{CREATE TABLE} commands: It doesn't do anything.
The @code{FOREIGN KEY} syntax without @code{ON DELETE ..} is mostly used
for documentation purposes. Some ODBC applications may uses this to
produce automatic @code{WHERE} clauses though, but this is usually
easy to override. @code{FOREIGN KEY} is sometimes used as a constraint check,
but this check is in practice unnecessary if one inserts rows in the tables
in the right order.

In @strong{MySQL} one can go around the problem that @code{ON DELETE
...} isn't implement by adding the approative @code{DELETE} statement to
the application when one deletes record from a table that has
@code{FOREIGN KEY}.  In practice this is as quick (in some case quicker)
and much more portable than using @code{FOREIGN KEY}.

Foreign keys are something that makes life very complicated, because
the foreign key definition must be stored in some database and then
the whole 'nice approach' of using only files that can be moved, copied
and removed will be destroyed.

In the near future we will extend @code{FOREIGN KEYS} so that at least
the information will be saved and may be retrieved by mysqldump and
ODBC.

@menu
* Broken Foreign KEY::          
@end menu

@node Broken Foreign KEY,  , Missing Foreign Keys, Missing Foreign Keys
@subsubsection Some reasons NOT to use FOREIGN KEYS

There is so many problems with the @code{FOREIGN KEY}s that we don't
know where to start.

@itemize @bullet
@item
The speed impact will be terrible when @code{INSERTING} and
@code{UPDATING} records and in this case almost all @code{FOREIGN KEY}
checks are useless because one usually inserts records in the right
tables in the right order.
@item
There will also be a need to hold locks on many more tables when
updating one because the side effects can cascade trough the hole
database. It's MUCH faster to first delete records from one table and
there after do delete from the other tables.
@item
One can't restore a table by doing anymore by doing a full delete from
the table and restore all records (from a new source or from a backup).
@item
If you have foreign keys you can't dump and restore tables without doing
this in a very specific order.
@item
It's very easy to do 'allowed' circular definitions that makes the
tables impossible to recreate with a single create statement, even if
the definition works and is usable.
@end itemize

The only nice aspect of foreign key is that it gives ODBC and some other
client programs the ability to see how a table is connected and use this
to show connection diagrams and to help building applicatons.

@strong{MySQL} will soon store the @code{FOREIGN KEY} definitions so that
a client can ask and receive an answer how the original connection was
made. The reason this can not be done is that the current @code{.frm} file format does not have any place for it.

@node Missing Views, Missing comments, Missing Foreign Keys, Missing functions
@subsection Views

MySQL doesn't support views, but this is on the TODO.

@node Missing comments,  , Missing Views, Missing functions
@subsection -- as start of a comment

Some other SQL has -- as start comment. @strong{MySQL} has # as the
start comment character, even if the @strong{MySQL} command line tool
removes all lines that starts with --.

MySQL will not support this degenerated comment style because we have
had many problems with automatic generated SQL queries that has used
something like the following code:

@example
UPDATE table_name SET credit=credit-!payment!
@end example

Where instead of !payment! we automaticly insert the value of the
payment.

What do you think will happen when 'payment' is negative ?

Because 1--1 is legal in SQL, we think is terrible that '--' means start
comment.

If you have a sql program in a textfile that contains -- comments you should
use

@example
replace " --" " #" < text-with-funny-comments.sql | mysql database.

instead of the normal

mysql database < text-with-funny-comments.sql
@end example

You can also change the -- to # comments in the command file with:

@example
replace " --" " #" -- text-with-funny-comments.sql
@end example

and change them back with:

@example
replace " #" " --" -- text-with-funny-comments.sql
@end example

@node Standards, Compatibility functions, Missing functions, Compatibility
@section What standards does @strong{MySQL} follow?

Entry level SQL92. ODBC level 0-2.

@node Compatibility functions, BLOB Limitations, Standards, Compatibility
@section What functions exist only for compatibility?

@itemize @bullet
@item
@code{GRANT}. @xref{Grant} This always succeeds. You should use the
MySQL privilege tables. @xref{Privileges}
@item
@code{CREATE INDEX}. @xref{Create Index} This always succeeds. You
should create your index with @code{CREATE TABLE}. @xref{Create table}
You can also use @code{ALTER TABLE}. @xref{Alter table}.
@item
@code{DROP INDEX}. @xref{Drop Index} This always succeeds. You can use
@code{ALTER TABLE} to drop indexes. @xref{Alter table}.
@end itemize

@node BLOB Limitations, Commit-rollback, Compatibility functions, Compatibility
@section Limitations of @code{BLOB} and @code{TEXT} types

If you want to @code{GROUP BY} or a @code{ORDER BY} on a @code{BLOB} or
@code{TEXT} field, you must make the field into a fixed length
object. The standard way to do this is with the @code{SUBSTRING}
functions. If you don't do this only the first @code{max_sort_length}
(default=1024) will considered when sorting.

@example
SELECT comment from table order by substring(comment,20);
@end example

@node Commit-rollback,  , BLOB Limitations, Compatibility
@section How to go cope without COMMIT-ROLLBACK

MySQL doesn't support COMMIT-ROLLBACK. The problem with COMMIT-ROLLBACK
is that for it to handle this efficiently it would require a completely
different table layout than @strong{MySQL} uses today. @strong{MySQL}
would also need extra threads that do automatic cleanups on the tables
and the disk space needed would be much higher. This would make
@strong{MySQL} about 2-4 times slower than it is today. One of the
reasons that @strong{MySQL} is so much faster than almost all other SQL
databases (typical times are at least 2-3 times faster) is the lack of
COMMIT-ROLLBACK.

For the moment, we are much more for implementing the SQL server language
(stored procedures). With this you very seldom really need COMMIT-ROLLBACK,
and you can do many more things without losing any speed.

Loops that need transactions can normally be coded with the help of
@code{LOCK TABLES} and one doesn't need cursors when one can update records
on the fly.

We have transactions and cursors on the TODO but not quite prioritised. If
it is implemented it will be as a option to @code{CREATE TABLE}. That
means that COMMIT-ROLLBACK will only work on those tables and only those
tables will be slower.

We at TcX have a greater need for a real fast database than a 100%
general database. Whenever we find a way to implement these without any
speed loss we will probably do it, but for the moment there is many more
important things to do. Check the TODO for how we prioritise things at
the moment. Customers with higher levels of support can alter this, so
things may be reprioritised.

The current problem is actually @code{ROLLBACK}. Without @code{ROLLBACK}
you can do anything with @code{LOCK TABLES}. To support @code{ROLLBACK}
@strong{MySQL} would had to be changed to store all old records that was
updated and revert everything back to the starting point if
@code{ROLLBACK} was issued. For simple cases this isn't that hard to do
(the current isamlog could be used for this), but if one wants to have
@code{ROLLBACK} with @code{ALTER/DROP/CREATE TABLE} it would make
everything much harder to implement.

To avoid using @code{ROLLBACK} one can do:

@enumerate
@item
@code{LOCK TABLES ...}
@item
Test conditions.
@item
Update if everything is ok.
@item
@code{UNLOCK TABLES}
@end enumerate

This is usually much faster, but not always. The only thing this doesn't
handle if someone does a kill on the process.

One can also use functions to update things in one operation. By doing
all updates relatively and/or only update those fields that actually
have changed one can get a very efficient application.

For example, when we are doing updates on some customer information, we
only update the customer data that has changed and only test that not
any of the changed data, or data that depends on the changed data, has
changed in the original row. The test for change is down with the
@code{WHERE} clause in the @code{UPDATE} statement. If the record wasn't
updated we give the client a message: "Some of the data you have changed
has been changed by another user", and then we show the old row versus
the new row in a window. The user can then decide which version of the
customer record he should use.

This gives us something like 'column locking' but actually even better,
because we only update some of the columns with relative
information. This means that a typical update statement looks something
like:

@example
UPDATE tablename SET pay_back=pay_back+'relative change'

UPDATE customer set customer_date='current_date', address='new address',
phone='new phone', money_he_owes_us=money_he_owes+'new_money' where
customer_id=id and address='old address' and phone='old phone';
@end example

As you can see, this is very efficient and even if another client has
changed the 'money_he_owes_us' or 'pay_back' amount this will still work.

In many cases, users have wanted @code{ROLLBACK} and/or @code{LOCK
TABLES} to manage unique identifiers for some tables. This can be
handled much more efficiently by using an @code{AUTO_INCREMENT} column
and the @strong{MySQL} API function
@code{mysql_insert_id}. @xref{mysql_insert_id}

At TcX we have never had any need for row level locking as we have
always been able to code around it. I know some cases that really need row
locking, but they are very few. If you want to have row level locking you
can do something like:

@example
UPDATE table_name SET row_flag=1 WHERE id=ID;
@end example

MySQL returns @code{affected rows} = 1 if the row was found and row_flag
wasn't 1 in the original document. On the TODO there is @code{GET_LOCK} and
@code{RELEASE_LOCK} for those that want to implement application level
locking.

@node Privilege system, Syntax, Compatibility, Top
@chapter How does @strong{MySQL} privileges work

@strong{MySQL} has a advanced but non-standard security/privilege
system.

@menu
* What Privileges::             
* Privileges::                  How does the privilege system work?
* Privilege tables::            
* Adding users::                Adding new user privileges to @strong{MySQL}
* Security::                    Default privileges.
* Security example::            A example of permission setup.
* Access denied::               
@end menu

@node What Privileges, Privileges, Privilege system, Privilege system
@section What can the privilege system do.

The basic function of the @strong{MySQL} privilege system is to give a
username on a host select,insert,update and delete privileges on a
database.

Extra function includes the ability to have a anonymous user and give
permission to use @strong{MySQL} specific funtions like @code{LOAD DATA
INFILE}.

@c and ... ???

@node Privileges, Privilege tables, What Privileges, Privilege system
@section How does the privilege system work?

In @strong{MySQL} the combination of host and user is the unique
identity. Don't think of users, think of host+user and everything should
be much clearer.  You can for example have a user named 'Robb' at two
different hosts (with different privileges) in @strong{MySQL} without
any conflicts.

The @strong{MySQL} privilege system makes sure that each user may do
exactly the things that they are supposed to be allowed to do. The
system decides to grant different privileges depending on @strong{which
xuser} connects from @strong{which host} to @strong{which database}.

You can always test your privileges with the script @code{mysqlaccess},
which Yves Carlier has provided for the @strong{MySQL} distribution.
@xref{Access denied}

The following switches to @code{mysqld} is relevant to security:
@table @code
@item --skip-grant-tables
Do not use the privilege system att all. This gives everyone @emph{full
access} to all databases!
@item --skip-name-resolve
Don't resolve hostnames. All hostnames must be IP-numbers or
'localhost'.
@item --skip-networking
Don't allow connections over the network (no TCP/IP).
@item --secure
Check that the ip that was returned from @code{get_hostbyname} resolves
back to the original hostname. This is done to make it harder for
someone on the outside to get access by simulating another host.

This is turned off by default since it sometimes takes a long time to
check this.
@end table

All privileges are stored in three tables. @code{user}, @code{host} and
@code{db}.

Everything granted in the @code{user} table is valid for every database
that cannot be found in the @code{db} table. For this reason, it might
be wise to grant users (apart from superusers) privileges on a
per-database basis only.

The @code{host} table is mainly there to maintain a list of ``secure''
servers. At TcX @code{host} contains a list of all machines on the
local network. These are granted all privileges.

The connecting user's privileges are calculated by the following
algorithm:

@enumerate
@item
First sort the tables by:
@multitable @columnfractions .3 .7
@item Table @tab Sorted by
@item host  @tab host without wild/hosts with wild/empty hosts
@item db    @tab host without wild/hosts with wild/empty hosts
@item user  @tab host/user
@end multitable
Host by putting hosts without wildcards first, followed by hosts with
wildcards and entries with @code{host = ""}. Within each host sort by
user using the same rules. Finally, in the @code{db} table, sort by db
using the same rules. In the steps below, we will look through the
sorted tables and @emph{always use the first match found}.
@item
Get the privileges for the connecting user from the @code{user} table
using the first match found. empty user.

Call this set of privileges
@var{Priv}.
@item
Get the privileges for the connecting user from the @code{db} table
using the first match found.
@item
If @code{host = ""} for the entry found in the @code{db} table, AND
@var{P} with the privileges for the host in the @code{host} table, i.e.
remove all privileges that are not "Y" in both. (If @code{host <> ""},
@var{P} is not affected. In suchcases, @code{host} must have matched the
connecting host's name at least partially. Therefor it can be assumed
that the privileges found in this row match the connecting host's
profile.)
@item
OR (add) @var{P} with the privileges for the user from the @code{user}
table, i.e. add all privileges that are "Y" in @code{user}.
@end enumerate

@emph{Remember that if you change the tables you must do a
@code{mysqladmin reload} to make the changes take effect.}

The connecting user gets the set of privileges @var{P}.

Let's show an example of the sorting and matching! Suppose that the user
table contains this:
@example
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
@end example

Then the search order will be:

@itemize @bullet
@item
localhost/root
@item
localhost/any
@item
any/jeffrey
@item
any/root
@end itemize

So jeffrey attempting to connect on localhost will be matched by the
@code{localhost/any} line, not by the @code{any/jeffrey} line. The
first match found is used!

So if you have access problems, print out the user table, sort it by
hand, and see where the match is being made.

Here follows an example to add a user 'custom' that can connect from hosts
'localhost', 'server.domain' and 'whitehouse.gov'. He wants to have password
'stupid'. The database 'bankacount' he only want to use from 'localhost' and
the 'customer' database he wants to be able to reach from all three hosts.

@example
shell> mysql mysql.
mysql> insert into user (host,user,password)
       values('localhost','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('server.domain','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('whitehouse.gov','custom',password('stupid'));

mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('localhost','bankacount','custom','Y','Y','Y','Y','Y','Y');
mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('%','customers','custom','Y','Y','Y','Y','Y','Y');
@end example

You can of course also use xmysqladmin, mysql_webadmin, mysqladmin and even
xmysql to insert/change and update values in the privilege tables.
You can find these utilities in the Contrib directory.

@node Privilege tables, Adding users, Privileges, Privilege system
@section The privilege tables

The grant tables privileges on rows are @strong{select},
@strong{insert}, @strong{update} and @strong{delete}.

The table and database privileges are @strong{create} and @strong{drop}.
Create and drop are for both tables and databases. Since a user with a
drop grant can delete any table, this is the same thing as a drop grant
for the database.

Other privileges give the right to use files (for @code{LOAD DATA INFILE} and
@code{SELECT INTO OUTFILE}) and to use the administrative commands
@strong{shutdown}, @strong{reload}, @strong{refresh} and @strong{process}.


The privilege system is based on 3 tables.

@table @asis
@item @code{user} table
Contains all host+user combinations that are allowed to connect to the
mysql server, together with their optional passwords. The @code{user}
table has the following columns:
@multitable @columnfractions .3 .3 .2 .2
@item Field         @tab Type          @tab Key @tab Default
@item Host          @tab char(60)      @tab PRI @tab ""
@item User          @tab char(16)      @tab PRI @tab ""
@item Password      @tab char(16)      @tab  -  @tab ""
@item Select_priv   @tab enum('N','Y') @tab  -  @tab N
@item Insert_priv   @tab enum('N','Y') @tab  -  @tab N
@item Update_priv   @tab enum('N','Y') @tab  -  @tab N
@item Delete_priv   @tab enum('N','Y') @tab  -  @tab N
@item Create_priv   @tab enum('N','Y') @tab  -  @tab N
@item Drop_priv     @tab enum('N','Y') @tab  -  @tab N
@item Reload_priv   @tab enum('N','Y') @tab  -  @tab N
@item Shutdown_priv @tab enum('N','Y') @tab  -  @tab N
@item Process_priv  @tab enum('N','Y') @tab  -  @tab N
@item File_priv     @tab enum('N','Y') @tab  -  @tab N
@end multitable
@item @code{db} table
Contains which databases a host+user is allowed to use, and what he can
do with the tables in each database. The @code{db} table has the
following columns:
@multitable @columnfractions .4 .2 .2 .2
@item Field       @tab Type          @tab Key @tab Default
@item Host        @tab char(60)      @tab PRI @tab ""
@item Db          @tab char(32)      @tab PRI @tab ""
@item User        @tab char(16)      @tab PRI @tab ""
@item Select_priv @tab enum('N','Y') @tab  -  @tab N
@item Insert_priv @tab enum('N','Y') @tab  -  @tab N
@item Update_priv @tab enum('N','Y') @tab  -  @tab N
@item Delete_priv @tab enum('N','Y') @tab  -  @tab N
@item Create_priv @tab enum('N','Y') @tab  -  @tab N
@item Drop_priv   @tab enum('N','Y') @tab  -  @tab N
@end multitable
@item @code{host} table
Is only used in big networks as a lookup for empty host entries in the
db table.  This means that if you want a user to be able to use the
database from all hosts in your network, you should put '' as the host
name in the db table.  In this case the @code{host} table should contain
a entry for every host in your network. The @code{host} table has the
following columns:
@multitable @columnfractions .4 .2 .2 .2
@item Field       @tab Type          @tab Key @tab Default
@item Host        @tab char(60)      @tab PRI @tab ""
@item Db          @tab char(32)      @tab PRI @tab ""
@item Select_priv @tab enum('N','Y') @tab  -  @tab N
@item Insert_priv @tab enum('N','Y') @tab  -  @tab N
@item Update_priv @tab enum('N','Y') @tab  -  @tab N
@item Delete_priv @tab enum('N','Y') @tab  -  @tab N
@item Create_priv @tab enum('N','Y') @tab  -  @tab N
@item Drop_priv   @tab enum('N','Y') @tab  -  @tab N
@end multitable
@end table

@itemize @bullet
@item
The @var{host} and @var{db} columns may contain a string with the SQL
wildcards @code{%} and @code{_}. Leaving any of these columns empty is
equivalent to setting it to '%'.
@item
A @var{host} may be @code{localhost}, a hostname, an IP number or a
string with wildcards. An empty host in the db table means any host in
the host table.  An empty host in the host or user table means @emph{any
host that can create a TCP connection to your server}.
@item
A @var{db} is the name of a database or an SQL regexp.
@item
An empty @var{user} column means any username will do. One can't have
wildcards in the user name.
@item
A user not matching anything in the @code{user} table will be processed
as a no-name user.
@item
The privileges from the user table are OR'ed to the @code{db} table.
This means that a superuser only needs to be in the user table with all
privilege-flags set to @code{Y}.
@end itemize

You can use a entry like @code{123.444.444.%} in the host table to give
every user on a IP C-net access. To avoid the possiblity that somebody
tries to fool this setup by nameing a host to
@code{123.444.444.somewhere.com} to fool the permission system. To avoid
this problem @strong{MySQL} disallows all hostnames that start with
digits and a dot. So if your host is named something like
@code{1.2.foo.com} it will never be allowed with name matching. Use the
IP number in this case.

@node Adding users, Security, Privilege tables, Privilege system
@section Adding new user privileges to @strong{MySQL}

To add privileges to the @strong{MySQL} database:

This assumes the current user has insert privileges for the mysql db
table and reload privileges. The server (mysqld) has to be running. If
it is not, start it with @code{safe_mysqld --log &}.

@example
> mysql mysql
  insert into user values ('%','monty',password('something'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') ;
  insert into user (host,user,password) values('localhost','dummy','') ;
  insert into user values ('%','admin','','N','N','N','N','N','N','Y','N','Y','Y') ;
  quit
> mysqladmin reload
@end example

This makes three new users:
@table @code
@item Monty
Full superuser, but must use password when using @strong{MySQL}.

@item admin
Doesn't need a password but is only allowed to use @code{mysqladmin reload},
@code{mysqladmin refresh} and @code{mysqladmin processlist}. May be granted
individual database privileges through table @code{db}.

@item dummy
Must be granted individual database privileges through table @code{db}.
@end table

@node Security, Security example, Adding users, Privilege system
@section Default privileges.

The default privileges (set in @file{scripts/mysql_install_db}) 
let root do anything. Any user can do anything with any database whose
name is 'test' or starts with 'test_'. A normal user can't use
@code{mysqladmin shutdown} or @code{mysqladmin processlist}. See the
script (@file{scripts/mysql_install_db}) for an example on how to add
other users.

The privilege tables are read into mysqld with @code{mysqladmin reload}.

@node Security example, Access denied, Security, Privilege system
@section A example of permission setup.

A common mistake is to forget that passwords are stored encrypted,
which leads to something like:

@code{INSERT INTO user VALUES ('%','jeffrey','bLa81m0','Y','Y','Y','N','N','N','N','N', 'N','N');}

Then (of course) a @code{mysqladmin reload} to make the authentication
change take effect, then trying to connect to the server:

$ @code{ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test}
Access denied

Try this instead:

@code{INSERT INTO user VALUES
('%','jeffrey',password('bLa81m0'),'Y','Y','Y','N','N','N','N','N','N','N');}

And like before @code{mysqladmin reload} to make the authentication change
take effect.

Now things should work.

@node Access denied,  , Security example, Privilege system
@section Why do I get this @code{Access denied?} error.

@itemize @bullet
@item
Have you installed the @strong{MySQL} grant tables with the script
'mysql_install_db'? Test by executing 'mysql -u root test'. This should
not give an error. You can also check if you have a file 'user.ISD' in
the mysql database directory (ordinary install_dir/var/mysql/user.ISD).
@item
Remember that you have to do 'mysqladmin reload' each time you change
the grant tables. Otherwise the old tables are still used!
@item
For testing, you should start the mysqld demon with the
@code{--without-grant-tables} option. Now you can change the @strong{MySQL}
grant tables and use the script @code{mysqlaccess} to check if your
grants works. @code{mysqladmin reload} tells the mysqld demon to
start using the new grant tables.
@item
Even if you have access problems with perl, python, or ODBC, always test
your privilege problems with @code{mysql -u user database} or
@code{mysql -uuser -ppassword database}.
@item
If you get the error 'Access denied' when trying to connect to the
database with @code{mysql -u user database} then you have a problem with
the 'user' table. Check this by doing @code{mysql -u root mysql} and
@code{select * from user}. You should get an entry with 'hostname' and
'user' matching your computers hostname and your username. If the client
and the server is running on the same host and you haven't used the
@code{--host} option to mysql and you are not using MIT threads,
'localhost' is a synonym for your hostname.
@item
The @code{Access denied} error message will tell you who you are trying
to log in as, from which host you are trying to log in from and if you
was using a password or not. You should normally have one entry in the
@code{user} table that exactly matches your host and user, exactly as
given in the error message.
@item
If @code{mysql -u root test} works but @code{mysql -h your_hostname -u
root test} gives 'Access denied' then you don't have the right name for
your host in the user table. For example if you have an entry with host
'tcx' in the 'user' table, but your DNS tells @strong{MySQL} that your
hostname is 'tcx.subnet.se' then the entry will not work. Test by adding
a record with the IP of your host in the 'user' table. You can,
natuarally, also add a host with a wildcard (for example 'tcx%') in the
'user table' (but using hostnames ending with % is pretty insecure).
@item
When using MIT threads, localhost is never used. All connections to the
mysqld demon is done by TCP IP and you must have your real hostname in
'user' even if you are running the client on the same host as the
server.
@item
If you get the error 'Access to database denied' then you have a problem
with the db table. If the used entry in the db table has an empty
hostname, check also the corresponding entry in the 'host' table.
@item
If @code{mysql -u user database} works on the server machine, but
@code{mysql -u host -u user database} doesn't work on another client
machine, then you don't have the client machine in the 'user' or the
'db' table.
@item
If you can't get password to work, remember that passwords must be
inserted with the PASSWORD function. @xref{Security example}
@item
If @code{mysql -u user test} works but @code{mysql -u user
other_database} doesn't work, you don't have the other_database in the
'db' table.
@item
If you get 'Access to database denied' when using the @code{SELECT
... INTO OUTFILE} or @code{LOAD DATA} SQL commands then you probably
don't have the file_priv privilege set for you in the user table.
@item
If everything else fails, start the @code{mysqld} demon with:
@code{--debug=d,general,query}. This will print info about the host and
user that tries to connect and also information about each command
issued. @xref{Debugging}.
@item
If you have any other problems with the @strong{MySQL} grant tables and
feel you must post the problem to the list, always add a dump of the
@strong{MySQL} grant tables. You can dump the tables with the
@code{mysqldump mysql} command. And as always post your problem with the
@code{mysqlbug} script.
@end itemize

@node Syntax, Stabilty, Privilege system, Top
@chapter @strong{MySQL} language reference

@menu
* Base Syntax::                 Literals. That is how are strings and numbers written?
* Column types::                Column types.
* Functions::                   Functions
* Create database::             Create database syntax.
* Drop database::               Drop database syntax.
* Create table::                CREATE TABLE syntax.
* Alter table::                 ALTER TABLE syntax
* Delete table::                DROP TABLE syntax.
* Delete::                      DELETE syntax.
* Select::                      SELECT syntax
* Join::                        Join syntax
* Insert::                      INSERT syntax
* Replace::                     REPLACE syntax
* Load::                        LOAD DATA INFILE syntax
* Update::                      UPDATE syntax
* Show::                        SHOW syntax. Get information about named of columns.
* Explain::                     EXPLAIN syntax. Get information about a SELECT.
* Describe::                    DESCRIBE syntax. Get information about names of columns.
* Lock tables::                 LOCK TABLES syntax.
* Set option::                  SET OPTION syntax.
* Grant::                       GRANT syntax. (Compatibility function).
* Create Index::                Create index syntax. (Compatibility function).
* Drop Index::                  Drop index syntax. (Compatibility function).
* Reserved words::              Is @strong{MySQL} picky about reserved words?
@end menu


@cindex Strings, How to escape things
@node Base Syntax, Column types, Syntax, Syntax
@section Literals. How do you write strings and numbers?

@subsection Strings

A string may have ' or " around it.

\ is a escape character. The following escape characters are recognised:
@table @code
@item \0
A ascii 0 character.
@item \n
A newline character.
@item \t
A tab character.
@item \r
A return character.
@item \b
A backspace character.
@item \'
A @code{'} character.
@item \"
A @code{"} character.
@item \\
A @code{\} character.
@item \%
A @code{%} character. This is used in wild-card strings to search after
@code{%}.
@item \_
A @code{_} character. This is used in wild-card strings to search after
@code{_}.
@end table

@example
A ' inside a string started with ' may be written as ''.
A " inside a string started with " may be written as "".
@end example

Some example selects that shows how it works.
@example
MySQL> select 'hello', "'hello'", '""hello""', '''h''e''l''l''o''', "hel""lo";
1 rows in set (0.00 sec)

+-------+---------+-----------+-------------+--------+
| hello | 'hello' | ""hello"" | 'h'e'l'l'o' | hel"lo |
+-------+---------+-----------+-------------+--------+
| hello | 'hello' | ""hello"" | 'h'e'l'l'o' | hel"lo |
+-------+---------+-----------+-------------+--------+
@end example

@example
mysql> select 'hello', "hello", '""hello""', "'ello", 'e''l''lo', '\'hello';
1 rows in set (0.00 sec)

+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | 'ello | e'l'lo | 'hello |
+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | 'ello | e'l'lo | 'hello |
+-------+-------+-----------+-------+--------+--------+
@end example

@example
mysql> select "This\nIs\nFour\nlines";
1 rows in set (0.00 sec)

+--------------------+
| This
Is
Four
lines |
+--------------------+
| This
Is
Four
lines |
+--------------------+
@end example

@cindex Quoting of binary data

If you want to insert binary data into a blob the following characters
must be represented by escape sequences:
@table @code
@item \0
Ascii 0. Should be replaced with "\0" (A backslash and a 0 digit).
@item \
Ascii 92, backslash
@item '
Ascii 39, Single quote
@item "
Ascii 33, Double quote
@end table

@subsection Numbers

Integers are just a sequence of digits. Floats use @code{.} as a decimal
separator.

Examples of valid numbers are: @code{1221}, @code{294.42},
@code{-32032.6809e+10}.

@subsection @code{NULL}

When using the text file export formats, @code{NULL} may be represented
by @code{\N}. @xref{Load}

@menu
* Legal names::                 
@end menu

@node Legal names,  , Base Syntax, Base Syntax
@subsection Database, table, index and column names

Database, table, index and column names all follow the same rules in
@strong{MySQL}.

A name may use alphanumeric characters from the default character
set. This is by default ISO-8859-1 Latin1 but may be changed when
compiling @strong{MySQL}.

Since @strong{MySQL} needs to be able to decide if something is a name
or a number the following special cases occurs.

@itemize @bullet
@item
A name can not consist of only numbers.
@item
A difference from many other systems is that it may start with a number.
@item
It is not recommended to use names like @code{1e}. This is because
expressions like @code{1e+1} may be interpreted like the expression
@code{1e + 1} or the number @code{1e+1}.
@end itemize

So punctuation characters like @code{.} and @code{@@} are not allowed
since they will be used to extend @strong{MySQL}.

@c force a new page for the type table if not enough space 
@need 3000
@node Column types, Functions, Base Syntax, Syntax
@section Column types.

The following column types are supported:

@itemize @bullet
@item
M means Max display size.
@item
L means the actual length in a single row.
@item
M means the maximum length.
@item
D means the number of decimals.
@end itemize

@tindex Types

@multitable @columnfractions .40 .53 .07
@item Name @tab Description @tab Size

@tindex TINYINT
@item TINYINT[(D)] [UNSIGNED] [ZEROFILL] @tab
A very small integer. Signed range -128 - 127. Unsigned range 0 -
255. @tab 1

@tindex SMALLINT
@item SMALLINT[(D)]. [UNSIGNED] [ZEROFILL] @tab 
A small integer. Signed range -32768 - 32767. Unsigned range 0 -
65535. @tab 2

@tindex MEDIUMINT
@item MEDIUMINT[(D)] [UNSIGNED] [ZEROFILL] @tab 
A medium integer. Signed range -8388608-8388607. Unsigned range 0 -
16777215. @tab 3

@tindex INT
@item INT[(D)] [UNSIGNED] [ZEROFILL] @tab 
A normal integer. Signed range -2147483648 - 2147483647. Unsigned range
0 - 4294967295. @tab 4

@tindex BIGINT
@item BIGINT[(D)] [UNSIGNED] [ZEROFILL] @tab 
A large integer. Signed range -9223372036854775808 -
9223372036854775807. Unsigned Range 0 - 18446744073709551615. @tab 8

@tindex FLOAT(4)
@tindex FLOAT(8)
@item FLOAT(Precision) @tab 
A small floating point number. Precision can be 4 or 8. FLOAT(4) is a
single precision number and FLOAT(8) is a double precision number (se
the DOUBLE entry). This syntax is for ODBC compatibility. Range
-3.402823466E+38F - -1.175494351E-38, 0, -1.175494351E-38 -
3.402823466E+38F. @tab 4

@tindex FLOAT
@tindex FLOAT(M,D)
@item FLOAT[(M,D)] @tab 
A small floating point number. Cannot be unsigned. Range
-3.402823466E+38F - -1.175494351E-38, 0, -1.175494351E-38 -
3.402823466E+38F. @tab 4

@tindex DOUBLE PRECISION
@item DOUBLE PRECISION[(M,D)] @tab 
A normal floating point number. Cannot be unsigned. Range
-1.7976931348623157E+308 - -2.2250738585072014E-308, 0,
2.2250738585072014E-308 - 1.7976931348623157E+308. @tab 8

@tindex REAL
@item REAL[(M,D)] @tab Same as DOUBLE @tab 8

@tindex DECIMAL
@item DECIMAL [(M,D)] @tab 
An unpacked floating point number. Cannot be unsigned. Currently the
same range maximum range as a double. Behaves as a CHAR column @tab M+D

@tindex NUMERIC
@item NUMERIC [(M,D)] @tab 
Same as DECIMAL @tab M+D

@tindex TIMESTAMP
@item TIMESTAMP [(M)] @tab 
An automatic timestamp. @tab 4

@tindex DATE
@item DATE @tab 
A type to store date information. Uses the "YYYY-MM-DD" syntax, but may
be updated with a number or a string. Understands at least the following
syntaxes: 'YY-MM-DD', 'YYYY-MM-DD', 'YYMMDD', 'YYMM', 'YY'.
Range 0000-00-00 to 9999-12-31. @tab 4

@tindex TIME
@item TIME @tab 
A type to store time information. Uses the "HH:MM:SS" syntax, but may be
updated with a number or a string. Understands at least the following 
syntaxes: 'HH:MM:DD, 'HHMMDD', 'HHMM', 'HH'. @tab 3

@tindex DATETIME
@item DATETIME @tab 
A type to store date and time information. Format "YYYY-MM-DD
HH:MM:SS". Takes 8 bytes. Range '0000-01-01 00:00:00' - '9999-12-31
23:59:59'. @tab 8

@tindex CHAR
@item CHAR(M) [binary] @tab 
A fixed length string that is always filled up with spaces to the
specified length. Range 1 - 255 characters. All end space are removed
when retrieved. Is sorted and compared case insensitively unless the
binary keyword is given. @tab M

@tindex VARCHAR
@item VARCHAR(M) [binary] @tab
A variable length string that is stored with its length. Maximum range 1
- 255 characters. Is sorted and compared case insensitively unless the
binary keyword is given. @tab L+1

@tindex TINYTEXT
@tindex TINYBLOB
@item TINYTEXT and TINYBLOB @tab
A @code{TEXT}/@code{BLOB} with max length of 255 characters. @tab L+1

@tindex TEXT
@tindex BLOB
@item TEXT and BLOB @tab
A @code{TEXT}/@code{BLOB} with max length of 65535 characters. @tab L+2

@tindex MEDIUMTEXT
@tindex MEDIUMBLOB
@item MEDIUMTEXT and MEDIUMBLOB @tab
A @code{TEXT}/@code{BLOB} with max length of 16777216 characters. @tab
L+3

@tindex LONGTEXT
@tindex LONGBLOB
@item LONGTEXT and LONGBLOB @tab
A @code{TEXT}/@code{BLOB} with max length of 4294967295 characters. @tab
L+4

@tindex ENUM
@item ENUM('value','value2',...) @tab
A string object that can have only one set of allowed values. @xref{Type
details}. @tab 1 or 2

@tindex SET
@item SET('value','value2',...) @tab
A string object that can have one or many values of a set of allowed
values. @xref{Type details}. @tab 1-8

@end multitable

@menu
* Type details::                More about data types
* Choosing types::              Choosing the right type for a column.
* Indexes::                     Column indexes
@end menu

@node Type details, Choosing types, Column types, Column types
@subsection More about data types 

@subsubsection Database size info.
In the above table L means the actual length of a instance and M the
maximum length. So L+1 for "abcd" means 5 bytes in the database.

If you use any data type with a L in the length field you will get a
variable length record format.

@subsubsection The numeric types
All integer types can have a optional argument @code{unsigned}.  This
can be used when you only want to allow positive numbers in the column
or you need a little bigger numerical range for the column.

Also for all integer columns the optional argument @code{ZEROFILL} means
that the column will be padded with zeroes up to the maximum length.

Max display size and decimals are for formatting and calculation of max
column width.

When storing a value in a integer that is outside its range,
@strong{MySQL} stores the maximum (or minimum) possible value. When
doing an @code{ALTER TABLE} or @code{LOAD DATA INFILE} one gets these
conversions as 'warnings'.  We have on the TODO to make INSERT and
UPDATE also can return warnings, but this is scheduled for the next
protocol change.

For example when storing @code{-999999999999999} into a int column the
value end up as @code{-2147483648}. And @code{9999999999999999} end up
as @code{2147483647}.

And if the int is unsigned the stored values above becomes @code{0} and
@code{4294967296}.

The same rules goes for all other integer types.

When returning data for an int(4) column that does not fit in it
@strong{MySQL} will return 9.99. And is an @code{UPDATE} a warning will
be issued.

Note that a type like @code{decimal(4,2)} means maximum 4 characters
with two decimal points. That gives a range between @code{-.99} ->
@code{9.99}.

To avoid some rounding problems, @strong{MySQL} always rounds everything
that it stores in any floating point column according to the number of
decimals. This means that @code{2.333} stored into @code{float(8,2)} is
stored as @code{2.33}.

@tindex TIMESTAMP
@subsubsection @code{TIMESTAMP} type
Has a range of 1 Dec 1970 time 0.00 to sometime in the year 2106 and a
resolution of one second. Will be automatically updated if not used in a
statement that updates a row or if set to @code{NULL}. Can be a (part
of) a index. Note that if you have many timestamp columns in a row, then
only the first timestamp column will be automatically updated. Any
timestamp column will be set to the current time if set to
@code{NULL}. Depending on the display size one gets one of the following
formats: "YYYY-MM-DD HH:MM:SS", "YY-MM-DD HH:MM:SS", "YYYY-MM-DD" or
"YY-MM-DD".

@tindex TEXT (Generic)
@tindex BLOB (Generic)
@subsubsection @code{TEXT} and @code{BLOB} types
These are objects that can have a variable length without upper limit.
All TEXT and BLOB objects are stored with is length (saved in 1 to 4
bytes depending on the type of object). The maximum @code{TEXT} and
@code{BLOB} length you can use is dependent on available memory and
client buffers. The only differences between @code{TEXT} and @code{BLOB}
is that @code{TEXT} is sorted and compared case insensitively while
@code{BLOB} is compared case insensitive (by character
values). @code{TEXT} and @code{BLOB} objects CANNOT be index.

A BLOB is a binary large object which can hold any amount of data.
There are 4 kinds of blobs @xref{Column types}. Normally one can regard
a BLOB as a VARCHAR without a specified limit.

@code{TEXT} is a @code{BLOB} that is sorted and compared case
insensitively.

A @code{BLOB}/@code{TEXT} column may not be bigger that the message
buffer. Note that you have to change the message buffer on both the
server and the client. @xref{MySQL parameters}.

@code{MyODBC} defines @code{BLOB}s as @code{LONGVARBINARY} and
@code{TEXT}s as @code{LONGVARCHAR}.

Restrictions for @code{BLOB} and @code{TEXT} columns:

@enumerate
@item
A @code{BLOB} or @code{TEXT} cannot be a index or a part of a index
@item
When one sorts or groups a @code{BLOB} or @code{TEXT} only the first
@code{max_sort_length} (default 1024) of the blob is used. This value
can be changed by the @code{-O} option when starting the mysqld
demon. One can group on an expression involving a @code{BLOB}/
@code{TEXT}: @code{SELECT id,SUBSTR(blob,1,100) GROUP BY 2}
@item
There is no end space truncation for @code{BLOB} and @code{TEXT} as
there is for @code{CHAR} and @code{VARCHAR}.
@end enumerate

@tindex ENUM
@subsubsection @code{ENUM} type
A string object that can have only one set of allowed values. The value
to be stored may be given case independently. If one tries to store a
non-existing value, "" is stored. If used in a number context this
object returns/stores the value index. If there is less than 255
possible values this object occupies 1 byte, else two bytes (with a
maximum of 65535 different values). Note that if a integer is put in the
@code{ENUM} you get the corresponding string with the first counting as
number zero. Sorting on @code{ENUM} types is done after the order of the
strings in the enum.

For example the column @code{test ENUM("one","two", "three")} can have
any off these values:

@example
"one"
"two"
"three"
@end example

@tindex SET
@subsubsection @code{SET} type
A string object that can have one or many values of a set of allowed
values. Each value is separated by a ','. If used in a number context
this object returns/stores the bit positions of the used values. This
object occupies (number_of_different_values-1)/8+1 bytes, rounded up to
1,2,3,4 or 8. One can't have more than 64 different values. Note that if
a integer is put in the @code{SET} you get the corresponding string with
the first bit corresponding to the first string. Sorting on @code{SET}
types is done numerically.

For example the column @code{test SET("one","two")} can have any off
these values:

@example
""
"one"
"two"
"one,two"
@end example

@cindex Types, Choosing
@cindex Choosing types
@node Choosing types, Indexes, Type details, Column types
@subsection Choosing the right type for a column.

Try to use the most precise type in all cases. For example for a integer
between 1-99999 a @code{unsigned mediumint} is the best type.

A common problem is representing monetary values accurately. In
@strong{MySQL} you should use the @code{DECIMAL} type. This is stored as
a string so no loss of accuracy should occur. If accuracy is not to
important the @code{DOUBLE} type may also be good enough.

To get real high precision you can always convert to a fixed point type
stored in a @code{BITINT}. This allows you to do all calculation with
integers and only convert the result back to floating point.

@cindex Indexes
@cindex Keys
@node Indexes,  , Choosing types, Column types
@subsection Column indexes

You can have indexes on all @strong{MySQL} columns except @code{BLOB}
and @code{TEXT} types. Using indexes on the relevant columns is the most
important thing in getting your selects to run fast.

For @code{CHAR} and @code{VARCHAR} columns you can have a index on a
prefix. The example below show how to create a index for the first 10
characters of a column. This is much faster and requires less disk space
than having a index on the whole column.

@example
CREATE TABLE test (
name CHAR(200),
KEY name (last_name(10));
@end example

@subsection Multiple column indexes

@strong{MySQL} can have one index on parts of different columns.

A multiple column index can be considered as a sorted array where the
columns are concatenated.  This makes for fast queries where the first
column in the index is a known quantity and the other columns are not.

Suppose that you have a table:

@example
CREATE TABLE test (
id INT,
last_name CHAR(30),
first_name CHAR(30),
PRIMARY KEY (id),
INDEX name (last_name,first_name));
@end example

Then the index @code{name} is a index over last_name and first_name.

The @code{name} index will be used in the following queries:

@example
SELECT * FROM test WHERE last_name="Widenius";

SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael";

SELECT * FROM test WHERE last_name="Widenius" AND
                         (first_name="Michael" OR first_name="Monty");

SELECT * FROM test WHERE last_name="Widenius" and
                         first_name >="M" and first_name < "N";
@end example

The @code{name} index will NOT be used in the following queries:

@example
SELECT * FROM test WHERE first_name="Michael";

SELECT * FROM test WHERE last_name="Widenius" or first_name="Michael";
@end example

@cindex Type portability
@subsection Type mapping to ease moving table definitions between different databases engines
                                                                     
To support easier use of code from different SQL vendors, @strong{MySQL}
does supports the following mappings:

@multitable @columnfractions .50 .50
@item binary(num)       @tab char(num) binary
@item char varying      @tab varchar
@item float4		@tab float
@item float8		@tab double
@item int1              @tab tinyint
@item int2		@tab smallint
@item int3              @tab mediumint
@item int4		@tab int
@item int8		@tab bigint
@item long varbinary    @tab blob
@item long varchar	@tab text
@item middleint         @tab mediumint
@item varbinary(num)	@tab varchar(num) binary
@end multitable

@cindex Functions for select & where
@node Functions, Create database, Column types, Syntax
@section Functions for use in @code{SELECT} and @code{WHERE} clauses 

A @code{select_expression} or @code{where_definition} can consist of any
expression using the following functions:

@need 2000
In the examples below the output of the @code{mysql} program has been
shortended. So

@example
mysql> select mod(29,9);
1 rows in set (0.00 sec)

+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+
@end example

Has been converted to 

@example
mysql> select mod(29,9);                ->      2
@end example

@menu
* Grouping functions::          Grouping functions.
* Arithmetic functions::        Normal arithmetic operations.
* Bit functions::               Bit functions.
* Logical functions::           Logical operations.
* Comparison functions::        Comparison operators.
* String comparison functions::  String comparison functions.
* Control flow functions::      Control flow functions.
* Mathematical functions::      Mathematical functions.
* String functions::            String functions.
* Date and time functions::     Date and time functions
* Miscellaneous functions::     Miscellaneous functions.
* Group by functions::          Functions for @code{GROUP BY} clause.
@end menu

@cindex Grouping of expressions
@node Grouping functions, Arithmetic functions, Functions, Functions
@subsection Grouping functions.
@ftable @code
@item (
@itemx )
@findex Parenthesis
Parenthesis. Force order of evaluation in a expression.
@example
mysql> select 1+2*3;                     ->      7
mysql> select (1+2)*3;                   ->      9
@end example
@end ftable

@node Arithmetic functions, Bit functions, Grouping functions, Functions
@subsection Normal arithmetic operations.
@findex Aritmetic expressions
@ftable @code
@item +
Addition
@item -
Subtraction.
@item *
Multiplication
@item /
Division. A division by zero results in a @code{NULL}.
@example
mysql> select 102/(1-1);                 ->      NULL
@end example
@end ftable

@cindex Aritmetic functions
@node Bit functions, Logical functions, Arithmetic functions, Functions
@subsection Bit functions.
These have a range of maximum 64 bits because @strong{MySQL} uses bigint
(64 bit) arithmetic.
@ftable @code
@item |
Bitwise OR.
@example
mysql> select 29 | 15;                   ->     31
@end example
@item &
Bitwise and.
@example
mysql> select 29 & 15;                   ->      13
@end example
@item BIT_COUNT()
Number of set bits in an argument.
@example
mysql> select bit_count(29);             ->      4
@end example
@end ftable

@node Logical functions, Comparison functions, Bit functions, Functions
@subsection Logical operations.
All logical function return 1 (TRUE) or 0 (FALSE).
@ftable @code
@item NOT
@itemx !
Logical NOT. Return 1 if argument is 0 else return 0.
@example
mysql> select NOT 1;                    ->      0
mysql> select NOT NULL;                 ->      NULL
mysql> select ! (1+1);                  ->      0
mysql> select ! 1+1;                    ->      1
@end example
@item OR
@itemx ||
Logical OR. Return 1 if any of the arguments are differs from 0.
@example
mysql> select 1 || 0;                   ->      1
mysql> select 0 || 0;                   ->      0
mysql> select 1 || NULL;                ->      1

@end example
@item AND
@itemx &&
Logical AND. Return 1 if all of the arguments is differs from 0.
@example
mysql> select 1 && NULL;                ->      0
mysql> select 1 && 0;                   ->      0
@end example
@end ftable

@cindex Casts
@cindex Type conversions
@node Comparison functions, String comparison functions, Logical functions, Functions
@subsection Comparison operators.
Returns 1 (TRUE) or 0 (FALSE). These functions work for both numbers and
strings. @strong{MySQL} uses the following rules to decide how the
compare is done:
@itemize @bullet
@item
If both arguments to a compare operation are strings, compare as
strings.
@item
If both arguments are integers, compare as integers.
@item
If one of arguments are a @code{TIMESTAMP} or @code{DATETIME} column and
the other argument is a constant. In this case the constant is converted
to a timestamp before the comparasion. All this is to be more ODBC
friendly.
@item
In all other case compare as floating point numbers (real).
@end itemize

@ftable @code
@item =
Equal.
@example
mysql> select 1 = 0;                    ->      0
mysql> select "0" = 0;                  ->      1
mysql> select "0.0" = 0;                ->      1
mysql> select "0.01" = 0;               ->      0
mysql> select ".01" = 0.01;             ->      1
@end example
@item <>
@itemx !=
Not equal.
@example
mysql> select ".01" <> "0.01";          ->      1
mysql> select .01 <> "0.01";            ->      0
mysql> select "zapp" <> "zappp";        ->      1
@end example
@itemx <=
Smaller than or equal.
@example
mysql> select 0.1 <= 2;                 ->      1
@end example
@itemx <
Smaller than.
@example
mysql> select 2 <= 2;                   ->      1
@end example
@itemx >=
Bigger than or equal.
@example
mysql> select 2 >= 2;                   ->      1
@end example
@itemx >
Bigger than.
@example
mysql> select 2 > 2;                    ->      0
@end example
@itemx ISNULL(A)
Returns 1 if @code{A} is @code{NULL} else 0. Same as @code{(A = NULL)}.
@example
mysql> select isnull(1+1);              ->      0
mysql> select isnull(1/0);              ->      1
@end example
@itemx A BETWEEN B AND C
@code{A} is bigger or equal as @code{B} and @code{A} is smaller or equal
to @code{C}. Does the same thing as @code{(A >= B AND A <= C)} if the
all arguments are of the same type.  It's the first argument (@code{A})
that decides how the comparison should be done!  If @code{A} is a string
expression, compare as strings. If @code{A} is a integer expression
compare as integers, else compare as reals.
@example
mysql> select 1 between 2 and 3;        ->      0
mysql> select 2 between 2 and 3;        ->      1
mysql> select 2 between 2 and "3";      ->      1
mysql> select 2 between 2 and "x-3";    ->      0
@end example
@end ftable

@node String comparison functions, Control flow functions, Comparison functions, Functions
@subsection String comparison functions.
@ftable @code

@item expr IN (value,...)
Returns 1 if expr is any of the values in the @code{IN} list, else it
returns 0.  If all values are constants, then all values are evaluated
according to the type of expr and sorted. The search for them item is
then done by using a binary search. This means @code{IN} is very quick
when used with constants in the @code{IN} part.
@example
mysql> select 2 in (0,3,5,"wefwf");               ->      0
mysql> select "wefwf" in (0,3,5,"wefwf");         ->      1
@end example

@item expr NOT IN (value,...)
Same as @code{NOT (expr IN (value,...))}

@findex LIKE
@item expr LIKE expr
SQL simple regular expression comparison. Returns 1 (TRUE) or 0 (FALSE).
With @code{LIKE} you have two wild characters.

@multitable @columnfractions .2 .6
@item @code{%} @tab Matches any number of characters, even zero characters.
@item @code{_} @tab Matches exactly one character.
@item @code{\%} @tab Matches one @code{%}.
@item @code{\_} @tab Matches one @code{_}.
@end multitable
@example
mysql> select "David!" like "David_";             ->      1
mysql> select "David!" like "David\_";            ->      0
mysql> select "David_" like "David\_";            ->      1
mysql> select "David!" like "%D%v%";              ->      1
@end example
@item expr NOT LIKE expr
Same as @code{NOT (expr LIKE expr)}.
@item expr REGEXP expr
Checks string against extended regular expr. @xref{Regexp}.
@example
mysql> select "Monty!" regexp "m%y%%";            ->      0
mysql> select "Monty!" regexp ".*";               ->      1
@end example
@item expr NOT REGEXP expr
Same as @code{NOT (expr REGEXP expr)}.
@item STRCMP()
Returns 0 if the strings are the same. Otherwise return -1 if first
argument is smaller according to the current sort-order, otherwise it
returns 1.
@example
mysql> select strcmp("text", "text2");            -> -1
mysql> select strcmp("text2", "text");            -> 1
mysql> select strcmp("text", "text");             -> 0
@end example
@end ftable

@node Control flow functions, Mathematical functions, String comparison functions, Functions
@subsection Control flow functions.
@ftable @code
@item IFNULL(A,B)
If @code{A} is not @code{NULL} it returns @code{A}, else @code{B}.
@example
mysql> select ifnull(1,0);        -> 1
mysql> select ifnull(0,10);       -> 0
mysql> select ifnull(1/0,10);     -> 10
@end example
@item IF(A,B,C)
If @code{A} is true (@code{A <> 0} and @code{A <> NULL}) then return
@code{B}, else return @code{C}.
@example
mysql> select if(1>2,2,3);        -> 3
@end example
@end ftable

@node Mathematical functions, String functions, Control flow functions, Functions
@subsection Mathematical functions.
All mathematical functions returns @code{NULL} in the case of a error.
@ftable @code
@item -
Sign. Changes sign of argument.
@example
mysql> select - 2;                -> -2
@end example
@item ABS()
Absolute value.
@example
mysql> select abs(2);             -> 2
mysql> select abs(-32);           -> 32
@end example
@item SIGN()
Sign of argument. Returns -1, 0 or 1.
@example
mysql> select sign(-32);          -> -1
mysql> select sign(0);            -> 0
mysql> select sign(234);          -> 1
@end example
@item MOD()
@itemx %
Module (like % in C).
@example
mysql> select mod(234, 10);       -> 4
mysql> select 253 % 7;            -> 1
mysql> select mod(29,9);                -> 2
@end example
@item FLOOR()
Largest integer value not greater than x.
@example
mysql> select floor(1.23);              -> 1
mysql> select floor(-1.23);             -> -2
@end example
@item CEILING()
Largest integer value not greater than x.
@example
mysql> select ceiling(-1.23);           -> -1
mysql> select ceiling(1.23);            -> 2
@end example
@item ROUND(N)
Round argument @code{N} to a integer.
@example
mysql> select round(-1.23);             -> -1
mysql> select round(-1.58);             -> -2
mysql> select round(1.58);              -> 2
@end example
@item ROUND(Number,Decimals)
Round argument @code{Number} to a number with @code{Decimals} decimals.
@example
mysql> select ROUND(1.298, 1);          -> 1.3
@end example
@item EXP(N)
Returns the value of @code{e} (the base of natural logarithms) raised to
the power of @code{N}.
@example
mysql> select exp(2);                   -> 7.389056
mysql> select exp(-2);                  -> 0.135335
@end example
@item LOG(X)
Return the natural logarithm of @code{X}.
@example
mysql> select log(2);             -> 0.693147
mysql> select log(-2);            -> NULL
@end example
@item LOG10(X)
return the base-10 logarithm of @code{X}.
@example
mysql> select log10(2);           -> 0.301030
mysql> select log10(100);                 -> 2.000000
mysql> select log10(-100);                -> NULL
@end example
@item POW(X,Y)
@itemx POWER(X,Y)
Return the value of @code{X} raised to the power of @code{Y}.
@example
mysql> select pow(2,2);           -> 4.000000
mysql> select pow(2,-2);                  -> 0.250000
@end example
@item sqrt(X)
Returns the non-negative square root of @code{X}.
@example
mysql> select sqrt(4);            -> 2.000000
mysql> select sqrt(20);           -> 4.472136
@end example
@item PI()
Return the value of PI.
@example
mysql> select PI();               -> 3.141593
@end example
@item COS(X)
Return the cosine of @code{X}, where @code{X} is given in radians.
@example
mysql> select cos(PI());                  -> -1.000000
@end example
@item SIN(X)
Return the sine of @code{X}, where @code{X} is given in radians.
@example
mysql> select sin(PI());                  -> 0.000000
@end example
@item TAN(X)
Returns the tangent of @code{X}, where @code{X} is given in radians.
@example
mysql> select tan(PI()+1);                -> 1.557408
@end example
@item ACOS(X)
Return the arc cosine of @code{X}; that is the value whose cosine is
@code{X}. If @code{X} is not in the range -1 to 1 @code{NULL} is
returned.
@example
mysql> select ACOS(1);                  -> 0.000000
mysql> select ACOS(1.0001);             -> NULL
mysql> select ACOS(0);          -> 1.570796
@end example
@item ASIN(X)
Return the arc sine of @code{X}; that is the value whose sine is
@code{X}. If @code{X} is not in the range -1 to 1 @code{NULL} is
returned.
@example
mysql> select ASIN("0.2");              -> 0.201358
mysql> select ASIN("foo");              -> 0.000000
@end example
@item ATAN(X)
Return the arc tangent of @code{X}; that is the value whose tangent is
@code{X}.
@example
mysql> select ATAN(2);          -> 1.107149
mysql> select ATAN(-2);         -> -1.107149
@end example
@itemx ATAN2(X,Y)
Return the arc tangent of the two variables @code{X} and @code{Y}. It is
similar to calculating the arc tangent of @code{Y / X}, except that the
signs of both arguments are used to determine the quadrant of the
result.
@example
mysql> select ATAN(-2,2);               -> -0.785398
mysql> select ATAN(PI(),0);             -> 1.570796
@end example
@item COT(N)
Return the cotangens of @code{N}.
@example
mysql> select COT(12);          -> -1.57267341
mysql> select COT(0);           -> NULL
@end example
@item RAND([X])
Returns a random float, @code{0 <= x <= 1.0}, using the integer
expression @code{X} as the optional seed value.
@example
mysql> SELECT RAND();           -> 0.5925
mysql> SELECT RAND(20);         -> 0.1811
mysql> SELECT RAND(20);         -> 0.1811
mysql> SELECT RAND();           -> 0.2079
mysql> SELECT RAND();           -> 0.7888
@end example
@item MIN(X,Y...)
Min value of arguments. Must have 2 or more arguments, else these are
@code{GROUP BY} functions. The arguments are compared as numbers. If no
records are found @code{NULL} is returned.
@example
mysql> SELECT MIN(2,0);                         -> 0
mysql> SELECT MIN(34,3,5,767);                  -> 3
mysql> SELECT MIN(a) from table where 1=0;      -> NULL
@end example
@item MAX(X,Y...)
Max value of arguments. Must have 2 or more arguments, else these are
@code{GROUP BY} functions. The arguments are compared as numbers. If no
records are found @code{NULL} is returned.
@example
mysql> SELECT MAX(34,3,5,767);                  -> 767
mysql> SELECT MAX(2,0,4,5,34);                  -> 34
mysql> SELECT MAX(a) from table where 1=0;      -> NULL
@end example
@item DEGREES(N)
Return @code{N} converted from radians to degrees.
@example
mysql> select DEGREES(PI());                    -> 180.000000
@end example
@item RADIANS(N)
Return @code{N} converted from degrees to radians.
@example
mysql> select RADIANS(90);                      -> 1.570796
@end example
@item TRUNCATE(Number, Decimals)
Truncate number @code{Number} to @code{Decimals} decimals.
@example
mysql> select TRUNCATE(1.223,1);                -> 1.2
mysql> select TRUNCATE(1.999,1);                -> 1.9
mysql> select TRUNCATE(1.999,0);                -> 1
@end example
@end ftable

@node String functions, Date and time functions, Mathematical functions, Functions
@subsection String functions.
@ftable @code
@item ASCII(S)
Returns the ASCII code value of the leftmost character of @code{S}. If
@code{S} is @code{NULL} return @code{NULL}.
@example
mysql> SELECT ascii(2);                         -> 50
mysql> SELECT ascii("dx");                      -> 100
@end example
@item CHAR(X,...)
Returns a string that consist of the characters given by the ASCII code
values of the arguments. @code{NULLs} are skipped.
@example
mysql> SELECT char(77,121,83,81,"76");          -> "MySQL"
@end example
@item CONCAT(X,Y...)
Concatenates strings. May have more than 2 arguments.
@example
mysql> SELECT CONCAT("My", "S", "QL");          -> "MySQL"
@end example
@item LENGTH(S)
@itemx OCTET_LENGTH(S)
@itemx CHAR_LENGTH(S)
@itemx CHARACTER_LENGTH(S)
Length of string. 
@example
mysql> SELECT length("text");                   -> 4
mysql> SELECT octet_length("text");             -> 4
@end example
@item LOCATE(A,B)
@itemx POSITION(B IN A)
Returns position of @code{A} substring in @code{B}. The first position
is 1. Returns 0 if @code{A} is not in @code{B}.
@example
mysql> select locate("bar", "foobarbar");         -> 4
mysql> select locate("xbar", "foobar");           -> 0
@end example
@item INSTR(A,B)
Returns position of first substring @code{B} in string @code{A}. This is
the same as @code{LOCATE} with swapped parameters.
@example
mysql> select instr("foobarbar", "bar");         -> 4
mysql> select instr("xbar", "foobar");           -> 0
@end example
@item LOCATE(A,B,C)
Returns position of first substring @code{A} in string @code{B} starting
at @code{C}.
@example
mysql> select locate("bar", "foobarbar",5);        -> 7
@end example
@item LEFT(str,length)
Gets length characters from beginning of string.
@example
mysql> select left("foobarbar", 5);             -> "fooba"
@end example
@item RIGHT(A,B)
@itemx SUBSTRING(A FROM B)
Gets @code{B} characters from end of string @code{A}.
@example
mysql> select right("foobarbar", 5);            -> "arbar"
mysql> select substring("foobarbar" from 5);    -> "arbar"
@end example
@item LTRIM(str)
Removes space characters from the beginning of string.
@example
mysql> select ltrim("  barbar");                -> "barbar"
@end example
@item RTRIM(str)
Removes space characters from the end of string.
mysql> select rtrim("barbar   ");             -> "barbar"
@item TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B)
Returns a character string with all @code{A} prefixes and/or suffixes
removed from @code{B}. If @code{BOTH}, @code{LEADING} and
@code{TRAILING} isn't used @code{BOTH} are assumed. If @code{A} is not
given, then spaces are removed.
@example
mysql> select trim("  bar   ");                      -> "bar"
mysql> select trim(leading "x" from "xxxbarxxx");    -> "barxxx"
mysql> select trim(both "x" from "xxxbarxxx");       -> "bar"
mysql> select trim(trailing "xyz" from "barxxyz");   -> "barx"
@end example
@item SOUNDEX(S)
Gets a soundex string from @code{S}. Two strings that sound 'about the
same' should have identical soundex strings. A 'standard' soundex string
is 4 characters long, but this function returns an arbitrary long
string. One can use @code{SUBSTRING} on the result to get a 'standard'
soundex string.  All non alpha characters are ignored in the given
string. All characters outside the A-Z range are treated as vocals.
@example
mysql> select soundex("Hello");                 -> "H400"
mysql> select soundex("Bдttre");                -> "B360"
mysql> select soundex("Quadratically");         -> "Q36324"
@end example
@item SUBSTRING(A, B, C)
@itemx SUBSTRING(A FROM B FOR C)
@itemx MID(A, B, C)
Returns substring from @code{A} starting at @code{B} with @code{C}
chars. The variant with @code{FROM} is ANSI SQL 92 syntax.
@example
mysql> select substring("Quadratically",5,6);          -> ratica
@end example
@item SUBSTRING_INDEX(String, Delimiter, Count)
Returns the substring from @code{String} after @code{Count}
@code{Delimiters}. If @code{Count} is positive the strings are searched
from left else if count is negative the substrings are searched and
returned from right.
@example
mysql> select substring_index("www.tcx.se", ".", 2);   -> "www.tcx"
mysql> select substring_index("www.tcx.se", ".", -2);  -> "tcx.se"
@end example
@item SPACE(N)
Return a string of @code{N} spaces.
@example
mysql> select SPACE(6);         -> "      "
@end example
@item REPLACE(A, B, C)
Replaces all occurrences of string @code{B} in string @code{A} with
string @code{C}.
@example
mysql> select replace("www.tcx.se", "w", "Ww");  -> "WwWwWw.tcx.se"
@end example
@item REPEAT(String, Count)
Repeats @code{String} @code{Count} times. If @code{Count <= 0} returns a
empty string. If @code{String} or @code{Count} is @code{NULL} or
@code{LENGTH(string)*count > max_allowed_size} returns @code{NULL}.
@example
mysql> select repeat("MySQL", 3);                -> "MySQLMySQLMySQL"
@end example
@item REVERSE(String)
Reverses all characters in string.
@example
mysql> select reverse("abc");  -> "cba"
@end example
@item INSERT(Org, Start, Length, New)
Replaces substring in @code{Org} starging at @code{Start} and
@code{Length} long with @code{New}. First position in @code{Org} is
numbered 1.
@example
mysql> select insert("Quadratic", 3, 4, "What");   -> "QuWhattic"
@end example
@item INTERVAL(N, N1, N2, N3...)
It is required that @code{Nn} > @code{N3} > @code{N2} > @code{N1} is
this function shall work. This is because a binary search is used (Very
fast). Returns 0 if @code{N} < @code{N1}, 1 if @code{N} < @code{N2} and
so on. All arguments are treated as numbers.
@example
mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);     -> 3
mysql> select INTERVAL(10, 1, 10, 100, 1000);           -> 2
mysql> select INTERVAL(22, 23, 30, 44, 200);            -> 0
@end example
@item LCASE(A)
@itemx LOWER(A)
Changes @code{A} to lower case according to current character set
,dmappings (Default Latin1).
@example
mysql> select lcase("QUADRATICALLY");           -> "quadratically"
@end example
@item UCASE(A)
@itemx UPPER(A)
Changes @code{A} to upper case.
@example
mysql> select ucase("Hej");             -> "HEJ"
@end example
@item ELT(N, A1, A2, A3...)
Returns @code{A1} if @code{N} = 1, @code{A2} if @code{N} = 2 and so
on. If @code{N} is less than 1 or bigger than the number of arguments
@code{NULL} is returned.
@example
mysql> select elt(1, "ej", "Heja", "hej", "foo");  -> "ej"
mysql> select elt(4, "ej", "Heja", "hej", "foo");  -> "foo"
@end example
@item FIELD(S, S1, S2, S3...)
Returns index of @code{S} in @code{S1}, @code{S2},
@code{S3}... list. The complement of @code{ELT()}.
@example
mysql> select ELT(2, "Hej", "ej", "Heja", "hej", "foo");                -> "ej"
mysql> select ELT(-2, "Hej", "ej", "Heja", "hej", "foo");               -> NULL
@end example
@end ftable

@node Date and time functions, Miscellaneous functions, String functions, Functions
@subsection Date and time functions

Some examples using more than one date function:

Select all record with a date_field from the last 30 days.
@example
SELECT something FROM table WHERE NOW() >
        FROM_DAYS(TO_DAYS(date_field) + 30);
@end example

@ftable @code
@item PERIOD_ADD(P, N)
Adds @code{N} months to period @code{P} (of type @code{YYMM} or
@code{YYYYMM}). Returns @code{YYYYMM}.
@example
mysql> select PERIOD_ADD(9801,2);               -> 199803
@end example
@item PERIOD_DIFF(A, B)
Returns months between periods @code{A} and @code{B}. @code{A} and
@code{B} should be of format @code{YYMM} or @code{YYYYMM}.
@example
mysql> select PERIOD_DIFF(9802,199703);         -> 11
@end example
@item TO_DAYS(Date)
Changes a @code{Date} to a daynumber (Number of days since year
0). @code{Date} may be a @code{DATE} string, a @code{DATETIME} string, a
@code{TIMESTAMP([6 | 8 | 14])} or a number of format @code{YYMMDD} or
@code{YYYYMMDD}.
@example
mysql> select TO_DAYS(9505);                    -> 733364
mysql> select TO_DAYS('1997-10-07);             -> 729669
@end example
@item FROM_DAYS()
Changes a daynumber to a DATE.
@example
mysql> select from_days(729669);                -> 1997-10-07       
@end example
@item DATE_FORMAT(Date, Format)
Formats the @code{Date} (a date or a timestamp) according to the
@code{Format} string. The following format commands are known:
@multitable @columnfractions .10 .90
@item M @tab Month name
@item W @tab Weekday name
@item D @tab Day of the month with english suffix
@item Y @tab Year with 4 digits
@item y @tab Year with 2 digits
@item m @tab Month
@item d @tab Day of the month
@item h @tab hour
@item i @tab Minutes
@item s @tab Seconds
@item w @tab Day of the week (0=Monday..)
@end multitable
All other characters are copied to the result.
@example
mysql> select date_format('1997-10-04 22:23:00', "W M Y h:i:s");
        -> "Saturday October 1997 22:23:00"
@end example
@item WEEKDAY(Date)
Gets weekday for @code{Date} (0 = Monday, 1 = Tuesday ..). @code{Date}
may be a date string, a datetime string, a timestamp([6 | 8 | 14]) or a
number of format @code{YYMMDD} or @code{YYYYMMDD}.
@example
mysql> select WEEKDAY('1997-10-04 22:23:00');           -> 5
mysql> select WEEKDAY('1997-11-05');                    -> 2
@end example
@item CURDATE()
@itemx CURRENT_DATE()
Returns todays date. In form @code{YYYYMMDD} or @code{"YYYY-MM-DD"}
depending on whether @code{CURDATE()} is used in a number or string
context.
@example
mysql> select CURDATE();                -> "1997-12-15"
mysql> select CURDATE()+0;              -> 19971215
@end example
@item CURTIME()
@itemx CURRENT_TIME()
Returns current time in form @code{HHMMSS} or @code{"HH:MM:SS"},
depending on whether @code{CURTIME()} is used in a number or string
context.
@example
mysql> select CURTIME();                -> "23:50:20"
mysql> select CURTIME()+0;              -> 235026
@end example
@item NOW()
@itemx SYSDATE()
@itemx CURRENT_TIMESTAMP()
Returns the current time in format @code{YYYYMMDDHHMMSS} or
@code{"YYYY-MM-DD HH:MM:SS"} depending on whether @code{NOW()} is used
in a number or string context.
@example
mysql> select NOW();            -> "1997-12-15 23:51:26"
mysql> select NOW()+0;          -> 19971215235131
@end example
@item UNIX_TIMESTAMP([Date])
If called without any arguments returns the current time as a unix
timestamp (seconds in GMT since 1970.01.01 00:00:00). Normally it is
called with a @code{TIMESTAMP} column as an argument in which case it
returns the columns value in seconds. @code{Date} may also be a date
string, a datetime string, or a number of format YYMMDD or YYYMMDD in
local time.
@example
mysql> select UNIX_TIMESTAMP();                         -> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');    -> 875996580
@end example
@item FROM_UNIXTIME(Unix_timestamp)
Returns a string of the timestamp in @code{YYYY-MM-DD HH:MM:SS} or
@code{YYYYMMDDHHMMSS} format depending on context (numeric/string).
@example
mysql> select FROM_UNIXTIME(875996580);   -> "1997-10-04 22:23:00"
@end example

@item FROM_UNIXTIME(Unix_timestamp, Format_string)
Returns a string of the timestamp formated according to the
Format_string. The format string may contain:
@multitable @columnfractions .2 .8
@item @code{M} @tab Month, textual
@item @code{W} @tab Day (of the week), textual
@item @code{D} @tab Day (of the month), numeric plus english suffix
@item @code{Y} @tab Year, numeric, 4 digits
@item @code{y} @tab Year, numeric, 2 digits
@item @code{m} @tab Month, numeric
@item @code{d} @tab Day (of the month), numeric
@item @code{h} @tab Hour, numeric
@item @code{i} @tab Minutes, numeric
@item @code{s} @tab Seconds, numeric
@item @code{w} @tab Day (of the week), numeric
@item All other @tab All other characters are just copied.
@end multitable
@example
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), "Y D M h:m:s x");
        -> "1997 23rd December 03:12:30 x"
@end example

@item SEC_TO_TIME(Seconds)
Returns the hours, minutes and seconds of the argument in @code{H:MM:SS}
or @code{HMMSS} format depending on context.
@example
mysql> select SEC_TO_TIME(2378);                -> "00:39:38"
mysql> select SEC_TO_TIME(2378)+0;              -> 3938
@end example
@item TIME_TO_SEC(Time)
Converts @code{Time} to seconds.
@example
mysql> select TIME_TO_SEC('22:23:00');  -> 80580
mysql> select TIME_TO_SEC('00:39:38');  -> 2378
@end example
@end ftable

@node Miscellaneous functions, Group by functions, Date and time functions, Functions
@subsection Miscellaneous functions.
@ftable @code
@item DATABASE()
Returns current database name.
@example
mysql> select DATABASE();               -> "test"
@end example
@item USER()
@itemx SYSTEM_USER()
@itemx SESSION_USER()
Returns current user name.
@example
mysql> select USER();                   -> "davida"
@end example
@item PASSWORD(String)
Calculates a password string from plaintext password @code{String}. This
must be used to store a password in the 'user' grant table.
@example
mysql> select PASSWORD("badpwd");       -> "7f84554057dd964b"
@end example
@item ENCRYPT(String[, Salt])
Crypt @code{String} with the unix @code{crypt()} command. The
@code{Salt} should be a string with 2 characters. If @code{crypt()} was
not found @code{NULL} will always be returned.
@example
@end example
@item LAST_INSERT_ID()
Returns the last automaticly generated value that was set in a
auto_increment column. @xref{mysql_insert_id}.
@example
mysql> select LAST_INSERT_ID();         -> 1
@end example
@item FORMAT(Nr, Num)
Formats number @code{Nr} to a Format like '#,###,###.##' with @code{Num}
decimals.
@example
mysql> select FORMAT(12332.33, 2);      -> "12,332.33"
@end example
@item VERSION
Return the version of the @strong{MySQL} server.
@example
mysql> select version();                -> "3.21.16-beta-log"
@end example
@end ftable

@node Group by functions,  , Miscellaneous functions, Functions
@subsection Functions for @code{GROUP BY} clause.
@ftable @code
@item COUNT(Expr)
Count number of non @code{NULL} rows. @code{count(*)} is optimised to
return very quickly if no other column is used in the @code{SELECT}.
@example
select count(*) from student;
select count(if(length(name)>3,1,NULL)) from student;
@end example
@item AVG(expr)
Average value of expr.
@item MIN(expr)
@itemx MAX(expr)
Minimum/Maximum value of expr. @code{min()} and @code{max()} may take a
string argument and will then return the minimum/maximum string value.
@item SUM(expr)
Sum of expr.
@item STD(expr)
Standard derivation of expression. This is a extension to @code{ANSI
SQL}.
@item BIT_OR(expr)
The bitwise @code{OR} of all bits in expr. Caclulation done with 64 bits
precision.
@item BIT_AND(expr)
The bitwise @code{AND} of all bits in expr. Caclulation done with 64
bits precision.
@end ftable

MySQL has extended the use of @code{GROUP BY}. You can use columns or
calculations in the @code{SELECT} expressions which doesn't appear in
the @code{GROUP BY} part. This stands for 'any possible value for this
group'.  By using this, one can get a higher performance by avoiding
sorting and grouping on unnecessary items.  For example, in the
following query one doesn't need to sort on b.name:

@example
SELECT a.id,b.name,COUNT(*) from a,b WHERE a.id=b.id GROUP BY a.id
@end example

@findex CREATE DATABASE
@node Create database, Drop database, Functions, Syntax
@section Create database syntax.

@example
CREATE DATABASE database_name
@end example

Creates a database with the given name. The name can only contain letters,
numbers or the @code{'_'} character. The max length of the database name is
32 characters. 
All databases in @strong{MySQL} are directories, so a CREATE DATABASE only
creates a directory in the @strong{MySQL} database directory.
You can also create databases with @code{mysqladmin}. 
@xref{Programs}

@findex DROP DATABASE
@node Drop database, Create table, Create database, Syntax
@section Create database syntax.

@example
DROP DATABASE database_name
@end example

Drop all tables in the database and deleted the database.
@strong{You have to be VERY carefull with this command!}
@code{DROP DATABASE} returns how many files was removed from the directory.
Normally this is number of tables*3. 
You can also drop databases with @code{mysqladmin}. 
@xref{Programs}

@findex CREATE TABLE
@node Create table, Alter table, Drop database, Syntax
@section CREATE TABLE syntax.

@example
CREATE TABLE table_name ( create_definition,... )

create_definition:
  column_name type [DEFAULT default_value] [NOT NULL | NULL] [ PRIMARY KEY ]
                   [reference_definition]
  or	PRIMARY KEY ( index_column_name,... )
  or	KEY [key_name] KEY( index_column_name,...)
  or	INDEX [index_name] ( index_column_name,...)
  or	UNIQUE [index_name] ( index_column_name,...)
  or    FOREIGN KEY index_name ( index_column_name,...) [reference_definition]
  or	CHECK (expr)

index_column_name:
	column_name [ (length) ]

reference_definition:
	REFERENCES table_name [( index_column_name,...)]
                   [ MATCH FULL | MATCH PARTIAL]
                   [ ON DELETE reference_option]
                   [ ON UPDATE reference_option]

reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
@end example

The FOREIGN KEY, CHECK and REFERENCE syntax are only for compatibility.
They don't actually do anything. @xref{Missing functions}

If a column doesn't have a DEFAULT value and is not declared as NOT NULL,
the default value is NULL.

@itemize @bullet
@item
ZEROFILL means that number is pre-zeroed to maximal length. With
@code{INT(5) ZEROFILL} a value of 5 is retrieved as @code{00005}.
@item
@code{BINARY} means that the column will be compared case sensitive. The
default is that all strings are compared case insensitive. @code{BINARY}
is 'sticky' which means that if a column marked @code{BINARY} is used in
a expression, the whole expression is compared @code{BINARY}.
@item
KEY is only a synonym for INDEX.
@item
If one doesn't assign a name to a index, the index will get the same
name as the first key_column with an optional _# to make it unique.
@item
Index columns and timestamp columns can't be NULL. For these columns the NULL
attribute is silently removed.
@item
With @code{column_name(length)} syntax one can specify a index which is only
a part of a @code{string} column. This can make the index file much smaller.
@item
A number column may have the additional attribute AUTO_INCREMENT
to automatically get the largest value+1 for each insert where column
value is NULL or 0. @xref{mysql_insert_id}
@item
One can insert NULL for timestamp and auto_increment columns. This results
in the current time / the next number.
@item
Blob columns can't be index.
@item
When one groups on a blob only the first 'max_sort_length' bytes are
used. @xref{BLOB Limitations}.
@item
Deleted records are in a linked list and subsequent inserts will reuse old
positions. To get smaller files one can use the @code{isamchk} utility to
reorganise tables.
@item
Each null column takes 1 bit extra, rounded up to the nearest byte.
@item
The maximum record length can be calculated as follows: 1+
sum_of_column_lengths + null_columns/8 + number of variable length
columns.
@item
In some cases an attribute may silently change after creation: @code{VARCHAR}
columns with a length of 1 or 2 are changed to @code{CHAR}. When using one
@code{VARCHAR} column all @code{CHAR} columns longer than 2 are changed to
@code{VARCHAR}'s.
@item
On @code{INSERT}/@code{UPDATE} all strings (@code{CHAR} and
@code{VARCHAR}) are silently chopped/padded to the maximal length given
by CREATE. All end spaces are also automatically removed. For example
@code{VARCHAR(10)} means that the column can contain strings with a
length up to 10 characters.
@item
Something/0 gives a @code{NULL} value.
@item
The regular expression function (@code{REGEXP} and @code{RLIKE}) uses
ISO8859-1 (Latin1) when deciding the type of a character.
@end itemize

@findex ALTER TABLE
@node Alter table, Delete table, Create table, Syntax
@section ALTER TABLE syntax

@example
ALTER [IGNORE] TABLE table_name alter_spec [, alter_spec ...]

alter_specification:
	ADD [COLUMN] create_definition
or	CHANGE [COLUMN] old_column_name create_definition
or	ALTER [COLUMN] column_name @{ SET DEFAULT literal | DROP DEFAULT @}
or	DROP [COLUMN] column_name
or	DROP PRIMARY KEY
or	DROP INDEX key_name
or	RENAME TABLE AS new_table_name
@end example

@itemize @bullet
@item
@code{ALTER TABLE} works by creating a temporary table and copying all
information to it and then the old table is deleted and the new one is
renamed. This is done in such a way that all updates are automatically
redirect to the new table without any failed updates. While the
@code{ALTER TABLE} is working, the old table is readable for other
clients. Table updates/writes to the table are stalled and only executed
after the new table is ready.
@item
If @code{IGNORE} isn't specified then the copy will be aborted and
rolled back if there exists any duplicated unique index in the new
table. This is a @strong{MySQL} extension.
@item
The @code{CHANGE column_name}, @code{DROP column_name} and @code{DROP
INDEX} are @strong{MySQL} extensions to ANSI SQL92.
@item
The optional word @code{COLUMN} is a pure noise word and can be omitted.
@item
The @code{ADD} and @code{CHANGE} takes the same create_definition as
@code{CREATE TABLE}. @xref{Create table}.
@item
@code{ALTER COLUMN} sets a new default value or removes the old
default value for a column.
@item
@code{DROP INDEX} removes an index. This is an @strong{MySQL} extension.
@item
The @code{FOREIGN KEY} syntax in @strong{MySQL} exists only for compatibility.
@xref{Missing functions}
@item
If one drops a column_name which is part of some index, this index part is
removed. If all index parts are removed then the index is removed.
@item
@code{DROP PRIMARY KEY} drops index named @code{PRIMARY} or if no such
index exists, it drops the first @code{UNIQUE} index in the table.
@item
@code{CHANGE} tries to convert data to the new format as good as possible.
@item
With @code{mysql_info(MYSQL*)} one can retrieve how many records were
copied and how many records were deleted because of multiple indexes.
@item
To use @code{ALTER TABLE} one has to have select, insert, delete,
update, create and drop privileges on the table.
@item
If one uses @code{ALTER TABLE table_name RENAME AS new_name} without any
other options, @strong{MySQL} will only do a fast rename of table table.
@end itemize

@findex DELETE TABLE
@node Delete table, Delete, Alter table, Syntax
@section DROP TABLE syntax.

@code{DROP TABLE table_name [, table_name...]}

Removes one or more tables. All the data and the definition is
@emph{removed} so take it easy with this command!

@findex DELETE
@node Delete, Select, Delete table, Syntax
@section DELETE syntax.

@code{DELETE FROM table_name WHERE where_definition}

Returns records affected.

If one does a delete without a where clause then the table is recreated
which is much faster than doing a delete for each row. In these cases, the
SQL command returns zero as affected records.

Using @code{DELETE FROM table_name} will work even if the data files do
not exist as only information from the table definition file,
@code{table_name.frm}, is used.

@itemize @bullet
@item
All string comparisons are case independent with case according to
ISO-8859-1 Latin1.
@item
LIKE is allowed on numerical columns.
@item
Compare with explicit NULL (column = NULL) is the same as if IS NULL was
used (column IS NULL). This is is done to be consistent with
@code{mSQL}.
@end itemize

@findex SELECT
@node Select, Join, Delete, Syntax
@section SELECT syntax

@code{SELECT [STRAIGHT_JOIN] [DISTINCT | ALL] select_expression,... [INTO OUTFILE 'file_name' ...] [ FROM table_references [WHERE where_definition ] [GROUP BY column,...] [ ORDER BY column [ASC | DESC] ,..] HAVING where_definition [LIMIT [offset,] rows] [PROCEDURE procedure_name]] }

Strings are automatically converted to numbers and numbers to strings
when needed (a-la Perl). If in a compare operation (@code{(=, <>, <= ,<,
>=, >)}) either of the arguments are numerical, the arguments are
compared as numbers, else the arguments are compared as strings. All
string comparisons are by default done case-independent by ISO8859-1
(The Scandinavian letter set which also works excellently with English).

@example
select 1 > "6x";        ->      0

select 7 > "6x";        ->      1

select 0 > "x6";        ->      0 

select 0 = "x6";        ->      1
@end example

@itemize -
@item
A column name does not have to have a table prefix if the given column name
is unique.
@item
A select expression may be given an alias which will be its column name and
can be used when sorting and grouping or in the @code{HAVING} clause.
@example
select concat(last_name,' ',first_name) as name from table order by name
@end example
@item
Table_references is a list of tables to join. This may also contain
@code{LEFT OUTER JOIN} references.
@xref{Join}
@item
In LIKE expressions % and _ may be preceded with '\' to skip the wild-card
meaning and get a literal % or _.
@item
A DATE is a string with one of the following syntaxes:
@itemize -
@item
YYMMDD        (Year is assumed to be 2000 if YY < 70.)
@item
YYYYMMDD
@item
YY.MM.DD	Where '.' may be any non numerical separator.
@item
YYYY.MM.DD	Where '.' may be any non numerical separator.
@end itemize

@item
@code{IFNULL()} and @code{IF()} returns number or string value according to
use.
@item
@code{ORDER} and @code{GROUP} columns may be given as column names,
column alias or column numbers in @code{SELECT} clauses.
@item
The @code{HAVING} clause can take any columns or alias in the
select_expressions. It is applied last, just before items are sent to
the client, without any optimisation. Don't use it for items that should
be in the WHERE clause. You can't write (yet):

@example
@code{SELECT user,MAX(salary) FROM users GROUP BY users HAVING max(salary)>10}
@end example

Change it to:

@example
@code{SELECT user,MAX(salary) AS sum FROM users GROUP BY users HAVING sum > 10}
@end example

@item
@code{STRAIGHT_JOIN} forces the optimiser to join the tables in the same
order that the tables are given in the @code{FROM} clause. One can use
this to get a query to be done more quickly if the optimiser joins the
tables in not optimal order. @xref{Explain}
@item
LIMIT takes one or two numerical arguments.
@itemize @bullet
@item
If one argument, the argument indicates the maximum number of rows in a result.
@item
If two arguments, the first argument says the offset to the first row to
return, the second is the maximum number of rows.
@end itemize
@item
INTO OUTFILE 'filename' writes the given set to a file. The file can not
exist from before. @xref{Load}.
@end itemize

@findex LEFT JOIN
@findex JOIN
@node Join, Insert, Select, Syntax
@section Join syntax

@strong{MySQL} supports the following @code{JOIN} syntaxes:

@example
table_reference, table_reference
table_reference [CROSS] JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference ON conditional-expr
table_reference LEFT [OUTER] JOIN table_reference USING (column-commalist)
table_reference NATURAL LEFT [OUTER] JOIN table_reference
@{ oj table_reference LEFT OUTER JOIN table_reference ON conditional-expr @}
@end example

@itemize @bullet
@item
A table reference may be aliased with @code{table_reference AS alias} or
@code{table_reference alias}.
@item
@code{,} and @code{JOIN} are semantically identical.  This does a full join
between the used tables.  One normally specifies in the @code{WHERE}
condition how the tables should be linked.
@item
The @code{ON} conditional is any @code{WHERE} conditional.  If there is no
matching record in for the right table in a @code{LEFT JOIN} a row with all
columns set to NULL will be used for the right table.
@item
The @code{USING} column-list is a list of fields that must exists in both
tables.  @code{A LEFT JOIN B USING (C1,C2,C3...)} is defined to be semantically
identical to using a @code{ON} expression
@code{ A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3... }.
@item
The @code{NATURAL LEFT JOIN} of two tables is defined to be semantically
identical to a @code{USING} with all column names that exists in both
tables.
@item
The last @code{LEFT JOIN} syntax is only to be compatible with ODBC.
@end itemize

@findex INSERT
@node Insert, Replace, Join, Syntax
@section INSERT syntax

@example
	INSERT INTO table [ (column_name,...) ] VALUES (expression,...)
or	INSERT INTO table [ (column_name,...) ] SELECT ...
@end example

An expression may use any previous column in column_name list (or table if
no column name list is given).

The following holds for a multi-row @code{INSERT} statement:
@itemize -
@item
The query cannot contain an @code{ORDER BY} clause.
@item
The target table of the @code{INSERT} statement cannot appear in the FROM
clause of the query.
@item
If one uses @code{INSERT INTO ... SELECT ...} then one can get the following
info string with the C API function @code{mysql_info()}.

@code{Records: 100 Duplicates: 0 Warnings: 0} Duplicates are number of
rows which couldn't be written because some index would be
duplicated. Warnings are columns which were set to NULL, but have been
declared NOT NULL. These will be set to their default value.
@item
If one sets a time stamp value to anything other than NULL, the time stamp
value will be copied to the result table. 
@item
Auto increment columns works as usual.
@end itemize

@findex REPLACE
@node Replace, Load, Insert, Syntax
@section REPLACE syntax

@example
	REPLACE INTO table [ (column_name,...) ] VALUES (expression,...)
or	REPLACE INTO table [ (column_name,...) ] SELECT ...
@end example

This works exactly like @code{INSERT}, except that if there was some old
record in the table with the same unique index the old record or records
will be deleted before this record is inserted.
@xref{Insert}.

@findex LOAD DATA INFILE
@node Load, Update, Replace, Syntax
@section LOAD DATA INFILE syntax

@code{LOAD DATA INFILE} 'text_file_name.text' [@code{REPLACE} |
@code{IGNORE}] @code{INTO} @code{TABLE} table_name [@code{FIELDS}
[@code{TERMINATED BY} ',' [@code{OPTIONALLY}] @code{ENCLOSED BY} '"'
@code{ESCAPED BY} '\\' ]] [@code{LINES TERMINATED BY} '\n'] [(Field1,
Field2...)]

This is used to read rows from a text file, which must be located on the
server, at a very high speed. The server-client protocol doesn't yet
support files over a connection. If you only have the file on the
client, use rcp or ftp to copy it, possibly compressed, to the server
before using @code{LOAD DATA INFILE}. All paths to the text file are
relative to the database directory.

To write data to a text file, use the @code{SELECT ... INTO OUTFILE
'interval.txt' fields terminated by ',' enclosed by '"' escaped by '\\'
lines terminated by '\n' FROM ...}  syntax.

Normally you don't have to specify any of the text file type options. The
default is a compact text file with columns separated with @code{tab}
characters and all rows end with a newline. Tabs, newlines and @code{\}
inside fields are prefixed with a @code{\}. NULL's are read and written as
\N.

@code{FIELDS TERMINATED BY} has the default value of @code{\t}.

@code{FIELDS [OPTIONALLY] ENCLOSED BY} has the default value of @code{''}.

@code{FIELDS ESCAPED BY} has the default value of @code{'\\'}.

@code{LINES TERMINATED BY} has the default value of @code{'\n'}.

@code{FIELDS TERMINATED BY} and @code{LINES TERMINATED BY} may be more
than 1 character.

If @code{LINES TERMINATED BY} is an empty string and @code{FIELDS
TERMINATED BY} is not empty then lines are also terminated with
@code{FIELDS TERMINATED BY}.

If @code{FIELDS TERMINATED BY} and @code{FIELDS ENCLOSED BY} both are
empty strings (@code{''}) then this gives a fixed row format ("not delimited"
import format). With a fixed row size NULL values are outputed as a 
blank string.
        
If you specify @code{OPTIONALLY} in @code{ENCLOSED BY}, then only
strings are enclosed in @code{ENCLOSED BY} by the @code{SELECT ... INTO}
statement.

Duplicated @code{ENCLOSED BY} chars are removed from strings that start
with @code{ENCLOSED BY}. For example: With @code{ENCLOSED BY '"'}:
@example
"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss	    -> The "BIG" boss
@end example

If @code{ESCAPED BY} is not empty then the following characters will be
prefixed with the escape character: @code{ESCAPED BY}, @code{ASCII 0},
and the first character in any of @code{FIELDS TERMINATED BY},
@code{FIELDS ENCLOSED BY} and @code{LINES TERMINATED BY}.

If @code{FIELDS ENCLOSED BY} is not empty then @code{NULL} is read as a
@code{NULL} value. If @code{FIELDS ESCAPED BY} is not empty then
@code{\N} is also read as a @code{NULL} value.

If @code{REPLACE} is used, then the new row will replace all rows which
have the same unique index. If @code{IGNORE} is used, the row will then
be skipped if there already exist a record with an identical unique
index. If none of the above options are used an error will be issued. The
rest of the text file will be ignored if one gets a duplicate index error.

Some possible cases that are not supported by @code{LOAD DATA}:
@itemize @bullet
@item
Fixed size rows (@code{FIELDS TERMINATED BY} and @code{FIELDS ENCLOSED
BY} both are empty) and BLOB columns.
@item
If some of the separators are a prefix of another.
@item
@code{FIELDS ESCAPED BY} is empty and the data contains @code{LINES
TERMINATED BY} or @code{FIELDS ENCLOSED BY} followed by @code{FIELDS
TERMINATED BY}.
@end itemize

All rows are read into the table. If a row has too few columns, the rest
of the columns are set to default values.

For security reasons the text file must either reside in the database
directory or be readable by all.

For more information about the escaped syntax,
@xref{Base Syntax}.

When the @code{LOAD DATA} query is done, one can get the following info
string with the C API function @code{mysql_info()}.

@code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0}

Warnings are incremented for each column which can't be stored without
loss of precision, for each column which didn't get a value from the
read text line (happens if the line is too short) and for each line
which has more data than can fit into the given columns.

An example that loads all columns:

@example
LOAD DATA INFILE 'persondata.text' INTO TABLE persondata;
@end example

@xref{Table efficiency}

@findex UPDATE
@node Update, Show, Load, Syntax
@section UPDATE syntax

UPDATE table SET column=expression,... WHERE where_definition

All updates are done from left to right. If one accesses a column in the
expression, update will then use the current value (a given value or the
default value) of the column.

@example
UPDATE persondata SET count=count+1
@end example

@findex SHOW DATABASES
@findex SHOW TABLES
@findex SHOW COLUMNS
@findex SHOW FIELDS
@findex SHOW INDEXES
@findex SHOW KEYS
@node Show, Explain, Update, Syntax
@section SHOW syntax. Get information about names of columns.

@example
	SHOW DATABASES [LIKE wild]
or 	SHOW TABLES [FROM database] [LIKE wild]
or	SHOW COLUMNS FROM table [FROM database] [LIKE wild]
or	SHOW INDEXES FROM table [FROM database]
@end example

Gives information about databases, tables or columns. If the @code{LIKE
wild} part is used the @code{wild} string is a normal SQL wildcard (with
% and _). @code{FIELDS} may be used as an alias for @code{COLUMNS} and
@code{KEYS} may be used as an alias for @code{INDEXES}.

@findex EXPLAIN
@node Explain, Describe, Show, Syntax
@section EXPLAIN syntax. Get information about a SELECT.

@example
	EXPLAIN SELECT select_options
@end example

Gives information about how and in which order tables are joined. With
the help of @code{EXPLAIN} one can see when one has to add more indexs
to tables to get a faster select that uses indexs to find the
records. You can also see if the optimiser joins the tables in an
optimal order. One can force the optimiser to use a specific join order
with the @code{STRAIGHT_JOIN} option to select.

The different join types are:

@table @code
@item system
The table has only 1 record (= system table)
@item const
The table has at most 1 matching record which will be read at the start of
the query. All columns in this table will be regarded as constants by the rest
of the optimiser.
@item eq_ref
One record will be read from this table for each combination of the previous
tables.
@item ref
All records with matching indexs will be read from this table for each
combination of the previous tables.
@item all
A full table scan will be done for each combination of the previous tables.
@end table

Here is a example of a join which is optimized with the help of
@code{EXPLAIN}.

@example
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
        tt.ProjectReference, tt.EstimatedShipDate,
        tt.ActualShipDate, tt.ClientID,
        tt.ServiceCodes, tt.RepetitiveID,
        tt.CurrentProcess, tt.CurrentDPPerson,
        tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
        et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1,
        do
        WHERE tt.SubmitTime Is Null and tt.ActualPC =
        et.EMPLOYID and tt.AssignedPC =
        et_1.EMPLOYID and tt.ClientID =
        do.CUSTNMBR;
@end example

The @code{EXPLAIN} returns the following:

@example
table   type    possible_keys   key     key_len ref     rows    Extra
et      ALL     PRIMARY NULL    NULL    NULL    74
do      ALL     PRIMARY NULL    NULL    NULL    2135
et_1    ALL     PRIMARY NULL    NULL    NULL    74
tt      ALL     AssignedPC,ClientID,ActualPC    NULL    NULL    NULL   3872
        range checked for each record (key map: 35)
@end example

In this case @strong{MySQL} is doing a full join for all tables! This will
take quite a long time as the product of the number of rows in each
table must be examined!. So if all tables had 1000 records @strong{MySQL}
has to look at 1000^4 = 1000000000000 rows. And if the tables are bigger
you can only imagine how long it would take...

In this case the first error is that @strong{MySQL} can't yet use
efficiently indexes on columns that are declared differently: (varchar()
and char() are not different in this context)

In this case @code{tt.ActualPC} is @code{char(10)} and
@code{et.EMPLOYID} is @code{char(15)}.

Fix:

@example
mysql> alter table tt change ActualPC ActualPC varchar(15);
@end example

And the above explain shows:

@example
table   type    possible_keys   key     key_len ref     rows    Extra
tt      ALL     AssignedPC,ClientID,ActualPC    NULL    NULL    NULL   3872
        where used
do      ALL     PRIMARY NULL    NULL    NULL    2135
        range checked for each record (key map: 1)
et_1    ALL     PRIMARY NULL    NULL    NULL    74
        range checked for each record (key map: 1)
et     eq_ref  PRIMARY PRIMARY 15      tt.ActualPC    1
@end example

Which is not perfect but much better. This version is executed in a
couple of seconds.

After

@example
mysql> alter table tt change AssignedPC AssignedPC varchar(15),
                      change ClientID Clientid     varchar(15);
@end example

You get the following from @code{EXPLAIN}:

@example
table   type    possible_keys   key     key_len ref     rows    Extra
et      ALL     PRIMARY NULL    NULL    NULL    74
tt      ref     AssignedPC,ClientID,ActualPC    ActualPC        15
        et.EMPLOYID   52      where used
et_1    eq_ref  PRIMARY PRIMARY 15      tt.AssignedPC  1
do      eq_ref  PRIMARY PRIMARY 15      tt.Clientid    1
@end example

Which is 'almost' as good as it can get.  The problem is that
@strong{MySQL} assumes that @code{tt.AcutalPC} is evenly distributed which
isn't the case in the tt.

Fortunally it easy to tell @strong{MySQL} about this:

@example
shell> isamchk -a PATH_TO_MYSQL_DATABASE/tt
shell> mysqladmin refresh
@end example

And now the join is 'perfect':

@example
table   type    possible_keys   key     key_len ref     rows    Extra
tt      ALL     AssignedPC,ClientID,ActualPC    NULL    NULL    NULL
        3872     where used
et      eq_ref  PRIMARY PRIMARY 15      tt.ActualPC    1
et_1    eq_ref  PRIMARY PRIMARY 15      tt.AssignedPC  1
do      eq_ref  PRIMARY PRIMARY 15      tt.Clientid    1
@end example

@findex DESC
@findex DESCRIBE
@node Describe, Lock tables, Explain, Syntax
@section DESCRIBE syntax. Get information about columns.

@code{(DESCRIBE | DESC) table [column]}

Gives information about columns. This command is for Oracle
compatibility. @xref{Show}. Column may be a column name or a
string. Strings may contain wild cards.

@findex LOCK TABLES
@findex UNLOCK TABLES
@node Lock tables, Set option, Describe, Syntax
@section @code{LOCK TABLES} syntax

@example
LOCK TABLES table_name [AS alias] READ|WRITE [, table_name READ|WRITE]
...
UNLOCK TABLES
@end example

Locks tables for this thread. Many threads may have a READ lock on the
same table, but one can use a table with a WRITE lock.  One can't update
a table on which one has a read LOCK.  When one uses @code{LOCK TABLES}
one must lock all tables one is going to use!

@example
LOCK TABLES t READ, t as t2 READ
SELECT * from t,t2;
@end example

All tables are automaticly unlocked when one issues another @code{LOCK
TABLES} or if the connection to the server is closed.

@findex SET OPTION
@node Set option, Grant, Lock tables, Syntax
@section SET OPTION syntax.

@example
SET [OPTION] SQL_VALUE_OPTION=value, ...
@end example

The used options remain in effect for the whole current session.

The different options are:

@table @code
@item SQL_SELECT_LIMIT=value 
The maximum number of records to return in any select.
If a select has a limit clause it overrides this statement.
The default value for a new connection is 'unlimited'.
@item SQL_BIG_TABLES= 0 | 1
If set to 1 then all temporary tables are stored on disk based. This
will be a little slower, but one will not get the error @code{The table
### is full} anymore for big selects that require a big temporary
tables.  The default value for a new connection is 0 (use in memory
temporary tables).
@item SQL_BIG_SELECTS= 0 | 1
If set to 1 then @strong{MySQL} will aborts if one will try to make a
select with probably will take a very long time. This is a nice to
terminate SELECTS with a erroneous @code{WHERE} statement. A big query
is defined as a @code{SELECT} that will probably have to examine more
than @code{max_join_size} rows.  The default value for a new connection
is 0 (allow all SELECT's).
@item SQL_LOG_OFF= 0 | 1
If set to 1 then no logging will done to the standard log for this client if
the client has process list privileges.
This doesn't affect the update log!
@item TIMESTAMP= timestamp_value | DEFAULT
Set the time for this client.  This is used to get the original timestamp if
one uses the update log to restore rows.
@item LAST_INSERT_ID= #
Set the value to be returned from LAST_INSERT_ID(). This is stored in the
update log when one uses LAST_INSERT_ID() in a command that updates a table.
@end table

@findex GRANT
@node Grant, Create Index, Set option, Syntax
@section GRANT syntax. (Compatibility function).

@example
GRANT (ALL PRIVILEGES | (SELECT, INSERT, UPDATE, DELETE,
 REFERENCES (column list), USAGE))
 ON table TO user,... [WITH GRANT OPTION]
@end example

This command doesn't do anything. It is only in @strong{MySQL} for
compatibility reasons. Privileges in @strong{MySQL} is handled with the
mysql grant tables. @xref{Privileges}

@findex CREATE INDEX
@node Create Index, Drop Index, Grant, Syntax
@section CREATE INDEX syntax (Compatibility function).

@code{CREATE [UNIQUE] INDEX index_name ON table_name ( column_name,... )}

This function doesn't do anything. It is only in @strong{MySQL} for
compatibility reasons.  You can create new index with ALTER
TABLE. @xref{Alter table}

@findex DROP INDEX
@node Drop Index, Reserved words, Create Index, Syntax
@section DROP INDEX syntax (Compatibility function).

@code{DROP INDEX index_name}

This always succeeds.
You can drop an index with ALTER TABLE. @xref{Alter table}

@cindex Reserved words
@node Reserved words,  , Drop Index, Syntax
@section Is @strong{MySQL} picky about reserved words?

A common problem stems from trying to create a table with column names
@code{timestamp} or @code{group}, the names of datatypes and functions
built into @strong{MySQL}.  You're allowed to do it (for example,
@code{ABS} is an allowed column name), but whitespace is not allowed
between a function name and the @code{'('} when using the functions
whose names are also column names.

The following are explictly reserved words in @strong{MySQL}. Most of
them (for example) @code{group}, are forbidden by ANSI SQL92 as column
and/or table names. A few are because @strong{MySQL} needs them and is
(currently) using a Yacc parser:

@multitable @columnfractions .25 .25 .25 .25
@c This is fixed by including symbols array from sql_lex.cc and running
@c fix-mysql-reserved-words from Davids .emacs.
@c But remove the non alphanumeric entries by hand first.
@item @code{action} @tab @code{add} @tab @code{all} @tab @code{alter}
@item @code{and} @tab @code{as} @tab @code{asc} @tab @code{auto_increment}
@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary}
@item @code{blob} @tab @code{both} @tab @code{by} @tab @code{cascade}
@item @code{char} @tab @code{character} @tab @code{change} @tab @code{check}
@item @code{column} @tab @code{columns} @tab @code{create} @tab @code{data}
@item @code{database} @tab @code{databases} @tab @code{date} @tab @code{datetime}
@item @code{day} @tab @code{day_hour} @tab @code{day_minute} @tab @code{day_second}
@item @code{dayofweek} @tab @code{dec} @tab @code{decimal} @tab @code{default}
@item @code{delete} @tab @code{desc} @tab @code{describe} @tab @code{distinct}
@item @code{double} @tab @code{drop} @tab @code{escaped} @tab @code{enclosed}
@item @code{enum} @tab @code{explain} @tab @code{fields} @tab @code{float}
@item @code{float4} @tab @code{float8} @tab @code{foreign} @tab @code{from}
@item @code{for} @tab @code{full} @tab @code{grant} @tab @code{group}
@item @code{having} @tab @code{hour} @tab @code{hour_minute} @tab @code{hour_second}
@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile}
@item @code{insert} @tab @code{int} @tab @code{integer} @tab @code{interval}
@item @code{int1} @tab @code{int2} @tab @code{int3} @tab @code{int4}
@item @code{int8} @tab @code{into} @tab @code{is} @tab @code{join}
@item @code{key} @tab @code{keys} @tab @code{leading} @tab @code{left}
@item @code{like} @tab @code{lines} @tab @code{limit} @tab @code{lock}
@item @code{load} @tab @code{long} @tab @code{longblob} @tab @code{longtext}
@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint}
@item @code{middleint} @tab @code{minute} @tab @code{minute_second} @tab @code{month}
@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not}
@item @code{null} @tab @code{on} @tab @code{option} @tab @code{optionally}
@item @code{or} @tab @code{order} @tab @code{outer} @tab @code{outfile}
@item @code{partial} @tab @code{precision} @tab @code{primary} @tab @code{procedure}
@item @code{privileges} @tab @code{read} @tab @code{real} @tab @code{references}
@item @code{rename} @tab @code{regexp} @tab @code{repeat} @tab @code{replace}
@item @code{restrict} @tab @code{rlike} @tab @code{select} @tab @code{set}
@item @code{show} @tab @code{smallint} @tab @code{sql_big_tables} @tab @code{sql_big_selects}
@item @code{sql_select_limit} @tab @code{sql_log_off} @tab @code{straight_join} @tab @code{starting}
@item @code{table} @tab @code{tables} @tab @code{terminated} @tab @code{text}
@item @code{time} @tab @code{timestamp} @tab @code{tinyblob} @tab @code{tinytext}
@item @code{tinyint} @tab @code{trailing} @tab @code{to} @tab @code{use}
@item @code{using} @tab @code{unique} @tab @code{unlock} @tab @code{unsigned}
@item @code{update} @tab @code{usage} @tab @code{values} @tab @code{varchar}
@item @code{varying} @tab @code{varbinary} @tab @code{with} @tab @code{write}
@item @code{where} @tab @code{year} @tab @code{year_month} @tab @code{zerofill}
@end multitable

The following symbols (from the table above) are disallowed by ANSI SQL
but allowed by @strong{MySQL} as column/table names. This is because
some of theese names are very natural names so a lot of people has
already used them.

@itemize @bullet
@item ACTION
@item BIT
@item DATE
@item ENUM
@item NO
@item TEXT
@item TIME
@item TIMESTAMP
@end itemize

@node Stabilty, Server, Syntax, Top
@chapter How safe/stable is @strong{MySQL}

@menu
* Stability::                   How stable is @strong{MySQL}?
* Releases::                    Why are there is so many release of @strong{MySQL}?
* Check::                       How often should one check the databases.
* Repair::                      How do you check/repair/reconstruct an @strong{MySQL} table?
* Upgrade::                     Is there anything special to do when upgrading/downgrading @strong{MySQL}?
@end menu

@node Stability, Releases, Stabilty, Stabilty
@section How stable is @strong{MySQL}?

At TcX, @strong{MySQL} has worked without any problems in our projects since mid
1996. When released to a wider public we noticed that there were some
parts of 'untested code' in @strong{MySQL} that were quickly found by the new user
group who made queries in a different manner.  Each new release
has had fewer portability problems than the previous one, even
though they have all had a lot of new features, and we hope that
it will be possible to label one of the
next releases 'stable'.

Each release of @strong{MySQL} has been usable and there has only been
problems when users start to use code from 'the gray zones'. Naturally,
outside users can't know what the gray zones are and I hope this section
will clarify those currently known.

We will here try to answer some of the more important questions that
seems to concern a lot of people and clarify some issues. This section
has been put together from the information that has come forward in the
mailing list which is very active in reporting bugs.

How stable is @strong{MySQL}? Can I depend on @strong{MySQL} in this project!

This is about the 3.21.x version of @strong{MySQL}. All known and reported bugs
are fixed in the latest version with the exception of the bugs listed in
the BUGS file which are things that are 'design' related.

@strong{MySQL} is written in multiple layers and different independent
modules. Here is a list of the different modules and how tested each of
them are.

@table @strong
@item The ISAM table handler. Stable
This is how all the data is stored. In all @strong{MySQL} releases there hasn't
been a single (reported) bug in this code. The only known way to get a
corrupted table is to kill the server in the middle of a update and
because all data is flushed to disk between each query even this is
unlikely to destroy any data beyond rescue. There hasn't been a single
bug report about lost data because of bugs in @strong{MySQL} either.

@item The parser and lexical analyser. Stable
There hasn't been a single reported bug in this system for a couple of
months.

@item The C client code. Stable
No known problems. In early 3.20 releases there were some limitations in
the send/receive buffer size. In 3.21.x the send/receive buffer is now
dynamic up to a default of 512K.

@item mysql, mysqladmin and mysqlshow. Stable
The command line clients have had very few bugs.

@item mysqldump and mysqlimport. Beta
Rewritten for 3.21.

@item Basic SQL. Stable
The basic SQL function system and string classes and dynamic memory
handling. Not a single reported bug on this system.

@item Query optimiser. Gamma
Some changes in 3.21.

@item Range optimiser. Alpha
Totally rewritten for 3.21.x

@item Join optimiser. Gamma
Small changes for 3.21.

@item GROUP BY, ORDER BY and related function COUNT(). Beta
Rewritten for 3.21 and throughly tested.

@item Locking. Gamma
This is very system dependent. One some systems there are big problems
using standard OS locking (fcntl).  In these cases, you should run the
@strong{MySQL} daemon with the @code{--skip-locking} flag.  Known
problems are some Linux systems and SUNOS when using NFS mounted file
systems.

@item Linux threads. Gamma
The only found problem is with the fcntl() call, which is fixed by using
--skip-locking. Some people have reported lockup problems with the 0.5
release.

@item Solaris 2.5+ pthreads. Stable
We use this for all our production work.

@item MIT threads (Other systems). Beta
No reported bugs since 3.20.15 and no known bugs since 3.20.16. On some
system there is 'misfeature' where some operations are quote slow (a
1/20 second sleep is done between each query). Of course MIT threads may
slow down everything a bit, but for index based selects a select is
usually done in one time frame so there shouldn't be a mutex
locking/thread juggling.

@item Other thread implementions. Alpha
The ports to other systems is very new and may still have bugs, either
in @strong{MySQL} or most often in the thread implementation itself.

@item LOAD DATA..., INSERT ... SELECT. Stable
Some people have thought they have found bugs in this but has turned up
being misunderstandings. So check the manual before reporting bugs!

@item ALTER TABLE. Gamma
Partly rewritten for 3.21.

@item mysqlperl. Stable
No bugs reported except a lot of compiling and linking problems.

@item DBD. Beta
Now maintained by Jochen Wiedmann.
@email{<wiedmann@@neckar-alb.de>}. Thanks!

@item mysqlaccess. Beta
Written and maintained by
@email{Yves.Carlier@@rug.ac.be}. Thanks!

@item The Technical Documentation. Beta
It is improving.

@item MyODBC (uses ODBC SDK 2.5). Beta
It seams to work well with some programs. 
@end table

TcX provides email support for paying customers, but the @strong{MySQL} mailing
list usually provides answers to all common questions. Bugs are usually
fixed right away with a patch that usually works and for serious bugs
there is almost always a new release.

@node Releases, Check, Stability, Stabilty
@section Why are there is so many releases of @strong{MySQL}?

Well, @strong{MySQL} is evolving quite rapidly here at TcX and we want
to share this with other @strong{MySQL} users. We try to make a release
when we have a very useful feature that others seem to have a need for.

We also try to help out users who request features that are easy to
implement. We also take note on what our licensed users want to have and
we especially take notes on what our extended email supported customers
want and try to help them out.

No one has to download a new release. The News section will tell you if
the new release has something you really want. @xref{News}.

If there is, by any chance, a fatal bug in a release we will make a new
release as soon as possible, that fixes the problem. We would like
other companies to do this too :)

The 3.21.x version has had many big changes for portability to a lot of
different systems. When the 3.21 release is stable we will remove the
alpha/beta suffix and move active development to the 3.22. Bugs will
still be fixed in the stable version. We don't believe in a complete
freeze, as this also leaves out bug fixes and things that 'must be
done'. 'Somewhat freezed' means that we will maybe add small things that
'almost surely will not affect anything thats already working'.

If you are running and old system and want to upgrade, but you don't
want to take chances with 3.21 you should upgrade to 3.20.32.  I have
tried to only fix fatal bugs and small, relatively safe changes in this
version.

If you are trying @strong{MySQL} for the first time or have a little
time to test out that your current system, you should use 3.21.

@node Check, Repair, Releases, Stabilty
@section Checking a table for errors.

If @strong{MySQL} crashed (for example if the computer is turned off) when all
data is not written to disk the tables may have become corrupted. To
check a table use:

@table @code
@item isamchk table_name
This finds 99.99 % of all errors. What it can't find is when only the
data file has been corrupted.
@item isamchk -e table_name
This goes through all data and does a complete check.
@item isamchk -ei table_name
As the above but it also prints some statistics.
@end table

We at TcX run a cron job on all our important tables once a week.

@example
35 0 * * 0 /path/to/isamchk -s /path/to/dbs/*/*.ISM
@end example

This prints out any crashed tables so we can go and examine and repair
them when needed.

As we haven't had any unexpected crashed (without hardware trouble)
tables for a couple of years now (this is really true), once a week is
more than enough of us.

Of course, whenever the machine has done a reboot in the middle of a
update one usually has to check all the tables that could have been
affected. (This is a 'expected crashed table')

We recommend that to start with one should do a @code{isamchk -s} on all
updated tables each night until one gets to trust @strong{MySQL} as much
as we trust it.

Naturally, one could add a check to safe_mysql that, if there is an old
pid file left after a reboot, it should check all tables that have been
modified the last 24 hours.

@node Repair, Upgrade, Check, Stabilty
@section How to repair tables.

The file format that @strong{MySQL} uses to store data has been extensively
tested, but there is always instances (like a hard kill on the mysqld
process in the middle of a write, a hardware error or a unexpected
shutdown of the computer) when some tables may be corrupted.

The sign of a corrupted table is usually when queries abort unexpectedly
and one gets errors like:

@itemize @bullet
@item
table.frm is locked against change.
@item
Can't find file 'table.ISM' (Errcode: ###)
@item
Got error ### from table handler. (Error 135 is an exception in this case)
@item
Unexpected end of file.
@item
Record file is crashed.
@end itemize

In thess cases you have to repair your tables. The isamchk extern
utility can usually detect and fix most things that can go
wrong. @xref{isamchk}.

If you are going to use isamchk on very large files, you should first
decide how much memory you want to give to isamchk. More memory
gives more speed. For example, if you have more than 32M ram, try:

@example
isamchk -O sortbuffer=16M -O keybuffer=16M -O readbuffer=1M
        -O writebuffer=1M ....
@end example

@itemize @bullet
@item
Part 1: Checking 
@itemize @bullet
@item
Check the permissions of the table files. Make them readable for the
user running mysqld.
@item
cd to the database directory.
@item
Run 'isamchk *.ISM' or ('isamchk -e *.ISM' if you have more time).
@item
You only have to repair those tables that your isamchk gives an
error. Use option -s to avoid unnecessary information.
@end itemize
@item
Part 2: Easy safe repair.
@itemize @bullet
@item
If you get weird errors when checking or repairing, like out of
memory or if isamchk crashes, go to part 3.
@item
Try first 'isamchk -rq table'. This will try to repair the .ISM file
without touching the important data table (.ISD).
If the data file (.ISD) contains everything and the delete links point
at the right places in the data file, this should work and the table
is fixed. Start repairing next table.
@item
Make a backup of the data file (table.ISD) before continuing.
@item
Use 'isamchk -r table'. This will remove wrong records and deleted
records from the data file and reconstruct the index (.ISM) file.
@item
If the above fails, use 'isamchk -ro table'. This is a little slower
but a crash-safer version of the above.
@end itemize
@item
Part 3:; Hard repair.
@itemize @bullet
@item
This should only happen if the first 16K block in the .ISM file is
destroyed, contains wrong information or if the .ISM is missing.
@item
In this case we have to create a new .ISM file. Do as follows:
@item
Move the data file .ISD file to some safe place.
@item
Recreate the .ISM file from the .frm file:
@example
shell> mysql database
mysql> delete from table_name;
mysql> quite
@end example
@item
Copy (don't move) the data file (.ISD) back on the newly created .ISD file
@item
Go back to Part 2. (This shouldn't be a endless loop). isamchk -rq should
now work.
@end itemize
@item
Part 4: Very hard repair.
@itemize @bullet
This can only happen if the descriptor file (.frm) also has
crashed. This should never happen, because the .frm file isn't written
to after the table is created.
@item
Restore the .frm file from a backup and go back to Part 3.
You can also restore the .ISM file and go back to Part 2.
In the latter case you should start with 'isamchk -r'.
@item
If you don't have a backup but know exactly how the table was
created, create a copy of the table in another database and
copy the .frm and .ISM file from there to your crashed
database and go back to Part 2.
@end itemize
@end itemize

@node Upgrade,  , Repair, Stabilty
@section Is there anything special to do when upgrading/downgrading @strong{MySQL}?

One can always move the @strong{MySQL} form and data files between
different versions on the same architecture as long as one has the same
base version of @strong{MySQL}. The current base version is of course
3. If one changes the character set (sort order) by recompiling
@strong{MySQL} one has to do a @code{isamchk -rq} on all tables.

@menu
* Upgrading-from-3.20::         
@end menu

@node Upgrading-from-3.20,  , Upgrade, Upgrade
@subsection Upgrading to 3.21 from a 3.20 version

If you already have a version older than 3.20.28 running and want to
switch to 3.21.# you have to do the following:

You can start the @code{mysqld} 3.21 server with @code{safe_mysqld
--old-protocol} to use it with the original 3.20 data. In this case the
new client function, @code{mysql_errno()}, will not return any server
error, only @code{CR_UNKNOWN_ERROR}, (but it works for client errors)
and the server uses the old password() checking instead of the new one.

If you are @emph{NOT} using @code{--old-protocol}:

@itemize @bullet
@item
All client code must be recompiled. If you are using ODBC you must get
the new myodbc 2.# driver
@item
The script @code{scripts/add_long_password} must be run to convert the
password field in the 'mysql/user' table to @code{char(16)}.
@item
All passwords must be reassigned in the mysql/user table (to get 62
instead of 31 bit passwords).
@item
The table format hasn't changed so you don't have to convert any tables.
@end itemize

@strong{MySQL} 3.20.28 and above can handle the new user table format
without affecting clients. If you have a @strong{MySQL} version below
3.20.28, passwords will not work on it anymore if you convert the user
table. So to be safe, you should first upgrade to at least 3.20.28 and
then upgrade to 3.21.#.

@cindex Protocol mismatch
The new client code works with a 3.20.# version, so you can use the old
3.20.# server if you experience problems with 3.21.# without having to
recompile the clients again.

If you are not using the option @code{--old-protocol} to @code{mysqld},
old clients will issue the error message:

@code{ERROR: Protocol mismatch. Server Version = 10 Client Version = 9}

@node Server, Common problems, Stabilty, Top
@chapter @strong{MySQL} Server functions

@menu
* Languages::                   Which languages are supported by @strong{MySQL}?
* Update log::                  The Update log
* Table size::                  How big can @strong{MySQL} tables be.
@end menu

@node Languages, Update log, Server, Server
@section Which languages are supported by @strong{MySQL}?

@code{mysqld} can give error messages in the following languages: Czech,
Dutch, English (default), French, German, Norwegian, Norwegian-ny,
Polish, Portuguese, Spanish and Swedish. 

To start @code{mysqld} with a language use one of the
@code{--language=lang} or @code{-L lang} switches:

@code{mysqld --language=swedish}
or
@code{mysqld --language=/usr/local/share/swedish}

Note that all the language names are in lowercase.

The language files are located in
@file{@var{mysql_base_dir}/share/@var{LANGUAGE}/}.

@subsection Character set used for data & sorting.

By default @strong{MySQL} will use the ISO8859-1 (Latin1) character
set. This is the character set used in the USA and western Europe.

The character set decides what characters are allowed in names and how
things are sorted by the @code{ORDER BY} and @code{GROUP BY} commands.

You may change this at compile time by the configure switch
@code{--with-charset=charset}. @xref{Quick-install}.

@node Update log, Table size, Languages, Server
@section The Update log

When started with the @code{--log-update=file_name} switch @code{mysqld}
makes a log file with all SQL command that update data. It results in a
file with name of @code{file_name.#} where # is a number that is
increased for each reload. If you do not give a file name the current
hostname is used.

The log in smart since it only writes statements that really update
data. So a @code{UPDATE} or a @code{DELETE} with a where that find no
rows is not written to the log. It even skips @code{UPDATE}s that update
a column to the value it had before.

The current limitations of @code{--log-update} are:

@code{TIMESTAMP} and all other updates with time functions will get the
current date instead of the orignal date.

@code{LAST_INSERT_ID()} values should be logged for more safety.

@cindex Table size
@cindex Size of tables
@node Table size,  , Update log, Server
@section How big can @strong{MySQL} tables be.

Currently a table is limited to the operation system file size.  On
Linux the current limit is 2G, on Solaris 2.5.1 the limit is 4G and on
Solaris 2.6 the limit is going to be 1000G. To get more that 4G requires
some changes to @strong{MySQL} that are on the Todo. @xref{Todo}.

If your big table is going to be read_only, you could use pack_isam
(@xref{pack_isam}) to merge and compress many tables to one.  As
pack_isam usually compresses a table with at least 50% you can have much
bigger tables.

Another solution can be included MERGE library allows one to handle a
collection of identical tables as one. Currently MERGE can only be used
to scan a collection of tables because it doesn't support indexes. We
will add indexes on this in the near future.  Identical in this case
means that all tables are created with identical column information.

@node Common problems, Performance, Server, Top
@chapter Solving some common problems with @strong{MySQL}

@cindex Replication
@menu
* Replication::                 Database replication
* Backup::                      Backup of databases
@end menu

@node Replication, Backup, Common problems, Common problems
@section Database replication

The most general way to do database replication is using the update
log. @xref{Update log}. This requires that one database acts as a master
(all data changes are done here) and one or more others as slaves. To
update a slave just run @code{mysql < update_log}.

If you never do deletes you can use timestamps.

It is possible to make a two way updating system using both the update
log (for deletes) and timestamps (on both sides). But in that case you
must be able to handle confilics when the same data has been changed in
both ends. You probably want to keep the old version to help with
deciding what has been updated.

@cindex Backup
@node Backup,  , Replication, Common problems
@section Backup of databases

Since @strong{MySQL} tables are stored as files it is easy to do a
backup. To get a consistent backu do a @code{LOCK TABLES} on the
relevant tables. @xref{Lock tables}. You only need a read lock so other
threads can continue to query the tables. When make a copy of the files
in the database directory. Or if you want to make a sql level backup you
can use @code{SELECT INTO OUTFILE}.

Another way is to use the @code{mysqldump} script.

@itemize @bullet
Do a full backup of your databases, with @code{mysqldump --tab=some-dir
--lock-tables} or simply by copying all table files (.frm, .ISM and
.ISD) away while the server isn't updating anything.
@item
start @code{mysqld} with @code{--log-update}
@item
You will get log files with name of 'hostname'.# where # is a number
that is increased for each reload.
@end itemize

When you have to restore something (if @code{isamchk -r} can't restore
all data as it can in 99.9% of all cases):

@itemize @bullet
@item
Restore the original mysqldump backup.
@item
ls -1 -t -r hostname.* | xargs cat | mysql 
@end itemize

The ls in the last command is done to get all log files in the right
order

You can also do selective backups with @code{select * into outfile from
table} and restore with @code{ LOAD DATA FROM INFILE 'file_name' REPLACE
...}. To avoid dublicate recods you need a @code{PRIMARY KEY} in the
table. The @code{REPLACE} means that if there is a 'duplicate index'
conflict when inserting new records the old record will be replaced with
the new one.

@node Performance, Benchmarks, Common problems, Top
@chapter How to get maximum performance out of @strong{MySQL}

@menu
* MySQL parameters::            How does one change the size of @strong{MySQL} buffers?
* Memory use::                  How does @strong{MySQL} use memory?
* MySQL indexes::               How does @strong{MySQL} use keys?
* Where optimisations ::        What kind of optimisation is done on the WHERE clause?
* Table cache::                 How does MySQL open & close tables?
* Table efficiency::            How should I arrange my table to be as fast/small as possible?
* Insert speed::                What factors @strong{MySQL} insert statement speeds.
* Delete speed::                What affects the speed of DELETE statement?
* Optimise::                    What options to use to get @strong{MySQL} to run at full speed?
* Row format::                  What is the different row formats? Or when to use VARCHAR/CHAR?
* Open tables::                 Why so many open tables?
@end menu

@node MySQL parameters, Memory use, Performance, Performance
@section How does one change the size of @strong{MySQL} buffers?

You can get the currently used buffer sizes with:

> @code{./mysqld --help}

This should result in a list of all mysqld options and configurable
variables like the following.

@example
Possibly variables to option --set-variable (-O) are: 
back_log              current value: 5
join_buffer           current value: 131072
key_buffer            current value: 1048568
max_allowed_packet    current value: 65536
max_connections       current value: 90
max_join_size         current value: 4294967295
max_sort_length       current value: 1024
net_buffer_length     current value: 8192
record_buffer         current value: 131072
sort_buffer           current value: 2097144
table_cache           current value: 64
tmp_table_size        current value: 1048576
thread_stack          current value: 65536
@end example

@multitable @columnfractions .3 .7
@item back_log @tab
How many outstanding connection requests may @strong{MySQL} have. This
comes into play when the main @strong{MySQL} thread gets @strong{VERY}
many connection requests in a very short time. It when takes some time
(but very short) for the main thread to check the connection and start a
new thread. The back_log is how many connects can be stacked during this
short time before @strong{MySQL} momentarily stops answering new
requests. You only need to increase this is you expext a large number of
connections in a short period of time.

Or in other words the size of the listen queue for incoming tcp/ip
connections.  The manual page for the unix system call listen(2) should
have more details.

Check your OS documentation for the maximum value for this value.
@item join_buffer @tab
This buffer is used for full joins (without indexs). It is allocated one
time for each full join between two tables. Increase this to get a
faster full join when adding indexes is not possible. Normaly the best
way to get fast joins is adding indexes.
@item key_buffer @tab
Buffers index blocks and is shared by all threads. You might want to
increase this when doing many delete/inserts on a table with lots of
indexs. To get even more speed use @code{LOCK TABLES}. @xref{Lock tables}.
@item max_allowed_packet @tab
Max size of one packet. This allows the message buffer to grow up to
this limit when needed (it is initiated to
@code{net_buffer_length}). May be set very big because this is mainly to
find erroneous packets. You must increase this if you are using big
BLOBS. It should be as big as the biggest BLOB you want to use.
@item max_connections @tab
How many simultaneous clients is allowed. If you increase this you
probably has to increase the number of file descriptors mysqld has. This
is Operating system depended so look at you OS documentation.
@item max_join_size @tab
Joins that touches more records that this return an error. Set this if
you have users to tend to make joins without a where that take a long
time and returns millions of rows.
@item max_sort_length @tab
The number of bytes to use when sorting on @code{BLOB} or @code{TEXT}
columns.
@item net_buffer_length @tab
The communication buffer is reset to this size between each query. This
should normally not be changed but if you have very little memory you
can set it to the expected size of a query.
@item record_buffer @tab
Each thread that is doing a sequential scan allocats a buffer of this
size for each table it scans. If you do many sequential scans you may
want to increase this.
@item sort_buffer @tab
Each tread that needs to do a sort allocats a buffer of this
size. Increase this for faster @code{ORDER BY} or @code{GROUP BY}. A
sort also allocates one or two temporary files. The maximum disk-space
needed is @code{(length_of_what_is_sorted + sizeof(database_pointer)) *
number_of_rows * 2}. @code{sizeof(database_pointer)} is usally 4 but may
grow in the future for really big tables.
@item table_cache @tab
Number of open tables for all threads. If this is increased you must see
to that the number of open file descriptor is also
increased. @strong{MySQL} need 2 file descriptors for each unique table.
@item tmp_table_size @tab
If a temporary table gets bigger than this a @code{The table ### is
full} error will ge generated. Increase this if you do many advanced
@code{GROUP BY} queries.
@item thread_stack @tab
How big will each threads @code{C} stack be. A lot of the limits
detected by crash-me is dependent on this. The default is normally
enough.
@end multitable

@strong{MySQL} uses algorithms that are very scalable so one can usually
run with very little memory or give @strong{MySQL} much memory to get a
better performance.

If you have much memory and many tables and want to have maximum
performance with a moderate number of clients you should use something
like:
@example
> safe_mysqld -O key_buffer=16Mk -O table_cache=128 \
        -O sort_buffer=4M -O record_buffer=1M &
@end example

If you have little memory with lots of connections, use something like:
@example
> safe_mysqld -O key_buffer=512k -O sort_buffer=100k -O record_buffer=100k &
@end example

or even

@example
> safe_mysqld -O key_buffer=512k -O sort_buffer=16k -O table_cache=32 \
        -O record_buffer=8k -O net_buffer=1K &
@end example

Note that if you change a option to @code{mysqld} it is only for that
instance. To see the effects of a parameter change do something like
this @code{mysqld -O keybuffer=32m --help}.

If there are very many connections, 'swapping problems' may occur if
mysqld has not been configured to use very little memory for each
connection. It also works nice if you have a enough memory for all
connections of course.

For example, for 200 open connections one should have a table cache of
at least 200 * (max_number of tables in join).

@node Memory use, MySQL indexes, MySQL parameters, Performance
@section How does @strong{MySQL} use memory ?

@itemize @bullet
@item
The key_buffer is shared by all threads, the rest are allocated when needed.
@item
Each connection uses some thread space, a stack (64K) and a connection
buffer (variable @code{net_buffer_length}).
@item
All threads share the same base memory.
@item
Nothing is memmapped yet (except compressed tables but that's another
story). This is because 32bit memory space of 4GB is not large enough for most
large tables. When we get a system with 64 bit address space we may add
general support for memmaping.
@item
When starting @code{mysqld} one can specify a key buffer. This will buffer
all indexs in all tables at FIFO basis (variable keybuffer).
@item
Each request doing a sequential scan over a table allocates a read buffer
(variable record_buffer).
@item
Each request doing a sort, allocates a sortbuffer and one or two temporary
files. The maximum extra disk-space needed is @math{(sort_key_length
+sizeof(long))*2}.
@item
All joins are done in one pass and most joins can be done without even
using a temporary table. Most temporary tables are memory based (HEAP)
tables. Temporary tables with a big recordlength (= sum of all column
lengths) or that contains @code{BLOB}s are stored on disk.  One current
problem is that if the HEAP table exceeds the size of
@code{tmp_table_size}, one will get the error: 'The table ### is full'.
In the future we will fix this by automatically changing the in memory
(HEAP) table to a disk based (NISAM) table if needed.  To go around this
problem one can increase the @code{-O tmp_table_size=#} option to mysqld
or use the SQL option @code{SQL_BIG_TABLES}.  @xref{Set option}.  In
@strong{MySQL} @code{3.20} the maximum size of the temporary table was
@code{recordbuffer*16}, so if you are using this version you have to
increase @code{recordbuffer}. There also exists a patch to always store
temporary tables on disk, but this will affect the speed of all
complicated queries.
@item
Almost all memory used when parsing and calculating is done on a local
memory store. No memory overhead is needed for small items and the normal
slow memory allocation/freeing is avoided. Memory is only allocated for
unexpectedly large strings (this is done with malloc/free).
@item
Each index file is opened once and the data file is opened once for each
concurrently running thread. For each concurrent thread a table
structure, column structures for each column and a buffer that has the
size of 3 * (maximum row length not counting BLOBS) is allocated. A BLOB
uses 5 to 8 bytes +length of blob data.
@item
For each table having BLOBS, a buffer is enlarged dynamically to read in
larger BLOB's. If one scans a table there will be a allocated buffer as
large as the largest BLOB.
@item
All used tables are saved in a cache and used by FIFO. Normally the cache is
64 tables. If a table has been used by 2 running threads at the same time,
there will be 2 entries of the table in the cache.
@item
A @code{mysqladmin refresh} closes all tables that are not used and marks all
used tables to be closed when the running thread finishes. This will
effectively free most used memory.
@end itemize

When running @code{mysqld} ps, other programs may report that is takes a lot of
memory. This may be caused by thread-stacks on different memory
addresses. For example, the Solaris ps calculates the unused memory
between stacks as used memory. You can verify this by checking available
swap with 'swap -s'. We have tested @code{mysqld} with commercial memory-leakage
detectors so there should not be any memory leaks.

@node MySQL indexes, Where optimisations , Memory use, Performance
@section How does @strong{MySQL} use indexs?

All indexs, PRIMARY, UNIQUE and INDEX(), are stored in B trees. Strings
are automatically prefix- and end-space compressed.

INDEX(col1, col2) creates a multiple index over the two columns.
The index can be seen like a concatenation of the given columns.
If you use INDEX(col1), INDEX(col2) instead of INDEX(col1,col2) you get
two separate indexs instead.

@example
SELECT * FROM table WHERE col1=# AND col2=#
@end example

In a case of INDEX(col1,col2) the right row(s) can be fetched directly.
In a case of INDEX(col1), INDEX(col2) the optimiser decides which index
will find fewer rows and this index will be used to fetch the rows.

If the table has an index INDEX(col1,col2,col3...) the prefix of this
can be used by the optimiser to find the rows. This means that the above
gives you search capabilities on: INDEX(col1) and INDEX(col1,col2) and
INDEX(col1,col2,col3)...

MySQL can't use a sub part of a index to locate rows through a index.

With the definition INDEX(col1,col2,col3):

@example
SELECT * FROM table WHERE col1=#
SELECT * FROM table WHERE col2=#
SELECT * FROM table WHERE col2=# and col3=#
@end example

only the first query will use indexs.

@node Where optimisations , Table cache, MySQL indexes, Performance
@section What kind of optimisation is done on the WHERE clause?

(Incomplete, @strong{MySQL} does a lot of optimisations.)

The first issue about getting a slow @code{SELECT ... WHERE} faster is
to check if one could add a index to make it faster. All references
between different tables should usually be done with indexs. One can use
the @code{EXPLAIN} command to check which indexes are used in a
@code{select}. @xref{Explain}. @xref{MySQL indexes}

@itemize @bullet
@item
Brace removal (all unnecessary braces are removed). @code{((a AND b) AND c OR
(((a AND b) AND (c AND d))))} -> @code{(a AND b) OR (a AND b AND c AND d)}
@item
Constant folding. @code{(a<b AND b=c) AND a=5} -> @code{b>5 AND b=c A=5}
@item
Constant condition removal (needed because of constant folding). @code{(b>=5
AND b=5) OR (b=6 and 5=5) or (B=7 and 5=6)} -> @code{B=5 or B=6}
@item
All constant expressions used by indexs are evaluated only once.
@item
Return zero rows if impossible select.
@item
HAVING is merged with WHERE if one doesn't use GROUP BY or group functions.
@item
For each sub join a simpler WHERE is constructed to get a fast WHERE evaluation
for each sub join and also to skip records as soon as possible.
@item
Find all indexs that may be used. Use the index which finds least records. A index
is used for the following cases: @code{=}, @code{>}, @code{>=}, @code{<},
@code{<=}, @code{BETWEEN} and a @code{LIKE} with a character prefix like
'something%'.
@item
Remove indexs that don't span all @code{AND} levels.
@itemize -
@item
have all preceding index_parts specified.
@item
@code{index = 1 or A = 10} -> @code{NULL} (can't use index.)
@item
@code{index = 1 or A = 10 and index=2} -> @code{index = 1 OR index = 2}
@item
@code{index_part_1 = const and index_part_3 = const} -> @code{index_part_1 =
const}
@end itemize

@item
Read all constant tables. A constant table is:

@enumerate
@item
A table with 0 or 1 record.
@item
A table which uses only other const tables and constants on a full unique index.
@end enumerate

@c What should the examples below show?
@itemize @bullet
@code{const_table.index = constant}
@item
@code{const_table.index_part_1 = const_table2.column and const_table.index_part_2 = constant}
@end itemize

@item
Find the best join combination to join the tables, by trying all
possibilities :(. If all columns in @code{ORDER BY} and in @code{GROUP}
comes from the same table, then this table is preferred first when joining.
@item
If there is a order clause and a different group clause or if the order or
group contains columns from other tables than the first table in the join cue,
a temporary table is created.
@item
For each table use a ranged index, if possible, to read records. Each table
index is queried and if there exists a index range that spans < 30% of the
records then a index is used. If no such index can be found a quick table
scan is used.
@item
Before each record is output-ed, skip those that match the HAVING clause.
@end itemize

@node Table cache, Table efficiency, Where optimisations , Performance
@section How does @strong{MySQL} open & close tables?

The cache of open tables can grow to a maximum of @code{table-cache}
(default 64, changeable with -O table_cache=#).
A table is never closed, except when the cache is full and another thread
tries to open a table or if one uses 'mysqladmin refresh'.

When the limit is reached, @strong{MySQL} closes as many tables as possible,
until the cache size has been reached or there are no more unused tables.
This means that if all tables are in use by some threads, there will be
more open tables than the cache limit, but the extra tables will be closed
eventually.
Tables are closed according to last-used order.

A table is opened (again) for each concurrent access. This means that
if one has two threads running on the same table or access the table
twice in the same query (with AS) the table needs to be opened twice.
The first open of any table takes 2 file descriptors, each following
use of the table takes only one file descriptor.

@subsubsection What are the drawbacks of creating possibly thousands of tables in a database?

Each table is actually 3 files.  If you have many files in a directory
open, close and create will be slow.  If you also do selects on many
different tables there will be a little overhead because when the table
cache is full for every table that has to be opened another has to be
closed. One can make the overhead smaller by making the table cache
larger.

@node Table efficiency, Insert speed, Table cache, Performance
@section How should I arrange my table to be as fast/small as possible?

@itemize @bullet
@item
Use @code{NOT NULL} if possible. It makes everything faster and you save 1
bit per column.
@item
All columns have default values. Only insert when the default value
isn't acceptable. You don't have to insert the columns of a timestamp or
an autoincremented index in the insert statement. @xref{mysql_insert_id}.
@item
Use the smaller INT types if possible to get smaller tables. For example,
@code{MEDIUMINT} is often better than @code{INT}.
@item
If you don't have any @code{VARCHAR} columns, a fixed size record format
will be used. This is much faster but may unfortunately waste some
space. @xref{Row format}.
@item
To make @strong{MySQL} optimise queries better, run @code{isamchk -a} on the
table once it is loaded with relevant data. This updates a value for each
index that tells how many rows that have the same value for this index in
average. Of course, this is always 1 for unique indexes.
@item
To sort an index and data according to an index use @code{isamchk -Sir1}
(if you want so sort on index 1). If you have a unique index that you want
to read all records from in numeric order this is a good way to make
that faster.
@item
When loading a table with data use @code{LOAD DATA FROM INFILE}. This is
usually 20 times faster than using a lot of INSERTs. If the text file
isn't on the server, rcp it to the server first. @xref{Load}.

You can even get more speed when loading data to tables with many indexs
by doing:
@itemize @bullet
@item
Create the table in mysql or perl with CREATE TABLE... 
@item
Do @code{mysqladmin refresh}.
@item
Use @code{isamchk -k0 database/table_name}. This will remove all use of indexs
from the table.
@item
Insert data into the table with @code{LOAD DATA INFILE...}.
@item
If you have pack_isam and want to compress the table, run pack_isam on it.
@item
Recreate the indexs with @code{isamchk -rq database/table_name}.
@item
Do @code{mysqladmin refresh}.
@end itemize

The other possibility to get some more speed to both
@code{LOAD DATA FROM INFILE} and @code{INSERT} is to enlarge the key buffer.
This can be done with the @code{-O key_buffer=#} option to @code{(safe)mysqld}.
For example 16M should be a good value if you have much RAM :)
@item
When dumping data as textfiles to other programs, use 
@code{SELECT ... INTO OUTFILE}. @xref{Load}.
@item
When doing many inserts/updates in a row, you can get more speed by using
@code{LOCK TABLES} on the tables. @code{...FROM INFILE...} and 
@code{...INTO OUTFILE...} are atomic so you don't have to use 
@code{LOCK TABLES} when using these. @xref{Lock tables}.
@end itemize

To check how you are doing, run @code{isamchk -evi} on the .ISM
file. @c @xref{isamchk}.

@node Insert speed, Delete speed, Table efficiency, Performance
@section What affects the speed of the INSERT statement?

The time to insert a record consists of:

@itemize @bullet
@item
Connect:                 (3)
@item
Sending query to server: (2)
@item
Parsing query:           (2)
@item
Inserting record:        (1 x size of record)
@item
Inserting indexs:          (1 x indexs)
@item
Close:                   (1)
@end itemize

Where (number) is proportional time. This does not take into calculation
the initial overhead to open tables (which is done once for each
simultaneous running query).

The size of the table slows down the insert of indexs with N log N
(B-trees).

A way of speeding ut inserts in to lock your table during the inserts.

@example
LOCK TABLES a WRITE;

INSERT INTO a VALUES (1,23)
INSERT INTO a VALUES (2,34)
INSERT INTO a VALUES (4,33)
INSERT INTO a VALUES (8,26)
INSERT INTO a VALUES (6,29)

UNLOCK TABLES;
@end example

The main speed difference is that the index buffer is only flushed once to
disk for all inserts. Normally there would be as many index buffer flushes
as there are inserts.

Locking will also lower the total time of multi-connection test but the
maximum wait time for some threads will go up.

For example:

@example
thread 1 does 1000 inserts
thread 2, 3, and 4 does 1 insert
thread 5 does 1000 inserts
@end example

If you don't use locking, 2, 3 and 4 will finish before 1 and 5. If you
use locking 2,3,4 may finnish before 1 or 5 but probably not, but the
total time should be about 40 % faster.

As @code{INSERTS}, @code{UPDATES} and @code{DELETES} are very fast in
@strong{MySQL} one will get better overall performance by adding locks
around everything that does more than about 5 inserts/updates in a row.
If one does very many inserts in a row one could do a @code{UNLOCK
TABLES} followed by a @code{LOCK TABLES} once in a while (about each
1000 rows) to give other threads access to the table. This would still
give a nice performance gain.

Of course @code{LOAD DATA INFILE} is much faster still.

@node Delete speed, Optimise, Insert speed, Performance
@section What affects the speed of DELETE statement?

The delete time of a record is exactly proportional to the number of
indexs. To increase the speed of deletes you can increase the size of the
index cache. The default index cache is 1M and to get faster deletes it
should be increased a couple of times (try 16M if you have enough
memory).

@node Optimise, Row format, Delete speed, Performance
@section How do I get @strong{MySQL} to run at full speed?

@itemize @bullet
@item
Start @code{mysqld} with the right options. More memory gives more speed
if you have it. @xref{MySQL parameters}.
@item
Create indexs to get your @code{SELECT}'s faster. @xref{MySQL indexes}
@item
Optimize your column types to be as efficient as possible. Use @code{NOT NULL} on all columns.
@xref{Table efficiency}
@item
@code{--skip-locking} disables file locking between SQL requests. This gives a greater speed
but has the following consequences:
@itemize @bullet
@item
One @emph{MUST} flush all tables with @code{mysqladmin refresh} before
one tries to check/repair tables with @code{isamchk}. (@code{isamchk -d
table_name} is always allowed).
@item
One can't run two @strong{MySQL} servers one the same data files, if
both are going to update the same tables.
@end itemize
The @code{--skip-locking} is default when compiling with MIT threads.
This is because flock() isn't fully support by MIT threads on all
platforms.
@item
If updates are a problem, updates can be delayed and then do many updates
in a row later. Many updates done in a row are much quicker than one at a time.
@item
If the problem is with MIT threads and one is using FreeBSD x.x. upgrading to
FreeBSD 3.0.(or higher:) should help. This gives a possibility to use sockets
(quicker than the current TCP/IP with MIT threads) and the thread package
is much more integrated.
@end itemize

@node Row format, Open tables, Optimise, Performance
@section What are the different row formats? Or when to use VARCHAR/CHAR?

Actually using no @code{VARCHAR} or @code{BLOB} types results in a fixed row
size. Otherwise @code{CHAR} and @code{VARCHAR} are the same.

You can check the format used in a table with @code{isamchk -d}.

@strong{MySQL} has three different table formats:

@enumerate
@item
Fixed length tables.
@itemize @bullet
@item
This is the default format.
@item
All non packed columns are space filled.
@item
Very quick.
@item
Easy to cache.
@item
Easy to reconstruct if crashed (of course, this only theoretical :-) as
records are in fixed positions.
@item
Don't have to be reorganised unless a huge number of records are deleted.
@end itemize

@item
Dynamic tables
@itemize @bullet
@item
Is used if there exists any columns with a @code{VARCHAR}, @code{TEXT}
or @code{BLOB} type in a table.
@item
All strings are dynamic (except if length < 3).
@item
Each record is preceded with a bitmap for which columns are not empty (this
isn't the same as null columns).
@item
Each string is saved with a length byte + string. If string is zero length
or a number is zero it takes no extra space, just the zero length bit for
each column.
@item
Each record is uses the exact record space required. If a record becomes
larger it is split into as many pieces as required.
@item
Takes little disk space.
@item
If records are changed a lot, @code{isamchk -r} should be run now and then to
reorganise the table. This is to get a better layout. Use @code{isamchk -ei
table_name} for some statistics.
@item
Not as easy to reconstruct because a record may be in many pieces and a link
may be missing.
@item
The expected row length for dynamic sized records is: 3 + (number_of_columns
+ 7) / 8 + (number of char columns) + packed_size_of_number_columns +
length_of_strings + (null_columns + 7) / 8. There will be a penalty of 6
bytes for each link. A dynamic record will be linked whenever a update
causes a enlargement of the record. Each new link will be at least 20 bytes,
so the next enlargement will probably go in the same link. If not, there will
be another link. You may check how many links there are with @code{isamchk
-ed}. All links may be removed with @code{isamchk -r}.
@end itemize

@item
Compressed tables (this is only with UNIREG/pack_isam)
@itemize @bullet
@item
Read only tables.
@item
Takes very little disk space. Minimises disk usage.
@item
Each record is compressed separately (very little access overhead).
@item
Can handle fixed or dynamic length records, but no BLOBs.
@item
Can be uncompressed with isamchk.
@end itemize
@end enumerate

@node Open tables,  , Row format, Performance
@section Why so many open tables?

When you run @code{mysqladmin status} you get something like:

@example
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
@end example

This can be somewhat perplexing if you only have 6 tables.

As @strong{MySQL} is multithreaded it may have many queries on the same
table at once. To minimise the problem with two threads having
different states on the same file, I open the table again for each
concurrent thread. This takes some memory and one extra file descriptor
for the data file. The index file descriptor is shared all threads.

@node Benchmarks, Tools, Performance, Top
@chapter @strong{MySQL} benchmark suite

This should contains a technical describtion of the @strong{MySQL}
benchmark suite (and crash-me) but that describtion is not written
yet. Currently see the code and results in @file{bench} directory in the
distribution. And of course on @uref{http://www.tcx.se/crash-me.html,
the web page}.

It is meant to be a benchmark that will tell any user what things a
given SQL implementation is good or bad at.

crash-me tries to find what a database supports by actually running
queries. It find for example:

@itemize @bullet
@item
What column types are supported.
@item
How many indexes.
@item
What functions are supported.
@item
How big can a query be.
@item
How big can a varchar column be.
@end itemize

@node Tools, Changing MySQL, Benchmarks, Top
@chapter @strong{MySQL} Utilites

@menu
* Programs::                    What does the executables do?
* isamchk::                     The @strong{MySQL} table check, optimize and repair program
* pack_isam::                   The @strong{MySQL} compressed read only table generator
@end menu

@cindex Environment variables.
@node Programs, isamchk, Tools, Tools
@section Overview of the different @strong{MySQL} programs

All @strong{MySQL} clients that communicate with the server useing the
@code{mysqlclient} library use the following environment variables:

@multitable @columnfractions .3 .7
@item Name @tab Description
@item MYSQL_UNIX_PORT @tab The default socket. Used with 'localhost'.
@item MYSQL_TCP_PORT  @tab The default TCP port.
@item MYSQL_PWD @tab The default password.
@end multitable

@table @code
@item mysql
A SQL shell (with gnu readline). Supports interactive use or as a non
interactive query tool. When used interactively result is given in a
ascii-table format, but when used as a filter the result is a
tab-separated output.
@item mysqlaccess
Script to check the privileges for a host, user and database combination.
@item mysqladmin
Administration utility. Create/Drop of databases, reload (read new users) and
refresh (flush tables to disk, reopen log files). Also gives version and
process info.
@item mysqld
The SQL daemon. This should always be running.
@item mysqldump
Dump a @strong{MySQL} database into a file with SQL statements or tab separated text
files. Enchanted freeware originally by Igor Romanenko.
@item mysqlimport
Imports one or more text-files into respective tables. Can use all
formats supported by @code{LOAD DATA INFILE}. @xref{Load}
@item mysqlshow
Shows information about database, tables, columns and indexs.
@item mysqlbug
This script should always be used when filing a bug report to the
@strong{MySQL} list.
@item mysql_install_db
Creates the @strong{MySQL} grant tables with default privileges. This is
usually only executed when installing the first @strong{MySQL} release
on a new system.
@item isamchk
Check, optimise and repair @strong{MySQL} tables.
@item make_binary_release
Makes a binary release of a compiled @strong{MySQL}. This could be sent
by ftp to www.tcx.se/pub/mysql/Incoming for the convenience of other
@strong{MySQL} users.
@item msql2mysql
A shell script to convert a @code{mSQL} program to
@strong{MySQL}. Doesn't handle all cases but gives a good start when
converting.
@item replace
Binary used for msql2mysql. Utility program to change strings in place
in files or on stdin. Uses a finite state machine to match longer
strings first. Can be used to swap strings, for example @code{replace a
b b a -- files} swaps @code{a} and @code{b} in the given files.
@item safe_mysqld
Starts the mysqld demon with some safety features. Restarts on error and
has logging of runtime information to a log file.
@end table

@node isamchk, pack_isam, Programs, Tools
@section The @strong{MySQL} table check, optimize and repair program

For information about how to use isamchk to repair a crashed table:
@xref{Repair}.

@menu
* isamchk memory use::          
* Low-level-table-info::        Getting low level table information
@end menu

@node isamchk memory use, Low-level-table-info, isamchk, isamchk
@subsection isamchk memory use

@code{isamchk} doesn't use any more memory than you allow it to use with
the @code{-O} options. The default is to use only about 2M to fix
things.

But @code{isamchk} uses temporary files in @code{TMPDIR}. If
@code{TMPDIR} points to a memory file system you mey easily get out of
memory errors.

Using @code{-O sortbuffer=16M} should probably be enough for most cases.

@node Low-level-table-info,  , isamchk memory use, isamchk
@subsection Getting low level table information 

To get a description/statistics from a table use the forms below. We
will explain some of the information in more detail later.

@table @code
@item isamchk -d table_name
isamchk in 'describe mode'. If one uses @code{--skip-locking}
@code{isamchk} may report an error for a table that is updated while
isamchk runs, but there isn't any risk of destroying data.
@item isamchk -d -v table_name
A little more verbose.
@item isamchk -eis table_name
Shows only the most important information from a table. Slow since it must
read the whole table.
@item isamchk -eiv table_name
Same as above but tells you what it is being done.
@end table

Example of @code{isamchk -d} output:
@example
ISAM file:     company.ISM
Data records:           1403698  Deleted blocks:         0
Recordlength:               226
Record format: Fixed length

table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text
@end example

Example of @code{isamchk -d -v} output:
@example
ISAM file:     company.ISM
Isam-version:  2
Creation time: 1996-08-28 11:44:22
Recover time:  1997-01-12 18:35:29
Data records:           1403698  Deleted blocks:              0
Datafile: Parts:        1403698  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length: 3791650815  Max keyfile length: 4294967294
Recordlength:               226
Record format: Fixed length
r
table description:
Key Start Len Index   Type                      Root Blocksize Rec/key
1   2     8   unique  double                15845376      1024       1
2   15    10  multip. text packed stripped  25062400      1024       2
3   219   8   multip. double                40907776      1024      73
4   63    10  multip. text packed stripped  48097280      1024       5
5   167   2   multip. unsigned short        55200768      1024    4840
6   177   4   multip. unsigned long         65145856      1024    1346
7   155   4   multip. text                  75090944      1024    4995
8   138   4   multip. unsigned long         85036032      1024      87
9   177   4   multip. unsigned long         96481280      1024     178
    193   1           text
@end example

Example of @code{isamchk -eis} output:
@example
Checking ISAM file: company.ISM
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Recordblocks:     1403698    Deleteblocks:         0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary contexts switches 639, Involuntary contexts switches 28966
@end example

Example of @code{isamchk -eiv} output:
@example
Checking ISAM file: company.ISM
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%

- check records and index references
[LOTS OF ROW NUMBERS DELETED]

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Recordblocks:     1403698    Deleteblocks:         0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary contexts switches 10604, Involuntary contexts switches 122798
@end example

Here is the data file sizes of the table used above.
@example
-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.ISD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.ISM
@end example

Explanations for the things @code{isamchk} prints:
@table @code
@item ISAM file
Name of isam file.
@item Isam-version
Version of isam format. Currently always 2.
@item Creation time
When was the data file created.
@item Recover time
When was the index/data file last reconstructed.
@item Data records
How many records/rows. 
@item Deleted blocks
How many deleted blocks still have reserved space. @xref{Repair}.
@item Datafile: Parts
For dynamic record format this shows how many data blocks there are. For
a optimised table without splits this is the same as @code{Data
records}.
@item Deleted data
How many bytes of non reclaimed deleted data.
@item Datafile pointer
How many bytes the datafile pointer has. It is usually 2, 3 or 4
bytes. Most tables manage with 2 bytes but this cannot be controlled
from @strong{MySQL} yet. For fixed tables this is a record address. For
dynamic tables this is a byte address.
@item Keyfile pointer
How many bytes has the datafile pointer. It is usually 1, 2 or 3
bytes. Most tables manage with 2 bytes but this is calculated
automatically by @strong{MySQL}. It is always a block address.
@item Max datafile length
How long (in bytes) can the table's data file (@code{.ISD}) get.
@item Max keyfile length
How long (in bytes) can the table's key file (@code{.ISM}) get.
@item Recordlength
How much space does each record/row take.
@item Record format
Which format does each record/row have. This example uses @code{Fixed
length}.
@item table description
A list of all keys in the table. For each key some low level information
is presented.
@item Key
This key's number.
@item Start
Where in the record/row does this index-part start.
@item Len
How long is this index-part. For packed numbers this should always be
the full length of the column. For strings it may be shorter than the full
length.
@item Index
@code{unique} or @code{multip.}. If one value can exist multiple times
in this index.
@item Type
What data-type does this index part have. This is a @code{C} data-type
with the options packed, stripped or empty.
@item Root
Address of the root index block.
@item Blocksize
The size of each index block. This is by default 1024 but may be changed
a compile time.
@item Rec/key
This is a statistical value used by the optimiser. It tells how many
records there are per value for this key. A unique key always has a
value of 1. This may be updated after a table is loaded (or greatly
changed) with @code{isamchk -a}. If this is not updated at all, a default
value of 30 is given.
@item
The 9th key is a multiple part key with two parts.
@item Keyblocks used
How many percent of the keyblocks are used. Since this table has just
been reorganised with isamchk the values are very high (very near
theoretical maximum).
@item Packed
MySQL tries to pack keys with a common suffix. This can only be used for
@code{CHAR}/@code{VARCHAR}/@code{DECIMAL} keys. For long strings like
names, this can significantly reduce the space used. In the above example
the 4 key is 10 characters long and gets a 60% reduction in space.
@item Max levels
How deep is the btree for this key. Large tables with long keys get high
values.
@item Records
How many rows does the table have.
@item M.recordlength
Average recordlength. For fixed tables this is the recordlength.
@item Packed
MySQL strips spaces from the end of strings. How many percent did we
save by doing this.
@item Recordspace used
How many percent of the datafile is used.
@item Empty space
How many percent of the datafile is unused.
@item Blocks/Record
How many blocks are there per record. This is always 1 for fixed format
tables. This value should stay as close to 1.0 as possible. If it gets
to great you can reorganise the table with
@code{isamchk}. @xref{Repair}.
@item Recordblocks
How many blocks are used. For fixed format, this is the same as the number
of records.
@item Deleteblocks
How many blocks are deleted.
@item Recorddata
How many bytes of actual user data there are in the datafile.
@item Deleted data
How many bytes of deleted data there are in the datafile.
@item Lost space
If a record is updated to a shorter length some space is lost. This is
the sum of all such losses.
@item Linkdata
When the dynamic format is used, blocks are linked with pointers (length
4-7 bytes). This is the sum of all such pointers.
@end table

@cindex Pack-ISAM
@node pack_isam,  , isamchk, Tools
@section The @strong{MySQL} compressed read only table generator

@code{pack_isam} is an extra that you get when ordering more that 10
licenses or extended support. Since @code{pack_isam} is distributed
binary only, @code{pack_isam} is only available on some platforms.

Of course, all future updates to @code{pack_isam} is included in the
price. @code{pack_isam} may at some time be included as standard when
we get some kind of turnover for @strong{MySQL}.

@code{pack_isam} works by compressing each column in the table
separately. The information needed to decompress is read into memory
when the table is opened. This gives a much better performance when
accessing individual records as one only has to uncompress exactly one
record, not a much larger disk block like when using stacker on MSDOS.

MySQL uses memory mapping (mmap) on compressed tables and falls back to
normal read/write file usage if mmap did not work.

Usually, pack_isam packs the datafile 40-70%.

There is currently two limitations with pack_isam:
@itemize @bullet
After packing, the table is read only.
@item
It can't pack blobs, yet. 
@end itemize

Fixing these limitations is on our TODO but with low priority.

@code{pack_isam} options:

@example
> pack_isam --help
pack_isam Ver 5.0 for SOLARIS 2.5 on SPARCstation
Copyright (C) 1994-1997 TcX AB & Monty Program KB & Detron HB.
This is not free software. You must have a license to use this program
This software comes with ABSOLUTELY NO WARRANTY

Pack a ISAM-database to take much smaller space
Keys are not updated, one must run isamchk -rq on datafile afterwards
Usage: pack_isam [OPTIONS]

  -b, --backup          Make a backup of the table as table_name.OLD
  -f, --force           Force packing of table even if it's gets bigger or
                        tempfile exists.
  -j, --join=#          Join all given tables into table.
                        All tables MUST be identical.
  -p, --packlength=#    Force storage size of recordlength (1,2 or 3)
  -s, --silent          Be more silent.
  -t, --test            Don't pack table only test packing it
  -v, --verbose         Write info about progress and packing result
  -w, --wait            Wait and retry if table is in use
  -T, --tmp_dir=#       Use temporary directory to store temporary table
  -#, --debug=...       output debug log. Often this is 'd:t:o,filename`
  -?, --help            display this help and exit
  -V, --version         output version information and exit
@end example

Typical run:

@example
(/my/monty/tmp) ls -l station.*
-rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.ISD
-rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.ISM
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

(/my/monty/tmp) isamchk -dvv station

ISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-02-02  3:06:43
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafilepointer (bytes):      2  Keyfile pointer (bytes):     2
Max datafile length:   54657023  Max keyfile length:   33554431
Recordlength:               834
Record format: Fixed length

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long              1024       1024          1
2   32    30  multip. text                      10240       1024          1

column Start Length Type
1     1     1                                         
2     2     4                                         
3     6     4                                         
4     10    1                                         
5     11    20                                        
6     31    1                                         
7     32    30                                        
8     62    35                                        
9     97    35                                        
10    132   35                                        
11    167   4                                         
12    171   16                                        
13    187   35                                        
14    222   4                                         
15    226   16                                        
16    242   20                                        
17    262   20                                        
18    282   20                                        
19    302   30                                        
20    332   4                                         
21    336   4                                         
22    340   1                                         
23    341   8                                         
24    349   8                                         
25    357   8                                         
26    365   2                                         
27    367   2                                         
28    369   4                                         
29    373   4                                         
30    377   1                                         
31    378   2                                         
32    380   8                                         
33    388   4                                         
34    392   4                                         
35    396   4                                         
36    400   4                                         
37    404   1                                         
38    405   4                                         
39    409   4                                         
40    413   4                                         
41    417   4                                         
42    421   4                                         
43    425   4                                         
44    429   20                                        
45    449   30                                        
46    479   1                                         
47    480   1                                         
48    481   79                                        
49    560   79                                        
50    639   79                                        
51    718   79                                        
52    797   8                                         
53    805   1                                         
54    806   1                                         
55    807   20                                        
56    827   4                                         
57    831   4

Compressing station.ISD: (1192 records)
- Calculating statistics
            
normal:     20  empty-space:      16  empty-zero:        12  empty-fill:  11
pre-space:   0  end-space:        12  intervall-fields:   5  zero:         7
Original trees:  57  After join: 17
- Compressing file
87.14%     

(/my/monty/tmp) ls -l station.*
-rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.ISD
-rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.ISM
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

(my/monty/tmp) isamchk -dvv station

ISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-04-17 19:04:26
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     1
Max datafile length:   16777215  Max keyfile length:     131071
Recordlength:               834
Record format: Compressed

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long             10240       1024          1
2   32    30  multip. text                      54272       1024          1

Field Start Length Type                         Huff tree  Bits
1     1     1      constant                             1     0
2     2     4      zerofill(1)                          2     9
3     6     4      no zeros, zerofill(1)                2     9
4     10    1                                           3     9
5     11    20     table-lockup                         4     0
6     31    1                                           3     9
7     32    30     no endspace, not_always              5     9
8     62    35     no endspace, not_always, no empty    6     9
9     97    35     no empty                             7     9
10    132   35     no endspace, not_always, no empty    6     9
11    167   4      zerofill(1)                          2     9
12    171   16     no endspace, not_always, no empty    5     9
13    187   35     no endspace, not_always, no empty    6     9
14    222   4      zerofill(1)                          2     9
15    226   16     no endspace, not_always, no empty    5     9
16    242   20     no endspace, not_always              8     9
17    262   20     no endspace, no empty                8     9
18    282   20     no endspace, no empty                5     9
19    302   30     no endspace, no empty                6     9
20    332   4      allways zero                         2     9
21    336   4      allways zero                         2     9
22    340   1                                           3     9
23    341   8      table-lockup                         9     0
24    349   8      table-lockup                        10     0
25    357   8      allways zero                         2     9
26    365   2                                           2     9
27    367   2      no zeros, zerofill(1)                2     9
28    369   4      no zeros, zerofill(1)                2     9
29    373   4      table-lockup                        11     0
30    377   1                                           3     9
31    378   2      no zeros, zerofill(1)                2     9
32    380   8      no zeros                             2     9
33    388   4      allways zero                         2     9
34    392   4      table-lockup                        12     0
35    396   4      no zeros, zerofill(1)               13     9
36    400   4      no zeros, zerofill(1)                2     9
37    404   1                                           2     9
38    405   4      no zeros                             2     9
39    409   4      allways zero                         2     9
40    413   4      no zeros                             2     9
41    417   4      allways zero                         2     9
42    421   4      no zeros                             2     9
43    425   4      allways zero                         2     9
44    429   20     no empty                             3     9
45    449   30     no empty                             3     9
46    479   1                                          14     4
47    480   1                                          14     4
48    481   79     no endspace, no empty               15     9
49    560   79     no empty                             2     9
50    639   79     no empty                             2     9
51    718   79     no endspace                         16     9
52    797   8      no empty                             2     9
53    805   1                                          17     1
54    806   1                                           3     9
55    807   20     no empty                             3     9
56    827   4      no zeros, zerofill(2)                2     9
57    831   4      no zeros, zerofill(1)                2     9
@end example

@node Changing MySQL, ODBC, Tools, Top
@chapter Adding functions to @strong{MySQL}

@menu
* Adding functions::            Adding new functions to @strong{MySQL}
@end menu

@node Adding functions,  , Changing MySQL, Changing MySQL
@section Adding new functions to @strong{MySQL}

If you need it as sql function (like @code{SOUNDEX()}), its real easy:

@enumerate
@item
Add one line in @code{sql_lex.cc} defining the function name in the
@code{sql_functions} array.
@item
Add two lines in @code{sql_yacc.y}. On defines the preprocessor symbol
yacc can define (this should be added at the beginning of the
file). Then define the function parameters and create an 'item' with
these parameters.  Check, for example, all occurrences of SOUNDEX in
@code{sql_yacc.y}
@item
In item_func.h declare a class inheriting from Item_num_func or
Item_str_func depending on whether your function returns a number or a
string.
@item
In @file{item_func.cc} add: @code{double *Item_func_newname::val()} If
you are defining a number function or @code{String
*Item_func_newname::Str(String *str)} if you are defining a string
function.
@item
You should probably also define the following function: @code{void
Item_func_newname::fix_length_and_dec()} This should at least calcutate
@code{max_length} based on the given arguments. @code{max_length} is the
maximal number of chars the function may return. If the function can't
return a @code{NULL}, one should set @code{maybe_null = 0}.
@end enumerate

About string functions:
@enumerate
@item
For string functions the @code{String *str} argument provides a string
buffer that may be used to hold the result.
@item
A string function should return the string that holds the result.
@item
All current string functions tries to avoid to alloc any memory unless
absolutely necessary!
@end enumerate

@cindex ODBC
@cindex Windows
@node ODBC, Problems, Changing MySQL, Top
@chapter ODBC

@menu
* Which ODBC OS::               Which operating systems does @strong{MySQL} ODBC support?
* ODBC Problems::               How should I report problems with @strong{MySQL} ODBC?
* MyODBC clients::              Programs known to work with MyODBC.
* ODBC administrator::          How do I fill in the various fields in the ODBC administrator program.
* ODBC and last_insert_id::     How to get the value of a AUTO_INCREMENT column in ODBC
@end menu

@node Which ODBC OS, ODBC Problems, ODBC, ODBC
@section Which operating systems does @strong{MySQL} ODBC support?

@strong{MySQL} ODBC is a 32 bit ODBC (2.50) level 0 driver for Windows95
and NT. We hope somebody will port it to Windows 3.x.

@node ODBC Problems, MyODBC clients, Which ODBC OS, ODBC
@section How should I report problems with @strong{MySQL} ODBC?

We have only tested ODBC with Admndemo, some C programs, Msquery and
Excel.

To give some light about any problem we would like to have the log file
from the ODBC manager (the log you get when requesting logs from
ODBCADMIN) and a MYODBC log.

To get a MYODBC log, please put this @code{MYSQL_DEBUG=d:t:O,filename}
in your @file{AUTOEXEC.BAT} and restart.

The log will be written to file @file{filename}.

@node MyODBC clients, ODBC administrator, ODBC Problems, ODBC
@section Programs known to work with MyODBC.

Most programs should work with MyODBC, but these we tested ourselves or
got a confirmation from some user that is works:

@table @asis
@item Program
Comment
@item Access
To make Access work:
@itemize @bullet
@item
You should have a primary key in the table.
@item
You should have a timestamp.
@item
Only use double float fields. Access fails when comparing with single
floats.
@item
Set 2 in the options field when connection to @strong{MySQL}.
@end itemize
@item Excel
Works. Some tips
@itemize @bullet
@item 
If you have problems with dates try to select them as strings.
@example
SELECT concat(sunrise_time), concat(sunset_time) FROM sunrise_sunset;
@end example
Values returned in this format (string) should be correctly recognised
by Excel97 as time values.

What @code{concat()} does in this case is that it fools ODBC to think
the column is of 'string type'. Without the 'concat()' ODBC knows the
column is of time type. And Exel does not understand that.

Note that this is uses bug in Excel because it automaticly converts a
string to a time. This would be great if the source was a text file, but
this is plain stupid when the source is a ODBC connection which reports
exact types for each column.
@end itemize
@item odbcadmin
Test program for ODBC.
@item Delphi
One must use DBE 3.2 or newer.
@item C++Builder
Tested with BDE 3.0. The only known problem is that when the table
schema changes, query fields are not updated. BDE however does not seem
to recognise primary keys, only the index PRIMARY, though this has not
been a problem.
@end table

@node ODBC administrator, ODBC and last_insert_id, MyODBC clients, ODBC
@section How do I fill in the various fields in the ODBC administrator program?

There are three possibilities for specifying the server name on
windows95:

@enumerate
@item
Use the IP.
@item
Add a file lmhosts with the following info: @code{ip hostname}
For example:
@example
194.216.84.21 my
@end example
@item
Configure the PC to use DNS.
@end enumerate
Example of how to fill in the 'ODBC setup'.
@example
Data Source Name:   test
Description:        This is my test database
Server:             194.216.84.21
User:               monty
Password:           my
Port:
@end example

These are default values to be given when prompting for a Driver
connect. You don't have to give 'server', 'user' or 'password' in this
screen. If port is not given the default port (3333) is used.

When connection to a ODBC source you have the option to change the
server, user, password and port.

@node ODBC and last_insert_id,  , ODBC administrator, ODBC
@section How to get the value of a AUTO_INCREMENT column in ODBC

A common problem is how to get the value of a automatically generated id
from a insert. With ODBC you can do something like this:

@example
INSERT INTO foo (auto,text) VALUES(NULL,'text')
select LAST_INSERT_ID()
@end example

or if you are just going to insert in into another table:a

@example
INSERT INTO foo (auto,text) VALUES(NULL,'text')
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text')
@end example

@node Problems, Clients, ODBC, Top
@chapter Problems and common errors

@menu
* Common errors::               Some common errors when using @strong{MySQL}
* Full disk::                   
* Error Access denied::         
* Changing MySQL user ::        How to run MysQL as a normal user.
* File permissions ::           Problems with file permissions.
* Using DATE::                  Problems using DATE columns.
* Case sensitivity::            Case sensitivity in searches.
@end menu

@node Common errors, Full disk, Problems, Problems
@section Some common errors when using @strong{MySQL}

@menu
* Gone away::                   @code{MySQL server has gone away} error.
* Out of memory::               Out of memory errors
* Packet to large::             
* Full table::                  The table is full
@end menu

@node Gone away, Out of memory, Common errors, Common errors
@subsection @code{MySQL server has gone away} error.

The most common reason for the @code{MySQL server has gone away} error
is that the server closed the connection because of a timeout. By
default the server closes the connection after 8 hours if nothing has
happended.

If you have a script you just have to reconnect and try again. If you
are using the mysql monitor just type @code{reconnect}.

@node Out of memory, Packet to large, Gone away, Common errors
@subsection Out of memory errors

If you do a query and get something like the following error:

@example
mysql: Out of memory at line 42, 'malloc.c'
mysql: neaded 8136 byte (8k), memory in use: 12481367 bytes (12189k))
ERROR 2008: MySQL client got out of memory                
@end example

Note that the error says the the @strong{MySQL} client. The reason for
this error is simply that the client does not have enough memory to
store the whole result.

@node Packet to large, Full table, Out of memory, Common errors
@subsection Packet to large

When the client gets a block bigger that @code{net_buffer_length} it
issues a @code{Packet to large} error.

If the @code{mysql} client is used you may set a bigger buffer by
starting the client with @code{mysql --set-variable=
net_buffer_length=1m}.

@cindex The table is full
@node Full table,  , Packet to large, Common errors
@subsection The table is full

This error occurs when a in memory temporary table gets bigger than
@code{tmp_table_size}. To avoid this problem one can increase the
@code{-O tmp_table_size=#} option to mysqld or use the SQL option
@code{SQL_BIG_TABLES}. @xref{Set option}.

@cindex Full disk
@cindex Disk full
@node Full disk, Error Access denied, Common errors, Problems
@section How does @strong{MySQL} hand a full disk

On a disk full condition @strong{MySQL} does the following:

@itemize @bullet
It checks once every minute if there is enough space to write the
current row. If there is enough disk it continues as if nothing had
happened.
@item
Every 6 minutes it writes a entry to the log file warning about disk
full.
@item
To continue you have only to free enough free space to insert all
records.
@item
To abort you have to send a @code{mysqladmin kill} to the thread and
free enough space for 1 row!
@end itemize

@node Error Access denied, Changing MySQL user , Full disk, Problems
@section @code{Access denied?} error.

@xref{Privileges}. And especially @xref{Access denied}.

@node Changing MySQL user , File permissions , Error Access denied, Problems
@section How to run @strong{MySQL} as a normal user.

mysqld (the @strong{MySQL} server) can run as any user. In order to change mysqld
to run as user USER, you'd have to the following:

@itemize @bullet
@item
Stop the server if it's running
@item
Change the database directories so that USER has read and write privileges
privileges to them:
@code{shell> chown -R USER /your/path/to/mysql/var}
@item
start the server as user USER
@item
If you are using mysql.server to start mysqld when the system is rebooted,
you should change mysql.server to call 'su' to user USER.
@item
@end itemize

You don't have to do anything to safe_mysqld to run as not root.

At this point, your mysqld process would be running fine and dandy as
user 'USER'. One thing hasn't changed though - the access
permissions. By default (right after running the permissions table
install script), only user 'root' has access permission to the database.
Unless you have changed that, it's still true. This shouldn't stop you
from accessing @strong{MySQL} when you're logged in under a user other
than root, just specify -u root to the client program. Note that
accessing @strong{MySQL} as root, by supplying -u root in the command
line, doesn't have ANYTHING to do with @strong{MySQL} running as root,
as a user or as anyone else. The access permissions and userbase of
@strong{MySQL} are completely separate from the UNIX users. The only
connection to the UNIX users is if you don't use the -u option to
clients. In this case the client will try to login into @strong{MySQL}
with your UNIX login name. If your UNIX box itself isn't secured, you
should probably at least put a password on the root users in the
@strong{MySQL} access tables, since any johndoe user can run 'mysql -u
root dbname' and do whatever he likes.

@node File permissions , Using DATE, Changing MySQL user , Problems
@section Problems with file permissions

If you have problems with file permissions, for example when
creating a table mysql gives:
"ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)",
then you might have the wrong value for environment variable UMASK.
Default umask is 0664. Fix:
@example
UMASK=432
export UMASK
./bin/safe_mysqld
@end example

@node Using DATE, Case sensitivity, File permissions , Problems
@section Problems using DATE columns.

The format of DATE is 'YYYY-MM-DD'. Actually nothing else is allowed
(ANSI SQL). One should use this format to update or in the WHERE clause,
ie select * from table_1 where idate >= '1997-05-05';

As a convenience, @strong{MySQL} automatically converts the date to a
number if used in a number context. It is also smart enough to allow a
'relaxed' string form when updating and in a @code{WHERE} with a compare
to a @code{TIMESTAMP}, @code{DATE} or a @code{DATETIME} column.

This means that the following works:

@example
insert into table_1 (idate) values (19970505) ;
insert into table_1 (idate) values ('19970505') ;
insert into table_1 (idate) values ('1997-05-05');
insert into table_1 (idate) values ('1997.05.05');
insert into table_1 (idate) values ('1997 05 05');

select idate from table_1 where idate >= '1997-05-05';
select idate from table_1 where idate >= 19970505;
select mod(idate,100)1 from table_1 where idate >= 19970505;
select idate from table_1 where idate >= '19970505';
@end example

The following will not work:

@example
select idate from table_1 where strcmp(idate,'19970505')=0;
Because '19970505' is compared as a string to '1997-05-05'.
@end example

@cindex Case sensitivity
@cindex Chinese
@cindex Big5 Chinese character encoding
@node Case sensitivity,  , Using DATE, Problems
@section Case sensitivity in searches.

By default a @strong{MySQL} column is case insensitive (There are some
character sets that never are case insensitive). That means that if you
search with @code{column like 'a%';} you will get all columns that start
with @code{A} or @code{a}. If you want to make this search case
sensitive use something like @code{INDEX(column, "A")=0} to check a
prefix. Or @code{STRCMP(column, "A") = 0} if the whole string should be
the same.

If you want @code{column} to always be treated in a case sensitive maner
declare it as @code{BINARY}. @xref{Create table}.

If you are using Chinese data in the so-called big5 encoding you want to
make all character columns @code{BINARY}. This works because the sorting
order of big5 encoding characters is based on the order of ascii codes.

@node Clients, Comparasions, Problems, Top
@chapter @strong{MySQL} client tools and API's

@menu
* C API::                       @strong{MySQL} C API
* Perl::                        @strong{MySQL} Perl API's
* JAVA::                        @strong{MySQL} JAVA connectivity (JDBC)
* PHP::                         @strong{MySQL} PHP API's
* C++::                         
* Python::                      @strong{MySQL} Python API's
* TCL::                         @strong{MySQL} TCL API's
@end menu

@node C API, Perl, Clients, Clients
@section @strong{MySQL} C API

The @code{C} API is distributed with @strong{MySQL}. It is included in
the @code{libmysqlclinet} library.It allows @code{C} programs to access
a database.

Most of the other client APIs (all except JAVA) use this library to
connect. So for example ypu can use the same environment variables.

The client has a max communication buffer size. This is automatically
increase up to the maximum size (the default for this is 512kb). As
buffers are increased (but not decreased until close) on demand, it will
not take any resources if one increases this. This size check is mostly
a check for erroneous queries and communication packets.

The commncation buffer must be big enough to contain a single SQL
statement and one row of returned data (but of course not at the same
time). Each threads communication buffer is dynamicly enlarged to handle
any row or query up to the imposed limit.

So if you have @code{BLOB}s that contains data up to 16M you must have
at least 16M as your communication buffer limit. @xref{MySQL
parameters}.

MySQL shrinks each communication buffer to @code{net_buffer_length}
after each query.


@multitable @columnfractions .3 .7
@item @strong{mysql_affected_rows} @tab
Retrieves the number of affected rows by the last UPDATE, DELETE or INSERT.
@item @strong{mysql_close} @tab
Closes a server connection.
@item @strong{mysql_connect} @tab
Establish a connection to a @strong{MySQL} server. 
@item @strong{mysql_create_db} @tab
Create a database.
@item @strong{mysql_data_seek} @tab
Seeks to an arbitrary row in a query result set.
@item @strong{mysql_drop_db} @tab
Drop a database.
@item @strong{mysql_eof} @tab
Determine if last row has been read.
@item @strong{mysql_error} @tab
The error message from last @strong{MySQL} function.
@item @strong{mysql_fetch_field} @tab
Find out what type a table field is.
@item @strong{mysql_fetch_lengths} @tab
Returns the length of all columns in a query result set.
@item @strong{mysql_fetch_row} @tab
Fetch the 'next' row in the query result.
@item @strong{mysql_field_seek} @tab
Put the column cursor on column number field.
@item @strong{mysql_free_result} @tab
Free memory used to store a query result. 
@item @strong{mysql_get_client_info} @tab
Return version information for the current client library. 
@item @strong{mysql_get_host_info} @tab
Returns name of server host.
@item @strong{mysql_get_proto_info} @tab
Get protocol version used by connection.
@item @strong{mysql_get_server_info} @tab
Returns the version number of the server.
@item @strong{mysql_insert_id} @tab
Returns ID generated for a AUTO_INCREMENT field. 
@item @strong{mysql_list_dbs} @tab
Return maching database names.
@item @strong{mysql_list_fields} @tab
Return maching field names.
@item @strong{mysql_list_processes} @tab
Get a list of the current server threads.
@item @strong{mysql_list_tables} @tab
Return maching table names.
@item @strong{mysql_num_fields} @tab
Return the number of columns in a result set.
@item @strong{mysql_num_rows} @tab
Returns the number of rows in result set.
@item @strong{mysql_query} @tab
Executes a SQL query.
@item @strong{mysql_real_query} @tab
Executes a SQL query with length information.
@item @strong{mysql_reload} @tab
Reload the user permissions table in the server.
@item @strong{mysql_select_db} @tab
Connect to a database.
@item @strong{mysql_shutdown} @tab
Shut down the database server.
@item @strong{mysql_stat} @tab
Return server status in a string.
@item @strong{mysql_store_result} @tab
Reads a result set to the client.
@item @strong{mysql_use_result} @tab
Initiate a dynamic result set for each row.
@end multitable 

@table @code
@findex mysql_affected_rows
@item int @strong{mysql_affected_rows}(MYSQL *mysql)
Retrieves the number of affected rows by the last UPDATE, DELETE or INSERT.
@findex mysql_close
@item void @strong{mysql_close}(MYSQL *mysql)
Closes a server connection.
@findex mysql_connect
@item MYSQL *@strong{mysql_connect}(MYSQL *mysql, const char *host, const char *user, const char *passwd)
Establish a connection to a @strong{MySQL} server. 
@findex mysql_create_db
@item int @strong{mysql_create_db}(MYSQL *mysql, const char *db)
Create a database.
@findex mysql_data_seek
@item void @strong{mysql_data_seek}(MYSQL_RES *res, uint offset)
Seeks to an arbitrary row in a query result set.
@findex mysql_drop_db
@item int @strong{mysql_drop_db}(MYSQL *mysql, const char *db)
Drop a database.
@findex mysql_eof
@item int @strong{mysql_eof}(MYSQL_RES *)
Determine if last row has been read.
@findex mysql_error
@item char *@strong{mysql_error}(MYSQL *mysql)
The error message from last @strong{MySQL} function.
@findex mysql_fetch_field
@item MYSQL_FIELD *@strong{mysql_fetch_field}(MYSQL_RES *handle)
Find out what type a table field is.

When querying for the length of a @code{BLOB} without retreving a result
@strong{MySQL} returns the 'default blob length', which is 8192, when
doing a select on the table. When one retrevies a result,
column_object->max_length contains the real max_length for the specific
query.

The 8192 is chosen because @strong{MySQL} doesn't know the max length
for the blob object. This should be made configurable sometime.

@findex mysql_fetch_lengths
@item unsigned int *@strong{mysql_fetch_lengths}(MYSQL_RES *mysql)
Returns the length of all columns in a query result set.
@findex mysql_fetch_row
@item MYSQL_ROW @strong{mysql_fetch_row}(MYSQL_RES *mysql)
Fetch the 'next' row in the query result.
@findex mysql_field_seek
@item void @strong{mysql_field_seek}(MYSQL_RES *result, int field)
Put the column cursor on column number field.
@findex mysql_free_result
@item void @strong{mysql_free_result}(MYSQL_RES *result)
Free memory used to store a query result. 
@findex mysql_get_client_info
@item char *@strong{mysql_get_client_info}(void)
Return version information for the current client library. 
@findex mysql_get_host_info
@item char *@strong{mysql_get_host_info}(MYSQL *mysql)
Returns name of server host.
@findex mysql_get_proto_info
@item int @strong{mysql_get_proto_info}(MYSQL *mysql)
Get protocol version used by connection.
@findex mysql_get_server_info
@item char *@strong{mysql_get_server_info}(MYSQL *mysql)
Returns the version number of the server.
@findex mysql_insert_id
@item int @strong{mysql_insert_id}(MYSQL *mysql)
Returns ID generated for AUTO_INCREMENT field. 
@findex mysql_list_dbs
@item MYSQL_RES *@strong{mysql_list_dbs}(MYSQL *mysql, const char *wild)
Return maching database names.
@findex mysql_list_fields
@item MYSQL_RES *@strong{mysql_list_fields}(MYSQL *mysql, const char *table, const char *wild)
Return maching field names.
@findex mysql_list_processes
@item MYSQL_RES *@strong{mysql_list_processes}(MYSQL *mysql)
Get a list of the current server threads.
@findex mysql_list_tables
@item MYSQL_RES *@strong{mysql_list_tables}(MYSQL *mysql, const char *wild)
Return maching table names.
@findex mysql_num_fields
@item int @strong{mysql_num_fields}(MYSQL_RES *result)
Return the number of columns in a result set.
@findex mysql_num_rows
@item int @strong{mysql_num_rows}(MYSQL_RES *result)
Returns the number of rows in result set.
@findex mysql_query
@item int @strong{mysql_query}(MYSQL *mysql, const char *query)
Executes a SQL query.
@findex mysql_real_query
@item int @strong{mysql_real_query}(MYSQL *mysql, const char *query, uint length)
Executes a SQL query with length information.
@findex mysql_reload
@item int @strong{mysql_reload}(MYSQL *mysql)
Reload the user permissions table in the server.
@findex mysql_select_db
@item int @strong{mysql_select_db}(MYSQL *mysql, const char *db)
Connect to a database.
@findex mysql_shutdown
@item int @strong{mysql_shutdown}(MYSQL *mysql)
Shut down the database server.
@findex mysql_stat
@item char *@strong{mysql_stat}(MYSQL *mysql)
Return server status in a string.
@findex mysql_store_result
@item MYSQL_RES *@strong{mysql_store_result}(MYSQL *mysql)
Reads a result set to the client.
@findex mysql_use_result
@item MYSQL_RES *@strong{mysql_use_result}(MYSQL *mysql)
Initiate a dynamic result set for each row.
@end table

@menu
* Query Results::               After @code{mysql_query()} returns success, @code{mysql_store_result()} sometimes returns NULL.
* Result values::               What results can I get from a query?
* mysql_insert_id::             How can get the unique ID for the last row?
* mysql_use_result::            What is the difference between @code{mysql_use_result()} and @code{mysql_store_result()} modes?
* linking::                     Problems linking with C API.
* threadsafe::                  How to make a threadsafe client
* Threadsafe client::           Making a threadsafe client
@end menu

@node Query Results, Result values, C API, C API
@subsection Why is it that after @code{mysql_query()} returns success, @code{mysql_store_result()} sometimes returns NULL?

It means one of the following:

@enumerate
@item
Malloc failure.
@item
The data couldn't be read (Error on connection).
@item
The statement was a statement which never returns data (@code{INSERT}
or @code{UPDATE} or @code{DELETE}).
@end enumerate

You can always check if the statement should have given a result by
checking that @code{mysql_num_columns(MYSQL *)} isn't 0. If this is 0
the last query was a statement that does not return values. For example
a @code{INSERT} or a @code{DELETE}.

You have got an error if @code{mysql_error(MYSQL *)} isn't empty!

@node Result values, mysql_insert_id, Query Results, C API
@subsection What results can I get from a query?

@code{mysql_affected_rows(MYSQL *)} returns the number of affected
rows in the last query when doing an INSERT, UPDATE or DELETE. Except,
if DELETE is used without a where clause then the table is truncated
which is much faster!. In this case it returns records affected as zero.

@code{mysql_insert_id(MYSQL *)} returns the given ID of the last
query when inserting a row into a table with a @code{AUTO_INCREMENT} index.
@xref{mysql_insert_id}

Some queries, @code{LOAD DATA INFILE...} and @code{INSERT INTO
... SELECT ...}, return additional info.  The result is returned in
@code{mysql_info(MYSQL *)}. @code{mysql_info()} returns a null pointer
if there is no additional information.

@node mysql_insert_id, mysql_use_result, Result values, C API
@subsection How can I get the unique ID for the last inserted row?

If you insert a record that has a @code{AUTO_INCREMENT} index then you
can get the given id with @code{mysql_insert_id(MYSQL *)}.

The last value is also stored in the server and can be retrieved with
the @code{LAST_INSERT_ID()} function.

You can check if an auto_increment index is used by the following
code. This also checks if the query was a insert with a
@code{auto_increment} index.

@example
if (mysql_error(MYSQL)[0] == 0 &&
    mysql_num_fields(MYSQL_RESULT) == 0 &&
    mysql_insert_id(MYSQL) != 0)
  used_id = mysql_insert_id(MYSQL);
@end example

The id that @code{LAST_INSERT_ID()} returns is maintained in the server
per connection. It will not be botched by another client. It will not
even be changed if you update another auto_increment column with a non
magic value (that is a not null or 0).

@node mysql_use_result, linking, mysql_insert_id, C API
@subsection What is the difference between @code{mysql_use_result()} and @code{mysql_store_result()} modes?

@code{mysql_use_results} reads the result directly from the server without
storing it in a local buffer. This is somewhat faster and uses much less
memory thatn @code{mysql_store_result}. One shouldn't use
@code{mysql_use_results} if there is a lot of processing being done for
each row at the client side, or if the output is sent to a screen on which
the user may do a ^S (stop scroll). Doing this would tie up the server
and then other threads can't update the used tables. One can't
use @code{mysql_data_seek} or issue other queries while using
@code{mysql_use_result}.

@node linking, threadsafe, mysql_use_result, C API
@subsection Problems linking with C API.

When linking with the C API you can get the following errors on some systems:

@example
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

Undefined        first referenced
 symbol          in file
floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client
@end example

This means that on your system you have to include the math library (-lm)
last in the compile/link line.

@node threadsafe, Threadsafe client, linking, C API
@subsection How to make a threadsafe client

The client is 'almost' thread-safe. The biggest problem is that
net.c (the subroutines that read from sockets) are not interrupt safe.
This was done with the thought that one may want to have one's own alarm
that can break a long read to a server.

The standard client libraries are not compiled with the thread options.

To get a thread safe client use the @code{-lmysys}, @code{-lstring} and
@code{-ldbug} libraries and @code{net_serv.o} that the server uses.

When using a threaded client I think one can have great use of the
thr_alarm.c routine. If you are using the mysys routines, the only
thing one has to remember is to call my_init() first!

@node Threadsafe client,  , threadsafe, C API
@subsection Making a threadsafe client

All functions except mysql_connect() are currently thread safe.

To get connect thread_safe you have to do the following:

Recompile the client with:

@example
CPPFLAGS=-DTHREAD_SAFE_CLIENT ./configure ...
@end example

You may get some errors because of undefined symbols when linking the
standard client as the pthread libraries are not included by default.

The resulting libmysqld.a library is now thread safe.

Two treads can't use the same handle (returned by
@code{mysql_connect()}) at the same time, even if two threads can use
different @code{MYSQL_RES} handles that was created with
@code{mysql_store_result()}.

When using a threaded client one can have great use of the
thr_alarm.c routine. If you are using the mysys routines, the only
thing one has to remember is to call my_init() first!

@node Perl, JAVA, C API, Clients
@section @strong{MySQL} Perl API's

Since @code{DBI/DBD} now is the recommended perl interface mysqlperl is
not documented here.

@menu
* Perl DBI Class::              The DBI interface
* DBI-info::                    More DBI/DBD information
@end menu

@subsection @code{DBI} with @code{DBD::mysql}

@code{DBI} is a generic interface for many databases. That means that
you can write a script what works with many different database engines
without change. You need a DataBase Driver (DBD) defined for each
database type. For @strong{MySQL}, this driver is called
@code{DBD::mysql}.

For more information on the Perl5 DBI, please visit
@uref{http://www.hermetica.com/technologia/DBI, DBIs web page} and read
the documentation. For more information on Object Oriented Programming
(OOP) as defined in Perl5, see
@uref{http://language.perl.com/info/documentation.html, The perl OOP
page}.

@node Perl DBI Class, DBI-info, Perl, Perl
@subsubsection The DBI interface

@strong{Portable DBI methods.}

@multitable @columnfractions .3 .7
@item connect @tab Establish a connection to a database server
@item prepare @tab Get a SQL statement ready for execution
@item do      @tab Prepares and executes a SQL statement
@item disconnect @tab Disconnect from the database server
@item quote   @tab Quote strings/blobs to be inserted
@item execute @tab Executes prepared statements
@item fetchrow_array @tab fetch the next row as an array of fields.
@item fetchrow_arrayref @tab fetch next row as a reference array of fields
@item fetchrow_hashref @tab fetch next row as a reference to a hashtable
@item fetchall_arrayref @tab Get all data as a array of arrays 
@item finish  @tab finish a statment and let the system free resources
@item rows    @tab Returns the number of rows affected
@item data_sources @tab Return an array of databases available on localhost
@item ChopBlanks @tab Shall fetchrow trim spaces
@item NUM_OF_PARAMS @tab Number of placeholders in the prepared statement
@item NULLABLE @tab Which columns can be NULL
@end multitable

@strong{MySQL specific methods.}

@multitable @columnfractions .3 .7
@item insertid @tab The latest auto_increment value
@item is_blob @tab Which column ar BLOBs
@item is_key @tab Which columns are keys
@item is_num @tab Which columns are numeric
@item is_pri_key @tab Which columns are primary keys
@item is_not_null @tab Which columns can NOT be NULL. See NULLABLE
@item length @tab Maximum theoretically possible column sizes
@item max_length @tab Maximum physical present column sizes
@item NAME @tab Column names
@item NUM_OF_FIELDS @tab Number of fields returned.
@item table @tab Table names in returned set
@item type @tab All coulumn types
@item _CreateDB @tab Create a database
@item _DropDB @tab Drop a database. @strong{THIS IS DANGEROUS}
@end multitable

@ftable @code

@item connect
You use the connect method to make a database connection to the data
source. The @code{$data_source} value should begin with
@code{DBI:driver_name:}.
Example connect methods with the @code{DBD::mysql} driver:
@example
$dbh = DBI->connect("DBI:mysql:$database", $user, $password);
$dbh = DBI->connect("DBI:mysql:$database:$hostname",
                    $user, $password);
$dbh = DBI->connect("DBI:mysql:$database:$hostname:$port",
                    $user, $password);
@end example
If the username and/or password are undefined, then the DBI will use the
values of the @code{DBI_USER}, @code{DBI_PASS} environment variables
respectively. If you don't specify a hostname, then it will default to
@code{"localhost"}. If you don't specify a port, then it defaults to the
default mysql port (3333).

@item prepare
Prepare gets a SQL statement ready for execution by the database engine
and returns a statement handle @code{($sth)} which invokes the execute
method. Example:
@example
$sth = $dbh->prepare($statement) or die "Can't prepare $statement: 
$dbh->errstr\n";
@end example

@item do
The "do" method prepares and executes a SQL statement and returns the
number of rows effected. This method is generally used for "non-select"
statements which can not be prepared in advance (driver limitation) or
which do not need to executed more than once (inserts, deletes,
etc.). Examples:
@example
$rc = $dbh->do($statement) or
        die "Can't execute $statement: $dbh- >errstr\n";
@end example

@item disconnect
Disconnect will disconnect the database handle from the database. This
is typically called right before you exit from the program. 
Example:
@example
$rc = $dbh->disconnect;
@end example

@item quote
The quote method is used to "escape" any special characters contained in
the string and to add the required outer quotation marks.
@example
$sql = $dbh->quote($string)
@end example

@item execute
This method executes the prepared statement. For non-select satements,
it returns the number of rows affected. For select statements, execute
only starts the SQL query in the database. You need to use one of the
@code{fetch_*} methods below to retrieve the data.  Example:
@example
$rv = $sth->execute or die "can't execute the query: $sth->errstr;
@end example

@item fetchrow_array
This method "fetches" the next row of data and returns it as an array of
field values.  Example:
@example
while(@@row = $sth->fetchrow_array) @{
        print qw($row[0]\t$row[1]\t$row[2]\n); 
@}
@end example

@item fetchrow_arrayref
This method "fetches" the next row of data and returns it as a reference
to an array of field values. Example:
@example
while($row_ref = $sth->fetchrow_arrayref) @{
        print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
@}
@end example

@item fetchrow_hashref
This method fetches a row of data and returns a reference to a hash
table containing field name/value pairs. This method is not nearly as
efficient as using array references as demonstrated above. Example:
@example
while($hash_ref = $sth->fetchrow_hashref) @{
        print qw($hash_ref->@{firstname@}\t$hash_ref->@{lastname@}\t\
                $hash_ref- > title@}\n);
@}
@end example

@item fetchall_arrayref
This method is used to get all the data (rows) to be returned from the
SQL statement. It returns a reference to an array of arrays of
references to each row. You access/print the data by using a nested
loop. Example:
@example
my $table = $sth->fetchall_arrayref or die "$sth->errstr\n";
my($i, $j);
for $i ( 0 .. $#@{$table@} ) @{
        for $j ( 0 .. $#@{$table->[$i]@} ) @{
                print "$table->[$i][$j]\t";
        @}
        print "\n";
@}
@end example

@item finish
Indicates that no more date will be fetched from this statement
handle. You call this method to free up the statement handle and any
system resources it may be holding.  Example:
@example
$rc = $sth->finish;
@end example

@item rows
Returns the number of rows affected (updated, deleted, etc.) from the
last command.  This is usually used after a do() or non-select execute()
statement.
@example
$rv = $sth->rows;
@end example

@item NULLABLE
A reference to an array of boolean values; TRUE indicates that this
column may contain NULL's.
@example
$null_possible = $sth->@{NULLABLE@}; 
@end example

@item NUM_OF_FIELDS
Number of fields returned by a SELECT or LISTFIELDS statement.  You may
use this for checking whether a statement returned a result: A zero
value indicates a non-SELECT statement like INSERT, DELETE or UPDATE.
@example
$nr_of_fields = $sth->@{NUM_OF_FIELDS@};
@end example

@item data_sources
This method returns an array of databases available to the mysql daemon
on localhost.
@example
@@dbs = DBI->data_sources("mysql"); 
@end example

@item ChopBlanks
This determines whether a fetchrow will chop preceding and trailing
blanks off the returned values.
@example
$sth->@{'ChopBlanks') =1; 
@end example

@end ftable

@strong{MySQL specific methods.}

@ftable @code
@item insertid
If you use the auto-increment feature of mysql, the new auto-incremented
values will be stored here.
@example
$new_id = $sth->@{insertid@};
@end example

@item is_blob
Reference to an array of boolean values; TRUE indicates, that the
respective column is a blob.
@example
$keys = $sth->@{is_blob@};
@end example

@item is_key
Reference to an array of boolean values; TRUE indicates, that the
respective column is a key.
@example
$keys = $sth->@{is_key@};
@end example

@item is_num
Reference to an array of boolean values; TRUE indicates, that the
respective column contains numeric values.
@example
$nums = $sth->@{is_num@};
@end example

@item is_pri_key
Reference to an array of boolean values; TRUE indicates, that the
respective column is a primary key.
@example
$pri_keys = $sth->@{is_pri_key@};
@end example

@item is_not_null
A reference to an array of boolean values; FALSE indicates that this
column may contain NULL's. You should better use the NULLABLE attribute
above which is a DBI standard.
@example
$not_nulls = $sth->@{is_not_null@};
@end example

@item max_length
@itemx length
A reference to an array of maximum column sizes. The max_length is the
maximum physically present in the result table, length gives the
theoretically possible maximum.
@example
$max_lengts = $sth->@{max_length@};
$lengts = $sth->@{length@};
@end example

@item NAME
A reference to an array of column names.
@example
$names = $sth->@{NAME@};
@end example

@item table
Returns a reference to an array of table names. 
@example
$tables = $sth->@{table@};
@end example
@end ftable

@node DBI-info,  , Perl DBI Class, Perl
@subsubsection More DBI/DBD information

You can use the perldoc command to get more information about DBI.

@example
perldoc DBI
perldoc DBI::FAQ
perldoc mysql
@end example

You can also use the @code{pod2man}, @code{pod2html}, etc.. tools to
translate to other formats.

And of course you can find the latest DBI information at
@uref{http://www.hermetica.com/technologia/DBI, the DBI web page @*}.

@node JAVA, PHP, Perl, Clients
@section @strong{MySQL} JAVA connectivity (JDBC)

Insert pointers/descriptions of JDBC.

@node PHP, C++, JAVA, Clients
@section @strong{MySQL} PHP API's

Insert pointers/descriptions of PHP.

@node C++, Python, PHP, Clients
@section @strong{MySQL} C++ API's

Insert pointers/descriptions for C++.

@node Python, TCL, C++, Clients
@section @strong{MySQL} Python API's

Insert pointers/descriptions for Python.

@node TCL,  , Python, Clients
@section @strong{MySQL} TCL API's

Insert pointers/descriptions for TCL.

@node Comparasions, Users, Clients, Top
@chapter How does @strong{MySQL} compare with other databases

@menu
* Compare mSQL::                How does @strong{MySQL} compare with mSQL Using mSQL
* Compare PostgreSQL::          How does @strong{MySQL} compare with PostgreSQL
@end menu

@node Compare mSQL, Compare PostgreSQL, Comparasions, Comparasions
@section How does @strong{MySQL} compare with @code{mSQL}

This section has been written by the @strong{MySQL} developers so it
should be read with that in mind. But there are NO factual errors that
we know of.

For a list of all supported limits, functions and types see the @*
@uref{http:www.tcx.se/crash-me.html, crash-me web page}.

@table @strong
@item Performance.

For a true comparison of speed use the growing @strong{MySQL} benchmarka
suite. @xref{Benchmarks}

@strong{MySQL} is significantly quicker on complex selects.

@code{mSQL} can get patalogically slow if you chage the order of tables
in a select. In the benchmark suite a time more that 15000 times slower
than @strong{MySQL} was seen.

Because of no thread creation overhead, small parser, few features and
simple security @code{mSQL} should be quicker at:

@itemize @bullet
Test that do a lot of connect/disconnect with a very simple query.
Inserts into very simple tables with few columns and keys.
@item
@code{CREATE TABLE} and @code{DROP TABLE}.
@item
@code{SELECT} one something that isn't a index. (A table scan is very
easy)
@end itemize

As these operations are so simple, it is hard to be better at them when
you have a higher start overhead. After the connection is established
@strong{MySQL} should perform much better.

@strong{MySQL} on the other hand is much faster than @code{mSQL} and
most other SQL implementions on the following:

@itemize @bullet
Retrieving large results (@strong{MySQL} has a better, faster and safer
protocol)
@item
Tables with variable length strings since @strong{MySQL} has more efficent
handling and can have indexs on varchars.
@item
Handling tables with many columns.
@item
Handling tables with large record lengths.
@item
SELECT with many expressions.
@item
SELECT on large tables.
@item
Handle many connections at the same time. @strong{MySQL} is fully
multi-threaded. Each connection has it is own thread, which means that
none of them has to wait for the other (unless a query modifying the
same table you need to use is executed). In @code{mSQL} all other
connections have to wait until the first, doesn't matter whether the
query is long or short, is executed and finished. After that the next
connection can be served, while all the others wait again, etc.
@item
Joins (We have seen (@xref{Benchmarks}) speed differences of 17000 times
on this one).
@item
@code{ORDER BY} and @code{GROUP BY}.
@item
@code{DISTINCT}.
@item
Using @code{TEXT} or @code{BLOB} columns.
@end itemize

@item SQL Features

@enumerate
@item @code{GROUP BY} & @code{HAVING}
@strong{MySQL} supports a full @code{GROUP BY} with both @code{HAVING}
and the following functions @code{count()}, @code{avg()}, @code{min()},
@code{max()}, @code{sum()} and @code{std()}. @code{min()} and
@code{max()} may take string arguments. @code{count(*)} is optimised to
return very quickly if this is the only thing in the query. @code{mSQL}
does not support @code{GROUP BY} at all.

@item @code{INSERT} & @code{UPDATE} with calculations.
@strong{MySQL} can do calculations in a @code{INSERT} or @code{UPDATE}.
@example
UPDATE SET x=x*10+y WHERE x<20;
@end example

@item Aliasing
@strong{MySQL} has column aliasing.

@item Qualifying column names.
If a column name is unique you do not have to use the full qualifier.

@item @code{SELECT} with functions
@strong{MySQL} has too many functions to list here. @xref{Functions}.

@end enumerate

@item Disk space efficiency
That is, how small can you make your tables.

MySQL has very precise types so that use can create tables that take
very little space. An example of a useful @strong{MySQL} datatype is the
mediumint that is 3 bytes long. If you have 10.000.0000 records even
saving one byte per record is very important.

Since @code{mSQL2} only has 4 types (char,text,int,real) it is hard to
get small tables.
@item Stability
This is harder to judge objectively. For @strong{MySQL} stability see
@xref{Stability}.

We have no experience with @code{mSQL} stability so we can not say
anything about that.

@item Price
Another important issue is of course the license. @strong{MySQL} has a
more flexible license than @code{mSQL} and is also cheaper than
@code{mSQL}. Remember to at least consider paying for a license or email
support for whatever product you choose to use. If you sell a product
with @strong{MySQL} you are of course required to get a license for
this.

@item Perl interfaces
MySQL has basically the same interfaces to perl as @code{mSQL} with some
added features.

@item JDBC (Java)
MySQL has a java interface by GWE technologies that has been improved by
Xiaokun Kelvin ZHU.

We know that @code{mSQL} has one but we have too little experience with
it to compare.

@item Rate of development
MySQL has a very small team of developers, but we are quite use to
coding C and C++ very rapidly. Since threads, functions, group by and so
on are still not implemented in @code{mSQL}, it has a lot of catching up
to do. To get some perspective on this you can view the @code{mSQL}
HISTORY file for the last year and compare it with the News
section. @xref{News}. It should be pretty obvious which one has
developed most rapidly.

@item Utility programs
Both @code{mSQL} and @strong{MySQL} has a lot of interesting third party
tools. Since it is very easy to port upwars (@code{mSQL} ->
@strong{MySQL}) @strong{MySQL} has almost all interesting @code{mSQL}
applications.

MySQL comes with a simple msql2mysql program that fixes the different
spelling of the most used functions. A conversion of a client program
from @code{mSQL} to mySQL usually takes a couple of minutes.
@end table

@menu
* Using mSQL tools::            How about mSQL tools like msql-tcl, msqljava?
* Protocol differences::        How different from @code{mSQL} are the @strong{MySQL} client/server communications protocols?
* Syntax differences::          What are the differences in the SQL syntax between @strong{MySQL} & @code{mSQL} 2.0?
@end menu

@node Using mSQL tools, Protocol differences, Compare mSQL, Compare mSQL
@subsection How about @code{mSQL} tools like msql-tcl, msqljava?

According to our experience it would just take a few hours to convert a
tool using the @code{mSQL} C API to the @strong{MySQL} C API.

The procedure:

@enumerate
@item
Run the shell script msql2mysql on the source. This needs the binary
program replace, which is distributed with @strong{MySQL}.
@item
Compile
@item
Fix all compiler errors:
@end enumerate

Differences between the @strong{MySQL} and @code{mSQL} C API's.
@itemize @bullet
@item
MySQL uses @strong{MySQL} as a connection type (@code{mSQL} uses an
@code{int}).
@item
MySQL connect takes a pointer to a MYSQL structure as a parameter.  It
is easy to define one globally or use malloc to get one.
@item
mysql_connect takes 2 extra parameters. You may set these to NULL,NULL
for default use (user and password).
@item
mysql_error takes the MYSQL structure as a parameter. Just add the
parameter to your old msql_error code if you are porting old code.
@item
Some incompatibilities exist as a result of @strong{MySQL} supporting
multiple connections to the server from the same process.
@item
@strong{MySQL} returns a error number and a text for all
errors. @code{mSQL} only returns a text error
@end itemize

@node Protocol differences, Syntax differences, Using mSQL tools, Compare mSQL
@subsection How different from @code{mSQL} are the @strong{MySQL} client/server communications protocols?

There are enough differences that it is impossible (at least not easy)
to support both.

The greatest differences between @strong{MySQL} and @code{mSQL} are:

@itemize @bullet
@item
A message buffer may contain many result rows.
@item
The message buffers are dynamically enlarged if the question or the
result is bigger than the current buffer up to a configurable server and
client limit.
@item
All packages are numbered to catch out dupplicated or missing packets.
@item
All columns are sent in ASCII, the length of columns and rows are sent
in packed binary coding (1,2 or 3 bytes).
@item
MySQL can read in the result unbuffered (without having to store the
full set in the client).
@item
If a single write/read takes more than 30 seconds then the server closes
the connection.
@item
If nothing has happened on a connection for 8 hours the server closes
the connection.
@end itemize

@node Syntax differences,  , Protocol differences, Compare mSQL
@subsection What are the differences in the SQL syntax between @strong{MySQL} & @code{mSQL} 2.0?

@itemize @bullet
@item
@code{CREATE TABLE}

@table @code
@item @strong{MySQL}
Has (among others) the following extra types: @xref{Create table}
@itemize -
@item
@code{UNSIGNED} option for all integer columns.
@item
@code{ZEROFILL} option for all integer columns.
@item
@code{AUTO_INCREMENT} option for all integer columns that also is a
@code{PRIMARY KEY}. @xref{mysql_insert_id}.
@item
@code{DEFAULT} value for all columns.
@item
@code{ENUM} type for one of a set of strings.
@item
@code{SET} type for many of a set of string.
@item
@code{BIGINT} type for 64 bit integers.
@end itemize
@item mSQL2
@multitable @columnfractions .3 .7
@item @code{mSQL} type @tab Corresponding @strong{MySQL} type.
@item char(len) @tab char(len)
@item text(len) @tab text(len). len is the maximal length. And @code{LIKE} works.
@item int @tab int. With many more options!
@item real @tab real. Or float. Both 4 and 8 bytes versions are available.
@item uint @tab Unsigned integer.
@item date @tab date. Takes ANSI SQL format instead of @code{mSQL}s own.
@item time @tab time
@item money @tab decimal(12,2). A fixed point value with two decimals.
@end multitable
@end table

@item
To create indexes.
@table @code
@item @strong{MySQL}
All indexes have to be given to @code{CREATE TABLE}. Indexes can not be
removed without recreating the table. @xref{Alter table}.
@item mSQL
Indexes must be created by a separate @code{CREATE INDEX}
clause. Indexes may be removed with @code{DROP INDEX}.
@end table

@item
To get a unique identifier in a table at insert.
@table @code
@item @strong{MySQL}
Use @code{AUTO_INCREMENT} as a column type
specifier. @xref{mysql_insert_id}.
@item mSQL
Create a @code{SEQUENCE} on a table and select the @code{_seq} column.
@end table

@item
To get a unique identifier for a row.
@table @code
@item @strong{MySQL}
Add a @code{PRIMARY KEY} to the table.
@item mSQL
Use the @code{_rowid} column. Observe that @code{_rowid} may change
depending on many factors.
@end table

@item
Get the time a column was last modified.
@table @code
@item @strong{MySQL}
Add a @code{TIMESTAMP} column to the table. And insert update it with a
@code{NULL} value. It when sutomaticaly gets the current time.
@item mSQL
Use the @code{_timestamp} column.
@end table

@item
Case insensitive searching.
@table @code
@item @strong{MySQL}
@code{LIKE} is always case insensitive. Also if possible @strong{MySQL}
uses indexes if the like argument doesn't start with a wild-card.
@item mSQL
Use @code{CLIKE}.
@end table

@item
End space handling.
@table @code
@item @strong{MySQL}
Stripps all spaces att the end of @code{CHAR} and @code{VARCHAR}
columns. Currently use a @code{TEXT} column if this behavior is
undesired.
@item mSQL
Keeps end space.
@end table

@item
What are the differences in the @code{WHERE} statement?
@table @code
@item @strong{MySQL}
@strong{MySQL} does everything correctly prioritized (AND is evaluated
before OR). To get @code{mSQL} behaviour in @strong{MySQL}, use
parenthesis: @code{select * from table where a=1 and b=2 or a=3 and b=4}
-> @code{select * from table where (a=1 and (b=2 or (a=3 and (b=4))))}.
@item mSQL
Evaluates everything from left to right. That means that some logical
calculation with more that 3 arguments can not be expressed in any
way. This also mean that you have to change some queries when you
upgrade to @strong{MySQL}. You do this easy by adding parenthesis.

Always when you are in doubt about what a query does:

@enumerate
@item
Remove all distinct keywords to make the query easier to debug.
@item
Write all columns from all tables to really see what you are doing.
@end enumerate

This will make it easier to see what goes wrong.
@end table

@item
Access Control
@table @code
@item @strong{MySQL}
Has tables to store grant options per user, host and
db. @xref{Privileges}
@item mSQL
Has a file @file{mSQL.acl} where you can grant read/write privileges for
users.
@item
@end table
@end itemize

@node Compare PostgreSQL,  , Compare mSQL, Comparasions
@section How does @strong{MySQL} compare with PostgreSQL

For a list of all supported limits, functions and types see the
@uref{http:www.tcx.se/crash-me.html, crash-me web page}.

PostgreSQL has some more advanced features like user defined types,
triggers, rules and transactions. But it lacks a lot of the standard
types and functions from ANSI SQL and ODBC. See the
@uref{http:www.tcx.se/crash-me.html, crash-me web page} for a complete
list of supported/unsupported types/function.

Normally PostgreSQL is much slower than
@strong{MySQL}. @xref{Benchmarks}.

@page
@node Users, Credits, Comparasions, Top
@appendix Some users of @strong{MySQL}.

@c @uref{http://where?, Some European phonebooks in @strong{MySQL}}

@itemize @bullet
@item
Some Web search engines:
@itemize -
@item
@uref{http://www.aaa.com.au, AAA Matilda Web Search}
@item
@uref{http://www.whatsnu.com/, What's New}
@item
@uref{http://www.aladin.de/, Aladin}
@item
@uref{http://www.columbus-finder.de/, Columbus Finder}
@item
@uref{http://www.spider.de/, Spider}
@item
@uref{http://www.blitzsuche.de/, Blitzsuche}
@end itemize
@item
Some Domain/Internet and Web service providers:
@itemize -
@item
@uref{http://www.ml.org, Monolith Internet Services} runs @strong{MySQL}
supporting nearly a million rows and over 100,000 users.
@item
@uref{http://www.wix.com/mysql-hosting, Registry over Web providers who
supports @strong{MySQL}}
@end itemize
@item
@uref{http://online.garant.ru, Internet information server}
@item
@uref{http://www.feature-showcase.com/htmls/demo_mysql.sql, AZC.COM's Feature Showcase}
@item
@uref{http://www.musicdatabase.com/, The Music Database}
@item
@uref{http://www.kiss.de/musik-mueller/, Musical note-sheets}
@item
@uref{http://TheMatrix.com/~matrix/band_search.phtml,
Musician's looking for other musicians (Free Service)}
@item
@uref{http://www.teach.org.uk/subjects/trainingcourse/g.html, Course Search}
@item
@uref{http://www.northerbys.com, Northerbys Online Auctions}
@item
@uref{http://www.hawkeye.net, Hawkeye}
@item
@uref{http://www.schiphol.nl/flights/home.htm, Amsterdam Airport Schiphol}
@item
@uref{http://TheMatrix.com/seventhsin/query.phtml, CD database}
@item
@uref{http://TheMatrix.com/~flmm/GEAR.html, Used Audio Gear Database}
@item
@uref{http://www.selftaught.com/, US Folk art broker}
@item
@uref{http://organizer.net/, Mail reading on the web}
@item
@uref{http://www.mypage.org/, Free home pages on www.somecoolname.mypage.org}
@item
@uref{http://www.schulweb.de/, Der Server fьr Schulen im Web (In German)}
@item
@uref{http://www.ald.net/, Auldhaefen Online Services}
@item
@uref{http://www.cary.net/, CaryNET Information Center}
@item
@uref{http://www.dataden.com/, Dataden Computer Systems}
@item
@uref{http://andree.grm.se/, Andrйemuseet (In Swedish)}
@item
@uref{http://www.him.net/, HOMESITE Internet Marketing}
@item
@uref{http://www.jade-v.com/techinfo.html, Jade-V Network Services }
@item
@uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml, Weather
World 2010 Technical Credits}
@item
@uref{http://gimp.foebud.org/registry/doc/, About The Gimp plugin
registry}
@item
@uref{http://www.fast-inc.com/Products/Archiver/database.html, JAVA tool
Archiver technical detail (Slightly optimistic about ANSI-92
complicate)}
@item
@uref{http://www.gamesdomain.com/cheats/usrcheat.phtml, Games Domain
Cheats Database}
@item
@uref{http://www.kcilink.com/poweredby/, The "Powered By" Page (Kcilink)}
@item
@uref{http://www.netcasting.net/index.whtml, Netcasting}
@item
@uref{http://www.cgishop.com/, CGI shop}
@end itemize

@page
@node Credits, News, Users, Top
@appendix Who has helped to make @strong{MySQL}.

Contributors to the @strong{MySQL} distribution in somewhat random
order:

@table @asis
@item Michael (Monty) Widenius
Has written the following parts of @strong{MySQL}:
@itemize @bullet
@item
All the main code in @code{mysqld}.
@item
New functions for the string library.
@item
Most of the mysys library.
@item
The @code{MISAM} library (A B-tree index file handler with index
compression and different record formats).
@item
The heap library. A memory table system with our superior full dynamic
hashing. In use since 1981 and published around 1984.
@item
replace (Look into it, it's COOL!).
@item
myodbc, the ODBC driver for Windows95.
@item
Fixing bugs in MIT threads to get it to work for @strong{MySQL}. And
also UNIREG A curses based application tool with lot of utilities.
@item
Porting of @code{mSQL} tools like msqlperl, DBD/DBI and DB2mysql.
@end itemize
@item David Axmark
@itemize @bullet
@item
Coordinator and main writer for the @strong{Reference Manual} including
enhancements to @code{texi2html}. Also automatic website updating from
this manual.
@item
autoconf & automake support.
@item
The licensing stuff.
@item
Parts of all the text files. Now days only the @file{README} is
left. The rest ended up in the manual.
@item
Our Mail master.
@item
Lots of testing of new features.
@item
Our in house 'free' software lawyer.
@item
Mailing list maintainer (who never has the time to do it right...)
@item
Our original portability code (more than 10 years old now). Now days
only some parts of mysys are left.
@item
Someone for Monty to call in the middle of the night when he just got
that new feature to work :-)
@end itemize
@item Kim Aldale
Rewriting Monty's and David's attempts at English into English.
@item Allan Larsson (The BOSS at TcX)
For all the time he has allowed Monty to spend on this 'maybe useful'
tool (@strong{MySQL}). Dedicated user (and bug finder) of UNIREG & @strong{MySQL}.
@item Per Eric Olsson
For more or less constructive criticism and real testing of the dynamic
record format.
@item David J. Hughes
For the effort to make a shareware SQL database. We at TcX started with
mSQL but found that it couldn't satisfy our purposes so instead we wrote
a SQL interface to our application builder UNIREG.  mysqladmin & mysql
are programs that were largely influenced by their mSQL counterparts. We
have put a lot of effort into making the @strong{MySQL} syntax a
superset of mSQL. Much of the API:s ideas are borrowed from mSQL to make
it easy to port free mSQL programs to @strong{MySQL}. @strong{MySQL}
doesn't contain any code from mSQL. Two files
(@file{client/insert_test.c} and @file{client/select_test.c}) in the
distribution are non copyrighted files from the mSQL distribution
(Copyrighted David J. Hughes). These are included as a example of the
changes that must be done to change from mSQL to @strong{MySQL}.
@item Fred Fish
For his excellent C debugging and trace library. Monty has made a number
of smaller improvements to the library (speed and additional options).
@item Richard A. O'Keefe
For his public domain string library.
@item Henry Spencer
For his regex library, used in 'WHERE column REGEXP regexp'.
@item Free Software Foundation
From whom we got an excellent compiler (gcc) and for their libc from
which I have borrowed strto.c to get some code working in Linux. Also
readline for the client.
@item Free Software Foundation & The XEmacs development team
For a really great editor/environment used by almost everybody at tcx/detron.
@item Igor Romanenko (igor@@frog.kiev.ua)
mysqldump  (Previously msqldump but ported and enhanced by Monty)
@item Tim Bunce, Alligator Descartes
For the DBD (perl) interface.
@item Andreas Koenig <a.koenig@@mind.de>
For the perl interface to @strong{MySQL}
@item Eugene Chan <eugene@@acenet.com.sg>
For porting PHP to @strong{MySQL}.
@item Michael J. Miller Jr. <mke@@terrapin.turbolift.com>
For the growing @strong{MySQL} user manual. And a lot of
spelling/language fixes for the FAQ.
@item Giovanni Maruzzelli <maruzz@@matrice.it>
For porting iODBC (unix ODBC).
@item Chris Provenzano
Portable user level pthreads. From the copyright: This product includes
software developed by Chris Provenzano, the University of California,
Berkeley, and contributors.  We are currently using version 1_60_beta6
patched by Monty (se mit-pthreads/Changes-mysql).
@item Xavier Leroy <Xavier.Leroy@@inria.fr>
The author of LinuxThreads (used by @strong{MySQL} on Linux).
@item Zarko Mocnik <zarko.mocnik@@dem.si>
Sorting for Slovenian language and the cset.tgz module for easier adding
of other character sets.
@item Yves Carlier Yves.Carlier@@rug.ac.be
mysqlaccess ; A program to show how the access right for a user.
@item Rhys Jones <rhys@@wales.com> (And GWE Technologies Limited)
For the JODBC; A module to extract data from @strong{MySQL} with a Java
client.
@item Dr Xiaokun Kelvin ZHU <X.Zhu@@brad.ac.uk>
Futher development of the JDBC driver and other @strong{MySQL} related
JAVA tools.
@item James Cooper <pixel@@organic.com>
For setting up a searchable mailing list archive at his site.
@item Rick_Mehalick <Rick_Mehalick@@i-o.com>
For xmysql a graphical X client for @strong{MySQL}.
@item Doug Sisk <sisk@@wix.com>
For providing RPM packages of @strong{MySQL} for RedHat Linux.
@item Jochen Wiedmann <wiedmann@@neckar-alb.de>
Maintaining of the perl module DBD::mysql
@item Therrien Gilbert <gilbert@@ican.net>
French error messages.
@item Petr snajdr, <snajdr@@pvt.net>
Czech error messages.
@item Jaroslaw Lewandowski <jotel@@itnet.com.pl>
Polish error messages
@item Miguel Angel Fernandez Roiz
Spanish error messages
@item Roy-Magne Mo <rmo@@www.hivolda.no>
Norwegian error messages and testing of 3.21.#
@item Timur I. Bakeyev <root@@timur.tatarstan.ru
Russian error messages
@item David Sacerdote <davids@@secnet.com>
Ideas for secure checking of DNS hostnames
@item Gianmassimo Vigazzola" <qwerg@@mbox.vol.it> or <qwerg@@tin.it>
Port to Win32/NT.
@item Irena Pancirov <irena@@mail.yacc.it>
Win32 port with Borland compiler.
@item Wei-Jou Chen <jou@@nematic.ieo.nctu.edu.tw>
Some support for Chinese(BIG5) characters.
@item Zeev Suraski <bourbon@@netvision.net.il>
from_unixtime time formating, ENCRYPT() functions, and bison adviser.
Active mailing list member.
@item Luuk de Boer <luuk_de_boer@@pi.net>
Ported (and extended) the benchmark suite to DBI/DBD.
Some new date functions.
@item Jay Flaherty <fty@@utk.edu>
Big parts of the perl DBI/DBD section.
@end table

Other contributors, bugfinders and testers: James H. Thompson, Maurizio
Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar
Haneke, jehamby@@lightside, psmith@@BayNetworks.COM, 
duane@@connect.com.au, root@@dondra.ofc.psyber.com

And lots of bug report/patches from the folks on the mailing list.

And a big tribute to those that helps us answer question on the
mysql@@tcx.se mailing list.

@table @asis
@item "Daniel Koch" <dkoch@@amcity.com>
IRIX setup.
@item "Luuk de Boer" <luuk_de_boer@@pi.net>
Benchmark questions.
@item Tim Sailer <tps@@users.buoy.com>
DBD-mysql questions.
@item "Boyd Lynn Gerber (801) 250-O795 Work" <gerberb@@zenez.com>
SCO related questions.
@item "Mehalick RE (Richard)  at MSXSEPC" <RM186061@@shellus.com>
XmySQL releated questions and basic installation questions.
@item Zeev Suraski <bourbon@@netvision.net.il>
Apache module configuration questions (log & auth), PHP related
questions, SQL syntax related questions and other general questions.
@item Francesc Guasch <frankie@@citel.upc.es>
General questions
@item Jonathan J Smith <jsmith@@wtp.net>
Questions pertaining to OS specifics with Linux, SQL syntax, and other
things that might be needing some work.
@item David Sklar <sklar@@student.net>
Using @strong{MySQL} from PHP and Perl.
@item Alistair MacDonald <A.MacDonald@@uel.ac.uk>
Not yet specified, but is flexible and can handle Linux and maybe HP/UX.
Will try to get user to use mysqlbug.
@item John Lyon <jlyon@@imag.net>
Questions about installing @strong{MySQL} on Linux systems, using either
.rpms, or compiling from source.
@item "Lorvid Ltd." lorvid@@WOLFENET.com
Simple billing/license/support/copyright issues.
@item Patrick Sherrill <patrick@@coconet.com>
ODBC and VisualC++ interface questions.
@item Randy Harmon <rjharmon@@uptimecomputers.com>
DBD, Linux, Some SQL syntax questions.
@end table

@node News, Bugs, Credits, Top
@appendix @strong{MySQL} change history

@menu
* News-3.21.x::                 Changes in release 3.21.x
* News-3.20.x::                 Changes in release 3.20.x
* News-3.19.x::                 Changes in release 3.19.x
@end menu

@node News-3.21.x, News-3.20.x, News, News
@section Changes in release 3.21.x

@menu
* News-3.21.19::               Changes in release 3.21.19
* News-3.21.18::                Changes in release 3.21.18
* News-3.21.17::                Changes in release 3.21.17
* News-3.21.16::                Changes in release 3.21.16
* News-3.21.15::                Changes in release 3.21.15
* News-3.21.14b::               Changes in release 3.21.14b
* News-3.21.14a::               Changes in release 3.21.14a
* News-3.21.13::                Changes in release 3.21.13
* News-3.21.12::                Changes in release 3.21.12
* News-3.21.11::                Changes in release 3.21.11
* News-3.21.10::                Changes in release 3.21.10
* News-3.21.9::                 Changes in release 3.21.9
* News-3.21.8::                 Changes in release 3.21.8
* News-3.21.7::                 Changes in release 3.21.7
* News-3.21.6::                 Changes in release 3.21.6
* News-3.21.5::                 Changes in release 3.21.5
* News-3.21.4::                 Changes in release 3.21.4
* News-3.21.3::                 Changes in release 3.21.3
* News-3.21.2::                 Changes in release 3.21.2
* News-3.21.0::                 Changes in release 3.21.0
@end menu

@node News-3.21.19, News-3.21.18, News-3.21.x, News-3.21.x
@subsection Changes in release 3.21.19
@itemize @bullet
@item
Upgraded DBD to 1823. This version implements mysql_use_result in DBD-Mysql.
@item
Benchmarks updated for empress (by Luuk)
@item
Fixed a case of slow range searching.
@item
Configure fixes (Docs directory).
@item
Added function @code{REVERSE()} (by Zeev Suraski)
@end itemize

@node News-3.21.18, News-3.21.17, News-3.21.19, News-3.21.x
@subsection Changes in release 3.21.18
@itemize @bullet
@item
Give error message if client C functions are called in wrong order.
@item
Added automatic reconnect to the libmysql.c library. If a write command
fails a automatic reconnect is done.
@item
Small sort sets doesn't use temporary files anymore.
@item
Upgraded DBI to 0.91
@item
Fixed a couple of problems with LEFT OUTER JOIN.
@item
Added CROSS JOIN syntax. CROSS is now a reserved word.
@item
Recoded yacc/bison stack allocation to be even safer and allow @strong{MySQL}
to handle even bigger expressions.
@item
Fixed a couple of problems with the update log.
@item
ORDER BY was slow when used with key ranges.
@end itemize

@node News-3.21.17, News-3.21.16, News-3.21.18, News-3.21.x
@subsection Changes in release 3.21.17
@itemize @bullet
@item
Changed documentation string of --with-unix-socket-path to avoid confusion.
@item
Added ODBC and ANSI SQL style @code{LEFT OUTER JOIN}.
@item
The following are new reserved words: @code{LEFT}, @code{NATURAL},
@code{USING}
@item 
The client library is now using the environment variable
@code{MYSQL_HOST} as the default host if it's defined.
@item
@code{SELECT column, SUM(expr)} now returns @code{NULL} for column when
there are matching rows.
@item
Fixed problem with compare of binary strings and blobs with ASCII
characters over 127. 
@item
Fixed lock problem: When freeing a read lock on a table with multiple
read locks, a thread waiting for write lock would have given the lock.
This shouldn't affect data integrity, but could possible make mysqld
to restart if one thread was reading data that another thread modified.
@item
LIMIT offset,count didn't work in INSERT ... SELECT.
@item
Optimized key block caching. This will be quicker than the old one when
using bigger key caches.
@end itemize

@node News-3.21.16, News-3.21.15, News-3.21.17, News-3.21.x
@subsection Changes in release 3.21.16

@itemize @bullet
@item
Added ODBC 2.0 & 3.0 functions: @code{POWER()}, @code{SPACE()},
@code{COT()}, @code{DEGREES()}, @code{RADIANS()}, @code{ROUND(2 arg)}
and @code{TRUNCATE()}.
@item
@strong{WARNING INCOMPATIBLE CHANGE!!}. @code{LOCATE()} parameters where
swapped according to ODBC standard. Fixed.
@item
Added function @code{TIME_TO_SEC()}.
@item
In some cases default values was not used for @code{NOT NULL} fields.
@item
Timestamp wasn't updated in @code{UPDATE SET ...} if the timestamp was
used as.
@item
Allow empty strings as default values for @code{BLOB} and @code{TEXT} to
be compatible with mysqldump.
@end itemize      

@node News-3.21.15, News-3.21.14b, News-3.21.16, News-3.21.x
@subsection Changes in release 3.21.15

@itemize @bullet
@item
@strong{WARNING INCOMPATIBLE CHANGE!!} mysqlperl is now from
Msql-Mysql-modules. This means that the connect() now takes
host,database,user,password ! The old version took
host,database,password,user.
@item
Allow @code{DATE '1997-01-01'}, @code{TIME '12:10:10'} and
@code{TIMESTAMP '1997-01-01 12:10:10'} formats required by ANSI SQL.
@strong{WARNING INCOMPATIBLE CHANGE!!} This has the unfortunate
side-effect that one can't have columns named @code{DATE}, @code{TIME}
or @code{TIMESTAMP} anymore :( Old columns can only be accessed with
'tablename.columnname'!
@item
Changed Makefiles to hopefully work better with BSD systems. Also
manual.dvi is now included in the distribution to avoid having stupid
makes trying to rebuild it.
@item
Readline library upgraded to version 2.1
@item
A new sortorder german-1. That is a normal iso-latin1 with a german sort
order.
@item
Perl DBI/DBD is now included in the distribution. DBI is now the
recommended way to connect to @strong{MySQL} from perl.
@item
New portable benchmark suite with DBD, with test results from mSQL 2.0.3,
@strong{MySQL}, PostgreSQL 6.2.1 and Solid server 2.2.
@item
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
mSQL, postgreSQL, Solid and @strong{MySQL}.
@item
Fixed bug in range-optimizer that crashed mysql on some queries.
@item
Table and column name completion for mysql command line tool, by Zeev
Suraski and Andi Gutmans.
@item
Added new command @code{REPLACE}, which works like @code{INSERT} but
replaces conflicting records with the new record. @code{REPLACE INTO
TABLE ... SELECT ...} works also.
@item
Added new commands: @code{CREATE DATABASE db_name} and @code{DROP
DATABASE db_name}.
@item
Added @code{RENAME} option to @code{ALTER TABLE}: @code{ALTER TABLE name
RENAME AS new_name}.
@item
make_binary_distribution now includes libgcc.a in libmysqlclient.a. This
should make linking work for people without gcc.
@item
Changed @code{net_write()} to @code{my_net_write()} because of name
conflict with sybase.
@item
New function @code{DAYOFWEEK()} compatible with ODBC.
@item
Stack checking and bison memory overrun checking to get @strong{MySQL}
safer with weird queries.
@end itemize

@node News-3.21.14b, News-3.21.14a, News-3.21.15, News-3.21.x
@subsection Changes in release 3.21.14b

@itemize @bullet
@item
Fixed a couple of small configure problems on some platforms.
@end itemize

@node News-3.21.14a, News-3.21.13, News-3.21.14b, News-3.21.x
@subsection Changes in release 3.21.14a

@itemize @bullet
@item
Ported to SCO Openserver 5.0.4  with FSU-threads.
@item
HP-UX 10.20 should work.
@item
Added new functions DATE_FORMAT() and DATE_ADD_MM()..
@item
Added NOT IN.
@item
Added automatic removal of 'ODBC function conversions': @{fn now() @}
@item
Handle ODBC 2.50.3 option flags.
@item
Fixed compare of DATE and TIME with NULL. 
@item
Changed language name from germany to german to be consistent with
the other language names.
@item
Fixed sorting problem on functions returning a float. Before the values
was converted to a int before sorting.
@item
Fixed slow sorting when sorting on key field when using KEY_COLUMN=constant.
@item
SORTING on calculated DOUBLE values sorted on integer results instead.
@item
'mysql' doesn't need a database argument anymore.
@item
Changed the place where HAVING should be. According to ANSI it should be
after GROUP BY but before ORDER BY. @strong{MySQL} 3.20 had it wrongly
last.
@item
Added Sybase command: USE DATABASE to start using another database.
@item
Added automatic adjusting of number of connections and table cache size
if the maximum number of files that can be opened are less than needed.
This should fix that mysqld doesn't crash even if one hasn't done a
ulimit -n 256 before starting mysqld.
@item
Added lots of limit checks to make it safer when running with too little
memory or when doing weird queries.
@end itemize

@node News-3.21.13, News-3.21.12, News-3.21.14a, News-3.21.x
@subsection Changes in release 3.21.13

@itemize @bullet
@item
Added retry of interrupted reads and clearing of errno.
This makes Linux systems much safer!
@item
Fixed locking bug when using many alias on the same table in the same select.
@item
Fixed bug with LIKE on number key.
@item
New error message so one can check if the connection was lost while
the command was running or if the connection was down from the start.
@item
Added --table option to mysql to print in table format.
Moved time and row information after query result.
Added automatic reconnect of lost connections.
@item
Added != as an alias for <>.
@item
Added function VERSION() to make easier logs.
@item
New multi-user test 'tests/fork_test.pl' to put some strain on the
thread library.
@end itemize

@node News-3.21.12, News-3.21.11, News-3.21.13, News-3.21.x
@subsection Changes in release 3.21.12

@itemize @bullet
@item
Fixed ftruncate() call in MIT-threads. This made isamchk() destroy the .ISM
files on (Free)BSD systems 2.#
@item
Fixed broken __P_ patch in MIT-threads
@item
Many memory overrun checks. All string functions now return @code{NULL}
if the returned string should be longer than @code{max_allowed_packet}.
@item
Changed the name if the @code{INTERVAL} type to @code{ENUM}, because
@code{INTERVAL} is used in ANSI SQL.
@item
In some cases doing a JOIN + GROUP + INTO OUTFILE, the result wasn't
grouped.
@item
LIKE with '_' as last character didn't work. Fixed
@item
Added extended ANSI SQL @code{TRIM()} function.
@item
Added @code{CURTIME()}.
@item
Added @code{ENCRYPT()} function by Zeev Suraski.
@item
Fixed better @code{FOREIGN KEY} syntax skipping. New reserved words:
@code{MATCH}, @code{FULL}, @code{PARTIAL}
@item
mysqld now allows ip and hostname to the @code{--bind-address} option.
@item
Added "SET OPTION CHARACTER SET cp1251_koi8" to enable conversions off
data to/from cp1251_koi8.
@item
Lots of changes for Win95 port. In theory this version should now be
easily portable to Win95.
@item
Changed the create column syntax off @code{NOT NULL} to be after the
@code{DEFAULT} value as specified in the ANSI SQL standard. This will
make mysqldump with @code{NOT NULL} and default values incompatible with
@strong{MySQL} 3.20.
@item
Added a lot of function name alias so one can use the functions with
ODBC or ANSI SQL92 syntax.
@item
Fixed @code{ALTER TABLE person ALTER COLUMN phone SET DEFAULT NULL}
syntax.
@item
Added CHAR and BIT as a synonyms for CHAR(1)
@item
Fixed core dump when updating as user with only select privilege.
@item
INSERT ... SELECT ... GROUP BY didn't work in some cases. On got
'Invalid use of group function'
@item
When using LIMIT, SELECT now always uses keys instead of record scan.
This will give better performance on SELECT and a WHERE that matches many
rows.
@item
Added Russian error messages.
@item
In some cases doing a join + group + INTO OUTFILE, the result wasn't
grouped.
@end itemize

@node News-3.21.11, News-3.21.10, News-3.21.12, News-3.21.x
@subsection Changes in release 3.21.11

@itemize @bullet
@item
Configure changes.
@item
MySQL new works with the new thread library on BSDI 3.0.
@item
Added new group functions: BIT_OR() and BIT_AND().
@item
Added compatibility functions: CHECK, REFERENCES. CHECK is now a
reserved word.
@item
Added BIT as a synonym for CHAR(1) to get better compatibility.
@item
Added option ALL to GRANT for better compatibility. (GRANT is still
a dummy fuction.
@item
Added partly translated dutch messages.
@item
Fixed bug in ORDER BY and GROUP BY with NULL columns
@item
Added function last_insert_id() to retreive last auto_increment value.
This is for clients to ODBC that can't use the mysql_insert_id API function,
but can be used by any client.
@item
Added option '--flush-logs' to mysqladmin.
@item
Added command 'status' to mysql.
@item
Fixed problem with order/group by because of bug in gcc.
@item
Fixed problem with INSERT ... SELECT .. GROUP BY.
@end itemize

@node News-3.21.10, News-3.21.9, News-3.21.11, News-3.21.x
@subsection Changes in release 3.21.10

@itemize @bullet
@item
New mysqlaccess.
@item
CREATE supports now all ODBC types and the mSQL @code{TEXT} type. All
ODBC 2.5 functions is also supported (added REPAT). This gives better
portability.
@item
Added text types: @code{TINYTEXT}, @code{TEXT}, @code{MIDDLETEXT} and
@code{LONGTEXT}.  These are actually blobs, but all searching is done
case independent.
@item
All old @code{BLOB} fields are now @code{TEXT} fields.  This only
changes that all searching on strings are case independent. One have to
do a ALTER TABLE and change the field to BLOB if one wants to have tests
done case dependent.
@item
Fixed some configure issues.
@item
Made the locking code a bit safer. Fixed very unlikely
dead lock situation.
@item
Fixed a couple of bugs in the range optimizer. Now the new range benchmark
test-select works.
@end itemize

@node News-3.21.9, News-3.21.8, News-3.21.10, News-3.21.x
@subsection Changes in release 3.21.9

@itemize @bullet
@item
Added --enable-unix-socket=pathname arg to configure.
@item
Fixed a couple of portable problems with include files.
@item
Fixed bug in range calculation that could return empty
set when searching on multiple key with only one entry (very rare).
@item
Most things ported to FSU threads, which should allow @strong{MySQL} to
run on SCO. @xref{SCO}.
@end itemize

@node News-3.21.8, News-3.21.7, News-3.21.9, News-3.21.x
@subsection Changes in release 3.21.8

@itemize @bullet
@item
Works now in Solaris 2.6
@item
Added handling of calculation of sum() functions.
One can now use for example: SUM(column)/COUNT(column)
@item
Added handling of trigometric functions: PI(), ACOS(), ASIN(), ATAN(),
COS(), SIN() and TAN().
@item
New languages: norwegian, norwegian-ny and portuguese.
@item
Fixed parameter bug in net_print in procedure.cc.
@item
Fixed a cople of memory leaks.
@item
Now allow also the old SELECT ... INTO OUTFILE syntax.
@item
Fixed bug with group by and select on key with many values.
@item
mysql_fetch_lengths() returned sometimes wrong lengths when one used
mysql_use_result(). This affected at least some cases of mysqldump --quick.
@item
Allow TIME, DATE and TIMESTAMP as column names.
@item
Fixed bug in optimization of WHERE const op field.
@item
Fixed problem when sorting on NULL fields.
@item
Fixed a couple of 64bit (Alpha) problems
@item
Added option --pid-file=# to mysqld
@item
Added date formating to from_unixtime(), originally by Zeev Suraski.
@item
Fixed bug in BETWEEN in range optimizer (Did only test = of the first
argument).
@item
Added machine dependent files for mit-pthreads i386-SCO. There is probably
more to do to get this to work on SCO 3.5. 
@end itemize

@node News-3.21.7, News-3.21.6, News-3.21.8, News-3.21.x
@subsection Changes in release 3.21.7

@itemize @bullet
@item
Changed to Makefile.am to take advantage of automake 1.2.
@item
Added the beginnings of a benchmark suite.
@item
Added more secure password handling.
@item
Added new client function: mysql_errno() to get the error number of
the error message. This makes error checking in the client much easier.
This makes the new server incompatible with the 3.20.# server when running
without --old-protocol.  The client code is backward compatible.
More information can be found in the README file!
@item
Fixed some problems when using very long, illegal names.
@end itemize

@node News-3.21.6, News-3.21.5, News-3.21.7, News-3.21.x
@subsection Changes in release 3.21.6

@itemize @bullet
@item
Fixed more portability issues (wrong sigwait and sigset define)
@item
configure should now be able to detect the last argument to accept().
@end itemize

@node News-3.21.5, News-3.21.4, News-3.21.6, News-3.21.x
@subsection Changes in release 3.21.5

@itemize @bullet
@item
Should now work at FreeBSD 3.0 if one used the FreeBSD-3.0-libc_r-1.0.diff
which can be found at http://www.tcx.se/patches.
@item
Added new option to mysqld: -O tmp_table_size=#
@item
New function from_unixtime(timestamp) which returns a date string in
YYYY-MM-DD HH:MM:DD format.
@item
New function sec_to_time(seconds) which returns a string in H:MM:SS format.
@item
new function: substring_index(), originally by Zeev Suraski.
@end itemize

@node News-3.21.4, News-3.21.3, News-3.21.5, News-3.21.x
@subsection Changes in release 3.21.4

@itemize @bullet
@item
Should now configure and compile on OSF1 4.0 with the Dec compiler.
@item
configure and compile on BSD3.0 works, but due to some bugs in the
BSDI 3.0 mysqld doesn't work here yet.
@item
configure and compiles on FreeBSD 3.0, but I couldn't get pthread_create to
work.
@end itemize

@node News-3.21.3, News-3.21.2, News-3.21.4, News-3.21.x
@subsection Changes in release 3.21.3

@itemize @bullet
@item
Added reverse check lookup of hostnames to get better security.
@item
Fixed some possible buffer overflows if one uses too long filenames.
@item
mysqld doesn't accept hostnames that starts with digits followed by a '.'
because the hostname may look like a IP.
@item
Added option --skip-networking to only allow socket connections.
(This will not work with MIT threads!)
@item
Added check of too long table names for alias.
@item
Added check if database name is okey.
@item
Addded check if too long table names.
@item
Removed wrong free() that killed the server on 'create/drop database'.
@item
Changed the name of some mysqld -O options to better names.
@item
Added option '-O join_cache_size=#'.
@item
Added option '-O max_join_size=#' to be able to set a limit how big
queries (in this case big = slow) one should be able to handle without
specifying 'SQL_OPTION OPTION_BIG_SELECTS=1'.  A # = is about 10
examined records. The default is 'unlimited'.
@item
When comparing a TIME, DATE, DATETIME or TIMESTAMP column to a 
constant the constant is converted to a time value before comparing.
This will make it easier to get ODBC and particularly Access97 to work with
the above types. It should also make dates easier to use and the compares
should be quicker than before.
@item
Applied patch from Jochen Wiedmann that fixes that query() in mysqlperl
now can take queries with \0 in it.
@item
Store of timestamp with 2 digit year YYMMDD didn't work.
@item
Fix that timestamp isn't automaticly updated if set in a update clause.
@item
Now the automatic timestamp field is the FIRST timestamp field.
@item
SELECT * INTO OUTFILE, which didn't correctly if the outfile already existed.
@item
'mysql' now shows thread id when starting or doing a reconnect.
@item
Changed the default sort buffer size from 2M to 1M.
@end itemize

@node News-3.21.2, News-3.21.0, News-3.21.3, News-3.21.x
@subsection Changes in release 3.21.2

@itemize @bullet
@item
The range optimizer is cooded, but only 85% tested. It can be enabled with
--new, but it crashes core a lot yet...
@item
More portable. Should compile one AIX and alpha-digital.
At least the isam library should be relative 64 bit clean.
@item
New isamchk which can detect and fix more problems.
@item
New options for isamlog.
@item
Using new version of automake
@item
Many small portability changes (from the AIX and alpha-digital port)
Better checking of pthread(s) library.
@item
czech error messages by snajdr@@pvt.net
@item
'mysql' now shows thread id when starting or doing a reconnect.
@item
Decresed some buffers to get less problems on system with little memory.
Also added more checks to handle 'out of memory' problems
@item
mysqladmin: One can now do 'mysqladmin kill 5,6,7,8'
@item
When the max connection limit is reached, one extra connection by a user with
the PROCESS_ACL privilege is granted.
@item
Added new mysqld option: -O backlog=#
@item
Increased max packet size from 512K to 1024K for client.
@item
Almost all of the functions code is now tested in the intern test suite.
@item
ALTER TABLE now returns warnings from field conversions.
@item
Port changed to 3306 (got it reserved from ISI).
@item
Added a fix for Visual Fox Base so that any schema name from a table
specification is automaticly removed.
@item
New function ASCII.
@item
Removed the between() function. On should use the 'col BETWEEN a AND b'
syntax instead.
@item
MySQL now doesn't anymore have to use a extra temporary table when sorting
on functions or SUM functions.
@item
Fixed bug that one couldn't use 'table_name.field_name' in UPDATE.
@item
Fixed SELECT DISTINCT when using 'hidden group'. For example:
SELECT DISTINCT MOD(some_field,10) FROM test GROUP BY some_field;
Note: some_field is normally in the select part. ANSI SQL should require
it.
@end itemize

@node News-3.21.0,  , News-3.21.2, News-3.21.x
@subsection Changes in release 3.21.0

@itemize @bullet
@item
New keywords used: INTERVAL, EXPLAIN, READ, WRITE, BINARY
@item
Added ODBC functions CHAR(num,...) and ASCII(string).
@item
Removed function BETWEEN(a,b,c). One should use the standard ANSI SYNTAX:
expr BETWEEN expr AND expr.
@item
New operator IN. This uses a binary search to find a match.
@item
New command @code{LOCK TABLES table_name [AS alias] (READ | WRITE), ...}
@item
New server option @code{mysqld --log-update} to get a log suitable for
incremental updates
@item
new command: EXPLAIN SELECT ... to get info about how the optimzier
will do the join.
@item
For easier client code, the client shouldn't anymore use
@code{FIELD_TYPE_TINY_BLOB}, @code{FIELD_TYPE_MEDIUM_BLOB},
@code{FIELD_TYPE_LONG_BLOB} or @code{FIELD_TYPE_VAR_STRING} (as
previously returned by mysql_list_fields).  One should instead only use
@code{FIELD_TYPE_BLOB} or @code{FIELD_TYPE_STRING}.  If one wants exact
types one should use the command @code{SHOW FIELDS} .
@item
Added varbinary syntax: @code{0x######} which can be used as a string
(default) or a number.
@item
@code{FIELD_TYPE_CHAR} is renamed to @code{FIELD_TYPE_TINY}.
@item
Changed all fields to C++ classes.
@item
Removed FORM struct.
@item
A field with a @code{DEFAULT} doesn't have to be @code{NOT NULL}
anymore.
@item
New field types:
@table @code
@item INTERVAL
A string with only can take a couple of defined values. The value is
stored as a 1-3 byte number that automaticly is mapped to a string.
This is sorted according to string positions!
@item SET
A string with may have one or many string values separated with ','.
The string is stored as a 1,2,3,4 or 8 byte number where each bit stands
for a specific string.  This is sorted according to unsigned bit value
if SET.
@end table
@item
Now all function calculation is done with double or long long.  This
will give one the full 64 bits range with bit functions and fix some
conversions that previously could give precision losses.  One should
avoid using 'unsigned long long' columns with full 64 bits range
(numbers bigger than 9223372036854775807) because calculations is done
with signed long long.
@item
ORDER BY  will now put NULL fields first. GROUP BY will also work with NULL.
@item
Full WHERE with expressions.
@item
New range optimizer with can resolve ranges when some prefix keypart is
constant. Example:
SELECT * FROM table_name WHERE key_part_1="customer" and key_part_2 >= 10 AND
key_part_2 <= 10)
@end itemize

@node News-3.20.x, News-3.19.x, News-3.21.x, News
@section Changes in release 3.20.x

Changes from 3.20.18 to 3.20.32b are not documented here since the the
3.21 release bransched here. And the relevant changes are also
documented as changes to the 3.21 version.

@menu
* News-3.20.18::                Changes in release 3.20.18
* News-3.20.17::                Changes in release 3.20.17
* News-3.20.16::                Changes in release 3.20.16
* News-3.20.15::                Changes in release 3.20.15
* News-3.20.14::                Changes in release 3.20.14
* News-3.20.13::                Changes in release 3.20.13
* News-3.20.11::                Changes in release 3.20.11
* News-3.20.10::                Changes in release 3.20.10
* News-3.20.9::                 Changes in release 3.20.9
* News-3.20.8::                 Changes in release 3.20.8
* News-3.20.7::                 Changes in release 3.20.7
* News-3.20.6::                 Changes in release 3.20.6
* News-3.20.3::                 Changes in release 3.20.3
* News-3.20.0::                 Changes in releases 3.20.0
@end menu

@node News-3.20.18, News-3.20.17, News-3.20.x, News-3.20.x
@subsection Changes in release 3.20.18

@itemize @bullet
@item
Added -p# (remove # directories from path) to isamlog.
All files are written with a relative path from the database directory
Now mysqld shouldn't crash on shutdown when using --log-isam. 
@item
New mysqlperl version. Is now compatible with msqlperl-0.63.
@item
New DBD module available in Contrib/
@item
Added group function STD() (standard derivation).
@item
The mysql server is now by default compiled without debugging information.
This will make the demon smaller and faster.
@item
Now one usually only have to give --basedir to mysqld. All other paths
are relative in a normal installation.
@item
BLOBs contained sometimes garbage when used with a SELECT on more than
one table and ORDER BY.
@item
Fixed that calculations that are not in GROUP BY works as expected.
(ANSI SQL extension)
Example: SELECT id,id+1 FROM table GROUP BY id
@item
The test of using MYSQL_PWD was reversed. Now MYSQL_PWD is enabled as default
in the default release.
@item
Fixed convert bug which got mysqld to core dump with Aritmetic error on
Sparc-386
@item
Added option --unbuffered to mysql. (For new mysqlaccess)
@item
When using overlapping (unnecessary keys) and join over many tables
the optimizer could get confused and return 0 records.
@end itemize

@node News-3.20.17, News-3.20.16, News-3.20.18, News-3.20.x
@subsection Changes in release 3.20.17

@itemize @bullet
@item
One can now use BLOBs columns and the functions IS NULL and IS NOT NULL
in the WHERE clause.
@item
All communication packages and row buffers are now alloced dynamicly on
demand. The default @code{max_allowed_packet} is now 65K for the server
and 512K for the client. This is mainly used to catch wrong packets that
could trash all memory. The server limit may be changed when it is
started.
@item
Changed stack usage to use less memory.
@item
Changed safe_mysqld to check for running demon.
@item
The @code{ELT()} function is renamed to @code{FIELD()}.  The new
@code{ELT()} function returns a value based on a index: @code{FIELD()}
is the invers of @code{ELT()} Example: @code{ELT(2,"A","B","C")} returns
@code{"B"}. @code{FIELD("B","A","B","C")} returns @code{2};
@item
COUNT(field) where field could have a NULL value now works.
@item
A couple of bug fixed in SELECT .. GROUP BY.
@item
Fixed memory overrun bug in WHERE with many unoptimizable brace levels.
@item
Fixed some small bugs in the grant code.
@item
If hostname isn't found by get_hostname, only the IP is checked. Before one
one got 'Access denies'
@item
Inserts of timestamps with values didn't always work.
@item
INSERT INTO ... SELECT .. WHERE could give the error
'Dupplicated field'
@item
Added some tests to safe_mysqld to make it 'safer'
@item
LIKE was case sensitive in some places and case insensitive in other.
Now @code{LIKE} is always case insensitive.
@item
mysql.cc; Allow '#' anywhere on the line.
@item
New command 'SET OPTION SQL_SELECT_LIMIT=#'. Se the FAQ for more details.
@item
New version of the mysqlaccess script
@item
Change from_days() and weekday() to also take a full timestamp or
a datetime as argument. Before they only took a number of type YYYYMMDD or
YYMMDD.
@item
Added new function unix_timestamp(timestamp_column);
@end itemize

@node News-3.20.16, News-3.20.15, News-3.20.17, News-3.20.x
@subsection Changes in release 3.20.16

@itemize @bullet
@item
More changes in MIT threads to get them safer. Fixed also some link
bugs at least in SUNOS.
@item
Changed mysqld to go around a bug in MIT threads. This makes multiple
small selects 20 times faster. Now lock_test.pl should work.
@item
Added mysql_FetchHash(handle) to mysqlperl
@item
The mysqlbug script is now distributed built to allow for reporting
bugs that appear during the build with it.
@item
Changed libmysql.c to prefer to use getpwuid() insted of cuserid().
@item
Fixed bug in select optimizer when using many tables with the same
column used as key to different tables.
@item
mysql.cc; Allow '#' anywhere on the line.
@item
Added new latin2 and Russian KOI8 character tables.
@item
Added support for a dummy GRANT command satisfy Powerbuilder.
@end itemize

@node News-3.20.15, News-3.20.14, News-3.20.16, News-3.20.x
@subsection Changes in release 3.20.15

@itemize @bullet
@item
Fixed fatal bug 'packets out of order' when using MIT threads. 
@item
Removed possible loop when thread waits for command from client
and fcntl() fails. Thanks to Mike Bretz for finding this bug 
@item
Changed alarm loop in mysqld.cc because shutdown didn't always
succeed in Linux.
@item
Removed use of termbits from mysql.cc  This conflicted with glibc 2.0
@item
Fixed some syntax errors for at least BSD and Linux.
@item
Fixed bug when doing a select as superuser without a database.
@item
Fixed bug when doing SELECT with group calculation to outfile.
@end itemize

@node News-3.20.14, News-3.20.13, News-3.20.15, News-3.20.x
@subsection Changes in release 3.20.14

@itemize @bullet
@item
If one gives '-p' or -password to mysql without an argument,
the password will be asked from the tty.
@item
Added default password from MYSQL_PWD. (by Elmar Haneke)
@item
Added commando 'kill' to mysqladmin to kill a specific mysql thread.
@item
Sometimes when doing a reconnect on a down connection this succeeded
first on second try.
@item
Fixed adding a auto_increment key with ALTER_TABLE.
@item
AVG() gave too small value on some selects with GROUP BY and ORDER BY.
@item
Added new DATETIME type (by Giovanni Maruzzelli <maruzz@@matrice.it>)
@item
Fixed that define 'DONT_USE_DEFAULT_FIELDS' works
@item
Changed to use a thread to handle alarms instead of signals on Solaris to
avoid race conditions.
@item
Fixed default length of signed numbers. (George Harvey <georgeh@@pinacl.co.uk>)
@item
Allow anything for CREATE INDEX.
@item
Add prezeros when packing numbers to DATE, TIME and TIMESTAMP.
@item
Fixed a bug in OR of multiple tables (Gave empty set).
@item
Added many patches to MIT threads. This fixes at least one lookup bug.
@end itemize

@node News-3.20.13, News-3.20.11, News-3.20.14, News-3.20.x
@subsection Changes in release 3.20.13

@itemize @bullet
@item
Added ANSI SQL94 DATE and TIME types.
@item
Fixed bug in select with and-or levels.
@item
Added support for Slovenian characters. The Contrib directory contains
source and instructions to add other character sets.
@item
Fixed bug with limit and order by.
@item
Allow order and group on items that isn't in the select list.
(Thanks to Wim Bonis <bonis@@kiss.de> for pointing this out) 
@item
Allow setting of timestamp values in INSERT.
@item
Fixed bug with SELECT ... WHERE ... = NULL.
@item
Added changes for glibc 2.0. To get glibc to work one should add the
gibc-2.0-sigwait-patch before compiling glibc.
@item
Fixed bug in alter table when changeing a not null field to allow NULLs.
@item
Added some ANS92 synonyms as field types to CREATE TABLE.
CREATE TABLE now allows FLOAT(4) and FLOAT(8) to mean FLOAT and DOUBLE.
@item
new utility program mysqlaccess by Yves.Carlier@@rug.ac.be.
This program shows the access rights for a specific user and the grant
rows which determinate this grant.
@item
Added WHERE const op field (by bonis@@kiss.de)
@end itemize

@node News-3.20.11, News-3.20.10, News-3.20.13, News-3.20.x
@subsection Changes in release 3.20.11

@itemize @bullet
@item
When using SELECT ... INTO OUTFILE all temporary tables are ISAM instead of
HEAP to allow big dumps.
@item
Changed date functions to be 'string functions'. This fixed some 'funny'
side effects when sorting on dates.
@item
Extended ALTER TABLE according to SQL92.
@item
Some minor compability changes.
@item
Added --port and --socket to all utility programs and mysqld.
@item
Fixed MIT threads readdir_r(). Now mysqladmin create database and drop
database should work.
@item
Changed MIT threads to use our tempnam. This should fix the 'sort aborted' bug.
@item
Added sync of records count in sql_update. This fixed slow updates on first
connection. (Thanks to Vaclav Bittner for the test)
@end itemize

@node News-3.20.10, News-3.20.9, News-3.20.11, News-3.20.x
@subsection Changes in release 3.20.10

@itemize @bullet
@item
New insert type: INSERT INTO ... SELECT ...
@item
mediumblob fixed.
@item
Fixed bug in ALTER TABLE and BLOBs.
@item
SELECT ... INTO OUTFILE now creates the file in the current database directory.
@item
DROP TABLE can now take a list of tables.
@item
Oracle synonym DESCRIBE (DESC)
@item
Changes to make_binary_distribution
@item
Added some comments about conifgures c++ link test to installation
instructions.
@item
Added --without-perl to configure.
@item
Lot's of small portability changes.
@end itemize

@node News-3.20.9, News-3.20.8, News-3.20.10, News-3.20.x
@subsection Changes in release 3.20.9

@itemize @bullet
@item
Alter table didn't copy null bit. This resulted that NULL fields where
always NULL.
@item
CREATE didn't take numbers as DEFAULT.
@item
Some compatibility changes for SunOS.
@item
Removed config.cache from old distribution.
@end itemize

@node News-3.20.8, News-3.20.7, News-3.20.9, News-3.20.x
@subsection Changes in release 3.20.8

@itemize @bullet
@item
Fixed bug with ALTER TABLE and multi part keys.
@end itemize

@node News-3.20.7, News-3.20.6, News-3.20.8, News-3.20.x
@subsection Changes in release 3.20.7

@itemize @bullet
@item
New commands: ALTER TABLE, SELECT ... INTO OUTFILE and LOAD DATA INFILE.
@item
New functions: NOW()
@item
Added new field: file_priv to mysql/user table.
@item
New scripts 'add_file_priv' which add the new field 'file_priv'
to the user table. This scripts must be executed if one wants to
use the new SELECT ... INTO and LOAD DATA INFILE...  commands
with a version of mysql less than 3.20.7.
@item
Fixed bug in locking code, with made lock_test.pl test fail.
@item
new files NEW and BUGS
@item
Changed select_test.c and insert_test.c to include config.h
@item
Added command 'status' to mysqladmin for short logging.
@item
Increased max keys to 16 and max key parts to 15.
@item
Use of sub keys. A key may now be a prefix of a string field.
@item
Added option -k for mysqlshow to get key info for table.
@item
Added long options to mysqldump.
@end itemize

@node News-3.20.6, News-3.20.3, News-3.20.7, News-3.20.x
@subsection Changes in release 3.20.6

@itemize @bullet
@item
Portable to more systems because of MIT threads. This will
automatically be used is configure can not find a -lpthreads library.
@item
GNU style long options to almost all programs. Test with 'program --help'.
@item
Some shared library support for linux.
@item
The FAQ is now in .texi format and is available in .html, .text, .ps,
@item
Added new sql function RAND([init])
@item
Changed sql_lex to handle \0 unquoted, but the client can't send
the query through the C api, because it takes a str pointer.
one have to use mysql_real_query() to send the query.
@item
Added API function: mysql_get_client_info
@item
mysqld now uses the N_MAX_KEY_LENGTH from nisam.h as the max allowed key
length.
@item
The following now works: "select filter_nr,filter_nr from filter order by
filter_nr"
Before you got the error: "Column: 'filter_nr' in order clause is ambiguous"
@item
mysql now outputs \0 \t \n and \\ when writing tab separated output.
when encountering ascii 0, tab, newline or \. This is to allow printing of
binary data in a portable format.
To get old behavior use -r (or --raw).
@item
Added german error messages (60 of 80 error messages translated)
@item
Added new api function: mysql_fetch_lengths(MYSQL_RES *) which
returns a array of of column lengths (of type uint).
@item
Fixed bug with IS NULL in where clause.
@item
Changed the optimizer a little to get better results when searching on a key
part.
@item
Added select option STRAIGHT_JOIN to tell the optimizer that it should join
tables in the given order.
@item
Added support of comment starting with '--' in mysql.cc (Postgres syntax)
@item
You can have select_expressions and table columns in a select which
are not used in the group part. This makes it efficient to implement lookups.
The used column should be a constant for each group because the value is
calculated only calculated once for the first found row in a group.
@example
SELECT id,lookup.text,sum(*) FROM test,lookup
WHERE test.id=lookup.id group by id;
@end example
@item
Fixed bug in SUM(function) (Could make core dump)
@item
Changed auto_increment according to SQL_SYNTAX:
INSERT into table (auto_field) values (0) inserted 0, but the SQL_SYNTAX
stated it should insert a auto_increment value.
@item
mysqlshow.c: Added number of records in table. Had to change the
client code a little to fix this.
@item
mysql now allows double '' or "" in strings for embedded ' or ".
@item
New math functions:  EXP, LOG, SQRT, ROUND, CEILING
@end itemize

@node News-3.20.3, News-3.20.0, News-3.20.6, News-3.20.x
@subsection Changes in release 3.20.3

@itemize @bullet
@item
The configure source now compiles a thread free client library
@code{-lmysqlclient}. This is the only library that needs to be linked
with client applications.  When using the binary releases one have to
link with @code{-lmysql -lmysys -ldbug -lstrings} as before.
@item
New readline from bash-2.0.
@item
LOTS of small changes to configure and makefiles (and related source).
@item
There should now be possible to compile in another directory using
vpath. Tested with GNU Make 3.75.
@item
safe_mysqld and mysql.server changed to be more compatible between
the source and the binary releases.
@item
LIMIT takes now one or two numerical arguments.
If one argument the argument indicates the maximum number of rows in
a result. If two arguments the first arguments says the offset to
the first row to return, the second is the maximum number of rows.
With this it's easy to do a poor mans next page/previous page www
application.
@item
Changed name of SQL function FIELDS to ELT.
Changed sql function INTERVALL() to INTERVAL().
@item
Made SHOW COLUMNS a synonym for SHOW FIELDS.
Added compatibility syntax FRIEND KEY to create table. This creates in mysql
a non unique key on the given columns.
@item
Added CREATE INDEX and DROP INDEX as compatibility functions. In mysql 
CREATE INDEX only checks if the index exists and gives an error if it doesn't
exists. DROP INDEX always succeeds.
@item
mysqladmin.c: Added client version to version info.
@item
Fixed core dump bug in sql_acl (core on new connection).
@item
Removed host,user and db tables from database test in the distribution.
@item
FIELD_TYPE_CHAR can now be signed (-128 - 127) or unsigned (0 - 255)
Before it was always unsigned.
@item
Bug fixes in concat(), weekday()
@item
Changed a lot of source to get mysqld to be compiled with SUNPRO
compiler.
@item
SQL functions must now have a '(' directly after the function name.
user '(' is now regarded as an identifier and a '('
@end itemize

@node News-3.20.0,  , News-3.20.3, News-3.20.x
@subsection Changes in release 3.20.0

@itemize @bullet
@item
The source distribution is done with configure and automake:
It will make porting much easier.  Readline is included in the
distribution.
@item
Separate client compilation:
The client code should be very easy to compile on system which
doesn't have threads.
@item
The old perl interface code is automaticly compiled and installed.
Automatic compiling of DBD will follow when the new DBD code is ported.
@item
Dynamic language support: mysqld can now be started with Swedish
or English (default) error messages.
@item
new functions: INSERT(),RTRIM(),LTRIM() and FORMAT(). 
@item
mysqldump now works correctly for all field types (even
auto_increment). The format for 'show fields from table' is changed
so the 'type' column contains info suitable for 'CREATE TABLE'.
In previous releases some CREATE TABLE info had to be patched to
when recreating tables
@item
Some parser bugs from 3.19.5 (blob and timestamp) are corrected.
Timestamp now returns different date info depending of it's
create length.
@item
Changed parser to allow a database name, table name and field name to
start with a number or '_'.
@item
All old C code from UNIREG changed to c++ and cleaned up. This makes
the demon a little smaller and easier to understand.
@item
A lot of small bug fixes done.
@item
New INSTALL files (not final version) and some info regarding porting.
@end itemize

@node News-3.19.x,  , News-3.20.x, News
@section Changes in release 3.19.x

@menu
* News-3.19.5::                 Changes in release 3.19.5
* News-3.19.4::                 Changes in release 3.19.4
* News-3.19.3::                 Changes in release 3.19.3
@end menu

@node News-3.19.5, News-3.19.4, News-3.19.x, News-3.19.x
@subsection Changes in release 3.19.5

@itemize @bullet
@item
Some new functions, some more optimization on joins.
@item
Should now compile clean on Linux (2.0.x)
@item
Added functions DATABASE(),USER(),POW(),LOG10() (needed for ODBC).
@item
In a WHERE with a ORDER BY on fields from only one table the table is
now preferred as first table in a multi-join.
@item
HAVING and IS NULL or IS NOT NULL now works.
@item
A group on one column and a sort on a group function (SUM,AVG...)
didn't work together. Fixed.
@item
mysqldump: Didn't send password to server.
@end itemize

@node News-3.19.4, News-3.19.3, News-3.19.5, News-3.19.x
@subsection Changes in release 3.19.4

@itemize @bullet
@item
Fixed horrible locking bug when inserting in one thread and reading
on another thread.
@item
Fixed one-off decimal bug.  1.00 was outputed as 1.0
@item
Added attribute 'Locked' to process list as info if a query is
locked by another query.
@item
Fixed full magic timestamp. Timestamp length may now be 14,12,10,8,6,4 or 2.
@item
sort on some number functions could be sorted wrong on last number.
@item
if(arg,syntax_error,syntax_error) crashed.
@item
added functions ceiling() and round(), exp(), log() and sqrt()
@item
enchanted BETWEEN to handle strings.
@end itemize

@node News-3.19.3,  , News-3.19.4, News-3.19.x
@subsection Changes in release 3.19.3

@itemize @bullet
@item
Fixed that select with grouping on blob's doesn't return wrong blob
info. grouping, sorting and distinct on blobs will not yet work as
expected (Probably it will group/sort by the first 7 characters in the
blob). Groping on formulas with a fixed string size (use mid on blob)
should work.
@item
When doing a full join (no direct keys) on multiple tables with blob
fields, the blob was garbage on output.
@item
Fixed distinct with calculated columns.
@end itemize

@node Bugs, Todo, News, Top
@appendix Known errors and design deficiencies in @strong{MySQL}

@itemize @bullet
@item
You can not build in another directory when using
mit-pthreads. Since this requires changes to mit-pthreads we are not
likely to fix this.
@item
HAVING can only use fields in select expression list. Functions must be
aliased.
@item
Blobs can't 'reliably' be used in @code{GROUP BY} or @code{ORDER BY} or
@code{DISTINCT}. Only the first @code{max_sort_length} (default 1024)
are used when comparing blobs in these cases.  This can be changed with
the @code{-O max_sort_length} parameter to mysql. A workaround for most
cases is to use a substring: @code{SELECT DISTINCT LEFT(blob,2048) FROM
table}.
@item
Calculation is done with @code{bigint} or @code{double} (both are
normally 64 bit long). It depends on the function which precision one
gets. The general rule is that bit functions are done with bigint
precision, IF, and ELT() with bigint or double precision and the rest
with double precision.
@item
All field types are fixed point fields. That means one must specify how
many decimals a floating point field shall have. All results will be
returned with the correct number of decimals.
@item
All string columns, except BLOBS, have automatically all end spaces
removed when retrieved. For CHAR types this is ok may be regarded as a
feature according to ANSI SQL92. The bug is that VARCHAR columns are
treated the same way. And a compare with a string constat should remove
spaces too. For example the following query never returns anything if
name isn't a BLOB.  @code{SELECT * FROM table WHERE name = 'david '}
@end itemize

For platform specific bugs see the sections about compiling and porting.

@node Todo, Porting, Bugs, Top
@appendix List of thing we want to add to @strong{MySQL} in the future.

Everything in this list is in the order it will be done.  If you want to
affect the priority order, please register a licence or support us and
tell us what you want to have done more quickly. @xref{Licensing and Support}.

@section Things what has to be done in the real near future.

@itemize @bullet
@item
Benchmarks.
@item
WIN95 port
@item
FreeBSD and MIT-threads;  Do sleeping threads take CPU?
@item
Allow join on key parts (optimizing issue).
@item
Check why 'delete' uses 'record check'
@item
Fix that BETWEEN recognizes binary strings. Now BETWEEN is case
insensitive.
@item
Fix that temporary HEAP tables is automatically converted to NISAM if
they get too big. At the moment one gets 'error 135' if one does a query
which has to use a big temporary table.
@item
Add EXTRACT function
@item
Subqueries. 'select id from t where grp in (select grp from g where u > 100)'
@item
Change conv_blob to handle blob as a text field.
@item
Entry for DECRYPT() and ENCRYPT();
@item
Fix libmysql.c to allow two mysql_query() commands in a row without
reading results or give a nice error message when one does this.
@item
Remember FOREIGN key definitions in the .frm file.
@item
Add date formating to now().
@item
Add GET_LOCK and RELEASE_LOCK commands to implement application level
locking. These locks are thought be tagged to a string to allow one to
use it in a very wide range of applications.  The locks would be saved
in memory in the server and implemented with mutex for high speed.
@item
Optimzie BIT type to take 1 bit (now BIT takes 1 char).
@item
Check why MIT-threads ctime() doesn't work on some FreeBSD systems.
@item
Check if locked threads take any cpu.
@item
Add ORDER BY to update. This would be handy with functions like:
generate_id(start,step).
@end itemize

@section Things that have to be done sometime.

@itemize @bullet
@item
Implement a table optimizer by a analyze procedure call that returns a
table like show fields with min and max value and the best
@strong{MySQL} type for that expression.
@item
get_changed_tables(timeout,table1,table2,...)
@item
Change the protocol to add more bits to field information.  For example
AUTO_INCREMENT.
@item
Optimize MIN() and MAX() to use keys for quick return.
@item
New function: LAST_UPDATED(table_name)
@item
Atomic updates; This includes a language that one can even use for
stored procedures.
@item
Change reading through tables to use memmap when possible. Now only
compressed tables use memmap.
@item
Make a SQL standard GRANT command with @strong{MySQL} extensions.
@item
Change CREATE INDEX to use ALTER TABLE or add secondary indexes.
@item
Change DROP INDEX to use ALTER TABLE or use secondary indexes.
@item
Add a new privilege 'Show_priv' for 'SHOW' commands.
@item
Make the automatic timestamp code nicer.  Add timestamps to the update
log with SET TIMESTAMP=#;
@item
Optimize the autoincrement code.
@item
Use read/write mutex in some places to get more speed.
@item
Full foreign key support. One probably wants to implement a procedural
language first.
@item
Simple views (first on one table, later on any expression).
@item
Add DISTINC qualifier to COUNT(), SUM()...
@item
When one finds a field=#, change all occurrence of field to #.  Now this
is only done for some simple cases.
@item
Change all const expression with calculated expressions if possible.
@item
Optimize key = expression. At the moment only key = field or key =
constant are optimized.
@item
Join some of the copy functions for nicer code.
@item
Change sql_yacc.y to an inline parser to get down it's size and get
better error messages (5 days)
@item
Change the parser to use only one rule per different number of arguments
in function.
@item
Use of full calculation names in the order part. (For ACCESS97)
@item
SQL_OPTION MAX_SELECT_TIME=#to put a time limit on a query.
@item
Fix sorting and grouping of blobs (partly solved now).
@item
Make the update log to a database.
@item
Negative LIMIT to retrieve data from the end.
@item
Alarm round client connect/read/write functions.
@item
Add own hostname-ip memory table for cached reverse name lookup.
@item
Make a mysqld version which isn't multithreaded (2-4 days).
@item
Please note the changes to safe_mysqld: according to FSSTND (which
Debian tries to follow) PID files should go into /var/run/<progname>.pid
and log files into /var/log. It would be nice if you could put the
"DATADIR" in the first declaration of "pidfile" and "log", so the
placement of these files can be changed with a single statement.
@end itemize

Time is given according to amount of work, not real time. TcX's main
business is the use of @strong{MySQL} not the development of it. But
since TcX is a very flexible company and we have put a lot of resources
into the development of @strong{MySQL}.

@section Some things we don't have any plans to do.

@itemize @bullet
@item
Transactions with rollback (we mainly do selects, and because we don't
do transactions we can be much quicker on everything else). We will
support some kind of atomic operations on multiple tables
though. Currently atomic operations can be done with @code{LOCK
TABLES}/@code{UNLOCK TABLES} but we will make this more automatic in the
future.
@end itemize

@node Porting, Regexp, Todo, Top
@appendix Comments on porting to other systems.

A working Posix thread library is needed for the server. On Solaris 2.5
we use SUN PThreads (the native thread support in 2.4 and earlier
versions are not good enough) and on Linux we use LinuxThreads by Xavier
Leroy @email{Xavier.Leroy@@inria.fr}.

The hard part of porting to a new UNIX variant without good native
thread support is probably to port MIT threads. See
@file{mit-pthreads/README} and
@uref{http://www.humanfactor.com/pthreads/, Programming POSIX Threads}.

The @strong{MySQL} distribution includes a patched version of
Provenzano's Pthreads from MIT (see
@uref{http://www.mit.edu:8001/people/proven/pthreads.html, MIT Pthreads
web page}). This can be used for some operating systems that does not
have posix threads.

It is also possible to use another user level thread package named FSU
Pthreads (see
@uref{http://www.informatik.hu-berlin.de/~mueller/pthreads.html, FSU
pthread home page}). This implementation is being used for the SCO port.

See the @file{thr_lock.c} and @file{thr_alarm.c} programs in the mysys
directory for some tests/examples of these problems

Both the server and the client needs a working C++ compiler (we use gcc
and have tried SparcWorks). Other compiler that is known to work is the
IRIX cc.

To compile only the client use @file{./configure --without-server}

There currently no support for only compiling the server. Nor is it
likly to be added unless someone has a good reason for it.

If you want/need to change any Makefile or the configure script you must
get automake and autoconf. We have used autoconf-2.12 and automake-1.2.

All steps needed to remake everything from the most basic files.

@example
/bin/rm */.deps/*.P
/bin/rm -f config.cache
aclocal
autoheader
aclocal
automake
autoconf
./configure --with-debug=yes --prefix='your installation directory'

# The makefiles generated above needs GNU make (called gmake below)
gmake clean all install init-db
@end example

@menu
* Debugging::                   Debugging @strong{MySQL}
* RTS-threads::                 Comments about RTS threads:
* Thread packages::             What is the difference between different thread packages?
@end menu

@node Debugging, RTS-threads, Porting, Porting
@section Debugging @strong{MySQL}

If you have some very specific problem, you can always try to debug
MySQL.

Start the mysql server with a trace log in /tmp/mysql.trace. The log
file will get very @emph{BIG}.

@code{mysqld --debug}

or you can start it with 

@code{mysqld --debug=d,info,error,query,general,where:O,/tmp/mysql.trace}

which only prints information with the most interesting tags.

@node RTS-threads, Thread packages, Debugging, Porting
@section Comments about RTS threads:

I have tried to use the RTS thread packages with @strong{MySQL} but
stumbled on the following problems:

They use old version of a lot of POSIX calls and it is very tedious to
make wrappers for all functions. I am inclined to think that it would
be easier to change the thread libraries to the newest POSIX
specification.

Some wrappers are already written. Se mysys/my_pthread.c for more info.

At least the following should be changed:

pthread_get_specific should use on argument.
sigwait should take two arguments.
A lot of functions (at least pthread_cond_wait, pthread_cond_timedwait)
should return the error code on error. Now they return -1 and set errno.

Another problem is that user level threads uses the ALRM signal and this
aborts a lot of functions (read, write, open...). @strong{MySQL} should
do a retry on interrupt on all of these but it not that easy to verify
it.

The biggest unsolved problem is the following:

To get thread_level alarms I changed mysys/thr_alarm.c to wait between
alarms with pthread_cond_timedwait() but this aborts with error EINTR.
I tried to debug the thread library why this happens but couldn't find
any easy solution.

If someone wants to try @strong{MySQL} with RTS threads I suggest the
following:

@itemize @bullet
@item
Change functions @strong{MySQL} uses from the thread library to POSIX.
This shouldn't take that long.
@item
Compile all libraries with the -DHAVE_rts_threads.
@item
Compile thr_alarm
@item
If there is some small differences in the implementation they may be fixed
by changing my_pthread.h and my_pthread.c
@item
Run thr_alarm. If it runs without any 'warning', 'error' or aborted messages
you are one the right track. Here follows an successful run on Solaris:
@example
Main thread: 1
Tread 0 (5) started
Thread: 5  Waiting
process_alarm
Tread 1 (6) started
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Sleeped for 1 (1) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Sleeped for 2 (2) sec
Thread: 6  Simulation of no alarm needed
Thread: 6  Sleeped for 0 (3) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Sleeped for 4 (4) sec
Thread: 6  Waiting
process_alarm
thread_alarm
Thread: 5  Sleeped for 10 (10) sec
Thread: 5  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Sleeped for 5 (5) sec
Thread: 6  Waiting
process_alarm
process_alarm

...
thread_alarm
Thread: 5  Sleeped for 0 (1) sec
end
@end example
@end itemize

@node Thread packages,  , RTS-threads, Porting
@section What is the difference between different thread packages?

@strong{MySQL} is very dependent on the used thread package. So when
choosing a good platform for @strong{MySQL} the thread package is very
important.

There are at least three types of thread packages.

@itemize @bullet
@item
User threads in a single process. Thread switching is managed with
alarms and the threads library manages all not thread- safe functions
with locks. Read, write and select are usually managed with a
thread-specific select that switches to another thread if the running
threads have to wait for data.  If the user thread packages are
integrated in the standard libs (FreeBSD and BSDI threads) the thread
package requires less overhead than thread packages that have to map all
unsafe calls (MIT-threads, FSU-threads and RTS threads).  In some
environments (for example SCO), all system calls are thread- safe so the
mapping can be done very easily (FSU-threads on SCO).  Downside: All
mapped calls take a little time and it's quite tricky to be able to
handle all situations. There are usually also some system calls that are
not handled by the thread package (like MIT-threads and sockets). Thread
scheduling isn't always optimal.
@item
User threads in separate processes. Thread switching is done by the
kernel and all data is shared between threads.  The thread package
manages the standard thread calls to allow sharing data between threads.
Linuxthreads is using this method.  Downside: Lots of processes. Thread
creating is slow. If one thread dies the rest are usually left hanging
and one has to kill them all before restarting. Thread switching is
somewhat expensive.
@item
Kernel threads. Thread switching is handled by the thread library or the
kernel and is very fast. Everything is done in one process but 'ps' may
on some systems show the different threads. If one thread aborts the
whole process aborts. Most system calls are threadsafe and should
require very little overhead.  Solaris, HPUX, AIX and OSF1 has kernel
threads.
@end itemize

In some systems kernel threads are managed by integrating user
level threads in the system libraries. In such cases, the thread
switching can only be done by the thread library and the kernel isn't
really 'thread aware'.

@node Regexp, Unireg, Porting, Top
@appendix Description of @strong{MySQL} regular expression syntax.

Regular expressions are a powerful way of specifying complex searches.

@strong{MySQL} uses regular Henry Spencers inplementation of regular
expressions. And that is aimed to conform to POSIX
1003.2. @strong{MySQL} uses the extended version.

To get more exact information see Henry Spencers regex.7 manual that is
included in the source distribution. @xref{Credits}.

This is a simplistic reference that skips the details. From here on a
regualr expressions is called a regexp.

A regular expression describes a set of strings. The simplest case is
one that has no special characters in it. For example the regexp
@code{hello} matches @code{hello} and nothing else. 

Nontrivial regular expressions use certain special constructs so that
they can match more than one string. For example, the regexp
@code{hello|word} matches either the string @code{hello} or the string
@code{word}.

And a more comples example regexp @code{B[an]*s} matches any of the
strings @code{Bananas}, @code{Baaaaas}, @code{Bs} and all other string
starting with a @code{B} and continuing with any number of @code{a}
@code{n} and ending with a @code{s}.

The following special characters/constructs are known.
@table @code
@item ^
Start of whole string.
@example
mysql> select "fo\nfo" regexp "^fo$";           -> 0
mysql> select "fofo" regexp "^fo";              -> 1
@end example
@item $
End of whole string.
@example
mysql> select "fo\no" regexp "^fo\no$";         -> 1
mysql> select "fo\no" regexp "^fo$";            -> 0
@end example
@item .
Any character (including newline).
@example
mysql> select "fofo" regexp "^f.*";             -> 1
mysql> select "fo\nfo" regexp "^f.*";           -> 1
@end example
@item a*
Any sequence of zero or more a's.
@example
mysql> select "Ban" regexp "^Ba*n";             -> 1
mysql> select "Baaan" regexp "^Ba*n";           -> 1
mysql> select "Bn" regexp "^Ba*n";              -> 1
@end example
@item a+
Any sequence of one or more a's.
@example
mysql> select "Ban" regexp "^Ba+n";             -> 1
mysql> select "Bn" regexp "^Ba+n";              -> 0
@end example
@item a?
Either zero or one a.
@example
mysql> select "Bn" regexp "^Ba?n";              -> 1
mysql> select "Ban" regexp "^Ba?n";             -> 1
mysql> select "Baan" regexp "^Ba?n";            -> 0
@end example
@item de|abc
Either the sequence @code{de} or @code{abc}.
@example
mysql> select "pi" regexp "pi|apa";             -> 1
mysql> select "axe" regexp "pi|apa";            -> 0
mysql> select "apa" regexp "pi|apa";            -> 1
mysql> select "apa" regexp "^(pi|apa)$";        -> 1
mysql> select "pi" regexp "^(pi|apa)$";         -> 1
mysql> select "pix" regexp "^(pi|apa)$";        -> 0
@end example
@item (abc)*
Zero or more times the sequence @code{abc}.
@example
mysql> select "pi" regexp "^(pi)+$";            -> 1
mysql> select "pip" regexp "^(pi)+$";           -> 0
mysql> select "pipi" regexp "^(pi)+$";          -> 1
@end example
@item @{1@}
@itemx @{2,3@}
The is a more general way of writing regexps that match many
occurences. 
@table @code
@item a*
Can be written as @code{a@{0,@}}.
@item +
Can be written as @code{a@{1,@}}.
@item ?
Can be written as @code{a@{0,1@}}.
@end table
To be more precice an atom followed by a bound containing one integer
@code{i} and no comma matches a sequence of exactly @code{i} matches of
the atom. An atom followed by a bound containing one integer @code{i}
and a comma matches a sequence of @code{i} or more matches of the atom.
An atom followed by a bound containing two integers @code{i} and
@code{j} matches a sequence of @code{i} through @code{j} (inclusive)
matches of the atom.

Both arguments must @code{0 >= value <= RE_DUP_MAX (default 255)}, and
if there are two of them, the second must be bigger or equal to the
first.
@item [a-dX]
@itemx [^a-dX]
Any character which is (not if ^ is used) either @code{a}, @code{b},
@code{c}, @code{d} or @code{X}. To include @code{]} it has to be written
first. To include @code{-} it has to be written first or last. So
@code{[0-9]} matches any decimal digit. All character that does not have
a defined mening inside a @code{[]} pair has no special meaning and
macthes only itself.
@example
mysql> select "aXbc" regexp "[a-dXYZ]";         -> 1
mysql> select "aXbc" regexp "^[a-dXYZ]$";       -> 0
mysql> select "aXbc" regexp "^[a-dXYZ]+$";      -> 1
mysql> select "aXbc" regexp "^[^a-dXYZ]+$";     -> 0
mysql> select "gheis" regexp "^[^a-dXYZ]+$";    -> 1
mysql> select "gheisa" regexp "^[^a-dXYZ]+$";   -> 0
@end example
@item [[.characters.]]
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}
collating element, then the RE @code{[[.ch.]]*c} matches the first five
characters of @code{chchcc}.

@item [=character-class=]
An equivalence class, standing for the sequences of characters of all
collating elements equivalent to that one, including itself.

For example, if @code{o} and @code{(+)} are the members of an
equivalence class, then @code{[[=o=]]}, @code{[[=(+)=]]}, and
@code{[o(+)]} are all synonymous. An equivalence class may not be an
endpoint of a range.

@item [:character_class:]
Within a bracket expression, the name of a character class enclosed in
@code{[:} and @code{:]} stands for the list of all characters belonging
to that class. Standard character class names are:

@multitable @columnfractions .33 .33 .33
@item alnum @tab digit @tab punct
@item alpha @tab graph @tab space
@item blank @tab lower @tab upper
@item cntrl @tab print @tab xdigit
@end multitable

These stand for the character classes defined in ctype(3). A locale may
provide others. A character class may not be used as an endpoint of a
range.
@example
mysql> select "justalnums" regexp "[[:alnum:]]+";       -> 1
mysql> select "!!" regexp "[[:alnum:]]+";               -> 0
@end example

@item [[:<:]]
@itemx [[:>:]]
These match the null string at the beginning and end of a word
respectively.  A word is defined as a sequence of word characters which
is neither preceded nor followed by word characters. A word character is
an alnum character (as defined by ctype(3)) or an underscore.
@example
mysql> select "a word a" regexp "[[:<:]]word[[:>:]]";      -> 1
mysql> select "a xword a" regexp "[[:<:]]word[[:>:]]";     -> 0
@end example
@end table

@example
mysql> select "weeknights" regexp "^(wee|week)(knights|nights)$"; -> 1
@end example

@node Unireg, Public, Regexp, Top
@appendix What is UNIREG ?

Unireg is our tty interface builder, but it uses a low level connection
to our NISAM (with is used by @strong{MySQL}) and because of this it is very
quick. It has existed since 1979 (on Unix in C since ~1986).

Unireg has the following components:

@itemize @bullet
@item
One table viewer with updates/browsing.
@item
Multi table viewer (with 1 scrolling region).
@item
Table creator. (With lots of column tags you can't create with @strong{MySQL})
This is WYSIWYG (for a tty). You design a screen and Unireg prompts for
the column specification.
@item
Report generator.
@item
A lot of utilities (Quick export/import of tables to/from text files,
analysis of table contents...).
@item
Powerful multi table updates (which we use a lot) with a BASIC like
language with LOTS of functions.
@item
Dynamic languages (at present in Swedish and Finnish). If somebody wants
an English version there are a few files that would have to be translate.
@item
The ability to run updates interactively or in a batch.
@item
Emacs like key definitions with keyboard macros.
@item
All this in a binary of 800k.
@item
The convform utility. Changes .frm and text files between different
character sets.
@item
The pack_isam utility. Packs a NISAM table (makes it 50-80%
smaller). The table can be read by @strong{MySQL} like an ordinary
table. Only 1 record has to be decompressed / access. Cannot handle
BLOB:s or updates (yet).
@end itemize

We update most of our production databases with the UNIREG interface and
serve web pages through @strong{MySQL} (and in some extreme cases the UNIREG
report generator).

Unireg takes about 3M of disk space and works on at least the following
platforms: SUN OS 4.x, Solaris, Linux, HPUX, ICL Unix, DNIX, SCO and
MSDOS.

Unireg is currently only available in Swedish and Finnish.

The price tag for UNIREG is 10,000 Swedish kr (about 1500$ US), but this
includes support. UNIREG is distributed as a binary. (But all the ISAM
sources can be found in @strong{MySQL}). Usually we compile the binary for the
customer at their site.

All new development is concentrated to @strong{MySQL}.

@page
@node Public, Function Index, Unireg, Top
@appendix The @strong{MySQL} server license

@center @strong{MySQL FREE PUBLIC LICENSE}
@center (Version 4, March 5, 1995)

@center Copyright (C) 1995, 1996 TcX AB & Monty Program KB & Detron HB
@center Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN
@center All rights reserved.

NOTE: This license is not the same as any of the GNU Licenses published
by the Free Software Foundation.  Its terms are substantially different
from those of the GNU Licenses.  If you are familiar with the GNU
Licenses, please read this license with extra care.

This License applies to the computer program known as "@strong{MySQL}".
The "Program", below, refers to such program, and a "work based on the
Program" means either the Program or any derivative work of the Program,
as defined in the United States Copyright Act of 1976, such as a
translation or a modification.  The Program is a copyrighted work whose
copyright is held by TcX Datakonsult AB and Monty Program KB and Detron
HB.

BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE
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.  NOTHING OTHER THAN THIS LICENSE GRANTS
YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE
WORKS.  THESE ACTIONS ARE PROHIBITED BY LAW.  IF YOU DO NOT ACCEPT THESE
TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.

@enumerate
@item
Licenses.

Licensor hereby grants you the following rights, provided that you comply
with all of the restrictions set forth in this License and provided,
further, that you distribute an unmodified copy of this License with the
Program:

@enumerate a
@item
You may copy and distribute literal (i.e., verbatim) copies of the
Program's source code as you receive it throughout the world, in any
medium.
@item
You may modify the Program, create works based on the Program and
distribute copies of such throughout the world, in any medium. 
@end enumerate

@item
Restrictions.

This license is subject to the following restrictions:
@enumerate a
@item
Distribution of the Program or any work based on the Program by a
commercial organization to any third party is prohibited if any payment is
made in connection with such distribution, whether directly (as in payment
for a copy of the Program) or indirectly (as in payment for some service
related to the Program, or payment for some product or service that
includes a copy of the Program "without charge"; these are only examples,
and not an exhaustive enumeration of prohibited activities).  However, the
following methods of distribution involving payment shall not in and of
themselves be a violation of this restriction:

@enumerate A
@item
Posting the Program on a public access information storage and retrieval
service for which a fee is received for retrieving information (such as
an on-line service), provided that the fee is not content-dependent
(i.e., the fee would be the same for retrieving the same volume of
information consisting of random data).
@item
Distributing the Program on a CD-ROM, provided that the files containing
the Program are reproduced entirely and verbatim on such CD-ROM, and
provided further that all information on such CD-ROM be redistributable
for non-commercial purposes without charge.
@end enumerate
@item
Activities other than copying, distribution and modification of the
Program are not subject to this License and they are outside its scope.
Functional use (running) of the Program is not restricted, and any
output produced through the use of the Program is subject to this
license only if its contents constitute a work based on the Program
(independent of having been made by running the Program).
@item
You must meet all of the following conditions with respect to the
distribution of any work based on the Program:
@enumerate A
@item
If you have modified the Program, you must cause your work to carry
prominent notices stating that you have modified the Program's files and
the date of any change;
@item
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 and at no charge to all third parties under the
terms of this License;
@item
If the modified program normally reads commands interactively when run,
you must cause it, at each time the modified program commences
operation, 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).  Such notice must also state that users
may redistribute the Program only under the conditions of this License
and tell the user how to view the copy of this License included with the
Program.  (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.);
@item
You must accompany any such work based on the Program with the complete
corresponding machine-readable source code, delivered on a medium
customarily used for software interchange.  The source code for a work
means the preferred form of the work for making modifications to it.
For an executable work, 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 executable code.  However, the source code distributed need not
include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of
the operating system on which the executable runs, unless that component
itself accompanies the executable code;
@item
If you distribute any written or printed material at all with the
Program or any work based on the Program, such material must include
either a written copy of this License, or a prominent written indication
that the Program or the work based on the Program is covered by this
License and written instructions for printing and/or displaying the copy
of the License on the distribution medium;
@item
You may not impose any further restrictions on the recipient's
exercise of the rights granted herein.

If distribution of executable or object code is made by offering the
equivalent ability to copy from a designated place, then offering
equivalent ability 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 code along with the object code.
@end enumerate
@end enumerate
@item
Reservation of Rights.

No rights are granted to the Program except as expressly set forth
herein.  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.  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.

@item
Other Restrictions.

If the distribution and/or use of the Program is restricted in certain
countries for any reason, Licensor may add an explicit geographical
distribution limitation excluding 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.

@item
Limitations.

THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY.  THERE IS NO
WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  THE ENTIRE
RISK AS 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.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL LICENSOR, 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 OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 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 enumerate

@page
@node Function Index, Concept Index, Public, Top
@unnumbered SQL command, type and function index. 

@printindex fn

@page
@node Concept Index,  , Function Index, Top
@unnumbered Concept Index
     
@printindex cp

@summarycontents
@contents

@bye

Do text here do something ??
