diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index fbf9c3702a3..649ea4cac52 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1,16 +1,5 @@ heikki@donna.mysql.fi -jani@janikt.pp.saunalahti.fi -miguel@light.local -monty@hundin.mysql.fi -monty@tik.mysql.fi -monty@work.mysql.com -mwagner@evoq.mwagner.org -paul@central.snake.net -paul@teton.kitebird.com -sasha@mysql.sashanet.com -serg@serg.mysql.com -tim@threads.polyesthetic.msg -tim@white.box +jani@hynda.mysql.fi jcole@tetra.spaceapes.com -davida@isil.mysql.com -tonu@x153.internalnet +tim@work.mysql.com +serg@serg.mysql.com diff --git a/Docs/manual.texi b/Docs/manual.texi index 86a4b92f304..8bb22202055 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -92,6 +92,7 @@ END-INFO-DIR-ENTRY @end iftex + @node Top, Introduction, (dir), (dir) @c @ifhtml @@ -114,16 +115,9 @@ distribution for that version. * MySQL Optimization:: * Reference:: @strong{MySQL} language reference * Table types:: @strong{MySQL} table types -* Fulltext Search:: Fulltext Search -* Maintenance:: Maintaining a @strong{MySQL} installation -* Adding functions:: Adding new functions to @strong{MySQL} -* Adding procedures:: Adding new procedures to @strong{MySQL} -* ODBC:: @strong{MySQL} ODBC Support -* Common programs:: Using @strong{MySQL} with some common programs -* Problems:: Problems -* Common problems:: Solving some common problems with @strong{MySQL} * Clients:: @strong{MySQL} client tools and APIs -* MySQL internals:: @strong{MySQL} internals +* Extending MySQL:: +* Problems:: Problems * Environment variables:: @strong{MySQL} environment variables * Users:: Some @strong{MySQL} users * MySQL customer usage:: @@ -141,14 +135,17 @@ distribution for that version. @end menu + + + +@node Introduction, Installing, Top, Top +@chapter General Information About MySQL + @cindex overview @cindex general information @cindex online location of manual @cindex manual, online location -@node Introduction, Installing, Top, Top -@chapter General Information About MySQL - This is the @strong{MySQL} reference manual; it documents @strong{MySQL} Version @value{mysql_version}. As @strong{MySQL} is work in progress, the manual gets updated frequently. There is a very good chance that @@ -245,6 +242,7 @@ see @ref{General-SQL}. For books that focus more specifically on * TODO:: @end menu + @node MySQL and MySQL AB, MySQL Information Sources, Introduction, Introduction @section MySQL, MySQL AB, and Open Source @@ -260,6 +258,7 @@ see @ref{General-SQL}. For books that focus more specifically on * Year 2000 compliance:: Year 2000 compliance @end menu + @node What-is, What is MySQL AB, MySQL and MySQL AB, MySQL and MySQL AB @subsection What Is MySQL @@ -351,6 +350,7 @@ language already supports @strong{MySQL}. The official way to pronounce @strong{MySQL} is ``My Ess Que Ell'' (not MY-SEQUEL). But we try to avoid correcting people who say MY-SEQUEL. + @node What is MySQL AB, Manual-info, What-is, MySQL and MySQL AB @subsection What Is MySQL AB @@ -463,6 +463,7 @@ Are a virtual company, networking with others. Work against software patents. @end itemize + @node Manual-info, Manual conventions, What is MySQL AB, MySQL and MySQL AB @subsection About This Manual @@ -480,6 +481,7 @@ This manual is written and maintained by David Axmark, Michael (Monty) Widenius, Jeremy Cole, and Paul DuBois. For other contributors, see @ref{Credits}. + @node Manual conventions, History, Manual-info, MySQL and MySQL AB @subsection Conventions Used in This Manual @@ -604,6 +606,7 @@ alternatives are listed within braces (@samp{@{} and @samp{@}}): @{DESCRIBE | DESC@} tbl_name @{col_name | wild@} @end example + @node History, Features, Manual conventions, MySQL and MySQL AB @subsection History of MySQL @@ -737,7 +740,8 @@ memory leakage detector. @item Includes @code{myisamchk}, a very fast utility for table checking, optimization, and repair. All of the functionality of @code{myisamchk} -is also available through the SQL interface as well. @xref{Maintenance}. +is also available through the SQL interface as well. +@xref{MySQL Database Administration}. @item Full support for several different character sets, including @@ -789,10 +793,12 @@ information about databases, tables, and indexes. The @code{EXPLAIN} command can be used to determine how the optimizer resolves a query. @end itemize -@cindex stability + @node Stability, Table size, Features, MySQL and MySQL AB @subsection How Stable Is MySQL? +@cindex stability + This section addresses the questions ``How stable is @strong{MySQL}?'' and ``Can I depend on @strong{MySQL} in this project?'' We will try to clarify some issues and to answer some of the more important questions that seem to @@ -948,6 +954,7 @@ Text search seems to work, but is still not widely used. Bugs are usually fixed right away with a patch; for serious bugs, there is almost always a new release. + @node Table size, Year 2000 compliance, Stability, MySQL and MySQL AB @subsection How Big Can MySQL Tables Be? @@ -1004,6 +1011,7 @@ Another solution can be the included MERGE library, which allows you to handle a collection of identical tables as one. @xref{MERGE, MERGE tables}. + @node Year 2000 compliance, , Table size, MySQL and MySQL AB @subsection Year 2000 Compliance @@ -1103,6 +1111,7 @@ provide unambiguous input. See @ref{Y2K issues} for @strong{MySQL}'s rules for dealing with ambiguous date input data (data containing 2-digit year values). + @node MySQL Information Sources, Licensing and Support, MySQL and MySQL AB, Introduction @section MySQL Information Sources @@ -1116,6 +1125,7 @@ values). * Questions:: @end menu + @node MySQL-Books, General-SQL, MySQL Information Sources, MySQL Information Sources @subsection Books About MySQL @@ -1468,6 +1478,7 @@ A complete reference to DBI. @end itemize @* + @node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources @subsection General SQL Information and Tutorials @@ -1497,6 +1508,7 @@ Alameda, CA USA A SQL tutorial is available on the net at http://w3.one.net/~jhoffman/sqltut.htm + @node Useful Links, Questions, General-SQL, MySQL Information Sources @subsection Useful MySQL-related Links @@ -2085,6 +2097,7 @@ require that you show a @strong{MySQL} logo somewhere if you wish your site to be added. It is okay to have it on a ``used tools'' page or something similar. + @node Questions, , Useful Links, MySQL Information Sources @subsection MySQL Mailing Lists @@ -2101,6 +2114,7 @@ something similar. This section introduces you to the @strong{MySQL} mailing lists, and gives some guidelines as to how to use them. + @node Mailing-list, Asking questions, Questions, Questions @subsubsection The MySQL Mailing Lists @@ -2246,6 +2260,7 @@ Email @code{subscribe mysql-br your@@email.address} to this list. Email @code{subscribe mysql your@@email.address} to this list. @end table + @node Asking questions, Bug reports, Mailing-list, Questions @subsubsection Asking Questions or Reporting Bugs @@ -2280,6 +2295,7 @@ 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@@lists.mysql.com}. + @node Bug reports, Answering questions, Asking questions, Questions @subsubsection How to Report Bugs or Problems @@ -2548,7 +2564,7 @@ upgrading to a newer version of @strong{MySQL}. @xref{News}. If you have a problem such that your data appears corrupt or you get errors when you access some particular table, you should first check and then try repairing your tables with @code{myisamchk} or @code{CHECK TABLE} and -@code{REPAIR TABLE}. @xref{Maintenance}. +@code{REPAIR TABLE}. @xref{MySQL Database Administration}. @item If you often get corrupted tables you should try to find out when and why this @@ -2587,6 +2603,7 @@ it is considered good etiquette to summarize the answers and send the summary to the mailing list so that others may have the benefit of responses you received that helped you solve your problem! + @node Answering questions, , Bug reports, Questions @subsubsection Guidelines for Answering Question on the Mailing List @@ -2607,6 +2624,7 @@ obliged to quote the entire original message. Please don't post mail messages from your browser with HTML mode turned on! Many users don't read mail with a browser! + @node Licensing and Support, Compatibility, MySQL Information Sources, Introduction @section MySQL Licensing and Support @@ -2638,6 +2656,7 @@ arrangements: @item Commercial licensing costs @end itemize + @node Licensing policy, Copyright, Licensing and Support, Licensing and Support @subsection MySQL Licensing Policy @@ -2724,6 +2743,7 @@ is to use the license form on @strong{MySQL}'s secure server at @uref{https://order.mysql.com/}. Other forms of payment are discussed in @ref{Payment information}. + @node Copyright, Licensing examples, Licensing policy, Licensing and Support @subsection Copyrights Used by MySQL @@ -2770,12 +2790,14 @@ However, if you use @strong{MySQL} for something important to you, you may want to help secure its development by purchasing licenses or a support contract. @xref{Support}. + @node Copyright changes, , Copyright, Copyright @subsubsection Copyright Changes Version 3.22 of @strong{MySQL} is still using a more strict license. See the documentation for that version for more information. + @node Licensing examples, Cost, Copyright, Licensing and Support @subsection Example Licensing Situations @@ -2797,6 +2819,7 @@ Note that a single @strong{MySQL} license covers any number of CPUs and @code{mysqld} servers on a machine! There is no artificial limit on the number of clients that connect to the server in any way. + @node Products that use MySQL, ISP, Licensing examples, Licensing examples @subsubsection Selling Products that use MySQL @@ -2841,6 +2864,7 @@ don't need a license. @end itemize + @node ISP, Web server, Products that use MySQL, Licensing examples @subsubsection ISP MySQL Services @@ -2867,6 +2891,7 @@ it should give its customers at least read access to the source of the @strong{MySQL} installation so that its customer can verify that it is patched correctly. + @node Web server, , ISP, Licensing examples @subsubsection Running a Web Server Using MySQL @@ -2881,6 +2906,7 @@ This is true even if you run a commercial Web server that uses version yourself. However, in this case we would like you to purchase @strong{MySQL} support, because @strong{MySQL} is helping your enterprise. + @node Cost, Support, Licensing examples, Licensing and Support @subsection MySQL Licensing and Support Costs @@ -2963,6 +2989,7 @@ Note that as our sales staff is very busy, it may take some time until your request is handled. Our support staff does however always answer promptly to support questions! + @node Payment information, Contact information, Cost, Cost @subsubsection Payment information @@ -3011,6 +3038,7 @@ us'' in the comment field. You can also mail a message to @email{sales@@mysql.com} (@strong{not} @code{mysql@@lists.mysql.com}!) with your company information and ask us to bill you. + @node Contact information, , Payment information, Cost @subsubsection Contact Information @@ -3053,6 +3081,7 @@ For general information inquires, please send e-mail to For questions or comments about the workings or content of the Web site, please send e-mail to @email{webmaster@@mysql.com}. + @node Support, , Cost, Licensing and Support @subsection Types of Commercial Support @@ -3091,6 +3120,7 @@ if you have login support (2000 EURO), you can expect us to work up to 10 hours to help you with things like this. @end itemize + @node Basic email support, Extended email support, Support, Support @subsubsection Basic E-mail Support @@ -3164,6 +3194,7 @@ If you want us to help optimize your system, you must upgrade to a higher level of support. @end itemize + @node Extended email support, Login support, Basic email support, Support @subsubsection Extended E-mail Support @@ -3211,6 +3242,7 @@ TODO List. @xref{TODO}. This will ensure that the features you really need will be implemented sooner than they might be otherwise. @end itemize + @node Login support, Extended login support, Extended email support, Support @subsubsection Login Support @@ -3254,6 +3286,7 @@ before talking on phone, to be able to work as efficiently as possible on solving the problem. @end itemize + @node Extended login support, Telephone support, Login support, Support @subsubsection Extended Login Support @@ -3291,6 +3324,7 @@ without charge. For the hours above 8 hours, you will be charged with a rate that is at least 20 % less than our standard rates. @end itemize + @node Telephone support, Table handler support, Extended login support, Support @subsubsection Telephone Support @@ -3307,6 +3341,7 @@ For non critical problem, you can request a @strong{MySQL} developer to phone back within 48 hours to discuss @code{MySQL} related issues. @end itemize + @node Table handler support, , Telephone support, Support @subsubsection Support for other table handlers @@ -3327,6 +3362,7 @@ timely manner, we can't guarantee a quick solution for any problems you can get with the different table handlers. We will however do our best to help you get the problem solved. + @node Compatibility, Comparisons, Licensing and Support, Introduction @section How Standards-compatible Is MySQL? @@ -3351,6 +3387,7 @@ will find out what they are, and how to use them. You will also find information about functionality missing from @strong{MySQL}, and how to work around some differences. + @node Extensions to ANSI, Differences from ANSI, Compatibility, Compatibility @subsection MySQL Extensions to ANSI SQL92 @@ -3596,6 +3633,7 @@ SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3; @end itemize + @node Differences from ANSI, ANSI mode, Extensions to ANSI, Compatibility @subsection MySQL Differences Compared to ANSI SQL92 @@ -3623,6 +3661,7 @@ This is because we don't think it's good to have to evaluate a lot of extra conditions in this case. @end itemize + @node ANSI mode, Missing functions, Differences from ANSI, Compatibility @subsection Running MySQL in ANSI Mode @@ -3649,6 +3688,7 @@ The default transaction isolation level is @code{SERIALIZABLE}. @xref{SET TRANSACTION}. @end itemize + @node Missing functions, Standards, ANSI mode, Compatibility @subsection Functionality Missing from MySQL @@ -3673,6 +3713,7 @@ list in this manual. @xref{TODO}. * Missing comments:: @samp{--} as the start of a comment @end menu + @node Missing Sub-selects, Missing SELECT INTO TABLE, Missing functions, Missing functions @subsubsection Sub-selects @@ -3730,6 +3771,7 @@ prompt> mysql --skip-column-names mydb < myscript.sql | mysql mydb be available in Version 4.0. You can now use the function @code{IN()} in other contexts, however. + @node Missing SELECT INTO TABLE, Missing Transactions, Missing Sub-selects, Missing functions @subsubsection @code{SELECT INTO TABLE} @@ -3748,6 +3790,7 @@ tblTemp1.fldOrder_ID > 100; Alternatively, you can use @code{SELECT INTO OUTFILE...} or @code{CREATE TABLE ... SELECT} to solve your problem. + @node Missing Transactions, Missing Triggers, Missing SELECT INTO TABLE, Missing functions @subsubsection Transactions @@ -3863,6 +3906,7 @@ that we believe to be better than any commercial replication system we know of. This system will work most reliably under the atomic operations, non-transactional, paradigm. Stay tuned. + @node Missing Triggers, Missing Foreign Keys, Missing Transactions, Missing functions @subsubsection Stored Procedures and Triggers @@ -3870,7 +3914,6 @@ operations, non-transactional, paradigm. Stay tuned. @cindex procedures, stored @cindex triggers, stored - A stored procedure is a set of SQL commands that can be compiled and stored in the server. Once this has been done, clients don't need to keep reissuing the entire query but can refer to the stored procedure. This provides better @@ -3890,6 +3933,7 @@ down everything, even queries for which they are not needed. To see when @strong{MySQL} might get stored procedures, see @ref{TODO}. + @node Missing Foreign Keys, Broken Foreign KEY, Missing Triggers, Missing functions @subsubsection Foreign Keys @@ -3934,6 +3978,7 @@ coded to avoid them. * Broken Foreign KEY:: Reasons NOT to use foreign keys constraints @end menu + @node Broken Foreign KEY, Missing Views, Missing Foreign Keys, Missing functions @subsubsection Reasons NOT to Use Foreign Keys constraints @@ -3990,6 +4035,7 @@ connection was made. The current @file{.frm} file format does not have any place for it. At a later stage we will implement the foreign key constraints for application that can't easily be coded to avoid them. + @node Missing Views, Missing comments, Broken Foreign KEY, Missing functions @subsubsection Views @@ -4012,6 +4058,7 @@ One doesn't need views in @strong{MySQL} to restrict access to columns as @strong{MySQL} has a very sophisticated privilege system. @xref{Privilege system}. + @node Missing comments, , Missing Views, Missing functions @subsubsection @samp{--} as the Start of a Comment @@ -4074,11 +4121,13 @@ Change them back with this command: shell> replace " #" " --" -- text-file-with-funny-comments.sql @end example + @node Standards, Commit-rollback, Missing functions, Compatibility @subsection What Standards Does MySQL Follow? Entry level SQL92. ODBC levels 0-2. + @node Commit-rollback, Bugs, Standards, Compatibility @subsection How to Cope Without @code{COMMIT}/@code{ROLLBACK} @@ -4213,6 +4262,7 @@ You can think of it as @strong{MySQL} changed the above query to: UPDATE tbl_name SET row_flag=1 WHERE id=ID and row_flag <> 1; @end example + @node Bugs, , Commit-rollback, Compatibility @subsection Known errors and design deficiencies in MySQL @@ -4455,6 +4505,7 @@ decimals. For platform-specific bugs, see the sections about compiling and porting. + @node Comparisons, TODO, Compatibility, Introduction @section How MySQL Compares to Other Databases @@ -4477,6 +4528,7 @@ For a list of all supported limits, functions, and types, see the @code{crash-me} Web page at @uref{http://www.mysql.com/information/crash-me.php}. + @node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons @subsection How MySQL Compares to @code{mSQL} @@ -4669,6 +4721,7 @@ For example, it changes instances of @code{msqlConnect()} to * Syntax differences:: @end menu + @node Using mSQL tools, Protocol differences, Compare mSQL, Compare mSQL @subsubsection How to Convert @code{mSQL} Tools for MySQL @@ -4714,6 +4767,7 @@ Some incompatibilities exist as a result of @strong{MySQL} supporting multiple connections to the server from the same process. @end itemize + @node Protocol differences, Syntax differences, Using mSQL tools, Compare mSQL @subsubsection How @code{mSQL} and MySQL Client/Server Communications Protocols Differ @@ -4752,6 +4806,7 @@ If a connection is idle for 8 hours, the server closes the connection. * Syntax differences:: @end menu + @node Syntax differences, , Protocol differences, Compare mSQL @subsubsection How @code{mSQL} 2.0 SQL Syntax Differs from MySQL @@ -4974,6 +5029,7 @@ can offer, you should use @code{PostgreSQL}. * MySQL-PostgreSQL benchmarks:: @end menu + @node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL @subsubsection MySQL and PostgreSQL development strategies @@ -5241,6 +5297,7 @@ in this section. * MySQL-PostgreSQL benchmarks:: @end menu + @node MySQL-PostgreSQL benchmarks, , MySQL-PostgreSQL features, Compare PostgreSQL @subsubsection Benchmarking MySQL and PostgreSQL @@ -5462,6 +5519,7 @@ We are working on an even better benchmark suite, including much better documentation of what the individual tests really do and how to add more tests to the suite. + @node TODO, , Comparisons, Introduction @section MySQL and the future (The TODO) @@ -5484,6 +5542,7 @@ The plan is that we in the future will support the full ANSI SQL99 standard, but with a lot of useful extensions. The challenge is to do this without sacrifying the speed or compromise the code. + @node TODO MySQL 4.0, TODO future, TODO, TODO @subsection Things that should be in 4.0 @@ -5569,6 +5628,7 @@ of @code{analyze} is run on all sub tables. @code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}. @end itemize + @node TODO future, TODO sometime, TODO MySQL 4.0, TODO @subsection Things that must be done in the real near future @@ -5850,6 +5910,7 @@ if it exists and @code{INSERT} a new row if the row didn't exist. (Like @code{REPLACE} works with @code{INSERT} / @code{DELETE}) @end itemize + @node TODO sometime, TODO unplanned, TODO future, TODO @subsection Things that have to be done sometime @@ -5945,6 +6006,7 @@ one must also handle the possible deadlocks this change will introduce. Time is given according to amount of work, not real time. + @node TODO unplanned, , TODO sometime, TODO @subsection Some things we don't have any plans to do @@ -5953,6 +6015,9 @@ Time is given according to amount of work, not real time. Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant. @end itemize + + + @node Installing, Tutorial, Introduction, Top @chapter MySQL Installation @@ -6000,6 +6065,7 @@ procedures apply whether you install @strong{MySQL} using a binary or source distribution. @end itemize + @node Quick Standard Installation, General Installation Issues, Installing, Installing @section Quick Standard Installation of MySQL @@ -6009,6 +6075,7 @@ source distribution. * Windows installation:: @end menu + @node Linux-RPM, Windows installation, Quick Standard Installation, Quick Standard Installation @subsection Installing MySQL on Linux @@ -6084,6 +6151,7 @@ and you should now be able to start using @strong{MySQL}. If something goes wrong, you can find more information in the binary installation chapter. @xref{Installing binary}. + @node Windows installation, , Linux-RPM, Quick Standard Installation @subsection Installing MySQL on Windows @@ -6173,6 +6241,7 @@ options that must be specified in your @file{my.ini} file! @xref{InnoDB start}. * MySQL binaries:: @end menu + @node Getting MySQL, Which OS, General Installation Issues, General Installation Issues @subsection How to Get MySQL @@ -6773,10 +6842,11 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @strong{Asia:} @itemize @bullet -@item +@c @item +@c Host cannot be resolved for last week at least 20010809 Tonu @c EMAIL: mirnshi@263.net (Meng Lingbo) -@image{Flags/china} China [Freecode] @ -@uref{http://www.freecode.net.cn/mirror/mysql/, WWW} +@c @image{Flags/china} China [Freecode] @ +@c @uref{http://www.freecode.net.cn/mirror/mysql/, WWW} @item @c EMAIL: yusun@atwell.co.jp (yu sun) @@ -7124,6 +7194,7 @@ forth more effort into testing on and optimizing for that particular platform. We are just stating our observations to help you make a decision on which platform to use @strong{MySQL} on in your setup. + @node Which version, Installation layouts, Which OS, General Installation Issues @subsection Which MySQL Version to Use @@ -7305,6 +7376,7 @@ Another test is that we use the newest @strong{MySQL} version in our internal production environment, on at least one machine. We have more than 100 gigabytes of data to work with. + @node Installation layouts, Many versions, Which version, General Installation Issues @subsection Installation Layouts @@ -7370,6 +7442,7 @@ The header file and library directories are @file{include/mysql} and You can create your own binary installation from a compiled source distribution by executing the script @file{scripts/make_binary_distribution}. + @node Many versions, MySQL binaries, Installation layouts, General Installation Issues @subsection How and When Updates Are Released @@ -7431,6 +7504,7 @@ and things that ``must be done.'' ``Somewhat frozen'' means that we may add small things that ``almost surely will not affect anything that's already working.'' + @node MySQL binaries, , Many versions, General Installation Issues @subsection MySQL Binaries Compiled by MySQL AB @@ -7490,6 +7564,7 @@ If you want to compile a debug version of @strong{MySQL}, you should add @code{--with-debug} or @code{--with-debug=full} to the above configure lines and remove any @code{-fomit-frame-pointer} options. + @node Installing source, Post-installation, General Installation Issues, Installing @section Installing a MySQL Source Distribution @@ -7564,6 +7639,7 @@ of getting a solution to your problem! You will find @code{mysqlbug} in the * MIT-pthreads:: @end menu + @node Quick install, Applying patches, Installing source, Installing source @subsection Quick Installation Overview @@ -7743,6 +7819,7 @@ running. @xref{Multiple servers}. @xref{Post-installation}. + @node Applying patches, configure options, Quick install, Installing source @subsection Applying Patches @@ -7784,6 +7861,7 @@ You may need to bring down any currently running server before you run systems do not allow you to install a new version of a program if it replaces the version that is currently executing. + @node configure options, Installing source tree, Applying patches, Installing source @subsection Typical @code{configure} Options @@ -8006,6 +8084,7 @@ system-specific section of this manual. @xref{Operating System Specific Notes}. @end itemize + @node Installing source tree, Compilation problems, configure options, Installing source @subsection Installing from the Development Source Tree @@ -8107,6 +8186,7 @@ a description. @end enumerate + @node Compilation problems, MIT-pthreads, Installing source tree, Installing source @subsection Problems Compiling? @@ -8328,6 +8408,7 @@ If you need to debug @code{mysqld} or a @strong{MySQL} client, run link your clients with the new client library. @xref{Debugging client}. @end itemize + @node MIT-pthreads, , Compilation problems, Installing source @subsection MIT-pthreads Notes @@ -8694,6 +8775,7 @@ shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tst The expected results are shown in the @file{./tests/auto_increment.res} file. @end enumerate + @node mysql_install_db, Starting server, Post-installation, Post-installation @subsection Problems Running @code{mysql_install_db} @cindex @code{mysql_install_db} script @@ -8806,6 +8888,7 @@ flush-privileges} or @code{mysqladmin reload} afterward to tell the server to reload the grant tables. @end table + @node Starting server, Automatic start, mysql_install_db, Post-installation @subsection Problems Starting the MySQL Server @cindex server, starting problems @@ -8964,8 +9047,10 @@ options. @xref{InnoDB start}. If you are using BDB (Berkeley DB) tables, you should familiarize yourself with the different BDB specific startup options. @xref{BDB start}. + @node Automatic start, , Starting server, Post-installation @subsection Starting and Stopping MySQL Automatically + @cindex starting, the server automatically @cindex stopping, the server @cindex server, starting and stopping @@ -9039,6 +9124,7 @@ read from option files: @xref{Option files}. + @node Upgrade, Operating System Specific Notes, Post-installation, Installing @section Upgrading/Downgrading MySQL @@ -9085,6 +9171,7 @@ dumping core after you upgrade @strong{MySQL}. * Upgrading-to-arch:: Upgrading to another architecture @end menu + @node Upgrading-from-3.22, Upgrading-from-3.21, Upgrade, Upgrade @subsection Upgrading From Version 3.22 to Version 3.23 @@ -9210,6 +9297,7 @@ on an @code{AND/OR} expression as @code{NOT NULL} = @code{NULL}. than the length argument. @end itemize + @node Upgrading-from-3.21, Upgrading-from-3.20, Upgrading-from-3.22, Upgrade @subsection Upgrading from Version 3.21 to Version 3.22 @@ -9241,8 +9329,10 @@ The @code{mysqld} variable @code{key_buffer} has changed names to @code{key_buffer_size}, but you can still use the old name in your startup files. + @node Upgrading-from-3.20, Upgrading-to-arch, Upgrading-from-3.21, Upgrade @subsection Upgrading from Version 3.20 to Version 3.21 + @cindex upgrading, 3.20 to 3.21 If you are running a version older than Version 3.20.28 and want to @@ -9310,6 +9400,7 @@ There are some new reserved words. The most notable are @code{DATE}, @code{TIME}, and @code{TIMESTAMP}. @end itemize + @node Upgrading-to-arch, , Upgrading-from-3.20, Upgrade @subsection Upgrading to Another Architecture @@ -9405,6 +9496,7 @@ After you import the @code{mysql} database on the new machine, execute @code{mysqladmin flush-privileges} so that the server reloads the grant table information. + @node Operating System Specific Notes, , Upgrade, Installing @section Operating System Specific Notes @@ -9420,6 +9512,7 @@ information. * Novell Netware:: @end menu + @node Linux, Windows, Operating System Specific Notes, Operating System Specific Notes @subsection Linux Notes (All Linux Versions) @@ -9685,6 +9778,7 @@ The following @code{configure} line should work with @code{fcc/FCC}: CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO '-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory @end example + @node Binary notes-Linux, Linux-x86, Linux, Linux @subsubsection Linux Notes for Binary Distributions @@ -9764,6 +9858,7 @@ your clients or use sockets, if you are running the database server and clients on the same machine. We hope that the @code{Linux 2.4} kernel will fix this problem in the future. + @node Linux-x86, Linux-SPARC, Binary notes-Linux, Linux @subsubsection Linux x86 Notes @@ -9825,6 +9920,7 @@ You can avoid using @file{libg++.a} by running @code{configure} like this: shell> CXX=gcc ./configure @end example + @node Linux-SPARC, Linux-Alpha, Linux-x86, Linux @subsubsection Linux SPARC Notes @@ -9841,6 +9937,7 @@ that is available at @code{vger.rutgers.edu} (a version of Linux that was never merged with the official 2.0.30). You must also install LinuxThreads Version 0.6 or newer. + @node Linux-Alpha, Linux-PowerPC, Linux-SPARC, Linux @subsubsection Linux Alpha Notes @@ -9887,12 +9984,14 @@ resulting image will core dump at start. In other words, @strong{DON'T} use @code{--with-mysqld-ldflags=-all-static} with @code{gcc}. @end itemize + @node Linux-PowerPC, Linux-MIPS, Linux-Alpha, Linux @subsubsection Linux PowerPC Notes @strong{MySQL} should work on MkLinux with the newest @code{glibc} package (tested with @code{glibc} 2.0.7). + @node Linux-MIPS, Linux-IA64, Linux-PowerPC, Linux @subsubsection Linux MIPS Notes @@ -9901,6 +10000,7 @@ newest @code{glibc} libraries (@code{glibc-2.0.7-29C2} is known to work). You must also use the @code{egcs} C++ compiler (@code{egcs-1.0.2-9}, @code{gcc 2.95.2} or newer). + @node Linux-IA64, , Linux-MIPS, Linux @subsubsection Linux IA64 Notes @@ -9947,6 +10047,7 @@ with the @strong{MySQL} Windows distribution. * Windows vs Unix:: @strong{MySQL}-Windows compared to Unix @strong{MySQL} @end menu + @node Win95 start, NT start, Windows, Windows @subsubsection Starting MySQL on Windows 95 or Windows 98 @@ -9994,6 +10095,7 @@ The last option is to start @code{mysqld} with @code{--standalone @file{C:\mysqld.trace} that should contain the reason why @code{mysqld} doesn't start. @xref{Making trace files}. + @node NT start, Windows running, Win95 start, Windows @subsubsection Starting MySQL on Windows NT or Windows 2000 @@ -10083,6 +10185,7 @@ C:\> C:\mysql\bin\mysqld --standalone --debug The last version gives you a debug trace in @file{C:\mysqld.trace}. @xref{Making trace files}. + @node Windows running, Windows and SSH, NT start, Windows @subsubsection Running MySQL on Windows @@ -10168,10 +10271,12 @@ With the current @strong{MySQL} versions you can easily add new users and change privileges with @code{GRANT} and @code{REVOKE} commands. @xref{GRANT}. -@c FIX this is ugly, real ugly. + @node Windows and SSH, Windows symbolic links, Windows running, Windows @subsubsection Connecting to a Remote MySQL from Windows with SSH +@c FIX this is ugly, real ugly. + @cindex SSH @cindex connecting, remotely with SSH @@ -10213,6 +10318,7 @@ for the @strong{MySQL} host server --- not @code{yourmysqlservername}. You should now have an ODBC connection to @strong{MySQL}, encrypted using SSH. + @node Windows symbolic links, Windows compiling, Windows and SSH, Windows @subsubsection Splitting Data Across Different Disks on Windows @@ -10252,6 +10358,7 @@ In @strong{MySQL} 4.0 we will enable symlinks by default. Then you should instead use the @code{skip-symlink} option if you want to disable this. + @node Windows compiling, Windows vs Unix, Windows symbolic links, Windows @subsubsection Compiling MySQL Clients on Windows @@ -10275,6 +10382,7 @@ with the static @file{mysqlclient.lib} library. Note that as the mysqlclient libraries are compiled as threaded libraries, you should also compile your code to be multi-threaded! + @node Windows vs Unix, , Windows compiling, Windows @subsubsection MySQL-Windows Compared to Unix MySQL @@ -10655,6 +10763,7 @@ symbolic link to it named @file{/etc/rc3.d/S99mysql.server}. * Solaris x86:: @end menu + @node Solaris 2.7, Solaris x86, Solaris, Solaris @subsubsection Solaris 2.7/2.8 Notes @@ -10863,6 +10972,7 @@ crash when @code{make} tries to run @code{lint} on C++ files. * OpenBSD 2.8:: OpenBSD 2.8 Notes @end menu + @node OpenBSD 2.5, OpenBSD 2.8, OpenBSD, BSD Notes @subsubsection OpenBSD 2.5 Notes @@ -10873,6 +10983,7 @@ with the following options: CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no @end example + @node OpenBSD 2.8, BSDI, OpenBSD 2.5, BSD Notes @subsubsection OpenBSD 2.8 Notes @@ -10892,6 +11003,7 @@ usage, and crashes. * BSDI4:: BSD/OS 4.x notes @end menu + @node BSDI2, BSDI3, BSDI, BSD Notes @subsubsection BSD/OS Version 2.x Notes @@ -10916,6 +11028,7 @@ If you are using @code{gcc}, you may also use have to use the If you get problems with the current date in @strong{MySQL}, setting the @code{TZ} variable will probably help. @xref{Environment variables}. + @node BSDI3, BSDI4, BSDI2, BSD Notes @subsubsection BSD/OS Version 3.x Notes @@ -10956,6 +11069,7 @@ If this doesn't work and you are using @code{bash}, try switching to @code{csh} or @code{sh}; some BSDI users have reported problems with @code{bash} and @code{ulimit}. + @node BSDI4, , BSDI3, BSD Notes @subsubsection BSD/OS Version 4.x Notes @@ -11812,6 +11926,7 @@ If you want to use @code{gcc}, you must use @code{gcc} 2.95.2 or newer. * OS/2:: @end menu + @node OS/2, BeOS, Other Unix Notes, Operating System Specific Notes @subsection OS/2 Notes @@ -11896,6 +12011,8 @@ We are interested in finding someone to do a port, and we will help them with any technical questions they may have while doing the port. + + @node Tutorial, MySQL Database Administration, Installing, Top @chapter Introduction to MySQL: A MySQL Tutorial @@ -11945,6 +12062,7 @@ Because this chapter is tutorial in nature, many details are necessarily left out. Consult the relevant sections of the manual for more information on the topics covered here. + @node Connecting-disconnecting, Entering queries, Tutorial, Tutorial @section Connecting to and Disconnecting from the Server @@ -12008,6 +12126,7 @@ You can also disconnect by pressing Control-D. Most examples in the following sections assume you are connected to the server. They indicate this by the @code{mysql>} prompt. + @node Entering queries, Database use, Connecting-disconnecting, Tutorial @section Entering Queries @@ -12234,6 +12353,7 @@ containing @code{QUIT}! This can be quite confusing, especially if you don't know that you need to supply the terminating quote before you can cancel the current command. + @node Database use, Getting information, Entering queries, Tutorial @section Creating and Using a Database @@ -12326,6 +12446,7 @@ mysql> GRANT ALL ON menagerie.* TO your_mysql_name; where @code{your_mysql_name} is the @strong{MySQL} user name assigned to you. + @node Creating database, Creating tables, Database use, Database use @subsection Creating and Selecting a Database @@ -12374,6 +12495,7 @@ option, you must do so with no intervening space (for example, as password on the command line is not recommended, because doing so exposes it to snooping by other users logged in on your machine. + @node Creating tables, Loading tables, Creating database, Database use @subsection Creating a Table @@ -12479,6 +12601,7 @@ mysql> DESCRIBE pet; You can use @code{DESCRIBE} any time, for example, if you forget the names of the columns in your table or what types they are. + @node Loading tables, Retrieving data, Creating tables, Database use @subsection Loading Data into a Table @@ -12553,6 +12676,7 @@ typing involved to load your records initially using several @code{INSERT} statements rather than a single @code{LOAD DATA} statement. + @node Retrieving data, , Loading tables, Database use @subsection Retrieving Information from a Table @@ -12588,6 +12712,7 @@ indicates the table from which you want to retrieve data. The @code{WHERE} clause is optional. If it's present, @code{conditions_to_satisfy} specifies conditions that rows must satisfy to qualify for retrieval. + @node Selecting all, Selecting rows, Retrieving data, Retrieving data @subsubsection Selecting All Data @@ -12646,6 +12771,7 @@ case you specify some constraints on the information you want. Let's look at some selection queries in terms of questions about your pets that they answer. + @node Selecting rows, Selecting columns, Selecting all, Retrieving data @subsubsection Selecting Particular Rows @@ -12724,6 +12850,7 @@ mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m") +-------+--------+---------+------+------------+-------+ @end example + @node Selecting columns, Sorting rows, Selecting rows, Retrieving data @subsubsection Selecting Particular Columns @@ -12807,6 +12934,7 @@ mysql> SELECT name, species, birth FROM pet +--------+---------+------------+ @end example + @node Sorting rows, Date calculations, Selecting columns, Retrieving data @subsubsection Sorting Rows @@ -12884,6 +13012,7 @@ Note that the @code{DESC} keyword applies only to the column name immediately preceding it (@code{birth}); @code{species} values are still sorted in ascending order. + @node Date calculations, Working with NULL, Sorting rows, Retrieving data @subsubsection Date Calculations @@ -13057,6 +13186,7 @@ Note that @code{MONTH} returns a number between 1 and 12. And addition has to be after the @code{MOD()} otherwise we would go from November (11) to January (1). + @node Working with NULL, Pattern matching, Date calculations, Retrieving data @subsubsection Working with @code{NULL} Values @@ -13097,6 +13227,7 @@ This special treatment of @code{NULL} is why, in the previous section, it was necessary to determine which animals are no longer alive using @code{death IS NOT NULL} instead of @code{death != NULL}. + @node Pattern matching, Counting rows, Working with NULL, Retrieving data @subsubsection Pattern Matching @@ -13295,6 +13426,7 @@ mysql> SELECT * FROM pet WHERE name REGEXP "^.@{5@}$"; +-------+--------+---------+------+------------+-------+ @end example + @node Counting rows, Multiple tables, Pattern matching, Retrieving data @subsubsection Counting Rows @@ -13434,6 +13566,7 @@ mysql> SELECT species, sex, COUNT(*) FROM pet +---------+------+----------+ @end example + @node Multiple tables, , Counting rows, Retrieving data @subsubsection Using More Than one Table @@ -13555,6 +13688,7 @@ In this query, we specify aliases for the table name in order to refer to the columns and keep straight which instance of the table each column reference is associated with. + @node Getting information, Examples, Database use, Tutorial @section Getting Information About Databases and Tables @@ -13620,6 +13754,7 @@ indexed, and @code{Default} specifies the column's default value. If you have indexes on a table, @code{SHOW INDEX FROM tbl_name} produces information about them. + @node Examples, Batch mode, Getting information, Tutorial @section Examples of Common Queries @@ -13685,6 +13820,7 @@ mysql> SELECT * FROM shop; * Calculating days:: @end menu + @node example-Maximum-column, example-Maximum-row, Examples, Examples @subsection The Maximum Value for a Column @@ -13700,6 +13836,7 @@ SELECT MAX(article) AS article FROM shop +---------+ @end example + @node example-Maximum-row, example-Maximum-column-group, example-Maximum-column, Examples @subsection The Row Holding the Maximum of a Certain Column @@ -13741,6 +13878,7 @@ LIMIT 1 @strong{NOTE}: If there are several most expensive articles (for example, each 19.95) the @code{LIMIT} solution shows only one of them! + @node example-Maximum-column-group, example-Maximum-column-group-row, example-Maximum-row, Examples @subsection Maximum of Column per Group @@ -13761,6 +13899,7 @@ GROUP BY article +---------+-------+ @end example + @node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples @subsection The Rows Holding the Group-wise Maximum of a Certain Field @@ -13832,6 +13971,7 @@ GROUP BY article; The last example can, of course, be made a bit more efficient by doing the splitting of the concatenated column in the client. + @node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples @subsection Using user variables @@ -13854,6 +13994,7 @@ select * from shop where price=@@min_price or price=@@max_price; +---------+--------+-------+ @end example + @node example-Foreign keys, Searching on two keys, example-user-variables, Examples @subsection Using Foreign Keys @@ -13937,6 +14078,7 @@ SELECT s.* FROM persons p, shirts s +----+-------+--------+-------+ @end example + @node Searching on two keys, Calculating days, example-Foreign keys, Examples @subsection Searching on Two Keys @@ -13973,6 +14115,7 @@ DROP TABLE tmp; The above way to solve this query is in effect an @code{UNION} of two queries. + @node Calculating days, , Searching on two keys, Examples @subsection Calculating visits per day @@ -14003,6 +14146,7 @@ Which returns: The above calculates how many different days was used for a given year/month combination, with automatic removal of duplicate entries. + @node Batch mode, Twin, Examples, Tutorial @section Using @code{mysql} in Batch Mode @@ -14105,6 +14249,7 @@ If you want to get the interactive output format in batch mode, use @code{mysql -t}. To echo to the output the commands that are executed, use @code{mysql -vvv}. + @node Twin, Apache, Batch mode, Tutorial @section Queries from Twin Project @@ -14143,6 +14288,7 @@ database. * Twin event:: Show a table on twin pair status @end menu + @node Twin pool, Twin event, Twin, Twin @subsection Find all Non-distributed Twins @@ -14266,6 +14412,7 @@ The current number of records in the tables used above: @item @code{postal_groups} @tab 100 @end multitable + @node Twin event, , Twin pool, Twin @subsection Show a Table on Twin Pair Status @@ -14324,6 +14471,8 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' @end example + + @node MySQL Database Administration, MySQL Optimization, Tutorial, Top @chapter MySQL Database Administration @@ -14352,6 +14501,7 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' * Multiple servers:: @end menu + @node Command-line options, Option files, Configuring MySQL, Configuring MySQL @subsection mysqld Command-line Options @@ -14595,6 +14745,13 @@ Disable using thread priorities for faster response time. Socket file to use for local connections instead of default @code{/tmp/mysql.sock}. +@item --sql-mode=option[,option[,option...]] +Option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, +IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY. + +By specifying all of the above options is same as using --ansi. +With this option one can turn on only needed SQL modes. @xref{ANSI mode}. + @item transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @} Sets the default transaction isolation level. @xref{SET TRANSACTION}. @@ -14866,6 +15023,7 @@ argument to @code{safe_mysqld}. * Multiple servers:: @end menu + @node Multiple servers, , Installing many servers, Configuring MySQL @subsection Running Multiple MySQL Servers on the Same Machine @@ -15325,6 +15483,7 @@ can do this by setting the @code{max_user_connections} variable in @code{mysqld}. @end itemize + @node Privileges options, What Privileges, Security, Privilege system @subsection Startup Options for @code{mysqld} Concerning Security @@ -17755,6 +17914,7 @@ make a lot of changes to a table) * Optimization:: @end menu + @node myisamchk syntax, myisamchk general options, Table maintenance, Table maintenance @subsubsection @code{myisamchk} Invocation Syntax @@ -18027,6 +18187,7 @@ of duplicate keys Unpack file packed with myisampack. @end table + @node myisamchk other options, myisamchk memory, myisamchk repair options, Table maintenance @subsubsection Other Options for @code{myisamchk} @@ -18057,6 +18218,7 @@ table's indexes in the same order that @code{myisamchk} sees them. Indexes are numbered beginning with 1. @end table + @node myisamchk memory, Crash recovery, myisamchk other options, Table maintenance @subsubsection @code{myisamchk} Memory Usage @@ -18850,6 +19012,7 @@ information and a description of what it means. * SHOW:: @end menu + @node OPTIMIZE TABLE, ANALYZE TABLE, Database Administration, Database Administration @subsection @code{OPTIMIZE TABLE} Syntax @@ -19050,6 +19213,7 @@ write is aborted with an disk full error message. * SHOW:: @end menu + @node SHOW, , KILL, Database Administration @subsection @code{SHOW} Syntax @@ -20404,7 +20568,7 @@ The list below briefly describes the @strong{MySQL} programs: @item myisamchk Utility to describe, check, optimize, and repair @strong{MySQL} tables. Because @code{myisamchk} has many functions, it is described in its own -chapter. @xref{Maintenance}. +chapter. @xref{MySQL Database Administration}. @cindex @code{make_binary_distribution} @item make_binary_distribution @@ -21266,6 +21430,7 @@ binaries includes: * Client-Side Overview:: * mysql:: * mysqladmin:: +* Using mysqlcheck:: * mysqldump:: * mysqlhotcopy:: * mysqlimport:: @@ -21332,7 +21497,7 @@ The list below briefly describes the @strong{MySQL} programs: @item myisamchk Utility to describe, check, optimize, and repair @strong{MySQL} tables. Because @code{myisamchk} has many functions, it is described in its own -chapter. @xref{Maintenance}. +chapter. @xref{MySQL Database Administration}. @cindex @code{make_binary_distribution} @item make_binary_distribution @@ -21755,7 +21920,7 @@ file, but want to be able to turn the feature off sometimes. @end itemize -@node mysqladmin, mysqldump, mysql, Client-Side Scripts +@node mysqladmin, Using mysqlcheck, mysql, Client-Side Scripts @subsection mysqladmin, Administrating a MySQL Server @cindex administration, server @@ -21875,7 +22040,131 @@ wait until the @strong{MySQL} @code{pid-file} is removed to ensure that the @code{mysqld} server has stopped properly. -@node mysqldump, mysqlhotcopy, mysqladmin, Client-Side Scripts +@node Using mysqlcheck, mysqldump, mysqladmin, Client-Side Scripts +@subsection Using @code{mysqlcheck} for Table Maintenance and Crash Recovery + +Since @strong{MySQL} version 3.23.38 you will be able to use a new +checking and repairing tool for @code{MyISAM} tables. The difference to +@code{myisamchk} is that @code{mysqlcheck} should be used when the +@code{mysqld} server is running, where as @code{myisamchk} should be used +when it is not. The benefit is that you no longer have to take the +server down for checking or repairing your tables. + +@code{mysqlcheck} uses @strong{MySQL} server commands @code{CHECK}, +@code{REPAIR}, @code{ANALYZE} and @code{OPTIMIZE} in a convenient way +for the user. + +There are three alternative ways to invoke @code{mysqlcheck}: + +@example +shell> mysqlcheck [OPTIONS] database [tables] +shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...] +shell> mysqlcheck [OPTIONS] --all-databases +@end example + +So it can be used in a similar way as @code{mysqldump} when it +comes to what databases and tables you want to choose. + +@code{mysqlcheck} does have a special feature compared to the other +clients; the default behavior, checking tables (-c), can be changed by +renaming the binary. So if you want to have a tool that repairs tables +by default, you should just copy @code{mysqlcheck} to your harddrive +with a new name, @code{mysqlrepair}, or alternatively make a symbolic +link to @code{mysqlrepair} and name the symbolic link as +@code{mysqlrepair}. If you invoke @code{mysqlrepair} now, it will repair +tables by default. + +The names that you can use to change @code{mysqlcheck} default behavior +are here: + +@example +mysqlrepair: The default option will be -r +mysqlanalyze: The default option will be -a +mysqloptimize: The default option will be -o +@end example + +The options available for @code{mysqlcheck} are listed here, please +check what your version supports with @code{mysqlcheck --help}. + +@table @code +@item -A, --all-databases +Check all the databases. This will be same as --databases with all +databases selected +@item -1, --all-in-1 +Instead of making one query for each table, execute all queries in 1 +query separately for each database. Table names will be in a comma +separated list. +@item -a, --analyze +Analyze given tables. +@item --auto-repair +If a checked table is corrupted, automatically fix it. Repairing will be +done after all tables have been checked, if corrupted ones were found. +@item -#, --debug=... +Output debug log. Often this is 'd:t:o,filename' +@item --character-sets-dir=... +Directory where character sets are +@item -c, --check +Check table for errors +@item -C, --check-only-changed +Check only tables that have changed since last check or haven't been +closed properly. +@item --compress +Use compression in server/client protocol. +@item -?, --help +Display this help message and exit. +@item -B, --databases +To check several databases. Note the difference in usage; In this case +no tables are given. All name arguments are regarded as database names. +@item --default-character-set=... +Set the default character set +@item -F, --fast +Check only tables that hasn't been closed properly +@item -f, --force +Continue even if we get an sql-error. +@item -e, --extended +If you are using this option with CHECK TABLE, it will ensure that the +table is 100 percent consistent, but will take a long time. + +If you are using this option with REPAIR TABLE, it will run an extended +repair on the table, which may not only take a long time to execute, but +may produce a lot of garbage rows also! +@item -h, --host=... +Connect to host. +@item -m, --medium-check +Faster than extended-check, but only finds 99.99 percent of all +errors. Should be good enough for most cases. +@item -o, --optimize +Optimize table +@item -p, --password[=...] +Password to use when connecting to server. If password is not given +it's solicited on the tty. +@item -P, --port=... +Port number to use for connection. +@item -q, --quick +If you are using this option with CHECK TABLE, it prevents the check +from scanning the rows to check for wrong links. This is the fastest +check. + +If you are using this option with REPAIR TABLE, it will try to repair +only the index tree. This is the fastest repair method for a table. +@item -r, --repair +Can fix almost anything except unique keys that aren't unique. +@item -s, --silent +Print only error messages. +@item -S, --socket=... +Socket file to use for connection. +@item --tables +Overrides option --databases (-B). +@item -u, --user=# +User for login if not current user. +@item -v, --verbose +Print info about the various stages. +@item -V, --version +Output version information and exit. +@end table + + +@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts @subsection mysqldump, Dumping Table Structure and Data @cindex dumping, databases @@ -22742,9 +23031,6 @@ the new updates. Note that if you are replicating a database, all updates to this database should be done through the master! -On older servers one can use the update log to do simple replication. -@xref{Log Replication}. - Another benefit of using replication is that one can get live backups of the system by doing a backup on a slave instead of doing it on the master. @xref{Backup}. @@ -22923,6 +23209,7 @@ it is preferred that you use @code{CHANGE MASTER TO} command. * Replication Problems:: @end menu + @node Replication Features, Replication Options, Replication HOWTO, Replication @subsection Replication Features and Known Problems @@ -23708,6 +23995,8 @@ isolate it into a separate test case first. Then report the problem to @email{bugs@@lists.mysql.com} with as much info as possible. + + @node MySQL Optimization, Reference, MySQL Database Administration, Top @chapter MySQL Optimization @@ -23776,6 +24065,7 @@ for most systems, but one should be aware of it. * Custom Benchmarks:: @end menu + @node Design Limitations, Portability, Optimize Overview, Optimize Overview @subsection MySQL Design Limitations/Tradeoffs @@ -23868,6 +24158,7 @@ In this case the table creation information should contain information of the initial size of the cache and how often the table should normally be refreshed. + @node Internal use, MySQL Benchmarks, Portability, Optimize Overview @subsection What Have We Used MySQL For? @@ -24667,6 +24958,7 @@ mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ; mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,... ; @end example + @node DISTINCT optimization, LEFT JOIN optimization, Where optimizations, Query Speed @subsection How MySQL Optimizes @code{DISTINCT} @@ -24791,6 +25083,7 @@ The size of temporary tables uses the @code{LIMIT #} to calculate how much space is needed to resolve the query. @end itemize + @node Insert speed, Update speed, LIMIT optimization, Query Speed @subsection Speed of @code{INSERT} Queries @@ -25138,6 +25431,7 @@ from the data, you should not lose anything by using @code{DELAY_KEY_WRITE}. * Table locking:: @end menu + @node Internal locking, Table locking, Locking Issues, Locking Issues @subsection How MySQL Locks Tables @@ -25327,6 +25621,7 @@ option to @code{DELETE} may help. @xref{DELETE, , @code{DELETE}}. * Open tables:: @end menu + @node Design, Data size, Optimizing Database Structure, Optimizing Database Structure @subsection Design Choices @@ -25624,6 +25919,7 @@ much more quickly find the few rows to return in the result. * Open tables:: @end menu + @node Indexes, Multiple-column indexes, MySQL indexes, Optimizing Database Structure @subsection Column Indexes @@ -25838,6 +26134,7 @@ between all threads. * SET OPTION:: @end menu + @node System, Server parameters, Optimizing the Server, Optimizing the Server @subsection System/Compile Time and Startup Parameter Tuning @@ -26419,30 +26716,7 @@ with the update log. * SET TRANSACTION:: @end menu -@node SET TRANSACTION, , SET OPTION, SET OPTION -@subsubsection @code{SET TRANSACTION} Syntax -@findex ISOLATION LEVEL - -@example -SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL -[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE] -@end example - -Sets the transaction isolation level for the global, whole session or -the next transaction. - -The default behavior is to set the isolation level for the next (not started) -transaction. - -If you set the @code{GLOBAL} privilege it will affect all new created threads. -You will need the @code{PROCESS} privilege to do do this. - -Setting the @code{SESSION} privilege will affect the following and all -future transactions. - -You can set the default isolation level for @code{mysqld} with -@code{--transaction-isolation=...}. @xref{Command-line options}. @node Disk issues, , Optimizing the Server, MySQL Optimization @@ -26539,6 +26813,7 @@ with the noatime flag. * Symbolic links:: @end menu + @node Symbolic links, , Disk issues, Disk issues @subsection Using Symbolic Links @@ -26682,44 +26957,24 @@ Things that are not yet supported: @item @code{mysqldump} doesn't include the symbolic links information in the output. @item -@code{BACKUP TABLE} and @code{RESTORE TABLE} doesn't use symbolic links. +@code{BACKUP TABLE} and @code{RESTORE TABLE} don't respect symbolic links. @end itemize - @node Reference, Table types, MySQL Optimization, Top @chapter MySQL Language Reference @menu -* Literals:: Literals: How to write strings and numbers -* Variables:: User variables +* Language Structure:: * Column types:: Column types * Functions:: Functions -* CREATE DATABASE:: @code{CREATE DATABASE} syntax -* DROP DATABASE:: @code{DROP DATABASE} syntax -* CREATE TABLE:: @code{CREATE TABLE} syntax -* ALTER TABLE:: @code{ALTER TABLE} syntax -* RENAME TABLE:: @code{RENAME TABLE} syntax -* DROP TABLE:: @code{DROP TABLE} syntax -* DELETE:: @code{DELETE} syntax -* TRUNCATE:: @code{TRUNCATE} syntax -* SELECT:: @code{SELECT} syntax -* JOIN:: @code{JOIN} syntax -* INSERT:: @code{INSERT} syntax -* REPLACE:: @code{REPLACE} syntax -* LOAD DATA:: @code{LOAD DATA INFILE} syntax -* UPDATE:: @code{UPDATE} syntax -* USE:: @code{USE} syntax -* DESCRIBE:: @code{DESCRIBE} syntax (Get information about names of columns) -* COMMIT:: @code{BEGIN/COMMIT/ROLLBACK} syntax -* LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax -* CREATE INDEX:: @code{CREATE INDEX} syntax -* DROP INDEX:: @code{DROP INDEX} syntax -* Comments:: Comment syntax -* CREATE FUNCTION:: @code{CREATE FUNCTION} syntax -* Reserved words:: Is @strong{MySQL} picky about reserved words? +* Data Manipulation:: +* Data Definition:: +* Basic User Commands:: +* Transactional Commands:: +* Fulltext Search:: @end menu @strong{MySQL} has a very complex, but intuitive and easy to learn SQL @@ -26730,8 +26985,21 @@ included in @strong{MySQL}. In order to use this chapter effectively, you may find it useful to refer to the various indexes. -@node Literals, Variables, Reference, Reference -@section Literals: How to Write Strings and Numbers +@node Language Structure, Column types, Reference, Reference +@section Language Structure + +@menu +* Literals:: +* Legal names:: +* Name case sensitivity:: +* Variables:: +* Comments:: +* Reserved words:: +@end menu + + +@node Literals, Legal names, Language Structure, Language Structure +@subsection Literals: How to Write Strings and Numbers @cindex strings, defined @cindex strings, escaping characters @@ -26744,15 +27012,16 @@ may find it useful to refer to the various indexes. * Number syntax:: Numbers * Hexadecimal values:: Hexadecimal values * NULL values:: @code{NULL} values -* Legal names:: Database, Table, Index, Column, and Alias Names @end menu + This section describes the various ways to write strings and numbers in @strong{MySQL}. It also covers the various nuances and ``gotchas'' that you may run into when dealing with these basic types in @strong{MySQL}. + @node String syntax, Number syntax, Literals, Literals -@subsection Strings +@subsubsection Strings A string is a sequence of characters, surrounded by either single quote (@samp{'}) or double quote (@samp{"}) characters (only the single quote @@ -26909,13 +27178,15 @@ characters to the proper escape sequences. @xref{Perl DBI Class, , Perl You should use an escape function on any string that might contain any of the special characters listed above! + +@node Number syntax, Hexadecimal values, String syntax, Literals +@subsubsection Numbers + @cindex numbers @cindex valid numbers, examples @cindex integers @cindex floats @cindex negative values -@node Number syntax, Hexadecimal values, String syntax, Literals -@subsection Numbers Integers are represented as a sequence of digits. Floats use @samp{.} as a decimal separator. Either type of number may be preceded by @samp{-} to @@ -26940,9 +27211,11 @@ Examples of valid floating-point numbers: An integer may be used in a floating-point context; it is interpreted as the equivalent floating-point number. -@tindex hexadecimal values + @node Hexadecimal values, NULL values, Number syntax, Literals -@subsection Hexadecimal Values +@subsubsection Hexadecimal Values + +@tindex hexadecimal values @strong{MySQL} supports hexadecimal values. In number context these act like an integer (64-bit precision). In string context these act like a binary @@ -26957,9 +27230,11 @@ mysql> select 0x5061756c; Hexadecimal strings are often used by ODBC to give values for BLOB columns. + +@node NULL values, , Hexadecimal values, Literals +@subsubsection @code{NULL} Values + @tindex NULL value -@node NULL values, Legal names, Hexadecimal values, Literals -@subsection @code{NULL} Values The @code{NULL} value means ``no data'' and is different from values such as @code{0} for numeric types or the empty string for string types. @@ -26969,6 +27244,10 @@ as @code{0} for numeric types or the empty string for string types. or export formats (@code{LOAD DATA INFILE}, @code{SELECT ... INTO OUTFILE}). @xref{LOAD DATA, , @code{LOAD DATA}}. + +@node Legal names, Name case sensitivity, Literals, Language Structure +@subsection Database, Table, Index, Column, and Alias Names + @cindex names @cindex legal names @cindex databases, names @@ -26976,13 +27255,12 @@ or export formats (@code{LOAD DATA INFILE}, @code{SELECT ... INTO OUTFILE}). @cindex indexes, names @cindex columns, names @cindex aliases, names -@node Legal names, , NULL values, Literals -@subsection Database, Table, Index, Column, and Alias Names @menu * Name case sensitivity:: Case sensitivity in names @end menu + Database, table, index, column, and alias names all follow the same rules in @strong{MySQL}. @@ -27069,10 +27347,12 @@ The syntax @code{.tbl_name} means the table @code{tbl_name} in the current database. This syntax is accepted for ODBC compatibility, because some ODBC programs prefix table names with a @samp{.} character. + +@node Name case sensitivity, Variables, Legal names, Language Structure +@subsection Case Sensitivity in Names + @cindex names, case-sensitivity @cindex case-sensitivity, in names -@node Name case sensitivity, , Legal names, Legal names -@subsubsection Case Sensitivity in Names @cindex database names, case sensitivity @cindex table names, case sensitivity @cindex column names, case sensitivity @@ -27118,11 +27398,13 @@ table names to lower case on storage and lookup. Note that if you change this option, you need to first convert your old table names to lower case before starting @code{mysqld}. + +@node Variables, Comments, Name case sensitivity, Language Structure +@subsection User Variables + @cindex variables, user @cindex user variables @cindex names, variables -@node Variables, Column types, Literals, Reference -@section User Variables @strong{MySQL} supports thread-specific variables with the @code{@@variablename} syntax. A variable name may consist of @@ -27176,10 +27458,183 @@ SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM table_name HAVING b=5; The reason is that @code{@@aa} will not contain the value of the current row, but the value of @code{id} for the previous accepted row. + +@menu +* Comments:: +* Reserved words:: +@end menu + +@node Comments, Reserved words, Variables, Language Structure +@subsection Comment Syntax + +@findex Comment syntax + +@cindex comments, adding + +The @strong{MySQL} server supports the @code{# to end of line}, @code{-- +to end of line} and @code{/* in-line or multiple-line */} comment +styles: + +@example +mysql> select 1+1; # This comment continues to the end of line +mysql> select 1+1; -- This comment continues to the end of line +mysql> select 1 /* this is an in-line comment */ + 1; +mysql> select 1+ +/* +this is a +multiple-line comment +*/ +1; +@end example + +Note that the @code{--} comment style requires you to have at least one space +after the @code{--}! + +Although the server understands the comment syntax just described, +there are some limitations on the way that the @code{mysql} client +parses @code{/* ... */} comments: + +@itemize @bullet +@item +Single-quote and double-quote characters are taken to indicate the beginning +of a quoted string, even within a comment. If the quote is not matched by a +second quote within the comment, the parser doesn't realize the comment has +ended. If you are running @code{mysql} interactively, you can tell that it +has gotten confused like this because the prompt changes from @code{mysql>} +to @code{'>} or @code{">}. + +@item +A semicolon is taken to indicate the end of the current SQL statement +and anything following it to indicate the beginning of the next statement. +@end itemize + +These limitations apply both when you run @code{mysql} interactively +and when you put commands in a file and tell @code{mysql} to read its +input from that file with @code{mysql < some-file}. + +@strong{MySQL} doesn't support the @samp{--} ANSI SQL comment style. +@xref{Missing comments}. + + +@node Reserved words, , Comments, Language Structure +@subsection Is MySQL Picky About Reserved Words? + +@cindex keywords +@cindex reserved words, exceptions + +A common problem stems from trying to create a table with column names that +use the names of datatypes or functions built into @strong{MySQL}, such as +@code{TIMESTAMP} or @code{GROUP}. 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 @samp{(} when using functions whose names are also +column names. + +The following words are explicitly reserved in @strong{MySQL}. Most of +them are forbidden by ANSI SQL92 as column and/or table names +(for example, @code{group}). +A few are reserved because @strong{MySQL} needs them and is +(currently) using a @code{yacc} parser: + +@c This is fixed by including the symbols table from lex.h here and then running +@c fix-mysql-reserved-words in emacs (or let David do it): +@c (defun fix-mysql-reserved-words () +@c (interactive) +@c (let ((cnt 0)) +@c (insert "\n@item ") +@c (while (looking-at "[ \t]*{ +\"\\([^\"]+\\)\"[ \t]*,.*\n") +@c (replace-match "@code{\\1}") +@c (incf cnt) +@c (if (> cnt 3) +@c (progn +@c (setf cnt 0) +@c (insert "\n@item ")) +@c (insert " @tab "))))) +@c But remove the non alphanumeric entries by hand first. +@c Updated after 3.23.4 990928 by David + +@multitable @columnfractions .25 .25 .25 .25 +@item @code{action} @tab @code{add} @tab @code{aggregate} @tab @code{all} +@item @code{alter} @tab @code{after} @tab @code{and} @tab @code{as} +@item @code{asc} @tab @code{avg} @tab @code{avg_row_length} @tab @code{auto_increment} +@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary} +@item @code{blob} @tab @code{bool} @tab @code{both} @tab @code{by} +@item @code{cascade} @tab @code{case} @tab @code{char} @tab @code{character} +@item @code{change} @tab @code{check} @tab @code{checksum} @tab @code{column} +@item @code{columns} @tab @code{comment} @tab @code{constraint} @tab @code{create} +@item @code{cross} @tab @code{current_date} @tab @code{current_time} @tab @code{current_timestamp} +@item @code{data} @tab @code{database} @tab @code{databases} @tab @code{date} +@item @code{datetime} @tab @code{day} @tab @code{day_hour} @tab @code{day_minute} +@item @code{day_second} @tab @code{dayofmonth} @tab @code{dayofweek} @tab @code{dayofyear} +@item @code{dec} @tab @code{decimal} @tab @code{default} @tab @code{delayed} +@item @code{delay_key_write} @tab @code{delete} @tab @code{desc} @tab @code{describe} +@item @code{distinct} @tab @code{distinctrow} @tab @code{double} @tab @code{drop} +@item @code{end} @tab @code{else} @tab @code{escape} @tab @code{escaped} +@item @code{enclosed} @tab @code{enum} @tab @code{explain} @tab @code{exists} +@item @code{fields} @tab @code{file} @tab @code{first} @tab @code{float} +@item @code{float4} @tab @code{float8} @tab @code{flush} @tab @code{foreign} +@item @code{from} @tab @code{for} @tab @code{full} @tab @code{function} +@item @code{global} @tab @code{grant} @tab @code{grants} @tab @code{group} +@item @code{having} @tab @code{heap} @tab @code{high_priority} @tab @code{hour} +@item @code{hour_minute} @tab @code{hour_second} @tab @code{hosts} @tab @code{identified} +@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile} +@item @code{inner} @tab @code{insert} @tab @code{insert_id} @tab @code{int} +@item @code{integer} @tab @code{interval} @tab @code{int1} @tab @code{int2} +@item @code{int3} @tab @code{int4} @tab @code{int8} @tab @code{into} +@item @code{if} @tab @code{is} @tab @code{isam} @tab @code{join} +@item @code{key} @tab @code{keys} @tab @code{kill} @tab @code{last_insert_id} +@item @code{leading} @tab @code{left} @tab @code{length} @tab @code{like} +@item @code{lines} @tab @code{limit} @tab @code{load} @tab @code{local} +@item @code{lock} @tab @code{logs} @tab @code{long} @tab @code{longblob} +@item @code{longtext} @tab @code{low_priority} @tab @code{max} @tab @code{max_rows} +@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint} +@item @code{middleint} @tab @code{min_rows} @tab @code{minute} @tab @code{minute_second} +@item @code{modify} @tab @code{month} @tab @code{monthname} @tab @code{myisam} +@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not} +@item @code{null} @tab @code{on} @tab @code{optimize} @tab @code{option} +@item @code{optionally} @tab @code{or} @tab @code{order} @tab @code{outer} +@item @code{outfile} @tab @code{pack_keys} @tab @code{partial} @tab @code{password} +@item @code{precision} @tab @code{primary} @tab @code{procedure} @tab @code{process} +@item @code{processlist} @tab @code{privileges} @tab @code{read} @tab @code{real} +@item @code{references} @tab @code{reload} @tab @code{regexp} @tab @code{rename} +@item @code{replace} @tab @code{restrict} @tab @code{returns} @tab @code{revoke} +@item @code{rlike} @tab @code{row} @tab @code{rows} @tab @code{second} +@item @code{select} @tab @code{set} @tab @code{show} @tab @code{shutdown} +@item @code{smallint} @tab @code{soname} @tab @code{sql_big_tables} @tab @code{sql_big_selects} +@item @code{sql_low_priority_updates} @tab @code{sql_log_off} @tab @code{sql_log_update} @tab @code{sql_select_limit} +@item @code{sql_small_result} @tab @code{sql_big_result} @tab @code{sql_warnings} @tab @code{straight_join} +@item @code{starting} @tab @code{status} @tab @code{string} @tab @code{table} +@item @code{tables} @tab @code{temporary} @tab @code{terminated} @tab @code{text} +@item @code{then} @tab @code{time} @tab @code{timestamp} @tab @code{tinyblob} +@item @code{tinytext} @tab @code{tinyint} @tab @code{trailing} @tab @code{to} +@item @code{type} @tab @code{use} @tab @code{using} @tab @code{unique} +@item @code{unlock} @tab @code{unsigned} @tab @code{update} @tab @code{usage} +@item @code{values} @tab @code{varchar} @tab @code{variables} @tab @code{varying} +@item @code{varbinary} @tab @code{with} @tab @code{write} @tab @code{when} +@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 these names are very natural names and a lot of people have already +used them. + +@itemize @bullet +@item @code{ACTION} +@item @code{BIT} +@item @code{DATE} +@item @code{ENUM} +@item @code{NO} +@item @code{TEXT} +@item @code{TIME} +@item @code{TIMESTAMP} +@end itemize + + +@node Column types, Functions, Language Structure, Reference +@section Column Types + @cindex columns, types @cindex types, columns -@node Column types, Functions, Variables, Reference -@section Column Types @strong{MySQL} supports a number of column types, which may be grouped into three categories: numeric types, date and time types, and string (character) @@ -27506,116 +27961,16 @@ be chosen from the list of values @code{'value1'}, @code{'value2'}, @end table @menu -* Storage requirements:: Column type storage requirements * Numeric types:: Numeric types * Date and time types:: Date and time types * String types:: String types * Choosing types:: Choosing the right type for a column * Other-vendor column types:: Using column types from other database engines +* Storage requirements:: Column type storage requirements @end menu -@cindex storage requirements, column type -@cindex columns, storage requirements -@node Storage requirements, Numeric types, Column types, Column types -@subsection Column Type Storage Requirements - -The storage requirements for each of the column types supported by -@strong{MySQL} are listed below by category. - -@cindex numeric types -@cindex types, numeric - -@subsubheading Storage requirements for numeric types - -@multitable @columnfractions .5 .5 -@item @strong{Column type} @tab @strong{Storage required} -@item @code{TINYINT} @tab 1 byte -@item @code{SMALLINT} @tab 2 bytes -@item @code{MEDIUMINT} @tab 3 bytes -@item @code{INT} @tab 4 bytes -@item @code{INTEGER} @tab 4 bytes -@item @code{BIGINT} @tab 8 bytes -@item @code{FLOAT(X)} @tab 4 if X <= 24 or 8 if 25 <= X <= 53 -@item @code{FLOAT} @tab 4 bytes -@item @code{DOUBLE} @tab 8 bytes -@item @code{DOUBLE PRECISION} @tab 8 bytes -@item @code{REAL} @tab 8 bytes -@item @code{DECIMAL(M,D)} @tab @code{M+2} bytes if D > 0, @code{M+1} bytes if D = 0 (@code{D}+2, if @code{M < D}) -@item @code{NUMERIC(M,D)} @tab @code{M+2} bytes if D > 0, @code{M+1} bytes if D = 0 (@code{D}+2, if @code{M < D}) -@end multitable - -@cindex date types -@cindex time types -@cindex types, date -@cindex types, time - -@subsubheading Storage requirements for date and time types - -@multitable @columnfractions .5 .5 -@item @strong{Column type} @tab @strong{Storage required} -@item @code{DATE} @tab 3 bytes -@item @code{DATETIME} @tab 8 bytes -@item @code{TIMESTAMP} @tab 4 bytes -@item @code{TIME} @tab 3 bytes -@item @code{YEAR} @tab 1 byte -@end multitable - -@subsubheading Storage requirements for string types - -@multitable @columnfractions .5 .5 -@item @strong{Column type} @tab @strong{Storage required} -@item @code{CHAR(M)} @tab @code{M} bytes, @code{1 <= M <= 255} -@item @code{VARCHAR(M)} @tab @code{L}+1 bytes, where @code{L <= M} and -@code{1 <= M <= 255} -@item @code{TINYBLOB}, @code{TINYTEXT} @tab @code{L}+1 bytes, -where @code{L} < 2^8 -@item @code{BLOB}, @code{TEXT} @tab @code{L}+2 bytes, -where @code{L} < 2^16 -@item @code{MEDIUMBLOB}, @code{MEDIUMTEXT} @tab @code{L}+3 bytes, -where @code{L} < 2^24 -@item @code{LONGBLOB}, @code{LONGTEXT} @tab @code{L}+4 bytes, -where @code{L} < 2^32 -@item @code{ENUM('value1','value2',...)} @tab 1 or 2 bytes, depending on -the number of enumeration values (65535 values maximum) -@item @code{SET('value1','value2',...)} @tab 1, 2, 3, 4 or 8 bytes, depending -on the number of set members (64 members maximum) -@end multitable - -@cindex BLOB, size -@cindex TEXT, size -@cindex VARCHAR, size -@code{VARCHAR} and the @code{BLOB} and @code{TEXT} types are variable-length -types, for which the storage requirements depend on the actual length of -column values (represented by @code{L} in the preceding table), rather than -on the type's maximum possible size. For example, a @code{VARCHAR(10)} -column can hold a string with a maximum length of 10 characters. The actual -storage required is the length of the string (@code{L}), plus 1 byte to -record the length of the string. For the string @code{'abcd'}, @code{L} is 4 -and the storage requirement is 5 bytes. - -The @code{BLOB} and @code{TEXT} types require 1, 2, 3, or 4 bytes to record -the length of the column value, depending on the maximum possible length of -the type. @xref{BLOB}. - -If a table includes any variable-length column types, the record format will -also be variable-length. Note that when a table is created, @strong{MySQL} -may, under certain conditions, change a column from a variable-length type to a -fixed-length type, or vice-versa. @xref{Silent column changes}. - -@cindex ENUM, size -The size of an @code{ENUM} object is determined by the number of -different enumeration values. One byte is used for enumerations with up -to 255 possible values. Two bytes are used for enumerations with up to -65535 values. @xref{ENUM}. - -@cindex SET, size -The size of a @code{SET} object is determined by the number of different -set members. If the set size is @code{N}, the object occupies @code{(N+7)/8} -bytes, rounded up to 1, 2, 3, 4, or 8 bytes. A @code{SET} can have a maximum -of 64 members. @xref{SET}. - -@node Numeric types, Date and time types, Storage requirements, Column types +@node Numeric types, Date and time types, Column types, Column types @subsection Numeric Types @strong{MySQL} supports all of the ANSI/ISO SQL92 numeric types. These @@ -27741,11 +28096,13 @@ Conversions that occur due to clipping are reported as ``warnings'' for @code{ALTER TABLE}, @code{LOAD DATA INFILE}, @code{UPDATE}, and multi-row @code{INSERT} statements. -@cindex types, Date and Time -@cindex Date and Time types + @node Date and time types, String types, Numeric types, Column types @subsection Date and Time Types +@cindex types, Date and Time +@cindex Date and Time types + @menu * Y2K issues:: Y2K issues and date types * DATETIME:: The @code{DATETIME}, @code{DATE} and @code{TIMESTAMP} types @@ -27753,6 +28110,7 @@ multi-row @code{INSERT} statements. * YEAR:: The @code{YEAR} type @end menu + The date and time types are @code{DATETIME}, @code{DATE}, @code{TIMESTAMP}, @code{TIME}, and @code{YEAR}. Each of these has a range of legal values, as well as a ``zero'' value that is used when you @@ -27822,11 +28180,13 @@ automatically to @code{NULL} in @strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle such values. @end itemize -@cindex Year 2000 issues -@cindex date types, Y2K issues + @node Y2K issues, DATETIME, Date and time types, Date and time types @subsubsection Y2K Issues and Date Types +@cindex Year 2000 issues +@cindex date types, Y2K issues + @strong{MySQL} itself is Y2K-safe (@pxref{Year 2000 compliance}), but input values presented to @strong{MySQL} may not be. Any input containing 2-digit year values is ambiguous, because the century is unknown. @@ -27858,11 +28218,13 @@ Note also that some functions like @code{MIN()} and @code{MAX()} will convert a case is to convert the @code{TIMESTAMP/DATE} to 4-digit year format or use something like @code{MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS))}. + +@node DATETIME, TIME, Y2K issues, Date and time types +@subsubsection The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} Types + @tindex DATETIME @tindex DATE @tindex TIMESTAMP -@node DATETIME, TIME, Y2K issues, Date and time types -@subsubsection The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} Types The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} types are related. This section describes their characteristics, how they are similar, and how @@ -28119,10 +28481,12 @@ Year values in the range @code{70-99} are converted to @code{1970-1999}. @end itemize @end itemize -@tindex TIME + @node TIME, YEAR, DATETIME, Date and time types @subsubsection The @code{TIME} Type +@tindex TIME + @strong{MySQL} retrieves and displays @code{TIME} values in @code{'HH:MM:SS'} format (or @code{'HHH:MM:SS'} format for large hours values). @code{TIME} values may range from @code{'-838:59:59'} to @code{'838:59:59'}. The reason @@ -28188,10 +28552,12 @@ because @code{'00:00:00'} is itself a legal @code{TIME} value, there is no way to tell, from a value of @code{'00:00:00'} stored in a table, whether the original value was specified as @code{'00:00:00'} or whether it was illegal. -@tindex YEAR + @node YEAR, , TIME, Date and time types @subsubsection The @code{YEAR} Type +@tindex YEAR + The @code{YEAR} type is a 1-byte type used for representing years. @strong{MySQL} retrieves and displays @code{YEAR} values in @code{YYYY} @@ -28229,13 +28595,16 @@ in a @code{YEAR} context, such as @code{NOW()}. Illegal @code{YEAR} values are converted to @code{0000}. -@cindex types, strings -@cindex string types + @node String types, Choosing types, Date and time types, Column types @subsection String Types +@cindex types, strings +@cindex string types + @tindex CHAR @tindex VARCHAR + @menu * CHAR:: The @code{CHAR} and @code{VARCHAR} types * BLOB:: The @code{BLOB} and @code{TEXT} types @@ -28243,10 +28612,12 @@ Illegal @code{YEAR} values are converted to @code{0000}. * SET:: The @code{SET} type @end menu + The string types are @code{CHAR}, @code{VARCHAR}, @code{BLOB}, @code{TEXT}, @code{ENUM}, and @code{SET}. This section describes how these types work, their storage requirements, and how to use them in your queries. + @node CHAR, BLOB, String types, String types @subsubsection The @code{CHAR} and @code{VARCHAR} Types @@ -28306,11 +28677,13 @@ The @code{BINARY} attribute is sticky. This means that if a column marked column at table creation time. @xref{Silent column changes}. -@tindex BLOB -@tindex TEXT + @node BLOB, ENUM, CHAR, String types @subsubsection The @code{BLOB} and @code{TEXT} Types +@tindex BLOB +@tindex TEXT + A @code{BLOB} is a binary large object that can hold a variable amount of data. The four @code{BLOB} types @code{TINYBLOB}, @code{BLOB}, @code{MEDIUMBLOB}, and @code{LONGBLOB} differ only in the maximum length of @@ -28393,10 +28766,12 @@ internally by a separately allocated object. This is in contrast to all other column types, for which storage is allocated once per column when the table is opened. -@tindex ENUM + @node ENUM, SET, BLOB, String types @subsubsection The @code{ENUM} Type +@tindex ENUM + An @code{ENUM} is a string object whose value normally is chosen from a list of allowed values that are enumerated explicitly in the column specification at table creation time. @@ -28480,10 +28855,12 @@ If you want to get all possible values for an @code{ENUM} column, you should use: @code{SHOW COLUMNS FROM table_name LIKE enum_column_name} and parse the @code{ENUM} definition in the second column. -@tindex SET + @node SET, , ENUM, String types @subsubsection The @code{SET} Type +@tindex SET + A @code{SET} is a string object that can have zero or more values, each of which must be chosen from a list of allowed values specified when the table is created. @code{SET} column values that consist of multiple set members @@ -28565,11 +28942,13 @@ If you want to get all possible values for a @code{SET} column, you should use: @code{SHOW COLUMNS FROM table_name LIKE set_column_name} and parse the @code{SET} definition in the second column. -@cindex types, columns -@cindex choosing types + @node Choosing types, Other-vendor column types, String types, Column types @subsection Choosing the Right Type for a Column +@cindex types, columns +@cindex choosing types + For the most efficient use of storage, try to use the most precise type in all cases. For example, if an integer column will be used for values in the range between @code{1} and @code{99999}, @code{MEDIUMINT UNSIGNED} is the @@ -28585,7 +28964,7 @@ in a @code{BIGINT}. This allows you to do all calculations with integers and convert results back to floating-point values only when necessary. -@node Other-vendor column types, , Choosing types, Column types +@node Other-vendor column types, Storage requirements, Choosing types, Column types @subsection Using Column Types from Other Database Engines @cindex types, portability @@ -28619,10 +28998,114 @@ with types used by other vendors and then issue a @code{DESCRIBE tbl_name} statement, @strong{MySQL} reports the table structure using the equivalent @strong{MySQL} types. -@cindex functions for @code{SELECT} and @code{WHERE} clauses -@node Functions, CREATE DATABASE, Column types, Reference + +@node Storage requirements, , Other-vendor column types, Column types +@subsection Column Type Storage Requirements + +@cindex storage requirements, column type +@cindex columns, storage requirements + +The storage requirements for each of the column types supported by +@strong{MySQL} are listed below by category. + +@cindex numeric types +@cindex types, numeric + +@subsubheading Storage requirements for numeric types + +@multitable @columnfractions .5 .5 +@item @strong{Column type} @tab @strong{Storage required} +@item @code{TINYINT} @tab 1 byte +@item @code{SMALLINT} @tab 2 bytes +@item @code{MEDIUMINT} @tab 3 bytes +@item @code{INT} @tab 4 bytes +@item @code{INTEGER} @tab 4 bytes +@item @code{BIGINT} @tab 8 bytes +@item @code{FLOAT(X)} @tab 4 if X <= 24 or 8 if 25 <= X <= 53 +@item @code{FLOAT} @tab 4 bytes +@item @code{DOUBLE} @tab 8 bytes +@item @code{DOUBLE PRECISION} @tab 8 bytes +@item @code{REAL} @tab 8 bytes +@item @code{DECIMAL(M,D)} @tab @code{M+2} bytes if D > 0, @code{M+1} bytes if D = 0 (@code{D}+2, if @code{M < D}) +@item @code{NUMERIC(M,D)} @tab @code{M+2} bytes if D > 0, @code{M+1} bytes if D = 0 (@code{D}+2, if @code{M < D}) +@end multitable + +@cindex date types +@cindex time types +@cindex types, date +@cindex types, time + +@subsubheading Storage requirements for date and time types + +@multitable @columnfractions .5 .5 +@item @strong{Column type} @tab @strong{Storage required} +@item @code{DATE} @tab 3 bytes +@item @code{DATETIME} @tab 8 bytes +@item @code{TIMESTAMP} @tab 4 bytes +@item @code{TIME} @tab 3 bytes +@item @code{YEAR} @tab 1 byte +@end multitable + +@subsubheading Storage requirements for string types + +@multitable @columnfractions .5 .5 +@item @strong{Column type} @tab @strong{Storage required} +@item @code{CHAR(M)} @tab @code{M} bytes, @code{1 <= M <= 255} +@item @code{VARCHAR(M)} @tab @code{L}+1 bytes, where @code{L <= M} and +@code{1 <= M <= 255} +@item @code{TINYBLOB}, @code{TINYTEXT} @tab @code{L}+1 bytes, +where @code{L} < 2^8 +@item @code{BLOB}, @code{TEXT} @tab @code{L}+2 bytes, +where @code{L} < 2^16 +@item @code{MEDIUMBLOB}, @code{MEDIUMTEXT} @tab @code{L}+3 bytes, +where @code{L} < 2^24 +@item @code{LONGBLOB}, @code{LONGTEXT} @tab @code{L}+4 bytes, +where @code{L} < 2^32 +@item @code{ENUM('value1','value2',...)} @tab 1 or 2 bytes, depending on +the number of enumeration values (65535 values maximum) +@item @code{SET('value1','value2',...)} @tab 1, 2, 3, 4 or 8 bytes, depending +on the number of set members (64 members maximum) +@end multitable + +@cindex BLOB, size +@cindex TEXT, size +@cindex VARCHAR, size +@code{VARCHAR} and the @code{BLOB} and @code{TEXT} types are variable-length +types, for which the storage requirements depend on the actual length of +column values (represented by @code{L} in the preceding table), rather than +on the type's maximum possible size. For example, a @code{VARCHAR(10)} +column can hold a string with a maximum length of 10 characters. The actual +storage required is the length of the string (@code{L}), plus 1 byte to +record the length of the string. For the string @code{'abcd'}, @code{L} is 4 +and the storage requirement is 5 bytes. + +The @code{BLOB} and @code{TEXT} types require 1, 2, 3, or 4 bytes to record +the length of the column value, depending on the maximum possible length of +the type. @xref{BLOB}. + +If a table includes any variable-length column types, the record format will +also be variable-length. Note that when a table is created, @strong{MySQL} +may, under certain conditions, change a column from a variable-length type to a +fixed-length type, or vice-versa. @xref{Silent column changes}. + +@cindex ENUM, size +The size of an @code{ENUM} object is determined by the number of +different enumeration values. One byte is used for enumerations with up +to 255 possible values. Two bytes are used for enumerations with up to +65535 values. @xref{ENUM}. + +@cindex SET, size +The size of a @code{SET} object is determined by the number of different +set members. If the set size is @code{N}, the object occupies @code{(N+7)/8} +bytes, rounded up to 1, 2, 3, 4, or 8 bytes. A @code{SET} can have a maximum +of 64 members. @xref{SET}. + + +@node Functions, Data Manipulation, Column types, Reference @section Functions for Use in @code{SELECT} and @code{WHERE} Clauses +@cindex functions for @code{SELECT} and @code{WHERE} clauses + A @code{select_expression} or @code{where_definition} in a SQL statement can consist of any expression using the functions described below. @@ -28664,229 +29147,57 @@ mysql> select MOD(29,9); @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 -* Casts:: Cast operators -* Control flow functions:: Control flow functions -* Mathematical functions:: Mathematical functions +* Non-typed Operators:: * String functions:: String functions +* Numeric Functions:: * Date and time functions:: Date and time functions -* Miscellaneous functions:: Miscellaneous functions -* Group by functions:: Functions for @code{GROUP BY} clause +* Other Functions:: @end menu -@cindex functions, grouping -@cindex grouping, expressions -@node Grouping functions, Arithmetic functions, Functions, Functions -@subsection Grouping Functions -@table @code + +@node Non-typed Operators, String functions, Functions, Functions +@subsection Non-Type-Specific Operators and Functions + +@menu +* Parenthesis:: +* Comparison Operators:: +* Logical Operators:: +* Control flow functions:: +@end menu + + +@node Parenthesis, Comparison Operators, Non-typed Operators, Non-typed Operators +@subsubsection Parenthesis @findex () (parentheses) @findex parentheses ( and ) -@item ( ... ) -Parentheses. Use these to force the order of evaluation in an expression: + +@cindex functions, grouping +@cindex grouping, expressions + +@example +( ... ) +@end example + +Use parenthesis to force the order of evaluation in an expression. For +example: + @example mysql> select 1+2*3; -> 7 mysql> select (1+2)*3; -> 9 @end example -@end table -@node Arithmetic functions, Bit functions, Grouping functions, Functions -@subsection Normal Arithmetic Operations -The usual arithmetic operators are available. Note that in the case of -@samp{-}, @samp{+}, and @samp{*}, the result is calculated with -@code{BIGINT} (64-bit) precision if both arguments are integers! -@cindex operations, arithmetic -@cindex arithmetic expressions -@table @code -@findex + (addition) -@findex addition (+) -@item + -Addition: -@example -mysql> select 3+5; - -> 8 -@end example +@node Comparison Operators, Logical Operators, Parenthesis, Non-typed Operators +@subsubsection Comparison Operators -@findex - (subtraction) -@findex subtraction (-) -@item - -Subtraction: -@example -mysql> select 3-5; - -> -2 -@end example - -@findex * (multiplication) -@findex multiplication (*) -@item * -Multiplication: -@example -mysql> select 3*5; - -> 15 -mysql> select 18014398509481984*18014398509481984.0; - -> 324518553658426726783156020576256.0 -mysql> select 18014398509481984*18014398509481984; - -> 0 -@end example - -The result of the last expression is incorrect because the result of the integer -multiplication exceeds the 64-bit range of @code{BIGINT} calculations. - -@findex / (division) -@findex division (/) -@item / -Division: -@example -mysql> select 3/5; - -> 0.60 -@end example - -Division by zero produces a @code{NULL} result: - -@example -mysql> select 102/(1-1); - -> NULL -@end example - -A division will be calculated with @code{BIGINT} arithmetic only if performed -in a context where its result is converted to an integer! -@end table - -@findex arithmetic functions -@findex bit functions -@findex functions, arithmetic -@findex functions, bit -@node Bit functions, Logical functions, Arithmetic functions, Functions -@subsection Bit Functions - -@strong{MySQL} uses @code{BIGINT} (64-bit) arithmetic for bit operations, so -these operators have a maximum range of 64 bits. - -@table @code -@findex | (bitwise OR) -@findex OR, bitwise -@item | -Bitwise OR: -@example -mysql> select 29 | 15; - -> 31 -@end example - -@findex & (bitwise AND) -@findex AND, bitwise -@item & -Bitwise AND: -@example -mysql> select 29 & 15; - -> 13 -@end example - -@findex << (left shift) -@item << -Shifts a longlong (@code{BIGINT}) number to the left: -@example -mysql> select 1 << 2; - -> 4 -@end example - -@findex >> (right shift) -@item >> -Shifts a longlong (@code{BIGINT}) number to the right: -@example -mysql> select 4 >> 2; - -> 1 -@end example - -@findex ~ -@item ~ -Invert all bits: -@example -mysql> select 5 & ~1; - -> 4 -@end example - -@findex BIT_COUNT() -@item BIT_COUNT(N) -Returns the number of bits that are set in the argument @code{N}: -@example -mysql> select BIT_COUNT(29); - -> 4 -@end example -@end table - -@findex Logical functions -@findex Functions, logical -@node Logical functions, Comparison functions, Bit functions, Functions -@subsection Logical Operations - -All logical functions return @code{1} (TRUE), @code{0} (FALSE) or -@code{NULL} (unknown, which is in most cases the same as FALSE): - -@table @code -@findex NOT, logical -@findex ! (logical NOT) -@item NOT -@itemx ! -Logical NOT. Returns @code{1} if the argument is @code{0}, otherwise returns -@code{0}. -Exception: @code{NOT NULL} returns @code{NULL}: -@example -mysql> select NOT 1; - -> 0 -mysql> select NOT NULL; - -> NULL -mysql> select ! (1+1); - -> 0 -mysql> select ! 1+1; - -> 1 -@end example -The last example returns @code{1} because the expression evaluates -the same way as @code{(!1)+1}. - -@findex OR, logical -@findex || (logical OR) -@item OR -@itemx || -Logical OR. Returns @code{1} if either argument is not @code{0} and not -@code{NULL}: -@example -mysql> select 1 || 0; - -> 1 -mysql> select 0 || 0; - -> 0 -mysql> select 1 || NULL; - -> 1 - -@end example - -@findex AND, logical -@findex && (logical AND) -@item AND -@itemx && -Logical AND. Returns @code{0} if either argument is @code{0} or @code{NULL}, -otherwise returns @code{1}: -@example -mysql> select 1 && NULL; - -> 0 -mysql> select 1 && 0; - -> 0 -@end example -@end table +@findex comparison operators @cindex casts @cindex type conversions -@findex comparison operators -@node Comparison functions, String comparison functions, Logical functions, Functions -@subsection Comparison Operators Comparison operations result in a value of @code{1} (TRUE), @code{0} (FALSE), or @code{NULL}. These functions work for both numbers and strings. Strings @@ -28990,8 +29301,8 @@ mysql> select 0.1 <= 2; @item < Less than: @example -mysql> select 2 <= 2; - -> 1 +mysql> select 2 < 2; + -> 0 @end example @findex >= (greater than or equal) @@ -29135,193 +29446,73 @@ mysql> select INTERVAL(22, 23, 30, 44, 200); @end example @end table -@findex string comparison functions -@findex functions, string comparison -@node String comparison functions, Casts, Comparison functions, Functions -@subsection String Comparison Functions -@cindex case sensitivity, in string comparisons -@cindex string comparisons, case sensitivity -Normally, if any expression in a string comparison is case sensitive, the -comparison is performed in case-sensitive fashion. +@node Logical Operators, Control flow functions, Comparison Operators, Non-typed Operators +@subsubsection Logical Operators + +@findex Logical functions +@findex Functions, logical + +All logical functions return @code{1} (TRUE), @code{0} (FALSE) or +@code{NULL} (unknown, which is in most cases the same as FALSE): @table @code -@findex LIKE -@item expr LIKE pat [ESCAPE 'escape-char'] -Pattern matching using -SQL simple regular expression comparison. Returns @code{1} (TRUE) or @code{0} -(FALSE). With @code{LIKE} you can use the following two wild-card characters -in the pattern: - -@multitable @columnfractions .1 .9 -@item @code{%} @tab Matches any number of characters, even zero characters -@item @code{_} @tab Matches exactly one character -@end multitable - +@findex NOT, logical +@findex ! (logical NOT) +@item NOT +@itemx ! +Logical NOT. Returns @code{1} if the argument is @code{0}, otherwise returns +@code{0}. +Exception: @code{NOT NULL} returns @code{NULL}: @example -mysql> select 'David!' LIKE 'David_'; - -> 1 -mysql> select 'David!' LIKE '%D%v%'; - -> 1 -@end example - -To test for literal instances of a wild-card character, precede the character -with the escape character. If you don't specify the @code{ESCAPE} character, -@samp{\} is assumed: - -@multitable @columnfractions .1 .9 -@item @code{\%} @tab Matches one @code{%} character -@item @code{\_} @tab Matches one @code{_} character -@end multitable - -@example -mysql> select 'David!' LIKE 'David\_'; +mysql> select NOT 1; -> 0 -mysql> select 'David_' LIKE 'David\_'; +mysql> select NOT NULL; + -> NULL +mysql> select ! (1+1); + -> 0 +mysql> select ! 1+1; -> 1 @end example +The last example returns @code{1} because the expression evaluates +the same way as @code{(!1)+1}. -To specify a different escape character, use the @code{ESCAPE} clause: - +@findex OR, logical +@findex || (logical OR) +@item OR +@itemx || +Logical OR. Returns @code{1} if either argument is not @code{0} and not +@code{NULL}: @example -mysql> select 'David_' LIKE 'David|_' ESCAPE '|'; +mysql> select 1 || 0; -> 1 +mysql> select 0 || 0; + -> 0 +mysql> select 1 || NULL; + -> 1 + @end example -The following two statements illustrate that string comparisons are -case insensitive unless one of the operands is a binary string: - +@findex AND, logical +@findex && (logical AND) +@item AND +@itemx && +Logical AND. Returns @code{0} if either argument is @code{0} or @code{NULL}, +otherwise returns @code{1}: @example -mysql> select 'abc' LIKE 'ABC'; - -> 1 -mysql> SELECT 'abc' LIKE BINARY 'ABC'; +mysql> select 1 && NULL; + -> 0 +mysql> select 1 && 0; -> 0 @end example - -@code{LIKE} is allowed on numeric expressions! (This is a @strong{MySQL} -extension to the ANSI SQL @code{LIKE}.) - -@example -mysql> select 10 LIKE '1%'; - -> 1 -@end example - -Note: Because @strong{MySQL} uses the C escape syntax in strings (for example, -@samp{\n}), you must double any @samp{\} that you use in your @code{LIKE} -strings. For example, to search for @samp{\n}, specify it as @samp{\\n}. To -search for @samp{\}, specify it as @samp{\\\\} (the backslashes are stripped -once by the parser and another time when the pattern match is done, leaving -a single backslash to be matched). - -@findex NOT LIKE -@item expr NOT LIKE pat [ESCAPE 'escape-char'] -Same as @code{NOT (expr LIKE pat [ESCAPE 'escape-char'])}. - -@cindex mSQL compatibility -@cindex compatibility, with mSQL -@findex REGEXP -@findex RLIKE -@item expr REGEXP pat -@itemx expr RLIKE pat -Performs a pattern match of a string expression @code{expr} against a pattern -@code{pat}. The pattern can be an extended regular expression. -@xref{Regexp}. Returns @code{1} if @code{expr} matches @code{pat}, otherwise -returns @code{0}. @code{RLIKE} is a synonym for @code{REGEXP}, provided for -@code{mSQL} compatibility. Note: Because @strong{MySQL} uses the C escape -syntax in strings (for example, @samp{\n}), you must double any @samp{\} that -you use in your @code{REGEXP} strings. As of @strong{MySQL} Version 3.23.4, -@code{REGEXP} is case insensitive for normal (not binary) strings: - -@example -mysql> select 'Monty!' REGEXP 'm%y%%'; - -> 0 -mysql> select 'Monty!' REGEXP '.*'; - -> 1 -mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line'; - -> 1 -mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A"; - -> 1 0 -mysql> select "a" REGEXP "^[a-d]"; - -> 1 -@end example - -@item -@code{REGEXP} and @code{RLIKE} use the current character set (ISO-8859-1 -Latin1 by default) when deciding the type of a character. - -@findex NOT REGEXP -@item expr NOT REGEXP pat -@itemx expr NOT RLIKE pat -Same as @code{NOT (expr REGEXP pat)}. - -@findex STRCMP() -@item STRCMP(expr1,expr2) -@code{STRCMP()} -returns @code{0} if the strings are the same, @code{-1} if the first -argument is smaller than the second according to the current sort order, -and @code{1} otherwise: - -@example -mysql> select STRCMP('text', 'text2'); - -> -1 -mysql> select STRCMP('text2', 'text'); - -> 1 -mysql> select STRCMP('text', 'text'); - -> 0 -@end example - -@findex MATCH ... AGAINST() -@item MATCH (col1,col2,...) AGAINST (expr) -@code{MATCH ... AGAINST()} is used for full-text search and returns -relevance - similarity measure between the text in columns -@code{(col1,col2,...)} and the query @code{expr}. Relevance is a -positive floating-point number. Zero relevance means no similarity. -For @code{MATCH ... AGAINST()} to work, a @strong{FULLTEXT} index -must be created first. @xref{CREATE TABLE, , @code{CREATE TABLE}}. -@code{MATCH ... AGAINST()} is available in @strong{MySQL} Version -3.23.23 or later. For details and usage examples -@pxref{Fulltext Search}. @end table -@findex casts -@cindex cast operators -@cindex operators, cast -@node Casts, Control flow functions, String comparison functions, Functions -@subsection Cast Operators -@table @code -@findex BINARY -@item @code{BINARY} -The @code{BINARY} operator casts the string following it to a binary string. -This is an easy way to force a column comparison to be case sensitive even -if the column isn't defined as @code{BINARY} or @code{BLOB}: -@example -mysql> select "a" = "A"; - -> 1 -mysql> select BINARY "a" = "A"; - -> 0 -@end example - -@code{BINARY} was introduced in @strong{MySQL} Version 3.23.0. - -Note that in some context @strong{MySQL} will not be able to use the -index efficiently when you cast an indexed column to @code{BINARY}. -@end table - -If you want to compare a blob case-insensitively you can always convert -the blob to upper case before doing the comparison: - -@example -SELECT 'A' LIKE UPPER(blob_col) FROM table_name; -@end example - -We plan to soon introduce casting between different character sets to -make string comparison even more flexible. +@node Control flow functions, , Logical Operators, Non-typed Operators +@subsubsection Control Flow Functions @findex control flow functions @findex functions, control flow -@node Control flow functions, Mathematical functions, Casts, Functions -@subsection Control Flow Functions @table @code @cindex @code{NULL}, testing for null @@ -29423,400 +29614,12 @@ The type of the return value (@code{INTEGER}, @code{DOUBLE} or @code{STRING}) is the same as the type of the first returned value (the expression after the first @code{THEN}). -@findex mathematical functions -@findex functions, mathematical -@node Mathematical functions, String functions, Control flow functions, Functions -@subsection Mathematical Functions -All mathematical functions return @code{NULL} in case of an error. -@table @code -@findex - (unary minus) -@findex minus, unary (-) -@findex unary minus (-) -@item - -Unary minus. Changes the sign of the argument: -@example -mysql> select - 2; - -> -2 -@end example - -Note that if this operator is used with a @code{BIGINT}, the return value is a -@code{BIGINT}! This means that you should avoid using @code{-} on integers that -may have the value of @code{-2^63}! - -@findex ABS() -@item ABS(X) -Returns the absolute value of @code{X}: -@example -mysql> select ABS(2); - -> 2 -mysql> select ABS(-32); - -> 32 -@end example - -This function is safe to use with @code{BIGINT} values. - -@findex SIGN() -@item SIGN(X) -Returns the sign of the argument as @code{-1}, @code{0}, or @code{1}, depending -on whether @code{X} is negative, zero, or positive: -@example -mysql> select SIGN(-32); - -> -1 -mysql> select SIGN(0); - -> 0 -mysql> select SIGN(234); - -> 1 -@end example - -@findex MOD() -@findex % (modulo) -@findex modulo (%) -@item MOD(N,M) -@itemx % -Modulo (like the @code{%} operator in C). -Returns the remainder of @code{N} divided by @code{M}: -@example -mysql> select MOD(234, 10); - -> 4 -mysql> select 253 % 7; - -> 1 -mysql> select MOD(29,9); - -> 2 -@end example - -This function is safe to use with @code{BIGINT} values. - -@findex FLOOR() -@item FLOOR(X) -Returns the largest integer value not greater than @code{X}: -@example -mysql> select FLOOR(1.23); - -> 1 -mysql> select FLOOR(-1.23); - -> -2 -@end example - -Note that the return value is converted to a @code{BIGINT}! - -@findex CEILING() -@item CEILING(X) -Returns the smallest integer value not less than @code{X}: -@example -mysql> select CEILING(1.23); - -> 2 -mysql> select CEILING(-1.23); - -> -1 -@end example - -Note that the return value is converted to a @code{BIGINT}! - -@findex ROUND() -@item ROUND(X) -Returns the argument @code{X}, rounded to the nearest integer: -@example -mysql> select ROUND(-1.23); - -> -1 -mysql> select ROUND(-1.58); - -> -2 -mysql> select ROUND(1.58); - -> 2 -@end example - -Note that the behavior of @code{ROUND()} when the argument -is half way between two integers depends on the C library -implementation. Some round to the nearest even number, -always up, always down, or always towards zero. If you need -one kind of rounding, you should use a well-defined function -like @code{TRUNCATE()} or @code{FLOOR()} instead. - -@findex ROUND() -@item ROUND(X,D) -Returns the argument @code{X}, rounded to a number with @code{D} decimals. -If @code{D} is @code{0}, the result will have no decimal point or fractional -part: - -@example -mysql> select ROUND(1.298, 1); - -> 1.3 -mysql> select ROUND(1.298, 0); - -> 1 -@end example - -@findex EXP() -@item EXP(X) -Returns the value of @code{e} (the base of natural logarithms) raised to -the power of @code{X}: -@example -mysql> select EXP(2); - -> 7.389056 -mysql> select EXP(-2); - -> 0.135335 -@end example -@findex LOG() -@item LOG(X) -Returns the natural logarithm of @code{X}: -@example -mysql> select LOG(2); - -> 0.693147 -mysql> select LOG(-2); - -> NULL -@end example -If you want the log of a number @code{X} to some arbitary base @code{B}, use -the formula @code{LOG(X)/LOG(B)}. - -@findex LOG10() -@item LOG10(X) -Returns 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 - -@findex POW() -@findex POWER() -@item POW(X,Y) -@itemx POWER(X,Y) -Returns 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 - -@findex SQRT() -@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 - -@findex PI() -@item PI() -Returns the value of PI. The default shown number of decimals is 5, but -@strong{MySQL} internally uses the full double precession for PI. -@example -mysql> select PI(); - -> 3.141593 -mysql> SELECT PI()+0.000000000000000000; - -> 3.141592653589793116 -@end example - -@findex COS() -@item COS(X) -Returns the cosine of @code{X}, where @code{X} is given in radians: -@example -mysql> select COS(PI()); - -> -1.000000 -@end example - -@findex SIN() -@item SIN(X) -Returns the sine of @code{X}, where @code{X} is given in radians: -@example -mysql> select SIN(PI()); - -> 0.000000 -@end example - -@findex TAN() -@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 - -@findex ACOS() -@item ACOS(X) -Returns the arc cosine of @code{X}, that is, the value whose cosine is -@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to -@code{1}: -@example -mysql> select ACOS(1); - -> 0.000000 -mysql> select ACOS(1.0001); - -> NULL -mysql> select ACOS(0); - -> 1.570796 -@end example - -@findex ASIN() -@item ASIN(X) -Returns the arc sine of @code{X}, that is, the value whose sine is -@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to -@code{1}: -@example -mysql> select ASIN(0.2); - -> 0.201358 -mysql> select ASIN('foo'); - -> 0.000000 -@end example - -@findex ATAN() -@item ATAN(X) -Returns 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 - -@findex ATAN2() -@item ATAN2(Y,X) -Returns 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 - -@findex COT() -@item COT(X) -Returns the cotangent of @code{X}: -@example -mysql> select COT(12); - -> -1.57267341 -mysql> select COT(0); - -> NULL -@end example - -@findex RAND() -@item RAND() -@itemx RAND(N) -Returns a random floating-point value in the range @code{0} to @code{1.0}. -If an integer argument @code{N} is specified, it is used as the 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 -You can't use a column with @code{RAND()} values in an @code{ORDER BY} -clause, because @code{ORDER BY} would evaluate the column multiple times. -In @strong{MySQL} Version 3.23, you can, however, do: -@code{SELECT * FROM table_name ORDER BY RAND()} - -This is useful to get a random sample of a set @code{SELECT * FROM -table1,table2 WHERE a=b AND c select LEAST(2,0); - -> 0 -mysql> select LEAST(34.0,3.0,5.0,767.0); - -> 3.0 -mysql> select LEAST("B","A","C"); - -> "A" -@end example -In @strong{MySQL} versions prior to Version 3.22.5, you can use @code{MIN()} -instead of @code{LEAST}. - -@findex GREATEST() -@item GREATEST(X,Y,...) -Returns the largest (maximum-valued) argument. -The arguments are compared using the same rules as for @code{LEAST}: -@example -mysql> select GREATEST(2,0); - -> 2 -mysql> select GREATEST(34.0,3.0,5.0,767.0); - -> 767.0 -mysql> select GREATEST("B","A","C"); - -> "C" -@end example -In @strong{MySQL} versions prior to Version 3.22.5, you can use @code{MAX()} -instead of @code{GREATEST}. - -@findex DEGREES() -@item DEGREES(X) -Returns the argument @code{X}, converted from radians to degrees: -@example -mysql> select DEGREES(PI()); - -> 180.000000 -@end example - -@findex RADIANS() -@item RADIANS(X) -Returns the argument @code{X}, converted from degrees to radians: -@example -mysql> select RADIANS(90); - -> 1.570796 -@end example - -@findex TRUNCATE() -@item TRUNCATE(X,D) -Returns the number @code{X}, truncated to @code{D} decimals. If @code{D} -is @code{0}, the result will have no decimal point or fractional part: -@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 - -Note that as decimal numbers are normally not stored as exact numbers in -computers, but as double values, you may be fooled by the following -result: - -@cindex rounding errors -@example -mysql> select TRUNCATE(10.28*100,0); - -> 1027 -@end example - -The above happens because 10.28 is actually stored as something like -10.2799999999999999. -@end table +@node String functions, Numeric Functions, Non-typed Operators, Functions +@subsection String Functions @findex string functions @findex functions, string -@node String functions, Date and time functions, Mathematical functions, Functions -@subsection String Functions String-valued functions return @code{NULL} if the length of the result would be greater than the @code{max_allowed_packet} server parameter. @xref{Server @@ -30373,10 +30176,672 @@ If a string function is given a binary string as an argument, the resulting string is also a binary string. A number converted to a string is treated as a binary string. This only affects comparisons. + +@menu +* String comparison functions:: +* Case Sensitivity Operators:: +@end menu + +@node String comparison functions, Case Sensitivity Operators, String functions, String functions +@subsubsection String Comparison Functions + +@findex string comparison functions +@findex functions, string comparison + +@cindex case sensitivity, in string comparisons +@cindex string comparisons, case sensitivity + +Normally, if any expression in a string comparison is case sensitive, the +comparison is performed in case-sensitive fashion. + +@table @code +@findex LIKE +@item expr LIKE pat [ESCAPE 'escape-char'] +Pattern matching using +SQL simple regular expression comparison. Returns @code{1} (TRUE) or @code{0} +(FALSE). With @code{LIKE} you can use the following two wild-card characters +in the pattern: + +@multitable @columnfractions .1 .9 +@item @code{%} @tab Matches any number of characters, even zero characters +@item @code{_} @tab Matches exactly one character +@end multitable + +@example +mysql> select 'David!' LIKE 'David_'; + -> 1 +mysql> select 'David!' LIKE '%D%v%'; + -> 1 +@end example + +To test for literal instances of a wild-card character, precede the character +with the escape character. If you don't specify the @code{ESCAPE} character, +@samp{\} is assumed: + +@multitable @columnfractions .1 .9 +@item @code{\%} @tab Matches one @code{%} character +@item @code{\_} @tab Matches one @code{_} character +@end multitable + +@example +mysql> select 'David!' LIKE 'David\_'; + -> 0 +mysql> select 'David_' LIKE 'David\_'; + -> 1 +@end example + +To specify a different escape character, use the @code{ESCAPE} clause: + +@example +mysql> select 'David_' LIKE 'David|_' ESCAPE '|'; + -> 1 +@end example + +The following two statements illustrate that string comparisons are +case insensitive unless one of the operands is a binary string: + +@example +mysql> select 'abc' LIKE 'ABC'; + -> 1 +mysql> SELECT 'abc' LIKE BINARY 'ABC'; + -> 0 +@end example + +@code{LIKE} is allowed on numeric expressions! (This is a @strong{MySQL} +extension to the ANSI SQL @code{LIKE}.) + +@example +mysql> select 10 LIKE '1%'; + -> 1 +@end example + +Note: Because @strong{MySQL} uses the C escape syntax in strings (for example, +@samp{\n}), you must double any @samp{\} that you use in your @code{LIKE} +strings. For example, to search for @samp{\n}, specify it as @samp{\\n}. To +search for @samp{\}, specify it as @samp{\\\\} (the backslashes are stripped +once by the parser and another time when the pattern match is done, leaving +a single backslash to be matched). + +@findex NOT LIKE +@item expr NOT LIKE pat [ESCAPE 'escape-char'] +Same as @code{NOT (expr LIKE pat [ESCAPE 'escape-char'])}. + +@cindex mSQL compatibility +@cindex compatibility, with mSQL +@findex REGEXP +@findex RLIKE +@item expr REGEXP pat +@itemx expr RLIKE pat +Performs a pattern match of a string expression @code{expr} against a pattern +@code{pat}. The pattern can be an extended regular expression. +@xref{Regexp}. Returns @code{1} if @code{expr} matches @code{pat}, otherwise +returns @code{0}. @code{RLIKE} is a synonym for @code{REGEXP}, provided for +@code{mSQL} compatibility. Note: Because @strong{MySQL} uses the C escape +syntax in strings (for example, @samp{\n}), you must double any @samp{\} that +you use in your @code{REGEXP} strings. As of @strong{MySQL} Version 3.23.4, +@code{REGEXP} is case insensitive for normal (not binary) strings: + +@example +mysql> select 'Monty!' REGEXP 'm%y%%'; + -> 0 +mysql> select 'Monty!' REGEXP '.*'; + -> 1 +mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line'; + -> 1 +mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A"; + -> 1 0 +mysql> select "a" REGEXP "^[a-d]"; + -> 1 +@end example + +@item +@code{REGEXP} and @code{RLIKE} use the current character set (ISO-8859-1 +Latin1 by default) when deciding the type of a character. + +@findex NOT REGEXP +@item expr NOT REGEXP pat +@itemx expr NOT RLIKE pat +Same as @code{NOT (expr REGEXP pat)}. + +@findex STRCMP() +@item STRCMP(expr1,expr2) +@code{STRCMP()} +returns @code{0} if the strings are the same, @code{-1} if the first +argument is smaller than the second according to the current sort order, +and @code{1} otherwise: + +@example +mysql> select STRCMP('text', 'text2'); + -> -1 +mysql> select STRCMP('text2', 'text'); + -> 1 +mysql> select STRCMP('text', 'text'); + -> 0 +@end example + +@findex MATCH ... AGAINST() +@item MATCH (col1,col2,...) AGAINST (expr) +@code{MATCH ... AGAINST()} is used for full-text search and returns +relevance - similarity measure between the text in columns +@code{(col1,col2,...)} and the query @code{expr}. Relevance is a +positive floating-point number. Zero relevance means no similarity. +For @code{MATCH ... AGAINST()} to work, a @strong{FULLTEXT} index +must be created first. @xref{CREATE TABLE, , @code{CREATE TABLE}}. +@code{MATCH ... AGAINST()} is available in @strong{MySQL} Version +3.23.23 or later. For details and usage examples +@pxref{Fulltext Search}. +@end table + + +@node Case Sensitivity Operators, , String comparison functions, String functions +@subsubsection Case Sensitivity + +@findex casts + +@cindex cast operators +@cindex operators, cast + +@table @code +@findex BINARY +@item @code{BINARY} +The @code{BINARY} operator casts the string following it to a binary string. +This is an easy way to force a column comparison to be case sensitive even +if the column isn't defined as @code{BINARY} or @code{BLOB}: +@example +mysql> select "a" = "A"; + -> 1 +mysql> select BINARY "a" = "A"; + -> 0 +@end example + +@code{BINARY} was introduced in @strong{MySQL} Version 3.23.0. + +Note that in some context @strong{MySQL} will not be able to use the +index efficiently when you cast an indexed column to @code{BINARY}. +@end table + +If you want to compare a blob case-insensitively you can always convert +the blob to upper case before doing the comparison: + +@example +SELECT 'A' LIKE UPPER(blob_col) FROM table_name; +@end example + +We plan to soon introduce casting between different character sets to +make string comparison even more flexible. + + +@node Numeric Functions, Date and time functions, String functions, Functions +@subsection Numeric Functions + +@menu +* Arithmetic functions:: +* Mathematical functions:: +@end menu + + +@node Arithmetic functions, Mathematical functions, Numeric Functions, Numeric Functions +@subsubsection Arithmetic Operations + +The usual arithmetic operators are available. Note that in the case of +@samp{-}, @samp{+}, and @samp{*}, the result is calculated with +@code{BIGINT} (64-bit) precision if both arguments are integers! + +@cindex operations, arithmetic +@cindex arithmetic expressions +@table @code +@findex + (addition) +@findex addition (+) +@item + +Addition: +@example +mysql> select 3+5; + -> 8 +@end example + +@findex - (subtraction) +@findex subtraction (-) +@item - +Subtraction: +@example +mysql> select 3-5; + -> -2 +@end example + +@findex * (multiplication) +@findex multiplication (*) +@item * +Multiplication: +@example +mysql> select 3*5; + -> 15 +mysql> select 18014398509481984*18014398509481984.0; + -> 324518553658426726783156020576256.0 +mysql> select 18014398509481984*18014398509481984; + -> 0 +@end example + +The result of the last expression is incorrect because the result of the integer +multiplication exceeds the 64-bit range of @code{BIGINT} calculations. + +@findex / (division) +@findex division (/) +@item / +Division: +@example +mysql> select 3/5; + -> 0.60 +@end example + +Division by zero produces a @code{NULL} result: + +@example +mysql> select 102/(1-1); + -> NULL +@end example + +A division will be calculated with @code{BIGINT} arithmetic only if performed +in a context where its result is converted to an integer! +@end table + + +@node Mathematical functions, , Arithmetic functions, Numeric Functions +@subsubsection Mathematical Functions +All mathematical functions return @code{NULL} in case of an error. + +@findex mathematical functions +@findex functions, mathematical + +@table @code +@findex - (unary minus) +@findex minus, unary (-) +@findex unary minus (-) +@item - +Unary minus. Changes the sign of the argument: +@example +mysql> select - 2; + -> -2 +@end example + +Note that if this operator is used with a @code{BIGINT}, the return value is a +@code{BIGINT}! This means that you should avoid using @code{-} on integers that +may have the value of @code{-2^63}! + +@findex ABS() +@item ABS(X) +Returns the absolute value of @code{X}: +@example +mysql> select ABS(2); + -> 2 +mysql> select ABS(-32); + -> 32 +@end example + +This function is safe to use with @code{BIGINT} values. + +@findex SIGN() +@item SIGN(X) +Returns the sign of the argument as @code{-1}, @code{0}, or @code{1}, depending +on whether @code{X} is negative, zero, or positive: +@example +mysql> select SIGN(-32); + -> -1 +mysql> select SIGN(0); + -> 0 +mysql> select SIGN(234); + -> 1 +@end example + +@findex MOD() +@findex % (modulo) +@findex modulo (%) +@item MOD(N,M) +@itemx % +Modulo (like the @code{%} operator in C). +Returns the remainder of @code{N} divided by @code{M}: +@example +mysql> select MOD(234, 10); + -> 4 +mysql> select 253 % 7; + -> 1 +mysql> select MOD(29,9); + -> 2 +@end example + +This function is safe to use with @code{BIGINT} values. + +@findex FLOOR() +@item FLOOR(X) +Returns the largest integer value not greater than @code{X}: +@example +mysql> select FLOOR(1.23); + -> 1 +mysql> select FLOOR(-1.23); + -> -2 +@end example + +Note that the return value is converted to a @code{BIGINT}! + +@findex CEILING() +@item CEILING(X) +Returns the smallest integer value not less than @code{X}: +@example +mysql> select CEILING(1.23); + -> 2 +mysql> select CEILING(-1.23); + -> -1 +@end example + +Note that the return value is converted to a @code{BIGINT}! + +@findex ROUND() +@item ROUND(X) +Returns the argument @code{X}, rounded to the nearest integer: +@example +mysql> select ROUND(-1.23); + -> -1 +mysql> select ROUND(-1.58); + -> -2 +mysql> select ROUND(1.58); + -> 2 +@end example + +Note that the behavior of @code{ROUND()} when the argument +is half way between two integers depends on the C library +implementation. Some round to the nearest even number, +always up, always down, or always towards zero. If you need +one kind of rounding, you should use a well-defined function +like @code{TRUNCATE()} or @code{FLOOR()} instead. + +@findex ROUND() +@item ROUND(X,D) +Returns the argument @code{X}, rounded to a number with @code{D} decimals. +If @code{D} is @code{0}, the result will have no decimal point or fractional +part: + +@example +mysql> select ROUND(1.298, 1); + -> 1.3 +mysql> select ROUND(1.298, 0); + -> 1 +@end example + +@findex EXP() +@item EXP(X) +Returns the value of @code{e} (the base of natural logarithms) raised to +the power of @code{X}: +@example +mysql> select EXP(2); + -> 7.389056 +mysql> select EXP(-2); + -> 0.135335 +@end example +@findex LOG() +@item LOG(X) +Returns the natural logarithm of @code{X}: +@example +mysql> select LOG(2); + -> 0.693147 +mysql> select LOG(-2); + -> NULL +@end example +If you want the log of a number @code{X} to some arbitary base @code{B}, use +the formula @code{LOG(X)/LOG(B)}. + +@findex LOG10() +@item LOG10(X) +Returns 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 + +@findex POW() +@findex POWER() +@item POW(X,Y) +@itemx POWER(X,Y) +Returns 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 + +@findex SQRT() +@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 + +@findex PI() +@item PI() +Returns the value of PI. The default shown number of decimals is 5, but +@strong{MySQL} internally uses the full double precession for PI. +@example +mysql> select PI(); + -> 3.141593 +mysql> SELECT PI()+0.000000000000000000; + -> 3.141592653589793116 +@end example + +@findex COS() +@item COS(X) +Returns the cosine of @code{X}, where @code{X} is given in radians: +@example +mysql> select COS(PI()); + -> -1.000000 +@end example + +@findex SIN() +@item SIN(X) +Returns the sine of @code{X}, where @code{X} is given in radians: +@example +mysql> select SIN(PI()); + -> 0.000000 +@end example + +@findex TAN() +@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 + +@findex ACOS() +@item ACOS(X) +Returns the arc cosine of @code{X}, that is, the value whose cosine is +@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to +@code{1}: +@example +mysql> select ACOS(1); + -> 0.000000 +mysql> select ACOS(1.0001); + -> NULL +mysql> select ACOS(0); + -> 1.570796 +@end example + +@findex ASIN() +@item ASIN(X) +Returns the arc sine of @code{X}, that is, the value whose sine is +@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to +@code{1}: +@example +mysql> select ASIN(0.2); + -> 0.201358 +mysql> select ASIN('foo'); + -> 0.000000 +@end example + +@findex ATAN() +@item ATAN(X) +Returns 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 + +@findex ATAN2() +@item ATAN2(Y,X) +Returns 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 + +@findex COT() +@item COT(X) +Returns the cotangent of @code{X}: +@example +mysql> select COT(12); + -> -1.57267341 +mysql> select COT(0); + -> NULL +@end example + +@findex RAND() +@item RAND() +@itemx RAND(N) +Returns a random floating-point value in the range @code{0} to @code{1.0}. +If an integer argument @code{N} is specified, it is used as the 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 +You can't use a column with @code{RAND()} values in an @code{ORDER BY} +clause, because @code{ORDER BY} would evaluate the column multiple times. +In @strong{MySQL} Version 3.23, you can, however, do: +@code{SELECT * FROM table_name ORDER BY RAND()} + +This is useful to get a random sample of a set @code{SELECT * FROM +table1,table2 WHERE a=b AND c select LEAST(2,0); + -> 0 +mysql> select LEAST(34.0,3.0,5.0,767.0); + -> 3.0 +mysql> select LEAST("B","A","C"); + -> "A" +@end example +In @strong{MySQL} versions prior to Version 3.22.5, you can use @code{MIN()} +instead of @code{LEAST}. + +@findex GREATEST() +@item GREATEST(X,Y,...) +Returns the largest (maximum-valued) argument. +The arguments are compared using the same rules as for @code{LEAST}: +@example +mysql> select GREATEST(2,0); + -> 2 +mysql> select GREATEST(34.0,3.0,5.0,767.0); + -> 767.0 +mysql> select GREATEST("B","A","C"); + -> "C" +@end example +In @strong{MySQL} versions prior to Version 3.22.5, you can use @code{MAX()} +instead of @code{GREATEST}. + +@findex DEGREES() +@item DEGREES(X) +Returns the argument @code{X}, converted from radians to degrees: +@example +mysql> select DEGREES(PI()); + -> 180.000000 +@end example + +@findex RADIANS() +@item RADIANS(X) +Returns the argument @code{X}, converted from degrees to radians: +@example +mysql> select RADIANS(90); + -> 1.570796 +@end example + +@findex TRUNCATE() +@item TRUNCATE(X,D) +Returns the number @code{X}, truncated to @code{D} decimals. If @code{D} +is @code{0}, the result will have no decimal point or fractional part: +@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 + +Note that as decimal numbers are normally not stored as exact numbers in +computers, but as double values, you may be fooled by the following +result: + +@cindex rounding errors +@example +mysql> select TRUNCATE(10.28*100,0); + -> 1027 +@end example + +The above happens because 10.28 is actually stored as something like +10.2799999999999999. +@end table + + +@node Date and time functions, Other Functions, Numeric Functions, Functions +@subsection Date and Time Functions + @findex date and time functions @findex functions, date and time -@node Date and time functions, Miscellaneous functions, String functions, Functions -@subsection Date and Time Functions See @ref{Date and time types} for a description of the range of values each type has and the valid formats in which date and time values may be @@ -30914,10 +31379,85 @@ mysql> select TIME_TO_SEC('00:39:38'); @end example @end table + +@node Other Functions, , Date and time functions, Functions +@subsection Other Functions + +@menu +* Bit functions:: +* Miscellaneous functions:: +@end menu + + +@node Bit functions, Miscellaneous functions, Other Functions, Other Functions +@subsubsection Bit Functions + +@findex arithmetic functions +@findex bit functions +@findex functions, arithmetic +@findex functions, bit + +@strong{MySQL} uses @code{BIGINT} (64-bit) arithmetic for bit operations, so +these operators have a maximum range of 64 bits. + +@table @code +@findex | (bitwise OR) +@findex OR, bitwise +@item | +Bitwise OR: +@example +mysql> select 29 | 15; + -> 31 +@end example + +@findex & (bitwise AND) +@findex AND, bitwise +@item & +Bitwise AND: +@example +mysql> select 29 & 15; + -> 13 +@end example + +@findex << (left shift) +@item << +Shifts a longlong (@code{BIGINT}) number to the left: +@example +mysql> select 1 << 2; + -> 4 +@end example + +@findex >> (right shift) +@item >> +Shifts a longlong (@code{BIGINT}) number to the right: +@example +mysql> select 4 >> 2; + -> 1 +@end example + +@findex ~ +@item ~ +Invert all bits: +@example +mysql> select 5 & ~1; + -> 4 +@end example + +@findex BIT_COUNT() +@item BIT_COUNT(N) +Returns the number of bits that are set in the argument @code{N}: +@example +mysql> select BIT_COUNT(29); + -> 4 +@end example +@end table + + +@node Miscellaneous functions, , Bit functions, Other Functions +@subsubsection Miscellaneous Functions + @findex miscellaneous functions @findex functions, miscellaneous -@node Miscellaneous functions, Group by functions, Date and time functions, Functions -@subsection Miscellaneous Functions @table @code @findex DATABASE() @@ -31196,1145 +31736,26 @@ control of master-slave synchronization, but was originally written to facilitate replication testing. @end table -@findex GROUP BY functions -@findex functions, GROUP BY -@node Group by functions, , Miscellaneous functions, Functions -@subsection Functions for Use with @code{GROUP BY} Clauses -If you use a group function in a statement containing no @code{GROUP BY} -clause, it is equivalent to grouping on all rows. +@node Data Manipulation, Data Definition, Functions, Reference +@section Data Manipulation: @code{SELECT}, @code{INSERT}, @code{UPDATE}, @code{DELETE} -@table @code -@findex COUNT() -@item COUNT(expr) -Returns a count of the number of non-@code{NULL} values in the rows -retrieved by a @code{SELECT} statement: - -@example -mysql> select student.student_name,COUNT(*) - from student,course - where student.student_id=course.student_id - GROUP BY student_name; - -@end example - -@code{COUNT(*)} is somewhat different in that it returns a count of -the number of rows retrieved, whether or not they contain @code{NULL} -values. - -@code{COUNT(*)} is optimized to -return very quickly if the @code{SELECT} retrieves from one table, no -other columns are retrieved, and there is no @code{WHERE} clause. -For example: - -@example -mysql> select COUNT(*) from student; -@end example - -@findex COUNT(DISTINCT) -@findex DISTINCT -@item COUNT(DISTINCT expr,[expr...]) -Returns a count of the number of different non-@code{NULL} values: - -@example -mysql> select COUNT(DISTINCT results) from student; -@end example - -In @strong{MySQL} you can get the number of distinct expression -combinations that don't contain NULL by giving a list of expressions. -In ANSI SQL you would have to do a concatenation of all expressions -inside @code{CODE(DISTINCT ..)}. - -@findex AVG() -@item AVG(expr) -Returns the average value of @code{expr}: - -@example -mysql> select student_name, AVG(test_score) - from student - GROUP BY student_name; -@end example - -@findex MIN() -@findex MAX() -@item MIN(expr) -@itemx MAX(expr) -Returns the minimum or maximum value of @code{expr}. @code{MIN()} and -@code{MAX()} may take a string argument; in such cases they return the -minimum or maximum string value. @xref{MySQL indexes}. - -@example -mysql> select student_name, MIN(test_score), MAX(test_score) - from student - GROUP BY student_name; -@end example - -@findex SUM() -@item SUM(expr) -Returns the sum of @code{expr}. Note that if the return set has no rows, -it returns NULL! - -@findex STD() -@findex STDDEV() -@cindex Oracle compatibility -@cindex compatibility, with Oracle -@item STD(expr) -@itemx STDDEV(expr) -Returns the standard deviation of @code{expr}. This is an extension to -ANSI SQL. The @code{STDDEV()} form of this function is provided for Oracle -compatibility. - -@findex BIT_OR() -@item BIT_OR(expr) -Returns the bitwise @code{OR} of all bits in @code{expr}. The calculation is -performed with 64-bit (@code{BIGINT}) precision. - -@findex BIT_AND() -@item BIT_AND(expr) -Returns the bitwise @code{AND} of all bits in @code{expr}. The calculation is -performed with 64-bit (@code{BIGINT}) precision. -@end table - -@cindex @code{GROUP BY}, extensions to ANSI SQL -@strong{MySQL} has extended the use of @code{GROUP BY}. You can use columns or -calculations in the @code{SELECT} expressions that don't appear in -the @code{GROUP BY} part. This stands for @emph{any possible value for this -group}. You can use this to get better performance by avoiding sorting and -grouping on unnecessary items. For example, you don't need to group on -@code{customer.name} in the following query: - -@example -mysql> 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 @code{customer.name} to the @code{GROUP -BY} clause. In @strong{MySQL}, the name is redundant if you don't run in -ANSI mode. - -@strong{Don't use this feature} if the columns you omit from the -@code{GROUP BY} part aren't unique in the group! You will get -unpredictable results. - -In some cases, you can use @code{MIN()} and @code{MAX()} to obtain a specific -column value even if it isn't unique. The following gives the value of -@code{column} from the row containing the smallest value in the @code{sort} -column: - -@example -substr(MIN(concat(rpad(sort,6,' '),column)),7) -@end example - -@xref{example-Maximum-column-group-row}. - -@cindex @code{ORDER BY}, aliases in -@cindex aliases, in @code{ORDER BY} clauses -@cindex @code{GROUP BY}, aliases in -@cindex aliases, in @code{GROUP BY} clauses -@cindex expression aliases -@cindex aliases, for expressions -Note that if you are using @strong{MySQL} Version 3.22 (or earlier) or if -you are trying to follow ANSI SQL, you can't use expressions in @code{GROUP -BY} or @code{ORDER BY} clauses. You can work around this limitation by -using an alias for the expression: - -@example -mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name - GROUP BY id,val ORDER BY val; -@end example - -In @strong{MySQL} Version 3.23 you can do: - -@example -mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND(); -@end example - -@findex CREATE DATABASE -@node CREATE DATABASE, DROP DATABASE, Functions, Reference -@section @code{CREATE DATABASE} Syntax - -@example -CREATE DATABASE [IF NOT EXISTS] db_name -@end example - -@code{CREATE DATABASE} creates a database with the given name. Rules for -allowable database names are given in @ref{Legal names}. An error occurs if -the database already exists and you didn't specify @code{IF NOT EXISTS}. - -Databases in @strong{MySQL} are implemented as directories containing files -that correspond to tables in the database. Because there are no tables in a -database when it is initially created, the @code{CREATE DATABASE} statement -only creates a directory under the @strong{MySQL} data directory. - -@cindex @code{mysqladmin} -You can also create databases with @code{mysqladmin}. -@xref{Client-Side Scripts}. - -@findex DROP DATABASE -@node DROP DATABASE, CREATE TABLE, CREATE DATABASE, Reference -@section @code{DROP DATABASE} Syntax - -@example -DROP DATABASE [IF EXISTS] db_name -@end example - -@code{DROP DATABASE} drops all tables in the database and deletes the -database. If you do a @code{DROP DATABASE} on a symbolic linked -database, both the link and the original database is deleted. @strong{Be -VERY careful with this command!} - -@code{DROP DATABASE} returns the number of files that were removed from -the database directory. Normally, this is three times the number of -tables, because normally each table corresponds to a @file{.MYD} file, a -@file{.MYI} file, and a @file{.frm} file. - -The @code{DROP DATABASE} command removes from the given database -directory all files with the following extensions: - -@multitable @columnfractions .25 .25 .25 .25 -@item .BAK @tab .DAT @tab .HSH @tab .ISD -@item .ISM @tab .ISM @tab .MRG @tab .MYD -@item .MYI @tab .db @tab .frm -@end multitable - -All subdirectories that consists of 2 digits (@code{RAID} directories) -are also removed. - -In @strong{MySQL} Version 3.22 or later, you can use the keywords -@code{IF EXISTS} to prevent an error from occurring if the database doesn't -exist. - -@cindex @code{mysqladmin} -You can also drop databases with @code{mysqladmin}. @xref{Client-Side Scripts}. - -@findex CREATE TABLE -@node CREATE TABLE, ALTER TABLE, DROP DATABASE, Reference -@section @code{CREATE TABLE} Syntax @menu -* Silent column changes:: Silent column changes +* SELECT:: +* INSERT:: +* INSERT DELAYED:: +* UPDATE:: +* DELETE:: +* TRUNCATE:: +* REPLACE:: +* LOAD DATA:: @end menu -@example -CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] -[table_options] [select_statement] - -create_definition: - col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] - [PRIMARY KEY] [reference_definition] - or PRIMARY KEY (index_col_name,...) - or KEY [index_name] (index_col_name,...) - or INDEX [index_name] (index_col_name,...) - or UNIQUE [INDEX] [index_name] (index_col_name,...) - or FULLTEXT [INDEX] [index_name] (index_col_name,...) - or [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...) - [reference_definition] - or CHECK (expr) - -type: - TINYINT[(length)] [UNSIGNED] [ZEROFILL] - or SMALLINT[(length)] [UNSIGNED] [ZEROFILL] - or MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] - or INT[(length)] [UNSIGNED] [ZEROFILL] - or INTEGER[(length)] [UNSIGNED] [ZEROFILL] - or BIGINT[(length)] [UNSIGNED] [ZEROFILL] - or REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] - or DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] - or FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] - or DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] - or NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] - or CHAR(length) [BINARY] - or VARCHAR(length) [BINARY] - or DATE - or TIME - or TIMESTAMP - or DATETIME - or TINYBLOB - or BLOB - or MEDIUMBLOB - or LONGBLOB - or TINYTEXT - or TEXT - or MEDIUMTEXT - or LONGTEXT - or ENUM(value1,value2,value3,...) - or SET(value1,value2,value3,...) - -index_col_name: - col_name [(length)] - -reference_definition: - REFERENCES tbl_name [(index_col_name,...)] - [MATCH FULL | MATCH PARTIAL] - [ON DELETE reference_option] - [ON UPDATE reference_option] - -reference_option: - RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT - -table_options: - TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MYISAM @} -or AUTO_INCREMENT = # -or AVG_ROW_LENGTH = # -or CHECKSUM = @{0 | 1@} -or COMMENT = "string" -or MAX_ROWS = # -or MIN_ROWS = # -or PACK_KEYS = @{0 | 1@} -or PASSWORD = "string" -or DELAY_KEY_WRITE = @{0 | 1@} -or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} -or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=# -or UNION = (table_name,[table_name...]) -or DATA DIRECTORY="directory" -or INDEX DIRECTORY="directory" - -select_statement: - [IGNORE | REPLACE] SELECT ... (Some legal select statement) -@end example - -@code{CREATE TABLE} -creates a table with the given name in the current database. Rules for -allowable table names are given in @ref{Legal names}. An error occurs if -there is no current database or if the table already exists. - -In @strong{MySQL} Version 3.22 or later, the table name can be specified as -@code{db_name.tbl_name}. This works whether or not there is a current -database. - -In @strong{MySQL} Version 3.23, you can use the @code{TEMPORARY} keyword when -you create a table. A temporary table will automatically be deleted if a -connection dies and the name is per connection. This means that two different -connections can both use the same temporary table name without conflicting -with each other or with an existing table of the same name. (The existing table -is hidden until the temporary table is deleted). - -In @strong{MySQL} Version 3.23 or later, you can use the keywords -@code{IF NOT EXISTS} so that an error does not occur if the table already -exists. Note that there is no verification that the table structures are -identical. - -Each table @code{tbl_name} is represented by some files in the database -directory. In the case of MyISAM-type tables you will get: - -@multitable @columnfractions .2 .8 -@item @strong{File} @tab @strong{Purpose} -@item @code{tbl_name.frm} @tab Table definition (form) file -@item @code{tbl_name.MYD} @tab Data file -@item @code{tbl_name.MYI} @tab Index file -@end multitable - -For more information on the properties of the various column types, see -@ref{Column types}: - -@itemize @bullet -@item -If neither @code{NULL} nor @code{NOT NULL} is specified, the column -is treated as though @code{NULL} had been specified. - -@item -An integer column may have the additional attribute @code{AUTO_INCREMENT}. -When you insert a value of @code{NULL} (recommended) or @code{0} into an -@code{AUTO_INCREMENT} column, the column is set to @code{value+1}, where -@code{value} is the largest value for the column currently in the table. -@code{AUTO_INCREMENT} sequences begin with @code{1}. -@xref{mysql_insert_id, , @code{mysql_insert_id()}}. - -If you delete the row containing the maximum value for an -@code{AUTO_INCREMENT} column, the value will be reused with an -@code{ISAM}, or @code{BDB} table but not with a -@code{MyISAM} or @code{InnoDB} table. If you delete all rows in the table -with @code{DELETE FROM table_name} (without a @code{WHERE}) in -@code{AUTOCOMMIT} mode, the sequence starts over for all table types. - -@strong{NOTE:} There can be only one @code{AUTO_INCREMENT} column per -table, and it must be indexed. @strong{MySQL} Version 3.23 will also only -work properly if the auto_increment column only has positive -values. Inserting a negative number is regarded as inserting a very large -positive number. This is done to avoid precision problems when -numbers 'wrap' over from positive to negative and also to ensure that one -doesn't accidentally get an auto_increment column that contains 0. - -@cindex ODBC compatibility -@cindex compatibility, with ODBC -To make @strong{MySQL} compatible with some ODBC applications, you can find -the last inserted row with the following query: - -@example -SELECT * FROM tbl_name WHERE auto_col IS NULL -@end example - -@item -@code{NULL} values are handled differently for @code{TIMESTAMP} columns than -for other column types. You cannot store a literal @code{NULL} in a -@code{TIMESTAMP} column; setting the column to @code{NULL} sets it to the -current date and time. Because @code{TIMESTAMP} columns behave this way, the -@code{NULL} and @code{NOT NULL} attributes do not apply in the normal way and -are ignored if you specify them. - -On the other hand, to make it easier for @strong{MySQL} clients to use -@code{TIMESTAMP} columns, the server reports that such columns may be -assigned @code{NULL} values (which is true), even though @code{TIMESTAMP} -never actually will contain a @code{NULL} value. You can see this when you -use @code{DESCRIBE tbl_name} to get a description of your table. - -Note that setting a @code{TIMESTAMP} column to @code{0} is not the same -as setting it to @code{NULL}, because @code{0} is a valid @code{TIMESTAMP} -value. - -@item -If no @code{DEFAULT} value is specified for a column, @strong{MySQL} -automatically assigns one. - -If the column may take @code{NULL} as a value, the default value is -@code{NULL}. - -If the column is declared as @code{NOT NULL}, the default value depends on -the column type: - -@itemize @minus -@item -For numeric types other than those declared with the @code{AUTO_INCREMENT} -attribute, the default is @code{0}. For an @code{AUTO_INCREMENT} column, the -default value is the next value in the sequence. - -@item -For date and time types other than @code{TIMESTAMP}, the default is the -appropriate zero value for the type. For the first @code{TIMESTAMP} -column in a table, the default value is the current date and time. -@xref{Date and time types}. - -@item -For string types other than @code{ENUM}, the default value is the empty string. -For @code{ENUM}, the default is the first enumeration value. -@end itemize - -Default values must be constants. This means, for example, that you cannot -set the default for a date column to be the value of a function such as -@code{NOW()} or @code{CURRENT_DATE}. - -@item -@code{KEY} is a synonym for @code{INDEX}. - -@item -In @strong{MySQL}, a @code{UNIQUE} key can have only distinct values. An -error occurs if you try to add a new row with a key that matches an existing -row. - -@item -@tindex PRIMARY KEY -A @code{PRIMARY KEY} is a unique @code{KEY} with the extra constraint -that all key columns must be defined as @code{NOT NULL}. In @strong{MySQL} -the key is named @code{PRIMARY}. A table can have only one @code{PRIMARY KEY}. -If you don't have a @code{PRIMARY KEY} and some applications ask for the -@code{PRIMARY KEY} in your tables, @strong{MySQL} will return the first -@code{UNIQUE} key, which doesn't have any @code{NULL} columns, as the -@code{PRIMARY KEY}. - -@item -A @code{PRIMARY KEY} can be a multiple-column index. However, you cannot -create a multiple-column index using the @code{PRIMARY KEY} key attibute in a -column specification. Doing so will mark only that single column as primary. -You must use the @code{PRIMARY KEY(index_col_name, ...)} syntax. - -@item -If the @code{PRIMARY} or @code{UNIQUE} key consists of only one column and this -is of type integer, you can also refer to it as @code{_rowid} -(new in Version 3.23.11). - -@item -If you don't assign a name to an index, the index will be assigned the same -name as the first @code{index_col_name}, with an optional suffix (@code{_2}, -@code{_3}, @code{...}) to make it unique. You can see index names for a -table using @code{SHOW INDEX FROM tbl_name}. -@xref{SHOW, , @code{SHOW}}. - -@item -@cindex @code{NULL} values, and indexes -@cindex indexes, and @code{NULL} values -Only the @code{MyISAM} table type supports indexes on columns that can have -@code{NULL} values. In other cases you must declare such columns -@code{NOT NULL} or an error results. - -@item -With @code{col_name(length)} syntax, you can specify an index that -uses only a part of a @code{CHAR} or @code{VARCHAR} column. This can -make the index file much smaller. -@xref{Indexes}. - -@item -@cindex @code{BLOB} columns, indexing -@cindex indexes, and @code{BLOB} columns -@cindex @code{TEXT} columns, indexing -@cindex indexes, and @code{TEXT} columns -Only the @code{MyISAM} table type supports indexing on @code{BLOB} and -@code{TEXT} columns. When putting an index on a @code{BLOB} or @code{TEXT} -column you MUST always specify the length of the index: -@example -CREATE TABLE test (blob_col BLOB, index(blob_col(10))); -@end example - -@item -When you use @code{ORDER BY} or @code{GROUP BY} with a @code{TEXT} or -@code{BLOB} column, only the first @code{max_sort_length} bytes are used. -@xref{BLOB, , @code{BLOB}}. - -@item -In @strong{MySQL} Version 3.23.23 or later, you can also create special -@strong{FULLTEXT} indexes. They are used for full-text search. Only the -@code{MyISAM} table type supports @code{FULLTEXT} indexes. They can be created -only from @code{VARCHAR} and @code{TEXT} columns. -Indexing always happens over the entire column, partial indexing is not -supported. See @ref{Fulltext Search} for details of operation. - -@item -The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't -actually do anything. The syntax for them is provided only for compatibility, -to make it easier to port code from other SQL servers and to run applications -that create tables with references. -@xref{Missing functions}. - -@item -Each @code{NULL} column takes one bit extra, rounded up to the nearest byte. - -@item -The maximum record length in bytes can be calculated as follows: - -@example -row length = 1 - + (sum of column lengths) - + (number of NULL columns + 7)/8 - + (number of variable-length columns) -@end example - -@item -The @code{table_options} and @code{SELECT} options are only -implemented in @strong{MySQL} Version 3.23 and above. - -The different table types are: - -@multitable @columnfractions .20 .80 -@item BDB or Berkeley_db @tab Transaction-safe tables with page locking. @xref{BDB}. -@item HEAP @tab The data for this table is only stored in memory. @xref{HEAP}. -@item ISAM @tab The original table handler. @xref{ISAM}. -@item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}. -@item MERGE @tab A collection of MyISAM tables used as one table. @xref{MERGE}. -@item MyISAM @tab The new binary portable table handler that is replacing ISAM. @xref{MyISAM}. -@end multitable -@xref{Table types}. - -If a table type is specified, and that particular type is not available, -@strong{MySQL} will choose the closest table type to the one that you have -specified. For example, if @code{TYPE=BDB} is specified, and that distribution -of @strong{MySQL} does not support @code{BDB} tables, the table will be created -as @code{MyISAM} instead. - -The other table options are used to optimize the behavior of the -table. In most cases, you don't have to specify any of them. -The options work for all table types, if not otherwise indicated: - -@multitable @columnfractions .20 .80 -@item @code{AUTO_INCREMENT} @tab The next auto_increment value you want to set for your table (MyISAM). -@item @code{AVG_ROW_LENGTH} @tab An approximation of the average row length for your table. You only need to set this for large tables with variable size records. -@item @code{CHECKSUM} @tab Set this to 1 if you want @strong{MySQL} to maintain a checksum for all rows (makes the table a little slower to update but makes it easier to find corrupted tables) (MyISAM). -@item @code{COMMENT} @tab A 60-character comment for your table. -@item @code{MAX_ROWS} @tab Max number of rows you plan to store in the table. -@item @code{MIN_ROWS} @tab Minimum number of rows you plan to store in the table. -@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). -@item @code{PASSWORD} @tab Encrypt the @code{.frm} file with a password. This option doesn't do anything in the standard @strong{MySQL} version. -@item @code{DELAY_KEY_WRITE} @tab Set this to 1 if want to delay key table updates until the table is closed (MyISAM). -@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently you can only use the DYNAMIC and STATIC options for MyISAM tables. -@end multitable - -When you use a @code{MyISAM} table, @strong{MySQL} uses the product of -@code{max_rows * avg_row_length} to decide how big the resulting table -will be. If you don't specify any of the above options, the maximum size -for a table will be 4G (or 2G if your operating systems only supports 2G -tables). The reason for this is just to keep down the pointer sizes -to make the index smaller and faster if you don't really need big files. - -If you don't use @code{PACK_KEYS}, the default is to only pack strings, -not numbers. If you use @code{PACK_KEYS=1}, numbers will be packed as well. - -When packing binary number keys, @strong{MySQL} will use prefix compression. -This means that you will only get a big benefit of this if you have -many numbers that are the same. Prefix compression means that every -key needs one extra byte to indicate how many bytes of the previous key are -the same for the next key (note that the pointer to the row is stored -in high-byte-first-order directly after the key, to improve -compression.) This means that if you have many equal keys on two rows -in a row, all following 'same' keys will usually only take 2 bytes -(including the pointer to the row). Compare this to the ordinary case -where the following keys will take storage_size_for_key + -pointer_size (usually 4). On the other hand, if all keys are -totally different, you will lose 1 byte per key, if the key isn't a -key that can have @code{NULL} values (In this case the packed key length will -be stored in the same byte that is used to mark if a key is @code{NULL}.) - -@item -If you specify a @code{SELECT} after the @code{CREATE} statement, -@strong{MySQL} will create new fields for all elements in the -@code{SELECT}. For example: - -@example -mysql> CREATE TABLE test (a int not null auto_increment, - primary key (a), key(b)) - TYPE=MyISAM SELECT b,c from test2; -@end example - -This will create a @code{MyISAM} table with three columns, a, b, and c. -Notice that the columns from the @code{SELECT} statement are appended to -the right side of the table, not overlapped onto it. Take the following -example: - -@example -mysql> select * from foo; -+---+ -| n | -+---+ -| 1 | -+---+ - -mysql> create table bar (m int) select n from foo; -Query OK, 1 row affected (0.02 sec) -Records: 1 Duplicates: 0 Warnings: 0 - -mysql> select * from bar; -+------+---+ -| m | n | -+------+---+ -| NULL | 1 | -+------+---+ -1 row in set (0.00 sec) -@end example - -For each row in table @code{foo}, a row is inserted in @code{bar} with -the values from @code{foo} and default values for the new columns. - -@code{CREATE TABLE ... SELECT} will not automaticly create any indexes -for you. This is done intentionally to make the command as flexible as -possible. If you want to have indexes in the created table, you should -specify these before the @code{SELECT} statement: - -@example -mysql> create table bar (unique (n)) select n from foo; -@end example - -If any errors occur while copying the data to the table, it will -automatically be deleted. - -To ensure that the update log/binary log can be used to re-create the -original tables, @strong{MySQL} will not allow concurrent inserts during -@code{CREATE TABLE .... SELECT}. -@item -The @code{RAID_TYPE} option will help you to break the 2G/4G limit for -the MyISAM data file (not the index file) on -operating systems that don't support big files. You can get also more speed -from the I/O bottleneck by putting @code{RAID} directories on different -physical disks. @code{RAID_TYPE} will work on any OS, as long as you have -configured @strong{MySQL} with @code{--with-raid}. For now the only allowed -@code{RAID_TYPE} is @code{STRIPED} (@code{1} and @code{RAID0} are aliases -for this). - -If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table, -@code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00, -01, 02 in the database directory. In each of these directories -@code{MyISAM} will create a @code{table_name.MYD}. When writing data -to the data file, the @code{RAID} handler will map the first -@code{RAID_CHUNKSIZE} *1024 bytes to the first file, the next -@code{RAID_CHUNKSIZE} *1024 bytes to the next file and so on. -@item -@code{UNION} is used when you want to use a collection of identical -tables as one. This only works with MERGE tables. @xref{MERGE}. - -For the moment you need to have @code{SELECT}, @code{UPDATE}, and -@code{DELETE} privileges on the tables you map to a @code{MERGE} table. -All mapped tables must be in the same database as the @code{MERGE} table. -@item -In the created table the @code{PRIMARY} key will be placed first, followed -by all @code{UNIQUE} keys and then the normal keys. This helps the -@strong{MySQL} optimizer to prioritize which key to use and also more quickly -detect duplicated @code{UNIQUE} keys. - -@item -By using @code{DATA DIRECTORY="directory"} or @code{INDEX -DIRECTORY="directory"} you can specify where the table handler should -put it's table and index files. This only works for @code{MyISAM} tables -in @code{MySQL} 4.0, when you are not using the @code{--skip-symlink} -option. @xref{Symbolic links to tables}. - -@end itemize - -@cindex silent column changes -@node Silent column changes, , CREATE TABLE, CREATE TABLE -@subsection Silent Column Specification Changes - -In some cases, @strong{MySQL} silently changes a column specification from -that given in a @code{CREATE TABLE} statement. (This may also occur with -@code{ALTER TABLE}.): - -@itemize @bullet -@item -@code{VARCHAR} columns with a length less than four are changed to -@code{CHAR}. - -@item -If any column in a table has a variable length, the entire row is -variable-length as a result. Therefore, if a table contains any -variable-length columns (@code{VARCHAR}, @code{TEXT}, or @code{BLOB}), -all @code{CHAR} columns longer than three characters are changed to -@code{VARCHAR} columns. This doesn't affect how you use the columns in -any way; in @strong{MySQL}, @code{VARCHAR} is just a different way to -store characters. @strong{MySQL} performs this conversion because it -saves space and makes table operations faster. @xref{Table types}. - -@item -@code{TIMESTAMP} display sizes must be even and in the range from 2 to 14. -If you specify a display size of 0 or greater than 14, the size is coerced -to 14. Odd-valued sizes in the range from 1 to 13 are coerced -to the next higher even number. - -@item -You cannot store a literal @code{NULL} in a @code{TIMESTAMP} column; setting -it to @code{NULL} sets it to the current date and time. Because -@code{TIMESTAMP} columns behave this way, the @code{NULL} and @code{NOT NULL} -attributes do not apply in the normal way and are ignored if you specify -them. @code{DESCRIBE tbl_name} always reports that a @code{TIMESTAMP} -column may be assigned @code{NULL} values. - -@item -@strong{MySQL} maps certain column types used by other SQL database vendors -to @strong{MySQL} types. @xref{Other-vendor column types}. -@end itemize - -If you want to see whether or not @strong{MySQL} used a column type other -than the one you specified, issue a @code{DESCRIBE tbl_name} statement after -creating or altering your table. - -@cindex @code{myisampack} -Certain other column type changes may occur if you compress a table -using @code{myisampack}. @xref{Compressed format}. - -@findex ALTER TABLE -@node ALTER TABLE, RENAME TABLE, CREATE TABLE, Reference -@section @code{ALTER TABLE} Syntax - -@example -ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...] - -alter_specification: - ADD [COLUMN] create_definition [FIRST | AFTER column_name ] - or ADD [COLUMN] (create_definition, create_definition,...) - or ADD INDEX [index_name] (index_col_name,...) - or ADD PRIMARY KEY (index_col_name,...) - or ADD UNIQUE [index_name] (index_col_name,...) - or ADD FULLTEXT [index_name] (index_col_name,...) - or ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...) - [reference_definition] - or ALTER [COLUMN] col_name @{SET DEFAULT literal | DROP DEFAULT@} - or CHANGE [COLUMN] old_col_name create_definition - or MODIFY [COLUMN] create_definition - or DROP [COLUMN] col_name - or DROP PRIMARY KEY - or DROP INDEX index_name - or RENAME [TO] new_tbl_name - or ORDER BY col - or table_options -@end example - -@code{ALTER TABLE} allows you to change the structure of an existing table. -For example, you can add or delete columns, create or destroy indexes, change -the type of existing columns, or rename columns or the table itself. You can -also change the comment for the table and type of the table. -@xref{CREATE TABLE, , @code{CREATE TABLE}}. - -If you use @code{ALTER TABLE} to change a column specification but -@code{DESCRIBE tbl_name} indicates that your column was not changed, it is -possible that @strong{MySQL} ignored your modification for one of the reasons -described in @ref{Silent column changes}. For example, if you try to change -a @code{VARCHAR} column to @code{CHAR}, @strong{MySQL} will still use -@code{VARCHAR} if the table contains other variable-length columns. - -@code{ALTER TABLE} works by making a temporary copy of the original table. -The alteration is performed on the copy, then the original table is -deleted and the new one is renamed. This is done in such a way that -all updates are automatically redirected to the new table without -any failed updates. While @code{ALTER TABLE} is executing, the original -table is readable by other clients. Updates and writes to the table -are stalled until the new table is ready. - -Note that if you use any other option to @code{ALTER TABLE} than -@code{RENAME}, @strong{MySQL} will always create a temporary table, even -if the data wouldn't strictly need to be copied (like when you change the -name of a column). We plan to fix this in the future, but as one doesn't -normally do @code{ALTER TABLE} that often this isn't that high on our TODO. - -@itemize @bullet -@item -To use @code{ALTER TABLE}, you need @strong{ALTER}, @strong{INSERT}, -and @strong{CREATE} privileges on the table. - -@item -@code{IGNORE} is a @strong{MySQL} extension to ANSI SQL92. -It controls how @code{ALTER TABLE} works if there are duplicates on -unique keys in the new table. -If @code{IGNORE} isn't specified, the copy is aborted and rolled back. -If @code{IGNORE} is specified, then for rows with duplicates on a unique -key, only the first row is used; the others are deleted. - -@item -You can issue multiple @code{ADD}, @code{ALTER}, @code{DROP}, and -@code{CHANGE} clauses in a single @code{ALTER TABLE} statement. This is a -@strong{MySQL} extension to ANSI SQL92, which allows only one of each clause -per @code{ALTER TABLE} statement. - -@item -@code{CHANGE col_name}, @code{DROP col_name}, and @code{DROP -INDEX} are @strong{MySQL} extensions to ANSI SQL92. - -@item -@code{MODIFY} is an Oracle extension to @code{ALTER TABLE}. - -@item -The optional word @code{COLUMN} is a pure noise word and can be omitted. - -@item -If you use @code{ALTER TABLE tbl_name RENAME TO new_name} without any other -options, @strong{MySQL} simply renames the files that correspond to the table -@code{tbl_name}. There is no need to create the temporary table. -@xref{RENAME TABLE,, @code{RENAME TABLE}}. - -@item -@code{create_definition} clauses use the same syntax for @code{ADD} and -@code{CHANGE} as for @code{CREATE TABLE}. Note that this syntax includes -the column name, not just the column type. -@xref{CREATE TABLE, , @code{CREATE TABLE}}. - -@item -You can rename a column using a @code{CHANGE old_col_name create_definition} -clause. To do so, specify the old and new column names and the type that -the column currently has. For example, to rename an @code{INTEGER} column -from @code{a} to @code{b}, you can do this: - -@example -mysql> ALTER TABLE t1 CHANGE a b INTEGER; -@end example - -If you want to change a column's type but not the name, @code{CHANGE} -syntax still requires two column names even if they are the same. For -example: - -@example -mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL; -@end example - -However, as of @strong{MySQL} Version 3.22.16a, you can also use @code{MODIFY} -to change a column's type without renaming it: - -@example -mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL; -@end example - -@item -If you use @code{CHANGE} or @code{MODIFY} to shorten a column for which -an index exists on part of the column (for instance, if you have an index -on the first 10 characters of a @code{VARCHAR} column), you cannot make -the column shorter than the number of characters that are indexed. - -@item -When you change a column type using @code{CHANGE} or @code{MODIFY}, -@strong{MySQL} tries to convert data to the new type as well as possible. - -@item -In @strong{MySQL} Version 3.22 or later, you can use @code{FIRST} or -@code{ADD ... AFTER col_name} to add a column at a specific position within -a table row. The default is to add the column last. - -@findex ALTER COLUMN -@item -@code{ALTER COLUMN} specifies a new default value for a column -or removes the old default value. -If the old default is removed and the column can be @code{NULL}, the new -default is @code{NULL}. If the column cannot be @code{NULL}, @strong{MySQL} -assigns a default value, as described in -@ref{CREATE TABLE, , @code{CREATE TABLE}}. - -@findex DROP INDEX -@item -@code{DROP INDEX} removes an index. This is a @strong{MySQL} extension to -ANSI SQL92. @xref{DROP INDEX}. - -@item -If columns are dropped from a table, the columns are also removed from any -index of which they are a part. If all columns that make up an index are -dropped, the index is dropped as well. - -@item -If a table contains only one column, the column cannot be dropped. -If what you intend is to remove the table, use @code{DROP TABLE} instead. - -@findex DROP PRIMARY KEY -@item -@code{DROP PRIMARY KEY} drops the primary index. If no such -index exists, it drops the first @code{UNIQUE} index in the table. -(@strong{MySQL} marks the first @code{UNIQUE} key as the @code{PRIMARY KEY} -if no @code{PRIMARY KEY} was specified explicitly.) - -@findex ORDER BY -@item -@code{ORDER BY} allows you to create the new table with the rows in a -specific order. Note that the table will not remain in this order after -inserts and deletes. In some cases, it may make sorting easier for -@strong{MySQL} if the table is in order by the column that you wish to -order it by later. This option is mainly useful when you know that you -are mostly going to query the rows in a certain order; By using this -option after big changes to the table, you may be able to get higher -performance. - -@findex ALTER TABLE -@item -If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique -indexes are created in a separate batch (like in @code{REPAIR}). -This should make @code{ALTER TABLE} much faster when you have many indexes. - -@item -@findex mysql_info() -With the C API function @code{mysql_info()}, you can find out how many -records were copied, and (when @code{IGNORE} is used) how many records were -deleted due to duplication of unique key values. - -@item -@cindex foreign keys -@cindex references -The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't -actually do anything. The syntax for them is provided only for compatibility, -to make it easier to port code from other SQL servers and to run applications -that create tables with references. -@xref{Missing functions}. -@end itemize - -Here is an example that shows some of the uses of @code{ALTER TABLE}. We -begin with a table @code{t1} that is created as shown below: - -@example -mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); -@end example - -To rename the table from @code{t1} to @code{t2}: - -@example -mysql> ALTER TABLE t1 RENAME t2; -@end example - -To change column @code{a} from @code{INTEGER} to @code{TINYINT NOT NULL} -(leaving the name the same), and to change column @code{b} from -@code{CHAR(10)} to @code{CHAR(20)} as well as renaming it from @code{b} to -@code{c}: - -@example -mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20); -@end example - -To add a new @code{TIMESTAMP} column named @code{d}: - -@example -mysql> ALTER TABLE t2 ADD d TIMESTAMP; -@end example - -To add an index on column @code{d}, and make column @code{a} the primary key: - -@example -mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a); -@end example - -To remove column @code{c}: - -@example -mysql> ALTER TABLE t2 DROP COLUMN c; -@end example - -To add a new @code{AUTO_INCREMENT} integer column named @code{c}: - -@example -mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, - ADD INDEX (c); -@end example - -Note that we indexed @code{c}, because @code{AUTO_INCREMENT} columns must be -indexed, and also that we declare @code{c} as @code{NOT NULL}, because -indexed columns cannot be @code{NULL}. - -When you add an @code{AUTO_INCREMENT} column, column values are filled in -with sequence numbers for you automatically. You can set the first -sequence number by executing @code{SET INSERT_ID=#} before -@code{ALTER TABLE} or using the @code{AUTO_INCREMENT = #} table option. -@xref{SET OPTION}. - -With MyISAM tables, if you don't change the @code{AUTO_INCREMENT} -column, the sequence number will not be affected. If you drop an -@code{AUTO_INCREMENT} column and then add another @code{AUTO_INCREMENT} -column, the numbers will start from 1 again. - -@xref{ALTER TABLE problems}. - -@findex RENAME TABLE -@node RENAME TABLE, DROP TABLE, ALTER TABLE, Reference -@section @code{RENAME TABLE} Syntax - -@example -RENAME TABLE tbl_name TO new_table_name[, tbl_name2 TO new_table_name2,...] -@end example - -The rename is done atomically, which means that no other thread can -access any of the tables while the rename is running. This makes it -possible to replace a table with an empty one: - -@example -CREATE TABLE new_table (...); -RENAME TABLE old_table TO backup_table, new_table TO old_table; -@end example - -The rename is done from left to right, which means that if you want to -swap two tables names, you have to: - -@example -RENAME TABLE old_table TO backup_table, - new_table TO old_table, - backup_table TO new_table; -@end example - -As long as two databases are on the same disk you can also rename -from one database to another: - -@example -RENAME TABLE current_database.table_name TO other_database.table_name; -@end example - -When you execute @code{RENAME}, you can't have any locked tables or -active transactions. You must also have the @code{ALTER} and @code{DROP} -privilege on the original table and @code{CREATE} and @code{INSERT} -privilege on the new table. - -If @strong{MySQL} encounters any errors in a multiple table rename, it -will do a reverse rename for all renamed tables to get everything back -to the original state. - -@findex DROP TABLE -@node DROP TABLE, DELETE, RENAME TABLE, Reference -@section @code{DROP TABLE} Syntax - -@example -DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE] -@end example - -@code{DROP TABLE} removes one or more tables. All table data and the table -definition are @emph{removed}, so @strong{be careful} with this command! - -In @strong{MySQL} Version 3.22 or later, you can use the keywords -@code{IF EXISTS} to prevent an error from occurring for tables that don't -exist. - -@code{RESTRICT} and @code{CASCADE} are allowed to make porting easier. -For the moment they don't do anything. - -@strong{NOTE}: @code{DROP TABLE} is not transaction-safe and will -automatically commit any active transactions. - - -@node DELETE, TRUNCATE, DROP TABLE, Reference -@section @code{DELETE} Syntax - -@findex DELETE - -@example -DELETE [LOW_PRIORITY] FROM tbl_name - [WHERE where_definition] - [LIMIT rows] -@end example - -@code{DELETE} deletes rows from @code{tbl_name} that satisfy the condition -given by @code{where_definition}, and returns the number of records deleted. - -@c If an @code{ORDER BY} clause is used, the rows will be deleted in that order. -@c This is really only useful in conjunction with @code{LIMIT}. For example: - -@c @example -@c DELETE FROM somelog -@c WHERE user = 'jcole' -@c ORDER BY timestamp -@c LIMIT 1 -@c @end example - -@c This will delete the oldest entry (by @code{timestamp}) where the row matches -@c the @code{WHERE} clause. - -If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are -deleted. If you do this in @code{AUTOCOMMIT} mode, this works as -@code{TRUNCATE}. @xref{TRUNCATE}. One problem with this is that -@code{DELETE} will return zero as the number of affected records, but -this will be fixed in 4.0. - -If you really want to know how many records are deleted when you are deleting -all rows, and are willing to suffer a speed penalty, you can use a -@code{DELETE} statement of this form: - -@example -mysql> DELETE FROM tbl_name WHERE 1>0; -@end example - -Note that this is MUCH slower than @code{DELETE FROM tbl_name} with no -@code{WHERE} clause, because it deletes rows one at a time. - -If you specify the keyword @code{LOW_PRIORITY}, execution of the -@code{DELETE} is delayed until no other clients are reading from the table. - -Deleted records are maintained in a linked list and subsequent @code{INSERT} -operations reuse old record positions. To reclaim unused space and reduce -file sizes, use the @code{OPTIMIZE TABLE} statement or the @code{myisamchk} -utility to reorganize tables. @code{OPTIMIZE TABLE} is easier, but -@code{myisamchk} is faster. -See @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}. - -The @strong{MySQL}-specific @code{LIMIT rows} option to @code{DELETE} tells -the server the maximum number of rows to be deleted before control is -returned to the client. This can be used to ensure that a specific -@code{DELETE} command doesn't take too much time. You can simply repeat -the @code{DELETE} command until the number of affected rows is less than -the @code{LIMIT} value. - -@findex TRUNCATE -@node TRUNCATE, SELECT, DELETE, Reference -@section @code{TRUNCATE} Syntax - -@example -TRUNCATE TABLE table_name -@end example - -Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}. -The differences are: - -@itemize @bullet -@item -Implemented as a drop and re-create of the table, which makes this -much faster when deleting many rows. -@item -Not transaction-safe; @code{TRUNCATE TABLE} will automatically end the current -transaction as if @code{COMMIT} would have been called. -@item -Doesn't return the number of deleted rows. -@item -As long as the table definition file @file{table_name.frm} is -valid, the table can be re-created this way, even if the data or index -files have become corrupted. -@end itemize - -@code{TRUNCATE} is an Oracle SQL extension. +@node SELECT, INSERT, Data Manipulation, Data Manipulation +@subsection @code{SELECT} Syntax @findex SELECT -@node SELECT, JOIN, TRUNCATE, Reference -@section @code{SELECT} Syntax @c help SELECT @example @@ -32606,6 +32027,14 @@ If you are using @code{FOR UPDATE} on a table handler with page/row locks, the examined rows will be write locked. @end itemize + +@menu +* JOIN:: +@end menu + +@node JOIN, , SELECT, SELECT +@subsubsection @code{JOIN} Syntax + @findex JOIN @findex INNER JOIN @findex CROSS JOIN @@ -32618,8 +32047,6 @@ the examined rows will be write locked. @findex NATURAL RIGHT JOIN @findex NATURAL RIGHT OUTER JOIN @findex STRAIGHT_JOIN -@node JOIN, INSERT, SELECT, Reference -@section @code{JOIN} Syntax @strong{MySQL} supports the following @code{JOIN} syntaxes for use in @code{SELECT} statements: @@ -32752,9 +32179,11 @@ mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND @xref{LEFT JOIN optimization, , @code{LEFT JOIN} optimization}. + +@node INSERT, INSERT DELAYED, SELECT, Data Manipulation +@subsection @code{INSERT} Syntax + @findex INSERT -@node INSERT, REPLACE, JOIN, Reference -@section @code{INSERT} Syntax @example INSERT [LOW_PRIORITY | DELAYED] [IGNORE] @@ -32880,13 +32309,14 @@ type. The column is set to the appropriate zero value for the type. @findex REPLACE ... SELECT @findex INSERT ... SELECT + @menu * INSERT SELECT:: -* INSERT DELAYED:: @end menu -@node INSERT SELECT, INSERT DELAYED, INSERT, INSERT -@subsection @code{INSERT ... SELECT} Syntax + +@node INSERT SELECT, , INSERT, INSERT +@subsubsection @code{INSERT ... SELECT} Syntax @example INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ... @@ -32930,11 +32360,14 @@ original tables, @strong{MySQL} will not allow concurrent inserts during You can of course also use @code{REPLACE} instead of @code{INSERT} to overwrite old rows. + +@node INSERT DELAYED, UPDATE, INSERT, Data Manipulation +@subsection @code{INSERT DELAYED} syntax + @findex INSERT DELAYED @findex DELAYED + @cindex INSERT DELAYED -@node INSERT DELAYED, , INSERT SELECT, INSERT -@subsection @code{INSERT DELAYED} syntax @example INSERT DELAYED ... @@ -33060,9 +32493,145 @@ server to handle a separate thread for each table on which you use @code{INSERT DELAYED}. This means that you should only use @code{INSERT DELAYED} when you are really sure you need it! + +@node UPDATE, DELETE, INSERT DELAYED, Data Manipulation +@subsection @code{UPDATE} Syntax + +@findex UPDATE + +@example +UPDATE [LOW_PRIORITY] [IGNORE] tbl_name + SET col_name1=expr1, [col_name2=expr2, ...] + [WHERE where_definition] + [LIMIT #] +@end example + +@code{UPDATE} updates columns in existing table rows with new values. +The @code{SET} clause indicates which columns to modify and the values +they should be given. The @code{WHERE} clause, if given, specifies +which rows should be updated. Otherwise all rows are updated. If the +@code{ORDER BY} clause is specified, the rows will be updated in the +order that is specified. + +If you specify the keyword @code{LOW_PRIORITY}, execution of the +@code{UPDATE} is delayed until no other clients are reading from the table. + +If you specify the keyword @code{IGNORE}, the update statement will not +abort even if we get duplicate key errors during the update. Rows that +would cause conflicts will not be updated. + +If you access a column from @code{tbl_name} in an expression, +@code{UPDATE} uses the current value of the column. For example, the +following statement sets the @code{age} column to one more than its +current value: + +@example +mysql> UPDATE persondata SET age=age+1; +@end example + +@code{UPDATE} assignments are evaluated from left to right. For example, the +following statement doubles the @code{age} column, then increments it: + +@example +mysql> UPDATE persondata SET age=age*2, age=age+1; +@end example + +If you set a column to the value it currently has, @strong{MySQL} notices +this and doesn't update it. + +@findex mysql_info() +@code{UPDATE} returns the number of rows that were actually changed. +In @strong{MySQL} Version 3.22 or later, the C API function @code{mysql_info()} +returns the number of rows that were matched and updated and the number of +warnings that occurred during the @code{UPDATE}. + +In @strong{MySQL} Version 3.23, you can use @code{LIMIT #} to ensure that +only a given number of rows are changed. + + +@node DELETE, TRUNCATE, UPDATE, Data Manipulation +@subsection @code{DELETE} Syntax + +@findex DELETE + +@example +DELETE [LOW_PRIORITY] FROM tbl_name + [WHERE where_definition] + [LIMIT rows] +@end example + +@code{DELETE} deletes rows from @code{tbl_name} that satisfy the condition +given by @code{where_definition}, and returns the number of records deleted. + +If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are +deleted. If you do this in @code{AUTOCOMMIT} mode, this works as +@code{TRUNCATE}. @xref{TRUNCATE}. One problem with this is that +@code{DELETE} will return zero as the number of affected records, but +this will be fixed in 4.0. + +If you really want to know how many records are deleted when you are deleting +all rows, and are willing to suffer a speed penalty, you can use a +@code{DELETE} statement of this form: + +@example +mysql> DELETE FROM tbl_name WHERE 1>0; +@end example + +Note that this is MUCH slower than @code{DELETE FROM tbl_name} with no +@code{WHERE} clause, because it deletes rows one at a time. + +If you specify the keyword @code{LOW_PRIORITY}, execution of the +@code{DELETE} is delayed until no other clients are reading from the table. + +Deleted records are maintained in a linked list and subsequent @code{INSERT} +operations reuse old record positions. To reclaim unused space and reduce +file sizes, use the @code{OPTIMIZE TABLE} statement or the @code{myisamchk} +utility to reorganize tables. @code{OPTIMIZE TABLE} is easier, but +@code{myisamchk} is faster. +See @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}. + +The @strong{MySQL}-specific @code{LIMIT rows} option to @code{DELETE} tells +the server the maximum number of rows to be deleted before control is +returned to the client. This can be used to ensure that a specific +@code{DELETE} command doesn't take too much time. You can simply repeat +the @code{DELETE} command until the number of affected rows is less than +the @code{LIMIT} value. + + +@node TRUNCATE, REPLACE, DELETE, Data Manipulation +@subsection @code{TRUNCATE} Syntax + +@findex TRUNCATE + +@example +TRUNCATE TABLE table_name +@end example + +Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}. +The differences are: + +@itemize @bullet +@item +Implemented as a drop and re-create of the table, which makes this +much faster when deleting many rows. +@item +Not transaction-safe; @code{TRUNCATE TABLE} will automatically end the current +transaction as if @code{COMMIT} would have been called. +@item +Doesn't return the number of deleted rows. +@item +As long as the table definition file @file{table_name.frm} is +valid, the table can be re-created this way, even if the data or index +files have become corrupted. +@end itemize + +@code{TRUNCATE} is an Oracle SQL extension. + + +@node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation +@subsection @code{REPLACE} Syntax + @findex REPLACE -@node REPLACE, LOAD DATA, INSERT, Reference -@section @code{REPLACE} Syntax @example REPLACE [LOW_PRIORITY | DELAYED] @@ -33092,9 +32661,11 @@ this case one row was inserted and then the duplicate was deleted. The above makes it easy to check if @code{REPLACE} added or replaced a row. + +@node LOAD DATA, , REPLACE, Data Manipulation +@subsection @code{LOAD DATA INFILE} Syntax + @findex LOAD DATA INFILE -@node LOAD DATA, UPDATE, REPLACE, Reference -@section @code{LOAD DATA INFILE} Syntax @example LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' @@ -33586,62 +33157,1022 @@ For more information about the efficiency of @code{INSERT} versus @code{LOAD DATA INFILE} and speeding up @code{LOAD DATA INFILE}, @xref{Insert speed}. -@findex UPDATE -@node UPDATE, USE, LOAD DATA, Reference -@section @code{UPDATE} Syntax + +@node Data Definition, Basic User Commands, Data Manipulation, Reference +@section Data Definition: @code{CREATE}, @code{DROP}, @code{ALTER} + +@menu +* CREATE DATABASE:: +* DROP DATABASE:: +* CREATE TABLE:: +* ALTER TABLE:: +* RENAME TABLE:: +* DROP TABLE:: +* CREATE INDEX:: +* DROP INDEX:: +@end menu + + +@node CREATE DATABASE, DROP DATABASE, Data Definition, Data Definition +@subsection @code{CREATE DATABASE} Syntax + +@findex CREATE DATABASE @example -UPDATE [LOW_PRIORITY] [IGNORE] tbl_name - SET col_name1=expr1, [col_name2=expr2, ...] - [WHERE where_definition] - [LIMIT #] +CREATE DATABASE [IF NOT EXISTS] db_name @end example -@code{UPDATE} updates columns in existing table rows with new values. -The @code{SET} clause indicates which columns to modify and the values -they should be given. The @code{WHERE} clause, if given, specifies -which rows should be updated. Otherwise all rows are updated. If the -@code{ORDER BY} clause is specified, the rows will be updated in the -order that is specified. +@code{CREATE DATABASE} creates a database with the given name. Rules for +allowable database names are given in @ref{Legal names}. An error occurs if +the database already exists and you didn't specify @code{IF NOT EXISTS}. -If you specify the keyword @code{LOW_PRIORITY}, execution of the -@code{UPDATE} is delayed until no other clients are reading from the table. +Databases in @strong{MySQL} are implemented as directories containing files +that correspond to tables in the database. Because there are no tables in a +database when it is initially created, the @code{CREATE DATABASE} statement +only creates a directory under the @strong{MySQL} data directory. -If you specify the keyword @code{IGNORE}, the update statement will not -abort even if we get duplicate key errors during the update. Rows that -would cause conflicts will not be updated. +@cindex @code{mysqladmin} +You can also create databases with @code{mysqladmin}. +@xref{Client-Side Scripts}. -If you access a column from @code{tbl_name} in an expression, -@code{UPDATE} uses the current value of the column. For example, the -following statement sets the @code{age} column to one more than its -current value: + +@node DROP DATABASE, CREATE TABLE, CREATE DATABASE, Data Definition +@subsection @code{DROP DATABASE} Syntax + +@findex DROP DATABASE @example -mysql> UPDATE persondata SET age=age+1; +DROP DATABASE [IF EXISTS] db_name @end example -@code{UPDATE} assignments are evaluated from left to right. For example, the -following statement doubles the @code{age} column, then increments it: +@code{DROP DATABASE} drops all tables in the database and deletes the +database. If you do a @code{DROP DATABASE} on a symbolic linked +database, both the link and the original database is deleted. @strong{Be +VERY careful with this command!} + +@code{DROP DATABASE} returns the number of files that were removed from +the database directory. Normally, this is three times the number of +tables, because normally each table corresponds to a @file{.MYD} file, a +@file{.MYI} file, and a @file{.frm} file. + +The @code{DROP DATABASE} command removes from the given database +directory all files with the following extensions: + +@multitable @columnfractions .25 .25 .25 .25 +@item .BAK @tab .DAT @tab .HSH @tab .ISD +@item .ISM @tab .ISM @tab .MRG @tab .MYD +@item .MYI @tab .db @tab .frm +@end multitable + +All subdirectories that consists of 2 digits (@code{RAID} directories) +are also removed. + +In @strong{MySQL} Version 3.22 or later, you can use the keywords +@code{IF EXISTS} to prevent an error from occurring if the database doesn't +exist. + +@cindex @code{mysqladmin} +You can also drop databases with @code{mysqladmin}. @xref{Client-Side Scripts}. + + +@menu +* CREATE TABLE:: +* ALTER TABLE:: +* RENAME TABLE:: +* DROP TABLE:: +* CREATE INDEX:: +* DROP INDEX:: +@end menu + +@node CREATE TABLE, ALTER TABLE, DROP DATABASE, Data Definition +@subsection @code{CREATE TABLE} Syntax + +@findex CREATE TABLE + +@menu +* Silent column changes:: Silent column changes +@end menu @example -mysql> UPDATE persondata SET age=age*2, age=age+1; +CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] +[table_options] [select_statement] + +create_definition: + col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] + [PRIMARY KEY] [reference_definition] + or PRIMARY KEY (index_col_name,...) + or KEY [index_name] (index_col_name,...) + or INDEX [index_name] (index_col_name,...) + or UNIQUE [INDEX] [index_name] (index_col_name,...) + or FULLTEXT [INDEX] [index_name] (index_col_name,...) + or [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...) + [reference_definition] + or CHECK (expr) + +type: + TINYINT[(length)] [UNSIGNED] [ZEROFILL] + or SMALLINT[(length)] [UNSIGNED] [ZEROFILL] + or MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] + or INT[(length)] [UNSIGNED] [ZEROFILL] + or INTEGER[(length)] [UNSIGNED] [ZEROFILL] + or BIGINT[(length)] [UNSIGNED] [ZEROFILL] + or REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] + or DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] + or FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] + or DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] + or NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] + or CHAR(length) [BINARY] + or VARCHAR(length) [BINARY] + or DATE + or TIME + or TIMESTAMP + or DATETIME + or TINYBLOB + or BLOB + or MEDIUMBLOB + or LONGBLOB + or TINYTEXT + or TEXT + or MEDIUMTEXT + or LONGTEXT + or ENUM(value1,value2,value3,...) + or SET(value1,value2,value3,...) + +index_col_name: + col_name [(length)] + +reference_definition: + REFERENCES tbl_name [(index_col_name,...)] + [MATCH FULL | MATCH PARTIAL] + [ON DELETE reference_option] + [ON UPDATE reference_option] + +reference_option: + RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT + +table_options: + TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MYISAM @} +or AUTO_INCREMENT = # +or AVG_ROW_LENGTH = # +or CHECKSUM = @{0 | 1@} +or COMMENT = "string" +or MAX_ROWS = # +or MIN_ROWS = # +or PACK_KEYS = @{0 | 1@} +or PASSWORD = "string" +or DELAY_KEY_WRITE = @{0 | 1@} +or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} +or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=# +or UNION = (table_name,[table_name...]) +or DATA DIRECTORY="directory" +or INDEX DIRECTORY="directory" + +select_statement: + [IGNORE | REPLACE] SELECT ... (Some legal select statement) @end example -If you set a column to the value it currently has, @strong{MySQL} notices -this and doesn't update it. +@code{CREATE TABLE} +creates a table with the given name in the current database. Rules for +allowable table names are given in @ref{Legal names}. An error occurs if +there is no current database or if the table already exists. +In @strong{MySQL} Version 3.22 or later, the table name can be specified as +@code{db_name.tbl_name}. This works whether or not there is a current +database. + +In @strong{MySQL} Version 3.23, you can use the @code{TEMPORARY} keyword when +you create a table. A temporary table will automatically be deleted if a +connection dies and the name is per connection. This means that two different +connections can both use the same temporary table name without conflicting +with each other or with an existing table of the same name. (The existing table +is hidden until the temporary table is deleted). + +In @strong{MySQL} Version 3.23 or later, you can use the keywords +@code{IF NOT EXISTS} so that an error does not occur if the table already +exists. Note that there is no verification that the table structures are +identical. + +Each table @code{tbl_name} is represented by some files in the database +directory. In the case of MyISAM-type tables you will get: + +@multitable @columnfractions .2 .8 +@item @strong{File} @tab @strong{Purpose} +@item @code{tbl_name.frm} @tab Table definition (form) file +@item @code{tbl_name.MYD} @tab Data file +@item @code{tbl_name.MYI} @tab Index file +@end multitable + +For more information on the properties of the various column types, see +@ref{Column types}: + +@itemize @bullet +@item +If neither @code{NULL} nor @code{NOT NULL} is specified, the column +is treated as though @code{NULL} had been specified. + +@item +An integer column may have the additional attribute @code{AUTO_INCREMENT}. +When you insert a value of @code{NULL} (recommended) or @code{0} into an +@code{AUTO_INCREMENT} column, the column is set to @code{value+1}, where +@code{value} is the largest value for the column currently in the table. +@code{AUTO_INCREMENT} sequences begin with @code{1}. +@xref{mysql_insert_id, , @code{mysql_insert_id()}}. + +If you delete the row containing the maximum value for an +@code{AUTO_INCREMENT} column, the value will be reused with an +@code{ISAM}, or @code{BDB} table but not with a +@code{MyISAM} or @code{InnoDB} table. If you delete all rows in the table +with @code{DELETE FROM table_name} (without a @code{WHERE}) in +@code{AUTOCOMMIT} mode, the sequence starts over for all table types. + +@strong{NOTE:} There can be only one @code{AUTO_INCREMENT} column per +table, and it must be indexed. @strong{MySQL} Version 3.23 will also only +work properly if the auto_increment column only has positive +values. Inserting a negative number is regarded as inserting a very large +positive number. This is done to avoid precision problems when +numbers 'wrap' over from positive to negative and also to ensure that one +doesn't accidentally get an auto_increment column that contains 0. + +@cindex ODBC compatibility +@cindex compatibility, with ODBC +To make @strong{MySQL} compatible with some ODBC applications, you can find +the last inserted row with the following query: + +@example +SELECT * FROM tbl_name WHERE auto_col IS NULL +@end example + +@item +@code{NULL} values are handled differently for @code{TIMESTAMP} columns than +for other column types. You cannot store a literal @code{NULL} in a +@code{TIMESTAMP} column; setting the column to @code{NULL} sets it to the +current date and time. Because @code{TIMESTAMP} columns behave this way, the +@code{NULL} and @code{NOT NULL} attributes do not apply in the normal way and +are ignored if you specify them. + +On the other hand, to make it easier for @strong{MySQL} clients to use +@code{TIMESTAMP} columns, the server reports that such columns may be +assigned @code{NULL} values (which is true), even though @code{TIMESTAMP} +never actually will contain a @code{NULL} value. You can see this when you +use @code{DESCRIBE tbl_name} to get a description of your table. + +Note that setting a @code{TIMESTAMP} column to @code{0} is not the same +as setting it to @code{NULL}, because @code{0} is a valid @code{TIMESTAMP} +value. + +@item +If no @code{DEFAULT} value is specified for a column, @strong{MySQL} +automatically assigns one. + +If the column may take @code{NULL} as a value, the default value is +@code{NULL}. + +If the column is declared as @code{NOT NULL}, the default value depends on +the column type: + +@itemize @minus +@item +For numeric types other than those declared with the @code{AUTO_INCREMENT} +attribute, the default is @code{0}. For an @code{AUTO_INCREMENT} column, the +default value is the next value in the sequence. + +@item +For date and time types other than @code{TIMESTAMP}, the default is the +appropriate zero value for the type. For the first @code{TIMESTAMP} +column in a table, the default value is the current date and time. +@xref{Date and time types}. + +@item +For string types other than @code{ENUM}, the default value is the empty string. +For @code{ENUM}, the default is the first enumeration value. +@end itemize + +Default values must be constants. This means, for example, that you cannot +set the default for a date column to be the value of a function such as +@code{NOW()} or @code{CURRENT_DATE}. + +@item +@code{KEY} is a synonym for @code{INDEX}. + +@item +In @strong{MySQL}, a @code{UNIQUE} key can have only distinct values. An +error occurs if you try to add a new row with a key that matches an existing +row. + +@item +@tindex PRIMARY KEY +A @code{PRIMARY KEY} is a unique @code{KEY} with the extra constraint +that all key columns must be defined as @code{NOT NULL}. In @strong{MySQL} +the key is named @code{PRIMARY}. A table can have only one @code{PRIMARY KEY}. +If you don't have a @code{PRIMARY KEY} and some applications ask for the +@code{PRIMARY KEY} in your tables, @strong{MySQL} will return the first +@code{UNIQUE} key, which doesn't have any @code{NULL} columns, as the +@code{PRIMARY KEY}. + +@item +A @code{PRIMARY KEY} can be a multiple-column index. However, you cannot +create a multiple-column index using the @code{PRIMARY KEY} key attibute in a +column specification. Doing so will mark only that single column as primary. +You must use the @code{PRIMARY KEY(index_col_name, ...)} syntax. + +@item +If the @code{PRIMARY} or @code{UNIQUE} key consists of only one column and this +is of type integer, you can also refer to it as @code{_rowid} +(new in Version 3.23.11). + +@item +If you don't assign a name to an index, the index will be assigned the same +name as the first @code{index_col_name}, with an optional suffix (@code{_2}, +@code{_3}, @code{...}) to make it unique. You can see index names for a +table using @code{SHOW INDEX FROM tbl_name}. +@xref{SHOW, , @code{SHOW}}. + +@item +@cindex @code{NULL} values, and indexes +@cindex indexes, and @code{NULL} values +Only the @code{MyISAM} table type supports indexes on columns that can have +@code{NULL} values. In other cases you must declare such columns +@code{NOT NULL} or an error results. + +@item +With @code{col_name(length)} syntax, you can specify an index that +uses only a part of a @code{CHAR} or @code{VARCHAR} column. This can +make the index file much smaller. +@xref{Indexes}. + +@item +@cindex @code{BLOB} columns, indexing +@cindex indexes, and @code{BLOB} columns +@cindex @code{TEXT} columns, indexing +@cindex indexes, and @code{TEXT} columns +Only the @code{MyISAM} table type supports indexing on @code{BLOB} and +@code{TEXT} columns. When putting an index on a @code{BLOB} or @code{TEXT} +column you MUST always specify the length of the index: +@example +CREATE TABLE test (blob_col BLOB, index(blob_col(10))); +@end example + +@item +When you use @code{ORDER BY} or @code{GROUP BY} with a @code{TEXT} or +@code{BLOB} column, only the first @code{max_sort_length} bytes are used. +@xref{BLOB, , @code{BLOB}}. + +@item +In @strong{MySQL} Version 3.23.23 or later, you can also create special +@strong{FULLTEXT} indexes. They are used for full-text search. Only the +@code{MyISAM} table type supports @code{FULLTEXT} indexes. They can be created +only from @code{VARCHAR} and @code{TEXT} columns. +Indexing always happens over the entire column, partial indexing is not +supported. See @ref{Fulltext Search} for details of operation. + +@item +The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't +actually do anything. The syntax for them is provided only for compatibility, +to make it easier to port code from other SQL servers and to run applications +that create tables with references. +@xref{Missing functions}. + +@item +Each @code{NULL} column takes one bit extra, rounded up to the nearest byte. + +@item +The maximum record length in bytes can be calculated as follows: + +@example +row length = 1 + + (sum of column lengths) + + (number of NULL columns + 7)/8 + + (number of variable-length columns) +@end example + +@item +The @code{table_options} and @code{SELECT} options are only +implemented in @strong{MySQL} Version 3.23 and above. + +The different table types are: + +@multitable @columnfractions .20 .80 +@item BDB or Berkeley_db @tab Transaction-safe tables with page locking. @xref{BDB}. +@item HEAP @tab The data for this table is only stored in memory. @xref{HEAP}. +@item ISAM @tab The original table handler. @xref{ISAM}. +@item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}. +@item MERGE @tab A collection of MyISAM tables used as one table. @xref{MERGE}. +@item MyISAM @tab The new binary portable table handler that is replacing ISAM. @xref{MyISAM}. +@end multitable +@xref{Table types}. + +If a table type is specified, and that particular type is not available, +@strong{MySQL} will choose the closest table type to the one that you have +specified. For example, if @code{TYPE=BDB} is specified, and that distribution +of @strong{MySQL} does not support @code{BDB} tables, the table will be created +as @code{MyISAM} instead. + +The other table options are used to optimize the behavior of the +table. In most cases, you don't have to specify any of them. +The options work for all table types, if not otherwise indicated: + +@multitable @columnfractions .20 .80 +@item @code{AUTO_INCREMENT} @tab The next auto_increment value you want to set for your table (MyISAM). +@item @code{AVG_ROW_LENGTH} @tab An approximation of the average row length for your table. You only need to set this for large tables with variable size records. +@item @code{CHECKSUM} @tab Set this to 1 if you want @strong{MySQL} to maintain a checksum for all rows (makes the table a little slower to update but makes it easier to find corrupted tables) (MyISAM). +@item @code{COMMENT} @tab A 60-character comment for your table. +@item @code{MAX_ROWS} @tab Max number of rows you plan to store in the table. +@item @code{MIN_ROWS} @tab Minimum number of rows you plan to store in the table. +@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). +@item @code{PASSWORD} @tab Encrypt the @code{.frm} file with a password. This option doesn't do anything in the standard @strong{MySQL} version. +@item @code{DELAY_KEY_WRITE} @tab Set this to 1 if want to delay key table updates until the table is closed (MyISAM). +@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently you can only use the DYNAMIC and STATIC options for MyISAM tables. +@end multitable + +When you use a @code{MyISAM} table, @strong{MySQL} uses the product of +@code{max_rows * avg_row_length} to decide how big the resulting table +will be. If you don't specify any of the above options, the maximum size +for a table will be 4G (or 2G if your operating systems only supports 2G +tables). The reason for this is just to keep down the pointer sizes +to make the index smaller and faster if you don't really need big files. + +If you don't use @code{PACK_KEYS}, the default is to only pack strings, +not numbers. If you use @code{PACK_KEYS=1}, numbers will be packed as well. + +When packing binary number keys, @strong{MySQL} will use prefix compression. +This means that you will only get a big benefit of this if you have +many numbers that are the same. Prefix compression means that every +key needs one extra byte to indicate how many bytes of the previous key are +the same for the next key (note that the pointer to the row is stored +in high-byte-first-order directly after the key, to improve +compression.) This means that if you have many equal keys on two rows +in a row, all following 'same' keys will usually only take 2 bytes +(including the pointer to the row). Compare this to the ordinary case +where the following keys will take storage_size_for_key + +pointer_size (usually 4). On the other hand, if all keys are +totally different, you will lose 1 byte per key, if the key isn't a +key that can have @code{NULL} values (In this case the packed key length will +be stored in the same byte that is used to mark if a key is @code{NULL}.) + +@item +If you specify a @code{SELECT} after the @code{CREATE} statement, +@strong{MySQL} will create new fields for all elements in the +@code{SELECT}. For example: + +@example +mysql> CREATE TABLE test (a int not null auto_increment, + primary key (a), key(b)) + TYPE=MyISAM SELECT b,c from test2; +@end example + +This will create a @code{MyISAM} table with three columns, a, b, and c. +Notice that the columns from the @code{SELECT} statement are appended to +the right side of the table, not overlapped onto it. Take the following +example: + +@example +mysql> select * from foo; ++---+ +| n | ++---+ +| 1 | ++---+ + +mysql> create table bar (m int) select n from foo; +Query OK, 1 row affected (0.02 sec) +Records: 1 Duplicates: 0 Warnings: 0 + +mysql> select * from bar; ++------+---+ +| m | n | ++------+---+ +| NULL | 1 | ++------+---+ +1 row in set (0.00 sec) +@end example + +For each row in table @code{foo}, a row is inserted in @code{bar} with +the values from @code{foo} and default values for the new columns. + +@code{CREATE TABLE ... SELECT} will not automaticly create any indexes +for you. This is done intentionally to make the command as flexible as +possible. If you want to have indexes in the created table, you should +specify these before the @code{SELECT} statement: + +@example +mysql> create table bar (unique (n)) select n from foo; +@end example + +If any errors occur while copying the data to the table, it will +automatically be deleted. + +To ensure that the update log/binary log can be used to re-create the +original tables, @strong{MySQL} will not allow concurrent inserts during +@code{CREATE TABLE .... SELECT}. +@item +The @code{RAID_TYPE} option will help you to break the 2G/4G limit for +the MyISAM data file (not the index file) on +operating systems that don't support big files. You can get also more speed +from the I/O bottleneck by putting @code{RAID} directories on different +physical disks. @code{RAID_TYPE} will work on any OS, as long as you have +configured @strong{MySQL} with @code{--with-raid}. For now the only allowed +@code{RAID_TYPE} is @code{STRIPED} (@code{1} and @code{RAID0} are aliases +for this). + +If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table, +@code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00, +01, 02 in the database directory. In each of these directories +@code{MyISAM} will create a @code{table_name.MYD}. When writing data +to the data file, the @code{RAID} handler will map the first +@code{RAID_CHUNKSIZE} *1024 bytes to the first file, the next +@code{RAID_CHUNKSIZE} *1024 bytes to the next file and so on. +@item +@code{UNION} is used when you want to use a collection of identical +tables as one. This only works with MERGE tables. @xref{MERGE}. + +For the moment you need to have @code{SELECT}, @code{UPDATE}, and +@code{DELETE} privileges on the tables you map to a @code{MERGE} table. +All mapped tables must be in the same database as the @code{MERGE} table. +@item +In the created table the @code{PRIMARY} key will be placed first, followed +by all @code{UNIQUE} keys and then the normal keys. This helps the +@strong{MySQL} optimizer to prioritize which key to use and also more quickly +detect duplicated @code{UNIQUE} keys. + +@item +By using @code{DATA DIRECTORY="directory"} or @code{INDEX +DIRECTORY="directory"} you can specify where the table handler should +put it's table and index files. This only works for @code{MyISAM} tables +in @code{MySQL} 4.0, when you are not using the @code{--skip-symlink} +option. @xref{Symbolic links to tables}. + +@end itemize + + +@node Silent column changes, , CREATE TABLE, CREATE TABLE +@subsubsection Silent Column Specification Changes + +@cindex silent column changes + +In some cases, @strong{MySQL} silently changes a column specification from +that given in a @code{CREATE TABLE} statement. (This may also occur with +@code{ALTER TABLE}.): + +@itemize @bullet +@item +@code{VARCHAR} columns with a length less than four are changed to +@code{CHAR}. + +@item +If any column in a table has a variable length, the entire row is +variable-length as a result. Therefore, if a table contains any +variable-length columns (@code{VARCHAR}, @code{TEXT}, or @code{BLOB}), +all @code{CHAR} columns longer than three characters are changed to +@code{VARCHAR} columns. This doesn't affect how you use the columns in +any way; in @strong{MySQL}, @code{VARCHAR} is just a different way to +store characters. @strong{MySQL} performs this conversion because it +saves space and makes table operations faster. @xref{Table types}. + +@item +@code{TIMESTAMP} display sizes must be even and in the range from 2 to 14. +If you specify a display size of 0 or greater than 14, the size is coerced +to 14. Odd-valued sizes in the range from 1 to 13 are coerced +to the next higher even number. + +@item +You cannot store a literal @code{NULL} in a @code{TIMESTAMP} column; setting +it to @code{NULL} sets it to the current date and time. Because +@code{TIMESTAMP} columns behave this way, the @code{NULL} and @code{NOT NULL} +attributes do not apply in the normal way and are ignored if you specify +them. @code{DESCRIBE tbl_name} always reports that a @code{TIMESTAMP} +column may be assigned @code{NULL} values. + +@item +@strong{MySQL} maps certain column types used by other SQL database vendors +to @strong{MySQL} types. @xref{Other-vendor column types}. +@end itemize + +If you want to see whether or not @strong{MySQL} used a column type other +than the one you specified, issue a @code{DESCRIBE tbl_name} statement after +creating or altering your table. + +@cindex @code{myisampack} +Certain other column type changes may occur if you compress a table +using @code{myisampack}. @xref{Compressed format}. + + +@node ALTER TABLE, RENAME TABLE, CREATE TABLE, Data Definition +@subsection @code{ALTER TABLE} Syntax + +@findex ALTER TABLE + +@example +ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...] + +alter_specification: + ADD [COLUMN] create_definition [FIRST | AFTER column_name ] + or ADD [COLUMN] (create_definition, create_definition,...) + or ADD INDEX [index_name] (index_col_name,...) + or ADD PRIMARY KEY (index_col_name,...) + or ADD UNIQUE [index_name] (index_col_name,...) + or ADD FULLTEXT [index_name] (index_col_name,...) + or ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...) + [reference_definition] + or ALTER [COLUMN] col_name @{SET DEFAULT literal | DROP DEFAULT@} + or CHANGE [COLUMN] old_col_name create_definition + or MODIFY [COLUMN] create_definition + or DROP [COLUMN] col_name + or DROP PRIMARY KEY + or DROP INDEX index_name + or RENAME [TO] new_tbl_name + or ORDER BY col + or table_options +@end example + +@code{ALTER TABLE} allows you to change the structure of an existing table. +For example, you can add or delete columns, create or destroy indexes, change +the type of existing columns, or rename columns or the table itself. You can +also change the comment for the table and type of the table. +@xref{CREATE TABLE, , @code{CREATE TABLE}}. + +If you use @code{ALTER TABLE} to change a column specification but +@code{DESCRIBE tbl_name} indicates that your column was not changed, it is +possible that @strong{MySQL} ignored your modification for one of the reasons +described in @ref{Silent column changes}. For example, if you try to change +a @code{VARCHAR} column to @code{CHAR}, @strong{MySQL} will still use +@code{VARCHAR} if the table contains other variable-length columns. + +@code{ALTER TABLE} works by making a temporary copy of the original table. +The alteration is performed on the copy, then the original table is +deleted and the new one is renamed. This is done in such a way that +all updates are automatically redirected to the new table without +any failed updates. While @code{ALTER TABLE} is executing, the original +table is readable by other clients. Updates and writes to the table +are stalled until the new table is ready. + +Note that if you use any other option to @code{ALTER TABLE} than +@code{RENAME}, @strong{MySQL} will always create a temporary table, even +if the data wouldn't strictly need to be copied (like when you change the +name of a column). We plan to fix this in the future, but as one doesn't +normally do @code{ALTER TABLE} that often this isn't that high on our TODO. + +@itemize @bullet +@item +To use @code{ALTER TABLE}, you need @strong{ALTER}, @strong{INSERT}, +and @strong{CREATE} privileges on the table. + +@item +@code{IGNORE} is a @strong{MySQL} extension to ANSI SQL92. +It controls how @code{ALTER TABLE} works if there are duplicates on +unique keys in the new table. +If @code{IGNORE} isn't specified, the copy is aborted and rolled back. +If @code{IGNORE} is specified, then for rows with duplicates on a unique +key, only the first row is used; the others are deleted. + +@item +You can issue multiple @code{ADD}, @code{ALTER}, @code{DROP}, and +@code{CHANGE} clauses in a single @code{ALTER TABLE} statement. This is a +@strong{MySQL} extension to ANSI SQL92, which allows only one of each clause +per @code{ALTER TABLE} statement. + +@item +@code{CHANGE col_name}, @code{DROP col_name}, and @code{DROP +INDEX} are @strong{MySQL} extensions to ANSI SQL92. + +@item +@code{MODIFY} is an Oracle extension to @code{ALTER TABLE}. + +@item +The optional word @code{COLUMN} is a pure noise word and can be omitted. + +@item +If you use @code{ALTER TABLE tbl_name RENAME TO new_name} without any other +options, @strong{MySQL} simply renames the files that correspond to the table +@code{tbl_name}. There is no need to create the temporary table. +@xref{RENAME TABLE,, @code{RENAME TABLE}}. + +@item +@code{create_definition} clauses use the same syntax for @code{ADD} and +@code{CHANGE} as for @code{CREATE TABLE}. Note that this syntax includes +the column name, not just the column type. +@xref{CREATE TABLE, , @code{CREATE TABLE}}. + +@item +You can rename a column using a @code{CHANGE old_col_name create_definition} +clause. To do so, specify the old and new column names and the type that +the column currently has. For example, to rename an @code{INTEGER} column +from @code{a} to @code{b}, you can do this: + +@example +mysql> ALTER TABLE t1 CHANGE a b INTEGER; +@end example + +If you want to change a column's type but not the name, @code{CHANGE} +syntax still requires two column names even if they are the same. For +example: + +@example +mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL; +@end example + +However, as of @strong{MySQL} Version 3.22.16a, you can also use @code{MODIFY} +to change a column's type without renaming it: + +@example +mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL; +@end example + +@item +If you use @code{CHANGE} or @code{MODIFY} to shorten a column for which +an index exists on part of the column (for instance, if you have an index +on the first 10 characters of a @code{VARCHAR} column), you cannot make +the column shorter than the number of characters that are indexed. + +@item +When you change a column type using @code{CHANGE} or @code{MODIFY}, +@strong{MySQL} tries to convert data to the new type as well as possible. + +@item +In @strong{MySQL} Version 3.22 or later, you can use @code{FIRST} or +@code{ADD ... AFTER col_name} to add a column at a specific position within +a table row. The default is to add the column last. + +@findex ALTER COLUMN +@item +@code{ALTER COLUMN} specifies a new default value for a column +or removes the old default value. +If the old default is removed and the column can be @code{NULL}, the new +default is @code{NULL}. If the column cannot be @code{NULL}, @strong{MySQL} +assigns a default value, as described in +@ref{CREATE TABLE, , @code{CREATE TABLE}}. + +@findex DROP INDEX +@item +@code{DROP INDEX} removes an index. This is a @strong{MySQL} extension to +ANSI SQL92. @xref{DROP INDEX}. + +@item +If columns are dropped from a table, the columns are also removed from any +index of which they are a part. If all columns that make up an index are +dropped, the index is dropped as well. + +@item +If a table contains only one column, the column cannot be dropped. +If what you intend is to remove the table, use @code{DROP TABLE} instead. + +@findex DROP PRIMARY KEY +@item +@code{DROP PRIMARY KEY} drops the primary index. If no such +index exists, it drops the first @code{UNIQUE} index in the table. +(@strong{MySQL} marks the first @code{UNIQUE} key as the @code{PRIMARY KEY} +if no @code{PRIMARY KEY} was specified explicitly.) + +@findex ORDER BY +@item +@code{ORDER BY} allows you to create the new table with the rows in a +specific order. Note that the table will not remain in this order after +inserts and deletes. In some cases, it may make sorting easier for +@strong{MySQL} if the table is in order by the column that you wish to +order it by later. This option is mainly useful when you know that you +are mostly going to query the rows in a certain order; By using this +option after big changes to the table, you may be able to get higher +performance. + +@findex ALTER TABLE +@item +If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique +indexes are created in a separate batch (like in @code{REPAIR}). +This should make @code{ALTER TABLE} much faster when you have many indexes. + +@item @findex mysql_info() -@code{UPDATE} returns the number of rows that were actually changed. -In @strong{MySQL} Version 3.22 or later, the C API function @code{mysql_info()} -returns the number of rows that were matched and updated and the number of -warnings that occurred during the @code{UPDATE}. +With the C API function @code{mysql_info()}, you can find out how many +records were copied, and (when @code{IGNORE} is used) how many records were +deleted due to duplication of unique key values. -In @strong{MySQL} Version 3.23, you can use @code{LIMIT #} to ensure that -only a given number of rows are changed. +@item +@cindex foreign keys +@cindex references +The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't +actually do anything. The syntax for them is provided only for compatibility, +to make it easier to port code from other SQL servers and to run applications +that create tables with references. +@xref{Missing functions}. +@end itemize + +Here is an example that shows some of the uses of @code{ALTER TABLE}. We +begin with a table @code{t1} that is created as shown below: + +@example +mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); +@end example + +To rename the table from @code{t1} to @code{t2}: + +@example +mysql> ALTER TABLE t1 RENAME t2; +@end example + +To change column @code{a} from @code{INTEGER} to @code{TINYINT NOT NULL} +(leaving the name the same), and to change column @code{b} from +@code{CHAR(10)} to @code{CHAR(20)} as well as renaming it from @code{b} to +@code{c}: + +@example +mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20); +@end example + +To add a new @code{TIMESTAMP} column named @code{d}: + +@example +mysql> ALTER TABLE t2 ADD d TIMESTAMP; +@end example + +To add an index on column @code{d}, and make column @code{a} the primary key: + +@example +mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a); +@end example + +To remove column @code{c}: + +@example +mysql> ALTER TABLE t2 DROP COLUMN c; +@end example + +To add a new @code{AUTO_INCREMENT} integer column named @code{c}: + +@example +mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, + ADD INDEX (c); +@end example + +Note that we indexed @code{c}, because @code{AUTO_INCREMENT} columns must be +indexed, and also that we declare @code{c} as @code{NOT NULL}, because +indexed columns cannot be @code{NULL}. + +When you add an @code{AUTO_INCREMENT} column, column values are filled in +with sequence numbers for you automatically. You can set the first +sequence number by executing @code{SET INSERT_ID=#} before +@code{ALTER TABLE} or using the @code{AUTO_INCREMENT = #} table option. +@xref{SET OPTION}. + +With MyISAM tables, if you don't change the @code{AUTO_INCREMENT} +column, the sequence number will not be affected. If you drop an +@code{AUTO_INCREMENT} column and then add another @code{AUTO_INCREMENT} +column, the numbers will start from 1 again. + +@xref{ALTER TABLE problems}. + + +@node RENAME TABLE, DROP TABLE, ALTER TABLE, Data Definition +@subsection @code{RENAME TABLE} Syntax + +@findex RENAME TABLE + +@example +RENAME TABLE tbl_name TO new_table_name[, tbl_name2 TO new_table_name2,...] +@end example + +The rename is done atomically, which means that no other thread can +access any of the tables while the rename is running. This makes it +possible to replace a table with an empty one: + +@example +CREATE TABLE new_table (...); +RENAME TABLE old_table TO backup_table, new_table TO old_table; +@end example + +The rename is done from left to right, which means that if you want to +swap two tables names, you have to: + +@example +RENAME TABLE old_table TO backup_table, + new_table TO old_table, + backup_table TO new_table; +@end example + +As long as two databases are on the same disk you can also rename +from one database to another: + +@example +RENAME TABLE current_database.table_name TO other_database.table_name; +@end example + +When you execute @code{RENAME}, you can't have any locked tables or +active transactions. You must also have the @code{ALTER} and @code{DROP} +privilege on the original table and @code{CREATE} and @code{INSERT} +privilege on the new table. + +If @strong{MySQL} encounters any errors in a multiple table rename, it +will do a reverse rename for all renamed tables to get everything back +to the original state. + + +@node DROP TABLE, CREATE INDEX, RENAME TABLE, Data Definition +@subsection @code{DROP TABLE} Syntax + +@findex DROP TABLE + +@example +DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE] +@end example + +@code{DROP TABLE} removes one or more tables. All table data and the table +definition are @emph{removed}, so @strong{be careful} with this command! + +In @strong{MySQL} Version 3.22 or later, you can use the keywords +@code{IF EXISTS} to prevent an error from occurring for tables that don't +exist. + +@code{RESTRICT} and @code{CASCADE} are allowed to make porting easier. +For the moment they don't do anything. + +@strong{NOTE}: @code{DROP TABLE} is not transaction-safe and will +automatically commit any active transactions. + + +@node CREATE INDEX, DROP INDEX, DROP TABLE, Data Definition +@subsection @code{CREATE INDEX} Syntax + +@findex CREATE INDEX + +@cindex indexes +@cindex indexes, multi-part +@cindex multi-part index + +@example +CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tbl_name (col_name[(length)],... ) +@end example + +The @code{CREATE INDEX} statement doesn't do anything in @strong{MySQL} prior +to Version 3.22. In Version 3.22 or later, @code{CREATE INDEX} is mapped to an +@code{ALTER TABLE} statement to create indexes. +@xref{ALTER TABLE, , @code{ALTER TABLE}}. + +Normally, you create all indexes on a table at the time the table itself +is created with @code{CREATE TABLE}. +@xref{CREATE TABLE, , @code{CREATE TABLE}}. +@code{CREATE INDEX} allows you to add indexes to existing tables. + +A column list of the form @code{(col1,col2,...)} creates a multiple-column +index. Index values are formed by concatenating the values of the given +columns. + +For @code{CHAR} and @code{VARCHAR} columns, indexes can be created that +use only part of a column, using @code{col_name(length)} syntax. (On +@code{BLOB} and @code{TEXT} columns the length is required). The +statement shown below creates an index using the first 10 characters of +the @code{name} column: + +@example +mysql> CREATE INDEX part_of_name ON customer (name(10)); +@end example + +Because most names usually differ in the first 10 characters, this index should +not be much slower than an index created from the entire @code{name} column. +Also, using partial columns for indexes can make the index file much smaller, +which could save a lot of disk space and might also speed up @code{INSERT} +operations! + +Note that you can only add an index on a column that can have @code{NULL} +values or on a @code{BLOB}/@code{TEXT} column if you are using +@strong{MySQL} Version 3.23.2 or newer and are using the @code{MyISAM} +table type. + +For more information about how @strong{MySQL} uses indexes, see +@ref{MySQL indexes, , @strong{MySQL} indexes}. + +@code{FULLTEXT} indexes can index only @code{VARCHAR} and +@code{TEXT} columns, and only in @code{MyISAM} tables. @code{FULLTEXT} indexes +are available in @strong{MySQL} Version 3.23.23 and later. +@ref{Fulltext Search}. + + +@node DROP INDEX, , CREATE INDEX, Data Definition +@subsection @code{DROP INDEX} Syntax + +@findex DROP INDEX + +@example +DROP INDEX index_name ON tbl_name +@end example + +@code{DROP INDEX} drops the index named @code{index_name} from the table +@code{tbl_name}. @code{DROP INDEX} doesn't do anything in @strong{MySQL} +prior to Version 3.22. In Version 3.22 or later, @code{DROP INDEX} is mapped to an +@code{ALTER TABLE} statement to drop the index. +@xref{ALTER TABLE, , @code{ALTER TABLE}}. + + +@node Basic User Commands, Transactional Commands, Data Definition, Reference +@section Basic MySQL User Utility Commands + +@menu +* USE:: +* DESCRIBE:: +@end menu + + +@node USE, DESCRIBE, Basic User Commands, Basic User Commands +@subsection @code{USE} Syntax @findex USE -@node USE, DESCRIBE, UPDATE, Reference -@section @code{USE} Syntax @example USE db_name @@ -33675,11 +34206,11 @@ mysql> SELECT author_name,editor_name FROM author,db2.editor The @code{USE} statement is provided for Sybase compatibility. +@node DESCRIBE, , USE, Basic User Commands +@subsection @code{DESCRIBE} Syntax (Get Information About Columns) @findex DESC @findex DESCRIBE -@node DESCRIBE, COMMIT, USE, Reference -@section @code{DESCRIBE} Syntax (Get Information About Columns) @example @{DESCRIBE | DESC@} tbl_name @{col_name | wild@} @@ -33703,11 +34234,23 @@ This statement is provided for Oracle compatibility. The @code{SHOW} statement provides similar information. @xref{SHOW, , @code{SHOW}}. + +@node Transactional Commands, Fulltext Search, Basic User Commands, Reference +@section MySQL Transactional and Locking Commands + +@menu +* COMMIT:: +* LOCK TABLES:: +* SET TRANSACTION:: +@end menu + + +@node COMMIT, LOCK TABLES, Transactional Commands, Transactional Commands +@subsection @code{BEGIN/COMMIT/ROLLBACK} Syntax + @findex BEGIN @findex COMMIT @findex ROLLBACK -@node COMMIT, LOCK TABLES, DESCRIBE, Reference -@section @code{BEGIN/COMMIT/ROLLBACK} Syntax By default, @strong{MySQL} runs in @code{autocommit} mode. This means that as soon as you execute an update, @strong{MySQL} will store the update on @@ -33761,10 +34304,12 @@ a @code{COMMIT} before executing the command): You can change the isolation level for transactions with @code{SET TRANSACTION ISOLATION LEVEL ...}. @xref{SET TRANSACTION}. + +@node LOCK TABLES, SET TRANSACTION, COMMIT, Transactional Commands +@subsection @code{LOCK TABLES/UNLOCK TABLES} Syntax + @findex LOCK TABLES @findex UNLOCK TABLES -@node LOCK TABLES, CREATE INDEX, COMMIT, Reference -@section @code{LOCK TABLES/UNLOCK TABLES} Syntax @example LOCK TABLES tbl_name [AS alias] @{READ | [READ LOCAL] | [LOW_PRIORITY] WRITE@} @@ -33898,276 +34443,297 @@ automatically commit any active transactions before attempting to lock the tables. -@node CREATE INDEX, DROP INDEX, LOCK TABLES, Reference -@section @code{CREATE INDEX} Syntax +@node SET TRANSACTION, , LOCK TABLES, Transactional Commands +@subsection @code{SET TRANSACTION} Syntax -@findex CREATE INDEX - -@cindex indexes -@cindex indexes, multi-part -@cindex multi-part index +@findex ISOLATION LEVEL @example -CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tbl_name (col_name[(length)],... ) +SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL +[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE] @end example -The @code{CREATE INDEX} statement doesn't do anything in @strong{MySQL} prior -to Version 3.22. In Version 3.22 or later, @code{CREATE INDEX} is mapped to an -@code{ALTER TABLE} statement to create indexes. -@xref{ALTER TABLE, , @code{ALTER TABLE}}. +Sets the transaction isolation level for the global, whole session or +the next transaction. -Normally, you create all indexes on a table at the time the table itself -is created with @code{CREATE TABLE}. -@xref{CREATE TABLE, , @code{CREATE TABLE}}. -@code{CREATE INDEX} allows you to add indexes to existing tables. +The default behavior is to set the isolation level for the next (not started) +transaction. -A column list of the form @code{(col1,col2,...)} creates a multiple-column -index. Index values are formed by concatenating the values of the given -columns. +If you set the @code{GLOBAL} privilege it will affect all new created threads. +You will need the @code{PROCESS} privilege to do do this. -For @code{CHAR} and @code{VARCHAR} columns, indexes can be created that -use only part of a column, using @code{col_name(length)} syntax. (On -@code{BLOB} and @code{TEXT} columns the length is required). The -statement shown below creates an index using the first 10 characters of -the @code{name} column: +Setting the @code{SESSION} privilege will affect the following and all +future transactions. + +You can set the default isolation level for @code{mysqld} with +@code{--transaction-isolation=...}. @xref{Command-line options}. + + +@node Fulltext Search, , Transactional Commands, Reference +@section MySQL Full-text Search + +@cindex searching, full-text +@cindex full-text search +@cindex FULLTEXT + +Since Version 3.23.23, @strong{MySQL} has support for full-text indexing +and searching. Full-text indexes in @strong{MySQL} are an index of type +@code{FULLTEXT}. @code{FULLTEXT} indexes can be created from @code{VARCHAR} +and @code{TEXT} columns at @code{CREATE TABLE} time or added later with +@code{ALTER TABLE} or @code{CREATE INDEX}. For large datasets, adding +@code{FULLTEXT} index with @code{ALTER TABLE} (or @code{CREATE INDEX}) would +be much faster than inserting rows into the empty table with a @code{FULLTEXT} +index. + +Full-text search is performed with the @code{MATCH} function. @example -mysql> CREATE INDEX part_of_name ON customer (name(10)); +mysql> CREATE TABLE articles ( + -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + -> title VARCHAR(200), + -> body TEXT, + -> FULLTEXT (title,body) + -> ); +Query OK, 0 rows affected (0.00 sec) + +mysql> INSERT INTO articles VALUES + -> (0,'MySQL Tutorial', 'DBMS stands for DataBase Management ...'), + -> (0,'How To Use MySQL Efficiently', 'After you went through a ...'), + -> (0,'Optimizing MySQL','In this tutorial we will show how to ...'), + -> (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. Normalize ...'), + -> (0,'MySQL vs. YourSQL', 'In the following database comparison we ...'), + -> (0,'MySQL Security', 'When configured properly, MySQL could be ...'); +Query OK, 5 rows affected (0.00 sec) +Records: 5 Duplicates: 0 Warnings: 0 + +mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database'); ++----+-------------------+---------------------------------------------+ +| id | title | body | ++----+-------------------+---------------------------------------------+ +| 5 | MySQL vs. YourSQL | In the following database comparison we ... | +| 1 | MySQL Tutorial | DBMS stands for DataBase Management ... | ++----+-------------------+---------------------------------------------+ +2 rows in set (0.00 sec) @end example -Because most names usually differ in the first 10 characters, this index should -not be much slower than an index created from the entire @code{name} column. -Also, using partial columns for indexes can make the index file much smaller, -which could save a lot of disk space and might also speed up @code{INSERT} -operations! +The function @code{MATCH} matches a natural language query @code{AGAINST} +a text collection (which is simply the set of columns covered by a +@code{FULLTEXT} index). For every row in a table it returns relevance - +a similarity measure between the text in that row (in the columns that are +part of the collection) and the query. When it is used in a @code{WHERE} +clause (see example above) the rows returned are automatically sorted with +relevance decreasing. Relevance is a non-negative floating-point number. +Zero relevance means no similarity. Relevance is computed based on the +number of words in the row, the number of unique words in that row, the +total number of words in the collection, and the number of documents (rows) +that contain a particular word. -Note that you can only add an index on a column that can have @code{NULL} -values or on a @code{BLOB}/@code{TEXT} column if you are using -@strong{MySQL} Version 3.23.2 or newer and are using the @code{MyISAM} -table type. - -For more information about how @strong{MySQL} uses indexes, see -@ref{MySQL indexes, , @strong{MySQL} indexes}. - -@code{FULLTEXT} indexes can index only @code{VARCHAR} and -@code{TEXT} columns, and only in @code{MyISAM} tables. @code{FULLTEXT} indexes -are available in @strong{MySQL} Version 3.23.23 and later. -@ref{Fulltext Search}. - -@findex DROP INDEX -@node DROP INDEX, Comments, CREATE INDEX, Reference -@section @code{DROP INDEX} Syntax +The above is a basic example of using @code{MATCH} function. Rows are +returned with relevance decreasing. @example -DROP INDEX index_name ON tbl_name +mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles; ++----+-----------------------------------------+ +| id | MATCH (title,body) AGAINST ('Tutorial') | ++----+-----------------------------------------+ +| 1 | 0.64840710366884 | +| 2 | 0 | +| 3 | 0.66266459031789 | +| 4 | 0 | +| 5 | 0 | +| 6 | 0 | ++----+-----------------------------------------+ +5 rows in set (0.00 sec) @end example -@code{DROP INDEX} drops the index named @code{index_name} from the table -@code{tbl_name}. @code{DROP INDEX} doesn't do anything in @strong{MySQL} -prior to Version 3.22. In Version 3.22 or later, @code{DROP INDEX} is mapped to an -@code{ALTER TABLE} statement to drop the index. -@xref{ALTER TABLE, , @code{ALTER TABLE}}. - -@findex Comment syntax -@cindex comments, adding -@node Comments, CREATE FUNCTION, DROP INDEX, Reference -@section Comment Syntax - -The @strong{MySQL} server supports the @code{# to end of line}, @code{-- -to end of line} and @code{/* in-line or multiple-line */} comment -styles: +This example shows how to retrieve the relevances. As neither @code{WHERE} +nor @code{ORDER BY} clauses are present, returned rows are not ordered. @example -mysql> select 1+1; # This comment continues to the end of line -mysql> select 1+1; -- This comment continues to the end of line -mysql> select 1 /* this is an in-line comment */ + 1; -mysql> select 1+ -/* -this is a -multiple-line comment -*/ -1; +mysql> SELECT id, body, MATCH (title,body) AGAINST ( + -> 'Security implications of running MySQL as root') AS score + -> FROM articles WHERE MATCH (title,body) AGAINST + -> ('Security implications of running MySQL as root'); ++----+-----------------------------------------------+-----------------+ +| id | body | score | ++----+-----------------------------------------------+-----------------+ +| 4 | 1. Never run mysqld as root. 2. Normalize ... | 1.5055546709332 | +| 6 | When configured properly, MySQL could be ... | 1.31140957288 | ++----+-----------------------------------------------+-----------------+ +2 rows in set (0.00 sec) @end example -Note that the @code{--} comment style requires you to have at least one space -after the @code{--}! +This is more complex example - the query returns the relevance and still +sorts the rows with relevance decreasing. To achieve it one should specify +@code{MATCH} twice. Note, that this will cause no additional overhead, as +@strong{MySQL} optimizer will notice that these two @code{MATCH} calls are +identical and will call full-text search code only once. -Although the server understands the comment syntax just described, -there are some limitations on the way that the @code{mysql} client -parses @code{/* ... */} comments: +@strong{MySQL} uses a very simple parser to split text into words. A +``word'' is any sequence of letters, numbers, @samp{'}, and @samp{_}. Any +``word'' that is present in the stopword list or just too short (3 +characters or less) is ignored. + +Every correct word in the collection and in the query is weighted, +according to its significance in the query or collection. This way, a +word that is present in many documents will have lower weight (and may +even have a zero weight), because it has lower semantic value in this +particular collection. Otherwise, if the word is rare, it will receive a +higher weight. The weights of the words are then combined to compute the +relevance of the row. + +Such a technique works best with large collections (in fact, it was +carefully tuned this way). For very small tables, word distribution +does not reflect adequately their semantical value, and this model +may sometimes produce bizarre results. + +@example +mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL'); +Empty set (0.00 sec) +@end example + +Search for the word @code{MySQL} produces no results in the above example. +Word @code{MySQL} is present in more than half of rows, and as such, is +effectively treated as a stopword (that is, with semantical value zero). +It is, really, the desired behavior - a natural language query should not +return every second row in 1GB table. + +A word that matches half of rows in a table is less likely to locate relevant +documents. In fact, it will most likely find plenty of irrelevant documents. +We all know this happens far too often when we are trying to find something on +the Internet with a search engine. It is with this reasoning that such rows +have been assigned a low semantical value in @strong{this particular dataset}. + +@menu +* Fulltext restrictions:: +* Fulltext Fine-tuning:: +* Fulltext Features to Appear in MySQL 4.0:: +* Fulltext TODO:: +@end menu + + +@node Fulltext restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search +@subsection Fulltext restrictions @itemize @bullet @item -Single-quote and double-quote characters are taken to indicate the beginning -of a quoted string, even within a comment. If the quote is not matched by a -second quote within the comment, the parser doesn't realize the comment has -ended. If you are running @code{mysql} interactively, you can tell that it -has gotten confused like this because the prompt changes from @code{mysql>} -to @code{'>} or @code{">}. +All parameters to the @code{MATCH} function must be columns from the +same table that is part of the same fulltext index. +@item +The argument to @code{AGAINST} must be a constant string. +@end itemize + + +@node Fulltext Fine-tuning, Fulltext Features to Appear in MySQL 4.0, Fulltext restrictions, Fulltext Search +@subsection Fine-tuning MySQL Full-text Search + +Unfortunately, full-text search has no user-tunable parameters yet, +although adding some is very high on the TODO. However, if you have a +@strong{MySQL} source distribution (@xref{Installing source}.), you can +somewhat alter the full-text search behavior. + +Note that full-text search was carefully tuned for the best searching +effectiveness. Modifying the default behavior will, in most cases, +only make the search results worse. Do not alter the @strong{MySQL} sources +unless you know what you are doing! + +@itemize @item -A semicolon is taken to indicate the end of the current SQL statement -and anything following it to indicate the beginning of the next statement. +Minimal length of word to be indexed is defined in +@code{myisam/ftdefs.h} file by the line +@example +#define MIN_WORD_LEN 4 +@end example +Change it to the value you prefer, recompile @strong{MySQL}, and rebuild +your @code{FULLTEXT} indexes. + +@item +The stopword list is defined in @code{myisam/ft_static.c} +Modify it to your taste, recompile @strong{MySQL} and rebuild +your @code{FULLTEXT} indexes. + +@item +The 50% threshold is caused by the particular weighting scheme chosen. To +disable it, change the following line in @code{myisam/ftdefs.h}: +@example +#define GWS_IN_USE GWS_PROB +@end example +to +@example +#define GWS_IN_USE GWS_FREQ +@end example +and recompile @strong{MySQL}. +There is no need to rebuild the indexes in this case. + @end itemize -These limitations apply both when you run @code{mysql} interactively -and when you put commands in a file and tell @code{mysql} to read its -input from that file with @code{mysql < some-file}. -@strong{MySQL} doesn't support the @samp{--} ANSI SQL comment style. -@xref{Missing comments}. +@node Fulltext Features to Appear in MySQL 4.0, Fulltext TODO, Fulltext Fine-tuning, Fulltext Search +@subsection New Features of Full-text Search to Appear in MySQL 4.0 -@findex CREATE FUNCTION -@findex DROP FUNCTION -@findex UDF functions -@findex User-defined functions -@findex Functions, user-defined -@node CREATE FUNCTION, Reserved words, Comments, Reference -@section @code{CREATE FUNCTION/DROP FUNCTION} Syntax - -@example -CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} - SONAME shared_library_name - -DROP FUNCTION function_name -@end example - -A user-definable function (UDF) is a way to extend @strong{MySQL} with a new -function that works like native (built in) @strong{MySQL} functions such as -@code{ABS()} and @code{CONCAT()}. - -@code{AGGREGATE} is a new option for @strong{MySQL} Version 3.23. An -@code{AGGREGATE} function works exactly like a native @strong{MySQL} -@code{GROUP} function like @code{SUM} or @code{COUNT()}. - -@code{CREATE FUNCTION} saves the function's name, type, and shared library -name in the @code{mysql.func} system table. You must have the -@strong{insert} and @strong{delete} privileges for the @code{mysql} database -to create and drop functions. - -All active functions are reloaded each time the server starts, unless -you start @code{mysqld} with the @code{--skip-grant-tables} option. In -this case, UDF initialization is skipped and UDFs are unavailable. -(An active function is one that has been loaded with @code{CREATE FUNCTION} -and not removed with @code{DROP FUNCTION}.) - -For instructions on writing user-definable functions, see @ref{Adding -functions}. For the UDF mechanism to work, functions must be written in C or -C++, your operating system must support dynamic loading and you must have -compiled @code{mysqld} dynamically (not statically). - -@cindex keywords -@cindex reserved words, exceptions -@node Reserved words, , CREATE FUNCTION, Reference -@section Is MySQL Picky About Reserved Words? - -A common problem stems from trying to create a table with column names that -use the names of datatypes or functions built into @strong{MySQL}, such as -@code{TIMESTAMP} or @code{GROUP}. 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 @samp{(} when using functions whose names are also -column names. - -The following words are explicitly reserved in @strong{MySQL}. Most of -them are forbidden by ANSI SQL92 as column and/or table names -(for example, @code{group}). -A few are reserved because @strong{MySQL} needs them and is -(currently) using a @code{yacc} parser: - -@c This is fixed by including the symbols table from lex.h here and then running -@c fix-mysql-reserved-words in emacs (or let David do it): -@c (defun fix-mysql-reserved-words () -@c (interactive) -@c (let ((cnt 0)) -@c (insert "\n@item ") -@c (while (looking-at "[ \t]*{ +\"\\([^\"]+\\)\"[ \t]*,.*\n") -@c (replace-match "@code{\\1}") -@c (incf cnt) -@c (if (> cnt 3) -@c (progn -@c (setf cnt 0) -@c (insert "\n@item ")) -@c (insert " @tab "))))) -@c But remove the non alphanumeric entries by hand first. -@c Updated after 3.23.4 990928 by David - -@multitable @columnfractions .25 .25 .25 .25 -@item @code{action} @tab @code{add} @tab @code{aggregate} @tab @code{all} -@item @code{alter} @tab @code{after} @tab @code{and} @tab @code{as} -@item @code{asc} @tab @code{avg} @tab @code{avg_row_length} @tab @code{auto_increment} -@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary} -@item @code{blob} @tab @code{bool} @tab @code{both} @tab @code{by} -@item @code{cascade} @tab @code{case} @tab @code{char} @tab @code{character} -@item @code{change} @tab @code{check} @tab @code{checksum} @tab @code{column} -@item @code{columns} @tab @code{comment} @tab @code{constraint} @tab @code{create} -@item @code{cross} @tab @code{current_date} @tab @code{current_time} @tab @code{current_timestamp} -@item @code{data} @tab @code{database} @tab @code{databases} @tab @code{date} -@item @code{datetime} @tab @code{day} @tab @code{day_hour} @tab @code{day_minute} -@item @code{day_second} @tab @code{dayofmonth} @tab @code{dayofweek} @tab @code{dayofyear} -@item @code{dec} @tab @code{decimal} @tab @code{default} @tab @code{delayed} -@item @code{delay_key_write} @tab @code{delete} @tab @code{desc} @tab @code{describe} -@item @code{distinct} @tab @code{distinctrow} @tab @code{double} @tab @code{drop} -@item @code{end} @tab @code{else} @tab @code{escape} @tab @code{escaped} -@item @code{enclosed} @tab @code{enum} @tab @code{explain} @tab @code{exists} -@item @code{fields} @tab @code{file} @tab @code{first} @tab @code{float} -@item @code{float4} @tab @code{float8} @tab @code{flush} @tab @code{foreign} -@item @code{from} @tab @code{for} @tab @code{full} @tab @code{function} -@item @code{global} @tab @code{grant} @tab @code{grants} @tab @code{group} -@item @code{having} @tab @code{heap} @tab @code{high_priority} @tab @code{hour} -@item @code{hour_minute} @tab @code{hour_second} @tab @code{hosts} @tab @code{identified} -@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile} -@item @code{inner} @tab @code{insert} @tab @code{insert_id} @tab @code{int} -@item @code{integer} @tab @code{interval} @tab @code{int1} @tab @code{int2} -@item @code{int3} @tab @code{int4} @tab @code{int8} @tab @code{into} -@item @code{if} @tab @code{is} @tab @code{isam} @tab @code{join} -@item @code{key} @tab @code{keys} @tab @code{kill} @tab @code{last_insert_id} -@item @code{leading} @tab @code{left} @tab @code{length} @tab @code{like} -@item @code{lines} @tab @code{limit} @tab @code{load} @tab @code{local} -@item @code{lock} @tab @code{logs} @tab @code{long} @tab @code{longblob} -@item @code{longtext} @tab @code{low_priority} @tab @code{max} @tab @code{max_rows} -@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint} -@item @code{middleint} @tab @code{min_rows} @tab @code{minute} @tab @code{minute_second} -@item @code{modify} @tab @code{month} @tab @code{monthname} @tab @code{myisam} -@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not} -@item @code{null} @tab @code{on} @tab @code{optimize} @tab @code{option} -@item @code{optionally} @tab @code{or} @tab @code{order} @tab @code{outer} -@item @code{outfile} @tab @code{pack_keys} @tab @code{partial} @tab @code{password} -@item @code{precision} @tab @code{primary} @tab @code{procedure} @tab @code{process} -@item @code{processlist} @tab @code{privileges} @tab @code{read} @tab @code{real} -@item @code{references} @tab @code{reload} @tab @code{regexp} @tab @code{rename} -@item @code{replace} @tab @code{restrict} @tab @code{returns} @tab @code{revoke} -@item @code{rlike} @tab @code{row} @tab @code{rows} @tab @code{second} -@item @code{select} @tab @code{set} @tab @code{show} @tab @code{shutdown} -@item @code{smallint} @tab @code{soname} @tab @code{sql_big_tables} @tab @code{sql_big_selects} -@item @code{sql_low_priority_updates} @tab @code{sql_log_off} @tab @code{sql_log_update} @tab @code{sql_select_limit} -@item @code{sql_small_result} @tab @code{sql_big_result} @tab @code{sql_warnings} @tab @code{straight_join} -@item @code{starting} @tab @code{status} @tab @code{string} @tab @code{table} -@item @code{tables} @tab @code{temporary} @tab @code{terminated} @tab @code{text} -@item @code{then} @tab @code{time} @tab @code{timestamp} @tab @code{tinyblob} -@item @code{tinytext} @tab @code{tinyint} @tab @code{trailing} @tab @code{to} -@item @code{type} @tab @code{use} @tab @code{using} @tab @code{unique} -@item @code{unlock} @tab @code{unsigned} @tab @code{update} @tab @code{usage} -@item @code{values} @tab @code{varchar} @tab @code{variables} @tab @code{varying} -@item @code{varbinary} @tab @code{with} @tab @code{write} @tab @code{when} -@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 these names are very natural names and a lot of people have already -used them. +This section includes a list of the fulltext features that are already +implemented in the 4.0 tree. It explains +@strong{More functions for full-text search} entry of @ref{TODO MySQL 4.0}. @itemize @bullet -@item @code{ACTION} -@item @code{BIT} -@item @code{DATE} -@item @code{ENUM} -@item @code{NO} -@item @code{TEXT} -@item @code{TIME} -@item @code{TIMESTAMP} +@item @code{REPAIR TABLE} with @code{FULLTEXT} indexes, +@code{ALTER TABLE} with @code{FULLTEXT} indexes, and +@code{OPTIMIZE TABLE} with @code{FULLTEXT} indexes are now +up to 100 times faster. + +@item @code{MATCH ... AGAINST} is going to supports the following +@strong{boolean operators}: + +@itemize @bullet +@item @code{+}word means the that word @strong{must} be present in every +row returned. +@item @code{-}word means the that word @strong{must not} be present in every +row returned. +@item @code{<} and @code{>} can be used to decrease and increase word +weight in the query. +@item @code{~} can be used to assign a @strong{negative} weight to a noise +word. +@item @code{*} is a truncation operator. @end itemize +Boolean search utilizes a more simplistic way of calculating the relevance, +that does not have a 50% threshold. + +@item Searches are now up to 2 times faster due to optimized search algorithm. + +@item Utility program @code{ft_dump} added for low-level @code{FULLTEXT} +index operations (querying/dumping/statistics). + +@end itemize + + +@node Fulltext TODO, , Fulltext Features to Appear in MySQL 4.0, Fulltext Search +@subsection Full-text Search TODO + +@itemize @bullet +@item Make all operations with @code{FULLTEXT} index @strong{faster}. +@item Support for braces @code{()} in boolean full-text search. +@item Phrase search, proximity operators +@item Boolean search can work without @code{FULLTEXT} index +(yes, @strong{very} slow). +@item Support for "always-index words". They could be any strings +the user wants to treat as words, examples are "C++", "AS/400", "TCP/IP", etc. +@item Support for full-text search in @code{MERGE} tables. +@item Support for multi-byte charsets. +@item Make stopword list to depend of the language of the data. +@item Stemming (dependent of the language of the data, of course). +@item Generic user-supplyable UDF (?) preparser. +@item Make the model more flexible (by adding some adjustable +parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}). +@end itemize + + + + +@node Table types, Clients, Reference, Top +@chapter MySQL Table Types + @cindex table types, choosing @cindex @code{BDB} table type @cindex @code{Berkeley_db} table type @@ -34178,8 +34744,6 @@ used them. @cindex MySQL table types @cindex @code{MyISAM} table type @cindex types, of tables -@node Table types, Fulltext Search, Reference, Top -@chapter MySQL Table Types As of @strong{MySQL} Version 3.23.6, you can choose between three basic table formats (@code{ISAM}, @code{HEAP} and @code{MyISAM}. Newer @@ -34250,10 +34814,11 @@ of both worlds. * MERGE:: MERGE tables * ISAM:: ISAM tables * HEAP:: HEAP tables -* InnoDB:: InnoDB tables * BDB:: BDB or Berkeley_db tables +* InnoDB:: InnoDB tables @end menu + @node MyISAM, MERGE, Table types, Table types @section MyISAM Tables @@ -34431,10 +34996,12 @@ backup media. * MyISAM table problems:: @end menu -@cindex key space, MyISAM + @node Key space, MyISAM table formats, MyISAM, MyISAM @subsection Space Needed for Keys +@cindex key space, MyISAM + @strong{MySQL} can support different index types, but the normal type is ISAM or MyISAM. These use a B-tree index, and you can roughly calculate the size for the index file as @code{(key_length+4)/0.67}, summed over @@ -34454,6 +35021,7 @@ In @code{MyISAM} tables, you can also prefix compress numbers by specifying many integer keys that have an identical prefix when the numbers are stored high-byte first. + @node MyISAM table formats, MyISAM table problems, Key space, MyISAM @subsection MyISAM Table Formats @@ -34467,6 +35035,7 @@ compressed tables, can only be created with the @code{myisampack} tool. * Compressed format:: Compressed table characteristics @end menu + @node Static format, Dynamic format, MyISAM table formats, MyISAM table formats @subsubsection Static (Fixed-length) Table Characteristics @@ -34506,11 +35075,13 @@ system. Usually requires more disk space than dynamic tables. @end itemize -@cindex dynamic table characteristics -@cindex tables, dynamic + @node Dynamic format, Compressed format, Static format, MyISAM table formats @subsubsection Dynamic Table Characteristics +@cindex dynamic table characteristics +@cindex tables, dynamic + This format is used if the table contains any @code{VARCHAR}, @code{BLOB}, or @code{TEXT} columns or if the table was created with @code{ROW_FORMAT=dynamic}. @@ -34570,10 +35141,12 @@ If not, there will be another link. You may check how many links there are with @code{myisamchk -ed}. All links may be removed with @code{myisamchk -r}. @end itemize -@cindex tables, compressed format + @node Compressed format, , Dynamic format, MyISAM table formats @subsubsection Compressed Table Characteristics +@cindex tables, compressed format + This is a read-only type that is generated with the optional @code{myisampack} tool (@code{pack_isam} for @code{ISAM} tables): @@ -34616,6 +35189,7 @@ columns. Can be uncompressed with @code{myisamchk}. @end itemize + @node MyISAM table problems, , MyISAM table formats, MyISAM @subsection MyISAM table problems. @@ -34628,6 +35202,7 @@ to become corrupted. * MyISAM table close:: @end menu + @node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems @subsubsection Corrupted MyISAM tables. @@ -34675,6 +35250,7 @@ checking if there is a recent row @code{restarted mysqld} in the mysqld error file). If this isn't the case, then you should try to make a test case of this. @xref{Reproduceable test case}. + @node MyISAM table close, , Corrupted MyISAM tables, MyISAM table problems @subsubsection Clients is using or hasn't closed the table properly @@ -34733,11 +35309,13 @@ be avoided as it currently replaces the data file with a new one, which is not signaled to the other servers. @end itemize -@cindex tables, merging -@cindex MERGE tables, defined + @node MERGE, ISAM, MyISAM, Table types @section MERGE Tables +@cindex tables, merging +@cindex MERGE tables, defined + @code{MERGE} tables are new in @strong{MySQL} Version 3.23.25. The code is still in gamma, but should be resonable stable. @@ -34886,10 +35464,12 @@ Change the @code{.MRG} file and issue a @code{FLUSH TABLE} on the read the new definition file. @end itemize -@cindex tables, ISAM + @node ISAM, HEAP, MERGE, Table types @section ISAM Tables +@cindex tables, ISAM + You can also use the deprecated ISAM table type. This will disappear rather soon because @code{MyISAM} is a better implementation of the same thing. ISAM uses a @code{B-tree} index. The index is stored in a file @@ -34928,10 +35508,12 @@ TABLE} statement: mysql> ALTER TABLE tbl_name TYPE = MYISAM; @end example -@cindex tables, @code{HEAP} -@node HEAP, InnoDB, ISAM, Table types + +@node HEAP, BDB, ISAM, Table types @section HEAP Tables +@cindex tables, @code{HEAP} + @code{HEAP} tables use a hashed index and are stored in memory. This makes them very fast, but if @strong{MySQL} crashes you will lose all data stored in them. @code{HEAP} is very useful for temporary tables! @@ -35006,7 +35588,303 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) @code{sizeof(char*)} is 4 on 32-bit machines and 8 on 64-bit machines. -@node InnoDB, BDB, HEAP, Table types + +@node BDB, InnoDB, HEAP, Table types +@section BDB or Berkeley_DB Tables + +@cindex tables, @code{BDB} +@cindex tables, @code{Berkeley DB} + +@menu +* BDB overview:: Overview of BDB Tables +* BDB install:: Installing BDB +* BDB start:: BDB startup options +* BDB characteristic:: Some characteristic of @code{BDB} tables: +* BDB TODO:: Some things we need to fix for BDB in the near future: +* BDB portability:: Operating systems supported by @strong{BDB} +* BDB errors:: Errors You May Get When Using BDB Tables +@end menu + +@node BDB overview, BDB install, BDB, BDB +@subsection Overview of BDB Tables + +Support for BDB tables is included in the @strong{MySQL} source distribution +starting from Version 3.23.34 and is activated in the @strong{MySQL}-Max +binary. + +BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided +@strong{MySQL} with a transactional table handler. By using BerkeleyDB +tables, your tables may have a greater chance of surviving crashes, and also +provides @code{COMMIT} and @code{ROLLBACK} on transactions. The +@strong{MySQL} source distribution comes with a BDB distribution that has a +couple of small patches to make it work more smoothly with @strong{MySQL}. +You can't use a non-patched @code{BDB} version with @strong{MySQL}. + +We at @strong{MySQL AB} are working in close cooperation with Sleepycat to +keep the quality of the @strong{MySQL}/BDB interface high. + +When it comes to supporting BDB tables, we are committed to help our +users to locate the problem and help creating a reproducable test case +for any problems involving BDB tables. Any such test case will be +forwarded to Sleepycat who in turn will help us find and fix the +problem. As this is a two stage operation, any problems with BDB tables +may take a little longer for us to fix than for other table handlers. +However, as the BerkeleyDB code itself has been used by many other +applications than @strong{MySQL}, we don't envision any big problems with +this. @xref{Table handler support}. + + +@node BDB install, BDB start, BDB overview, BDB +@subsection Installing BDB + +If you have downloaded a binary version of @strong{MySQL} that includes +support for BerkeleyDB, simply follow the instructions for installing a +binary version of @strong{MySQL}. +@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}. + +To compile @strong{MySQL} with Berkeley DB support, download @strong{MySQL} +Version 3.23.34 or newer and configure @code{MySQL} with the +@code{--with-berkeley-db} option. @xref{Installing source}. + +@example +cd /path/to/source/of/mysql-3.23.34 +./configure --with-berkeley-db +@end example + +Please refer to the manual provided with the @code{BDB} distribution for +more updated information. + +Even though Berkeley DB is in itself very tested and reliable, +the @strong{MySQL} interface is still considered beta quality. +We are actively improving and optimizing it to get it stable very +soon. + + +@node BDB start, BDB characteristic, BDB install, BDB +@subsection BDB startup options + +If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB} +tables will not be updated until you execute @code{COMMIT}. Instead of commit +you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}. + +If you are running with @code{AUTOCOMMIT=1} (the default), your changes +will be committed immediately. You can start an extended transaction with +the @code{BEGIN WORK} SQL command, after which your changes will not be +committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK} +the changes). + +The following options to @code{mysqld} can be used to change the behavior of +BDB tables: + +@multitable @columnfractions .30 .70 +@item @strong{Option} @tab @strong{Meaning} +@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir. +@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST). +@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory. +@item @code{--bdb-no-sync} @tab Don't synchronously flush logs. +@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode. +@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initializing Berkeley DB) +@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name. +@item @code{--skip-bdb} @tab Don't use berkeley db. +@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}. +@end multitable + +If you use @code{--skip-bdb}, @strong{MySQL} will not initialize the +Berkeley DB library and this will save a lot of memory. Of course, +you cannot use @code{BDB} tables if you are using this option. + +Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you +intend to use BDB tables. This may, however, give you problems when you +try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting +server}. + +With @code{bdb_max_lock} you can specify the maximum number of locks +(10000 by default) you can have active on a BDB table. You should +increase this if you get errors of type @code{bdb: Lock table is out of +available locks} or @code{Got error 12 from ...} when you have do long +transactions or when @code{mysqld} has to examine a lot of rows to +calculate the query. + +You may also want to change @code{binlog_cache_size} and +@code{max_binlog_cache_size} if you are using big multi-line transactions. +@xref{COMMIT}. + + +@node BDB characteristic, BDB TODO, BDB start, BDB +@subsection Some characteristic of @code{BDB} tables: + +@itemize @bullet +@item +To be able to rollback transactions BDB maintain log files. For maximum +performance you should place these on another disk than your databases +by using the @code{--bdb_log_dir} options. +@item +@strong{MySQL} performs a checkpoint each time a new BDB log +file is started, and removes any log files that are not needed for +current transactions. One can also run @code{FLUSH LOGS} at any time +to checkpoint the Berkeley DB tables. + +For disaster recovery, one should use table backups plus +@strong{MySQL}'s binary log. @xref{Backup}. + +@strong{Warning}: If you delete old log files that are in use, BDB will +not be able to do recovery at all and you may lose data if something +goes wrong. +@item +@strong{MySQL} requires a @code{PRIMARY KEY} in each BDB table to be +able to refer to previously read rows. If you don't create one, +@strong{MySQL} will create an maintain a hidden @code{PRIMARY KEY} for +you. The hidden key has a length of 5 bytes and is incremented for each +insert attempt. +@item +If all columns you access in a @code{BDB} table are part of the same index or +part of the primary key, then @strong{MySQL} can execute the query +without having to access the actual row. In a @code{MyISAM} table the +above holds only if the columns are part of the same index. +@item +The @code{PRIMARY KEY} will be faster than any other key, as the +@code{PRIMARY KEY} is stored together with the row data. As the other keys are +stored as the key data + the @code{PRIMARY KEY}, it's important to keep the +@code{PRIMARY KEY} as short as possible to save disk and get better speed. +@item +@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If +you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal +multiple-write lock on the table to ensure that the table will be +properly locked if another thread issues a table lock. +@item +Internal locking in @code{BDB} tables is done on page level. +@item +@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't +maintain a count of the number of rows in the table. +@item +Scanning is slower than with @code{MyISAM} tables as one has data in BDB +tables stored in B-trees and not in a separate data file. +@item +The application must always be prepared to handle cases where +any change of a @code{BDB} table may make an automatic rollback and any +read may fail with a deadlock error. +@item +Keys are not compressed to previous keys as with ISAM or MyISAM +tables. In other words, the key information will take a little more +space in @code{BDB} tables compared to MyISAM tables which don't use +@code{PACK_KEYS=0}. +@item +There is often holes in the BDB table to allow you to insert new rows in +the middle of the key tree. This makes BDB tables somewhat larger than +MyISAM tables. +@item +The optimizer needs to know an approximation of the number of rows in +the table. @strong{MySQL} solves this by counting inserts and +maintaining this in a separate segment in each BDB table. If you don't +do a lot of @code{DELETE} or @code{ROLLBACK}:s this number should be +accurate enough for the @strong{MySQL} optimizer, but as @strong{MySQL} +only store the number on close, it may be wrong if @strong{MySQL} dies +unexpectedly. It should not be fatal even if this number is not 100 % +correct. One can update the number of rows by executing @code{ANALYZE +TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE +TABLE}. +@item +If you get full disk with a @code{BDB} table, you will get an error +(probably error 28) and the transaction should roll back. This is in +contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will +wait for enough free disk before continuing. +@end itemize + + +@node BDB TODO, BDB portability, BDB characteristic, BDB +@subsection Some things we need to fix for BDB in the near future: + +@itemize @bullet +@item +It's very slow to open many BDB tables at the same time. If you are +going to use BDB tables, you should not have a very big table cache (> +256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql} +client. We plan to partly fix this in 4.0. +@item +@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB +tables. +@item +Optimize performance. +@item +Change to not use page locks at all when we are scanning tables. +@end itemize + + +@node BDB portability, BDB errors, BDB TODO, BDB +@subsection Operating systems supported by @strong{BDB} + +If you after having built @strong{MySQL} with support for BDB tables get +the following error in the log file when you start @code{mysqld}: + +@example +bdb: architecture lacks fast mutexes: applications cannot be threaded +Can't init dtabases +@end example + +This means that @code{BDB} tables are not supported for your architecture. +In this case you have to rebuild @strong{MySQL} without BDB table support. + +NOTE: The following list is not complete; We will update this as we get +more information about this. + +Currently we know that BDB tables works with the following operating +system. + +@itemize @bullet +@item +Linux 2.x intel +@item +Solaris sparc +@item +SCO OpenServer +@item +SCO UnixWare 7.0.1 +@end itemize + +It doesn't work with the following operating systems: + +@itemize @bullet +@item +Linux 2.x Alpha +@item +Max OS X +@end itemize + + +@node BDB errors, , BDB portability, BDB +@subsection Errors You May Get When Using BDB Tables + +@itemize @bullet +@item +If you get the following error in the @code{hostname.err log} when +starting @code{mysqld}: + +@example +bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version # +@end example +it means that the new @code{BDB} version doesn't support the old log +file format. In this case you have to delete all @code{BDB} log BDB +from your database directory (the files that has the format +@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also +recommend you to do a @code{mysqldump --opt} of your old @code{BDB} +tables, delete the old table and restore the dump. +@item +If you are running in not @code{auto_commit} mode and delete a table you +are using by another thread you may get the following error messages in +the @strong{MySQL} error file: + +@example +001119 23:43:56 bdb: Missing log fileid entry +001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid +@end example + +This is not fatal but we don't recommend that you delete tables if you are +not in @code{auto_commit} mode, until this problem is fixed (the fix is +not trivial). +@end itemize + + +@node InnoDB, , BDB, Table types @section InnoDB Tables @menu @@ -35026,6 +35904,7 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) * InnoDB contact information:: InnoDB contact information. @end menu + @node InnoDB overview, InnoDB start, InnoDB, InnoDB @subsection InnoDB tables overview @@ -35072,6 +35951,7 @@ may consist of several files. This is different from, for example, InnoDB is distributed under the GNU GPL License Version 2 (of June 1991). In the source distribution of @strong{MySQL}, InnoDB appears as a subdirectory. + @node InnoDB start, InnoDB init, InnoDB overview, InnoDB @subsection InnoDB startup options @@ -35225,6 +36105,7 @@ performance it is wisest not to specify this parameter at all, in which case it will get the default value. @end multitable + @node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB @subsection Creating InnoDB table space @@ -35290,6 +36171,7 @@ mysqld: ready for connections * Error creating InnoDB:: @end menu + @node Error creating InnoDB, , InnoDB init, InnoDB init @subsubsection If something goes wrong in database creation @@ -35300,6 +36182,7 @@ create some InnoDB tables, delete also the corresponding @file{.frm} files for these tables from the @strong{MySQL} database directories. Then you can try the InnoDB database creation again. + @node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB @subsection Creating InnoDB tables @@ -35383,6 +36266,7 @@ it is better that you kill the database process and delete all InnoDB data and log files and all InnoDB table @file{.frm} files, and start your job again, rather than wait for millions of disk i/os to complete. + @node Adding and removing, Backing up, Using InnoDB tables, InnoDB @subsection Adding and removing InnoDB data and log files @@ -35405,6 +36289,7 @@ database. Delete then the old log files from the log file directory, edit @file{my.cnf}, and start @strong{MySQL} again. InnoDB will tell you at the startup that it is creating new log files. + @node Backing up, Moving, Adding and removing, InnoDB @subsection Backing up and recovering an InnoDB database @@ -35491,6 +36376,7 @@ MySQL manual. * InnoDB checkpoints:: @end menu + @node InnoDB checkpoints, , Backing up, Backing up @subsubsection Checkpoints @@ -35522,6 +36408,7 @@ the total size of the log files as big as the buffer pool or even bigger. The drawback in big log files is that crash recovery can last longer because there will be more log to apply to the database. + @node Moving, InnoDB transaction model, Backing up, InnoDB @subsection Moving an InnoDB database to another machine @@ -35542,6 +36429,7 @@ the big rollback segment the big import transaction will generate. Do the commit only after importing a whole table or a segment of a table. + @node InnoDB transaction model, Implementation, Moving, InnoDB @subsection InnoDB transaction model @@ -35576,6 +36464,7 @@ transaction. * InnoDB Deadlock detection:: @end menu + @node InnoDB consistent read, InnoDB locking reads, InnoDB transaction model, InnoDB transaction model @subsubsection Consistent read @@ -35601,6 +36490,7 @@ on the tables it accesses, and therefore other users are free to modify those tables at the same time a consistent read is being performed on the table. + @node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model @subsubsection Locking reads @@ -35658,6 +36548,7 @@ available data setting exclusive locks on each row it reads. Thus it sets the same locks a searched SQL @code{UPDATE} would set on the rows. + @node InnoDB Next-key locking, InnoDB Locks set, InnoDB locking reads, InnoDB transaction model @subsubsection Next-key locking: avoiding the phantom problem @@ -35712,6 +36603,7 @@ anyone meanwhile inserting a duplicate for your row. Thus the next-key locking allows you to 'lock' the non-existence of something in your table. + @node InnoDB Locks set, InnoDB Deadlock detection, InnoDB Next-key locking, InnoDB transaction model @subsubsection Locks set by different SQL statements in InnoDB @@ -35764,6 +36656,7 @@ get a table lock on a table where another user currently has row level locks. But that does not put transaction integerity into danger. @end itemize + @node InnoDB Deadlock detection, , InnoDB Locks set, InnoDB transaction model @subsubsection Deadlock detection and rollback @@ -35880,6 +36773,7 @@ INSERT INTO yourtable VALUES (1, 2), (5, 5); This tip is of course valid for inserts into any table type, not just InnoDB. + @node Implementation, Table and index, InnoDB transaction model, InnoDB @subsection Implementation of multiversioning @@ -35929,6 +36823,7 @@ its index records from the database. This removal operation is called a purge, and it is quite fast, usually taking the same order of time as the SQL statement which did the deletion. + @node Table and index, File space management, Implementation, InnoDB @subsection Table and index structures @@ -35964,6 +36859,7 @@ will use more space. * InnoDB Physical record:: @end menu + @node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index @subsubsection Physical structure of an index @@ -35979,6 +36875,7 @@ If records are inserted in a random order, then the pages will be 1/2 - 15/16 full. If the fillfactor of an index page drops below 1/2, InnoDB will try to contract the index tree to free the page. + @node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index @subsubsection Insert buffering @@ -36006,6 +36903,7 @@ same page in of the index tree, and hence save disk i/o's. It has been measured that the insert buffer can speed up insertions to a table up to 15 times. + @node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index @subsubsection Adaptive hash indexes @@ -36029,6 +36927,7 @@ In a sense, through the adaptive hash index mechanism InnoDB adapts itself to ample main memory, coming closer to the architecture of main memory databases. + @node InnoDB Physical record, , InnoDB Adaptive hash, Table and index @subsubsection Physical record structure @@ -36086,6 +36985,7 @@ The behavior of auto-increment is not defined if a user gives a negative value to the column or if the value becomes bigger than the maximum integer that can be stored in the specified integer type. + @node File space management, Error handling, Table and index, InnoDB @subsection File space management and disk i/o @@ -36095,6 +36995,7 @@ integer that can be stored in the specified integer type. * InnoDB File Defragmenting:: @end menu + @node InnoDB Disk i/o, InnoDB File space, File space management, File space management @subsubsection Disk i/o @@ -36126,6 +37027,7 @@ in a tablespace seems to be in the process of being fully read into the buffer pool. Then InnoDB posts the remaining reads to the i/o system. + @node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk i/o, File space management @subsubsection File space management @@ -36173,6 +37075,7 @@ but remember that deleted rows can be physically removed only in a purge operation after they are no longer needed in transaction rollback or consistent read. + @node InnoDB File Defragmenting, , InnoDB File space, File space management @subsubsection Defragmenting a table @@ -36196,6 +37099,7 @@ records are deleted only from the end, then the the file space management algorithm of InnoDB guarantees that fragmentation in the index will not occur. + @node Error handling, InnoDB restrictions, File space management, InnoDB @subsection Error handling @@ -36228,6 +37132,7 @@ Other errors are mostly detected by the @strong{MySQL} layer of code, and they roll back the corresponding SQL statement. @end itemize + @node InnoDB restrictions, InnoDB contact information, Error handling, InnoDB @subsection Some restrictions on InnoDB tables @@ -36288,6 +37193,7 @@ The maximum tablespace size is 4 billion database pages. This is also the maximum size for a table. The minimum tablespace size is 10 MB. @end itemize + @node InnoDB contact information, , InnoDB restrictions, InnoDB @subsection InnoDB contact information @@ -36305,3700 +37211,10 @@ P.O.Box 800 Finland @end example -@cindex tables, @code{BDB} -@cindex tables, @code{Berkeley DB} -@node BDB, , InnoDB, Table types -@section BDB or Berkeley_DB Tables -@menu -* BDB overview:: Overview of BDB Tables -* BDB install:: Installing BDB -* BDB start:: BDB startup options -* BDB characteristic:: Some characteristic of @code{BDB} tables: -* BDB TODO:: Some things we need to fix for BDB in the near future: -* BDB portability:: Operating systems supported by @strong{BDB} -* BDB errors:: Errors You May Get When Using BDB Tables -@end menu -@node BDB overview, BDB install, BDB, BDB -@subsection Overview of BDB Tables -Support for BDB tables is included in the @strong{MySQL} source distribution -starting from Version 3.23.34 and is activated in the @strong{MySQL}-Max -binary. - -BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided -@strong{MySQL} with a transactional table handler. By using BerkeleyDB -tables, your tables may have a greater chance of surviving crashes, and also -provides @code{COMMIT} and @code{ROLLBACK} on transactions. The -@strong{MySQL} source distribution comes with a BDB distribution that has a -couple of small patches to make it work more smoothly with @strong{MySQL}. -You can't use a non-patched @code{BDB} version with @strong{MySQL}. - -We at @strong{MySQL AB} are working in close cooperation with Sleepycat to -keep the quality of the @strong{MySQL}/BDB interface high. - -When it comes to supporting BDB tables, we are committed to help our -users to locate the problem and help creating a reproducable test case -for any problems involving BDB tables. Any such test case will be -forwarded to Sleepycat who in turn will help us find and fix the -problem. As this is a two stage operation, any problems with BDB tables -may take a little longer for us to fix than for other table handlers. -However, as the BerkeleyDB code itself has been used by many other -applications than @strong{MySQL}, we don't envision any big problems with -this. @xref{Table handler support}. - -@node BDB install, BDB start, BDB overview, BDB -@subsection Installing BDB - -If you have downloaded a binary version of @strong{MySQL} that includes -support for BerkeleyDB, simply follow the instructions for installing a -binary version of @strong{MySQL}. -@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}. - -To compile @strong{MySQL} with Berkeley DB support, download @strong{MySQL} -Version 3.23.34 or newer and configure @code{MySQL} with the -@code{--with-berkeley-db} option. @xref{Installing source}. - -@example -cd /path/to/source/of/mysql-3.23.34 -./configure --with-berkeley-db -@end example - -Please refer to the manual provided with the @code{BDB} distribution for -more updated information. - -Even though Berkeley DB is in itself very tested and reliable, -the @strong{MySQL} interface is still considered beta quality. -We are actively improving and optimizing it to get it stable very -soon. - -@node BDB start, BDB characteristic, BDB install, BDB -@subsection BDB startup options - -If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB} -tables will not be updated until you execute @code{COMMIT}. Instead of commit -you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}. - -If you are running with @code{AUTOCOMMIT=1} (the default), your changes -will be committed immediately. You can start an extended transaction with -the @code{BEGIN WORK} SQL command, after which your changes will not be -committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK} -the changes). - -The following options to @code{mysqld} can be used to change the behavior of -BDB tables: - -@multitable @columnfractions .30 .70 -@item @strong{Option} @tab @strong{Meaning} -@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir. -@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST). -@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory. -@item @code{--bdb-no-sync} @tab Don't synchronously flush logs. -@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode. -@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initializing Berkeley DB) -@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name. -@item @code{--skip-bdb} @tab Don't use berkeley db. -@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}. -@end multitable - -If you use @code{--skip-bdb}, @strong{MySQL} will not initialize the -Berkeley DB library and this will save a lot of memory. Of course, -you cannot use @code{BDB} tables if you are using this option. - -Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you -intend to use BDB tables. This may, however, give you problems when you -try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting -server}. - -With @code{bdb_max_lock} you can specify the maximum number of locks -(10000 by default) you can have active on a BDB table. You should -increase this if you get errors of type @code{bdb: Lock table is out of -available locks} or @code{Got error 12 from ...} when you have do long -transactions or when @code{mysqld} has to examine a lot of rows to -calculate the query. - -You may also want to change @code{binlog_cache_size} and -@code{max_binlog_cache_size} if you are using big multi-line transactions. -@xref{COMMIT}. - -@node BDB characteristic, BDB TODO, BDB start, BDB -@subsection Some characteristic of @code{BDB} tables: - -@itemize @bullet -@item -To be able to rollback transactions BDB maintain log files. For maximum -performance you should place these on another disk than your databases -by using the @code{--bdb_log_dir} options. -@item -@strong{MySQL} performs a checkpoint each time a new BDB log -file is started, and removes any log files that are not needed for -current transactions. One can also run @code{FLUSH LOGS} at any time -to checkpoint the Berkeley DB tables. - -For disaster recovery, one should use table backups plus -@strong{MySQL}'s binary log. @xref{Backup}. - -@strong{Warning}: If you delete old log files that are in use, BDB will -not be able to do recovery at all and you may lose data if something -goes wrong. -@item -@strong{MySQL} requires a @code{PRIMARY KEY} in each BDB table to be -able to refer to previously read rows. If you don't create one, -@strong{MySQL} will create an maintain a hidden @code{PRIMARY KEY} for -you. The hidden key has a length of 5 bytes and is incremented for each -insert attempt. -@item -If all columns you access in a @code{BDB} table are part of the same index or -part of the primary key, then @strong{MySQL} can execute the query -without having to access the actual row. In a @code{MyISAM} table the -above holds only if the columns are part of the same index. -@item -The @code{PRIMARY KEY} will be faster than any other key, as the -@code{PRIMARY KEY} is stored together with the row data. As the other keys are -stored as the key data + the @code{PRIMARY KEY}, it's important to keep the -@code{PRIMARY KEY} as short as possible to save disk and get better speed. -@item -@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If -you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal -multiple-write lock on the table to ensure that the table will be -properly locked if another thread issues a table lock. -@item -Internal locking in @code{BDB} tables is done on page level. -@item -@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't -maintain a count of the number of rows in the table. -@item -Scanning is slower than with @code{MyISAM} tables as one has data in BDB -tables stored in B-trees and not in a separate data file. -@item -The application must always be prepared to handle cases where -any change of a @code{BDB} table may make an automatic rollback and any -read may fail with a deadlock error. -@item -Keys are not compressed to previous keys as with ISAM or MyISAM -tables. In other words, the key information will take a little more -space in @code{BDB} tables compared to MyISAM tables which don't use -@code{PACK_KEYS=0}. -@item -There is often holes in the BDB table to allow you to insert new rows in -the middle of the key tree. This makes BDB tables somewhat larger than -MyISAM tables. -@item -The optimizer needs to know an approximation of the number of rows in -the table. @strong{MySQL} solves this by counting inserts and -maintaining this in a separate segment in each BDB table. If you don't -do a lot of @code{DELETE} or @code{ROLLBACK}:s this number should be -accurate enough for the @strong{MySQL} optimizer, but as @strong{MySQL} -only store the number on close, it may be wrong if @strong{MySQL} dies -unexpectedly. It should not be fatal even if this number is not 100 % -correct. One can update the number of rows by executing @code{ANALYZE -TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE -TABLE}. -@item -If you get full disk with a @code{BDB} table, you will get an error -(probably error 28) and the transaction should roll back. This is in -contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will -wait for enough free disk before continuing. -@end itemize - -@node BDB TODO, BDB portability, BDB characteristic, BDB -@subsection Some things we need to fix for BDB in the near future: - -@itemize @bullet -@item -It's very slow to open many BDB tables at the same time. If you are -going to use BDB tables, you should not have a very big table cache (> -256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql} -client. We plan to partly fix this in 4.0. -@item -@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB -tables. -@item -Optimize performance. -@item -Change to not use page locks at all when we are scanning tables. -@end itemize - -@node BDB portability, BDB errors, BDB TODO, BDB -@subsection Operating systems supported by @strong{BDB} - -If you after having built @strong{MySQL} with support for BDB tables get -the following error in the log file when you start @code{mysqld}: - -@example -bdb: architecture lacks fast mutexes: applications cannot be threaded -Can't init dtabases -@end example - -This means that @code{BDB} tables are not supported for your architecture. -In this case you have to rebuild @strong{MySQL} without BDB table support. - -NOTE: The following list is not complete; We will update this as we get -more information about this. - -Currently we know that BDB tables works with the following operating -system. - -@itemize @bullet -@item -Linux 2.x intel -@item -Solaris sparc -@item -SCO OpenServer -@item -SCO UnixWare 7.0.1 -@end itemize - -It doesn't work with the following operating systems: - -@itemize @bullet -@item -Linux 2.x Alpha -@item -Max OS X -@end itemize - -@node BDB errors, , BDB portability, BDB -@subsection Errors You May Get When Using BDB Tables - -@itemize @bullet -@item -If you get the following error in the @code{hostname.err log} when -starting @code{mysqld}: - -@example -bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version # -@end example -it means that the new @code{BDB} version doesn't support the old log -file format. In this case you have to delete all @code{BDB} log BDB -from your database directory (the files that has the format -@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also -recommend you to do a @code{mysqldump --opt} of your old @code{BDB} -tables, delete the old table and restore the dump. -@item -If you are running in not @code{auto_commit} mode and delete a table you -are using by another thread you may get the following error messages in -the @strong{MySQL} error file: - -@example -001119 23:43:56 bdb: Missing log fileid entry -001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid -@end example - -This is not fatal but we don't recommend that you delete tables if you are -not in @code{auto_commit} mode, until this problem is fixed (the fix is -not trivial). -@end itemize - - -@node Fulltext Search, Maintenance, Table types, Top -@chapter MySQL Full-text Search - -@cindex searching, full-text -@cindex full-text search -@cindex FULLTEXT - -Since Version 3.23.23, @strong{MySQL} has support for full-text indexing -and searching. Full-text indexes in @strong{MySQL} are an index of type -@code{FULLTEXT}. @code{FULLTEXT} indexes can be created from @code{VARCHAR} -and @code{TEXT} columns at @code{CREATE TABLE} time or added later with -@code{ALTER TABLE} or @code{CREATE INDEX}. For large datasets, adding -@code{FULLTEXT} index with @code{ALTER TABLE} (or @code{CREATE INDEX}) would -be much faster than inserting rows into the empty table with a @code{FULLTEXT} -index. - -Full-text search is performed with the @code{MATCH} function. - -@example -mysql> CREATE TABLE articles ( - -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - -> title VARCHAR(200), - -> body TEXT, - -> FULLTEXT (title,body) - -> ); -Query OK, 0 rows affected (0.00 sec) - -mysql> INSERT INTO articles VALUES - -> (0,'MySQL Tutorial', 'DBMS stands for DataBase Management ...'), - -> (0,'How To Use MySQL Efficiently', 'After you went through a ...'), - -> (0,'Optimizing MySQL','In this tutorial we will show how to ...'), - -> (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. Normalize ...'), - -> (0,'MySQL vs. YourSQL', 'In the following database comparison we ...'), - -> (0,'MySQL Security', 'When configured properly, MySQL could be ...'); -Query OK, 5 rows affected (0.00 sec) -Records: 5 Duplicates: 0 Warnings: 0 - -mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database'); -+----+-------------------+---------------------------------------------+ -| id | title | body | -+----+-------------------+---------------------------------------------+ -| 5 | MySQL vs. YourSQL | In the following database comparison we ... | -| 1 | MySQL Tutorial | DBMS stands for DataBase Management ... | -+----+-------------------+---------------------------------------------+ -2 rows in set (0.00 sec) -@end example - -The function @code{MATCH} matches a natural language query @code{AGAINST} -a text collection (which is simply the set of columns covered by a -@code{FULLTEXT} index). For every row in a table it returns relevance - -a similarity measure between the text in that row (in the columns that are -part of the collection) and the query. When it is used in a @code{WHERE} -clause (see example above) the rows returned are automatically sorted with -relevance decreasing. Relevance is a non-negative floating-point number. -Zero relevance means no similarity. Relevance is computed based on the -number of words in the row, the number of unique words in that row, the -total number of words in the collection, and the number of documents (rows) -that contain a particular word. - -The above is a basic example of using @code{MATCH} function. Rows are -returned with relevance decreasing. - -@example -mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles; -+----+-----------------------------------------+ -| id | MATCH (title,body) AGAINST ('Tutorial') | -+----+-----------------------------------------+ -| 1 | 0.64840710366884 | -| 2 | 0 | -| 3 | 0.66266459031789 | -| 4 | 0 | -| 5 | 0 | -| 6 | 0 | -+----+-----------------------------------------+ -5 rows in set (0.00 sec) -@end example - -This example shows how to retrieve the relevances. As neither @code{WHERE} -nor @code{ORDER BY} clauses are present, returned rows are not ordered. - -@example -mysql> SELECT id, body, MATCH (title,body) AGAINST ( - -> 'Security implications of running MySQL as root') AS score - -> FROM articles WHERE MATCH (title,body) AGAINST - -> ('Security implications of running MySQL as root'); -+----+-----------------------------------------------+-----------------+ -| id | body | score | -+----+-----------------------------------------------+-----------------+ -| 4 | 1. Never run mysqld as root. 2. Normalize ... | 1.5055546709332 | -| 6 | When configured properly, MySQL could be ... | 1.31140957288 | -+----+-----------------------------------------------+-----------------+ -2 rows in set (0.00 sec) -@end example - -This is more complex example - the query returns the relevance and still -sorts the rows with relevance decreasing. To achieve it one should specify -@code{MATCH} twice. Note, that this will cause no additional overhead, as -@strong{MySQL} optimizer will notice that these two @code{MATCH} calls are -identical and will call full-text search code only once. - -@strong{MySQL} uses a very simple parser to split text into words. A -``word'' is any sequence of letters, numbers, @samp{'}, and @samp{_}. Any -``word'' that is present in the stopword list or just too short (3 -characters or less) is ignored. - -Every correct word in the collection and in the query is weighted, -according to its significance in the query or collection. This way, a -word that is present in many documents will have lower weight (and may -even have a zero weight), because it has lower semantic value in this -particular collection. Otherwise, if the word is rare, it will receive a -higher weight. The weights of the words are then combined to compute the -relevance of the row. - -Such a technique works best with large collections (in fact, it was -carefully tuned this way). For very small tables, word distribution -does not reflect adequately their semantical value, and this model -may sometimes produce bizarre results. - -@example -mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL'); -Empty set (0.00 sec) -@end example - -Search for the word @code{MySQL} produces no results in the above example. -Word @code{MySQL} is present in more than half of rows, and as such, is -effectively treated as a stopword (that is, with semantical value zero). -It is, really, the desired behavior - a natural language query should not -return every second row in 1GB table. - -A word that matches half of rows in a table is less likely to locate relevant -documents. In fact, it will most likely find plenty of irrelevant documents. -We all know this happens far too often when we are trying to find something on -the Internet with a search engine. It is with this reasoning that such rows -have been assigned a low semantical value in @strong{this particular dataset}. - -@menu -* Fulltext restrictions:: -* Fulltext Fine-tuning:: -* Fulltext Features to Appear in MySQL 4.0:: -* Fulltext TODO:: -@end menu - -@node Fulltext restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search -@section Fulltext restrictions -@itemize @bullet -@item -All parameters to the @code{MATCH} function must be columns from the -same table that is part of the same fulltext index. -@item -The argument to @code{AGAINST} must be a constant string. -@end itemize - -@node Fulltext Fine-tuning, Fulltext Features to Appear in MySQL 4.0, Fulltext restrictions, Fulltext Search -@section Fine-tuning MySQL Full-text Search - -Unfortunately, full-text search has no user-tunable parameters yet, -although adding some is very high on the TODO. However, if you have a -@strong{MySQL} source distribution (@xref{Installing source}.), you can -somewhat alter the full-text search behavior. - -Note that full-text search was carefully tuned for the best searching -effectiveness. Modifying the default behavior will, in most cases, -only make the search results worse. Do not alter the @strong{MySQL} sources -unless you know what you are doing! - -@itemize - -@item -Minimal length of word to be indexed is defined in -@code{myisam/ftdefs.h} file by the line -@example -#define MIN_WORD_LEN 4 -@end example -Change it to the value you prefer, recompile @strong{MySQL}, and rebuild -your @code{FULLTEXT} indexes. - -@item -The stopword list is defined in @code{myisam/ft_static.c} -Modify it to your taste, recompile @strong{MySQL} and rebuild -your @code{FULLTEXT} indexes. - -@item -The 50% threshold is caused by the particular weighting scheme chosen. To -disable it, change the following line in @code{myisam/ftdefs.h}: -@example -#define GWS_IN_USE GWS_PROB -@end example -to -@example -#define GWS_IN_USE GWS_FREQ -@end example -and recompile @strong{MySQL}. -There is no need to rebuild the indexes in this case. - -@end itemize - -@node Fulltext Features to Appear in MySQL 4.0, Fulltext TODO, Fulltext Fine-tuning, Fulltext Search -@section New Features of Full-text Search to Appear in MySQL 4.0 - -This section includes a list of the fulltext features that are already -implemented in the 4.0 tree. It explains -@strong{More functions for full-text search} entry of @ref{TODO MySQL 4.0}. - -@itemize @bullet -@item @code{REPAIR TABLE} with @code{FULLTEXT} indexes, -@code{ALTER TABLE} with @code{FULLTEXT} indexes, and -@code{OPTIMIZE TABLE} with @code{FULLTEXT} indexes are now -up to 100 times faster. - -@item @code{MATCH ... AGAINST} is going to supports the following -@strong{boolean operators}: - -@itemize @bullet -@item @code{+}word means the that word @strong{must} be present in every -row returned. -@item @code{-}word means the that word @strong{must not} be present in every -row returned. -@item @code{<} and @code{>} can be used to decrease and increase word -weight in the query. -@item @code{~} can be used to assign a @strong{negative} weight to a noise -word. -@item @code{*} is a truncation operator. -@end itemize - -Boolean search utilizes a more simplistic way of calculating the relevance, -that does not have a 50% threshold. - -@item Searches are now up to 2 times faster due to optimized search algorithm. - -@item Utility program @code{ft_dump} added for low-level @code{FULLTEXT} -index operations (querying/dumping/statistics). - -@end itemize - -@node Fulltext TODO, , Fulltext Features to Appear in MySQL 4.0, Fulltext Search -@section Full-text Search TODO - -@itemize @bullet -@item Make all operations with @code{FULLTEXT} index @strong{faster}. -@item Support for braces @code{()} in boolean full-text search. -@item Phrase search, proximity operators -@item Boolean search can work without @code{FULLTEXT} index -(yes, @strong{very} slow). -@item Support for "always-index words". They could be any strings -the user wants to treat as words, examples are "C++", "AS/400", "TCP/IP", etc. -@item Support for full-text search in @code{MERGE} tables. -@item Support for multi-byte charsets. -@item Make stopword list to depend of the language of the data. -@item Stemming (dependent of the language of the data, of course). -@item Generic user-supplyable UDF (?) preparser. -@item Make the model more flexible (by adding some adjustable -parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}). -@end itemize - - -@node Maintenance, Adding functions, Fulltext Search, Top -@chapter Maintaining a MySQL Installation - -@cindex installation maintenance -@cindex maintaining, tables -@cindex tables, maintaining -@cindex databases, maintaining -@cindex @code{myisamchk} -@cindex @code{mysqlcheck} -@cindex crash, recovery -@cindex recovery, from crash - - -@menu -* Using mysqlcheck:: Using mysqlcheck for maintenance and recovery -@end menu - -This chapter covers what you should know about maintaining a @strong{MySQL} -distribution. You will learn how to care for your tables on a regular -basis, and what to do when disaster strikes. - -@node Using mysqlcheck, , Maintenance, Maintenance -@section Using @code{mysqlcheck} for Table Maintenance and Crash Recovery - -Since @strong{MySQL} version 3.23.38 you will be able to use a new -checking and repairing tool for @code{MyISAM} tables. The difference to -@code{myisamchk} is that @code{mysqlcheck} should be used when the -@code{mysqld} server is running, where as @code{myisamchk} should be used -when it is not. The benefit is that you no longer have to take the -server down for checking or repairing your tables. - -@code{mysqlcheck} uses @strong{MySQL} server commands @code{CHECK}, -@code{REPAIR}, @code{ANALYZE} and @code{OPTIMIZE} in a convenient way -for the user. - -There are three alternative ways to invoke @code{mysqlcheck}: - -@example -shell> mysqlcheck [OPTIONS] database [tables] -shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...] -shell> mysqlcheck [OPTIONS] --all-databases -@end example - -So it can be used in a similar way as @code{mysqldump} when it -comes to what databases and tables you want to choose. - -@code{mysqlcheck} does have a special feature compared to the other -clients; the default behavior, checking tables (-c), can be changed by -renaming the binary. So if you want to have a tool that repairs tables -by default, you should just copy @code{mysqlcheck} to your harddrive -with a new name, @code{mysqlrepair}, or alternatively make a symbolic -link to @code{mysqlrepair} and name the symbolic link as -@code{mysqlrepair}. If you invoke @code{mysqlrepair} now, it will repair -tables by default. - -The names that you can use to change @code{mysqlcheck} default behavior -are here: - -@example -mysqlrepair: The default option will be -r -mysqlanalyze: The default option will be -a -mysqloptimize: The default option will be -o -@end example - -The options available for @code{mysqlcheck} are listed here, please -check what your version supports with @code{mysqlcheck --help}. - -@table @code -@item -A, --all-databases -Check all the databases. This will be same as --databases with all -databases selected -@item -1, --all-in-1 -Instead of making one query for each table, execute all queries in 1 -query separately for each database. Table names will be in a comma -separated list. -@item -a, --analyze -Analyze given tables. -@item --auto-repair -If a checked table is corrupted, automatically fix it. Repairing will be -done after all tables have been checked, if corrupted ones were found. -@item -#, --debug=... -Output debug log. Often this is 'd:t:o,filename' -@item --character-sets-dir=... -Directory where character sets are -@item -c, --check -Check table for errors -@item -C, --check-only-changed -Check only tables that have changed since last check or haven't been -closed properly. -@item --compress -Use compression in server/client protocol. -@item -?, --help -Display this help message and exit. -@item -B, --databases -To check several databases. Note the difference in usage; In this case -no tables are given. All name arguments are regarded as database names. -@item --default-character-set=... -Set the default character set -@item -F, --fast -Check only tables that hasn't been closed properly -@item -f, --force -Continue even if we get an sql-error. -@item -e, --extended -If you are using this option with CHECK TABLE, it will ensure that the -table is 100 percent consistent, but will take a long time. - -If you are using this option with REPAIR TABLE, it will run an extended -repair on the table, which may not only take a long time to execute, but -may produce a lot of garbage rows also! -@item -h, --host=... -Connect to host. -@item -m, --medium-check -Faster than extended-check, but only finds 99.99 percent of all -errors. Should be good enough for most cases. -@item -o, --optimize -Optimize table -@item -p, --password[=...] -Password to use when connecting to server. If password is not given -it's solicited on the tty. -@item -P, --port=... -Port number to use for connection. -@item -q, --quick -If you are using this option with CHECK TABLE, it prevents the check -from scanning the rows to check for wrong links. This is the fastest -check. - -If you are using this option with REPAIR TABLE, it will try to repair -only the index tree. This is the fastest repair method for a table. -@item -r, --repair -Can fix almost anything except unique keys that aren't unique. -@item -s, --silent -Print only error messages. -@item -S, --socket=... -Socket file to use for connection. -@item --tables -Overrides option --databases (-B). -@item -u, --user=# -User for login if not current user. -@item -v, --verbose -Print info about the various stages. -@item -V, --version -Output version information and exit. -@end table - - - -@cindex functions, new -@cindex adding, new functions -@cindex user-defined functions, adding -@cindex UDFs, defined -@cindex functions, user-defined -@node Adding functions, Adding procedures, Maintenance, Top -@chapter Adding New Functions to MySQL - -There are two ways to add new functions to @strong{MySQL}: - -@itemize @bullet -@item You can add the function through the user-definable function (UDF) -interface. User-definable functions are added and removed dynamically using -the @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements. -@xref{CREATE FUNCTION, , @code{CREATE FUNCTION}}. - -@item You can add the function as a native (built in) @strong{MySQL} function. -Native functions are compiled into the @code{mysqld} server and become -available on a permanent basis. -@end itemize - -Each method has advantages and disadvantages: - -@itemize @bullet -@item -If you write a user-definable function, you must install the object file -in addition to the server itself. If you compile your function into the -server, you don't need to do that. -@item -You can add UDFs to a binary @strong{MySQL} distribution. Native functions -require you to modify a source distribution. -@item -If you upgrade your @strong{MySQL} distribution, you can continue to use your -previously installed UDFs. For native functions, you must repeat your -modifications each time you upgrade. -@end itemize - -Whichever method you use to add new functions, they may be used just like -native functions such as @code{ABS()} or @code{SOUNDEX()}. - -@menu -* Adding UDF:: Adding a new user-definable function -* Adding native function:: Adding a new native function -@end menu - -@cindex adding, user-definable functions -@cindex user-defined functions, adding -@cindex functions, user-definable, adding -@node Adding UDF, Adding native function, Adding functions, Adding functions -@section Adding a New User-definable Function - -@menu -* UDF calling sequences:: UDF calling sequences -* UDF arguments:: Argument processing -* UDF return values:: Return values and error handling -* UDF compiling:: Compiling and installing user-definable functions -@end menu - -For the UDF mechanism to work, functions must be written in C or C++ and your -operating system must support dynamic loading. The @strong{MySQL} source -distribution includes a file @file{sql/udf_example.cc} that defines 5 new -functions. Consult this file to see how UDF calling conventions work. - -For @code{mysqld} to be able to use UDF functions, you should configure MySQL -with @code{--with-mysqld-ldflags=-rdynamic} The reason is that to on -many platforms (including Linux) you can load a dynamic library (with -@code{dlopen()}) from a static linked program, which you would get if -you are using @code{--with-mysqld-ldflags=-all-static} If you want to -use an UDF that needs to access symbols from @code{mysqld} (like the -@code{methaphone} example in @file{sql/udf_example.cc} that uses -@code{default_charset_info}), you must link the program with -@code{-rdynamic}. (see @code{man dlopen}). - -For each function that you want to use in SQL statements, you should define -corresponding C (or C++) functions. In the discussion below, the name -``xxx'' is used for an example function name. To distinquish between SQL and -C/C++ usage, @code{XXX()} (uppercase) indicates a SQL function call, and -@code{xxx()} (lowercase) indicates a C/C++ function call. - -The C/C++ functions that you write to implement the interface for -@code{XXX()} are: - -@table @asis -@item @code{xxx()} (required) -The main function. This is where the function result is computed. -The correspondence between the SQL type and return type of your C/C++ -function is shown below: - -@multitable @columnfractions .2 .8 -@item @strong{SQL type} @tab @strong{C/C++ type} -@item @code{STRING} @tab @code{char *} -@item @code{INTEGER} @tab @code{long long} -@item @code{REAL} @tab @code{double} -@end multitable - -@item @code{xxx_init()} (optional) -The initialization function for @code{xxx()}. It can be used to: - -@itemize @bullet -@item -Check the number of arguments to @code{XXX()}. -@item -Check that the arguments are of a required type or, alternatively, -tell @strong{MySQL} to coerce arguments to the types you want when -the main function is called. -@item -Allocate any memory required by the main function. -@item -Specify the maximum length of the result. -@item -Specify (for @code{REAL} functions) the maximum number of decimals. -@item -Specify whether or not the result can be @code{NULL}. -@end itemize - -@item @code{xxx_deinit()} (optional) -The deinitialization function for @code{xxx()}. It should deallocate any -memory allocated by the initialization function. -@end table - -When a SQL statement invokes @code{XXX()}, @strong{MySQL} calls the -initialization function @code{xxx_init()} to let it perform any required -setup, such as argument checking or memory allocation. If @code{xxx_init()} -returns an error, the SQL statement is aborted with an error message and the -main and deinitialization functions are not called. Otherwise, the main -function @code{xxx()} is called once for each row. After all rows have been -processed, the deinitialization function @code{xxx_deinit()} is called so it -can perform any required cleanup. - -All functions must be thread safe (not just the main function, -but the initialization and deinitialization functions as well). This means -that you are not allowed to allocate any global or static variables that -change! If you need memory, you should allocate it in @code{xxx_init()} -and free it in @code{xxx_deinit()}. - -@cindex calling sequences, UDF -@node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF -@subsection UDF Calling Sequences - -The main function should be declared as shown below. Note that the return -type and parameters differ, depending on whether you will declare the SQL -function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL} -in the @code{CREATE FUNCTION} statement: - -@noindent -For @code{STRING} functions: - -@example -char *xxx(UDF_INIT *initid, UDF_ARGS *args, - char *result, unsigned long *length, - char *is_null, char *error); -@end example - -@noindent -For @code{INTEGER} functions: - -@example -long long xxx(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error); -@end example - -@noindent -For @code{REAL} functions: - -@example -double xxx(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error); -@end example - -The initialization and deinitialization functions are declared like this: - -@example -my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); - -void xxx_deinit(UDF_INIT *initid); -@end example - -The @code{initid} parameter is passed to all three functions. It points to a -@code{UDF_INIT} structure that is used to communicate information between -functions. The @code{UDF_INIT} structure members are listed below. The -initialization function should fill in any members that it wishes to change. -(To use the default for a member, leave it unchanged.): - -@table @code -@item my_bool maybe_null -@code{xxx_init()} should set @code{maybe_null} to @code{1} if @code{xxx()} -can return @code{NULL}. The default value is @code{1} if any of the -arguments are declared @code{maybe_null}. - -@item unsigned int decimals -Number of decimals. The default value is the maximum number of decimals in -the arguments passed to the main function. (For example, if the function is -passed @code{1.34}, @code{1.345}, and @code{1.3}, the default would be 3, -because @code{1.345} has 3 decimals. - -@item unsigned int max_length -The maximum length of the string result. The default value differs depending -on the result type of the function. For string functions, the default is the -length of the longest argument. For integer functions, the default is 21 -digits. For real functions, the default is 13 plus the number of decimals -indicated by @code{initid->decimals}. (For numeric functions, the length -includes any sign or decimal point characters.) - -@item char *ptr -A pointer that the function can use for its own purposes. For example, -functions can use @code{initid->ptr} to communicate allocated memory -between functions. In @code{xxx_init()}, allocate the memory and assign it -to this pointer: - -@example -initid->ptr = allocated_memory; -@end example - -In @code{xxx()} and @code{xxx_deinit()}, refer to @code{initid->ptr} to use -or deallocate the memory. -@end table - -@cindex argument processing -@cindex processing, arguments -@node UDF arguments, UDF return values, UDF calling sequences, Adding UDF -@subsection Argument Processing - -The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the -members listed below: - -@table @code -@item unsigned int arg_count -The number of arguments. Check this value in the initialization function -if you want your function to be called with a particular number of arguments. -For example: - -@example -if (args->arg_count != 2) -@{ - strcpy(message,"XXX() requires two arguments"); - return 1; -@} -@end example - - -@item enum Item_result *arg_type -The types for each argument. The possible type values are -@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}. - -To make sure that arguments are of a given type and return an -error if they are not, check the @code{arg_type} array in the initialization -function. For example: - -@example -if (args->arg_type[0] != STRING_RESULT || - args->arg_type[1] != INT_RESULT) -@{ - strcpy(message,"XXX() requires a string and an integer"); - return 1; -@} -@end example - -As an alternative to requiring your function's arguments to be of particular -types, you can use the initialization function to set the @code{arg_type} -elements to the types you want. This causes @strong{MySQL} to coerce -arguments to those types for each call to @code{xxx()}. For example, to -specify coercion of the first two arguments to string and integer, do this in -@code{xxx_init()}: - -@example -args->arg_type[0] = STRING_RESULT; -args->arg_type[1] = INT_RESULT; -@end example - -@item char **args -@code{args->args} communicates information to the initialization function -about the general nature of the arguments your function was called with. For a -constant argument @code{i}, @code{args->args[i]} points to the argument -value. (See below for instructions on how to access the value properly.) -For a non-constant argument, @code{args->args[i]} is @code{0}. -A constant argument is an expression that uses only constants, such as -@code{3} or @code{4*7-2} or @code{SIN(3.14)}. A non-constant argument is an -expression that refers to values that may change from row to row, such as -column names or functions that are called with non-constant arguments. - -For each invocation of the main function, @code{args->args} contains the -actual arguments that are passed for the row currently being processed. - -Functions can refer to an argument @code{i} as follows: - -@itemize @bullet -@item -An argument of type @code{STRING_RESULT} is given as a string pointer plus a -length, to allow handling of binary data or data of arbitrary length. The -string contents are available as @code{args->args[i]} and the string length -is @code{args->lengths[i]}. You should not assume that strings are -null-terminated. - -@item -For an argument of type @code{INT_RESULT}, you must cast -@code{args->args[i]} to a @code{long long} value: - -@example -long long int_val; -int_val = *((long long*) args->args[i]); -@end example - -@item -For an argument of type @code{REAL_RESULT}, you must cast -@code{args->args[i]} to a @code{double} value: - -@example -double real_val; -real_val = *((double*) args->args[i]); -@end example -@end itemize - -@item unsigned long *lengths -For the initialization function, the @code{lengths} array indicates the -maximum string length for each argument. For each invocation of the main -function, @code{lengths} contains the actual lengths of any string arguments -that are passed for the row currently being processed. For arguments of -types @code{INT_RESULT} or @code{REAL_RESULT}, @code{lengths} still contains -the maximum length of the argument (as for the initialization function). -@end table - -@cindex UDFs, return values -@cindex return values, UDFs -@cindex errors, handling for UDFs -@cindex handling, errors -@node UDF return values, UDF compiling, UDF arguments, Adding UDF -@subsection Return Values and Error Handling - -The initialization function should return @code{0} if no error occurred and -@code{1} otherwise. If an error occurs, @code{xxx_init()} should store a -null-terminated error message in the @code{message} parameter. The message -will be returned to the client. The message buffer is -@code{MYSQL_ERRMSG_SIZE} characters long, but you should try to keep the -message to less than 80 characters so that it fits the width of a standard -terminal screen. - -The return value of the main function @code{xxx()} is the function value, for -@code{long long} and @code{double} functions. A string functions should -return a pointer to the result and store the length of the string in the -@code{length} arguments. @code{result} is a buffer at least 255 bytes long. -Set these to the contents and length of the return value. For example: - -@example -memcpy(result, "result string", 13); -*length = 13; -@end example - -If your string functions that needs to return a string longer than 255 -bytes, you must allocate the space for it with @code{malloc()} in your -@code{xxx_init()} function or your @code{xxx()} function and free it in -your @code{xxx_deinit()} function. You can store the allocated memory -in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by -future @code{xxx()} calls. @xref{UDF calling sequences}. - -To indicate a return value of @code{NULL} in the main function, set -@code{is_null} to @code{1}: - -@example -*is_null = 1; -@end example - -To indicate an error return in the main function, set the @code{error} -parameter to @code{1}: - -@example -*error = 1; -@end example - -If @code{xxx()} sets @code{*error} to @code{1} for any row, the function -value is @code{NULL} for the current row and for any subsequent rows -processed by the statement in which @code{XXX()} was invoked. (@code{xxx()} -will not even be called for subsequent rows.) @strong{NOTE:} In -@strong{MySQL} versions prior to 3.22.10, you should set both @code{*error} -and @code{*is_null}: - -@example -*error = 1; -*is_null = 1; -@end example - -@cindex compiling, user-defined functions -@cindex UDFs, compiling -@cindex installing, user-defined functions -@node UDF compiling, , UDF return values, Adding UDF -@subsection Compiling and Installing User-definable Functions - -Files implementing UDFs must be compiled and installed on the host where the -server runs. This process is described below for the example UDF file -@file{udf_example.cc} that is included in the @strong{MySQL} source -distribution. This file contains the following functions: - -@itemize @bullet -@item -@code{metaphon()} returns a metaphon string of the string argument. -This is something like a soundex string, but it's more tuned for English. -@item -@code{myfunc_double()} returns the sum of the ASCII values of the -characters in its arguments, divided by the sum of the length of its arguments. -@item -@code{myfunc_int()} returns the sum of the length of its arguments. -@item -@code{sequence([const int])} returns an sequence starting from the given -number or 1 if no number has been given. -@item -@code{lookup()} returns the IP number for a hostname. -@item -@code{reverse_lookup()} returns the hostname for an IP number. -The function may be called with a string @code{"xxx.xxx.xxx.xxx"} or -four numbers. -@end itemize - -A dynamically loadable file should be compiled as a sharable object file, -using a command something like this: - -@example -shell> gcc -shared -o udf_example.so myfunc.cc -@end example - -You can easily find out the correct compiler options for your system by -running this command in the @file{sql} directory of your @strong{MySQL} -source tree: - -@example -shell> make udf_example.o -@end example - -You should run a compile command similar to the one that @code{make} displays, -except that you should remove the @code{-c} option near the end of the line -and add @code{-o udf_example.so} to the end of the line. (On some systems, -you may need to leave the @code{-c} on the command.) - -Once you compile a shared object containing UDFs, you must install it -and tell @strong{MySQL} about it. Compiling a shared object from -@file{udf_example.cc} produces a file named something like -@file{udf_example.so} (the exact name may vary from platform to platform). -Copy this file to some directory searched by @code{ld}, such as -@file{/usr/lib}. On many systems, you can set the @code{LD_LIBRARY} or -@code{LD_LIBRARY_PATH} environment variable to point at the directory where -you have your UDF function files. The @code{dlopen} manual page tells you -which variable you should use on your system. You should set this in -@code{mysql.server} or @code{safe_mysqld} and restart @code{mysqld}. - -After the library is installed, notify @code{mysqld} about the new -functions with these commands: - -@example -mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; -mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; -mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; -mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; -mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; -@end example - -Functions can be deleted using @code{DROP FUNCTION}: - -@example -mysql> DROP FUNCTION metaphon; -mysql> DROP FUNCTION myfunc_double; -mysql> DROP FUNCTION myfunc_int; -mysql> DROP FUNCTION lookup; -mysql> DROP FUNCTION reverse_lookup; -@end example - -The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the -system table @code{func} in the @code{mysql} database. The function's name, -type and shared library name are saved in the table. You must have the -@strong{insert} and @strong{delete} privileges for the @code{mysql} database -to create and drop functions. - -You should not use @code{CREATE FUNCTION} to add a function that has already -been created. If you need to reinstall a function, you should remove it with -@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}. You -would need to do this, for example, if you recompile a new version of your -function, so that @code{mysqld} gets the new version. Otherwise the server -will continue to use the old version. - -Active functions are reloaded each time the server starts, unless you start -@code{mysqld} with the @code{--skip-grant-tables} option. In this case, UDF -initialization is skipped and UDFs are unavailable. (An active function is -one that has been loaded with @code{CREATE FUNCTION} and not removed with -@code{DROP FUNCTION}.) - -@cindex adding, native functions -@cindex native functions, adding -@cindex functions, native, adding -@node Adding native function, , Adding UDF, Adding functions -@section Adding a New Native Function - -The procedure for adding a new native function is described below. Note -that you cannot add native functions to a binary distribution because -the procedure involves modifying @strong{MySQL} source code. You must -compile @strong{MySQL} yourself from a source distribution. Also note -that if you migrate to another version of @strong{MySQL} (for example, -when a new version is released), you will need to repeat the procedure -with the new version. - -To add a new native @strong{MySQL} function, follow these steps: - -@enumerate -@item -Add one line to @file{lex.h} that defines the function name in the -@code{sql_functions[]} array. -@item -If the function prototype is simple (just takes zero, one, two or three -arguments), you should in lex.h specify SYM(FUNC_ARG#) (where # is the -number of arguments) as the second argument in the -@code{sql_functions[]} array and add a function that creates a function -object in @file{item_create.cc}. Take a look at @code{"ABS"} and -@code{create_funcs_abs()} for an example of this. - -If the function prototype is complicated (for example takes a variable number -of arguments), you should add two lines to @file{sql_yacc.yy}. One -indicates the preprocessor symbol that @code{yacc} should define (this -should be added at the beginning of the file). Then define the function -parameters and add an ``item'' with these parameters to the -@code{simple_expr} parsing rule. For an example, check all occurrences -of @code{ATAN} in @file{sql_yacc.yy} to see how this is done. -@item -In @file{item_func.h}, declare a class inheriting from @code{Item_num_func} or -@code{Item_str_func}, depending on whether your function returns a number or a -string. -@item -In @file{item_func.cc}, add one of the following declarations, depending -on whether you are defining a numeric or string function: -@example -double Item_func_newname::val() -longlong Item_func_newname::val_int() -String *Item_func_newname::Str(String *str) -@end example - -If you inherit your object from any of the standard items (like -@code{Item_num_func} you probably only have to define one of the above -functions and let the parent object take care of the other functions. -For example, the @code{Item_str_func} class defines a @code{val()} function -that executes @code{atof()} on the value returned by @code{::str()}. - -@item -You should probably also define the following object function: -@example -void Item_func_newname::fix_length_and_dec() -@end example -This function should at least calculate @code{max_length} based on the -given arguments. @code{max_length} is the maximum number of characters -the function may return. This function should also set @code{maybe_null -= 0} if the main function can't return a @code{NULL} value. The -function can check if any of the function arguments can return -@code{NULL} by checking the arguments @code{maybe_null} variable. You -can take a look at @code{Item_func_mod::fix_length_and_dec} for a -typical example of how to do this. -@end enumerate - -All functions must be thread safe (In other words, don't use any global or -static variables in the functions without protecting them with mutexes). - -If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()} -or @code{::str()} you should set @code{null_value} to 1 and return 0. - -For @code{::str()} object functions, there are some additional -considerations to be aware of: - -@itemize @bullet -@item -The @code{String *str} argument provides a string buffer that may be -used to hold the result. (For more information about the @code{String} type, -take a look at the @file{sql_string.h} file.) -@item -The @code{::str()} function should return the string that holds the result or -@code{(char*) 0} if the result is @code{NULL}. -@item -All current string functions try to avoid allocating any memory unless -absolutely necessary! -@end itemize - -@cindex procedures, adding -@cindex adding, procedures -@cindex new procedures, adding -@node Adding procedures, ODBC, Adding functions, Top -@chapter Adding New Procedures to MySQL - -In @strong{MySQL}, you can define a procedure in C++ that can access and -modify the data in a query before it is sent to the client. The modification -can be done on row-by-row or @code{GROUP BY} level. - -We have created an example procedure in @strong{MySQL} Version 3.23 to -show you what can be done. - -Additionally we recommend you to take a look at 'mylua', which you can find in the Contrib directory. @xref{Contrib}. Which this you can use the LUA -language to load a procedure at runtime into @code{mysqld}. - -@menu -* procedure analyse:: Procedure analyse -* Writing a procedure:: Writing a procedure. -@end menu - -@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures -@section Procedure Analyse - -@code{analyse([max elements,[max memory]])} - -This procedure is defined in the @file{sql/sql_analyse.cc}. This -examines the result from your query and returns an analysis of the -results: - -@itemize @bullet -@item -@code{max elements} (default 256) is the maximum number of distinct values -@code{analyse} will notice per column. This is used by @code{analyse} to check if -the optimal column type should be of type @code{ENUM}. -@item -@code{max memory} (default 8192) is the maximum memory @code{analyse} should -allocate per column while trying to find all distinct values. -@end itemize - -@example -SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]]) -@end example - -@node Writing a procedure, , procedure analyse, Adding procedures -@section Writing a Procedure - -For the moment, the only documentation for this is the source. - -You can find all information about procedures by examining the following files: - -@itemize @bullet -@item @file{sql/sql_analyse.cc} -@item @file{sql/procedure.h} -@item @file{sql/procedure.cc} -@item @file{sql/sql_select.cc} -@end itemize - -@cindex ODBC -@cindex Windows -@cindex MyODBC -@node ODBC, Common programs, Adding procedures, Top -@chapter MySQL ODBC Support - -@menu -* Installing MyODBC:: How to install MyODBC -* ODBC administrator:: How to fill in the various fields in the ODBC administrator program -* MyODBC connect parameters:: -* ODBC Problems:: How to report problems with @strong{MySQL} ODBC -* MyODBC clients:: Programs known to work with @strong{MyODBC} -* ODBC and last_insert_id:: How to get the value of an @code{AUTO_INCREMENT} column in ODBC -* MyODBC bug report:: Reporting problems with MyODBC -@end menu - -@strong{MySQL} provides support for ODBC by means of the @strong{MyODBC} -program. This chapter will teach you how to install @strong{MyODBC}, -and how to use it. Here, you will also find a list of common programs that -are known to work with @strong{MyODBC}. - -@node Installing MyODBC, ODBC administrator, ODBC, ODBC -@section How To Install MyODBC - -@strong{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and level -2 features) driver for connecting an ODBC-aware application to -@strong{MySQL}. @strong{MyODBC} works on Windows95, Windows98, NT, and -on most Unix platforms. - -@strong{MyODBC} is in public domain, and you can find the newest version -at @uref{http://www.mysql.com/downloads/api-myodbc.html}. - -If you have problem with @strong{MyODBC} and your program also works -with OLEDB, you should try the OLEDB driver that you can find in the -Contrib section. @xref{Contrib}. - -Normally you only need to install @strong{MyODBC} on Windows machines. -You only need @strong{MyODBC} for Unix if you have a program like -ColdFusion that is running on the Unix machine and uses ODBC to connect -to the databases. - -If you want to install @strong{MyODBC} on a Unix box, you will also need -an @strong{ODBC} manager. @strong{MyODBC} is known to work with -most of the Unix ODBC managers. You can find a list at these in the -@strong{ODBC}-related links section on the @strong{MySQL} useful links page. -@xref{Useful Links}. - -To install @strong{MyODBC} on Windows, you should download the -appropriate @strong{MyODBC} .zip file (for Windows or NT/Win2000), -unpack it with @code{WINZIP}, or some similar program, and execute the -@code{SETUP.EXE} file. - -On Windows/NT you may get the following error when trying to install -@strong{MyODBC}: - -@example -An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart -Windows and try installing again (before running any applications which -use ODBC) -@end example - -The problem in this case is that some other program is using ODBC and -because of how Windows is designed, you may not in this case be able to -install a new ODBC drivers with Microsoft's ODBC setup program. In most -cases you can continue by just pressing @code{Ignore} to copy the rest -of the MyODBC files and the final installation should still work. If -this doesn't work, the solution is to reboot your computer in ``safe -mode`` (Choose this by pressing F8 just before your machine starts -Windows during rebooting), install @strong{MyODBC}, and reboot to normal -mode. - -@itemize @bullet -@item -To make a connection to a Unix box from a Windows box, with an ODBC -application (one that doesn't support @strong{MySQL} natively), you must -first install @strong{MyODBC} on the Windows machine. -@item -The user and Windows machine must have the access privileges to the -@strong{MySQL} server on the Unix machine. This is set up with the -@code{GRANT} command. @xref{GRANT,,@code{GRANT}}. -@item -You must create an ODBC DSN entry as follows: - -@itemize @minus -@item -Open the Control Panel on the Windows machine. -@item -Double-click the ODBC Data Sources 32 bits icon. -@item -Click the tab User DSN. -@item -Click the button Add. -@item -Select @strong{MySQL} in the screen Create New Data Source and click -the Finish button. -@item -The @strong{MySQL} Driver default configuration screen is shown. -@xref{ODBC administrator}. -@end itemize - -@item -Now start your application and select the ODBC driver with the DSN you -specified in the ODBC administrator. -@end itemize - -Notice that there are other configuration options on the screen of -@strong{MySQL} (trace, don't prompt on connect, etc) that you can try if -you run into problems. - -@cindex ODBC, administrator -@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC -@section How to Fill in the Various Fields in the ODBC Administrator Program - -There are three possibilities for specifying the server name on -Windows95: - -@itemize @bullet -@item -Use the IP address of the server. -@item -Add a file @file{\windows\lmhosts} with the following information: - -@example -ip hostname -@end example - -For example: - -@example -194.216.84.21 my_hostname -@end example - -@item -Configure the PC to use DNS. -@end itemize - -Example of how to fill in the @code{ODBC setup}: -@example -Windows DSN name: test -Description: This is my test database -MySql Database: test -Server: 194.216.84.21 -User: monty -Password: my_password -Port: -@end example - -The value for the @code{Windows DSN name} field is any name that is unique -in your Windows ODBC setup. - -You don't have to specify values for the @code{Server}, @code{User}, -@code{Password}, or @code{Port} fields in the ODBC setup screen. -However, if you do, the values will be used as the defaults later when -you attempt to make a connection. You have the option of changing the -values at that time. - -If the port number is not given, the default port (@value{default_port}) -is used. - -If you specify the option @code{Read options from C:\my.cnf}, the groups -@code{client} and @code{odbc} will be read from the @file{C:\my.cnf} file. -You can use all options that are usable by @code{mysql_options()}. -@xref{mysql_options, , @code{mysql_options}}. - -@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC -@section Connect parameters for MyODBC - -One can specify the following parameters for @strong{MyODBC} on -the @code{[Servername]} section of an @code{ODBC.INI} file or -through the @code{InConnectionString} argument in the -@code{SQLDriverConnect()} call. - -@multitable @columnfractions .2 .2 .6 -@item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment} -@item user @tab ODBC (on Windows) @tab The username used to connect to @strong{MySQL}. -@item server @tab localhost @tab The hostname of the @strong{MySQL} server. -@item database @tab @tab The default database -@item option @tab 0 @tab A integer by which you can specify how @strong{MyODBC} should work. See below. -@item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}. -@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}. -@item password @tab @tab The password for the @code{server} @code{user} combination. -@item socket @tab @tab The socket or Windows pipe to connect to. -@end multitable - -The option argument is used to tell @strong{MyODBC} that the client isn't 100% -ODBC compliant. On Windows, one normally sets the option flag by -toggling the different options on the connection screen but one can also -set this in the opton argument. The following options are listed in the -same order as they appear in the @strong{MyODBC} connect screen: - -@multitable @columnfractions .1 .9 -@item @strong{Bit} @tab @strong{Meaning} -@item 1 @tab The client can't handle that @strong{MyODBC} returns the real width of a column. -@item 2 @tab The client can't handle that MySQL returns the true value of affected rows. If this flag is set then MySQL returns 'found rows' instead. One must have MySQL 3.21.14 or newer to get this to work. -@item 4 @tab Make a debug log in c:\myodbc.log. This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT} -@item 8 @tab Don't set any packet limit for results and parameters. -@item 16 @tab Don't prompt for questions even if driver would like to prompt -@item 32 @tab Simulate a ODBC 1.0 driver in some context. -@item 64 @tab Ignore use of database name in 'database.table.column'. -@item 128 @tab Force use of ODBC manager cursors (experimental). -@item 256 @tab Disable the use of extended fetch (experimental) -@item 512 @tab Pad CHAR fields to full column length. -@item 1024 @tab SQLDescribeCol() will return fully qualifed column names -@item 2048 @tab Use the compressed server/client protocol -@item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords! -@item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT. -@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG). -@item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental) -@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf} -@item 131072 @tab Add some extra safety checks (should not bee needed but...) -@end multitable - -If you want to have many options, you should add the above flags! For -example setting option to 12 (4+8) gives you debugging without package -limits! - -The default @file{MYODBC.DLL} is compiled for optimal performance. If -you want to to debug @strong{MyODBC} (for example to enable tracing), -you should instead use @code{MYODBCD.DLL}. To install this file, copy -@file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file. - -@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC -@section How to Report Problems with MyODBC - -@strong{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder, -Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows), -ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports, -DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes -4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 -bit, VC++, and Visual Basic. - -If you know of any other applications that work with @strong{MyODBC}, please -send mail to @email{myodbc@@lists.mysql.com} about this! - -With some programs you may get an error like: -@code{Another user has modifies the record that you have modified}. In most -cases this can be solved by doing one of the following things: - -@itemize @bullet -@item -Add a primary key for the table if there isn't one already. -@item -Add a timestamp column if there isn't one already. -@item -Only use double float fields. Some programs may fail when they compare -single floats. -@end itemize - -If the above doesn't help, you should do a @code{MyODBC} trace file and -try to figure out why things go wrong. - -@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC -@section Programs Known to Work with MyODBC - -Most programs should work with @strong{MyODBC}, but for each of those -listed below, we have tested it ourselves or received confirmation from -some user that it works: - -@table @asis -@item @strong{Program} -@strong{Comment} -@cindex Access program - -@item Access -To make Access work: -@itemize @bullet -@item -If you are using Access 2000, you should get and install the newest -Microsoft MDAC (@code{Microsoft Data Access Components}) from -@uref{http://www.microsoft.com/data}. This will fix the following bug -in Access: when you export data to @strong{MySQL}, the table and column -names aren't specified. Another way to around this bug is to upgrade to -MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together -provide a workaround for this bug! - -Note that if you are using @strong{MySQL} Version 3.22, you must to apply the -MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around -this problem. -@item -Set the ``Return matching rows'' MyODBC option field when connecting to -@strong{MySQL}. -@item -You should have a primary key in the table. If not, new or updated rows -may show up as @code{#Deleted#}. -@item -You should have a timestamp in all tables you want to be able to update. -For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} -is recommended instead of other @code{TIMESTAMP(X)} variations. -@item -Only use double float fields. Access fails when comparing with single floats. -The symptom usually is that new or updated rows may show up as @code{#Deleted#} -or that you can't find or update rows. -@item -If you still get the error @code{Another user has changed your data} after -adding a @code{TIMESTAMP} column, the following trick may help you: - -Don't use @code{table} data sheet view. Create instead a form with the -fields you want, and use that @code{form} data sheet view. You should -set the @code{DefaultValue} property for the @code{TIMESTAMP} column to -@code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column -from view so your users are not confused. -@item -Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If -you want to have @code{MEMO} columns instead, you should change the -column to @code{TEXT} with @code{ALTER TABLE}. -@item -Access can't always handle @code{DATE} columns properly. If you have a problem -with these, change the columns to @code{DATETIME}. -@item -In some cases, Access may generate illegal SQL queries that -@strong{MySQL} can't understand. You can fix this by selecting -@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. -@item -If you have in Access a column defined as BYTE, Access will try to export this -as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you -problems if you have values > 127 in the column! -@item -If you are using Access 7.0, You should use the option flag @code{Return -matching rows}. -@item -If you are using Access 2.0, You should use the option flags @code{Return -matching rows} and @code{Simulate ODBC 1.0}. -@end itemize - -@cindex ADO program -@item ADO -When you are coding with the ADO API and @strong{MyODBC} you need to put -attention in some default properties that aren't supported by the -@strong{MySQL} server. For example, using the @code{CursorLocation -Property} as @code{adUseServer} will return for the @code{RecordCount -Property} a result of -1. To have the right value, you need to set this -property to @code{adUseClient}, like is showing in the VB code below: - -@example -Dim myconn As New ADODB.Connection -Dim myrs As New Recordset -Dim mySQL As String -Dim myrows As Long - -myconn.Open "DSN=MyODBCsample" -mySQL = "SELECT * from user" -myrs.Source = mySQL -Set myrs.ActiveConnection = myconn -myrs.CursorLocation = adUseClient -myrs.Open -myrows = myrs.RecordCount - -myrs.Close -myconn.Close -@end example - -Another workaround is to use a @code{SELECT COUNT(*)} statement -for a similar query to get the correct row count. - -@item Active server pages (ASP) -You should use the option flag @code{Return matching rows}. - -@item BDE applications -To get these to work, you should set the option flags -@code{Don't optimize column widths} and @code{Return matching rows}. - -@cindex Borland Buidler 4 program -@item Borland Builder 4 -When you start a query you can use the property @code{Active} or use the -method @code{Open}. Note that @code{Active} will start by automatically -issuing a @code{SELECT * FROM ...} query that may not be a good thing if -your tables are big! -@item ColdFusion (On Unix) -The following information is taken from the ColdFusion documentation: - -Use the following information to configure ColdFusion Server for Linux -to use the unixODBC driver with @strong{MyODBC} for @strong{MySQL} data -sources. Allaire has verified that @strong{MyODBC} Version 2.50.26 -works with @strong{MySQL} Version 3.22.27 and ColdFusion for Linux. (Any -newer version should also work.) You can download @strong{MyODBC} at -@uref{http://www.mysql.com/downloads/api-myodbc.html} - -@cindex ColdFusion program -ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator -to add the @strong{MySQL} data source. However, the driver is not -included with ColdFusion Version 4.5.1. Before the @strong{MySQL} driver -will appear in the ODBC datasources drop-down list, you must build and -copy the @strong{MyODBC} driver to -@file{/opt/coldfusion/lib/libmyodbc.so}. - -The Contrib directory contains the program mydsn-xxx.zip which allows -you to build and remove the DSN registry file for the MyODBC driver -on Coldfusion applications. - -@cindex DataJunction -@item DataJunction -You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as -it exports the latter in a manner that causes @strong{MySQL} grief. -@cindex Excel -@item Excel -Works. Some tips: -@itemize @bullet -@item -If you have problems with dates, try to select them as strings using the -@code{CONCAT()} function. For example: -@example -select CONCAT(rise_time), CONCAT(set_time) - from sunrise_sunset; -@end example -Values retrieved as strings this way should be correctly recognized -as time values by Excel97. - -The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking -the column is of ``string type''. Without the @code{CONCAT()}, ODBC knows the -column is of time type, and Excel does not understand that. - -Note that this is a bug in Excel, because it automatically converts a -string to a time. This would be great if the source was a text file, but -is plain stupid when the source is an ODBC connection that reports -exact types for each column. -@end itemize -@cindex Word program -@item Word - -To retrieve data from @strong{MySQL} to Word/Excel documents, you need to -use the @code{MyODBC} driver and the Add-in Microsoft Query help. - -For example, create a db with a table containing 2 columns of text: - -@itemize @bullet -@item -Insert rows using the @code{mysql} client command-line tool. -@item -Create a DSN file using the MyODBC driver, for example, my for the db above. -@item -Open the Word application. -@item -Create a blank new documentation. -@item -Using the tool bar called Database, press the button insert database. -@item -Press the button Get Data. -@item -At the right hand of the screen Get Data, press the button Ms Query. -@item -In the Ms Query create a New Data Source using the DSN file my. -@item -Select the new query. -@item -Select the columns that you want. -@item -Make a filter if you want. -@item -Make a Sort if you want. -@item -Select Return Data to Microsoft Word. -@item -Click Finish. -@item -Click Insert data and select the records. -@item -Click OK and you see the rows in your Word document. -@end itemize - -@cindex odbcadmin program -@item odbcadmin -Test program for ODBC. -@cindex Delphi program -@item Delphi -You must use BDE Version 3.2 or newer. Set the `Don't optimize column width' -option field when connecting to @strong{MySQL}. - -Also, here is some potentially useful Delphi code that sets up both an -ODBC entry and a BDE entry for @strong{MyODBC} (the BDE entry requires a BDE -Alias Editor that is free at a Delphi Super Page near -you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this): - -@example -fReg:= TRegistry.Create; - fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True); - fReg.WriteString('Database', 'Documents'); - fReg.WriteString('Description', ' '); - fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll'); - fReg.WriteString('Flag', '1'); - fReg.WriteString('Password', ''); - fReg.WriteString('Port', ' '); - fReg.WriteString('Server', 'xmark'); - fReg.WriteString('User', 'winuser'); - fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True); - fReg.WriteString('DocumentsFab', 'MySQL'); - fReg.CloseKey; - fReg.Free; - - Memo1.Lines.Add('DATABASE NAME='); - Memo1.Lines.Add('USER NAME='); - Memo1.Lines.Add('ODBC DSN=DocumentsFab'); - Memo1.Lines.Add('OPEN MODE=READ/WRITE'); - Memo1.Lines.Add('BATCH COUNT=200'); - Memo1.Lines.Add('LANGDRIVER='); - Memo1.Lines.Add('MAX ROWS=-1'); - Memo1.Lines.Add('SCHEMA CACHE DIR='); - Memo1.Lines.Add('SCHEMA CACHE SIZE=8'); - Memo1.Lines.Add('SCHEMA CACHE TIME=-1'); - Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT'); - Memo1.Lines.Add('SQLQRYMODE='); - Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE'); - Memo1.Lines.Add('ENABLE BCD=FALSE'); - Memo1.Lines.Add('ROWSET SIZE=20'); - Memo1.Lines.Add('BLOBS TO CACHE=64'); - Memo1.Lines.Add('BLOB SIZE=32'); - - AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines); -@end example - -@cindex C++Builder -@item C++Builder -Tested with BDE Version 3.0. The only known problem is that when the table -schema changes, query fields are not updated. BDE, however, does not seem -to recognize primary keys, only the index PRIMARY, though this has not -been a problem. - -@item Vision -You should use the option flag @code{Return matching rows}. - -@cindex Visual Basic -@item Visual Basic -To be able to update a table, you must define a primary key for the table. - -Visual Basic with ADO can't handle big integers. This means that some queries -like @code{SHOW PROCESSLIST} will not work properly. The fix is to set -add the option @code{OPTION=16834} in the ODBC connect string or set -the @code{Change BIGINT columns to INT} option in the MyODBC connect screen. -You may also want to set the @code{Return matching rows} option. - -@item VisualInterDev -If you get the error @code{[Microsoft][ODBC Driver Manager] Driver does -not support this parameter} the reason may be that you have a -@code{BIGINT} in your result. Try setting the @code{Change BIGINT -columns to INT} option in the MyODBC connect screen. - -@item Visual Objects -You should use the option flag @code{Don't optimize column widths}. -@end table - -@cindex AUTO-INCREMENT, ODBC -@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC -@section How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC - -A common problem is how to get the value of an automatically generated ID -from an @code{INSERT}. With ODBC, you can do something like this (assuming -that @code{auto} is an @code{AUTO_INCREMENT} field): - -@example -INSERT INTO foo (auto,text) VALUES(NULL,'text'); -SELECT LAST_INSERT_ID(); -@end example - -Or, if you are just going to insert the ID into another table, you can do this: - -@example -INSERT INTO foo (auto,text) VALUES(NULL,'text'); -INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); -@end example - -@xref{Getting unique ID}. - -For the benefit of some ODBC applications (at least Delphi and Access), -the following query can be used to find a newly inserted row: -@example -SELECT * FROM tbl_name WHERE auto IS NULL; -@end example - -@cindex reporting, MyODBC problems -@cindex problems, ODBC -@cindex MyODBC, reporting problems -@node MyODBC bug report, , ODBC and last_insert_id, ODBC -@section Reporting Problems with MyODBC - -If you encounter difficulties with @strong{MyODBC}, you should start by -making a log file from the ODBC manager (the log you get when requesting -logs from ODBCADMIN) and a @strong{MyODBC} log. - -To get a @strong{MyODBC} log, you need to do the following: - -@enumerate -@item -Ensure that you are using @code{myodbcd.dll} and not @code{myodbc.dll}. -The easiest way to do this is to get @code{myodbcd.dll} from the MyODBC -distribution and copy it over the @code{myodbc.dll}, which is probably -in your @code{C:\windows\system32} or @code{C:\winnt\system32} directory. - -Note that you probably want to restore the old myodbc.dll file when you -have finished testing, as this is a lot faster than @code{myodbcd.dll}. -@item -Tag the `Trace MyODBC' option flag in the @strong{MyODBC} connect/configure -screen. The log will be written to file @file{C:\myodbc.log}. - -If the trace option is not remembered when you are going back to the -above screen, it means that you are not using the @code{myodbcd.dll} -driver (see above). -@item -Start your application and try to get it to fail. -@end enumerate - -Check the @code{MyODBC trace file}, to find out what could be wrong. -You should be able to find out the issued queries by searching after -the string @code{>mysql_real_query} in the @file{myodbc.log} file. - -You should also try duplicating the queries in the @code{mysql} monitor -or @code{admndemo} to find out if the error is MyODBC or @strong{MySQL}. - -If you find out something is wrong, please only send the relevant rows -(max 40 rows) to @email{myodbc@@lists.mysql.com}. Please never -send the whole MyODBC or ODBC log file! - -If you are unable to find out what's wrong, the last option is to -make an archive (tar or zip) that contains a MyODBC trace file, the ODBC -log file, and a README file that explains the problem. You can send this -to @uref{ftp://support.mysql.com/pub/mysql/secret}. Only we at -@strong{MySQL AB} will have access to the files you upload, and we will -be very discrete with the data! - -If you can create a program that also shows this problem, please -upload this too! - -If the program works with some other SQL server, you should make an ODBC log -file where you do exactly the same thing in the other SQL server. - -Remember that the more information you can supply to us, the more -likely it is that we can fix the problem! - -@node Common programs, Problems, ODBC, Top -@chapter Using MySQL with Some Common Programs - -@menu -* Borland C++:: -@end menu - -This chapter describes how to use @strong{MySQL} with some common programs. - -In this chapter you will: - -@itemize @bullet -@item -Learn how to easily store your Apache log files in a @strong{MySQL} -database. -@item -Find some tips on how to compile @strong{MySQL} and @strong{MySQL}-based -programs using Borland C++. -@end itemize - - -@cindex Borland C++ compiler -@node Borland C++, , Common programs, Common programs -@section Borland C++ - -You can compile the @strong{MySQL} Windows source with Borland C++ 5.02. -(The Windows source includes only projects for Microsoft VC++, for -Borland C++ you have to do the project files yourself). - -One known problem with Borland C++ is that it uses a different structure -alignment than VC++. This means that you will run into problems if you -try to use the default @code{libmysql.dll} libraries (that was compiled -with VC++) with Borland C++. You can do one of the following to avoid -this problem. - -@itemize @bullet -@item -You can use the static @strong{MySQL} libraries for Borland C++ that you -can find on @uref{http://www.mysql.com/downloads/os-win32.html}. -@item -Only call @code{mysql_init()} with @code{NULL} as an argument, not a -pre-allocated MYSQL struct. -@end itemize - -@cindex problems, common errors -@cindex errors, common -@node Problems, Common problems, Common programs, Top -@chapter Problems and Common Errors - -@menu -* What is crashing:: How to determine what is causing problems -* Crashing:: What to do if @strong{MySQL} keeps crashing -* Link errors:: Problems when linking with the @strong{MySQL} client library -* Common errors:: Some common errors when using @strong{MySQL} -* Full disk:: How @strong{MySQL} handles a full disk -* Temporary files:: Where @strong{MySQL} stores temporary files -* Problems with mysql.sock:: How to protect @file{/tmp/mysql.sock} -* Changing MySQL user:: How to run @strong{MySQL} as a normal user -* Resetting permissions:: How to reset a forgotten password. -* File permissions :: Problems with file permissions -* Not enough file handles:: File not found -* Using DATE:: Problems using @code{DATE} columns -* Timezone problems:: Timezone problems -* Case sensitivity:: Case sensitivity in searches -* Problems with NULL:: Problems with @code{NULL} values -* Problems with alias:: Problems with @code{alias} -* Deleting from related tables:: Deleting rows from related tables -* No matching rows:: Solving problems with no matching rows -* ALTER TABLE problems:: Problems with @code{ALTER TABLE}. -* Change column order:: How to change the order of columns in a table -* Temporary table problems:: -@end menu - -This chapter lists some common problems and error messages that users have -run into. You will learn how to figure out what the problem is, and what -to do to solve it. You will also find proper solutions to some common -problems. - -@node What is crashing, Crashing, Problems, Problems -@section How to Determine What Is Causing Problems - -When you run into problems, the first thing you should do is to find out -which program / piece of equipment is causing problems: - -@itemize @bullet -@item -If you have one of the following symptoms, then it is probably a hardware -(like memory, motherboard, CPU, or hard disk) or kernel problem: -@itemize @minus -@item -The keyboard doesn't work. This can normally be checked by pressing -Caps Lock. If the Caps Lock light doesn't change you have to replace -your keyboard. (Before doing this, you should try to reboot -your computer and check all cables to the keyboard.) -@item -The mouse pointer doesn't move. -@item -The machine doesn't answer to a remote machine's pings. -@item -Different, unrelated programs don't behave correctly. -@item -If your system rebooted unexpectedly (a faulty user level program should -NEVER be able to take down your system). -@end itemize - -In this case you should start by checking all your cables and run some -diagnostic tool to check your hardware! -You should also check if there are any patches, updates, or service -packs for your operating system that could likely solve your problems. -Check also that all your libraries (like glibc) are up to date. - -It's always good to use a machine with ECC memory to discover -memory problems early! -@item -If your keyboard is locked up, you may be able to fix this by -logging into your machine from another machine and execute -@code{kbd_mode -a} on it. - -@item -Please examine your system log file (/var/log/messages or similar) for -reasons for your problems. If you think the problem is in @strong{MySQL} -then you should also examine @strong{MySQL}'s log files. @xref{Update log}. - -@item -If you don't think you have hardware problems, you should try to find -out which program is causing problems. - -Try using @code{top}, @code{ps}, @code{taskmanager}, or some similar program, -to check which program is taking all CPU or is locking the machine. - -@item -Check with @code{top}, @code{df}, or a similar program if you are out of -memory, disk space, open files, or some other critical resource. - -@item -If the problem is some runaway process, you can always try to kill it. If it -doesn't want to die, there is probably a bug in the operating system. -@end itemize - -If after you have examined all other possibilities and you have -concluded that it's the @strong{MySQL} server or a @strong{MySQL} client -that is causing the problem, it's time to do a bug report for our -mailing list or our support team. In the bug report, try to give a -very detailed description of how the system is behaving and what you think is -happening. You should also state why you think it's @strong{MySQL} that -is causing the problems. Take into consideration all the situations in -this chapter. State any problems exactly how they appear when you -examine your system. Use the 'cut and paste' method for any output -and/or error messages from programs and/or log files! - -Try to describe in detail which program is not working and all -symptoms you see! We have in the past received many bug reports that just -state "the system doesn't work". This doesn't provide us with any -information about what could be the problem. - -If a program fails, it's always useful to know: - -@itemize @bullet -@item -Has the program in question made a segmentation fault (core dumped)? -@item -Is the program taking the whole CPU? Check with @code{top}. Let the -program run for a while, it may be evaluating something heavy. -@item -If it's the @code{mysqld} server that is causing problems, can you -do @code{mysqladmin -u root ping} or @code{mysqladmin -u root processlist}? -@item -What does a client program say (try with @code{mysql}, for example) -when you try to connect to the @strong{MySQL} server? -Does the client jam? Do you get any output from the program? -@end itemize - -When sending a bug report, you should of follow the outlines -described in this manual. @xref{Asking questions}. - -@cindex crash, repeated -@node Crashing, Link errors, What is crashing, Problems -@section What to Do if MySQL Keeps Crashing - -All @strong{MySQL} versions are tested on many platforms before they are -released. This doesn't mean that there aren't any bugs in -@strong{MySQL}, but it means if there are bugs, they are very few and can be -hard to find. If you have a problem, it will always help if you try to -find out exactly what crashes your system, as you will have a much better -chance of getting this fixed quickly. - -First, you should try to find out whether the problem is that the -@code{mysqld} daemon dies or whether your problem has to do with your -client. You can check how long your @code{mysqld} server has been up by -executing @code{mysqladmin version}. If @code{mysqld} has died, you may -find the reason for this in the file -@file{mysql-data-directory/`hostname`.err}. @xref{Error log}. - -Many crashes of @strong{MySQL} are caused by corrupted index / data -files. @strong{MySQL} will update the data on disk, with the -@code{write()} system call, after every SQL statement and before the -client is notified about the result. (This is not true if you are running -with @code{delayed_key_writes}, in which case only the data is written.) -This means that the data is safe even if @code{mysqld} crashes, as the OS will -ensure that the not flushed data is written to disk. You can force -@strong{MySQL} to sync everything to disk after every SQL command by -starting @code{mysqld} with @code{--flush}. - -The above means that normally you shouldn't get corrupted tables unless: - -@itemize @bullet -@item -Someone/something killed @code{mysqld} or the machine in the middle -of an update. -@item -You have found a bug in @code{mysqld} that caused it to die in the -middle of an update. -@item -Someone is manipulating the data/index files outside of @strong{mysqld} -without locking the table properly. -@item -If you are running many @code{mysqld} servers on the same data on a -system that doesn't support good file system locks (normally handled by -the @code{lockd} daemon ) or if you are running -multiple servers with @code{--skip-locking} -@item -You have a crashed index/data file that contains very wrong data that -got @code{mysqld} confused. -@item -You have found a bug in the data storage code. This isn't that likely, -but it's at least possible. In this case you can try to change the file -type to another database handler by using @code{ALTER TABLE} on a -repaired copy of the table! -@end itemize - -Because it is very difficult to know why something is crashing, first try to -check whether or not things that work for others crash for you. Please try -the following things: - -@itemize @bullet -@item -Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run -@code{myisamchk --silent --force */*.MYI} on all tables, and restart the -@code{mysqld} daemon. This will ensure that you are running from a clean -state. @xref{Maintenance}. - -@item -Use @code{mysqld --log} and try to determine from the information in the log -whether or not some specific query kills the server. About 95% of all bugs are -related to a particular query! Normally this is one of the last queries in -the log file just before @strong{MySQL} restarted. @xref{Query log}. -If you can repeatadly kill @strong{MySQL} with one of the queries, even -when you have checked all tables just before doing the query, then you -have been able to locate the bug and should do a bug report for this! -@xref{Bug reports}. - -@item -Try to make a test case that we can use to reproduce the problem. -@xref{Reproduceable test case}. - -@item -Try running the included mysql-test test and the @strong{MySQL} -benchmarks. @xref{MySQL test suite}. They should test @strong{MySQL} -rather well. You can also add code that to the benchmarks to simulates -your application! The benchmarks can be found in the @file{bench} -directory in the source distribution or, for a binary distribution, in -the @file{sql-bench} directory under your @strong{MySQL} installation -directory. - -@item -Try @code{fork_test.pl} and @code{fork2_test.pl}. - -@item -If you configure @strong{MySQL} for debugging, it will be much easier to -gather information about possible errors if something goes wrong. -Reconfigure @strong{MySQL} with the @code{--with-debug} option or -@code{--with-debug=full} to @code{configure} and then recompile. -@xref{Debugging server}. - -@item -Configuring @strong{MySQL} for debugging causes a safe memory allocator to be -included that can find some errors. It also provides a lot of output about -what is happening. - -@item -Have you applied the latest patches for your operating system? - -@item -Use the @code{--skip-locking} option to @code{mysqld}. On some systems, the -@code{lockd} lock manager does not work properly; the @code{--skip-locking} -option tells @code{mysqld} not to use external locking. (This means that you -cannot run 2 @code{mysqld} servers on the same data and that you must be -careful if you use @code{myisamchk}, but it may be instructive to try the -option as a test.) - -@item -Have you tried @code{mysqladmin -u root processlist} when @code{mysqld} -appears to be running but not responding? Sometimes @code{mysqld} is not -comatose even though you might think so. The problem may be that all -connections are in use, or there may be some internal lock problem. -@code{mysqladmin processlist} will usually be able to make a connection even -in these cases, and can provide useful information about the current number -of connections and their status. - -@item -Run the command @code{mysqladmin -i 5 status} or @code{mysqladmin -i 5 --r status} or in a separate window to produce statistics while you run -your other queries. - -@item -Try the following: -@enumerate -@item -Start @code{mysqld} from @code{gdb} (or in another debugger). -@xref{Using gdb on mysqld}. - -@item -Run your test scripts. - -@item -Print the backtrace and the local variables at the 3 lowest levels. In gdb you -can do this with the following commands when @code{mysqld} has crashed inside -gdb: - -@example -backtrace -info local -up -info local -up -info local -@end example - -With gdb you can also examine which threads exist with @code{info -threads} and switch to a specific thread with @code{thread #}, where -@code{#} is the thread id. -@end enumerate - -@item -Try to simulate your application with a Perl script to force -@strong{MySQL} to crash or misbehave. - -@item -Send a normal bug report. @xref{Bug reports}. Be even more detailed -than usual. Because @strong{MySQL} works for many people, it may be that the -crash results from something that exists only on your computer (for example, -an error that is related to your particular system libraries). -@item -If you have a problem with tables with dynamic-length rows and you are -not using @code{BLOB/TEXT} columns (but only @code{VARCHAR} columns), you -can try to change all @code{VARCHAR} to @code{CHAR} with @code{ALTER -TABLE}. This will force @strong{MySQL} to use fixed-size rows. -Fixed-size rows take a little extra space, but are much more tolerant to -corruption! - -The current dynamic row code has been in use at @strong{MySQL AB} for at -least 3 years without any problems, but by nature dynamic-length rows are -more prone to errors, so it may be a good idea to try the above to see if -it helps! -@end itemize - -@cindex linking, errors -@cindex errors, linking -@cindex problems, linking -@node Link errors, Common errors, Crashing, Problems -@section Problems When Linking with the MySQL Client Library - -If you are linking your program and you get errors for unreferenced -symbols that start with @code{mysql_}, like the following: - -@example -/tmp/ccFKsdPa.o: In function `main': -/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init' -/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect' -/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect' -/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error' -/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close' -@end example - -you should be able to solve this by adding @code{-Lpath-to-the-mysql-library --lmysqlclient} @strong{LAST} on your link line. - -If you get @code{undefined reference} errors for the @code{uncompress} -or @code{compress} function, add @code{-lgz} @strong{LAST} on your link -line and try again! - -If you get @code{undefined reference} errors for functions that should -exist on your system, like @code{connect}, check the man page for the -function in question, for which libraries you should add to the link -line! - -If you get @code{undefined reference} errors for functions that don't -exist on your system, like the following: - -@example -mf_format.o(.text+0x201): undefined reference to `__lxstat' -@end example - -it usually means that your library is compiled on a system that is not -100 % compatible with yours. In this case you should download the -latest @strong{MySQL} source distribution and compile this yourself. -@xref{Installing source}. - -If you are trying to run a program and you then get errors for -unreferenced symbols that start with @code{mysql_} or that the -@code{mysqlclient} library can't be found, this means that your system -can't find the share @code{libmysqlclient.so} library. - -The fix for this is to tell your system to search after shared -libraries where the library is located by one of the following methods: - -@itemize @bullet -@item -Add the path to the directory where you have @code{libmysqlclient.so} the -@code{LD_LIBRARY_PATH} environment variable. -@item -Add the path to the directory where you have @code{libmysqlclient.so} the -@code{LD_LIBRARY} environment variable. -@item -Copy @code{libmysqlclient.so} to some place that is searched by your system, -like @file{/lib}, and update the shared library information by executing -@code{ldconfig}. -@end itemize - -Another way to solve this problem is to link your program statically, with -@code{-static}, or by removing the dynamic @strong{MySQL} libraries -before linking your code. In the second case you should be -sure that no other programs are using the dynamic libraries! - -@cindex errors, list of -@node Common errors, Full disk, Link errors, Problems -@section Some Common Errors When Using MySQL - -@menu -* Error Access denied:: @code{Access denied} Error -* Gone away:: @code{MySQL server has gone away} error -* Can not connect to server:: @code{Can't connect to [local] MySQL server} error -* Blocked host:: @code{Host '...' is blocked} error -* Too many connections:: @code{Too many connections} error -* Non-transactional tables:: @code{Some non-transactional changed tables couldn't be rolled back} Error -* Out of memory:: @code{Out of memory} error -* Packet too large:: @code{Packet too large} error -* Communication errors:: Communication errors / Aborted connection -* Full table:: @code{The table is full} error -* Cannot create:: @code{Can't create/write to file} Error -* Commands out of sync:: @code{Commands out of sync} error in client -* Ignoring user:: @code{Ignoring user} error -* Cannot find table:: @code{Table 'xxx' doesn't exist} error -* Cannot initialize character set:: -@end menu - -This section lists some errors that users frequently get. You will find -descriptions of the errors, and how to solve the problem here. - -@cindex errors, access denied -@cindex problems, access denied errors -@cindex access denied errors -@node Error Access denied, Gone away, Common errors, Common errors -@subsection @code{Access denied} Error - -@xref{Privileges}, and especially. @xref{Access denied}. - -@node Gone away, Can not connect to server, Error Access denied, Common errors -@subsection @code{MySQL server has gone away} Error - -This section also covers the related @code{Lost connection to server -during query} error. - -The most common reason for the @code{MySQL server has gone away} error -is that the server timed out and closed the connection. By default, the -server closes the connection after 8 hours if nothing has happened. You -can change the time limit by setting the @code{wait_timeout} variable when -you start @code{mysqld}. - -Another common reason to receive the @code{MySQL server has gone away} error -is because you have issued a ``close'' on your @strong{MySQL} connection -and then tried to run a query on the closed connection. - -You can check that the @strong{MySQL} hasn't died by executing -@code{mysqladmin version} and examining the uptime. - -If you have a script, you just have to issue the query again for the client -to do an automatic reconnection. - -You normally can get the following error codes in this case -(which one you get is OS-dependent): - -@multitable @columnfractions .3 .7 -@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the -server. -@item @code{CR_SERVER_LOST} @tab The client didn't get an error when writing -to the server, but it didn't get a full answer (or any answer) to the question. -@end multitable - -You can also get these errors if you send a query to the server that is -incorrect or too large. If @code{mysqld} gets a packet that is too large -or out of order, it assumes that something has gone wrong with the client and -closes the connection. If you need big queries (for example, if you are -working with big @code{BLOB} columns), you can increase the query limit by -starting @code{mysqld} with the @code{-O max_allowed_packet=#} option -(default 1M). The extra memory is allocated on demand, so @code{mysqld} will -use more memory only when you issue a big query or when @code{mysqld} must -return a big result row! - -@node Can not connect to server, Blocked host, Gone away, Common errors -@subsection @code{Can't connect to [local] MySQL server} error - -A @strong{MySQL} client on Unix can connect to the @code{mysqld} server in two -different ways: Unix sockets, which connect through a file in the file -system (default @file{/tmp/mysqld.sock}) or TCP/IP, which connects -through a port number. Unix sockets are faster than TCP/IP but can only -be used when connecting to a server on the same computer. Unix sockets -are used if you don't specify a hostname or if you specify the special -hostname @code{localhost}. - -On Windows you can connect only with TCP/IP if the @code{mysqld} server -is running on Win95/Win98. If it's running on NT, you can also connect -with named pipes. The name of the named pipe is @strong{MySQL}. If you -don't give a hostname when connecting to @code{mysqld}, a @strong{MySQL} client -will first try to connect to the named pipe, and if this doesn't work it -will connect to the TCP/IP port. You can force the use of named pipes -on Windows by using @code{.} as the hostname. - -The error (2002) @code{Can't connect to ...} normally means that there -isn't a @strong{MySQL} server running on the system or that you are -using a wrong socket file or TCP/IP port when trying to connect to the -@code{mysqld} server. - -Start by checking (using @code{ps} or the task manager on Windows) that -there is a process running named @code{mysqld} on your server! If there -isn't any @code{mysqld} process, you should start one. @xref{Starting -server}. - -If a @code{mysqld} process is running, you can check the server by -trying these different connections (the port number and socket pathname -might be different in your setup, of course): - -@example -shell> mysqladmin version -shell> mysqladmin variables -shell> mysqladmin -h `hostname` version variables -shell> mysqladmin -h `hostname` --port=3306 version -shell> mysqladmin -h 'ip for your host' version -shell> mysqladmin --socket=/tmp/mysql.sock version -@end example - -Note the use of backquotes rather than forward quotes with the @code{hostname} -command; these cause the output of @code{hostname} (that is, the current -hostname) to be substituted into the @code{mysqladmin} command. - -Here are some reasons the @code{Can't connect to local MySQL server} -error might occur: - -@itemize @bullet -@item -@code{mysqld} is not running. -@item -You are running on a system that uses MIT-pthreads. -If you are running on a system that doesn't have native threads, -@code{mysqld} uses the MIT-pthreads package. @xref{Which OS}. However, -all MIT-pthreads versions doesn't support Unix sockets. On a system -without sockets support you must always specify the hostname explicitly -when connecting to the server. Try using this command to check the -connection to the server: -@example -shell> mysqladmin -h `hostname` version -@end example -@item -Someone has removed the Unix socket that @code{mysqld} uses (default -@file{/tmp/mysqld.sock}). You might have a @code{cron} job that removes -the @strong{MySQL} socket (for example, a job that removes old files -from the @file{/tmp} directory). You can always run @code{mysqladmin -version} and check that the socket @code{mysqladmin} is trying to use -really exists. The fix in this case is to change the @code{cron} job to -not remove @file{mysqld.sock} or to place the socket somewhere else. You -can specify a different socket location at @strong{MySQL} configuration -time with this command: -@example -shell> ./configure --with-unix-socket-path=/path/to/socket -@end example -You can also start @code{safe_mysqld} with the -@code{--socket=/path/to/socket} option and set the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname before starting your -@strong{MySQL} clients. -@item -You have started the @code{mysqld} server with -the @code{--socket=/path/to/socket} option. If you change the socket -pathname for the server, you must also notify the @strong{MySQL} clients -about the new path. You can do this by setting the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname or by providing the socket path -as an argument to the clients. You can test the socket with this command: - -@example -shell> mysqladmin --socket=/path/to/socket version -@end example -@item -You are using Linux and one thread has died (core dumped). In this case -you must kill the other @code{mysqld} threads (for example, with the -@code{mysql_zap} script before you can start a new @strong{MySQL} -server. @xref{Crashing}. -@item -You may not have read and write privilege to either the directory that holds -the socket file or privilege to the socket file itself. In this case you -have to either change the privilege for the directory / file or restart -@code{mysqld} so that it uses a directory that you can access. -@end itemize - -If you get the error message @code{Can't connect to MySQL server on -some_hostname}, you can try the following things to find out what the -problem is : - -@itemize @bullet -@item -Check if the server is up by doing @code{telnet your-host-name -tcp-ip-port-number} and press @code{RETURN} a couple of times. If there -is a @strong{MySQL} server running on this port you should get a -responses that includes the version number of the running @strong{MySQL} -server. If you get an error like @code{telnet: Unable to connect to -remote host: Connection refused}, then there is no server running on the -given port. -@item -Try connecting to the @code{mysqld} daemon on the local machine and check -the TCP/IP port that @code{mysqld} it's configured to use (variable @code{port}) with -@code{mysqladmin variables}. -@item -Check that your @code{mysqld} server is not started with the -@code{--skip-networking} option. -@end itemize - -@node Blocked host, Too many connections, Can not connect to server, Common errors -@subsection @code{Host '...' is blocked} Error - -If you get an error like this: - -@example -Host 'hostname' is blocked because of many connection errors. -Unblock with 'mysqladmin flush-hosts' -@end example - -this means that @code{mysqld} has gotten a lot (@code{max_connect_errors}) -of connect requests from the host @code{'hostname'} that have been interrupted -in the middle. After @code{max_connect_errors} failed requests, @code{mysqld} -assumes that something is wrong (like an attack from a cracker), and -blocks the site from further connections until someone executes the command -@code{mysqladmin flush-hosts}. - -By default, @code{mysqld} blocks a host after 10 connection errors. -You can easily adjust this by starting the server like this: - -@example -shell> safe_mysqld -O max_connect_errors=10000 & -@end example - -Note that if you get this error message for a given host, you should first -check that there isn't anything wrong with TCP/IP connections from that -host. If your TCP/IP connections aren't working, it won't do you any good to -increase the value of the @code{max_connect_errors} variable! - -@node Too many connections, Non-transactional tables, Blocked host, Common errors -@subsection @code{Too many connections} Error - -If you get the error @code{Too many connections} when you try to connect -to @strong{MySQL}, this means that there is already @code{max_connections} -clients connected to the @code{mysqld} server. - -If you need more connections than the default (100), then you should restart -@code{mysqld} with a bigger value for the @code{max_connections} variable. - -Note that @code{mysqld} actually allows (@code{max_connections}+1) -clients to connect. The last connection is reserved for a user with the -@strong{process} privilege. By not giving this privilege to normal -users (they shouldn't need this), an administrator with this privilege -can log in and use @code{SHOW PROCESSLIST} to find out what could be -wrong. @xref{SHOW}. - -The maximum number of connects @strong{MySQL} is depending on how good -the thread library is on a given platform. Linux or Solaris should be -able to support 500-1000 simultaneous connections, depending on how much -RAM you have and what your clients are doing. - -@cindex Non-transactional tables -@node Non-transactional tables, Out of memory, Too many connections, Common errors -@subsection @code{Some non-transactional changed tables couldn't be rolled back} Error - -If you get the error/warning: @code{Warning: Some non-transactional -changed tables couldn't be rolled back} when trying to do a -@code{ROLLBACK}, this means that some of the tables you used in the -transaction didn't support transactions. These non-transactional tables -will not be affected by the @code{ROLLBACK} statement. - -The most typical case when this happens is when you have tried to create -a table of a type that is not supported by your @code{mysqld} binary. -If @code{mysqld} doesn't support a table type (or if the table type is -disabled by a startup option) , it will instead create the table type -with the table type that is most resembles to the one you requested, -probably @code{MyISAM}. - -You can check the table type for a table by doing: - -@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. - -You can check the extensions your @code{mysqld} binary supports by doing: - -@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. - -@node Out of memory, Packet too large, Non-transactional tables, Common errors -@subsection @code{Out of memory} Error - -If you issue a query and get something like the following error: - -@example -mysql: Out of memory at line 42, 'malloc.c' -mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) -ERROR 2008: MySQL client ran out of memory -@end example - -note that the error refers to the @strong{MySQL} client @code{mysql}. The -reason for this error is simply that the client does not have enough memory to -store the whole result. - -To remedy the problem, first check that your query is correct. Is it -reasonable that it should return so many rows? If so, -you can use @code{mysql --quick}, which uses @code{mysql_use_result()} -to retrieve the result set. This places less of a load on the client (but -more on the server). - -@node Packet too large, Communication errors, Out of memory, Common errors -@subsection @code{Packet too large} Error - -When a @strong{MySQL} client or the @code{mysqld} server gets a packet bigger -than @code{max_allowed_packet} bytes, it issues a @code{Packet too large} -error and closes the connection. - -If you are using the @code{mysql} client, you may specify a bigger buffer by -starting the client with @code{mysql --set-variable=max_allowed_packet=8M}. - -If you are using other clients that do not allow you to specify the maximum -packet size (such as @code{DBI}), you need to set the packet size when you -start the server. You cau use a command-line option to @code{mysqld} to set -@code{max_allowed_packet} to a larger size. For example, if you are -expecting to store the full length of a @code{BLOB} into a table, you'll need -to start the server with the @code{--set-variable=max_allowed_packet=16M} -option. - -@cindex aborted clients -@cindex aborted connection -@cindex connection, aborted -@node Communication errors, Full table, Packet too large, Common errors -@subsection Communication Errors / Aborted Connection - -Starting with @code{MySQL 3.23.40} you only get the @code{Aborted -connection} error of you start @code{mysqld} with @code{--warnings}. - -If you find errors like the following in your error log. - -@example -010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' -@end example - -@xref{Error log}. - -This means that something of the following has happened: - -@itemize @bullet -@item -The client program did not call @code{mysql_close()} before exit. -@item -The client had been sleeping more than @code{wait_timeout} or -@code{interactive_timeout} without doing any requests. @xref{SHOW -VARIABLES}. -@item -The client program ended abruptly in the middle of the transfer. -@end itemize - -When the above happens, the server variable @code{Aborted_clients} is -incremented. - -The server variable @code{Aborted_connects} is incremented when: - -@itemize @bullet -@item -When a connection packet doesn't contain the right information. -@item -When the user didn't have privileges to connect to a database. -@item -When a user uses a wrong password. -@item -When it takes more than @code{connect_timeout} seconds to get -a connect package. -@end itemize - -Note that the above could indicate that someone is trying to break into -your database! - -@xref{SHOW VARIABLES}. - -Other reasons for problems with Aborted clients / Aborted connections. -@itemize @bullet -@item -Usage of duplex Ethernet protocol, both half and full with -Linux. Many Linux Ethernet drivers have this bug. You should test -for this bug by transferring a huge file via ftp between these two -machines. If a transfer goes in burst-pause-burst-pause ... mode then -you are experiencing a Linux duplex syndrome. The only solution to -this problem is switching of both half and full duplexing on hubs -and switches. -@item -Some problem with the thread library that causes interrupts on reads. -@item -Badly configured TCP/IP. -@item -Faulty Ethernets or hubs or switches, cables ... This can be diagnosed -properly only by replacing hardware. -@end itemize - - -@cindex table is full -@node Full table, Cannot create, Communication errors, Common errors -@subsection @code{The table is full} Error - -This error occurs in older @strong{MySQL} versions when an in-memory temporary -table becomes larger than @code{tmp_table_size} bytes. To avoid this -problem, you can use the @code{-O tmp_table_size=#} option to -@code{mysqld} to increase the temporary table size or use the SQL -option @code{SQL_BIG_TABLES} before you issue the problematic -query. @xref{SET OPTION, , @code{SET OPTION}}. - -You can also start @code{mysqld} with the @code{--big-tables} option. -This is exactly the same as using @code{SQL_BIG_TABLES} for all queries. - -In @strong{MySQL} Version 3.23, in-memory temporary tables will automatically be -converted to a disk-based @code{MyISAM} table after the table size gets -bigger than @code{tmp_table_size}. - -@cindex can't create/write to file -@node Cannot create, Commands out of sync, Full table, Common errors -@subsection @code{Can't create/write to file} Error - -If you get an error for some queries of type: - -@example -Can't create/write to file '\\sqla3fe_0.ism'. -@end example - -this means that @strong{MySQL} can't create a temporary file for the -result set in the given temporary directory. (The above error is a -typical error message on Windows, and the Unix error message is similar.) -The fix is to start @code{mysqld} with @code{--tmpdir=path} or to add to your option -file: - -@example -[mysqld] -tmpdir=C:/temp -@end example - -assuming that the @file{c:\\temp} directory exists. @xref{Option files}. - -Check also the error code that you get with @code{perror}. One reason -may also be a disk full error; - -@example -shell> perror 28 -Error code 28: No space left on device -@end example - -@cindex commands out of sync -@node Commands out of sync, Ignoring user, Cannot create, Common errors -@subsection @code{Commands out of sync} Error in Client - -If you get @code{Commands out of sync; You can't run this command now} -in your client code, you are calling client functions in the wrong order! - -This can happen, for example, if you are using @code{mysql_use_result()} and -try to execute a new query before you have called @code{mysql_free_result()}. -It can also happen if you try to execute two queries that return data without -a @code{mysql_use_result()} or @code{mysql_store_result()} in between. - -@node Ignoring user, Cannot find table, Commands out of sync, Common errors -@subsection @code{Ignoring user} Error - -If you get the following error: - -@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} - -this means that when @code{mysqld} was started or when it reloaded the -permissions tables, it found an entry in the @code{user} table with -an invalid password. As a result, the entry is simply ignored by the -permission system. - -Possible causes of and fixes for this problem: - -@itemize @bullet -@item -You may be running a new version of @code{mysqld} with an old -@code{user} table. -You can check this by executing @code{mysqlshow mysql user} to see if -the password field is shorter than 16 characters. If so, you can correct this -condition by running the @code{scripts/add_long_password} script. - -@item -The user has an old password (8 characters long) and you didn't start -@code{mysqld} with the @code{--old-protocol} option. -Update the user in the @code{user} table with a new password or -restart @code{mysqld} with @code{--old-protocol}. - -@item -@findex PASSWORD() -You have specified a password in the @code{user} table without using the -@code{PASSWORD()} function. Use @code{mysql} to update the user in the -@code{user} table with a new password. Make sure to use the @code{PASSWORD()} -function: - -@example -mysql> update user set password=PASSWORD('your password') - where user='XXX'; -@end example -@end itemize - -@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors -@subsection @code{Table 'xxx' doesn't exist} Error - -If you get the error @code{Table 'xxx' doesn't exist} or @code{Can't -find file: 'xxx' (errno: 2)}, this means that no table exists -in the current database with the name @code{xxx}. - -Note that as @strong{MySQL} uses directories and files to store databases and -tables, the database and table names are @strong{case sensitive}! -(On Windows the databases and tables names are not case sensitive, but all -references to a given table within a query must use the same case!) - -You can check which tables you have in the current database with -@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. - -@cindex multibyte character sets -@node Cannot initialize character set, , Cannot find table, Common errors -@subsection @code{Can@'t initialize character set xxx} error. - -If you get an error like: - -@example -MySQL Connection Failed: Can't initialize character set xxx -@end example - -This means one of the following things: - -@itemize @bullet -@item -The character set is a multi-byte character set and you have not support -for the character set in the client. - -In this case you need to recompile the client with -@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. -@xref{configure options}. - -All standard @strong{MySQL} binaries are compiled with -@code{--with-extra-character-sets=complex} which will enable support for -all multi-byte character sets. @xref{Character sets}. - -@item -The character set is a simple character set which is not compiled into -@code{mysqld} and the character set definition files is not in the place -where the client expect to find them. - -In this case you need to: - -@itemize @bullet -@item -Recompile the client with support for the character set. -@xref{configure options}. -@item -Specify to the client where the character set definition files are. For many -client you can do this with the -@code{--character-sets-dir=path-to-charset-dir} option. -@item -Copy the character definition files to the path where the client expect them -to be. -@end itemize -@end itemize - -@cindex full disk -@cindex disk full -@node Full disk, Temporary files, Common errors, Problems -@section How MySQL Handles a Full Disk - -@noindent -When a disk-full condition occurs, @strong{MySQL} does the following: - -@itemize @bullet -@item -It checks once every minute to see whether or not there is enough space to -write the current row. If there is enough space, it continues as if nothing had -happened. -@item -Every 6 minutes it writes an entry to the log file warning about the disk -full condition. -@end itemize - -@noindent -To alleviate the problem, you can take the following actions: - -@itemize @bullet -@item -To continue, you only have to free enough disk space to insert all records. -@item -To abort the thread, you must send a @code{mysqladmin kill} to the thread. -The thread will be aborted the next time it checks the disk (in 1 minute). -@item -Note that other threads may be waiting for the table that caused the disk -full condition. If you have several ``locked'' threads, killing the one -thread that is waiting on the disk-full condition will allow the other -threads to continue. -@end itemize - -Exceptions to the above behaveour is when you use @code{REPAIR} or -@code{OPTIMIZE} or when the indexes are created in a batch after an -@code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. - -All of the above commands may use big temporary files that left to -themself would cause big problems for the rest of the system. If -@strong{MySQL} gets disk full while doing any of the above operations, -it will remove the big temporary files and mark the table as crashed -(except for @code{ALTER TABLE}, in which the old table will be left -unchanged). - - -@node Temporary files, Problems with mysql.sock, Full disk, Problems -@section Where MySQL Stores Temporary Files - -@strong{MySQL} uses the value of the @code{TMPDIR} environment variable as -the pathname of the directory in which to store temporary files. If you don't -have @code{TMPDIR} set, @strong{MySQL} uses the system default, which is -normally @file{/tmp} or @file{/usr/tmp}. If the file system containing your -temporary file directory is too small, you should edit @code{safe_mysqld} to -set @code{TMPDIR} to point to a directory in a file system where you have -enough space! You can also set the temporary directory using the -@code{--tmpdir} option to @code{mysqld}. - -@strong{MySQL} creates all temporary files as hidden files. This ensures -that the temporary files will be removed if @code{mysqld} is terminated. The -disadvantage of using hidden files is that you will not see a big temporary -file that fills up the file system in which the temporary file directory is -located. - -When sorting (@code{ORDER BY} or @code{GROUP BY}), @strong{MySQL} normally -uses one or two temporary files. The maximum disk-space needed is: - -@example -(length of what is sorted + sizeof(database pointer)) -* number of matched rows -* 2 -@end example - -@code{sizeof(database pointer)} is usually 4, but may grow in the future for -really big tables. - -For some @code{SELECT} queries, @strong{MySQL} also creates temporary SQL -tables. These are not hidden and have names of the form @file{SQL_*}. - -@code{ALTER TABLE} creates a temporary table in the same directory as -the original table. - -@cindex @code{mysql.sock}, protection -@cindex deletion, @code{mysql.sock} -@node Problems with mysql.sock, Changing MySQL user, Temporary files, Problems -@section How to Protect @file{/tmp/mysql.sock} from Being Deleted - -If you have problems with the fact that anyone can delete the -@strong{MySQL} communication socket @file{/tmp/mysql.sock}, you can, -on most versions of Unix, protect your @file{/tmp} file system by setting -the @code{sticky} bit on it. Log in as @code{root} and do the following: - -@example -shell> chmod +t /tmp -@end example - -This will protect your @file{/tmp} file system so that files can be deleted -only by their owners or the superuser (@code{root}). - -You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}. -If the last permission bit is @code{t}, the bit is set. - -@cindex starting, @code{mysqld} -@cindex @code{mysqld}, starting -@node Changing MySQL user, Resetting permissions, Problems with mysql.sock, Problems -@section How to Run MySQL As a Normal User - -The @strong{MySQL} server @code{mysqld} can be started and run by any user. -In order to change @code{mysqld} to run as a Unix user @code{user_name}, you must -do the following: - -@enumerate -@item -Stop the server if it's running (use @code{mysqladmin shutdown}). - -@item -Change the database directories and files so that @code{user_name} has -privileges to read and write files in them (you may need to do this as -the Unix @code{root} user): - -@example -shell> chown -R user_name /path/to/mysql/datadir -@end example - -If directories or files within the @strong{MySQL} data directory are -symlinks, you'll also need to follow those links and change the directories -and files they point to. @code{chown -R} may not follow symlinks for -you. - -@item -Start the server as user @code{user_name}, or, if you are using -@strong{MySQL} Version 3.22 or later, start @code{mysqld} as the Unix @code{root} -user and use the @code{--user=user_name} option. @code{mysqld} will switch -to run as the Unix user @code{user_name} before accepting any connections. - -@item -To start the server as the given user name automatically at system -startup time, add a @code{user} line that specifies the user name to -the @code{[mysqld]} group of the @file{/etc/my.cnf} option file or the -@file{my.cnf} option file in the server's data directory. For example: - -@example -[mysqld] -user=user_name -@end example -@end enumerate - -At this point, your @code{mysqld} process should be running fine and dandy as -the Unix user @code{user_name}. One thing hasn't changed, though: the -contents of the permissions tables. By default (right after running the -permissions table install script @code{mysql_install_db}), the @strong{MySQL} -user @code{root} is the only user with permission to access the @code{mysql} -database or to create or drop databases. Unless you have changed those -permissions, they still hold. This shouldn't stop you from accessing -@strong{MySQL} as the @strong{MySQL} @code{root} user when you're logged in -as a Unix user other than @code{root}; just specify the @code{-u root} option -to the client program. - -Note that accessing @strong{MySQL} as @code{root}, by supplying @code{-u -root} on the command line, has @emph{nothing} to do with @strong{MySQL} running -as the Unix @code{root} user, or, indeed, as another Unix user. The access -permissions and user names of @strong{MySQL} are completely separate from -Unix user names. The only connection with Unix user names is that if you -don't provide a @code{-u} option when you invoke a client program, the client -will try to connect using your Unix login name as your @strong{MySQL} user -name. - -If your Unix box itself isn't secured, you should probably at least put a -password on the @strong{MySQL} @code{root} users in the access tables. -Otherwise, any user with an account on that machine can run @code{mysql -u -root db_name} and do whatever he likes. - -@cindex passwords, forgotten -@cindex passwords, resetting -@cindex root user, password resetting -@node Resetting permissions, File permissions , Changing MySQL user, Problems -@section How to Reset a Forgotten Password - -If you have forgotten the @code{root} user password for @strong{MySQL}, you -can restore it with the following procedure: - -@enumerate -@item -Take down the @code{mysqld} server by sending a @code{kill} (not @code{kill --9}) to the @code{mysqld} server. The pid is stored in a @code{.pid} -file, which is normally in the @strong{MySQL} database directory: - -@example -kill `cat /mysql-data-directory/hostname.pid` -@end example - -You must be either the Unix @code{root} user or the same user the server -runs as to do this. - -@item -Restart @code{mysqld} with the @code{--skip-grant-tables} option. -@item -Connect to the @code{mysqld} server with @code{mysql -h hostname mysql} and change -the password with a @code{GRANT} command. @xref{GRANT,,@code{GRANT}}. -You can also do this with -@code{mysqladmin -h hostname -u user password 'new password'} -@item -Load the privilege tables with: @code{mysqladmin -h hostname -flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}. -@end enumerate - -Note that after you started @code{mysqld} with @code{--skip-grant-tables}, -any usage of @code{GRANT} commands will give you an @code{Unknown command} -error until you have executed @code{FLUSH PRIVILEGES}. - -@cindex files, permissions -@cindex error mesaages, can't find file -@cindex files, not found message -@node File permissions , Not enough file handles, Resetting permissions, Problems -@section Problems with File Permissions - -If you have problems with file permissions, for example, if @code{mysql} -issues the following error message when you create a table: - -@example -ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) -@end example - -@tindex UMASK environment variable -@tindex Environment variable, UMASK -then the environment variable @code{UMASK} might be set incorrectly when -@code{mysqld} starts up. The default umask value is @code{0660}. You can -change this behavior by starting @code{safe_mysqld} as follows: - -@example -shell> UMASK=384 # = 600 in octal -shell> export UMASK -shell> /path/to/safe_mysqld & -@end example - -@tindex UMASK_DIR environment variable -@tindex Environment variable, UMASK_DIR -By default @strong{MySQL} will create database and @code{RAID} -directories with permission type 0700. You can modify this behavior by -setting the @code{UMASK_DIR} variable. If you set this, new -directories are created with the combined @code{UMASK} and -@code{UMASK_DIR}. For example, if you want to give group access to -all new directories, you can do: - -@example -shell> UMASK_DIR=504 # = 770 in octal -shell> export UMASK_DIR -shell> /path/to/safe_mysqld & -@end example - -In @strong{MySQL} Version 3.23.25 and above, @strong{MySQL} assumes that the -value for @code{UMASK} and @code{UMASK_DIR} is in octal if it starts -with a zero. - -@xref{Environment variables}. - -@node Not enough file handles, Using DATE, File permissions , Problems -@section File Not Found - -If you get @code{ERROR '...' not found (errno: 23)}, @code{Can't open -file: ... (errno: 24)}, or any other error with @code{errno 23} or -@code{errno 24} from @strong{MySQL}, it means that you haven't allocated -enough file descriptors for @strong{MySQL}. You can use the -@code{perror} utility to get a description of what the error number -means: - -@example -shell> perror 23 -File table overflow -shell> perror 24 -Too many open files -shell> perror 11 -Resource temporarily unavailable -@end example - -The problem here is that @code{mysqld} is trying to keep open too many -files simultaneously. You can either tell @code{mysqld} not to open so -many files at once or increase the number of file descriptors -available to @code{mysqld}. - -To tell @code{mysqld} to keep open fewer files at a time, you can make -the table cache smaller by using the @code{-O table_cache=32} option to -@code{safe_mysqld} (the default value is 64). Reducing the value of -@code{max_connections} will also reduce the number of open files (the -default value is 90). - -@tindex ulimit -To change the number of file descriptors available to @code{mysqld}, you -can use the option @code{--open-files-limit=#} to @code{safe_mysqld} or -@code{-O open-files-limit=#} to @code{mysqld}. @xref{SHOW VARIABLES}. -The easiest way to do that is to add the option to your option file. -@xref{Option files}. If you have an old @code{mysqld} version that -doesn't support this, you can edit the @code{safe_mysqld} script. There -is a commented-out line @code{ulimit -n 256} in the script. You can -remove the @code{'#'} character to uncomment this line, and change the -number 256 to affect the number of file descriptors available to -@code{mysqld}. - -@code{ulimit} (and @code{open-files-limit}) can increase the number of -file descriptors, but only up to the limit imposed by the operating -system. There is also a 'hard' limit that can only be overrided if you -start @code{safe_mysqld} or @code{mysqld} as root (Just remember that -you need to also use the @code{--user=..} option in this case). If you -need to increase the OS limit on the number of file descriptors -available to each process, consult the documentation for your operating -system. - -Note that if you run the @code{tcsh} shell, @code{ulimit} will not work! -@code{tcsh} will also report incorrect values when you ask for the current -limits! In this case you should start @code{safe_mysqld} with @code{sh}! - -@findex DATE -@cindex DATE columns, problems -@cindex problems, @code{DATE} columns -@node Using DATE, Timezone problems, Not enough file handles, Problems -@section Problems Using @code{DATE} Columns - -The format of a @code{DATE} value is @code{'YYYY-MM-DD'}. According to ANSI -SQL, no other format is allowed. You should use this format in @code{UPDATE} -expressions and in the WHERE clause of @code{SELECT} statements. For -example: - -@example -mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; -@end example - -As a convenience, @strong{MySQL} automatically converts a date to a number if -the date is used in a numeric context (and vice versa). It is also smart -enough to allow a ``relaxed'' string form when updating and in a @code{WHERE} -clause that compares a date to a @code{TIMESTAMP}, @code{DATE}, or a -@code{DATETIME} column. (Relaxed form means that any punctuation character -may be used as the separator between parts. For example, @code{'1998-08-15'} -and @code{'1998#08#15'} are equivalent.) @strong{MySQL} can also convert a -string containing no separators (such as @code{'19980815'}), provided it -makes sense as a date. - -The special date @code{'0000-00-00'} can be stored and retrieved as -@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through -@strong{MyODBC}, it will automatically be converted to @code{NULL} in -@strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of -date. - -Because @strong{MySQL} performs the conversions described above, the following -statements work: - -@example -mysql> INSERT INTO tbl_name (idate) VALUES (19970505); -mysql> INSERT INTO tbl_name (idate) VALUES ('19970505'); -mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00'); - -mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05'; -mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505; -mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505; -mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505'; -@end example - -@noindent -However, the following will not work: - -@example -mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; -@end example - -@code{STRCMP()} is a string function, so it converts @code{idate} to -a string and performs a string comparison. It does not convert -@code{'19970505'} to a date and perform a date comparison. - -Note that @strong{MySQL} does no checking whether or not the date is -correct. If you store an incorrect date, such as @code{'1998-2-31'}, the -wrong date will be stored. If the date cannot be converted to any reasonable -value, a @code{0} is stored in the @code{DATE} field. This is mainly a speed -issue and we think it is up to the application to check the dates, and not -the server. - -@cindex timezone problems -@cindex problems, timezone -@tindex TZ environment variable -@tindex Environment variable, TZ -@node Timezone problems, Case sensitivity, Using DATE, Problems -@section Time Zone Problems - -If you have a problem with @code{SELECT NOW()} returning values in GMT and -not your local time, you have to set the @code{TZ} environment variable to -your current time zone. This should be done for the environment in which -the server runs, for example, in @code{safe_mysqld} or @code{mysql.server}. -@xref{Environment variables}. - -@cindex case sensitivity, in searches -@cindex searching, and case-sensitivity -@cindex Chinese -@cindex Big5 Chinese character encoding -@node Case sensitivity, Problems with NULL, Timezone problems, Problems -@section Case Sensitivity in Searches - -By default, @strong{MySQL} searches are case-insensitive (although there are -some character sets that are never case insensitive, such as @code{czech}). -That means that if you search with @code{col_name LIKE 'a%'}, you will get all -column values that start with @code{A} or @code{a}. If you want to make this -search case-sensitive, use something like @code{INDEX(col_name, "A")=0} to -check a prefix. Or use @code{STRCMP(col_name, "A") = 0} if the column value -must be exactly @code{"A"}. - -Simple comparison operations (@code{>=, >, = , < , <=}, sorting and -grouping) are based on each character's ``sort value''. Characters with -the same sort value (like E, e and é) are treated as the same character! - -In older @strong{MySQL} versions @code{LIKE} comparisons where done on -the uppercase value of each character (E == e but E <> é). In newer -@strong{MySQL} versions @code{LIKE} works just like the other comparison -operators. - -If you want a column always to be treated in case-sensitive fashion, -declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{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. - -@cindex @code{NULL} values, vs. empty values -@tindex NULL -@node Problems with NULL, Problems with alias, Case sensitivity, Problems -@section Problems with @code{NULL} Values - -The concept of the @code{NULL} value is a common source of confusion for -newcomers to SQL, who often think that @code{NULL} is the same thing as an -empty string @code{''}. This is not the case! For example, the following -statements are completely different: - -@example -mysql> INSERT INTO my_table (phone) VALUES (NULL); -mysql> INSERT INTO my_table (phone) VALUES (""); -@end example - -Both statements insert a value into the @code{phone} column, but the first -inserts a @code{NULL} value and the second inserts an empty string. The -meaning of the first can be regarded as ``phone number is not known'' and the -meaning of the second can be regarded as ``she has no phone''. - -In SQL, the @code{NULL} value is always false in comparison to any -other value, even @code{NULL}. An expression that contains @code{NULL} -always produces a @code{NULL} value unless otherwise indicated in -the documentation for the operators and functions involved in the -expression. All columns in the following example return @code{NULL}: - -@example -mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); -@end example - -If you want to search for column values that are @code{NULL}, you -cannot use the @code{=NULL} test. The following statement returns no -rows, because @code{expr = NULL} is FALSE, for any expression: - -@example -mysql> SELECT * FROM my_table WHERE phone = NULL; -@end example - -To look for @code{NULL} values, you must use the @code{IS NULL} test. -The following shows how to find the @code{NULL} phone number and the -empty phone number: - -@example -mysql> SELECT * FROM my_table WHERE phone IS NULL; -mysql> SELECT * FROM my_table WHERE phone = ""; -@end example - -In @strong{MySQL}, as in many other SQL servers, you can't index -columns that can have @code{NULL} values. You must declare such columns -@code{NOT NULL}. Conversely, you cannot insert @code{NULL} into an indexed -column. - -@findex LOAD DATA INFILE -When reading data with @code{LOAD DATA INFILE}, empty columns are updated -with @code{''}. If you want a @code{NULL} value in a column, you should use -@code{\N} in the text file. The literal word @code{'NULL'} may also be used -under some circumstances. -@xref{LOAD DATA, , @code{LOAD DATA}}. - -When using @code{ORDER BY}, @code{NULL} values are presented first. If you -sort in descending order using @code{DESC}, @code{NULL} values are presented -last. When using @code{GROUP BY}, all @code{NULL} values are regarded as -equal. - -To help with @code{NULL} handling, you can use the @code{IS NULL} and -@code{IS NOT NULL} operators and the @code{IFNULL()} function. - -@cindex @code{TIMESTAMP}, and @code{NULL} values -@cindex @code{AUTO_INCREMENT}, and @code{NULL} values -@cindex @code{NULL} values, and @code{TIMESTAMP} columns -@cindex @code{NULL} values, and @code{AUTO_INCREMENT} columns -For some column types, @code{NULL} values are handled specially. If you -insert @code{NULL} into the first @code{TIMESTAMP} column of a table, the -current date and time is inserted. If you insert @code{NULL} into an -@code{AUTO_INCREMENT} column, the next number in the sequence is inserted. - -@tindex alias -@node Problems with alias, Deleting from related tables, Problems with NULL, Problems -@section Problems with @code{alias} - -You can use an alias to refer to a column in the @code{GROUP BY}, -@code{ORDER BY}, or in the @code{HAVING} part. Aliases can also be used -to give columns better names: - -@example -SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; -SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; -SELECT id AS "Customer identity" FROM table_name; -@end example - -Note that ANSI SQL doesn't allow you to refer to an alias in a -@code{WHERE} clause. This is because when the @code{WHERE} code is -executed the column value may not yet be determined. For example, the -following query is @strong{illegal}: - -@example -SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; -@end example - -The @code{WHERE} statement is executed to determine which rows should -be included in the @code{GROUP BY} part while @code{HAVING} is used to -decide which rows from the result set should be used. - -@cindex deleting, rows -@cindex rows, deleting -@cindex tables, deleting rows -@node Deleting from related tables, No matching rows, Problems with alias, Problems -@section Deleting Rows from Related Tables - -As @strong{MySQL} doesn't support sub-selects or use of more than one table -in the @code{DELETE} statement, you should use the following approach to -delete rows from 2 related tables: - -@enumerate -@item -@code{SELECT} the rows based on some @code{WHERE} condition in the main table. -@item -@code{DELETE} the rows in the main table based on the same condition. -@item -@code{DELETE FROM related_table WHERE related_column IN (selected_rows)}. -@end enumerate - -If the total number of characters in the query with -@code{related_column} is more than 1,048,576 (the default value of -@code{max_allowed_packet}, you should split it into smaller parts and -execute multiple @code{DELETE} statements. You will probably get the -fastest @code{DELETE} by only deleting 100-1000 @code{related_column} -id's per query if the @code{related_column} is an index. If the -@code{related_column} isn't an index, the speed is independent of the -number of arguments in the @code{IN} clause. - -@cindex no matching rows -@cindex rows, matching problems -@node No matching rows, ALTER TABLE problems, Deleting from related tables, Problems -@section Solving Problems with No Matching Rows - -If you have a complicated query that has many tables and that doesn't -return any rows, you should use the following procedure to find out what -is wrong with your query: - -@enumerate -@item -Test the query with @code{EXPLAIN} and check if you can find something that is -obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. - -@item -Select only those fields that are used in the @code{WHERE} clause. - -@item -Remove one table at a time from the query until it returns some rows. -If the tables are big, it's a good idea to use @code{LIMIT 10} with the query. - -@item -Do a @code{SELECT} for the column that should have matched a row against -the table that was last removed from the query. - -@item -If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that -have decimals, you can't use @code{=}! This problem is common in most -computer languages because floating-point values are not exact values: - -@example -mysql> SELECT * FROM table_name WHERE float_column=3.5; - -> -mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55; -@end example - -In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! - -@item -If you still can't figure out what's wrong, create a minimal test that can -be run with @code{mysql test < query.sql} that shows your problems. -You can create a test file with @code{mysqldump --quick database tables > query.sql}. Open the file in an editor, remove some insert lines (if there are -too many of these), and add your select statement at the end of the file. - -Test that you still have your problem by doing: - -@example -shell> mysqladmin create test2 -shell> mysql test2 < query.sql -@end example - -Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. -@end enumerate - -@tindex ALTER TABLE -@node ALTER TABLE problems, Change column order, No matching rows, Problems -@section Problems with @code{ALTER TABLE}. - -@code{ALTER TABLE} changes a table to the current character set. -If you during @code{ALTER TABLE} get a duplicate key error, then the cause -is either that the new character sets maps to keys to the same value -or that the table is corrupted, in which case you should run -@code{REPAIR TABLE} on the table. - -If @code{ALTER TABLE} dies with an error like this: - -@example -Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) -@end example - -the problem may be that @strong{MySQL} has crashed in a previous @code{ALTER -TABLE} and there is an old table named @file{A-something} or -@file{B-something} lying around. In this case, go to the @strong{MySQL} data -directory and delete all files that have names starting with @code{A-} or -@code{B-}. (You may want to move them elsewhere instead of deleting them.) - -@code{ALTER TABLE} works the following way: - -@itemize @bullet -@item Create a new table named @file{A-xxx} with the requested changes. -@item All rows from the old table are copied to @file{A-xxx}. -@item The old table is renamed @file{B-xxx}. -@item @file{A-xxx} is renamed to your old table name. -@item @file{B-xxx} is deleted. -@end itemize - -If something goes wrong with the renaming operation, @strong{MySQL} tries to -undo the changes. If something goes seriously wrong (this shouldn't happen, -of course), @strong{MySQL} may leave the old table as @file{B-xxx}, but a -simple rename on the system level should get your data back. - -@cindex reordering, columns -@cindex columns, changing -@cindex changing, column order -@cindex tables, changing column order -@node Change column order, Temporary table problems, ALTER TABLE problems, Problems -@section How To Change the Order of Columns in a Table - -The whole point of SQL is to abstract the application from the data -storage format. You should always specify the order in which you wish to -retrieve your data. For example: - -@example -SELECT col_name1, col_name2, col_name3 FROM tbl_name; -@end example - -will return columns in the order @code{col_name1}, @code{col_name2}, @code{col_name3}, whereas: - -@example -SELECT col_name1, col_name3, col_name2 FROM tbl_name; -@end example - -will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. - -You should @strong{NEVER}, in an application, use @code{SELECT *} and -retrieve the columns based on their position, because the order in which -columns are returned @strong{CANNOT} be guaranteed over time. A simple -change to your database may cause your application to fail rather -dramatically. - -If you want to change the order of columns anyway, you can do it as follows: - -@enumerate -@item -Create a new table with the columns in the right order. -@item -Execute -@code{INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table}. -@item -Drop or rename @code{old_table}. -@item -@code{ALTER TABLE new_table RENAME old_table}. -@end enumerate - -@cindex temporary tables, problems -@node Temporary table problems, , Change column order, Problems -@section TEMPORARY TABLE problems - -The following are a list of the limitations with @code{TEMPORARY TABLES}. - -@itemize @bullet -@item -A temporary table can only be of type @code{HEAP}, @code{ISAM} or -@code{MyISAM}. -@item -You can't use temporary tables more than once in the same query. -For example, the following doesn't work. - -@example -select * from temporary_table, temporary_table as t2; -@end example - -We plan to fix the above in 4.0. -@item -You can't use @code{RENAME} on a @code{TEMPORARY} table. -Note that @code{ALTER TABLE org_name RENAME new_name} works! - -We plan to fix the above in 4.0. -@end itemize - -@cindex problems, solving -@cindex solving, problems -@cindex databases, replicating -@node Common problems, Clients, Problems, Top -@chapter Solving Some Common Problems with MySQL - -@cindex replication -@menu -* Log Replication:: Database replication with update log -@end menu - -In this chapter, you will find information to solve some of the more common -tasks with @strong{MySQL}. This includes making backups, running more than -one @strong{MySQL} server daemon on a single machine, and replicating a -database using the update or binary logs. - -@cindex database replication -@cindex replication, database -@node Log Replication, , Common problems, Common problems -@section Database Replication with Update Log - -Now that master-slave internal replication is available starting in -Version 3.23.15, using the update log to implement replications is not -recommended. @xref{Replication}. - -However, it is still possible to replicate a database by using the -update log or the binary log. @xref{Update log}. This requires one -database that acts as a master (to which data changes are made) and one -or more other databases that act as slaves. To update a slave, just run -@code{mysql < update_log.*} or @code{mysqlbinlog binary_log.* | mysql}. -Supply host, user, and password options that are appropriate for the -slave database, and use the update log from the master database as -input. - -If you never delete anything from a table, you can use a @code{TIMESTAMP} -column to find out which rows have been inserted or changed in the table -since the last replication (by comparing the time when you did the -replication last time) and only copy these rows to the mirror. - -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 conflicts when the same data have been changed in -both ends. You probably want to keep the old version to help with -deciding what has been updated. - -Because replication in this case is done with SQL statements, you should not -use the following functions in statements that update the database; they may -not return the same value as in the original database: - -@itemize @bullet -@item @code{DATABASE()} -@item @code{GET_LOCK()} and @code{RELEASE_LOCK()} -@item @code{RAND()} -@item @code{USER()}, @code{SYSTEM_USER()} or @code{SESSION_USER()} -@item @code{VERSION()}, @code{CONNECT_ID()} -@end itemize - -All time functions are safe to use, as the timestamp is sent to the -mirror if needed. @code{LAST_INSERT_ID()} is also safe to use. - - -@node Clients, MySQL internals, Common problems, Top +@node Clients, Extending MySQL, Table types, Top @chapter MySQL APIs @cindex client tools @@ -40008,14 +37224,15 @@ mirror if needed. @code{LAST_INSERT_ID()} is also safe to use. @cindex library, @code{mysqlclient} @menu -* C:: @strong{MySQL} C API -* Perl:: @strong{MySQL} Perl API -* Eiffel:: @strong{MySQL} Eiffel wrapper -* Java:: @strong{MySQL} Java connectivity (JDBC) * PHP:: @strong{MySQL} PHP API +* Perl:: @strong{MySQL} Perl API +* ODBC:: +* C:: @strong{MySQL} C API * Cplusplus:: @strong{MySQL} C++ APIs +* Java:: @strong{MySQL} Java connectivity (JDBC) * Python:: @strong{MySQL} Python APIs * Tcl:: @strong{MySQL} Tcl APIs +* Eiffel:: @strong{MySQL} Eiffel wrapper @end menu This chapter describes the APIs available for @strong{MySQL}, where to get @@ -40023,2825 +37240,50 @@ them, and how to use them. The C API is the most extensively covered, as it was developed by the @strong{MySQL} team, and is the basis for most of the other APIs. -@cindex C API, datatypes -@cindex datatypes, C API -@node C, Perl, Clients, Clients -@section MySQL C API + +@node PHP, Perl, Clients, Clients +@section MySQL PHP API + +@cindex PHP API + +PHP is a server-side, HTML-embedded scripting language that may be used to +create dynamic Web pages. It contains support for accessing several +databases, including @strong{MySQL}. PHP may be run as a separate program +or compiled as a module for use with the Apache Web server. + +The distribution and documentation are available at the +@uref{http://www.php.net/, PHP web site}. @menu -* C API datatypes:: C API Datatypes -* C API function overview:: C API Function Overview -* C API functions:: C API Function Descriptions -* C API problems:: -* Thread-safe clients:: +* PHP problems:: Common problems with MySQL and PHP @end menu -The C API code is distributed with @strong{MySQL}. It is included in the -@code{mysqlclient} library and allows C programs to access a database. - -Many of the clients in the @strong{MySQL} source distribution are -written in C. If you are looking for examples that demonstrate how to -use the C API, take a look at these clients. You can find these in the -@code{clients} directory in the @strong{MySQL} source distribution. - -Most of the other client APIs (all except Java) use the @code{mysqlclient} -library to communicate with the @strong{MySQL} server. This means that, for -example, you can take advantage of many of the same environment variables -that are used by other client programs, because they are referenced from the -library. See @ref{Client-Side Scripts}, for a list of these variables. - -The client has a maximum communication buffer size. The size of the buffer -that is allocated initially (16K bytes) is automatically increased up to the -maximum size (the maximum is 16M). Because buffer sizes are increased -only as demand warrants, simply increasing the default maximum limit does not -in itself cause more resources to be used. This size check is mostly a check -for erroneous queries and communication packets. - -The communication buffer must be large enough to contain a single SQL -statement (for client-to-server traffic) and one row of returned data (for -server-to-client traffic). Each thread's communication buffer is dynamically -enlarged to handle any query or row up to the maximum limit. For example, if -you have @code{BLOB} values that contain up to 16M of data, you must have a -communication buffer limit of at least 16M (in both server and client). The -client's default maximum is 16M, but the default maximum in the server is -1M. You can increase this by changing the value of the -@code{max_allowed_packet} parameter when the server is started. @xref{Server -parameters}. - -The @strong{MySQL} server shrinks each communication buffer to -@code{net_buffer_length} bytes after each query. For clients, the size of -the buffer associated with a connection is not decreased until the connection -is closed, at which time client memory is reclaimed. - -For programming with threads, consult the 'how to make a thread-safe -client' chapter. @xref{Thread-safe clients}. - -@node C API datatypes, C API function overview, C, C -@subsection C API Datatypes -@table @code - -@tindex MYSQL C type -@item MYSQL -This structure represents a handle to one database connection. It is -used for almost all @strong{MySQL} functions. - -@tindex MYSQL_RES C type -@item MYSQL_RES -This structure represents the result of a query that returns rows -(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). The -information returned from a query is called the @emph{result set} in the -remainder of this section. - -@tindex MYSQL_ROW C type -@item MYSQL_ROW -This is a type-safe representation of one row of data. It is currently -implemented as an array of counted byte strings. (You cannot treat these as -null-terminated strings if field values may contain binary data, because such -values may contain null bytes internally.) Rows are obtained by calling -@code{mysql_fetch_row()}. - -@tindex MYSQL_FIELD C type -@item MYSQL_FIELD -This structure contains information about a field, such as the field's -name, type, and size. Its members are described in more detail below. -You may obtain the @code{MYSQL_FIELD} structures for each field by -calling @code{mysql_fetch_field()} repeatedly. Field values are not part of -this structure; they are contained in a @code{MYSQL_ROW} structure. - - -@tindex MYSQL_FIELD_OFFSET C type -@item MYSQL_FIELD_OFFSET -This is a type-safe representation of an offset into a @strong{MySQL} field -list. (Used by @code{mysql_field_seek()}.) Offsets are field numbers -within a row, beginning at zero. - -@tindex my_ulonglong C type -@tindex my_ulonglong values, printing -@item my_ulonglong -The type used for the number of rows and for @code{mysql_affected_rows()}, -@code{mysql_num_rows()}, and @code{mysql_insert_id()}. This type provides a -range of @code{0} to @code{1.84e19}. - -On some systems, attempting to print a value of type @code{my_ulonglong} -will not work. To print such a value, convert it to @code{unsigned long} -and use a @code{%lu} print format. Example: -@example -printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result)); -@end example -@end table - -@noindent -The @code{MYSQL_FIELD} structure contains the members listed below: - -@table @code -@item char * name -The name of the field, as a null-terminated string. - -@item char * table -The name of the table containing this field, if it isn't a calculated field. -For calculated fields, the @code{table} value is an empty string. - -@item char * def -The default value of this field, as a null-terminated string. This is set -only if you use @code{mysql_list_fields()}. - -@item enum enum_field_types type -The type of the field. -The @code{type} value may be one of the following: - -@multitable @columnfractions .3 .55 -@item @strong{Type value} @tab @strong{Type meaning} -@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT} field -@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT} field -@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER} field -@item @code{FIELD_TYPE_INT24} @tab @code{MEDIUMINT} field -@item @code{FIELD_TYPE_LONGLONG} @tab @code{BIGINT} field -@item @code{FIELD_TYPE_DECIMAL} @tab @code{DECIMAL} or @code{NUMERIC} field -@item @code{FIELD_TYPE_FLOAT} @tab @code{FLOAT} field -@item @code{FIELD_TYPE_DOUBLE} @tab @code{DOUBLE} or @code{REAL} field -@item @code{FIELD_TYPE_TIMESTAMP} @tab @code{TIMESTAMP} field -@item @code{FIELD_TYPE_DATE} @tab @code{DATE} field -@item @code{FIELD_TYPE_TIME} @tab @code{TIME} field -@item @code{FIELD_TYPE_DATETIME} @tab @code{DATETIME} field -@item @code{FIELD_TYPE_YEAR} @tab @code{YEAR} field -@item @code{FIELD_TYPE_STRING} @tab String (@code{CHAR} or @code{VARCHAR}) field -@item @code{FIELD_TYPE_BLOB} @tab @code{BLOB} or @code{TEXT} field (use @code{max_length} to determine the maximum length) -@item @code{FIELD_TYPE_SET} @tab @code{SET} field -@item @code{FIELD_TYPE_ENUM} @tab @code{ENUM} field -@item @code{FIELD_TYPE_NULL} @tab @code{NULL}-type field -@item @code{FIELD_TYPE_CHAR} @tab Deprecated; use @code{FIELD_TYPE_TINY} instead -@end multitable - -You can use the @code{IS_NUM()} macro to test whether or not a field has a -numeric type. Pass the @code{type} value to @code{IS_NUM()} and it -will evaluate to TRUE if the field is numeric: - -@example -if (IS_NUM(field->type)) - printf("Field is numeric\n"); -@end example - -@item unsigned int length -The width of the field, as specified in the table definition. - -@item unsigned int max_length -The maximum width of the field for the result set (the length of the longest -field value for the rows actually in the result set). If you use -@code{mysql_store_result()} or @code{mysql_list_fields()}, this contains the -maximum length for the field. If you use @code{mysql_use_result()}, the -value of this variable is zero. - -@item unsigned int flags -Different bit-flags for the field. The @code{flags} value may have zero -or more of the following bits set: - -@multitable @columnfractions .3 .55 -@item @strong{Flag value} @tab @strong{Flag meaning} -@item @code{NOT_NULL_FLAG} @tab Field can't be @code{NULL} -@item @code{PRI_KEY_FLAG} @tab Field is part of a primary key -@item @code{UNIQUE_KEY_FLAG} @tab Field is part of a unique key -@item @code{MULTIPLE_KEY_FLAG} @tab Field is part of a non-unique key -@item @code{UNSIGNED_FLAG} @tab Field has the @code{UNSIGNED} attribute -@item @code{ZEROFILL_FLAG} @tab Field has the @code{ZEROFILL} attribute -@item @code{BINARY_FLAG} @tab Field has the @code{BINARY} attribute -@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT} -attribute -@item @code{ENUM_FLAG} @tab Field is an @code{ENUM} (deprecated) -@item @code{BLOB_FLAG} @tab Field is a @code{BLOB} or @code{TEXT} (deprecated) -@item @code{TIMESTAMP_FLAG} @tab Field is a @code{TIMESTAMP} (deprecated) -@end multitable - -Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, and @code{TIMESTAMP_FLAG} -flags is deprecated because they indicate the type of a field rather -than an attribute of its type. It is preferable to test -@code{field->type} against @code{FIELD_TYPE_BLOB}, -@code{FIELD_TYPE_ENUM}, or @code{FIELD_TYPE_TIMESTAMP} instead. - -@noindent -The example below illustrates a typical use of the @code{flags} value: - -@example -if (field->flags & NOT_NULL_FLAG) - printf("Field can't be null\n"); -@end example - -You may use the following convenience macros to determine the boolean -status of the @code{flags} value: - -@multitable @columnfractions .3 .5 -@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL} -@item @code{IS_PRI_KEY(flags)} @tab True if this field is a primary key -@item @code{IS_BLOB(flags)} @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead) -@end multitable - -@item unsigned int decimals -The number of decimals for numeric fields. -@end table - -@cindex C API, functions -@cindex functions, C API -@node C API function overview, C API functions, C API datatypes, C -@subsection C API Function Overview - -The functions available in the C API are listed below and are described in -greater detail in the next section. -@xref{C API functions}. - -@multitable @columnfractions .3 .7 -@item @strong{mysql_affected_rows()} @tab -Returns the number of rows changed/deleted/inserted by the last @code{UPDATE}, -@code{DELETE}, or @code{INSERT} query. - -@item @strong{mysql_close()} @tab -Closes a server connection. - -@item @strong{mysql_connect()} @tab -Connects to a @strong{MySQL} server. This function is deprecated; use -@code{mysql_real_connect()} instead. - -@item @strong{mysql_change_user()} @tab -Changes user and database on an open connection. - -@item @strong{mysql_character_set_name()} @tab -Returns the name of the default character set for the connection. - -@item @strong{mysql_create_db()} @tab -Creates a database. This function is deprecated; use the SQL command -@code{CREATE DATABASE} instead. - -@item @strong{mysql_data_seek()} @tab -Seeks to an arbitrary row in a query result set. - -@item @strong{mysql_debug()} @tab -Does a @code{DBUG_PUSH} with the given string. - -@item @strong{mysql_drop_db()} @tab -Drops a database. This function is deprecated; use the SQL command -@code{DROP DATABASE} instead. - -@item @strong{mysql_dump_debug_info()} @tab -Makes the server write debug information to the log. - -@item @strong{mysql_eof()} @tab -Determines whether or not the last row of a result set has been read. -This function is deprecated; @code{mysql_errno()} or @code{mysql_error()} -may be used instead. - -@item @strong{mysql_errno()} @tab -Returns the error number for the most recently invoked @strong{MySQL} function. - -@item @strong{mysql_error()} @tab -Returns the error message for the most recently invoked @strong{MySQL} function. - -@item @strong{mysql_real_escape_string()} @tab -Escapes special characters in a string for use in a SQL statement taking -into account the current charset of the connection. - -@item @strong{mysql_escape_string()} @tab -Escapes special characters in a string for use in a SQL statement. - -@item @strong{mysql_fetch_field()} @tab -Returns the type of the next table field. - -@item @strong{mysql_fetch_field_direct()} @tab -Returns the type of a table field, given a field number. - -@item @strong{mysql_fetch_fields()} @tab -Returns an array of all field structures. - -@item @strong{mysql_fetch_lengths()} @tab -Returns the lengths of all columns in the current row. - -@item @strong{mysql_fetch_row()} @tab -Fetches the next row from the result set. - -@item @strong{mysql_field_seek()} @tab -Puts the column cursor on a specified column. - -@item @strong{mysql_field_count()} @tab -Returns the number of result columns for the most recent query. - -@item @strong{mysql_field_tell()} @tab -Returns the position of the field cursor used for the last -@code{mysql_fetch_field()}. - -@item @strong{mysql_free_result()} @tab -Frees memory used by a result set. - -@item @strong{mysql_get_client_info()} @tab -Returns client version information. - -@item @strong{mysql_get_host_info()} @tab -Returns a string describing the connection. - -@item @strong{mysql_get_proto_info()} @tab -Returns the protocol version used by the connection. - -@item @strong{mysql_get_server_info()} @tab -Returns the server version number. - -@item @strong{mysql_info()} @tab -Returns information about the most recently executed query. - -@item @strong{mysql_init()} @tab -Gets or initializes a @code{MYSQL} structure. - -@item @strong{mysql_insert_id()} @tab -Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous -query. - -@item @strong{mysql_kill()} @tab -Kills a given thread. - -@item @strong{mysql_list_dbs()} @tab -Returns database names matching a simple regular expression. - -@item @strong{mysql_list_fields()} @tab -Returns field names matching a simple regular expression. - -@item @strong{mysql_list_processes()} @tab -Returns a list of the current server threads. - -@item @strong{mysql_list_tables()} @tab -Returns table names matching a simple regular expression. - -@item @strong{mysql_num_fields()} @tab -Returns the number of columns in a result set. - -@item @strong{mysql_num_rows()} @tab -Returns the number of rows in a result set. - -@item @strong{mysql_options()} @tab -Sets connect options for @code{mysql_connect()}. - -@item @strong{mysql_ping()} @tab -Checks whether or not the connection to the server is working, reconnecting -as necessary. - -@item @strong{mysql_query()} @tab -Executes a SQL query specified as a null-terminated string. - -@item @strong{mysql_real_connect()} @tab -Connects to a @strong{MySQL} server. - -@item @strong{mysql_real_query()} @tab -Executes a SQL query specified as a counted string. - -@item @strong{mysql_reload()} @tab -Tells the server to reload the grant tables. - -@item @strong{mysql_row_seek()} @tab -Seeks to a row in a result set, using value returned from -@code{mysql_row_tell()}. - -@item @strong{mysql_row_tell()} @tab -Returns the row cursor position. - -@item @strong{mysql_select_db()} @tab -Selects a database. - -@item @strong{mysql_shutdown()} @tab -Shuts down the database server. - -@item @strong{mysql_stat()} @tab -Returns the server status as a string. - -@item @strong{mysql_store_result()} @tab -Retrieves a complete result set to the client. - -@item @strong{mysql_thread_id()} @tab -Returns the current thread ID. - -@item @strong{mysql_thread_save()} @tab -Returns 1 if the clients are compiled as thread-safe. - -@item @strong{mysql_use_result()} @tab -Initiates a row-by-row result set retrieval. -@end multitable - -To connect to the server, call @code{mysql_init()} to initialize a -connection handler, then call @code{mysql_real_connect()} with that -handler (along with other information such as the hostname, user name, -and password). Upon connection, @code{mysql_real_connect()} sets the -@code{reconnect} flag (part of the MYSQL structure) to a value of -@code{1}. This flag indicates, in the event that a query cannot be -performed because of a lost connection, to try reconnecting to the -server before giving up. When you are done with the connection, call -@code{mysql_close()} to terminate it. - -While a connection is active, the client may send SQL queries to the server -using @code{mysql_query()} or @code{mysql_real_query()}. The difference -between the two is that @code{mysql_query()} expects the query to be -specified as a null-terminated string whereas @code{mysql_real_query()} -expects a counted string. If the string contains binary data (which may -include null bytes), you must use @code{mysql_real_query()}. - -For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE}, -@code{DELETE}), you can find out how many rows were changed (affected) -by calling @code{mysql_affected_rows()}. - -For @code{SELECT} queries, you retrieve the selected rows as a result set. -(Note that some statements are @code{SELECT}-like in that they return rows. -These include @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}. They should -be treated the same way as @code{SELECT} statements.) - -There are two ways for a client to process result sets. One way is to -retrieve the entire result set all at once by calling -@code{mysql_store_result()}. This function acquires from the server all the -rows returned by the query and stores them in the client. The second way is -for the client to initiate a row-by-row result set retrieval by calling -@code{mysql_use_result()}. This function initializes the retrieval, but does -not actually get any rows from the server. - -In both cases, you access rows by calling @code{mysql_fetch_row()}. With -@code{mysql_store_result()}, @code{mysql_fetch_row()} accesses rows that have -already been fetched from the server. With @code{mysql_use_result()}, -@code{mysql_fetch_row()} actually retrieves the row from the server. -Information about the size of the data in each row is available by -calling @code{mysql_fetch_lengths()}. - -After you are done with a result set, call @code{mysql_free_result()} -to free the memory used for it. - -The two retrieval mechanisms are complementary. Client programs should -choose the approach that is most appropriate for their requirements. -In practice, clients tend to use @code{mysql_store_result()} more -commonly. - -An advantage of @code{mysql_store_result()} is that because the rows have all -been fetched to the client, you not only can access rows sequentially, you -can move back and forth in the result set using @code{mysql_data_seek()} or -@code{mysql_row_seek()} to change the current row position within the result -set. You can also find out how many rows there are by calling -@code{mysql_num_rows()}. On the other hand, the memory requirements for -@code{mysql_store_result()} may be very high for large result sets and you -are more likely to encounter out-of-memory conditions. - -An advantage of @code{mysql_use_result()} is that the client requires less -memory for the result set because it maintains only one row at a time (and -because there is less allocation overhead, @code{mysql_use_result()} can be -faster). Disadvantages are that you must process each row quickly to avoid -tying up the server, you don't have random access to rows within the result -set (you can only access rows sequentially), and you don't know how many rows -are in the result set until you have retrieved them all. Furthermore, you -@emph{must} retrieve all the rows even if you determine in mid-retrieval that -you've found the information you were looking for. - -The API makes it possible for clients to respond appropriately to -queries (retrieving rows only as necessary) without knowing whether or -not the query is a @code{SELECT}. You can do this by calling -@code{mysql_store_result()} after each @code{mysql_query()} (or -@code{mysql_real_query()}). If the result set call succeeds, the query -was a @code{SELECT} and you can read the rows. If the result set call -fails, call @code{mysql_field_count()} to determine whether or not a -result was actually to be expected. If @code{mysql_field_count()} -returns zero, the query returned no data (indicating that it was an -@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not -expected to return rows. If @code{mysql_field_count()} is non-zero, the -query should have returned rows, but didn't. This indicates that the -query was a @code{SELECT} that failed. See the description for -@code{mysql_field_count()} for an example of how this can be done. - -Both @code{mysql_store_result()} and @code{mysql_use_result()} allow you to -obtain information about the fields that make up the result set (the number -of fields, their names and types, etc.). You can access field information -sequentially within the row by calling @code{mysql_fetch_field()} repeatedly, -or by field number within the row by calling -@code{mysql_fetch_field_direct()}. The current field cursor position may be -changed by calling @code{mysql_field_seek()}. Setting the field cursor -affects subsequent calls to @code{mysql_fetch_field()}. You can also get -information for fields all at once by calling @code{mysql_fetch_fields()}. - -For detecting and reporting errors, @strong{MySQL} provides access to error -information by means of the @code{mysql_errno()} and @code{mysql_error()} -functions. These return the error code or error message for the most -recently invoked function that can succeed or fail, allowing you to determine -when an error occurred and what it was. - -@node C API functions, C API problems, C API function overview, C -@subsection C API Function Descriptions - -@menu -* mysql_affected_rows:: @code{mysql_affected_rows()} -* mysql_close:: @code{mysql_close()} -* mysql_connect:: @code{mysql_connect()} -* mysql_change_user:: @code{mysql_change_user()} -* mysql_character_set_name:: @code{mysql_character_set_name()} -* mysql_create_db:: @code{mysql_create_db()} -* mysql_data_seek:: @code{mysql_data_seek()} -* mysql_debug:: @code{mysql_debug()} -* mysql_drop_db:: @code{mysql_drop_db()} -* mysql_dump_debug_info:: @code{mysql_dump_debug_info()} -* mysql_eof:: @code{mysql_eof()} -* mysql_errno:: @code{mysql_errno()} -* mysql_error:: @code{mysql_error()} -* mysql_escape_string:: @code{mysql_escape_string()} -* mysql_fetch_field:: @code{mysql_fetch_field()} -* mysql_fetch_fields:: @code{mysql_fetch_fields()} -* mysql_fetch_field_direct:: @code{mysql_fetch_field_direct()} -* mysql_fetch_lengths:: @code{mysql_fetch_lengths()} -* mysql_fetch_row:: @code{mysql_fetch_row()} -* mysql_field_count:: @code{mysql_field_count()} -* mysql_field_seek:: @code{mysql_field_seek()} -* mysql_field_tell:: @code{mysql_field_tell()} -* mysql_free_result:: @code{mysql_free_result()} -* mysql_get_client_info:: @code{mysql_get_client_info()} -* mysql_get_host_info:: @code{mysql_get_host_info()} -* mysql_get_proto_info:: @code{mysql_get_proto_info()} -* mysql_get_server_info:: @code{mysql_get_server_info()} -* mysql_info:: @code{mysql_info()} -* mysql_init:: @code{mysql_init()} -* mysql_insert_id:: @code{mysql_insert_id()} -* mysql_kill:: @code{mysql_kill()} -* mysql_list_dbs:: @code{mysql_list_dbs()} -* mysql_list_fields:: @code{mysql_list_fields()} -* mysql_list_processes:: @code{mysql_list_processes()} -* mysql_list_tables:: @code{mysql_list_tables()} -* mysql_num_fields:: @code{mysql_num_fields()} -* mysql_num_rows:: @code{mysql_num_rows()} -* mysql_options:: @code{mysql_options()} -* mysql_ping:: @code{mysql_ping()} -* mysql_query:: @code{mysql_query()} -* mysql_real_connect:: @code{mysql_real_connect()} -* mysql_real_escape_string:: @code{mysql_real_escape_string()} -* mysql_real_query:: @code{mysql_real_query()} -* mysql_reload:: @code{mysql_reload()} -* mysql_row_seek:: @code{mysql_row_seek()} -* mysql_row_tell:: @code{mysql_row_tell()} -* mysql_select_db:: @code{mysql_select_db()} -* mysql_shutdown:: @code{mysql_shutdown()} -* mysql_stat:: @code{mysql_stat()} -* mysql_store_result:: @code{mysql_store_result()} -* mysql_thread_id:: @code{mysql_thread_id()} -* mysql_use_result:: @code{mysql_use_result()} -@end menu - -In the descriptions below, a parameter or return value of @code{NULL} means -@code{NULL} in the sense of the C programming language, not a -@strong{MySQL} @code{NULL} value. - -Functions that return a value generally return a pointer or an integer. -Unless specified otherwise, functions returning a pointer return a -non-@code{NULL} value to indicate success or a @code{NULL} value to indicate -an error, and functions returning an integer return zero to indicate success -or non-zero to indicate an error. Note that ``non-zero'' means just that. -Unless the function description says otherwise, do not test against a value -other than zero: - -@example -if (result) /* correct */ - ... error ... - -if (result < 0) /* incorrect */ - ... error ... - -if (result == -1) /* incorrect */ - ... error ... -@end example - -When a function returns an error, the @strong{Errors} subsection of the -function description lists the possible types of errors. You can -find out which of these occurred by calling @code{mysql_errno()}. -A string representation of the error may be obtained by calling -@code{mysql_error()}. - -@findex @code{mysql_affected_rows()} -@node mysql_affected_rows, mysql_close, C API functions, C API functions -@subsubsection @code{mysql_affected_rows()} - -@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} - -@subsubheading Description - -Returns the number of rows changed by the last @code{UPDATE}, deleted by -the last @code{DELETE} or inserted by the last @code{INSERT} -statement. May be called immediately after @code{mysql_query()} for -@code{UPDATE}, @code{DELETE}, or @code{INSERT} statements. For -@code{SELECT} statements, @code{mysql_affected_rows()} works like -@code{mysql_num_rows()}. - -@subsubheading Return Values - -An integer greater than zero indicates the number of rows affected or -retrieved. Zero indicates that no records where updated for an -@code{UPDATE} statement, no rows matched the @code{WHERE} clause in the -query or that no query has yet been executed. -1 indicates that the -query returned an error or that, for a @code{SELECT} query, -@code{mysql_affected_rows()} was called prior to calling -@code{mysql_store_result()}. - -@subsubheading Errors - -None. - -@subsubheading Example - -@example -mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); -printf("%ld products updated",(long) mysql_affected_rows(&mysql)); -@end example - -If one specifies the flag @code{CLIENT_FOUND_ROWS} when connecting to -@code{mysqld}, @code{mysql_affected_rows()} will return the number of -rows matched by the @code{WHERE} statement for @code{UPDATE} statements. - -Note that when one uses a @code{REPLACE} command, -@code{mysql_affected_rows()} will return 2 if the new row replaced and -old row. This is because in this case one row was inserted and then the -duplicate was deleted. - -@findex @code{mysql_close()} -@node mysql_close, mysql_connect, mysql_affected_rows, C API functions -@subsubsection @code{mysql_close()} - -@code{void mysql_close(MYSQL *mysql)} - -@subsubheading Description -Closes a previously opened connection. @code{mysql_close()} also deallocates -the connection handle pointed to by @code{mysql} if the handle was allocated -automatically by @code{mysql_init()} or @code{mysql_connect()}. - -@subsubheading Return Values - -None. - -@subsubheading Errors - -None. - -@findex @code{mysql_connect()} -@node mysql_connect, mysql_change_user, mysql_close, C API functions -@subsubsection @code{mysql_connect()} - -@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} - -@subsubheading Description - -This function is deprecated. It is preferable to use -@code{mysql_real_connect()} instead. - -@code{mysql_connect()} attempts to establish a connection to a @strong{MySQL} -database engine running on @code{host}. @code{mysql_connect()} must complete -successfully before you can execute any of the other API functions, with the -exception of @code{mysql_get_client_info()}. - -The meanings of the parameters are the same as for the corresponding -parameters for @code{mysql_real_connect()} with the difference that the -connection parameter may be @code{NULL}. In this case the C API -allocates memory for the connection structure automatically and frees it -when you call @code{mysql_close()}. The disadvantage of this approach is -that you can't retrieve an error message if the connection fails. (To -get error information from @code{mysql_errno()} or @code{mysql_error()}, -you must provide a valid @code{MYSQL} pointer.) - -@subsubheading Return Values - -Same as for @code{mysql_real_connect()}. - -@subsubheading Errors - -Same as for @code{mysql_real_connect()}. - -@findex @code{mysql_change_user()} -@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions -@subsubsection @code{mysql_change_user()} - -@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const -char *password, const char *db)} - -@subsubheading Description - -Changes the user and causes the database specified by @code{db} to -become the default (current) database on the connection specified by -@code{mysql}. In subsequent queries, this database is the default for -table references that do not include an explicit database specifier. - -This function was introduced in @strong{MySQL} Version 3.23.3. - -@code{mysql_change_user()} fails unless the connected user can be -authenticated or if he doesn't have permission to use the database. In -this case the user and database are not changed - -The @code{db} parameter may be set to @code{NULL} if you don't want to have a -default database. - -@subsubheading Return values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -The same that you can get from @code{mysql_real_connect()}. - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@item ER_UNKNOWN_COM_ERROR -The @strong{MySQL} server doesn't implement this command (probably an old server) -@item ER_ACCESS_DENIED_ERROR -The user or password was wrong. -@item ER_BAD_DB_ERROR -The database didn't exist. -@item ER_DBACCESS_DENIED_ERROR -The user did not have access rights to the database. -@item ER_WRONG_DB_NAME -The database name was too long. -@end table - -@subsubheading Example - -@example -if (mysql_change_user(&mysql, "user", "password", "new_database")) -@{ - fprintf(stderr, "Failed to change user. Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_character_set_name()} -@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions -@subsubsection @code{mysql_character_set_name()} - -@code{const char *mysql_character_set_name(MYSQL *mysql)} - -@subsubheading Description - -Returns the default character set for the current connection. - -@subsubheading Return Values - -The default character set - -@subsubheading Errors -None. - - -@findex @code{mysql_create_db()} -@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions -@subsubsection @code{mysql_create_db()} - -@code{int mysql_create_db(MYSQL *mysql, const char *db)} - -@subsubheading Description -Creates the database named by the @code{db} parameter. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{CREATE DATABASE} statement instead. - -@subsubheading Return Values - -Zero if the database was created successfully. Non-zero if an error -occurred. - -@subsubheading Errors -@table @code - -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. - -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. - -@item CR_SERVER_LOST -The connection to the server was lost during the query. - -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -if(mysql_create_db(&mysql, "my_database")) -@{ - fprintf(stderr, "Failed to create new database. Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_data_seek()} -@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions -@subsubsection @code{mysql_data_seek()} - -@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} - -@subsubheading Description -Seeks to an arbitrary row in a query result set. This requires that the -result set structure contains the entire result of the query, so -@code{mysql_data_seek()} may be used in conjunction only with -@code{mysql_store_result()}, not with @code{mysql_use_result()}. - -The offset should be a value in the range from 0 to -@code{mysql_num_rows(result)-1}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@findex @code{mysql_debug()} -@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions -@subsubsection @code{mysql_debug()} - -@code{void mysql_debug(char *debug)} - -@subsubheading Description -Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the -Fred Fish debug library. To use this function, you must compile the client -library to support debugging. -@xref{Debugging server}. @xref{Debugging client}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@subsubheading Example - -The call shown below causes the client library to generate a trace file in -@file{/tmp/client.trace} on the client machine: - -@example -mysql_debug("d:t:O,/tmp/client.trace"); -@end example - -@findex @code{mysql_drop_db()} -@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions -@subsubsection @code{mysql_drop_db()} - -@code{int mysql_drop_db(MYSQL *mysql, const char *db)} - -@subsubheading Description -Drops the database named by the @code{db} parameter. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{DROP DATABASE} statement instead. - -@subsubheading Return Values - -Zero if the database was dropped successfully. Non-zero if an error -occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -if(mysql_drop_db(&mysql, "my_database")) - fprintf(stderr, "Failed to drop the database: Error: %s\n", - mysql_error(&mysql)); -@end example - -@findex @code{mysql_dump_debug_info()} -@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions -@subsubsection @code{mysql_dump_debug_info()} - -@code{int mysql_dump_debug_info(MYSQL *mysql)} - -@subsubheading Description - -Instructs the server to write some debug information to the log. The -connected user must have the @strong{process} privilege for this to work. - -@subsubheading Return values - -Zero if the command was successful. Non-zero if an error occurred. - -@subsubheading Errors -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_eof()} -@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions -@subsubsection @code{mysql_eof()} - -@code{my_bool mysql_eof(MYSQL_RES *result)} - -@subsubheading Description - -This function is deprecated. @code{mysql_errno()} or @code{mysql_error()} -may be used instead. - -@code{mysql_eof()} determines whether or not the last row of a result -set has been read. - -If you acquire a result set from a successful call to -@code{mysql_store_result()}, the client receives the entire set in one -operation. In this case, a @code{NULL} return from @code{mysql_fetch_row()} -always means the end of the result set has been reached and it is -unnecessary to call @code{mysql_eof()}. - -On the other hand, if you use @code{mysql_use_result()} to initiate a result -set retrieval, the rows of the set are obtained from the server one by one as -you call @code{mysql_fetch_row()} repeatedly. Because an error may occur on -the connection during this process, a @code{NULL} return value from -@code{mysql_fetch_row()} does not necessarily mean the end of the result set -was reached normally. In this case, you can use @code{mysql_eof()} to -determine what happened. @code{mysql_eof()} returns a non-zero value if the -end of the result set was reached and zero if an error occurred. - -Historically, @code{mysql_eof()} predates the standard @strong{MySQL} error -functions @code{mysql_errno()} and @code{mysql_error()}. Because those error -functions provide the same information, their use is preferred over -@code{mysql_eof()}, which is now deprecated. (In fact, they provide more -information, because @code{mysql_eof()} returns only a boolean value whereas -the error functions indicate a reason for the error when one occurs.) - -@subsubheading Return Values - -Zero if no error occurred. Non-zero if the end of the result set has been -reached. - -@subsubheading Errors -None. - -@subsubheading Example - -The following example shows how you might use @code{mysql_eof()}: - -@example -mysql_query(&mysql,"SELECT * FROM some_table"); -result = mysql_use_result(&mysql); -while((row = mysql_fetch_row(result))) -@{ - // do something with data -@} -if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error -@{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); -@} -@end example - -However, you can achieve the same effect with the standard @strong{MySQL} -error functions: - -@example -mysql_query(&mysql,"SELECT * FROM some_table"); -result = mysql_use_result(&mysql); -while((row = mysql_fetch_row(result))) -@{ - // do something with data -@} -if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error -@{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_errno()} -@node mysql_errno, mysql_error, mysql_eof, C API functions -@subsubsection @code{mysql_errno()} - -@code{unsigned int mysql_errno(MYSQL *mysql)} - -@subsubheading Description - -For the connection specified by @code{mysql}, @code{mysql_errno()} returns -the error code for the most recently invoked API function that can succeed -or fail. A return value of zero means that no error occurred. Client error -message numbers are listed in the @strong{MySQL} @file{errmsg.h} header file. -Server error message numbers are listed in @file{mysqld_error.h}. In the -@strong{MySQL} source distribution you can find a complete list of -error messages and error numbers in the file @file{Docs/mysqld_error.txt}. - -@subsubheading Return Values - -An error code value. Zero if no error occurred. - -@subsubheading Errors -None. - -@findex @code{mysql_error()} -@node mysql_error, mysql_escape_string, mysql_errno, C API functions -@subsubsection @code{mysql_error()} - -@code{char *mysql_error(MYSQL *mysql)} - -@subsubheading Description - -For the connection specified by @code{mysql}, @code{mysql_error()} returns -the error message for the most recently invoked API function that can succeed -or fail. An empty string (@code{""}) is returned if no error occurred. -This means the following two tests are equivalent: - -@example -if(mysql_errno(&mysql)) -@{ - // an error occurred -@} - -if(mysql_error(&mysql)[0] != '\0') -@{ - // an error occurred -@} -@end example - -The language of the client error messages may be changed by -recompiling the @strong{MySQL} client library. Currently you can choose -error messages in several different languages. -@xref{Languages}. - -@subsubheading Return Values - -A character string that describes the error. An empty string if no error -occurred. - -@subsubheading Errors -None. - -@findex @code{mysql_escape_string()} -@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions -@subsubsection @code{mysql_escape_string()} - -You should use @code{mysql_real_escape_string()} instead! - -This is identical to @code{mysql_real_escape_string()} except that it -takes the connection as the first -argument. @code{mysql_real_escape_string()} will escape the string -according to the current character set while -@code{mysql_escape_string()} does not respect the current charset -setting. - -@findex @code{mysql_fetch_field()} -@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions -@subsubsection @code{mysql_fetch_field()} - -@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} - -@subsubheading Description - -Returns the definition of one column of a result set as a @code{MYSQL_FIELD} -structure. Call this function repeatedly to retrieve information about all -columns in the result set. @code{mysql_fetch_field()} returns @code{NULL} -when no more fields are left. - -@code{mysql_fetch_field()} is reset to return information about the first -field each time you execute a new @code{SELECT} query. The field returned by -@code{mysql_fetch_field()} is also affected by calls to -@code{mysql_field_seek()}. - -If you've called @code{mysql_query()} to perform a @code{SELECT} on a table -but have not called @code{mysql_store_result()}, @strong{MySQL} returns the -default blob length (8K bytes) if you call @code{mysql_fetch_field()} to ask -for the length of a @code{BLOB} field. (The 8K size is chosen because -@strong{MySQL} doesn't know the maximum length for the @code{BLOB}. This -should be made configurable sometime.) Once you've retrieved the result set, -@code{field->max_length} contains the length of the largest value for this -column in the specific query. - -@subsubheading Return Values - -The @code{MYSQL_FIELD} structure for the current column. @code{NULL} -if no columns are left. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_FIELD *field; - -while((field = mysql_fetch_field(result))) -@{ - printf("field name %s\n", field->name); -@} -@end example - -@findex @code{mysql_fetch_fields()} -@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions -@subsubsection @code{mysql_fetch_fields()} - -@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} - -@subsubheading Description - -Returns an array of all @code{MYSQL_FIELD} structures for a result set. -Each structure provides the field definition for one column of the result -set. - -@subsubheading Return Values - -An array of @code{MYSQL_FIELD} structures for all columns of a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -unsigned int num_fields; -unsigned int i; -MYSQL_FIELD *fields; - -num_fields = mysql_num_fields(result); -fields = mysql_fetch_fields(result); -for(i = 0; i < num_fields; i++) -@{ - printf("Field %u is %s\n", i, fields[i].name); -@} -@end example - -@findex @code{mysql_fetch_field_direct()} -@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions -@subsubsection @code{mysql_fetch_field_direct()} - -@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} - -@subsubheading Description - -Given a field number @code{fieldnr} for a column within a result set, returns -that column's field definition as a @code{MYSQL_FIELD} structure. You may use -this function to retrieve the definition for an arbitrary column. The value -of @code{fieldnr} should be in the range from 0 to -@code{mysql_num_fields(result)-1}. - -@subsubheading Return Values - -The @code{MYSQL_FIELD} structure for the specified column. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -unsigned int num_fields; -unsigned int i; -MYSQL_FIELD *field; - -num_fields = mysql_num_fields(result); -for(i = 0; i < num_fields; i++) -@{ - field = mysql_fetch_field_direct(result, i); - printf("Field %u is %s\n", i, field->name); -@} -@end example - -@findex @code{mysql_fetch_lengths()} -@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions -@subsubsection @code{mysql_fetch_lengths()} - -@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} - -@subsubheading Description - -Returns the lengths of the columns of the current row within a result set. -If you plan to copy field values, this length information is also useful for -optimization, because you can avoid calling @code{strlen()}. In addition, if -the result set contains binary data, you @emph{must} use this function to -determine the size of the data, because @code{strlen()} returns incorrect -results for any field containing null characters. - -The length for empty columns and for columns containing @code{NULL} values is -zero. To see how to distinguish these two cases, see the description for -@code{mysql_fetch_row()}. - -@subsubheading Return Values - -An array of unsigned long integers representing the size of each column (not -including any terminating null characters). -@code{NULL} if an error occurred. - -@subsubheading Errors -@code{mysql_fetch_lengths()} is valid only for the current row of the result -set. It returns @code{NULL} if you call it before calling -@code{mysql_fetch_row()} or after retrieving all rows in the result. - -@subsubheading Example - -@example -MYSQL_ROW row; -unsigned long *lengths; -unsigned int num_fields; -unsigned int i; - -row = mysql_fetch_row(result); -if (row) -@{ - num_fields = mysql_num_fields(result); - lengths = mysql_fetch_lengths(result); - for(i = 0; i < num_fields; i++) - @{ - printf("Column %u is %lu bytes in length.\n", i, lengths[i]); - @} -@} -@end example - -@findex @code{mysql_fetch_row()} -@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions -@subsubsection @code{mysql_fetch_row()} - -@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} - -@subsubheading Description - -Retrieves the next row of a result set. When used after -@code{mysql_store_result()}, @code{mysql_fetch_row()} returns @code{NULL} -when there are no more rows to retrieve. When used after -@code{mysql_use_result()}, @code{mysql_fetch_row()} returns @code{NULL} when -there are no more rows to retrieve or if an error occurred. - -The number of values in the row is given by @code{mysql_num_fields(result)}. -If @code{row} holds the return value from a call to @code{mysql_fetch_row()}, -pointers to the values are accessed as @code{row[0]} to -@code{row[mysql_num_fields(result)-1]}. @code{NULL} values in the row are -indicated by @code{NULL} pointers. - -The lengths of the field values in the row may be obtained by calling -@code{mysql_fetch_lengths()}. Empty fields and fields containing -@code{NULL} both have length 0; you can distinguish these by checking -the pointer for the field value. If the pointer is @code{NULL}, the field -is @code{NULL}; otherwise the field is empty. - -@subsubheading Return Values - -A @code{MYSQL_ROW} structure for the next row. @code{NULL} if -there are no more rows to retrieve or if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -MYSQL_ROW row; -unsigned int num_fields; -unsigned int i; - -num_fields = mysql_num_fields(result); -while ((row = mysql_fetch_row(result))) -@{ - unsigned long *lengths; - lengths = mysql_fetch_lengths(result); - for(i = 0; i < num_fields; i++) - @{ - printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); - @} - printf("\n"); -@} -@end example - -@findex @code{mysql_field_count()} -@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions -@subsubsection @code{mysql_field_count()} - -@code{unsigned int mysql_field_count(MYSQL *mysql)} - -If you are using a version of @strong{MySQL} earlier than Version 3.22.24, you -should use @code{unsigned int mysql_num_fields(MYSQL *mysql)} instead. - -@subsubheading Description - -Returns the number of columns for the most recent query on the connection. - -The normal use of this function is when @code{mysql_store_result()} -returned @code{NULL} (and thus you have no result set pointer). -In this case, you can call @code{mysql_field_count()} to -determine whether or not @code{mysql_store_result()} should have produced a -non-empty result. This allows the client program to take proper action -without knowing whether or not the query was a @code{SELECT} (or -@code{SELECT}-like) statement. The example shown below illustrates how this -may be done. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -An unsigned integer representing the number of fields in a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_RES *result; -unsigned int num_fields; -unsigned int num_rows; - -if (mysql_query(&mysql,query_string)) -@{ - // error -@} -else // query succeeded, process any data returned by it -@{ - result = mysql_store_result(&mysql); - if (result) // there are rows - @{ - num_fields = mysql_num_fields(result); - // retrieve rows, then call mysql_free_result(result) - @} - else // mysql_store_result() returned nothing; should it have? - @{ - if(mysql_field_count(&mysql) == 0) - @{ - // query does not return data - // (it was not a SELECT) - num_rows = mysql_affected_rows(&mysql); - @} - else // mysql_store_result() should have returned data - @{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); - @} - @} -@} -@end example - -An alternative is to replace the @code{mysql_field_count(&mysql)} call with -@code{mysql_errno(&mysql)}. In this case, you are checking directly for an -error from @code{mysql_store_result()} rather than inferring from the value -of @code{mysql_field_count()} whether or not the statement was a -@code{SELECT}. - -@findex @code{mysql_field_seek()} -@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions -@subsubsection @code{mysql_field_seek()} - -@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} - -@subsubheading Description - -Sets the field cursor to the given offset. The next call to -@code{mysql_fetch_field()} will retrieve the field definition of the column -associated with that offset. - -To seek to the beginning of a row, pass an @code{offset} value of zero. - -@subsubheading Return Values - -The previous value of the field cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_field_tell()} -@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions -@subsubsection @code{mysql_field_tell()} - -@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} - -@subsubheading Description - -Returns the position of the field cursor used for the last -@code{mysql_fetch_field()}. This value can be used as an argument to -@code{mysql_field_seek()}. - -@subsubheading Return Values - -The current offset of the field cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_free_result()} -@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions -@subsubsection @code{mysql_free_result()} - -@code{void mysql_free_result(MYSQL_RES *result)} - -@subsubheading Description - -Frees the memory allocated for a result set by @code{mysql_store_result()}, -@code{mysql_use_result()}, @code{mysql_list_dbs()}, etc. When you are done -with a result set, you must free the memory it uses by calling -@code{mysql_free_result()}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@findex @code{mysql_get_client_info()} -@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions -@subsubsection @code{mysql_get_client_info()} - -@code{char *mysql_get_client_info(void)} - -@subsubheading Description - -Returns a string that represents the client library version. - -@subsubheading Return Values - -A character string that represents the @strong{MySQL} client library version. - -@subsubheading Errors -None. - -@findex @code{mysql_get_host_info()} -@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions -@subsubsection @code{mysql_get_host_info()} - -@code{char *mysql_get_host_info(MYSQL *mysql)} - -@subsubheading Description - -Returns a string describing the type of connection in use, including the -server host name. - -@subsubheading Return Values - -A character string representing the server host name and the connection type. - -@subsubheading Errors -None. - -@findex @code{mysql_get_proto_info()} -@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions -@subsubsection @code{mysql_get_proto_info()} - -@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} - -@subsubheading Description - -Returns the protocol version used by current connection. - -@subsubheading Return Values - -An unsigned integer representing the protocol version used by the current -connection. - -@subsubheading Errors -None. - -@findex @code{mysql_get_server_info()} -@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions -@subsubsection @code{mysql_get_server_info()} - -@code{char *mysql_get_server_info(MYSQL *mysql)} - -@subsubheading Description - -Returns a string that represents the server version number. - -@subsubheading Return Values - -A character string that represents the server version number. - -@subsubheading Errors -None. - -@findex @code{mysql_info()} -@node mysql_info, mysql_init, mysql_get_server_info, C API functions -@subsubsection @code{mysql_info()} - -@code{char *mysql_info(MYSQL *mysql)} - -@subsubheading Description - -Retrieves a string providing information about the most recently executed -query, but only for the statements listed below. For other statements, -@code{mysql_info()} returns @code{NULL}. The format of the string varies -depending on the type of query, as described below. The numbers are -illustrative only; the string will contain values appropriate for the query. - -@table @code -@item INSERT INTO ... SELECT ... -String format: @code{Records: 100 Duplicates: 0 Warnings: 0} -@item INSERT INTO ... VALUES (...),(...),(...)... -String format: @code{Records: 3 Duplicates: 0 Warnings: 0} -@item LOAD DATA INFILE ... -String format: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0} -@item ALTER TABLE -String format: @code{Records: 3 Duplicates: 0 Warnings: 0} -@item UPDATE -String format: @code{Rows matched: 40 Changed: 40 Warnings: 0} -@end table - -Note that @code{mysql_info()} returns a non-@code{NULL} value for the -@code{INSERT ... VALUES} statement only if multiple value lists are -specified in the statement. - -@subsubheading Return Values - -A character string representing additional information about the most -recently executed query. @code{NULL} if no information is available for the -query. - -@subsubheading Errors -None. - -@findex @code{mysql_init()} -@node mysql_init, mysql_insert_id, mysql_info, C API functions -@subsubsection @code{mysql_init()} - -@code{MYSQL *mysql_init(MYSQL *mysql)} - -@subsubheading Description - -Allocates or initializes a @code{MYSQL} object suitable for -@code{mysql_real_connect()}. If @code{mysql} is a @code{NULL} pointer, the -function allocates, initializes, and returns a new object. Otherwise the -object is initialized and the address of the object is returned. If -@code{mysql_init()} allocates a new object, it will be freed when -@code{mysql_close()} is called to close the connection. - -@subsubheading Return Values - -An initialized @code{MYSQL*} handle. @code{NULL} if there was -insufficient memory to allocate a new object. - -@subsubheading Errors -In case of insufficient memory, @code{NULL} is returned. - -@findex @code{mysql_insert_id()} -@node mysql_insert_id, mysql_kill, mysql_init, C API functions -@subsubsection @code{mysql_insert_id()} - -@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} - -@subsubheading Description - -Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous -query. Use this function after you have performed an @code{INSERT} query -into a table that contains an @code{AUTO_INCREMENT} field. - -Note that @code{mysql_insert_id()} returns @code{0} if the previous query -does not generate an @code{AUTO_INCREMENT} value. If you need to save -the value for later, be sure to call @code{mysql_insert_id()} immediately -after the query that generates the value. - -Also note that the value of the SQL @code{LAST_INSERT_ID()} function always -contains the most recently generated @code{AUTO_INCREMENT} value, and is -not reset between queries because the value of that function is maintained -in the server. - -@subsubheading Return Values - -The value of the @code{AUTO_INCREMENT} field that was updated by the previous -query. Returns zero if there was no previous query on the connection or if -the query did not update an @code{AUTO_INCREMENT} value. - -@subsubheading Errors -None. - -@findex @code{mysql_kill()} -@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions -@subsubsection @code{mysql_kill()} - -@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} - -@subsubheading Description - -Asks the server to kill the thread specified by @code{pid}. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_dbs()} -@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions -@subsubsection @code{mysql_list_dbs()} - -@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of database names on the server that match -the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all databases. Calling -@code{mysql_list_dbs()} is similar to executing the query @code{SHOW -databases [LIKE wild]}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_fields()} -@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions -@subsubsection @code{mysql_list_fields()} - -@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of field names in the given table that match -the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all fields. Calling -@code{mysql_list_fields()} is similar to executing the query @code{SHOW -COLUMNS FROM tbl_name [LIKE wild]}. - -Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} -instead of @code{mysql_list_fields()}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_processes()} -@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions -@subsubsection @code{mysql_list_processes()} - -@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} - -@subsubheading Description - -Returns a result set describing the current server threads. This is the same -kind of information as that reported by @code{mysqladmin processlist} or -a @code{SHOW PROCESSLIST} query. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_tables()} -@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions -@subsubsection @code{mysql_list_tables()} - -@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of table names in the current database that -match the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all tables. Calling -@code{mysql_list_tables()} is similar to executing the query @code{SHOW -tables [LIKE wild]}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_num_fields()} -@findex @code{mysql_field_count()} -@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions -@subsubsection @code{mysql_num_fields()} - -@code{unsigned int mysql_num_fields(MYSQL_RES *result)} - -or - -@code{unsigned int mysql_num_fields(MYSQL *mysql)} - -The second form doesn't work on @strong{MySQL} Version 3.22.24 or newer. To pass a -@code{MYSQL*} argument, you must use -@code{unsigned int mysql_field_count(MYSQL *mysql)} instead. - -@subsubheading Description - -Returns the number of columns in a result set. - -Note that you can get the number of columns either from a pointer to a result -set or to a connection handle. You would use the connection handle if -@code{mysql_store_result()} or @code{mysql_use_result()} returned -@code{NULL} (and thus you have no result set pointer). In this case, you can -call @code{mysql_field_count()} to determine whether or not -@code{mysql_store_result()} should have produced a non-empty result. This -allows the client program to take proper action without knowing whether or -not the query was a @code{SELECT} (or @code{SELECT}-like) statement. The -example shown below illustrates how this may be done. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -An unsigned integer representing the number of fields in a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_RES *result; -unsigned int num_fields; -unsigned int num_rows; - -if (mysql_query(&mysql,query_string)) -@{ - // error -@} -else // query succeeded, process any data returned by it -@{ - result = mysql_store_result(&mysql); - if (result) // there are rows - @{ - num_fields = mysql_num_fields(result); - // retrieve rows, then call mysql_free_result(result) - @} - else // mysql_store_result() returned nothing; should it have? - @{ - if (mysql_errno(&mysql)) - @{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); - @} - else if (mysql_field_count(&mysql) == 0) - @{ - // query does not return data - // (it was not a SELECT) - num_rows = mysql_affected_rows(&mysql); - @} - @} -@} -@end example - -An alternative (if you KNOW that your query should have returned a result set) -is to replace the @code{mysql_errno(&mysql)} call with a check if -@code{mysql_field_count(&mysql)} is = 0. This will only happen if something -went wrong. - -@findex @code{mysql_num_rows()} -@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions -@subsubsection @code{mysql_num_rows()} - -@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} - -@subsubheading Description - -Returns the number of rows in the result set. - -The use of @code{mysql_num_rows()} depends on whether you use -@code{mysql_store_result()} or @code{mysql_use_result()} to return the result -set. If you use @code{mysql_store_result()}, @code{mysql_num_rows()} may be -called immediately. If you use @code{mysql_use_result()}, -@code{mysql_num_rows()} will not return the correct value until all the rows -in the result set have been retrieved. - -@subsubheading Return Values - -The number of rows in the result set. - -@subsubheading Errors -None. - -@findex @code{mysql_options()} -@node mysql_options, mysql_ping, mysql_num_rows, C API functions -@subsubsection @code{mysql_options()} - -@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} - -@subsubheading Description - -Can be used to set extra connect options and affect behavior for a connection. -This function may be called multiple times to set several options. - -@code{mysql_options()} should be called after @code{mysql_init()} and before -@code{mysql_connect()} or @code{mysql_real_connect()}. - -The @code{option} argument is the option that you want to set; the @code{arg} -argument is the value for the option. If the option is an integer, then -@code{arg} should point to the value of the integer. - -Possible options values: - -@multitable @columnfractions .25 .25 .5 -@item @strong{Option} @tab @strong{Argument type} @tab @strong{Function} -@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds. -@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol. -@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a @strong{MySQL} server on NT. -@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the @strong{MySQL} server. Will automatically be re-executed when reconnecting. -@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}. -@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Read options from the named group from @file{my.cnf} or the file specified with @code{MYSQL_READ_DEFAULT_FILE}. -@end multitable - -Note that the group @code{client} is always read if you use -@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. - -The specified group in the option file may contain the following options: - -@multitable @columnfractions .3 .7 -@item @code{connect_timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server. -@item @code{compress} @tab Use the compressed client/server protocol. -@item @code{database} @tab Connect to this database if no database was specified in the connect command. -@item @code{debug} @tab Debug options. -@item @code{host} @tab Default host name. -@item @code{init-command} @tab Command to execute when connecting to @strong{MySQL} server. Will automatically be re-executed when reconnecting. -@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}. -@item @code{password} @tab Default password. -@item @code{pipe} @tab Use named pipes to connect to a @strong{MySQL} server on NT. -@item @code{port} @tab Default port number. -@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}. -@item @code{socket} @tab Default socket number. -@item -@item @code{user} @tab Default user. -@end multitable - -Note that @code{timeout} has been replaced by @code{connect_timeout}, but -@code{timeout} will still work for a while. - -For more information about option files, see @ref{Option files}. - -@subsubheading Return Values - -Zero for success. Non-zero if you used an unknown option. - -@subsubheading Example - -@example -MYSQL mysql; - -mysql_init(&mysql); -mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); -mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); -if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) -@{ - fprintf(stderr, "Failed to connect to database: Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -The above requests the client to use the compressed client/server protocol and -read the additional options from the @code{odbc} section in the @code{my.cnf} -file. - -@findex @code{mysql_ping()} -@node mysql_ping, mysql_query, mysql_options, C API functions -@subsubsection @code{mysql_ping()} - -@code{int mysql_ping(MYSQL *mysql)} - -@subsubheading Description - -Checks whether or not the connection to the server is working. If it has gone -down, an automatic reconnection is attempted. - -This function can be used by clients that remain idle for a long while, -to check whether or not the server has closed the connection and reconnect -if necessary. - -@subsubheading Return Values - -Zero if the server is alive. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_query()} -@node mysql_query, mysql_real_connect, mysql_ping, C API functions -@subsubsection @code{mysql_query()} - -@code{int mysql_query(MYSQL *mysql, const char *query)} - -@subsubheading Description -Executes the SQL query pointed to by the null-terminated string @code{query}. -The query must consist of a single SQL statement. You should not add -a terminating semicolon (@samp{;}) or @code{\g} to the statement. - -@code{mysql_query()} cannot be used for queries that contain binary data; you -should use @code{mysql_real_query()} instead. (Binary data may contain the -@samp{\0} character, which @code{mysql_query()} interprets as the end of the -query string.) - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, , @code{mysql_field_count}}. - -@subsubheading Return Values - -Zero if the query was successful. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_real_connect()} -@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions -@subsubsection @code{mysql_real_connect()} - -@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, - const char *user, const char *passwd, const char *db, - unsigned int port, const char *unix_socket, - unsigned int client_flag)} - -@subsubheading Description - -@code{mysql_real_connect()} attempts to establish a connection to a -@strong{MySQL} database engine running on @code{host}. -@code{mysql_real_connect()} must complete successfully before you can execute -any of the other API functions, with the exception of -@code{mysql_get_client_info()}. - -The parameters are specified as follows: +@node PHP problems, , PHP, PHP +@subsection Common Problems with MySQL and PHP @itemize @bullet -@item -The first parameter should be the address of an existing @code{MYSQL} -structure. Before calling @code{mysql_real_connect()} you must call -@code{mysql_init()} to initialize the @code{MYSQL} structure. You can -change a lot of connect options with the @code{mysql_options()} -call. @xref{mysql_options}. - -@item -The value of @code{host} may be either a hostname or an IP address. If -@code{host} is @code{NULL} or the string @code{"localhost"}, a connection to -the local host is assumed. If the OS supports sockets (Unix) or named pipes -(Windows), they are used instead of TCP/IP to connect to the server. - -@item -The @code{user} parameter contains the user's @strong{MySQL} login ID. If -@code{user} is @code{NULL}, the current user is assumed. Under Unix, this is -the current login name. Under Windows ODBC, the current user name must be -specified explicitly. -@xref{ODBC administrator}. - -@item -The @code{passwd} parameter contains the password for @code{user}. If -@code{passwd} is @code{NULL}, only entries in the @code{user} table for the -user that have a blank (empty) password field will be checked for a match. This -allows the database administrator to set up the @strong{MySQL} privilege -system in such a way that users get different privileges depending on whether -or not they have specified a password. - -NOTE: Do not attempt to encrypt the password before calling -@code{mysql_real_connect()}; password encryption is handled automatically by -the client API. - -@item -@code{db} is the database name. -If @code{db} is not @code{NULL}, the connection will set the default -database to this value. - -@item -If @code{port} is not 0, the value will be used as the port number -for the TCP/IP connection. Note that the @code{host} parameter -determines the type of the connection. - -@item -If @code{unix_socket} is not @code{NULL}, the string specifies the -socket or named pipe that should be used. Note that the @code{host} -parameter determines the type of the connection. - -@item -The value of @code{client_flag} is usually 0, but can be set to a combination -of the following flags in very special circumstances: - -@multitable @columnfractions .25 .7 -@item @strong{Flag name} @tab @strong{Flag meaning} -@code{mysqld} to be more ODBC-friendly. -@item @code{CLIENT_COMPRESS} @tab Use compression protocol. -@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows. -@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words. -@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection. -@item @code{CLIENT_NO_SCHEMA} @tab Don't allow the @code{db_name.tbl_name.col_name} syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs. -@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes -@item @code{CLIENT_SSL} @tab Use SSL (encrypted protocol). -@end multitable +@item Error: "Maximum Execution Time Exceeded" +This is a PHP limit; Go into the @file{php3.ini} file and set the maximum +execution time up from 30 seconds to something higher, as needed. +It is also not a bad idea to double the ram allowed per script to 16MB instead of +8 MB. +@item Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." +This means that your PHP version isn't compiled with @strong{MySQL} support. +You can either compile a dynamic @strong{MySQL} module and load it into PHP or +recompile PHP with built-in @strong{MySQL} support. This is described in +detail in the PHP manual. +@item Error: "undefined reference to `uncompress'" +This means that the client library is compiled with support for a compressed +client/server protocol. The fix is to add @code{-lz} last when linking +with @code{-lmysqlclient}. @end itemize -@subsubheading Return Values -A @code{MYSQL*} connection handle if the connection was successful, -@code{NULL} if the connection was unsuccessful. For a successful connection, -the return value is the same as the value of the first parameter, unless you -pass @code{NULL} for that parameter. - -@subsubheading Errors - -@table @code -@item CR_CONN_HOST_ERROR -Failed to connect to the @strong{MySQL} server. - -@item CR_CONNECTION_ERROR -Failed to connect to the local @strong{MySQL} server. - -@item CR_IPSOCK_ERROR -Failed to create an IP socket. - -@item CR_OUT_OF_MEMORY -Out of memory. - -@item CR_SOCKET_CREATE_ERROR -Failed to create a Unix socket. - -@item CR_UNKNOWN_HOST -Failed to find the IP address for the hostname. - -@item CR_VERSION_ERROR -A protocol mismatch resulted from attempting to connect to a server with a -client library that uses a different protocol version. This can happen if you -use a very old client library to connect to a new server that wasn't started -with the @code{--old-protocol} option. - -@item CR_NAMEDPIPEOPEN_ERROR -Failed to create a named pipe on Windows. - -@item CR_NAMEDPIPEWAIT_ERROR -Failed to wait for a named pipe on Windows. - -@item CR_NAMEDPIPESETSTATE_ERROR -Failed to get a pipe handler on Windows. - -@item CR_SERVER_LOST -If @code{connect_timeout} > 0 and it took longer then @code{connect_timeout} -seconds to connect to the server or if the server died while executing the -@code{init-command}. - -@end table - -@subsubheading Example - -@example -MYSQL mysql; - -mysql_init(&mysql); -mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); -if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) -@{ - fprintf(stderr, "Failed to connect to database: Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -By using @code{mysql_options()} the @strong{MySQL} library will read the -@code{[client]} and @code{your_prog_name} sections in the @code{my.cnf} -file which will ensure that your program will work, even if someone has -set up @strong{MySQL} in some non-standard way. - -Note that upon connection, @code{mysql_real_connect()} sets the @code{reconnect} -flag (part of the MYSQL structure) to a value of @code{1}. This flag indicates, -in the event that a query cannot be performed because of a lost connection, to -try reconnecting to the server before giving up. - -@findex @code{mysql_real_escape_string()} -@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions -@subsubsection @code{mysql_real_escape_string()} - -@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)} - -@subsubheading Description - -This function is used to create a legal SQL string that you can use in a -SQL statement. @xref{String syntax}. - -The string in @code{from} is encoded to an escaped SQL string, taking -into account the current character set of the connection. The result is placed -in @code{to} and a terminating null byte is appended. Characters -encoded are @code{NUL} (ASCII 0), @samp{\n}, @samp{\r}, @samp{\}, -@samp{'}, @samp{"}, and Control-Z (@pxref{Literals}). - -The string pointed to by @code{from} must be @code{length} bytes long. You -must allocate the @code{to} buffer to be at least @code{length*2+1} bytes -long. (In the worse case, each character may need to be encoded as using two -bytes, and you need room for the terminating null byte.) When -@code{mysql_escape_string()} returns, the contents of @code{to} will be a -null-terminated string. The return value is the length of the encoded -string, not including the terminating null character. - -@subsubheading Example - -@example -char query[1000],*end; - -end = strmov(query,"INSERT INTO test_table values("); -*end++ = '\''; -end += mysql_real_escape_string(&mysql, end,"What's this",11); -*end++ = '\''; -*end++ = ','; -*end++ = '\''; -end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); -*end++ = '\''; -*end++ = ')'; - -if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) -@{ - fprintf(stderr, "Failed to insert row, Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -The @code{strmov()} function used in the example is included in the -@code{mysqlclient} library and works like @code{strcpy()} but returns a -pointer to the terminating null of the first parameter. - -@subsubheading Return Values - -The length of the value placed into @code{to}, not including the -terminating null character. - -@subsubheading Errors -None. - -@findex @code{mysql_real_query()} -@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions -@subsubsection @code{mysql_real_query()} - -@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} - -@subsubheading Description - -Executes the SQL query pointed to by @code{query}, which should be a string -@code{length} bytes long. The query must consist of a single SQL statement. -You should not add a terminating semicolon (@samp{;}) or @code{\g} to the -statement. - -You @emph{must} use @code{mysql_real_query()} rather than -@code{mysql_query()} for queries that contain binary data, because binary data -may contain the @samp{\0} character. In addition, @code{mysql_real_query()} -is faster than @code{mysql_query()} because it does not call @code{strlen()} on -the query string. - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, @code{mysql_field_count}}. - -@subsubheading Return Values - -Zero if the query was successful. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_reload()} -@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions -@subsubsection @code{mysql_reload()} - -@code{int mysql_reload(MYSQL *mysql)} - -@subsubheading Description - -Asks the @strong{MySQL} server to reload the grant tables. The -connected user must have the @strong{reload} privilege. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{FLUSH PRIVILEGES} statement instead. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_row_seek()} -@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions -@subsubsection @code{mysql_row_seek()} - -@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} - -@subsubheading Description -Sets the row cursor to an arbitrary row in a query result set. This requires -that the result set structure contains the entire result of the query, so -@code{mysql_row_seek()} may be used in conjunction only with -@code{mysql_store_result()}, not with @code{mysql_use_result()}. - -The offset should be a value returned from a call to @code{mysql_row_tell()} -or to @code{mysql_row_seek()}. This value is not simply a row number; if you -want to seek to a row within a result set using a row number, use -@code{mysql_data_seek()} instead. - -@subsubheading Return Values - -The previous value of the row cursor. This value may be passed to a -subsequent call to @code{mysql_row_seek()}. - -@subsubheading Errors -None. - -@findex @code{mysql_row_tell()} -@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions -@subsubsection @code{mysql_row_tell()} - -@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} - -@subsubheading Description - -Returns the current position of the row cursor for the last -@code{mysql_fetch_row()}. This value can be used as an argument to -@code{mysql_row_seek()}. - -You should use @code{mysql_row_tell()} only after @code{mysql_store_result()}, -not after @code{mysql_use_result()}. - -@subsubheading Return Values - -The current offset of the row cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_select_db()} -@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions -@subsubsection @code{mysql_select_db()} - -@code{int mysql_select_db(MYSQL *mysql, const char *db)} - -@subsubheading Description - -Causes the database specified by @code{db} to become the default (current) -database on the connection specified by @code{mysql}. In subsequent queries, -this database is the default for table references that do not include an -explicit database specifier. - -@code{mysql_select_db()} fails unless the connected user can be authenticated -as having permission to use the database. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_shutdown()} -@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions -@subsubsection @code{mysql_shutdown()} - -@code{int mysql_shutdown(MYSQL *mysql)} - -@subsubheading Description - -Asks the database server to shut down. The connected user must have -@strong{shutdown} privileges. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_stat()} -@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions -@subsubsection @code{mysql_stat()} - -@code{char *mysql_stat(MYSQL *mysql)} - -@subsubheading Description - -Returns a character string containing information similar to that provided by -the @code{mysqladmin status} command. This includes uptime in seconds and -the number of running threads, questions, reloads, and open tables. - -@subsubheading Return Values - -A character string describing the server status. @code{NULL} if an -error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_store_result()} -@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions -@subsubsection @code{mysql_store_result()} - -@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} - -@subsubheading Description - -You must call @code{mysql_store_result()} or @code{mysql_use_result()} -for every query that successfully retrieves data (@code{SELECT}, -@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). - -You don't have to call @code{mysql_store_result()} or -@code{mysql_use_result()} for other queries, but it will not do any -harm or cause any notable performance if you call @code{mysql_store_result()} -in all cases. You can detect if the query didn't have a result set by -checking if @code{mysql_store_result()} returns 0 (more about this later one). - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, @code{mysql_field_count}}. - -@code{mysql_store_result()} reads the entire result of a query to the client, -allocates a @code{MYSQL_RES} structure, and places the result into this -structure. - -@code{mysql_store_results()} returns a null pointer if the query didn't return -a result set (if the query was, for example, an @code{INSERT} statement). - -@code{mysql_store_results()} also returns a null pointer if reading of the -result set failed. You can check if you got an error by checking if -@code{mysql_error()} doesn't return a null pointer, if -@code{mysql_errno()} returns <> 0, or if @code{mysql_field_count()} -returns <> 0. - -An empty result set is returned if there are no rows returned. (An empty -result set differs from a null pointer as a return value.) - -Once you have called @code{mysql_store_result()} and got a result back -that isn't a null pointer, you may call @code{mysql_num_rows()} to find -out how many rows are in the result set. - -You can call @code{mysql_fetch_row()} to fetch rows from the result set, -or @code{mysql_row_seek()} and @code{mysql_row_tell()} to obtain or -set the current row position within the result set. - -You must call @code{mysql_free_result()} once you are done with the result -set. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result structure with the results. @code{NULL} if -an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_thread_id()} -@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions -@subsubsection @code{mysql_thread_id()} - -@code{unsigned long mysql_thread_id(MYSQL *mysql)} - -@subsubheading Description - -Returns the thread ID of the current connection. This value can be used as -an argument to @code{mysql_kill()} to kill the thread. - -If the connection is lost and you reconnect with @code{mysql_ping()}, the -thread ID will change. This means you should not get the thread ID and store -it for later. You should get it when you need it. - -@subsubheading Return Values - -The thread ID of the current connection. - -@subsubheading Errors -None. - -@findex @code{mysql_use_result()} -@node mysql_use_result, , mysql_thread_id, C API functions -@subsubsection @code{mysql_use_result()} - -@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} - -@subsubheading Description - -You must call @code{mysql_store_result()} or @code{mysql_use_result()} for -every query that successfully retrieves data (@code{SELECT}, @code{SHOW}, -@code{DESCRIBE}, @code{EXPLAIN}). - -@code{mysql_use_result()} initiates a result set retrieval but does not -actually read the result set into the client like @code{mysql_store_result()} -does. Instead, each row must be retrieved individually by making calls to -@code{mysql_fetch_row()}. This reads the result of a query directly from the -server without storing it in a temporary table or local buffer, which is -somewhat faster and uses much less memory than @code{mysql_store_result()}. -The client will only allocate memory for the current row and a communication -buffer that may grow up to @code{max_allowed_packet} bytes. - -On the other hand, you shouldn't use @code{mysql_use_result()} if you are -doing a lot of processing for each row on the client side, or if the output -is sent to a screen on which the user may type a @code{^S} (stop scroll). -This will tie up the server and prevent other threads from updating any -tables from which the data is being fetched. - -When using @code{mysql_use_result()}, you must execute -@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise the -unfetched rows will be returned as part of the result set for your next -query. The C API will give the error @code{Commands out of sync; You can't -run this command now} if you forget to do this! - -You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()}, -@code{mysql_row_tell()}, @code{mysql_num_rows()}, or -@code{mysql_affected_rows()} with a result returned from -@code{mysql_use_result()}, nor may you issue other queries until the -@code{mysql_use_result()} has finished. (However, after you have fetched all -the rows, @code{mysql_num_rows()} will accurately return the number of rows -fetched.) - -You must call @code{mysql_free_result()} once you are done with the result -set. - -@subsubheading Return Values - -A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@node C API problems, Thread-safe clients, C API functions, C -@subsection Common questions and problems when using the C API - -@tindex @code{mysql_query()} -@tindex @code{mysql_store_result()} -@menu -* NULL mysql_store_result:: -* Query results:: -* Getting unique ID:: -* C API linking problems:: -@end menu - -@node NULL mysql_store_result, Query results, C API problems, C API problems -@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?} - -It is possible for @code{mysql_store_result()} to return @code{NULL} -following a successful call to @code{mysql_query()}. When this happens, it -means one of the following conditions occurred: - -@itemize @bullet -@item -There was a @code{malloc()} failure (for example, if the result set was too -large). - -@item -The data couldn't be read (an error occurred on the connection). - -@item -The query returned no data (for example, it was an @code{INSERT}, -@code{UPDATE}, or @code{DELETE}). -@end itemize - -You can always check whether or not the statement should have produced a -non-empty result by calling @code{mysql_field_count()}. If -@code{mysql_field_count()} returns zero, the result is empty and the last -query was a statement that does not return values (for example, an -@code{INSERT} or a @code{DELETE}). If @code{mysql_field_count()} returns a -non-zero value, the statement should have produced a non-empty result. -See the description of the @code{mysql_field_count()} function for an -example. - -You can test for an error by calling @code{mysql_error()} or -@code{mysql_errno()}. - -@cindex queries, C API results -@menu -* Query results:: -* Getting unique ID:: -* C API linking problems:: -@end menu - -@node Query results, Getting unique ID, NULL mysql_store_result, C API problems -@subsubsection What Results Can I Get From a Query? - -In addition to the result set returned by a query, you can also get the -following information: - -@itemize @bullet -@item -@code{mysql_affected_rows()} returns the number of rows affected by the last -query when doing an @code{INSERT}, @code{UPDATE}, or @code{DELETE}. An -exception is that if @code{DELETE} is used without a @code{WHERE} clause, the -table is re-created empty, which is much faster! In this case, -@code{mysql_affected_rows()} returns zero for the number of records -affected. - -@item -@code{mysql_num_rows()} returns the number of rows in a result set. With -@code{mysql_store_result()}, @code{mysql_num_rows()} may be called as soon as -@code{mysql_store_result()} returns. With @code{mysql_use_result()}, -@code{mysql_num_rows()} may be called only after you have fetched all the -rows with @code{mysql_fetch_row()}. - -@item -@code{mysql_insert_id()} returns the ID generated by the last -query that inserted a row into a table with an @code{AUTO_INCREMENT} index. -@xref{mysql_insert_id, , @code{mysql_insert_id()}}. - -@item -Some queries (@code{LOAD DATA INFILE ...}, @code{INSERT INTO -... SELECT ...}, @code{UPDATE}) return additional information. The result is -returned by @code{mysql_info()}. See the description for @code{mysql_info()} -for the format of the string that it returns. @code{mysql_info()} returns a -@code{NULL} pointer if there is no additional information. -@end itemize - -@cindex unique ID -@cindex last row, unique ID -@cindex ID, unique -@cindex tables, unique ID for last row -@node Getting unique ID, C API linking problems, Query results, C API problems -@subsubsection How Can I Get the Unique ID for the Last Inserted Row? - -If you insert a record in a table containing a column that has the -@code{AUTO_INCREMENT} attribute, you can get the most recently generated -ID by calling the @code{mysql_insert_id()} function. - -You can also retrieve the ID by using the @code{LAST_INSERT_ID()} function in -a query string that you pass to @code{mysql_query()}. - -You can check if an @code{AUTO_INCREMENT} index is used by executing -the following code. This also checks if the query was an @code{INSERT} with -an @code{AUTO_INCREMENT} index: - -@example -if (mysql_error(&mysql)[0] == 0 && - mysql_num_fields(result) == 0 && - mysql_insert_id(&mysql) != 0) -@{ - used_id = mysql_insert_id(&mysql); -@} -@end example - -The most recently generated ID is maintained in the server on a -per-connection basis. It will not be changed by another client. It will not -even be changed if you update another @code{AUTO_INCREMENT} column with a -non-magic value (that is, a value that is not @code{NULL} and not @code{0}). - -If you want to use the ID that was generated for one table and insert -it into a second table, you can use SQL statements like this: - -@example -INSERT INTO foo (auto,text) - VALUES(NULL,'text'); # generate ID by inserting NULL -INSERT INTO foo2 (id,text) - VALUES(LAST_INSERT_ID(),'text'); # use ID in second table -@end example - -@cindex linking, problems -@cindex C API, linking problems -@node C API linking problems, , Getting unique ID, C API problems -@subsubsection Problems Linking with the C API - -When linking with the C API, the following errors may occur 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 - -If this happens on your system, you must include the math library by -adding @code{-lm} to the end of the compile/link line. - -@cindex clients, thread-safe -@cindex thread-safe clients -@node Thread-safe clients, , C API problems, C -@subsection How to Make a Thread-safe Client - -The client library is almost thread safe. The biggest problem is -that the subroutines in @file{net.c} that read from sockets are not -interrupt safe. This was done with the thought that you might want to -have your own alarm that can break a long read to a server. If you -install interrupt handlers for the @code{SIGPIPE} interrupt, -the socket handling should be thread safe. - -In the older binaries we distribute on our Web site, the client -libraries are not normally compiled with the thread-safe option (the -Windows binaries are by default compiled to be thread safe). -Newer binary distributions should have both a normal and a -thread-safe client library. - -To get a really thread-safe client where you can interrupt the client -from other threads and set timeouts when talking with the @strong{MySQL} -server, you should use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} -libraries and the @code{net_serv.o} code that the server uses. - -If you don't need interrupts or timeouts, you can just compile a thread -safe client library @code{(mysqlclient_r)} and use this. @xref{C,, -MySQL C API}. In this case you don't have to worry about the -@code{net_serv.o} object file or the other @strong{MySQL} libraries. - -When using a threaded client and you want to use timeouts and interrupts, -you can make great use of the routines in the @file{thr_alarm.c} file. -If you are using routines from the @code{mysys} library, the only thing -you must remember is to call @code{my_init()} first! - -All functions except @code{mysql_real_connect()} are by default -thread safe. The following notes describe how to compile a thread safe -client library and use it in a thread-safe manner. (The notes below for -@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as -well, but because @code{mysql_connect()} is deprecated, you should be -using @code{mysql_real_connect()} anyway.) - -To make @code{mysql_real_connect()} thread safe, you must recompile the -client library with this command: - -@example -shell> ./configure --with-thread-safe-client -@end example - -This will create a thread-safe client library @code{libmysqlclient_r}. -@code{--with-thread-safe-client}. This library is thread safe per -connection. You can let two threads share the same connection as long -as you do the following: - -@itemize @bullet -@item -Two threads can't send a query to the @strong{MySQL} at the same time on -the same connection. In particular, you have to ensure that between a -@code{mysql_query()} and @code{mysql_store_result()} no other thread is using -the same connection. -@item -Many threads can access different result sets that are retrieved with -@code{mysql_store_result()}. -@item -If you use @code{mysql_use_result}, you have to ensure that no other thread -is asking anything on the same connection until the result set is closed. -However, it really is best for threaded clients that share the same -connection to use @code{mysql_use_result()}. -@item -If you want to use multiple threads on the same connection, you must -have a mutex lock around your @code{mysql_query()} and -@code{mysql_store_result()} call combination. Once -@code{mysql_store_result()} is ready, the lock can be released and other -threads may query the same connection. -@item -If you program with POSIX threads, you can use -@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} to -establish and release a mutex lock. -@end itemize - -You may get some errors because of undefined symbols when linking your -client with @code{mysqlclient_r}. In most cases this is because you haven't -included the thread libraries on the link/compile line. +@node Perl, ODBC, PHP, Clients +@section MySQL Perl API @cindex APIs, Perl @cindex Perl API -@node Perl, Eiffel, C, Clients -@section MySQL Perl API This section documents the Perl @code{DBI} interface. The former interface was called @code{mysqlperl}. @code{DBI}/@code{DBD} now is the @@ -42854,10 +37296,12 @@ documented here. * DBI-info:: More @code{DBI}/@code{DBD} information @end menu -@cindex @code{DBI} interface + @node DBI with DBD, Perl DBI Class, Perl, Perl @subsection @code{DBI} with @code{DBD::mysql} +@cindex @code{DBI} interface + @code{DBI} is a generic interface for many databases. That means that you can write a script that works with many different database engines without change. You need a DataBase Driver (DBD) defined for each @@ -42881,10 +37325,12 @@ Note that if you want to use transactions with Perl, you need to have Installation instructions for @strong{MySQL} Perl support are given in @ref{Perl support}. -@cindex @code{DBI} Perl module + @node Perl DBI Class, DBI-info, DBI with DBD, Perl @subsection The @code{DBI} Interface +@cindex @code{DBI} Perl module + @noindent @strong{Portable DBI Methods} @@ -43356,10 +37802,12 @@ $types = $sth->@{type@}; @end table -@cindex @code{DBI/DBD} + @node DBI-info, , Perl DBI Class, Perl @subsection More @code{DBI}/@code{DBD} Information +@cindex @code{DBI/DBD} + You can use the @code{perldoc} command to get more information about @code{DBI}. @@ -43378,21 +37826,3646 @@ the @code{DBI} Web page: @uref{http://www.symbolstone.org/technology/perl/DBI/index.html} @end example -@cindex Eiffel Wrapper -@cindex wrappers, Eiffel -@node Eiffel, Java, Perl, Clients -@section MySQL Eiffel wrapper -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains an Eiffel wrapper written by Michael Ravits. +@node ODBC, C, Perl, Clients +@section MySQL ODBC Support -You can also find this at: -@url{http://www.netpedia.net/hosting/newplayer/} +@cindex ODBC +@cindex Windows +@cindex MyODBC + +@menu +* Installing MyODBC:: How to install MyODBC +* ODBC administrator:: How to fill in the various fields in the ODBC administrator program +* MyODBC connect parameters:: +* ODBC Problems:: How to report problems with @strong{MySQL} ODBC +* MyODBC clients:: Programs known to work with @strong{MyODBC} +* ODBC and last_insert_id:: How to get the value of an @code{AUTO_INCREMENT} column in ODBC +* MyODBC bug report:: Reporting problems with MyODBC +@end menu + + +@strong{MySQL} provides support for ODBC by means of the @strong{MyODBC} +program. This chapter will teach you how to install @strong{MyODBC}, +and how to use it. Here, you will also find a list of common programs that +are known to work with @strong{MyODBC}. + + +@node Installing MyODBC, ODBC administrator, ODBC, ODBC +@subsection How To Install MyODBC + +@strong{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and level +2 features) driver for connecting an ODBC-aware application to +@strong{MySQL}. @strong{MyODBC} works on Windows95, Windows98, NT, and +on most Unix platforms. + +@strong{MyODBC} is in public domain, and you can find the newest version +at @uref{http://www.mysql.com/downloads/api-myodbc.html}. + +If you have problem with @strong{MyODBC} and your program also works +with OLEDB, you should try the OLEDB driver that you can find in the +Contrib section. @xref{Contrib}. + +Normally you only need to install @strong{MyODBC} on Windows machines. +You only need @strong{MyODBC} for Unix if you have a program like +ColdFusion that is running on the Unix machine and uses ODBC to connect +to the databases. + +If you want to install @strong{MyODBC} on a Unix box, you will also need +an @strong{ODBC} manager. @strong{MyODBC} is known to work with +most of the Unix ODBC managers. You can find a list at these in the +@strong{ODBC}-related links section on the @strong{MySQL} useful links page. +@xref{Useful Links}. + +To install @strong{MyODBC} on Windows, you should download the +appropriate @strong{MyODBC} .zip file (for Windows or NT/Win2000), +unpack it with @code{WINZIP}, or some similar program, and execute the +@code{SETUP.EXE} file. + +On Windows/NT you may get the following error when trying to install +@strong{MyODBC}: + +@example +An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart +Windows and try installing again (before running any applications which +use ODBC) +@end example + +The problem in this case is that some other program is using ODBC and +because of how Windows is designed, you may not in this case be able to +install a new ODBC drivers with Microsoft's ODBC setup program. In most +cases you can continue by just pressing @code{Ignore} to copy the rest +of the MyODBC files and the final installation should still work. If +this doesn't work, the solution is to reboot your computer in ``safe +mode`` (Choose this by pressing F8 just before your machine starts +Windows during rebooting), install @strong{MyODBC}, and reboot to normal +mode. + +@itemize @bullet +@item +To make a connection to a Unix box from a Windows box, with an ODBC +application (one that doesn't support @strong{MySQL} natively), you must +first install @strong{MyODBC} on the Windows machine. +@item +The user and Windows machine must have the access privileges to the +@strong{MySQL} server on the Unix machine. This is set up with the +@code{GRANT} command. @xref{GRANT,,@code{GRANT}}. +@item +You must create an ODBC DSN entry as follows: + +@itemize @minus +@item +Open the Control Panel on the Windows machine. +@item +Double-click the ODBC Data Sources 32 bits icon. +@item +Click the tab User DSN. +@item +Click the button Add. +@item +Select @strong{MySQL} in the screen Create New Data Source and click +the Finish button. +@item +The @strong{MySQL} Driver default configuration screen is shown. +@xref{ODBC administrator}. +@end itemize + +@item +Now start your application and select the ODBC driver with the DSN you +specified in the ODBC administrator. +@end itemize + +Notice that there are other configuration options on the screen of +@strong{MySQL} (trace, don't prompt on connect, etc) that you can try if +you run into problems. + + +@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC +@subsection How to Fill in the Various Fields in the ODBC Administrator Program + +@cindex ODBC, administrator + +There are three possibilities for specifying the server name on +Windows95: + +@itemize @bullet +@item +Use the IP address of the server. +@item +Add a file @file{\windows\lmhosts} with the following information: + +@example +ip hostname +@end example + +For example: + +@example +194.216.84.21 my_hostname +@end example + +@item +Configure the PC to use DNS. +@end itemize + +Example of how to fill in the @code{ODBC setup}: +@example +Windows DSN name: test +Description: This is my test database +MySql Database: test +Server: 194.216.84.21 +User: monty +Password: my_password +Port: +@end example + +The value for the @code{Windows DSN name} field is any name that is unique +in your Windows ODBC setup. + +You don't have to specify values for the @code{Server}, @code{User}, +@code{Password}, or @code{Port} fields in the ODBC setup screen. +However, if you do, the values will be used as the defaults later when +you attempt to make a connection. You have the option of changing the +values at that time. + +If the port number is not given, the default port (@value{default_port}) +is used. + +If you specify the option @code{Read options from C:\my.cnf}, the groups +@code{client} and @code{odbc} will be read from the @file{C:\my.cnf} file. +You can use all options that are usable by @code{mysql_options()}. +@xref{mysql_options, , @code{mysql_options}}. + + +@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC +@subsection Connect parameters for MyODBC + +One can specify the following parameters for @strong{MyODBC} on +the @code{[Servername]} section of an @code{ODBC.INI} file or +through the @code{InConnectionString} argument in the +@code{SQLDriverConnect()} call. + +@multitable @columnfractions .2 .2 .6 +@item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment} +@item user @tab ODBC (on Windows) @tab The username used to connect to @strong{MySQL}. +@item server @tab localhost @tab The hostname of the @strong{MySQL} server. +@item database @tab @tab The default database +@item option @tab 0 @tab A integer by which you can specify how @strong{MyODBC} should work. See below. +@item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}. +@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}. +@item password @tab @tab The password for the @code{server} @code{user} combination. +@item socket @tab @tab The socket or Windows pipe to connect to. +@end multitable + +The option argument is used to tell @strong{MyODBC} that the client isn't 100% +ODBC compliant. On Windows, one normally sets the option flag by +toggling the different options on the connection screen but one can also +set this in the opton argument. The following options are listed in the +same order as they appear in the @strong{MyODBC} connect screen: + +@multitable @columnfractions .1 .9 +@item @strong{Bit} @tab @strong{Meaning} +@item 1 @tab The client can't handle that @strong{MyODBC} returns the real width of a column. +@item 2 @tab The client can't handle that MySQL returns the true value of affected rows. If this flag is set then MySQL returns 'found rows' instead. One must have MySQL 3.21.14 or newer to get this to work. +@item 4 @tab Make a debug log in c:\myodbc.log. This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT} +@item 8 @tab Don't set any packet limit for results and parameters. +@item 16 @tab Don't prompt for questions even if driver would like to prompt +@item 32 @tab Simulate a ODBC 1.0 driver in some context. +@item 64 @tab Ignore use of database name in 'database.table.column'. +@item 128 @tab Force use of ODBC manager cursors (experimental). +@item 256 @tab Disable the use of extended fetch (experimental) +@item 512 @tab Pad CHAR fields to full column length. +@item 1024 @tab SQLDescribeCol() will return fully qualifed column names +@item 2048 @tab Use the compressed server/client protocol +@item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords! +@item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT. +@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG). +@item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental) +@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf} +@item 131072 @tab Add some extra safety checks (should not bee needed but...) +@end multitable + +If you want to have many options, you should add the above flags! For +example setting option to 12 (4+8) gives you debugging without package +limits! + +The default @file{MYODBC.DLL} is compiled for optimal performance. If +you want to to debug @strong{MyODBC} (for example to enable tracing), +you should instead use @code{MYODBCD.DLL}. To install this file, copy +@file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file. + + +@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC +@subsection How to Report Problems with MyODBC + +@strong{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder, +Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows), +ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports, +DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes +4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 +bit, VC++, and Visual Basic. + +If you know of any other applications that work with @strong{MyODBC}, please +send mail to @email{myodbc@@lists.mysql.com} about this! + +With some programs you may get an error like: +@code{Another user has modifies the record that you have modified}. In most +cases this can be solved by doing one of the following things: + +@itemize @bullet +@item +Add a primary key for the table if there isn't one already. +@item +Add a timestamp column if there isn't one already. +@item +Only use double float fields. Some programs may fail when they compare +single floats. +@end itemize + +If the above doesn't help, you should do a @code{MyODBC} trace file and +try to figure out why things go wrong. + + +@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC +@subsection Programs Known to Work with MyODBC + +Most programs should work with @strong{MyODBC}, but for each of those +listed below, we have tested it ourselves or received confirmation from +some user that it works: + +@table @asis +@item @strong{Program} +@strong{Comment} +@cindex Access program + +@item Access +To make Access work: +@itemize @bullet +@item +If you are using Access 2000, you should get and install the newest +Microsoft MDAC (@code{Microsoft Data Access Components}) from +@uref{http://www.microsoft.com/data}. This will fix the following bug +in Access: when you export data to @strong{MySQL}, the table and column +names aren't specified. Another way to around this bug is to upgrade to +MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together +provide a workaround for this bug! + +Note that if you are using @strong{MySQL} Version 3.22, you must to apply the +MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around +this problem. +@item +Set the ``Return matching rows'' MyODBC option field when connecting to +@strong{MySQL}. +@item +You should have a primary key in the table. If not, new or updated rows +may show up as @code{#Deleted#}. +@item +You should have a timestamp in all tables you want to be able to update. +For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} +is recommended instead of other @code{TIMESTAMP(X)} variations. +@item +Only use double float fields. Access fails when comparing with single floats. +The symptom usually is that new or updated rows may show up as @code{#Deleted#} +or that you can't find or update rows. +@item +If you still get the error @code{Another user has changed your data} after +adding a @code{TIMESTAMP} column, the following trick may help you: + +Don't use @code{table} data sheet view. Create instead a form with the +fields you want, and use that @code{form} data sheet view. You should +set the @code{DefaultValue} property for the @code{TIMESTAMP} column to +@code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column +from view so your users are not confused. +@item +Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If +you want to have @code{MEMO} columns instead, you should change the +column to @code{TEXT} with @code{ALTER TABLE}. +@item +Access can't always handle @code{DATE} columns properly. If you have a problem +with these, change the columns to @code{DATETIME}. +@item +In some cases, Access may generate illegal SQL queries that +@strong{MySQL} can't understand. You can fix this by selecting +@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. +@item +If you have in Access a column defined as BYTE, Access will try to export this +as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you +problems if you have values > 127 in the column! +@item +If you are using Access 7.0, You should use the option flag @code{Return +matching rows}. +@item +If you are using Access 2.0, You should use the option flags @code{Return +matching rows} and @code{Simulate ODBC 1.0}. +@end itemize + +@cindex ADO program +@item ADO +When you are coding with the ADO API and @strong{MyODBC} you need to put +attention in some default properties that aren't supported by the +@strong{MySQL} server. For example, using the @code{CursorLocation +Property} as @code{adUseServer} will return for the @code{RecordCount +Property} a result of -1. To have the right value, you need to set this +property to @code{adUseClient}, like is showing in the VB code below: + +@example +Dim myconn As New ADODB.Connection +Dim myrs As New Recordset +Dim mySQL As String +Dim myrows As Long + +myconn.Open "DSN=MyODBCsample" +mySQL = "SELECT * from user" +myrs.Source = mySQL +Set myrs.ActiveConnection = myconn +myrs.CursorLocation = adUseClient +myrs.Open +myrows = myrs.RecordCount + +myrs.Close +myconn.Close +@end example + +Another workaround is to use a @code{SELECT COUNT(*)} statement +for a similar query to get the correct row count. + +@item Active server pages (ASP) +You should use the option flag @code{Return matching rows}. + +@item BDE applications +To get these to work, you should set the option flags +@code{Don't optimize column widths} and @code{Return matching rows}. + +@cindex Borland Buidler 4 program +@item Borland Builder 4 +When you start a query you can use the property @code{Active} or use the +method @code{Open}. Note that @code{Active} will start by automatically +issuing a @code{SELECT * FROM ...} query that may not be a good thing if +your tables are big! +@item ColdFusion (On Unix) +The following information is taken from the ColdFusion documentation: + +Use the following information to configure ColdFusion Server for Linux +to use the unixODBC driver with @strong{MyODBC} for @strong{MySQL} data +sources. Allaire has verified that @strong{MyODBC} Version 2.50.26 +works with @strong{MySQL} Version 3.22.27 and ColdFusion for Linux. (Any +newer version should also work.) You can download @strong{MyODBC} at +@uref{http://www.mysql.com/downloads/api-myodbc.html} + +@cindex ColdFusion program +ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator +to add the @strong{MySQL} data source. However, the driver is not +included with ColdFusion Version 4.5.1. Before the @strong{MySQL} driver +will appear in the ODBC datasources drop-down list, you must build and +copy the @strong{MyODBC} driver to +@file{/opt/coldfusion/lib/libmyodbc.so}. + +The Contrib directory contains the program mydsn-xxx.zip which allows +you to build and remove the DSN registry file for the MyODBC driver +on Coldfusion applications. + +@cindex DataJunction +@item DataJunction +You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as +it exports the latter in a manner that causes @strong{MySQL} grief. +@cindex Excel +@item Excel +Works. Some tips: +@itemize @bullet +@item +If you have problems with dates, try to select them as strings using the +@code{CONCAT()} function. For example: +@example +select CONCAT(rise_time), CONCAT(set_time) + from sunrise_sunset; +@end example +Values retrieved as strings this way should be correctly recognized +as time values by Excel97. + +The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking +the column is of ``string type''. Without the @code{CONCAT()}, ODBC knows the +column is of time type, and Excel does not understand that. + +Note that this is a bug in Excel, because it automatically converts a +string to a time. This would be great if the source was a text file, but +is plain stupid when the source is an ODBC connection that reports +exact types for each column. +@end itemize +@cindex Word program +@item Word + +To retrieve data from @strong{MySQL} to Word/Excel documents, you need to +use the @code{MyODBC} driver and the Add-in Microsoft Query help. + +For example, create a db with a table containing 2 columns of text: + +@itemize @bullet +@item +Insert rows using the @code{mysql} client command-line tool. +@item +Create a DSN file using the MyODBC driver, for example, my for the db above. +@item +Open the Word application. +@item +Create a blank new documentation. +@item +Using the tool bar called Database, press the button insert database. +@item +Press the button Get Data. +@item +At the right hand of the screen Get Data, press the button Ms Query. +@item +In the Ms Query create a New Data Source using the DSN file my. +@item +Select the new query. +@item +Select the columns that you want. +@item +Make a filter if you want. +@item +Make a Sort if you want. +@item +Select Return Data to Microsoft Word. +@item +Click Finish. +@item +Click Insert data and select the records. +@item +Click OK and you see the rows in your Word document. +@end itemize + +@cindex odbcadmin program +@item odbcadmin +Test program for ODBC. +@cindex Delphi program +@item Delphi +You must use BDE Version 3.2 or newer. Set the `Don't optimize column width' +option field when connecting to @strong{MySQL}. + +Also, here is some potentially useful Delphi code that sets up both an +ODBC entry and a BDE entry for @strong{MyODBC} (the BDE entry requires a BDE +Alias Editor that is free at a Delphi Super Page near +you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this): + +@example +fReg:= TRegistry.Create; + fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True); + fReg.WriteString('Database', 'Documents'); + fReg.WriteString('Description', ' '); + fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll'); + fReg.WriteString('Flag', '1'); + fReg.WriteString('Password', ''); + fReg.WriteString('Port', ' '); + fReg.WriteString('Server', 'xmark'); + fReg.WriteString('User', 'winuser'); + fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True); + fReg.WriteString('DocumentsFab', 'MySQL'); + fReg.CloseKey; + fReg.Free; + + Memo1.Lines.Add('DATABASE NAME='); + Memo1.Lines.Add('USER NAME='); + Memo1.Lines.Add('ODBC DSN=DocumentsFab'); + Memo1.Lines.Add('OPEN MODE=READ/WRITE'); + Memo1.Lines.Add('BATCH COUNT=200'); + Memo1.Lines.Add('LANGDRIVER='); + Memo1.Lines.Add('MAX ROWS=-1'); + Memo1.Lines.Add('SCHEMA CACHE DIR='); + Memo1.Lines.Add('SCHEMA CACHE SIZE=8'); + Memo1.Lines.Add('SCHEMA CACHE TIME=-1'); + Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT'); + Memo1.Lines.Add('SQLQRYMODE='); + Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE'); + Memo1.Lines.Add('ENABLE BCD=FALSE'); + Memo1.Lines.Add('ROWSET SIZE=20'); + Memo1.Lines.Add('BLOBS TO CACHE=64'); + Memo1.Lines.Add('BLOB SIZE=32'); + + AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines); +@end example + +@cindex C++Builder +@item C++Builder +Tested with BDE Version 3.0. The only known problem is that when the table +schema changes, query fields are not updated. BDE, however, does not seem +to recognize primary keys, only the index PRIMARY, though this has not +been a problem. + +@item Vision +You should use the option flag @code{Return matching rows}. + +@cindex Visual Basic +@item Visual Basic +To be able to update a table, you must define a primary key for the table. + +Visual Basic with ADO can't handle big integers. This means that some queries +like @code{SHOW PROCESSLIST} will not work properly. The fix is to set +add the option @code{OPTION=16834} in the ODBC connect string or set +the @code{Change BIGINT columns to INT} option in the MyODBC connect screen. +You may also want to set the @code{Return matching rows} option. + +@item VisualInterDev +If you get the error @code{[Microsoft][ODBC Driver Manager] Driver does +not support this parameter} the reason may be that you have a +@code{BIGINT} in your result. Try setting the @code{Change BIGINT +columns to INT} option in the MyODBC connect screen. + +@item Visual Objects +You should use the option flag @code{Don't optimize column widths}. +@end table + + +@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC +@subsection How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC + +@cindex AUTO-INCREMENT, ODBC + +A common problem is how to get the value of an automatically generated ID +from an @code{INSERT}. With ODBC, you can do something like this (assuming +that @code{auto} is an @code{AUTO_INCREMENT} field): + +@example +INSERT INTO foo (auto,text) VALUES(NULL,'text'); +SELECT LAST_INSERT_ID(); +@end example + +Or, if you are just going to insert the ID into another table, you can do this: + +@example +INSERT INTO foo (auto,text) VALUES(NULL,'text'); +INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); +@end example + +@xref{Getting unique ID}. + +For the benefit of some ODBC applications (at least Delphi and Access), +the following query can be used to find a newly inserted row: +@example +SELECT * FROM tbl_name WHERE auto IS NULL; +@end example + + +@node MyODBC bug report, , ODBC and last_insert_id, ODBC +@subsection Reporting Problems with MyODBC + +@cindex reporting, MyODBC problems +@cindex problems, ODBC +@cindex MyODBC, reporting problems + +If you encounter difficulties with @strong{MyODBC}, you should start by +making a log file from the ODBC manager (the log you get when requesting +logs from ODBCADMIN) and a @strong{MyODBC} log. + +To get a @strong{MyODBC} log, you need to do the following: + +@enumerate +@item +Ensure that you are using @code{myodbcd.dll} and not @code{myodbc.dll}. +The easiest way to do this is to get @code{myodbcd.dll} from the MyODBC +distribution and copy it over the @code{myodbc.dll}, which is probably +in your @code{C:\windows\system32} or @code{C:\winnt\system32} directory. + +Note that you probably want to restore the old myodbc.dll file when you +have finished testing, as this is a lot faster than @code{myodbcd.dll}. +@item +Tag the `Trace MyODBC' option flag in the @strong{MyODBC} connect/configure +screen. The log will be written to file @file{C:\myodbc.log}. + +If the trace option is not remembered when you are going back to the +above screen, it means that you are not using the @code{myodbcd.dll} +driver (see above). +@item +Start your application and try to get it to fail. +@end enumerate + +Check the @code{MyODBC trace file}, to find out what could be wrong. +You should be able to find out the issued queries by searching after +the string @code{>mysql_real_query} in the @file{myodbc.log} file. + +You should also try duplicating the queries in the @code{mysql} monitor +or @code{admndemo} to find out if the error is MyODBC or @strong{MySQL}. + +If you find out something is wrong, please only send the relevant rows +(max 40 rows) to @email{myodbc@@lists.mysql.com}. Please never +send the whole MyODBC or ODBC log file! + +If you are unable to find out what's wrong, the last option is to +make an archive (tar or zip) that contains a MyODBC trace file, the ODBC +log file, and a README file that explains the problem. You can send this +to @uref{ftp://support.mysql.com/pub/mysql/secret}. Only we at +@strong{MySQL AB} will have access to the files you upload, and we will +be very discrete with the data! + +If you can create a program that also shows this problem, please +upload this too! + +If the program works with some other SQL server, you should make an ODBC log +file where you do exactly the same thing in the other SQL server. + +Remember that the more information you can supply to us, the more +likely it is that we can fix the problem! + + +@node C, Cplusplus, ODBC, Clients +@section MySQL C API + +@cindex C API, datatypes +@cindex datatypes, C API + +@menu +* C API datatypes:: C API Datatypes +* C API function overview:: C API Function Overview +* C API functions:: C API Function Descriptions +* C API problems:: +* Building clients:: +* Thread-safe clients:: +@end menu + +The C API code is distributed with @strong{MySQL}. It is included in the +@code{mysqlclient} library and allows C programs to access a database. + +Many of the clients in the @strong{MySQL} source distribution are +written in C. If you are looking for examples that demonstrate how to +use the C API, take a look at these clients. You can find these in the +@code{clients} directory in the @strong{MySQL} source distribution. + +Most of the other client APIs (all except Java) use the @code{mysqlclient} +library to communicate with the @strong{MySQL} server. This means that, for +example, you can take advantage of many of the same environment variables +that are used by other client programs, because they are referenced from the +library. See @ref{Client-Side Scripts}, for a list of these variables. + +The client has a maximum communication buffer size. The size of the buffer +that is allocated initially (16K bytes) is automatically increased up to the +maximum size (the maximum is 16M). Because buffer sizes are increased +only as demand warrants, simply increasing the default maximum limit does not +in itself cause more resources to be used. This size check is mostly a check +for erroneous queries and communication packets. + +The communication buffer must be large enough to contain a single SQL +statement (for client-to-server traffic) and one row of returned data (for +server-to-client traffic). Each thread's communication buffer is dynamically +enlarged to handle any query or row up to the maximum limit. For example, if +you have @code{BLOB} values that contain up to 16M of data, you must have a +communication buffer limit of at least 16M (in both server and client). The +client's default maximum is 16M, but the default maximum in the server is +1M. You can increase this by changing the value of the +@code{max_allowed_packet} parameter when the server is started. @xref{Server +parameters}. + +The @strong{MySQL} server shrinks each communication buffer to +@code{net_buffer_length} bytes after each query. For clients, the size of +the buffer associated with a connection is not decreased until the connection +is closed, at which time client memory is reclaimed. + +For programming with threads, consult the 'how to make a thread-safe +client' chapter. @xref{Thread-safe clients}. + + +@node C API datatypes, C API function overview, C, C +@subsection C API Datatypes + +@table @code +@tindex MYSQL C type +@item MYSQL +This structure represents a handle to one database connection. It is +used for almost all @strong{MySQL} functions. + +@tindex MYSQL_RES C type +@item MYSQL_RES +This structure represents the result of a query that returns rows +(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). The +information returned from a query is called the @emph{result set} in the +remainder of this section. + +@tindex MYSQL_ROW C type +@item MYSQL_ROW +This is a type-safe representation of one row of data. It is currently +implemented as an array of counted byte strings. (You cannot treat these as +null-terminated strings if field values may contain binary data, because such +values may contain null bytes internally.) Rows are obtained by calling +@code{mysql_fetch_row()}. + +@tindex MYSQL_FIELD C type +@item MYSQL_FIELD +This structure contains information about a field, such as the field's +name, type, and size. Its members are described in more detail below. +You may obtain the @code{MYSQL_FIELD} structures for each field by +calling @code{mysql_fetch_field()} repeatedly. Field values are not part of +this structure; they are contained in a @code{MYSQL_ROW} structure. + + +@tindex MYSQL_FIELD_OFFSET C type +@item MYSQL_FIELD_OFFSET +This is a type-safe representation of an offset into a @strong{MySQL} field +list. (Used by @code{mysql_field_seek()}.) Offsets are field numbers +within a row, beginning at zero. + +@tindex my_ulonglong C type +@tindex my_ulonglong values, printing +@item my_ulonglong +The type used for the number of rows and for @code{mysql_affected_rows()}, +@code{mysql_num_rows()}, and @code{mysql_insert_id()}. This type provides a +range of @code{0} to @code{1.84e19}. + +On some systems, attempting to print a value of type @code{my_ulonglong} +will not work. To print such a value, convert it to @code{unsigned long} +and use a @code{%lu} print format. Example: +@example +printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result)); +@end example +@end table + +@noindent +The @code{MYSQL_FIELD} structure contains the members listed below: + +@table @code +@item char * name +The name of the field, as a null-terminated string. + +@item char * table +The name of the table containing this field, if it isn't a calculated field. +For calculated fields, the @code{table} value is an empty string. + +@item char * def +The default value of this field, as a null-terminated string. This is set +only if you use @code{mysql_list_fields()}. + +@item enum enum_field_types type +The type of the field. +The @code{type} value may be one of the following: + +@multitable @columnfractions .3 .55 +@item @strong{Type value} @tab @strong{Type meaning} +@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT} field +@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT} field +@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER} field +@item @code{FIELD_TYPE_INT24} @tab @code{MEDIUMINT} field +@item @code{FIELD_TYPE_LONGLONG} @tab @code{BIGINT} field +@item @code{FIELD_TYPE_DECIMAL} @tab @code{DECIMAL} or @code{NUMERIC} field +@item @code{FIELD_TYPE_FLOAT} @tab @code{FLOAT} field +@item @code{FIELD_TYPE_DOUBLE} @tab @code{DOUBLE} or @code{REAL} field +@item @code{FIELD_TYPE_TIMESTAMP} @tab @code{TIMESTAMP} field +@item @code{FIELD_TYPE_DATE} @tab @code{DATE} field +@item @code{FIELD_TYPE_TIME} @tab @code{TIME} field +@item @code{FIELD_TYPE_DATETIME} @tab @code{DATETIME} field +@item @code{FIELD_TYPE_YEAR} @tab @code{YEAR} field +@item @code{FIELD_TYPE_STRING} @tab String (@code{CHAR} or @code{VARCHAR}) field +@item @code{FIELD_TYPE_BLOB} @tab @code{BLOB} or @code{TEXT} field (use @code{max_length} to determine the maximum length) +@item @code{FIELD_TYPE_SET} @tab @code{SET} field +@item @code{FIELD_TYPE_ENUM} @tab @code{ENUM} field +@item @code{FIELD_TYPE_NULL} @tab @code{NULL}-type field +@item @code{FIELD_TYPE_CHAR} @tab Deprecated; use @code{FIELD_TYPE_TINY} instead +@end multitable + +You can use the @code{IS_NUM()} macro to test whether or not a field has a +numeric type. Pass the @code{type} value to @code{IS_NUM()} and it +will evaluate to TRUE if the field is numeric: + +@example +if (IS_NUM(field->type)) + printf("Field is numeric\n"); +@end example + +@item unsigned int length +The width of the field, as specified in the table definition. + +@item unsigned int max_length +The maximum width of the field for the result set (the length of the longest +field value for the rows actually in the result set). If you use +@code{mysql_store_result()} or @code{mysql_list_fields()}, this contains the +maximum length for the field. If you use @code{mysql_use_result()}, the +value of this variable is zero. + +@item unsigned int flags +Different bit-flags for the field. The @code{flags} value may have zero +or more of the following bits set: + +@multitable @columnfractions .3 .55 +@item @strong{Flag value} @tab @strong{Flag meaning} +@item @code{NOT_NULL_FLAG} @tab Field can't be @code{NULL} +@item @code{PRI_KEY_FLAG} @tab Field is part of a primary key +@item @code{UNIQUE_KEY_FLAG} @tab Field is part of a unique key +@item @code{MULTIPLE_KEY_FLAG} @tab Field is part of a non-unique key +@item @code{UNSIGNED_FLAG} @tab Field has the @code{UNSIGNED} attribute +@item @code{ZEROFILL_FLAG} @tab Field has the @code{ZEROFILL} attribute +@item @code{BINARY_FLAG} @tab Field has the @code{BINARY} attribute +@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT} +attribute +@item @code{ENUM_FLAG} @tab Field is an @code{ENUM} (deprecated) +@item @code{BLOB_FLAG} @tab Field is a @code{BLOB} or @code{TEXT} (deprecated) +@item @code{TIMESTAMP_FLAG} @tab Field is a @code{TIMESTAMP} (deprecated) +@end multitable + +Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, and @code{TIMESTAMP_FLAG} +flags is deprecated because they indicate the type of a field rather +than an attribute of its type. It is preferable to test +@code{field->type} against @code{FIELD_TYPE_BLOB}, +@code{FIELD_TYPE_ENUM}, or @code{FIELD_TYPE_TIMESTAMP} instead. + +@noindent +The example below illustrates a typical use of the @code{flags} value: + +@example +if (field->flags & NOT_NULL_FLAG) + printf("Field can't be null\n"); +@end example + +You may use the following convenience macros to determine the boolean +status of the @code{flags} value: + +@multitable @columnfractions .3 .5 +@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL} +@item @code{IS_PRI_KEY(flags)} @tab True if this field is a primary key +@item @code{IS_BLOB(flags)} @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead) +@end multitable + +@item unsigned int decimals +The number of decimals for numeric fields. +@end table + + +@node C API function overview, C API functions, C API datatypes, C +@subsection C API Function Overview + +@cindex C API, functions +@cindex functions, C API + +The functions available in the C API are listed below and are described in +greater detail in the next section. +@xref{C API functions}. + +@multitable @columnfractions .3 .7 +@item @strong{mysql_affected_rows()} @tab +Returns the number of rows changed/deleted/inserted by the last @code{UPDATE}, +@code{DELETE}, or @code{INSERT} query. + +@item @strong{mysql_close()} @tab +Closes a server connection. + +@item @strong{mysql_connect()} @tab +Connects to a @strong{MySQL} server. This function is deprecated; use +@code{mysql_real_connect()} instead. + +@item @strong{mysql_change_user()} @tab +Changes user and database on an open connection. + +@item @strong{mysql_character_set_name()} @tab +Returns the name of the default character set for the connection. + +@item @strong{mysql_create_db()} @tab +Creates a database. This function is deprecated; use the SQL command +@code{CREATE DATABASE} instead. + +@item @strong{mysql_data_seek()} @tab +Seeks to an arbitrary row in a query result set. + +@item @strong{mysql_debug()} @tab +Does a @code{DBUG_PUSH} with the given string. + +@item @strong{mysql_drop_db()} @tab +Drops a database. This function is deprecated; use the SQL command +@code{DROP DATABASE} instead. + +@item @strong{mysql_dump_debug_info()} @tab +Makes the server write debug information to the log. + +@item @strong{mysql_eof()} @tab +Determines whether or not the last row of a result set has been read. +This function is deprecated; @code{mysql_errno()} or @code{mysql_error()} +may be used instead. + +@item @strong{mysql_errno()} @tab +Returns the error number for the most recently invoked @strong{MySQL} function. + +@item @strong{mysql_error()} @tab +Returns the error message for the most recently invoked @strong{MySQL} function. + +@item @strong{mysql_real_escape_string()} @tab +Escapes special characters in a string for use in a SQL statement taking +into account the current charset of the connection. + +@item @strong{mysql_escape_string()} @tab +Escapes special characters in a string for use in a SQL statement. + +@item @strong{mysql_fetch_field()} @tab +Returns the type of the next table field. + +@item @strong{mysql_fetch_field_direct()} @tab +Returns the type of a table field, given a field number. + +@item @strong{mysql_fetch_fields()} @tab +Returns an array of all field structures. + +@item @strong{mysql_fetch_lengths()} @tab +Returns the lengths of all columns in the current row. + +@item @strong{mysql_fetch_row()} @tab +Fetches the next row from the result set. + +@item @strong{mysql_field_seek()} @tab +Puts the column cursor on a specified column. + +@item @strong{mysql_field_count()} @tab +Returns the number of result columns for the most recent query. + +@item @strong{mysql_field_tell()} @tab +Returns the position of the field cursor used for the last +@code{mysql_fetch_field()}. + +@item @strong{mysql_free_result()} @tab +Frees memory used by a result set. + +@item @strong{mysql_get_client_info()} @tab +Returns client version information. + +@item @strong{mysql_get_host_info()} @tab +Returns a string describing the connection. + +@item @strong{mysql_get_proto_info()} @tab +Returns the protocol version used by the connection. + +@item @strong{mysql_get_server_info()} @tab +Returns the server version number. + +@item @strong{mysql_info()} @tab +Returns information about the most recently executed query. + +@item @strong{mysql_init()} @tab +Gets or initializes a @code{MYSQL} structure. + +@item @strong{mysql_insert_id()} @tab +Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous +query. + +@item @strong{mysql_kill()} @tab +Kills a given thread. + +@item @strong{mysql_list_dbs()} @tab +Returns database names matching a simple regular expression. + +@item @strong{mysql_list_fields()} @tab +Returns field names matching a simple regular expression. + +@item @strong{mysql_list_processes()} @tab +Returns a list of the current server threads. + +@item @strong{mysql_list_tables()} @tab +Returns table names matching a simple regular expression. + +@item @strong{mysql_num_fields()} @tab +Returns the number of columns in a result set. + +@item @strong{mysql_num_rows()} @tab +Returns the number of rows in a result set. + +@item @strong{mysql_options()} @tab +Sets connect options for @code{mysql_connect()}. + +@item @strong{mysql_ping()} @tab +Checks whether or not the connection to the server is working, reconnecting +as necessary. + +@item @strong{mysql_query()} @tab +Executes a SQL query specified as a null-terminated string. + +@item @strong{mysql_real_connect()} @tab +Connects to a @strong{MySQL} server. + +@item @strong{mysql_real_query()} @tab +Executes a SQL query specified as a counted string. + +@item @strong{mysql_reload()} @tab +Tells the server to reload the grant tables. + +@item @strong{mysql_row_seek()} @tab +Seeks to a row in a result set, using value returned from +@code{mysql_row_tell()}. + +@item @strong{mysql_row_tell()} @tab +Returns the row cursor position. + +@item @strong{mysql_select_db()} @tab +Selects a database. + +@item @strong{mysql_shutdown()} @tab +Shuts down the database server. + +@item @strong{mysql_stat()} @tab +Returns the server status as a string. + +@item @strong{mysql_store_result()} @tab +Retrieves a complete result set to the client. + +@item @strong{mysql_thread_id()} @tab +Returns the current thread ID. + +@item @strong{mysql_thread_save()} @tab +Returns 1 if the clients are compiled as thread-safe. + +@item @strong{mysql_use_result()} @tab +Initiates a row-by-row result set retrieval. +@end multitable + +To connect to the server, call @code{mysql_init()} to initialize a +connection handler, then call @code{mysql_real_connect()} with that +handler (along with other information such as the hostname, user name, +and password). Upon connection, @code{mysql_real_connect()} sets the +@code{reconnect} flag (part of the MYSQL structure) to a value of +@code{1}. This flag indicates, in the event that a query cannot be +performed because of a lost connection, to try reconnecting to the +server before giving up. When you are done with the connection, call +@code{mysql_close()} to terminate it. + +While a connection is active, the client may send SQL queries to the server +using @code{mysql_query()} or @code{mysql_real_query()}. The difference +between the two is that @code{mysql_query()} expects the query to be +specified as a null-terminated string whereas @code{mysql_real_query()} +expects a counted string. If the string contains binary data (which may +include null bytes), you must use @code{mysql_real_query()}. + +For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE}, +@code{DELETE}), you can find out how many rows were changed (affected) +by calling @code{mysql_affected_rows()}. + +For @code{SELECT} queries, you retrieve the selected rows as a result set. +(Note that some statements are @code{SELECT}-like in that they return rows. +These include @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}. They should +be treated the same way as @code{SELECT} statements.) + +There are two ways for a client to process result sets. One way is to +retrieve the entire result set all at once by calling +@code{mysql_store_result()}. This function acquires from the server all the +rows returned by the query and stores them in the client. The second way is +for the client to initiate a row-by-row result set retrieval by calling +@code{mysql_use_result()}. This function initializes the retrieval, but does +not actually get any rows from the server. + +In both cases, you access rows by calling @code{mysql_fetch_row()}. With +@code{mysql_store_result()}, @code{mysql_fetch_row()} accesses rows that have +already been fetched from the server. With @code{mysql_use_result()}, +@code{mysql_fetch_row()} actually retrieves the row from the server. +Information about the size of the data in each row is available by +calling @code{mysql_fetch_lengths()}. + +After you are done with a result set, call @code{mysql_free_result()} +to free the memory used for it. + +The two retrieval mechanisms are complementary. Client programs should +choose the approach that is most appropriate for their requirements. +In practice, clients tend to use @code{mysql_store_result()} more +commonly. + +An advantage of @code{mysql_store_result()} is that because the rows have all +been fetched to the client, you not only can access rows sequentially, you +can move back and forth in the result set using @code{mysql_data_seek()} or +@code{mysql_row_seek()} to change the current row position within the result +set. You can also find out how many rows there are by calling +@code{mysql_num_rows()}. On the other hand, the memory requirements for +@code{mysql_store_result()} may be very high for large result sets and you +are more likely to encounter out-of-memory conditions. + +An advantage of @code{mysql_use_result()} is that the client requires less +memory for the result set because it maintains only one row at a time (and +because there is less allocation overhead, @code{mysql_use_result()} can be +faster). Disadvantages are that you must process each row quickly to avoid +tying up the server, you don't have random access to rows within the result +set (you can only access rows sequentially), and you don't know how many rows +are in the result set until you have retrieved them all. Furthermore, you +@emph{must} retrieve all the rows even if you determine in mid-retrieval that +you've found the information you were looking for. + +The API makes it possible for clients to respond appropriately to +queries (retrieving rows only as necessary) without knowing whether or +not the query is a @code{SELECT}. You can do this by calling +@code{mysql_store_result()} after each @code{mysql_query()} (or +@code{mysql_real_query()}). If the result set call succeeds, the query +was a @code{SELECT} and you can read the rows. If the result set call +fails, call @code{mysql_field_count()} to determine whether or not a +result was actually to be expected. If @code{mysql_field_count()} +returns zero, the query returned no data (indicating that it was an +@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not +expected to return rows. If @code{mysql_field_count()} is non-zero, the +query should have returned rows, but didn't. This indicates that the +query was a @code{SELECT} that failed. See the description for +@code{mysql_field_count()} for an example of how this can be done. + +Both @code{mysql_store_result()} and @code{mysql_use_result()} allow you to +obtain information about the fields that make up the result set (the number +of fields, their names and types, etc.). You can access field information +sequentially within the row by calling @code{mysql_fetch_field()} repeatedly, +or by field number within the row by calling +@code{mysql_fetch_field_direct()}. The current field cursor position may be +changed by calling @code{mysql_field_seek()}. Setting the field cursor +affects subsequent calls to @code{mysql_fetch_field()}. You can also get +information for fields all at once by calling @code{mysql_fetch_fields()}. + +For detecting and reporting errors, @strong{MySQL} provides access to error +information by means of the @code{mysql_errno()} and @code{mysql_error()} +functions. These return the error code or error message for the most +recently invoked function that can succeed or fail, allowing you to determine +when an error occurred and what it was. + + +@node C API functions, C API problems, C API function overview, C +@subsection C API Function Descriptions + +@menu +* mysql_affected_rows:: @code{mysql_affected_rows()} +* mysql_close:: @code{mysql_close()} +* mysql_connect:: @code{mysql_connect()} +* mysql_change_user:: @code{mysql_change_user()} +* mysql_character_set_name:: @code{mysql_character_set_name()} +* mysql_create_db:: @code{mysql_create_db()} +* mysql_data_seek:: @code{mysql_data_seek()} +* mysql_debug:: @code{mysql_debug()} +* mysql_drop_db:: @code{mysql_drop_db()} +* mysql_dump_debug_info:: @code{mysql_dump_debug_info()} +* mysql_eof:: @code{mysql_eof()} +* mysql_errno:: @code{mysql_errno()} +* mysql_error:: @code{mysql_error()} +* mysql_escape_string:: @code{mysql_escape_string()} +* mysql_fetch_field:: @code{mysql_fetch_field()} +* mysql_fetch_fields:: @code{mysql_fetch_fields()} +* mysql_fetch_field_direct:: @code{mysql_fetch_field_direct()} +* mysql_fetch_lengths:: @code{mysql_fetch_lengths()} +* mysql_fetch_row:: @code{mysql_fetch_row()} +* mysql_field_count:: @code{mysql_field_count()} +* mysql_field_seek:: @code{mysql_field_seek()} +* mysql_field_tell:: @code{mysql_field_tell()} +* mysql_free_result:: @code{mysql_free_result()} +* mysql_get_client_info:: @code{mysql_get_client_info()} +* mysql_get_host_info:: @code{mysql_get_host_info()} +* mysql_get_proto_info:: @code{mysql_get_proto_info()} +* mysql_get_server_info:: @code{mysql_get_server_info()} +* mysql_info:: @code{mysql_info()} +* mysql_init:: @code{mysql_init()} +* mysql_insert_id:: @code{mysql_insert_id()} +* mysql_kill:: @code{mysql_kill()} +* mysql_list_dbs:: @code{mysql_list_dbs()} +* mysql_list_fields:: @code{mysql_list_fields()} +* mysql_list_processes:: @code{mysql_list_processes()} +* mysql_list_tables:: @code{mysql_list_tables()} +* mysql_num_fields:: @code{mysql_num_fields()} +* mysql_num_rows:: @code{mysql_num_rows()} +* mysql_options:: @code{mysql_options()} +* mysql_ping:: @code{mysql_ping()} +* mysql_query:: @code{mysql_query()} +* mysql_real_connect:: @code{mysql_real_connect()} +* mysql_real_escape_string:: @code{mysql_real_escape_string()} +* mysql_real_query:: @code{mysql_real_query()} +* mysql_reload:: @code{mysql_reload()} +* mysql_row_seek:: @code{mysql_row_seek()} +* mysql_row_tell:: @code{mysql_row_tell()} +* mysql_select_db:: @code{mysql_select_db()} +* mysql_shutdown:: @code{mysql_shutdown()} +* mysql_stat:: @code{mysql_stat()} +* mysql_store_result:: @code{mysql_store_result()} +* mysql_thread_id:: @code{mysql_thread_id()} +* mysql_use_result:: @code{mysql_use_result()} +@end menu + +In the descriptions below, a parameter or return value of @code{NULL} means +@code{NULL} in the sense of the C programming language, not a +@strong{MySQL} @code{NULL} value. + +Functions that return a value generally return a pointer or an integer. +Unless specified otherwise, functions returning a pointer return a +non-@code{NULL} value to indicate success or a @code{NULL} value to indicate +an error, and functions returning an integer return zero to indicate success +or non-zero to indicate an error. Note that ``non-zero'' means just that. +Unless the function description says otherwise, do not test against a value +other than zero: + +@example +if (result) /* correct */ + ... error ... + +if (result < 0) /* incorrect */ + ... error ... + +if (result == -1) /* incorrect */ + ... error ... +@end example + +When a function returns an error, the @strong{Errors} subsection of the +function description lists the possible types of errors. You can +find out which of these occurred by calling @code{mysql_errno()}. +A string representation of the error may be obtained by calling +@code{mysql_error()}. + + +@node mysql_affected_rows, mysql_close, C API functions, C API functions +@subsubsection @code{mysql_affected_rows()} + +@findex @code{mysql_affected_rows()} + +@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} + +@subsubheading Description + +Returns the number of rows changed by the last @code{UPDATE}, deleted by +the last @code{DELETE} or inserted by the last @code{INSERT} +statement. May be called immediately after @code{mysql_query()} for +@code{UPDATE}, @code{DELETE}, or @code{INSERT} statements. For +@code{SELECT} statements, @code{mysql_affected_rows()} works like +@code{mysql_num_rows()}. + +@subsubheading Return Values + +An integer greater than zero indicates the number of rows affected or +retrieved. Zero indicates that no records where updated for an +@code{UPDATE} statement, no rows matched the @code{WHERE} clause in the +query or that no query has yet been executed. -1 indicates that the +query returned an error or that, for a @code{SELECT} query, +@code{mysql_affected_rows()} was called prior to calling +@code{mysql_store_result()}. + +@subsubheading Errors + +None. + +@subsubheading Example + +@example +mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); +printf("%ld products updated",(long) mysql_affected_rows(&mysql)); +@end example + +If one specifies the flag @code{CLIENT_FOUND_ROWS} when connecting to +@code{mysqld}, @code{mysql_affected_rows()} will return the number of +rows matched by the @code{WHERE} statement for @code{UPDATE} statements. + +Note that when one uses a @code{REPLACE} command, +@code{mysql_affected_rows()} will return 2 if the new row replaced and +old row. This is because in this case one row was inserted and then the +duplicate was deleted. + + +@node mysql_close, mysql_connect, mysql_affected_rows, C API functions +@subsubsection @code{mysql_close()} + +@findex @code{mysql_close()} + +@code{void mysql_close(MYSQL *mysql)} + +@subsubheading Description +Closes a previously opened connection. @code{mysql_close()} also deallocates +the connection handle pointed to by @code{mysql} if the handle was allocated +automatically by @code{mysql_init()} or @code{mysql_connect()}. + +@subsubheading Return Values + +None. + +@subsubheading Errors + +None. + + +@node mysql_connect, mysql_change_user, mysql_close, C API functions +@subsubsection @code{mysql_connect()} + +@findex @code{mysql_connect()} + +@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} + +@subsubheading Description + +This function is deprecated. It is preferable to use +@code{mysql_real_connect()} instead. + +@code{mysql_connect()} attempts to establish a connection to a @strong{MySQL} +database engine running on @code{host}. @code{mysql_connect()} must complete +successfully before you can execute any of the other API functions, with the +exception of @code{mysql_get_client_info()}. + +The meanings of the parameters are the same as for the corresponding +parameters for @code{mysql_real_connect()} with the difference that the +connection parameter may be @code{NULL}. In this case the C API +allocates memory for the connection structure automatically and frees it +when you call @code{mysql_close()}. The disadvantage of this approach is +that you can't retrieve an error message if the connection fails. (To +get error information from @code{mysql_errno()} or @code{mysql_error()}, +you must provide a valid @code{MYSQL} pointer.) + +@subsubheading Return Values + +Same as for @code{mysql_real_connect()}. + +@subsubheading Errors + +Same as for @code{mysql_real_connect()}. + + +@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions +@subsubsection @code{mysql_change_user()} + +@findex @code{mysql_change_user()} + +@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const +char *password, const char *db)} + +@subsubheading Description + +Changes the user and causes the database specified by @code{db} to +become the default (current) database on the connection specified by +@code{mysql}. In subsequent queries, this database is the default for +table references that do not include an explicit database specifier. + +This function was introduced in @strong{MySQL} Version 3.23.3. + +@code{mysql_change_user()} fails unless the connected user can be +authenticated or if he doesn't have permission to use the database. In +this case the user and database are not changed + +The @code{db} parameter may be set to @code{NULL} if you don't want to have a +default database. + +@subsubheading Return values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +The same that you can get from @code{mysql_real_connect()}. + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@item ER_UNKNOWN_COM_ERROR +The @strong{MySQL} server doesn't implement this command (probably an old server) +@item ER_ACCESS_DENIED_ERROR +The user or password was wrong. +@item ER_BAD_DB_ERROR +The database didn't exist. +@item ER_DBACCESS_DENIED_ERROR +The user did not have access rights to the database. +@item ER_WRONG_DB_NAME +The database name was too long. +@end table + +@subsubheading Example + +@example +if (mysql_change_user(&mysql, "user", "password", "new_database")) +@{ + fprintf(stderr, "Failed to change user. Error: %s\n", + mysql_error(&mysql)); +@} +@end example + + +@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions +@subsubsection @code{mysql_character_set_name()} + +@findex @code{mysql_character_set_name()} + +@code{const char *mysql_character_set_name(MYSQL *mysql)} + +@subsubheading Description + +Returns the default character set for the current connection. + +@subsubheading Return Values + +The default character set + +@subsubheading Errors +None. + + +@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions +@subsubsection @code{mysql_create_db()} + +@findex @code{mysql_create_db()} + +@code{int mysql_create_db(MYSQL *mysql, const char *db)} + +@subsubheading Description +Creates the database named by the @code{db} parameter. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{CREATE DATABASE} statement instead. + +@subsubheading Return Values + +Zero if the database was created successfully. Non-zero if an error +occurred. + +@subsubheading Errors +@table @code + +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. + +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. + +@item CR_SERVER_LOST +The connection to the server was lost during the query. + +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +if(mysql_create_db(&mysql, "my_database")) +@{ + fprintf(stderr, "Failed to create new database. Error: %s\n", + mysql_error(&mysql)); +@} +@end example + + +@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions +@subsubsection @code{mysql_data_seek()} + +@findex @code{mysql_data_seek()} + +@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} + +@subsubheading Description +Seeks to an arbitrary row in a query result set. This requires that the +result set structure contains the entire result of the query, so +@code{mysql_data_seek()} may be used in conjunction only with +@code{mysql_store_result()}, not with @code{mysql_use_result()}. + +The offset should be a value in the range from 0 to +@code{mysql_num_rows(result)-1}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + + +@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions +@subsubsection @code{mysql_debug()} + +@findex @code{mysql_debug()} + +@code{void mysql_debug(char *debug)} + +@subsubheading Description +Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the +Fred Fish debug library. To use this function, you must compile the client +library to support debugging. +@xref{Debugging server}. @xref{Debugging client}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + +@subsubheading Example + +The call shown below causes the client library to generate a trace file in +@file{/tmp/client.trace} on the client machine: + +@example +mysql_debug("d:t:O,/tmp/client.trace"); +@end example + + +@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions +@subsubsection @code{mysql_drop_db()} + +@findex @code{mysql_drop_db()} + +@code{int mysql_drop_db(MYSQL *mysql, const char *db)} + +@subsubheading Description +Drops the database named by the @code{db} parameter. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{DROP DATABASE} statement instead. + +@subsubheading Return Values + +Zero if the database was dropped successfully. Non-zero if an error +occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +if(mysql_drop_db(&mysql, "my_database")) + fprintf(stderr, "Failed to drop the database: Error: %s\n", + mysql_error(&mysql)); +@end example + + +@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions +@subsubsection @code{mysql_dump_debug_info()} + +@findex @code{mysql_dump_debug_info()} + +@code{int mysql_dump_debug_info(MYSQL *mysql)} + +@subsubheading Description + +Instructs the server to write some debug information to the log. The +connected user must have the @strong{process} privilege for this to work. + +@subsubheading Return values + +Zero if the command was successful. Non-zero if an error occurred. + +@subsubheading Errors +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions +@subsubsection @code{mysql_eof()} + +@findex @code{mysql_eof()} + +@code{my_bool mysql_eof(MYSQL_RES *result)} + +@subsubheading Description + +This function is deprecated. @code{mysql_errno()} or @code{mysql_error()} +may be used instead. + +@code{mysql_eof()} determines whether or not the last row of a result +set has been read. + +If you acquire a result set from a successful call to +@code{mysql_store_result()}, the client receives the entire set in one +operation. In this case, a @code{NULL} return from @code{mysql_fetch_row()} +always means the end of the result set has been reached and it is +unnecessary to call @code{mysql_eof()}. + +On the other hand, if you use @code{mysql_use_result()} to initiate a result +set retrieval, the rows of the set are obtained from the server one by one as +you call @code{mysql_fetch_row()} repeatedly. Because an error may occur on +the connection during this process, a @code{NULL} return value from +@code{mysql_fetch_row()} does not necessarily mean the end of the result set +was reached normally. In this case, you can use @code{mysql_eof()} to +determine what happened. @code{mysql_eof()} returns a non-zero value if the +end of the result set was reached and zero if an error occurred. + +Historically, @code{mysql_eof()} predates the standard @strong{MySQL} error +functions @code{mysql_errno()} and @code{mysql_error()}. Because those error +functions provide the same information, their use is preferred over +@code{mysql_eof()}, which is now deprecated. (In fact, they provide more +information, because @code{mysql_eof()} returns only a boolean value whereas +the error functions indicate a reason for the error when one occurs.) + +@subsubheading Return Values + +Zero if no error occurred. Non-zero if the end of the result set has been +reached. + +@subsubheading Errors +None. + +@subsubheading Example + +The following example shows how you might use @code{mysql_eof()}: + +@example +mysql_query(&mysql,"SELECT * FROM some_table"); +result = mysql_use_result(&mysql); +while((row = mysql_fetch_row(result))) +@{ + // do something with data +@} +if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error +@{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); +@} +@end example + +However, you can achieve the same effect with the standard @strong{MySQL} +error functions: + +@example +mysql_query(&mysql,"SELECT * FROM some_table"); +result = mysql_use_result(&mysql); +while((row = mysql_fetch_row(result))) +@{ + // do something with data +@} +if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error +@{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); +@} +@end example + + +@node mysql_errno, mysql_error, mysql_eof, C API functions +@subsubsection @code{mysql_errno()} + +@findex @code{mysql_errno()} + +@code{unsigned int mysql_errno(MYSQL *mysql)} + +@subsubheading Description + +For the connection specified by @code{mysql}, @code{mysql_errno()} returns +the error code for the most recently invoked API function that can succeed +or fail. A return value of zero means that no error occurred. Client error +message numbers are listed in the @strong{MySQL} @file{errmsg.h} header file. +Server error message numbers are listed in @file{mysqld_error.h}. In the +@strong{MySQL} source distribution you can find a complete list of +error messages and error numbers in the file @file{Docs/mysqld_error.txt}. + +@subsubheading Return Values + +An error code value. Zero if no error occurred. + +@subsubheading Errors +None. + + +@node mysql_error, mysql_escape_string, mysql_errno, C API functions +@subsubsection @code{mysql_error()} + +@findex @code{mysql_error()} + +@code{char *mysql_error(MYSQL *mysql)} + +@subsubheading Description + +For the connection specified by @code{mysql}, @code{mysql_error()} returns +the error message for the most recently invoked API function that can succeed +or fail. An empty string (@code{""}) is returned if no error occurred. +This means the following two tests are equivalent: + +@example +if(mysql_errno(&mysql)) +@{ + // an error occurred +@} + +if(mysql_error(&mysql)[0] != '\0') +@{ + // an error occurred +@} +@end example + +The language of the client error messages may be changed by +recompiling the @strong{MySQL} client library. Currently you can choose +error messages in several different languages. +@xref{Languages}. + +@subsubheading Return Values + +A character string that describes the error. An empty string if no error +occurred. + +@subsubheading Errors +None. + + +@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions +@subsubsection @code{mysql_escape_string()} + +@findex @code{mysql_escape_string()} + +You should use @code{mysql_real_escape_string()} instead! + +This is identical to @code{mysql_real_escape_string()} except that it +takes the connection as the first +argument. @code{mysql_real_escape_string()} will escape the string +according to the current character set while +@code{mysql_escape_string()} does not respect the current charset +setting. + + +@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions +@subsubsection @code{mysql_fetch_field()} + +@findex @code{mysql_fetch_field()} + +@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} + +@subsubheading Description + +Returns the definition of one column of a result set as a @code{MYSQL_FIELD} +structure. Call this function repeatedly to retrieve information about all +columns in the result set. @code{mysql_fetch_field()} returns @code{NULL} +when no more fields are left. + +@code{mysql_fetch_field()} is reset to return information about the first +field each time you execute a new @code{SELECT} query. The field returned by +@code{mysql_fetch_field()} is also affected by calls to +@code{mysql_field_seek()}. + +If you've called @code{mysql_query()} to perform a @code{SELECT} on a table +but have not called @code{mysql_store_result()}, @strong{MySQL} returns the +default blob length (8K bytes) if you call @code{mysql_fetch_field()} to ask +for the length of a @code{BLOB} field. (The 8K size is chosen because +@strong{MySQL} doesn't know the maximum length for the @code{BLOB}. This +should be made configurable sometime.) Once you've retrieved the result set, +@code{field->max_length} contains the length of the largest value for this +column in the specific query. + +@subsubheading Return Values + +The @code{MYSQL_FIELD} structure for the current column. @code{NULL} +if no columns are left. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_FIELD *field; + +while((field = mysql_fetch_field(result))) +@{ + printf("field name %s\n", field->name); +@} +@end example + + +@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions +@subsubsection @code{mysql_fetch_fields()} + +@findex @code{mysql_fetch_fields()} + +@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} + +@subsubheading Description + +Returns an array of all @code{MYSQL_FIELD} structures for a result set. +Each structure provides the field definition for one column of the result +set. + +@subsubheading Return Values + +An array of @code{MYSQL_FIELD} structures for all columns of a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +unsigned int num_fields; +unsigned int i; +MYSQL_FIELD *fields; + +num_fields = mysql_num_fields(result); +fields = mysql_fetch_fields(result); +for(i = 0; i < num_fields; i++) +@{ + printf("Field %u is %s\n", i, fields[i].name); +@} +@end example + + +@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions +@subsubsection @code{mysql_fetch_field_direct()} + +@findex @code{mysql_fetch_field_direct()} + +@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} + +@subsubheading Description + +Given a field number @code{fieldnr} for a column within a result set, returns +that column's field definition as a @code{MYSQL_FIELD} structure. You may use +this function to retrieve the definition for an arbitrary column. The value +of @code{fieldnr} should be in the range from 0 to +@code{mysql_num_fields(result)-1}. + +@subsubheading Return Values + +The @code{MYSQL_FIELD} structure for the specified column. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +unsigned int num_fields; +unsigned int i; +MYSQL_FIELD *field; + +num_fields = mysql_num_fields(result); +for(i = 0; i < num_fields; i++) +@{ + field = mysql_fetch_field_direct(result, i); + printf("Field %u is %s\n", i, field->name); +@} +@end example + + +@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions +@subsubsection @code{mysql_fetch_lengths()} + +@findex @code{mysql_fetch_lengths()} + +@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} + +@subsubheading Description + +Returns the lengths of the columns of the current row within a result set. +If you plan to copy field values, this length information is also useful for +optimization, because you can avoid calling @code{strlen()}. In addition, if +the result set contains binary data, you @emph{must} use this function to +determine the size of the data, because @code{strlen()} returns incorrect +results for any field containing null characters. + +The length for empty columns and for columns containing @code{NULL} values is +zero. To see how to distinguish these two cases, see the description for +@code{mysql_fetch_row()}. + +@subsubheading Return Values + +An array of unsigned long integers representing the size of each column (not +including any terminating null characters). +@code{NULL} if an error occurred. + +@subsubheading Errors +@code{mysql_fetch_lengths()} is valid only for the current row of the result +set. It returns @code{NULL} if you call it before calling +@code{mysql_fetch_row()} or after retrieving all rows in the result. + +@subsubheading Example + +@example +MYSQL_ROW row; +unsigned long *lengths; +unsigned int num_fields; +unsigned int i; + +row = mysql_fetch_row(result); +if (row) +@{ + num_fields = mysql_num_fields(result); + lengths = mysql_fetch_lengths(result); + for(i = 0; i < num_fields; i++) + @{ + printf("Column %u is %lu bytes in length.\n", i, lengths[i]); + @} +@} +@end example + + +@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions +@subsubsection @code{mysql_fetch_row()} + +@findex @code{mysql_fetch_row()} + +@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} + +@subsubheading Description + +Retrieves the next row of a result set. When used after +@code{mysql_store_result()}, @code{mysql_fetch_row()} returns @code{NULL} +when there are no more rows to retrieve. When used after +@code{mysql_use_result()}, @code{mysql_fetch_row()} returns @code{NULL} when +there are no more rows to retrieve or if an error occurred. + +The number of values in the row is given by @code{mysql_num_fields(result)}. +If @code{row} holds the return value from a call to @code{mysql_fetch_row()}, +pointers to the values are accessed as @code{row[0]} to +@code{row[mysql_num_fields(result)-1]}. @code{NULL} values in the row are +indicated by @code{NULL} pointers. + +The lengths of the field values in the row may be obtained by calling +@code{mysql_fetch_lengths()}. Empty fields and fields containing +@code{NULL} both have length 0; you can distinguish these by checking +the pointer for the field value. If the pointer is @code{NULL}, the field +is @code{NULL}; otherwise the field is empty. + +@subsubheading Return Values + +A @code{MYSQL_ROW} structure for the next row. @code{NULL} if +there are no more rows to retrieve or if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +MYSQL_ROW row; +unsigned int num_fields; +unsigned int i; + +num_fields = mysql_num_fields(result); +while ((row = mysql_fetch_row(result))) +@{ + unsigned long *lengths; + lengths = mysql_fetch_lengths(result); + for(i = 0; i < num_fields; i++) + @{ + printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); + @} + printf("\n"); +@} +@end example + + +@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions +@subsubsection @code{mysql_field_count()} + +@findex @code{mysql_field_count()} + +@code{unsigned int mysql_field_count(MYSQL *mysql)} + +If you are using a version of @strong{MySQL} earlier than Version 3.22.24, you +should use @code{unsigned int mysql_num_fields(MYSQL *mysql)} instead. + +@subsubheading Description + +Returns the number of columns for the most recent query on the connection. + +The normal use of this function is when @code{mysql_store_result()} +returned @code{NULL} (and thus you have no result set pointer). +In this case, you can call @code{mysql_field_count()} to +determine whether or not @code{mysql_store_result()} should have produced a +non-empty result. This allows the client program to take proper action +without knowing whether or not the query was a @code{SELECT} (or +@code{SELECT}-like) statement. The example shown below illustrates how this +may be done. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +An unsigned integer representing the number of fields in a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; + +if (mysql_query(&mysql,query_string)) +@{ + // error +@} +else // query succeeded, process any data returned by it +@{ + result = mysql_store_result(&mysql); + if (result) // there are rows + @{ + num_fields = mysql_num_fields(result); + // retrieve rows, then call mysql_free_result(result) + @} + else // mysql_store_result() returned nothing; should it have? + @{ + if(mysql_field_count(&mysql) == 0) + @{ + // query does not return data + // (it was not a SELECT) + num_rows = mysql_affected_rows(&mysql); + @} + else // mysql_store_result() should have returned data + @{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); + @} + @} +@} +@end example + +An alternative is to replace the @code{mysql_field_count(&mysql)} call with +@code{mysql_errno(&mysql)}. In this case, you are checking directly for an +error from @code{mysql_store_result()} rather than inferring from the value +of @code{mysql_field_count()} whether or not the statement was a +@code{SELECT}. + + +@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions +@subsubsection @code{mysql_field_seek()} + +@findex @code{mysql_field_seek()} + +@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} + +@subsubheading Description + +Sets the field cursor to the given offset. The next call to +@code{mysql_fetch_field()} will retrieve the field definition of the column +associated with that offset. + +To seek to the beginning of a row, pass an @code{offset} value of zero. + +@subsubheading Return Values + +The previous value of the field cursor. + +@subsubheading Errors +None. + + +@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions +@subsubsection @code{mysql_field_tell()} + +@findex @code{mysql_field_tell()} + +@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} + +@subsubheading Description + +Returns the position of the field cursor used for the last +@code{mysql_fetch_field()}. This value can be used as an argument to +@code{mysql_field_seek()}. + +@subsubheading Return Values + +The current offset of the field cursor. + +@subsubheading Errors +None. + + +@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions +@subsubsection @code{mysql_free_result()} + +@findex @code{mysql_free_result()} + +@code{void mysql_free_result(MYSQL_RES *result)} + +@subsubheading Description + +Frees the memory allocated for a result set by @code{mysql_store_result()}, +@code{mysql_use_result()}, @code{mysql_list_dbs()}, etc. When you are done +with a result set, you must free the memory it uses by calling +@code{mysql_free_result()}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + + +@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions +@subsubsection @code{mysql_get_client_info()} + +@findex @code{mysql_get_client_info()} + +@code{char *mysql_get_client_info(void)} + +@subsubheading Description + +Returns a string that represents the client library version. + +@subsubheading Return Values + +A character string that represents the @strong{MySQL} client library version. + +@subsubheading Errors +None. + + +@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions +@subsubsection @code{mysql_get_host_info()} + +@findex @code{mysql_get_host_info()} + +@code{char *mysql_get_host_info(MYSQL *mysql)} + +@subsubheading Description + +Returns a string describing the type of connection in use, including the +server host name. + +@subsubheading Return Values + +A character string representing the server host name and the connection type. + +@subsubheading Errors +None. + + +@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions +@subsubsection @code{mysql_get_proto_info()} + +@findex @code{mysql_get_proto_info()} + +@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} + +@subsubheading Description + +Returns the protocol version used by current connection. + +@subsubheading Return Values + +An unsigned integer representing the protocol version used by the current +connection. + +@subsubheading Errors +None. + + +@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions +@subsubsection @code{mysql_get_server_info()} + +@findex @code{mysql_get_server_info()} + +@code{char *mysql_get_server_info(MYSQL *mysql)} + +@subsubheading Description + +Returns a string that represents the server version number. + +@subsubheading Return Values + +A character string that represents the server version number. + +@subsubheading Errors +None. + + +@node mysql_info, mysql_init, mysql_get_server_info, C API functions +@subsubsection @code{mysql_info()} + +@findex @code{mysql_info()} + +@code{char *mysql_info(MYSQL *mysql)} + +@subsubheading Description + +Retrieves a string providing information about the most recently executed +query, but only for the statements listed below. For other statements, +@code{mysql_info()} returns @code{NULL}. The format of the string varies +depending on the type of query, as described below. The numbers are +illustrative only; the string will contain values appropriate for the query. + +@table @code +@item INSERT INTO ... SELECT ... +String format: @code{Records: 100 Duplicates: 0 Warnings: 0} +@item INSERT INTO ... VALUES (...),(...),(...)... +String format: @code{Records: 3 Duplicates: 0 Warnings: 0} +@item LOAD DATA INFILE ... +String format: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0} +@item ALTER TABLE +String format: @code{Records: 3 Duplicates: 0 Warnings: 0} +@item UPDATE +String format: @code{Rows matched: 40 Changed: 40 Warnings: 0} +@end table + +Note that @code{mysql_info()} returns a non-@code{NULL} value for the +@code{INSERT ... VALUES} statement only if multiple value lists are +specified in the statement. + +@subsubheading Return Values + +A character string representing additional information about the most +recently executed query. @code{NULL} if no information is available for the +query. + +@subsubheading Errors +None. + + +@node mysql_init, mysql_insert_id, mysql_info, C API functions +@subsubsection @code{mysql_init()} + +@findex @code{mysql_init()} + +@code{MYSQL *mysql_init(MYSQL *mysql)} + +@subsubheading Description + +Allocates or initializes a @code{MYSQL} object suitable for +@code{mysql_real_connect()}. If @code{mysql} is a @code{NULL} pointer, the +function allocates, initializes, and returns a new object. Otherwise the +object is initialized and the address of the object is returned. If +@code{mysql_init()} allocates a new object, it will be freed when +@code{mysql_close()} is called to close the connection. + +@subsubheading Return Values + +An initialized @code{MYSQL*} handle. @code{NULL} if there was +insufficient memory to allocate a new object. + +@subsubheading Errors +In case of insufficient memory, @code{NULL} is returned. + + +@node mysql_insert_id, mysql_kill, mysql_init, C API functions +@subsubsection @code{mysql_insert_id()} + +@findex @code{mysql_insert_id()} + +@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} + +@subsubheading Description + +Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous +query. Use this function after you have performed an @code{INSERT} query +into a table that contains an @code{AUTO_INCREMENT} field. + +Note that @code{mysql_insert_id()} returns @code{0} if the previous query +does not generate an @code{AUTO_INCREMENT} value. If you need to save +the value for later, be sure to call @code{mysql_insert_id()} immediately +after the query that generates the value. + +Also note that the value of the SQL @code{LAST_INSERT_ID()} function always +contains the most recently generated @code{AUTO_INCREMENT} value, and is +not reset between queries because the value of that function is maintained +in the server. + +@subsubheading Return Values + +The value of the @code{AUTO_INCREMENT} field that was updated by the previous +query. Returns zero if there was no previous query on the connection or if +the query did not update an @code{AUTO_INCREMENT} value. + +@subsubheading Errors +None. + + +@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions +@subsubsection @code{mysql_kill()} + +@findex @code{mysql_kill()} + +@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} + +@subsubheading Description + +Asks the server to kill the thread specified by @code{pid}. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions +@subsubsection @code{mysql_list_dbs()} + +@findex @code{mysql_list_dbs()} + +@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of database names on the server that match +the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all databases. Calling +@code{mysql_list_dbs()} is similar to executing the query @code{SHOW +databases [LIKE wild]}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions +@subsubsection @code{mysql_list_fields()} + +@findex @code{mysql_list_fields()} + +@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of field names in the given table that match +the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all fields. Calling +@code{mysql_list_fields()} is similar to executing the query @code{SHOW +COLUMNS FROM tbl_name [LIKE wild]}. + +Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} +instead of @code{mysql_list_fields()}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions +@subsubsection @code{mysql_list_processes()} + +@findex @code{mysql_list_processes()} + +@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} + +@subsubheading Description + +Returns a result set describing the current server threads. This is the same +kind of information as that reported by @code{mysqladmin processlist} or +a @code{SHOW PROCESSLIST} query. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions +@subsubsection @code{mysql_list_tables()} + +@findex @code{mysql_list_tables()} + +@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of table names in the current database that +match the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all tables. Calling +@code{mysql_list_tables()} is similar to executing the query @code{SHOW +tables [LIKE wild]}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions +@subsubsection @code{mysql_num_fields()} + +@findex @code{mysql_num_fields()} +@findex @code{mysql_field_count()} + +@code{unsigned int mysql_num_fields(MYSQL_RES *result)} + +or + +@code{unsigned int mysql_num_fields(MYSQL *mysql)} + +The second form doesn't work on @strong{MySQL} Version 3.22.24 or newer. To pass a +@code{MYSQL*} argument, you must use +@code{unsigned int mysql_field_count(MYSQL *mysql)} instead. + +@subsubheading Description + +Returns the number of columns in a result set. + +Note that you can get the number of columns either from a pointer to a result +set or to a connection handle. You would use the connection handle if +@code{mysql_store_result()} or @code{mysql_use_result()} returned +@code{NULL} (and thus you have no result set pointer). In this case, you can +call @code{mysql_field_count()} to determine whether or not +@code{mysql_store_result()} should have produced a non-empty result. This +allows the client program to take proper action without knowing whether or +not the query was a @code{SELECT} (or @code{SELECT}-like) statement. The +example shown below illustrates how this may be done. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +An unsigned integer representing the number of fields in a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; + +if (mysql_query(&mysql,query_string)) +@{ + // error +@} +else // query succeeded, process any data returned by it +@{ + result = mysql_store_result(&mysql); + if (result) // there are rows + @{ + num_fields = mysql_num_fields(result); + // retrieve rows, then call mysql_free_result(result) + @} + else // mysql_store_result() returned nothing; should it have? + @{ + if (mysql_errno(&mysql)) + @{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); + @} + else if (mysql_field_count(&mysql) == 0) + @{ + // query does not return data + // (it was not a SELECT) + num_rows = mysql_affected_rows(&mysql); + @} + @} +@} +@end example + +An alternative (if you KNOW that your query should have returned a result set) +is to replace the @code{mysql_errno(&mysql)} call with a check if +@code{mysql_field_count(&mysql)} is = 0. This will only happen if something +went wrong. + + +@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions +@subsubsection @code{mysql_num_rows()} + +@findex @code{mysql_num_rows()} + +@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} + +@subsubheading Description + +Returns the number of rows in the result set. + +The use of @code{mysql_num_rows()} depends on whether you use +@code{mysql_store_result()} or @code{mysql_use_result()} to return the result +set. If you use @code{mysql_store_result()}, @code{mysql_num_rows()} may be +called immediately. If you use @code{mysql_use_result()}, +@code{mysql_num_rows()} will not return the correct value until all the rows +in the result set have been retrieved. + +@subsubheading Return Values + +The number of rows in the result set. + +@subsubheading Errors +None. + + +@node mysql_options, mysql_ping, mysql_num_rows, C API functions +@subsubsection @code{mysql_options()} + +@findex @code{mysql_options()} + +@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} + +@subsubheading Description + +Can be used to set extra connect options and affect behavior for a connection. +This function may be called multiple times to set several options. + +@code{mysql_options()} should be called after @code{mysql_init()} and before +@code{mysql_connect()} or @code{mysql_real_connect()}. + +The @code{option} argument is the option that you want to set; the @code{arg} +argument is the value for the option. If the option is an integer, then +@code{arg} should point to the value of the integer. + +Possible options values: + +@multitable @columnfractions .25 .25 .5 +@item @strong{Option} @tab @strong{Argument type} @tab @strong{Function} +@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds. +@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol. +@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a @strong{MySQL} server on NT. +@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the @strong{MySQL} server. Will automatically be re-executed when reconnecting. +@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}. +@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Read options from the named group from @file{my.cnf} or the file specified with @code{MYSQL_READ_DEFAULT_FILE}. +@end multitable + +Note that the group @code{client} is always read if you use +@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. + +The specified group in the option file may contain the following options: + +@multitable @columnfractions .3 .7 +@item @code{connect_timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server. +@item @code{compress} @tab Use the compressed client/server protocol. +@item @code{database} @tab Connect to this database if no database was specified in the connect command. +@item @code{debug} @tab Debug options. +@item @code{host} @tab Default host name. +@item @code{init-command} @tab Command to execute when connecting to @strong{MySQL} server. Will automatically be re-executed when reconnecting. +@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}. +@item @code{password} @tab Default password. +@item @code{pipe} @tab Use named pipes to connect to a @strong{MySQL} server on NT. +@item @code{port} @tab Default port number. +@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}. +@item @code{socket} @tab Default socket number. +@item +@item @code{user} @tab Default user. +@end multitable + +Note that @code{timeout} has been replaced by @code{connect_timeout}, but +@code{timeout} will still work for a while. + +For more information about option files, see @ref{Option files}. + +@subsubheading Return Values + +Zero for success. Non-zero if you used an unknown option. + +@subsubheading Example + +@example +MYSQL mysql; + +mysql_init(&mysql); +mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); +mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); +if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) +@{ + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +The above requests the client to use the compressed client/server protocol and +read the additional options from the @code{odbc} section in the @code{my.cnf} +file. + + +@node mysql_ping, mysql_query, mysql_options, C API functions +@subsubsection @code{mysql_ping()} + +@findex @code{mysql_ping()} + +@code{int mysql_ping(MYSQL *mysql)} + +@subsubheading Description + +Checks whether or not the connection to the server is working. If it has gone +down, an automatic reconnection is attempted. + +This function can be used by clients that remain idle for a long while, +to check whether or not the server has closed the connection and reconnect +if necessary. + +@subsubheading Return Values + +Zero if the server is alive. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_query, mysql_real_connect, mysql_ping, C API functions +@subsubsection @code{mysql_query()} + +@findex @code{mysql_query()} + +@code{int mysql_query(MYSQL *mysql, const char *query)} + +@subsubheading Description +Executes the SQL query pointed to by the null-terminated string @code{query}. +The query must consist of a single SQL statement. You should not add +a terminating semicolon (@samp{;}) or @code{\g} to the statement. + +@code{mysql_query()} cannot be used for queries that contain binary data; you +should use @code{mysql_real_query()} instead. (Binary data may contain the +@samp{\0} character, which @code{mysql_query()} interprets as the end of the +query string.) + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, , @code{mysql_field_count}}. + +@subsubheading Return Values + +Zero if the query was successful. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions +@subsubsection @code{mysql_real_connect()} + +@findex @code{mysql_real_connect()} + +@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, + unsigned int port, const char *unix_socket, + unsigned int client_flag)} + +@subsubheading Description + +@code{mysql_real_connect()} attempts to establish a connection to a +@strong{MySQL} database engine running on @code{host}. +@code{mysql_real_connect()} must complete successfully before you can execute +any of the other API functions, with the exception of +@code{mysql_get_client_info()}. + +The parameters are specified as follows: + +@itemize @bullet +@item +The first parameter should be the address of an existing @code{MYSQL} +structure. Before calling @code{mysql_real_connect()} you must call +@code{mysql_init()} to initialize the @code{MYSQL} structure. You can +change a lot of connect options with the @code{mysql_options()} +call. @xref{mysql_options}. + +@item +The value of @code{host} may be either a hostname or an IP address. If +@code{host} is @code{NULL} or the string @code{"localhost"}, a connection to +the local host is assumed. If the OS supports sockets (Unix) or named pipes +(Windows), they are used instead of TCP/IP to connect to the server. + +@item +The @code{user} parameter contains the user's @strong{MySQL} login ID. If +@code{user} is @code{NULL}, the current user is assumed. Under Unix, this is +the current login name. Under Windows ODBC, the current user name must be +specified explicitly. +@xref{ODBC administrator}. + +@item +The @code{passwd} parameter contains the password for @code{user}. If +@code{passwd} is @code{NULL}, only entries in the @code{user} table for the +user that have a blank (empty) password field will be checked for a match. This +allows the database administrator to set up the @strong{MySQL} privilege +system in such a way that users get different privileges depending on whether +or not they have specified a password. + +NOTE: Do not attempt to encrypt the password before calling +@code{mysql_real_connect()}; password encryption is handled automatically by +the client API. + +@item +@code{db} is the database name. +If @code{db} is not @code{NULL}, the connection will set the default +database to this value. + +@item +If @code{port} is not 0, the value will be used as the port number +for the TCP/IP connection. Note that the @code{host} parameter +determines the type of the connection. + +@item +If @code{unix_socket} is not @code{NULL}, the string specifies the +socket or named pipe that should be used. Note that the @code{host} +parameter determines the type of the connection. + +@item +The value of @code{client_flag} is usually 0, but can be set to a combination +of the following flags in very special circumstances: + +@multitable @columnfractions .25 .7 +@item @strong{Flag name} @tab @strong{Flag meaning} +@code{mysqld} to be more ODBC-friendly. +@item @code{CLIENT_COMPRESS} @tab Use compression protocol. +@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows. +@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words. +@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection. +@item @code{CLIENT_NO_SCHEMA} @tab Don't allow the @code{db_name.tbl_name.col_name} syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs. +@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes +@item @code{CLIENT_SSL} @tab Use SSL (encrypted protocol). +@end multitable +@end itemize + +@subsubheading Return Values + +A @code{MYSQL*} connection handle if the connection was successful, +@code{NULL} if the connection was unsuccessful. For a successful connection, +the return value is the same as the value of the first parameter, unless you +pass @code{NULL} for that parameter. + +@subsubheading Errors + +@table @code +@item CR_CONN_HOST_ERROR +Failed to connect to the @strong{MySQL} server. + +@item CR_CONNECTION_ERROR +Failed to connect to the local @strong{MySQL} server. + +@item CR_IPSOCK_ERROR +Failed to create an IP socket. + +@item CR_OUT_OF_MEMORY +Out of memory. + +@item CR_SOCKET_CREATE_ERROR +Failed to create a Unix socket. + +@item CR_UNKNOWN_HOST +Failed to find the IP address for the hostname. + +@item CR_VERSION_ERROR +A protocol mismatch resulted from attempting to connect to a server with a +client library that uses a different protocol version. This can happen if you +use a very old client library to connect to a new server that wasn't started +with the @code{--old-protocol} option. + +@item CR_NAMEDPIPEOPEN_ERROR +Failed to create a named pipe on Windows. + +@item CR_NAMEDPIPEWAIT_ERROR +Failed to wait for a named pipe on Windows. + +@item CR_NAMEDPIPESETSTATE_ERROR +Failed to get a pipe handler on Windows. + +@item CR_SERVER_LOST +If @code{connect_timeout} > 0 and it took longer then @code{connect_timeout} +seconds to connect to the server or if the server died while executing the +@code{init-command}. + +@end table + +@subsubheading Example + +@example +MYSQL mysql; + +mysql_init(&mysql); +mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); +if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) +@{ + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +By using @code{mysql_options()} the @strong{MySQL} library will read the +@code{[client]} and @code{your_prog_name} sections in the @code{my.cnf} +file which will ensure that your program will work, even if someone has +set up @strong{MySQL} in some non-standard way. + +Note that upon connection, @code{mysql_real_connect()} sets the @code{reconnect} +flag (part of the MYSQL structure) to a value of @code{1}. This flag indicates, +in the event that a query cannot be performed because of a lost connection, to +try reconnecting to the server before giving up. + + +@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions +@subsubsection @code{mysql_real_escape_string()} + +@findex @code{mysql_real_escape_string()} + +@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)} + +@subsubheading Description + +This function is used to create a legal SQL string that you can use in a +SQL statement. @xref{String syntax}. + +The string in @code{from} is encoded to an escaped SQL string, taking +into account the current character set of the connection. The result is placed +in @code{to} and a terminating null byte is appended. Characters +encoded are @code{NUL} (ASCII 0), @samp{\n}, @samp{\r}, @samp{\}, +@samp{'}, @samp{"}, and Control-Z (@pxref{Literals}). + +The string pointed to by @code{from} must be @code{length} bytes long. You +must allocate the @code{to} buffer to be at least @code{length*2+1} bytes +long. (In the worse case, each character may need to be encoded as using two +bytes, and you need room for the terminating null byte.) When +@code{mysql_escape_string()} returns, the contents of @code{to} will be a +null-terminated string. The return value is the length of the encoded +string, not including the terminating null character. + +@subsubheading Example + +@example +char query[1000],*end; + +end = strmov(query,"INSERT INTO test_table values("); +*end++ = '\''; +end += mysql_real_escape_string(&mysql, end,"What's this",11); +*end++ = '\''; +*end++ = ','; +*end++ = '\''; +end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); +*end++ = '\''; +*end++ = ')'; + +if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) +@{ + fprintf(stderr, "Failed to insert row, Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +The @code{strmov()} function used in the example is included in the +@code{mysqlclient} library and works like @code{strcpy()} but returns a +pointer to the terminating null of the first parameter. + +@subsubheading Return Values + +The length of the value placed into @code{to}, not including the +terminating null character. + +@subsubheading Errors +None. + + +@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions +@subsubsection @code{mysql_real_query()} + +@findex @code{mysql_real_query()} + +@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} + +@subsubheading Description + +Executes the SQL query pointed to by @code{query}, which should be a string +@code{length} bytes long. The query must consist of a single SQL statement. +You should not add a terminating semicolon (@samp{;}) or @code{\g} to the +statement. + +You @emph{must} use @code{mysql_real_query()} rather than +@code{mysql_query()} for queries that contain binary data, because binary data +may contain the @samp{\0} character. In addition, @code{mysql_real_query()} +is faster than @code{mysql_query()} because it does not call @code{strlen()} on +the query string. + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, @code{mysql_field_count}}. + +@subsubheading Return Values + +Zero if the query was successful. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions +@subsubsection @code{mysql_reload()} + +@findex @code{mysql_reload()} + +@code{int mysql_reload(MYSQL *mysql)} + +@subsubheading Description + +Asks the @strong{MySQL} server to reload the grant tables. The +connected user must have the @strong{reload} privilege. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{FLUSH PRIVILEGES} statement instead. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions +@subsubsection @code{mysql_row_seek()} + +@findex @code{mysql_row_seek()} + +@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} + +@subsubheading Description +Sets the row cursor to an arbitrary row in a query result set. This requires +that the result set structure contains the entire result of the query, so +@code{mysql_row_seek()} may be used in conjunction only with +@code{mysql_store_result()}, not with @code{mysql_use_result()}. + +The offset should be a value returned from a call to @code{mysql_row_tell()} +or to @code{mysql_row_seek()}. This value is not simply a row number; if you +want to seek to a row within a result set using a row number, use +@code{mysql_data_seek()} instead. + +@subsubheading Return Values + +The previous value of the row cursor. This value may be passed to a +subsequent call to @code{mysql_row_seek()}. + +@subsubheading Errors +None. + + +@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions +@subsubsection @code{mysql_row_tell()} + +@findex @code{mysql_row_tell()} + +@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} + +@subsubheading Description + +Returns the current position of the row cursor for the last +@code{mysql_fetch_row()}. This value can be used as an argument to +@code{mysql_row_seek()}. + +You should use @code{mysql_row_tell()} only after @code{mysql_store_result()}, +not after @code{mysql_use_result()}. + +@subsubheading Return Values + +The current offset of the row cursor. + +@subsubheading Errors +None. + + +@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions +@subsubsection @code{mysql_select_db()} + +@findex @code{mysql_select_db()} + +@code{int mysql_select_db(MYSQL *mysql, const char *db)} + +@subsubheading Description + +Causes the database specified by @code{db} to become the default (current) +database on the connection specified by @code{mysql}. In subsequent queries, +this database is the default for table references that do not include an +explicit database specifier. + +@code{mysql_select_db()} fails unless the connected user can be authenticated +as having permission to use the database. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions +@subsubsection @code{mysql_shutdown()} + +@findex @code{mysql_shutdown()} + +@code{int mysql_shutdown(MYSQL *mysql)} + +@subsubheading Description + +Asks the database server to shut down. The connected user must have +@strong{shutdown} privileges. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions +@subsubsection @code{mysql_stat()} + +@findex @code{mysql_stat()} + +@code{char *mysql_stat(MYSQL *mysql)} + +@subsubheading Description + +Returns a character string containing information similar to that provided by +the @code{mysqladmin status} command. This includes uptime in seconds and +the number of running threads, questions, reloads, and open tables. + +@subsubheading Return Values + +A character string describing the server status. @code{NULL} if an +error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions +@subsubsection @code{mysql_store_result()} + +@findex @code{mysql_store_result()} + +@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} + +@subsubheading Description + +You must call @code{mysql_store_result()} or @code{mysql_use_result()} +for every query that successfully retrieves data (@code{SELECT}, +@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). + +You don't have to call @code{mysql_store_result()} or +@code{mysql_use_result()} for other queries, but it will not do any +harm or cause any notable performance if you call @code{mysql_store_result()} +in all cases. You can detect if the query didn't have a result set by +checking if @code{mysql_store_result()} returns 0 (more about this later one). + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, @code{mysql_field_count}}. + +@code{mysql_store_result()} reads the entire result of a query to the client, +allocates a @code{MYSQL_RES} structure, and places the result into this +structure. + +@code{mysql_store_results()} returns a null pointer if the query didn't return +a result set (if the query was, for example, an @code{INSERT} statement). + +@code{mysql_store_results()} also returns a null pointer if reading of the +result set failed. You can check if you got an error by checking if +@code{mysql_error()} doesn't return a null pointer, if +@code{mysql_errno()} returns <> 0, or if @code{mysql_field_count()} +returns <> 0. + +An empty result set is returned if there are no rows returned. (An empty +result set differs from a null pointer as a return value.) + +Once you have called @code{mysql_store_result()} and got a result back +that isn't a null pointer, you may call @code{mysql_num_rows()} to find +out how many rows are in the result set. + +You can call @code{mysql_fetch_row()} to fetch rows from the result set, +or @code{mysql_row_seek()} and @code{mysql_row_tell()} to obtain or +set the current row position within the result set. + +You must call @code{mysql_free_result()} once you are done with the result +set. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result structure with the results. @code{NULL} if +an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions +@subsubsection @code{mysql_thread_id()} + +@findex @code{mysql_thread_id()} + +@code{unsigned long mysql_thread_id(MYSQL *mysql)} + +@subsubheading Description + +Returns the thread ID of the current connection. This value can be used as +an argument to @code{mysql_kill()} to kill the thread. + +If the connection is lost and you reconnect with @code{mysql_ping()}, the +thread ID will change. This means you should not get the thread ID and store +it for later. You should get it when you need it. + +@subsubheading Return Values + +The thread ID of the current connection. + +@subsubheading Errors +None. + + +@node mysql_use_result, , mysql_thread_id, C API functions +@subsubsection @code{mysql_use_result()} + +@findex @code{mysql_use_result()} + +@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} + +@subsubheading Description + +You must call @code{mysql_store_result()} or @code{mysql_use_result()} for +every query that successfully retrieves data (@code{SELECT}, @code{SHOW}, +@code{DESCRIBE}, @code{EXPLAIN}). + +@code{mysql_use_result()} initiates a result set retrieval but does not +actually read the result set into the client like @code{mysql_store_result()} +does. Instead, each row must be retrieved individually by making calls to +@code{mysql_fetch_row()}. This reads the result of a query directly from the +server without storing it in a temporary table or local buffer, which is +somewhat faster and uses much less memory than @code{mysql_store_result()}. +The client will only allocate memory for the current row and a communication +buffer that may grow up to @code{max_allowed_packet} bytes. + +On the other hand, you shouldn't use @code{mysql_use_result()} if you are +doing a lot of processing for each row on the client side, or if the output +is sent to a screen on which the user may type a @code{^S} (stop scroll). +This will tie up the server and prevent other threads from updating any +tables from which the data is being fetched. + +When using @code{mysql_use_result()}, you must execute +@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise the +unfetched rows will be returned as part of the result set for your next +query. The C API will give the error @code{Commands out of sync; You can't +run this command now} if you forget to do this! + +You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()}, +@code{mysql_row_tell()}, @code{mysql_num_rows()}, or +@code{mysql_affected_rows()} with a result returned from +@code{mysql_use_result()}, nor may you issue other queries until the +@code{mysql_use_result()} has finished. (However, after you have fetched all +the rows, @code{mysql_num_rows()} will accurately return the number of rows +fetched.) + +You must call @code{mysql_free_result()} once you are done with the result +set. + +@subsubheading Return Values + +A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node C API problems, Building clients, C API functions, C +@subsection Common questions and problems when using the C API + +@tindex @code{mysql_query()} +@tindex @code{mysql_store_result()} + +@menu +* NULL mysql_store_result:: +* Query results:: +* Getting unique ID:: +* C API linking problems:: +@end menu + + +@node NULL mysql_store_result, Query results, C API problems, C API problems +@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?} + +It is possible for @code{mysql_store_result()} to return @code{NULL} +following a successful call to @code{mysql_query()}. When this happens, it +means one of the following conditions occurred: + +@itemize @bullet +@item +There was a @code{malloc()} failure (for example, if the result set was too +large). + +@item +The data couldn't be read (an error occurred on the connection). + +@item +The query returned no data (for example, it was an @code{INSERT}, +@code{UPDATE}, or @code{DELETE}). +@end itemize + +You can always check whether or not the statement should have produced a +non-empty result by calling @code{mysql_field_count()}. If +@code{mysql_field_count()} returns zero, the result is empty and the last +query was a statement that does not return values (for example, an +@code{INSERT} or a @code{DELETE}). If @code{mysql_field_count()} returns a +non-zero value, the statement should have produced a non-empty result. +See the description of the @code{mysql_field_count()} function for an +example. + +You can test for an error by calling @code{mysql_error()} or +@code{mysql_errno()}. + +@cindex queries, C API results +@menu +* Query results:: +* Getting unique ID:: +* C API linking problems:: +@end menu + + +@node Query results, Getting unique ID, NULL mysql_store_result, C API problems +@subsubsection What Results Can I Get From a Query? + +In addition to the result set returned by a query, you can also get the +following information: + +@itemize @bullet +@item +@code{mysql_affected_rows()} returns the number of rows affected by the last +query when doing an @code{INSERT}, @code{UPDATE}, or @code{DELETE}. An +exception is that if @code{DELETE} is used without a @code{WHERE} clause, the +table is re-created empty, which is much faster! In this case, +@code{mysql_affected_rows()} returns zero for the number of records +affected. + +@item +@code{mysql_num_rows()} returns the number of rows in a result set. With +@code{mysql_store_result()}, @code{mysql_num_rows()} may be called as soon as +@code{mysql_store_result()} returns. With @code{mysql_use_result()}, +@code{mysql_num_rows()} may be called only after you have fetched all the +rows with @code{mysql_fetch_row()}. + +@item +@code{mysql_insert_id()} returns the ID generated by the last +query that inserted a row into a table with an @code{AUTO_INCREMENT} index. +@xref{mysql_insert_id, , @code{mysql_insert_id()}}. + +@item +Some queries (@code{LOAD DATA INFILE ...}, @code{INSERT INTO +... SELECT ...}, @code{UPDATE}) return additional information. The result is +returned by @code{mysql_info()}. See the description for @code{mysql_info()} +for the format of the string that it returns. @code{mysql_info()} returns a +@code{NULL} pointer if there is no additional information. +@end itemize + + +@node Getting unique ID, C API linking problems, Query results, C API problems +@subsubsection How Can I Get the Unique ID for the Last Inserted Row? + +@cindex unique ID +@cindex last row, unique ID +@cindex ID, unique +@cindex tables, unique ID for last row + +If you insert a record in a table containing a column that has the +@code{AUTO_INCREMENT} attribute, you can get the most recently generated +ID by calling the @code{mysql_insert_id()} function. + +You can also retrieve the ID by using the @code{LAST_INSERT_ID()} function in +a query string that you pass to @code{mysql_query()}. + +You can check if an @code{AUTO_INCREMENT} index is used by executing +the following code. This also checks if the query was an @code{INSERT} with +an @code{AUTO_INCREMENT} index: + +@example +if (mysql_error(&mysql)[0] == 0 && + mysql_num_fields(result) == 0 && + mysql_insert_id(&mysql) != 0) +@{ + used_id = mysql_insert_id(&mysql); +@} +@end example + +The most recently generated ID is maintained in the server on a +per-connection basis. It will not be changed by another client. It will not +even be changed if you update another @code{AUTO_INCREMENT} column with a +non-magic value (that is, a value that is not @code{NULL} and not @code{0}). + +If you want to use the ID that was generated for one table and insert +it into a second table, you can use SQL statements like this: + +@example +INSERT INTO foo (auto,text) + VALUES(NULL,'text'); # generate ID by inserting NULL +INSERT INTO foo2 (id,text) + VALUES(LAST_INSERT_ID(),'text'); # use ID in second table +@end example + + +@node C API linking problems, , Getting unique ID, C API problems +@subsubsection Problems Linking with the C API + +@cindex linking, problems +@cindex C API, linking problems + +When linking with the C API, the following errors may occur 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 + +If this happens on your system, you must include the math library by +adding @code{-lm} to the end of the compile/link line. + + +@node Building clients, Thread-safe clients, C API problems, C +@subsection Building Client Programs + +@cindex client programs, building +@cindex linking +@cindex building, client programs +@cindex programs, client + +If you compile @strong{MySQL} clients that you've written yourself or that +you obtain from a third party, they must be linked using the +@code{-lmysqlclient -lz} option on the link command. You may also need to +specify a @code{-L} option to tell the linker where to find the library. For +example, if the library is installed in @file{/usr/local/mysql/lib}, use +@code{-L/usr/local/mysql/lib -lmysqlclient -lz} on the link command. + +For clients that use @strong{MySQL} header files, you may need to specify a +@code{-I} option when you compile them (for example, +@code{-I/usr/local/mysql/include}), so the compiler can find the header +files. + + +@node Thread-safe clients, , Building clients, C +@subsection How to Make a Thread-safe Client + +@cindex clients, thread-safe +@cindex thread-safe clients + +The client library is almost thread safe. The biggest problem is +that the subroutines in @file{net.c} that read from sockets are not +interrupt safe. This was done with the thought that you might want to +have your own alarm that can break a long read to a server. If you +install interrupt handlers for the @code{SIGPIPE} interrupt, +the socket handling should be thread safe. + +In the older binaries we distribute on our Web site, the client +libraries are not normally compiled with the thread-safe option (the +Windows binaries are by default compiled to be thread safe). +Newer binary distributions should have both a normal and a +thread-safe client library. + +To get a really thread-safe client where you can interrupt the client +from other threads and set timeouts when talking with the @strong{MySQL} +server, you should use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} +libraries and the @code{net_serv.o} code that the server uses. + +If you don't need interrupts or timeouts, you can just compile a thread +safe client library @code{(mysqlclient_r)} and use this. @xref{C,, +MySQL C API}. In this case you don't have to worry about the +@code{net_serv.o} object file or the other @strong{MySQL} libraries. + +When using a threaded client and you want to use timeouts and interrupts, +you can make great use of the routines in the @file{thr_alarm.c} file. +If you are using routines from the @code{mysys} library, the only thing +you must remember is to call @code{my_init()} first! + +All functions except @code{mysql_real_connect()} are by default +thread safe. The following notes describe how to compile a thread safe +client library and use it in a thread-safe manner. (The notes below for +@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as +well, but because @code{mysql_connect()} is deprecated, you should be +using @code{mysql_real_connect()} anyway.) + +To make @code{mysql_real_connect()} thread safe, you must recompile the +client library with this command: + +@example +shell> ./configure --with-thread-safe-client +@end example + +This will create a thread-safe client library @code{libmysqlclient_r}. +@code{--with-thread-safe-client}. This library is thread safe per +connection. You can let two threads share the same connection as long +as you do the following: + +@itemize @bullet +@item +Two threads can't send a query to the @strong{MySQL} at the same time on +the same connection. In particular, you have to ensure that between a +@code{mysql_query()} and @code{mysql_store_result()} no other thread is using +the same connection. +@item +Many threads can access different result sets that are retrieved with +@code{mysql_store_result()}. +@item +If you use @code{mysql_use_result}, you have to ensure that no other thread +is asking anything on the same connection until the result set is closed. +However, it really is best for threaded clients that share the same +connection to use @code{mysql_use_result()}. +@item +If you want to use multiple threads on the same connection, you must +have a mutex lock around your @code{mysql_query()} and +@code{mysql_store_result()} call combination. Once +@code{mysql_store_result()} is ready, the lock can be released and other +threads may query the same connection. +@item +If you program with POSIX threads, you can use +@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} to +establish and release a mutex lock. +@end itemize + +You may get some errors because of undefined symbols when linking your +client with @code{mysqlclient_r}. In most cases this is because you haven't +included the thread libraries on the link/compile line. + + +@node Cplusplus, Java, C, Clients +@section MySQL C++ APIs + +@menu +* Borland C++:: +@end menu + + +@cindex C++ APIs + +Two APIs are available in the @strong{MySQL} +@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. + + +@node Borland C++, , Cplusplus, Cplusplus +@subsection Borland C++ + +@cindex Borland C++ compiler + +You can compile the @strong{MySQL} Windows source with Borland C++ 5.02. +(The Windows source includes only projects for Microsoft VC++, for +Borland C++ you have to do the project files yourself). + +One known problem with Borland C++ is that it uses a different structure +alignment than VC++. This means that you will run into problems if you +try to use the default @code{libmysql.dll} libraries (that was compiled +with VC++) with Borland C++. You can do one of the following to avoid +this problem. + +@itemize @bullet +@item +You can use the static @strong{MySQL} libraries for Borland C++ that you +can find on @uref{http://www.mysql.com/downloads/os-win32.html}. +@item +Only call @code{mysql_init()} with @code{NULL} as an argument, not a +pre-allocated MYSQL struct. +@end itemize + + +@node Java, Python, Cplusplus, Clients +@section MySQL Java Connectivity (JDBC) @cindex Java connectivity @cindex JDBC -@node Java, PHP, Eiffel, Clients -@section MySQL Java Connectivity (JDBC) There are 2 supported JDBC drivers for @strong{MySQL} (the mm driver and the Reisin JDBC driver). You can find a copy of the mm driver at @@ -43402,52 +41475,11 @@ the Reisin JDBC driver). You can find a copy of the mm driver at documentation consult any JDBC documentation and the driver's own documentation for @strong{MySQL}-specific features. -@cindex PHP API -@node PHP, Cplusplus, Java, Clients -@section MySQL PHP API -PHP is a server-side, HTML-embedded scripting language that may be used to -create dynamic Web pages. It contains support for accessing several -databases, including @strong{MySQL}. PHP may be run as a separate program -or compiled as a module for use with the Apache Web server. - -The distribution and documentation are available at the -@uref{http://www.php.net/, PHP web site}. - -@menu -* PHP problems:: Common problems with MySQL and PHP -@end menu - -@node PHP problems, , PHP, PHP -@subsection Common Problems with MySQL and PHP - -@itemize @bullet -@item Error: "Maximum Execution Time Exceeded" -This is a PHP limit; Go into the @file{php3.ini} file and set the maximum -execution time up from 30 seconds to something higher, as needed. -It is also not a bad idea to double the ram allowed per script to 16MB instead of -8 MB. -@item Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." -This means that your PHP version isn't compiled with @strong{MySQL} support. -You can either compile a dynamic @strong{MySQL} module and load it into PHP or -recompile PHP with built-in @strong{MySQL} support. This is described in -detail in the PHP manual. -@item Error: "undefined reference to `uncompress'" -This means that the client library is compiled with support for a compressed -client/server protocol. The fix is to add @code{-lz} last when linking -with @code{-lmysqlclient}. -@end itemize - -@cindex C++ APIs -@node Cplusplus, Python, PHP, Clients -@section MySQL C++ APIs - -Two APIs are available in the @strong{MySQL} -@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. +@node Python, Tcl, Java, Clients +@section MySQL Python APIs @cindex Python APIs -@node Python, Tcl, Cplusplus, Clients -@section MySQL Python APIs The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} contains a Python interface written by Joseph Skinner. @@ -43456,21 +41488,741 @@ You can also use the Python interface to iODBC to access a @strong{MySQL} server. @uref{http://starship.skyport.net/~lemburg/,mxODBC} -@cindex Tcl APIs -@node Tcl, , Python, Clients + +@node Tcl, Eiffel, Python, Clients @section MySQL Tcl APIs +@cindex Tcl APIs + @uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl at binevolve}. The @uref{http://www.mysql.com/Downloads/Contrib,Contrib directory} contains a Tcl interface that is based on msqltcl 1.50. +@node Eiffel, , Tcl, Clients +@section MySQL Eiffel wrapper + +@cindex Eiffel Wrapper +@cindex wrappers, Eiffel + +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains an Eiffel wrapper written by Michael Ravits. + +You can also find this at: +@url{http://www.netpedia.net/hosting/newplayer/} + + + + +@node Extending MySQL, Problems, Clients, Top +@chapter Extending MySQL + +@menu +* Adding functions:: +* Adding procedures:: +* MySQL internals:: +@end menu + + +@node Adding functions, Adding procedures, Extending MySQL, Extending MySQL +@section Adding New Functions to MySQL + +@cindex functions, new +@cindex adding, new functions +@cindex user-defined functions, adding +@cindex UDFs, defined +@cindex functions, user-defined + +There are two ways to add new functions to @strong{MySQL}: + +@itemize @bullet +@item You can add the function through the user-definable function (UDF) +interface. User-definable functions are added and removed dynamically using +the @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements. +@xref{CREATE FUNCTION, , @code{CREATE FUNCTION}}. + +@item You can add the function as a native (built in) @strong{MySQL} function. +Native functions are compiled into the @code{mysqld} server and become +available on a permanent basis. +@end itemize + +Each method has advantages and disadvantages: + +@itemize @bullet +@item +If you write a user-definable function, you must install the object file +in addition to the server itself. If you compile your function into the +server, you don't need to do that. +@item +You can add UDFs to a binary @strong{MySQL} distribution. Native functions +require you to modify a source distribution. +@item +If you upgrade your @strong{MySQL} distribution, you can continue to use your +previously installed UDFs. For native functions, you must repeat your +modifications each time you upgrade. +@end itemize + +Whichever method you use to add new functions, they may be used just like +native functions such as @code{ABS()} or @code{SOUNDEX()}. + +@menu +* CREATE FUNCTION:: +* Adding UDF:: Adding a new user-definable function +* Adding native function:: Adding a new native function +@end menu + + +@node CREATE FUNCTION, Adding UDF, Adding functions, Adding functions +@subsection @code{CREATE FUNCTION/DROP FUNCTION} Syntax + +@findex CREATE FUNCTION +@findex DROP FUNCTION +@findex UDF functions +@findex User-defined functions +@findex Functions, user-defined + +@example +CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} + SONAME shared_library_name + +DROP FUNCTION function_name +@end example + +A user-definable function (UDF) is a way to extend @strong{MySQL} with a new +function that works like native (built in) @strong{MySQL} functions such as +@code{ABS()} and @code{CONCAT()}. + +@code{AGGREGATE} is a new option for @strong{MySQL} Version 3.23. An +@code{AGGREGATE} function works exactly like a native @strong{MySQL} +@code{GROUP} function like @code{SUM} or @code{COUNT()}. + +@code{CREATE FUNCTION} saves the function's name, type, and shared library +name in the @code{mysql.func} system table. You must have the +@strong{insert} and @strong{delete} privileges for the @code{mysql} database +to create and drop functions. + +All active functions are reloaded each time the server starts, unless +you start @code{mysqld} with the @code{--skip-grant-tables} option. In +this case, UDF initialization is skipped and UDFs are unavailable. +(An active function is one that has been loaded with @code{CREATE FUNCTION} +and not removed with @code{DROP FUNCTION}.) + +For instructions on writing user-definable functions, see @ref{Adding +functions}. For the UDF mechanism to work, functions must be written in C or +C++, your operating system must support dynamic loading and you must have +compiled @code{mysqld} dynamically (not statically). + + + +@node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions +@subsection Adding a New User-definable Function + +@cindex adding, user-definable functions +@cindex user-defined functions, adding +@cindex functions, user-definable, adding + +@menu +* UDF calling sequences:: UDF calling sequences +* UDF arguments:: Argument processing +* UDF return values:: Return values and error handling +* UDF compiling:: Compiling and installing user-definable functions +@end menu + + +For the UDF mechanism to work, functions must be written in C or C++ and your +operating system must support dynamic loading. The @strong{MySQL} source +distribution includes a file @file{sql/udf_example.cc} that defines 5 new +functions. Consult this file to see how UDF calling conventions work. + +For @code{mysqld} to be able to use UDF functions, you should configure MySQL +with @code{--with-mysqld-ldflags=-rdynamic} The reason is that to on +many platforms (including Linux) you can load a dynamic library (with +@code{dlopen()}) from a static linked program, which you would get if +you are using @code{--with-mysqld-ldflags=-all-static} If you want to +use an UDF that needs to access symbols from @code{mysqld} (like the +@code{methaphone} example in @file{sql/udf_example.cc} that uses +@code{default_charset_info}), you must link the program with +@code{-rdynamic}. (see @code{man dlopen}). + +For each function that you want to use in SQL statements, you should define +corresponding C (or C++) functions. In the discussion below, the name +``xxx'' is used for an example function name. To distinquish between SQL and +C/C++ usage, @code{XXX()} (uppercase) indicates a SQL function call, and +@code{xxx()} (lowercase) indicates a C/C++ function call. + +The C/C++ functions that you write to implement the interface for +@code{XXX()} are: + +@table @asis +@item @code{xxx()} (required) +The main function. This is where the function result is computed. +The correspondence between the SQL type and return type of your C/C++ +function is shown below: + +@multitable @columnfractions .2 .8 +@item @strong{SQL type} @tab @strong{C/C++ type} +@item @code{STRING} @tab @code{char *} +@item @code{INTEGER} @tab @code{long long} +@item @code{REAL} @tab @code{double} +@end multitable + +@item @code{xxx_init()} (optional) +The initialization function for @code{xxx()}. It can be used to: + +@itemize @bullet +@item +Check the number of arguments to @code{XXX()}. +@item +Check that the arguments are of a required type or, alternatively, +tell @strong{MySQL} to coerce arguments to the types you want when +the main function is called. +@item +Allocate any memory required by the main function. +@item +Specify the maximum length of the result. +@item +Specify (for @code{REAL} functions) the maximum number of decimals. +@item +Specify whether or not the result can be @code{NULL}. +@end itemize + +@item @code{xxx_deinit()} (optional) +The deinitialization function for @code{xxx()}. It should deallocate any +memory allocated by the initialization function. +@end table + +When a SQL statement invokes @code{XXX()}, @strong{MySQL} calls the +initialization function @code{xxx_init()} to let it perform any required +setup, such as argument checking or memory allocation. If @code{xxx_init()} +returns an error, the SQL statement is aborted with an error message and the +main and deinitialization functions are not called. Otherwise, the main +function @code{xxx()} is called once for each row. After all rows have been +processed, the deinitialization function @code{xxx_deinit()} is called so it +can perform any required cleanup. + +All functions must be thread safe (not just the main function, +but the initialization and deinitialization functions as well). This means +that you are not allowed to allocate any global or static variables that +change! If you need memory, you should allocate it in @code{xxx_init()} +and free it in @code{xxx_deinit()}. + + +@node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF +@subsubsection UDF Calling Sequences + +@cindex calling sequences, UDF + +The main function should be declared as shown below. Note that the return +type and parameters differ, depending on whether you will declare the SQL +function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL} +in the @code{CREATE FUNCTION} statement: + +@noindent +For @code{STRING} functions: + +@example +char *xxx(UDF_INIT *initid, UDF_ARGS *args, + char *result, unsigned long *length, + char *is_null, char *error); +@end example + +@noindent +For @code{INTEGER} functions: + +@example +long long xxx(UDF_INIT *initid, UDF_ARGS *args, + char *is_null, char *error); +@end example + +@noindent +For @code{REAL} functions: + +@example +double xxx(UDF_INIT *initid, UDF_ARGS *args, + char *is_null, char *error); +@end example + +The initialization and deinitialization functions are declared like this: + +@example +my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); + +void xxx_deinit(UDF_INIT *initid); +@end example + +The @code{initid} parameter is passed to all three functions. It points to a +@code{UDF_INIT} structure that is used to communicate information between +functions. The @code{UDF_INIT} structure members are listed below. The +initialization function should fill in any members that it wishes to change. +(To use the default for a member, leave it unchanged.): + +@table @code +@item my_bool maybe_null +@code{xxx_init()} should set @code{maybe_null} to @code{1} if @code{xxx()} +can return @code{NULL}. The default value is @code{1} if any of the +arguments are declared @code{maybe_null}. + +@item unsigned int decimals +Number of decimals. The default value is the maximum number of decimals in +the arguments passed to the main function. (For example, if the function is +passed @code{1.34}, @code{1.345}, and @code{1.3}, the default would be 3, +because @code{1.345} has 3 decimals. + +@item unsigned int max_length +The maximum length of the string result. The default value differs depending +on the result type of the function. For string functions, the default is the +length of the longest argument. For integer functions, the default is 21 +digits. For real functions, the default is 13 plus the number of decimals +indicated by @code{initid->decimals}. (For numeric functions, the length +includes any sign or decimal point characters.) + +@item char *ptr +A pointer that the function can use for its own purposes. For example, +functions can use @code{initid->ptr} to communicate allocated memory +between functions. In @code{xxx_init()}, allocate the memory and assign it +to this pointer: + +@example +initid->ptr = allocated_memory; +@end example + +In @code{xxx()} and @code{xxx_deinit()}, refer to @code{initid->ptr} to use +or deallocate the memory. +@end table + + +@node UDF arguments, UDF return values, UDF calling sequences, Adding UDF +@subsubsection Argument Processing + +@cindex argument processing +@cindex processing, arguments + +The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the +members listed below: + +@table @code +@item unsigned int arg_count +The number of arguments. Check this value in the initialization function +if you want your function to be called with a particular number of arguments. +For example: + +@example +if (args->arg_count != 2) +@{ + strcpy(message,"XXX() requires two arguments"); + return 1; +@} +@end example + + +@item enum Item_result *arg_type +The types for each argument. The possible type values are +@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}. + +To make sure that arguments are of a given type and return an +error if they are not, check the @code{arg_type} array in the initialization +function. For example: + +@example +if (args->arg_type[0] != STRING_RESULT || + args->arg_type[1] != INT_RESULT) +@{ + strcpy(message,"XXX() requires a string and an integer"); + return 1; +@} +@end example + +As an alternative to requiring your function's arguments to be of particular +types, you can use the initialization function to set the @code{arg_type} +elements to the types you want. This causes @strong{MySQL} to coerce +arguments to those types for each call to @code{xxx()}. For example, to +specify coercion of the first two arguments to string and integer, do this in +@code{xxx_init()}: + +@example +args->arg_type[0] = STRING_RESULT; +args->arg_type[1] = INT_RESULT; +@end example + +@item char **args +@code{args->args} communicates information to the initialization function +about the general nature of the arguments your function was called with. For a +constant argument @code{i}, @code{args->args[i]} points to the argument +value. (See below for instructions on how to access the value properly.) +For a non-constant argument, @code{args->args[i]} is @code{0}. +A constant argument is an expression that uses only constants, such as +@code{3} or @code{4*7-2} or @code{SIN(3.14)}. A non-constant argument is an +expression that refers to values that may change from row to row, such as +column names or functions that are called with non-constant arguments. + +For each invocation of the main function, @code{args->args} contains the +actual arguments that are passed for the row currently being processed. + +Functions can refer to an argument @code{i} as follows: + +@itemize @bullet +@item +An argument of type @code{STRING_RESULT} is given as a string pointer plus a +length, to allow handling of binary data or data of arbitrary length. The +string contents are available as @code{args->args[i]} and the string length +is @code{args->lengths[i]}. You should not assume that strings are +null-terminated. + +@item +For an argument of type @code{INT_RESULT}, you must cast +@code{args->args[i]} to a @code{long long} value: + +@example +long long int_val; +int_val = *((long long*) args->args[i]); +@end example + +@item +For an argument of type @code{REAL_RESULT}, you must cast +@code{args->args[i]} to a @code{double} value: + +@example +double real_val; +real_val = *((double*) args->args[i]); +@end example +@end itemize + +@item unsigned long *lengths +For the initialization function, the @code{lengths} array indicates the +maximum string length for each argument. For each invocation of the main +function, @code{lengths} contains the actual lengths of any string arguments +that are passed for the row currently being processed. For arguments of +types @code{INT_RESULT} or @code{REAL_RESULT}, @code{lengths} still contains +the maximum length of the argument (as for the initialization function). +@end table + + +@node UDF return values, UDF compiling, UDF arguments, Adding UDF +@subsubsection Return Values and Error Handling + +@cindex UDFs, return values +@cindex return values, UDFs +@cindex errors, handling for UDFs +@cindex handling, errors + +The initialization function should return @code{0} if no error occurred and +@code{1} otherwise. If an error occurs, @code{xxx_init()} should store a +null-terminated error message in the @code{message} parameter. The message +will be returned to the client. The message buffer is +@code{MYSQL_ERRMSG_SIZE} characters long, but you should try to keep the +message to less than 80 characters so that it fits the width of a standard +terminal screen. + +The return value of the main function @code{xxx()} is the function value, for +@code{long long} and @code{double} functions. A string functions should +return a pointer to the result and store the length of the string in the +@code{length} arguments. @code{result} is a buffer at least 255 bytes long. +Set these to the contents and length of the return value. For example: + +@example +memcpy(result, "result string", 13); +*length = 13; +@end example + +If your string functions that needs to return a string longer than 255 +bytes, you must allocate the space for it with @code{malloc()} in your +@code{xxx_init()} function or your @code{xxx()} function and free it in +your @code{xxx_deinit()} function. You can store the allocated memory +in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by +future @code{xxx()} calls. @xref{UDF calling sequences}. + +To indicate a return value of @code{NULL} in the main function, set +@code{is_null} to @code{1}: + +@example +*is_null = 1; +@end example + +To indicate an error return in the main function, set the @code{error} +parameter to @code{1}: + +@example +*error = 1; +@end example + +If @code{xxx()} sets @code{*error} to @code{1} for any row, the function +value is @code{NULL} for the current row and for any subsequent rows +processed by the statement in which @code{XXX()} was invoked. (@code{xxx()} +will not even be called for subsequent rows.) @strong{NOTE:} In +@strong{MySQL} versions prior to 3.22.10, you should set both @code{*error} +and @code{*is_null}: + +@example +*error = 1; +*is_null = 1; +@end example + + +@node UDF compiling, , UDF return values, Adding UDF +@subsubsection Compiling and Installing User-definable Functions + +@cindex compiling, user-defined functions +@cindex UDFs, compiling +@cindex installing, user-defined functions + +Files implementing UDFs must be compiled and installed on the host where the +server runs. This process is described below for the example UDF file +@file{udf_example.cc} that is included in the @strong{MySQL} source +distribution. This file contains the following functions: + +@itemize @bullet +@item +@code{metaphon()} returns a metaphon string of the string argument. +This is something like a soundex string, but it's more tuned for English. +@item +@code{myfunc_double()} returns the sum of the ASCII values of the +characters in its arguments, divided by the sum of the length of its arguments. +@item +@code{myfunc_int()} returns the sum of the length of its arguments. +@item +@code{sequence([const int])} returns an sequence starting from the given +number or 1 if no number has been given. +@item +@code{lookup()} returns the IP number for a hostname. +@item +@code{reverse_lookup()} returns the hostname for an IP number. +The function may be called with a string @code{"xxx.xxx.xxx.xxx"} or +four numbers. +@end itemize + +A dynamically loadable file should be compiled as a sharable object file, +using a command something like this: + +@example +shell> gcc -shared -o udf_example.so myfunc.cc +@end example + +You can easily find out the correct compiler options for your system by +running this command in the @file{sql} directory of your @strong{MySQL} +source tree: + +@example +shell> make udf_example.o +@end example + +You should run a compile command similar to the one that @code{make} displays, +except that you should remove the @code{-c} option near the end of the line +and add @code{-o udf_example.so} to the end of the line. (On some systems, +you may need to leave the @code{-c} on the command.) + +Once you compile a shared object containing UDFs, you must install it +and tell @strong{MySQL} about it. Compiling a shared object from +@file{udf_example.cc} produces a file named something like +@file{udf_example.so} (the exact name may vary from platform to platform). +Copy this file to some directory searched by @code{ld}, such as +@file{/usr/lib}. On many systems, you can set the @code{LD_LIBRARY} or +@code{LD_LIBRARY_PATH} environment variable to point at the directory where +you have your UDF function files. The @code{dlopen} manual page tells you +which variable you should use on your system. You should set this in +@code{mysql.server} or @code{safe_mysqld} and restart @code{mysqld}. + +After the library is installed, notify @code{mysqld} about the new +functions with these commands: + +@example +mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; +mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; +mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; +@end example + +Functions can be deleted using @code{DROP FUNCTION}: + +@example +mysql> DROP FUNCTION metaphon; +mysql> DROP FUNCTION myfunc_double; +mysql> DROP FUNCTION myfunc_int; +mysql> DROP FUNCTION lookup; +mysql> DROP FUNCTION reverse_lookup; +@end example + +The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the +system table @code{func} in the @code{mysql} database. The function's name, +type and shared library name are saved in the table. You must have the +@strong{insert} and @strong{delete} privileges for the @code{mysql} database +to create and drop functions. + +You should not use @code{CREATE FUNCTION} to add a function that has already +been created. If you need to reinstall a function, you should remove it with +@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}. You +would need to do this, for example, if you recompile a new version of your +function, so that @code{mysqld} gets the new version. Otherwise the server +will continue to use the old version. + +Active functions are reloaded each time the server starts, unless you start +@code{mysqld} with the @code{--skip-grant-tables} option. In this case, UDF +initialization is skipped and UDFs are unavailable. (An active function is +one that has been loaded with @code{CREATE FUNCTION} and not removed with +@code{DROP FUNCTION}.) + + +@node Adding native function, , Adding UDF, Adding functions +@subsection Adding a New Native Function + +@cindex adding, native functions +@cindex native functions, adding +@cindex functions, native, adding + +The procedure for adding a new native function is described below. Note +that you cannot add native functions to a binary distribution because +the procedure involves modifying @strong{MySQL} source code. You must +compile @strong{MySQL} yourself from a source distribution. Also note +that if you migrate to another version of @strong{MySQL} (for example, +when a new version is released), you will need to repeat the procedure +with the new version. + +To add a new native @strong{MySQL} function, follow these steps: + +@enumerate +@item +Add one line to @file{lex.h} that defines the function name in the +@code{sql_functions[]} array. +@item +If the function prototype is simple (just takes zero, one, two or three +arguments), you should in lex.h specify SYM(FUNC_ARG#) (where # is the +number of arguments) as the second argument in the +@code{sql_functions[]} array and add a function that creates a function +object in @file{item_create.cc}. Take a look at @code{"ABS"} and +@code{create_funcs_abs()} for an example of this. + +If the function prototype is complicated (for example takes a variable number +of arguments), you should add two lines to @file{sql_yacc.yy}. One +indicates the preprocessor symbol that @code{yacc} should define (this +should be added at the beginning of the file). Then define the function +parameters and add an ``item'' with these parameters to the +@code{simple_expr} parsing rule. For an example, check all occurrences +of @code{ATAN} in @file{sql_yacc.yy} to see how this is done. +@item +In @file{item_func.h}, declare a class inheriting from @code{Item_num_func} or +@code{Item_str_func}, depending on whether your function returns a number or a +string. +@item +In @file{item_func.cc}, add one of the following declarations, depending +on whether you are defining a numeric or string function: +@example +double Item_func_newname::val() +longlong Item_func_newname::val_int() +String *Item_func_newname::Str(String *str) +@end example + +If you inherit your object from any of the standard items (like +@code{Item_num_func} you probably only have to define one of the above +functions and let the parent object take care of the other functions. +For example, the @code{Item_str_func} class defines a @code{val()} function +that executes @code{atof()} on the value returned by @code{::str()}. + +@item +You should probably also define the following object function: +@example +void Item_func_newname::fix_length_and_dec() +@end example +This function should at least calculate @code{max_length} based on the +given arguments. @code{max_length} is the maximum number of characters +the function may return. This function should also set @code{maybe_null += 0} if the main function can't return a @code{NULL} value. The +function can check if any of the function arguments can return +@code{NULL} by checking the arguments @code{maybe_null} variable. You +can take a look at @code{Item_func_mod::fix_length_and_dec} for a +typical example of how to do this. +@end enumerate + +All functions must be thread safe (In other words, don't use any global or +static variables in the functions without protecting them with mutexes). + +If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()} +or @code{::str()} you should set @code{null_value} to 1 and return 0. + +For @code{::str()} object functions, there are some additional +considerations to be aware of: + +@itemize @bullet +@item +The @code{String *str} argument provides a string buffer that may be +used to hold the result. (For more information about the @code{String} type, +take a look at the @file{sql_string.h} file.) +@item +The @code{::str()} function should return the string that holds the result or +@code{(char*) 0} if the result is @code{NULL}. +@item +All current string functions try to avoid allocating any memory unless +absolutely necessary! +@end itemize + + +@node Adding procedures, MySQL internals, Adding functions, Extending MySQL +@section Adding New Procedures to MySQL + +@cindex procedures, adding +@cindex adding, procedures +@cindex new procedures, adding + +In @strong{MySQL}, you can define a procedure in C++ that can access and +modify the data in a query before it is sent to the client. The modification +can be done on row-by-row or @code{GROUP BY} level. + +We have created an example procedure in @strong{MySQL} Version 3.23 to +show you what can be done. + +Additionally we recommend you to take a look at 'mylua', which you can find in the Contrib directory. @xref{Contrib}. Which this you can use the LUA +language to load a procedure at runtime into @code{mysqld}. + +@menu +* procedure analyse:: Procedure analyse +* Writing a procedure:: Writing a procedure. +@end menu + + +@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures +@subsection Procedure Analyse + +@code{analyse([max elements,[max memory]])} + +This procedure is defined in the @file{sql/sql_analyse.cc}. This +examines the result from your query and returns an analysis of the +results: + +@itemize @bullet +@item +@code{max elements} (default 256) is the maximum number of distinct values +@code{analyse} will notice per column. This is used by @code{analyse} to check if +the optimal column type should be of type @code{ENUM}. +@item +@code{max memory} (default 8192) is the maximum memory @code{analyse} should +allocate per column while trying to find all distinct values. +@end itemize + +@example +SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]]) +@end example + + +@node Writing a procedure, , procedure analyse, Adding procedures +@subsection Writing a Procedure + +For the moment, the only documentation for this is the source. + +You can find all information about procedures by examining the following files: + +@itemize @bullet +@item @file{sql/sql_analyse.cc} +@item @file{sql/procedure.h} +@item @file{sql/procedure.cc} +@item @file{sql/sql_select.cc} +@end itemize + + +@node MySQL internals, , Adding procedures, Extending MySQL +@section MySQL Internals @cindex internals @cindex threads -@node MySQL internals, Environment variables, Clients, Top -@chapter MySQL Internals This chapter describes a lot of things that you need to know when working on the @strong{MySQL} code. If you plan to contribute to MySQL @@ -43486,8 +42238,9 @@ This is a relatively low traffic list, in comparison with * MySQL test suite:: MySQL test suite @end menu + @node MySQL threads, MySQL test suite, MySQL internals, MySQL internals -@section MySQL Threads +@subsection MySQL Threads The @strong{MySQL} server creates the following threads: @@ -43533,10 +42286,12 @@ started to read and apply updates from the master. @code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED}, and replication threads. + +@node MySQL test suite, , MySQL threads, MySQL internals +@subsection MySQL Test Suite + @cindex mysqltest, MySQL Test Suite @cindex testing mysqld, mysqltest -@node MySQL test suite, , MySQL threads, MySQL internals -@section MySQL Test Suite Until recently, our main full-coverage test suite was based on proprietary customer data and for that reason has not been publicly available. The only @@ -43563,8 +42318,9 @@ applications. * Reporting mysqltest bugs:: @end menu + @node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite -@subsection Running the MySQL Test Suite +@subsubsection Running the MySQL Test Suite The test system consist of a test language interpreter (@code{mysqltest}), a shell script to run all @@ -43590,8 +42346,9 @@ You can run one individual test case with If one test fails, you should test running @code{mysql-test-run} with the @code{--force} option to check if any other tests fails. + @node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite -@subsection Extending the MySQL Test Suite +@subsubsection Extending the MySQL Test Suite You can use the @code{mysqltest} language to write your own test cases. Unfortunately, we have not yet written full documentation for it - we plan to @@ -43671,8 +42428,9 @@ attachments, you should ftp all the relevant files to: @end itemize + @node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite -@subsection Reporting bugs in the MySQL Test Suite +@subsubsection Reporting Bugs in the MySQL Test Suite If your @strong{MySQL} version doesn't pass the test suite you should do the following: @@ -43742,9 +42500,1720 @@ do that. Just specify the @code{--with-debug} options to @code{configure}! @xref{Installing source}. @end itemize + + + +@node Problems, Environment variables, Extending MySQL, Top +@appendix Problems and Common Errors + +@cindex problems, common errors +@cindex errors, common + +@menu +* What is crashing:: How to determine what is causing problems +* Crashing:: What to do if @strong{MySQL} keeps crashing +* Link errors:: Problems when linking with the @strong{MySQL} client library +* Common errors:: Some common errors when using @strong{MySQL} +* Full disk:: How @strong{MySQL} handles a full disk +* Temporary files:: Where @strong{MySQL} stores temporary files +* Problems with mysql.sock:: How to protect @file{/tmp/mysql.sock} +* Changing MySQL user:: How to run @strong{MySQL} as a normal user +* Resetting permissions:: How to reset a forgotten password. +* File permissions :: Problems with file permissions +* Not enough file handles:: File not found +* Using DATE:: Problems using @code{DATE} columns +* Timezone problems:: Timezone problems +* Case sensitivity:: Case sensitivity in searches +* Problems with NULL:: Problems with @code{NULL} values +* Problems with alias:: Problems with @code{alias} +* Deleting from related tables:: Deleting rows from related tables +* No matching rows:: Solving problems with no matching rows +* ALTER TABLE problems:: Problems with @code{ALTER TABLE}. +* Change column order:: How to change the order of columns in a table +* Temporary table problems:: +@end menu + +This chapter lists some common problems and error messages that users have +run into. You will learn how to figure out what the problem is, and what +to do to solve it. You will also find proper solutions to some common +problems. + + +@node What is crashing, Crashing, Problems, Problems +@appendixsec How to Determine What Is Causing Problems + +When you run into problems, the first thing you should do is to find out +which program / piece of equipment is causing problems: + +@itemize @bullet +@item +If you have one of the following symptoms, then it is probably a hardware +(like memory, motherboard, CPU, or hard disk) or kernel problem: +@itemize @minus +@item +The keyboard doesn't work. This can normally be checked by pressing +Caps Lock. If the Caps Lock light doesn't change you have to replace +your keyboard. (Before doing this, you should try to reboot +your computer and check all cables to the keyboard.) +@item +The mouse pointer doesn't move. +@item +The machine doesn't answer to a remote machine's pings. +@item +Different, unrelated programs don't behave correctly. +@item +If your system rebooted unexpectedly (a faulty user level program should +NEVER be able to take down your system). +@end itemize + +In this case you should start by checking all your cables and run some +diagnostic tool to check your hardware! +You should also check if there are any patches, updates, or service +packs for your operating system that could likely solve your problems. +Check also that all your libraries (like glibc) are up to date. + +It's always good to use a machine with ECC memory to discover +memory problems early! +@item +If your keyboard is locked up, you may be able to fix this by +logging into your machine from another machine and execute +@code{kbd_mode -a} on it. + +@item +Please examine your system log file (/var/log/messages or similar) for +reasons for your problems. If you think the problem is in @strong{MySQL} +then you should also examine @strong{MySQL}'s log files. @xref{Update log}. + +@item +If you don't think you have hardware problems, you should try to find +out which program is causing problems. + +Try using @code{top}, @code{ps}, @code{taskmanager}, or some similar program, +to check which program is taking all CPU or is locking the machine. + +@item +Check with @code{top}, @code{df}, or a similar program if you are out of +memory, disk space, open files, or some other critical resource. + +@item +If the problem is some runaway process, you can always try to kill it. If it +doesn't want to die, there is probably a bug in the operating system. +@end itemize + +If after you have examined all other possibilities and you have +concluded that it's the @strong{MySQL} server or a @strong{MySQL} client +that is causing the problem, it's time to do a bug report for our +mailing list or our support team. In the bug report, try to give a +very detailed description of how the system is behaving and what you think is +happening. You should also state why you think it's @strong{MySQL} that +is causing the problems. Take into consideration all the situations in +this chapter. State any problems exactly how they appear when you +examine your system. Use the 'cut and paste' method for any output +and/or error messages from programs and/or log files! + +Try to describe in detail which program is not working and all +symptoms you see! We have in the past received many bug reports that just +state "the system doesn't work". This doesn't provide us with any +information about what could be the problem. + +If a program fails, it's always useful to know: + +@itemize @bullet +@item +Has the program in question made a segmentation fault (core dumped)? +@item +Is the program taking the whole CPU? Check with @code{top}. Let the +program run for a while, it may be evaluating something heavy. +@item +If it's the @code{mysqld} server that is causing problems, can you +do @code{mysqladmin -u root ping} or @code{mysqladmin -u root processlist}? +@item +What does a client program say (try with @code{mysql}, for example) +when you try to connect to the @strong{MySQL} server? +Does the client jam? Do you get any output from the program? +@end itemize + +When sending a bug report, you should of follow the outlines +described in this manual. @xref{Asking questions}. + + +@node Crashing, Link errors, What is crashing, Problems +@appendixsec What to Do if MySQL Keeps Crashing + +@cindex crash, repeated + +All @strong{MySQL} versions are tested on many platforms before they are +released. This doesn't mean that there aren't any bugs in +@strong{MySQL}, but it means if there are bugs, they are very few and can be +hard to find. If you have a problem, it will always help if you try to +find out exactly what crashes your system, as you will have a much better +chance of getting this fixed quickly. + +First, you should try to find out whether the problem is that the +@code{mysqld} daemon dies or whether your problem has to do with your +client. You can check how long your @code{mysqld} server has been up by +executing @code{mysqladmin version}. If @code{mysqld} has died, you may +find the reason for this in the file +@file{mysql-data-directory/`hostname`.err}. @xref{Error log}. + +Many crashes of @strong{MySQL} are caused by corrupted index / data +files. @strong{MySQL} will update the data on disk, with the +@code{write()} system call, after every SQL statement and before the +client is notified about the result. (This is not true if you are running +with @code{delayed_key_writes}, in which case only the data is written.) +This means that the data is safe even if @code{mysqld} crashes, as the OS will +ensure that the not flushed data is written to disk. You can force +@strong{MySQL} to sync everything to disk after every SQL command by +starting @code{mysqld} with @code{--flush}. + +The above means that normally you shouldn't get corrupted tables unless: + +@itemize @bullet +@item +Someone/something killed @code{mysqld} or the machine in the middle +of an update. +@item +You have found a bug in @code{mysqld} that caused it to die in the +middle of an update. +@item +Someone is manipulating the data/index files outside of @strong{mysqld} +without locking the table properly. +@item +If you are running many @code{mysqld} servers on the same data on a +system that doesn't support good file system locks (normally handled by +the @code{lockd} daemon ) or if you are running +multiple servers with @code{--skip-locking} +@item +You have a crashed index/data file that contains very wrong data that +got @code{mysqld} confused. +@item +You have found a bug in the data storage code. This isn't that likely, +but it's at least possible. In this case you can try to change the file +type to another database handler by using @code{ALTER TABLE} on a +repaired copy of the table! +@end itemize + +Because it is very difficult to know why something is crashing, first try to +check whether or not things that work for others crash for you. Please try +the following things: + +@itemize @bullet +@item +Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run +@code{myisamchk --silent --force */*.MYI} on all tables, and restart the +@code{mysqld} daemon. This will ensure that you are running from a clean +state. @xref{MySQL Database Administration}. + +@item +Use @code{mysqld --log} and try to determine from the information in the log +whether or not some specific query kills the server. About 95% of all bugs are +related to a particular query! Normally this is one of the last queries in +the log file just before @strong{MySQL} restarted. @xref{Query log}. +If you can repeatadly kill @strong{MySQL} with one of the queries, even +when you have checked all tables just before doing the query, then you +have been able to locate the bug and should do a bug report for this! +@xref{Bug reports}. + +@item +Try to make a test case that we can use to reproduce the problem. +@xref{Reproduceable test case}. + +@item +Try running the included mysql-test test and the @strong{MySQL} +benchmarks. @xref{MySQL test suite}. They should test @strong{MySQL} +rather well. You can also add code that to the benchmarks to simulates +your application! The benchmarks can be found in the @file{bench} +directory in the source distribution or, for a binary distribution, in +the @file{sql-bench} directory under your @strong{MySQL} installation +directory. + +@item +Try @code{fork_test.pl} and @code{fork2_test.pl}. + +@item +If you configure @strong{MySQL} for debugging, it will be much easier to +gather information about possible errors if something goes wrong. +Reconfigure @strong{MySQL} with the @code{--with-debug} option or +@code{--with-debug=full} to @code{configure} and then recompile. +@xref{Debugging server}. + +@item +Configuring @strong{MySQL} for debugging causes a safe memory allocator to be +included that can find some errors. It also provides a lot of output about +what is happening. + +@item +Have you applied the latest patches for your operating system? + +@item +Use the @code{--skip-locking} option to @code{mysqld}. On some systems, the +@code{lockd} lock manager does not work properly; the @code{--skip-locking} +option tells @code{mysqld} not to use external locking. (This means that you +cannot run 2 @code{mysqld} servers on the same data and that you must be +careful if you use @code{myisamchk}, but it may be instructive to try the +option as a test.) + +@item +Have you tried @code{mysqladmin -u root processlist} when @code{mysqld} +appears to be running but not responding? Sometimes @code{mysqld} is not +comatose even though you might think so. The problem may be that all +connections are in use, or there may be some internal lock problem. +@code{mysqladmin processlist} will usually be able to make a connection even +in these cases, and can provide useful information about the current number +of connections and their status. + +@item +Run the command @code{mysqladmin -i 5 status} or @code{mysqladmin -i 5 +-r status} or in a separate window to produce statistics while you run +your other queries. + +@item +Try the following: +@enumerate +@item +Start @code{mysqld} from @code{gdb} (or in another debugger). +@xref{Using gdb on mysqld}. + +@item +Run your test scripts. + +@item +Print the backtrace and the local variables at the 3 lowest levels. In gdb you +can do this with the following commands when @code{mysqld} has crashed inside +gdb: + +@example +backtrace +info local +up +info local +up +info local +@end example + +With gdb you can also examine which threads exist with @code{info +threads} and switch to a specific thread with @code{thread #}, where +@code{#} is the thread id. +@end enumerate + +@item +Try to simulate your application with a Perl script to force +@strong{MySQL} to crash or misbehave. + +@item +Send a normal bug report. @xref{Bug reports}. Be even more detailed +than usual. Because @strong{MySQL} works for many people, it may be that the +crash results from something that exists only on your computer (for example, +an error that is related to your particular system libraries). +@item +If you have a problem with tables with dynamic-length rows and you are +not using @code{BLOB/TEXT} columns (but only @code{VARCHAR} columns), you +can try to change all @code{VARCHAR} to @code{CHAR} with @code{ALTER +TABLE}. This will force @strong{MySQL} to use fixed-size rows. +Fixed-size rows take a little extra space, but are much more tolerant to +corruption! + +The current dynamic row code has been in use at @strong{MySQL AB} for at +least 3 years without any problems, but by nature dynamic-length rows are +more prone to errors, so it may be a good idea to try the above to see if +it helps! +@end itemize + + +@node Link errors, Common errors, Crashing, Problems +@appendixsec Problems When Linking with the MySQL Client Library + +@cindex linking, errors +@cindex errors, linking +@cindex problems, linking + +If you are linking your program and you get errors for unreferenced +symbols that start with @code{mysql_}, like the following: + +@example +/tmp/ccFKsdPa.o: In function `main': +/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init' +/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect' +/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect' +/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error' +/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close' +@end example + +you should be able to solve this by adding @code{-Lpath-to-the-mysql-library +-lmysqlclient} @strong{LAST} on your link line. + +If you get @code{undefined reference} errors for the @code{uncompress} +or @code{compress} function, add @code{-lz} @strong{LAST} on your link +line and try again! + +If you get @code{undefined reference} errors for functions that should +exist on your system, like @code{connect}, check the man page for the +function in question, for which libraries you should add to the link +line! + +If you get @code{undefined reference} errors for functions that don't +exist on your system, like the following: + +@example +mf_format.o(.text+0x201): undefined reference to `__lxstat' +@end example + +it usually means that your library is compiled on a system that is not +100 % compatible with yours. In this case you should download the +latest @strong{MySQL} source distribution and compile this yourself. +@xref{Installing source}. + +If you are trying to run a program and you then get errors for +unreferenced symbols that start with @code{mysql_} or that the +@code{mysqlclient} library can't be found, this means that your system +can't find the share @code{libmysqlclient.so} library. + +The fix for this is to tell your system to search after shared +libraries where the library is located by one of the following methods: + +@itemize @bullet +@item +Add the path to the directory where you have @code{libmysqlclient.so} the +@code{LD_LIBRARY_PATH} environment variable. +@item +Add the path to the directory where you have @code{libmysqlclient.so} the +@code{LD_LIBRARY} environment variable. +@item +Copy @code{libmysqlclient.so} to some place that is searched by your system, +like @file{/lib}, and update the shared library information by executing +@code{ldconfig}. +@end itemize + +Another way to solve this problem is to link your program statically, with +@code{-static}, or by removing the dynamic @strong{MySQL} libraries +before linking your code. In the second case you should be +sure that no other programs are using the dynamic libraries! + + +@node Common errors, Full disk, Link errors, Problems +@appendixsec Some Common Errors When Using MySQL + +@cindex errors, list of + +@menu +* Error Access denied:: @code{Access denied} Error +* Gone away:: @code{MySQL server has gone away} error +* Can not connect to server:: @code{Can't connect to [local] MySQL server} error +* Blocked host:: @code{Host '...' is blocked} error +* Too many connections:: @code{Too many connections} error +* Non-transactional tables:: @code{Some non-transactional changed tables couldn't be rolled back} Error +* Out of memory:: @code{Out of memory} error +* Packet too large:: @code{Packet too large} error +* Communication errors:: Communication errors / Aborted connection +* Full table:: @code{The table is full} error +* Cannot create:: @code{Can't create/write to file} Error +* Commands out of sync:: @code{Commands out of sync} error in client +* Ignoring user:: @code{Ignoring user} error +* Cannot find table:: @code{Table 'xxx' doesn't exist} error +* Cannot initialize character set:: +@end menu + + +This section lists some errors that users frequently get. You will find +descriptions of the errors, and how to solve the problem here. + + +@node Error Access denied, Gone away, Common errors, Common errors +@appendixsubsec @code{Access denied} Error + +@cindex errors, access denied +@cindex problems, access denied errors +@cindex access denied errors + +@xref{Privileges}, and especially. @xref{Access denied}. + + +@node Gone away, Can not connect to server, Error Access denied, Common errors +@appendixsubsec @code{MySQL server has gone away} Error + +This section also covers the related @code{Lost connection to server +during query} error. + +The most common reason for the @code{MySQL server has gone away} error +is that the server timed out and closed the connection. By default, the +server closes the connection after 8 hours if nothing has happened. You +can change the time limit by setting the @code{wait_timeout} variable when +you start @code{mysqld}. + +Another common reason to receive the @code{MySQL server has gone away} error +is because you have issued a ``close'' on your @strong{MySQL} connection +and then tried to run a query on the closed connection. + +You can check that the @strong{MySQL} hasn't died by executing +@code{mysqladmin version} and examining the uptime. + +If you have a script, you just have to issue the query again for the client +to do an automatic reconnection. + +You normally can get the following error codes in this case +(which one you get is OS-dependent): + +@multitable @columnfractions .3 .7 +@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the +server. +@item @code{CR_SERVER_LOST} @tab The client didn't get an error when writing +to the server, but it didn't get a full answer (or any answer) to the question. +@end multitable + +You can also get these errors if you send a query to the server that is +incorrect or too large. If @code{mysqld} gets a packet that is too large +or out of order, it assumes that something has gone wrong with the client and +closes the connection. If you need big queries (for example, if you are +working with big @code{BLOB} columns), you can increase the query limit by +starting @code{mysqld} with the @code{-O max_allowed_packet=#} option +(default 1M). The extra memory is allocated on demand, so @code{mysqld} will +use more memory only when you issue a big query or when @code{mysqld} must +return a big result row! + + +@node Can not connect to server, Blocked host, Gone away, Common errors +@appendixsubsec @code{Can't connect to [local] MySQL server} error + +A @strong{MySQL} client on Unix can connect to the @code{mysqld} server in two +different ways: Unix sockets, which connect through a file in the file +system (default @file{/tmp/mysqld.sock}) or TCP/IP, which connects +through a port number. Unix sockets are faster than TCP/IP but can only +be used when connecting to a server on the same computer. Unix sockets +are used if you don't specify a hostname or if you specify the special +hostname @code{localhost}. + +On Windows you can connect only with TCP/IP if the @code{mysqld} server +is running on Win95/Win98. If it's running on NT, you can also connect +with named pipes. The name of the named pipe is @strong{MySQL}. If you +don't give a hostname when connecting to @code{mysqld}, a @strong{MySQL} client +will first try to connect to the named pipe, and if this doesn't work it +will connect to the TCP/IP port. You can force the use of named pipes +on Windows by using @code{.} as the hostname. + +The error (2002) @code{Can't connect to ...} normally means that there +isn't a @strong{MySQL} server running on the system or that you are +using a wrong socket file or TCP/IP port when trying to connect to the +@code{mysqld} server. + +Start by checking (using @code{ps} or the task manager on Windows) that +there is a process running named @code{mysqld} on your server! If there +isn't any @code{mysqld} process, you should start one. @xref{Starting +server}. + +If a @code{mysqld} process is running, you can check the server by +trying these different connections (the port number and socket pathname +might be different in your setup, of course): + +@example +shell> mysqladmin version +shell> mysqladmin variables +shell> mysqladmin -h `hostname` version variables +shell> mysqladmin -h `hostname` --port=3306 version +shell> mysqladmin -h 'ip for your host' version +shell> mysqladmin --socket=/tmp/mysql.sock version +@end example + +Note the use of backquotes rather than forward quotes with the @code{hostname} +command; these cause the output of @code{hostname} (that is, the current +hostname) to be substituted into the @code{mysqladmin} command. + +Here are some reasons the @code{Can't connect to local MySQL server} +error might occur: + +@itemize @bullet +@item +@code{mysqld} is not running. +@item +You are running on a system that uses MIT-pthreads. +If you are running on a system that doesn't have native threads, +@code{mysqld} uses the MIT-pthreads package. @xref{Which OS}. However, +all MIT-pthreads versions doesn't support Unix sockets. On a system +without sockets support you must always specify the hostname explicitly +when connecting to the server. Try using this command to check the +connection to the server: +@example +shell> mysqladmin -h `hostname` version +@end example +@item +Someone has removed the Unix socket that @code{mysqld} uses (default +@file{/tmp/mysqld.sock}). You might have a @code{cron} job that removes +the @strong{MySQL} socket (for example, a job that removes old files +from the @file{/tmp} directory). You can always run @code{mysqladmin +version} and check that the socket @code{mysqladmin} is trying to use +really exists. The fix in this case is to change the @code{cron} job to +not remove @file{mysqld.sock} or to place the socket somewhere else. You +can specify a different socket location at @strong{MySQL} configuration +time with this command: +@example +shell> ./configure --with-unix-socket-path=/path/to/socket +@end example +You can also start @code{safe_mysqld} with the +@code{--socket=/path/to/socket} option and set the environment variable +@code{MYSQL_UNIX_PORT} to the socket pathname before starting your +@strong{MySQL} clients. +@item +You have started the @code{mysqld} server with +the @code{--socket=/path/to/socket} option. If you change the socket +pathname for the server, you must also notify the @strong{MySQL} clients +about the new path. You can do this by setting the environment variable +@code{MYSQL_UNIX_PORT} to the socket pathname or by providing the socket path +as an argument to the clients. You can test the socket with this command: + +@example +shell> mysqladmin --socket=/path/to/socket version +@end example +@item +You are using Linux and one thread has died (core dumped). In this case +you must kill the other @code{mysqld} threads (for example, with the +@code{mysql_zap} script before you can start a new @strong{MySQL} +server. @xref{Crashing}. +@item +You may not have read and write privilege to either the directory that holds +the socket file or privilege to the socket file itself. In this case you +have to either change the privilege for the directory / file or restart +@code{mysqld} so that it uses a directory that you can access. +@end itemize + +If you get the error message @code{Can't connect to MySQL server on +some_hostname}, you can try the following things to find out what the +problem is : + +@itemize @bullet +@item +Check if the server is up by doing @code{telnet your-host-name +tcp-ip-port-number} and press @code{RETURN} a couple of times. If there +is a @strong{MySQL} server running on this port you should get a +responses that includes the version number of the running @strong{MySQL} +server. If you get an error like @code{telnet: Unable to connect to +remote host: Connection refused}, then there is no server running on the +given port. +@item +Try connecting to the @code{mysqld} daemon on the local machine and check +the TCP/IP port that @code{mysqld} it's configured to use (variable @code{port}) with +@code{mysqladmin variables}. +@item +Check that your @code{mysqld} server is not started with the +@code{--skip-networking} option. +@end itemize + + +@node Blocked host, Too many connections, Can not connect to server, Common errors +@appendixsubsec @code{Host '...' is blocked} Error + +If you get an error like this: + +@example +Host 'hostname' is blocked because of many connection errors. +Unblock with 'mysqladmin flush-hosts' +@end example + +this means that @code{mysqld} has gotten a lot (@code{max_connect_errors}) +of connect requests from the host @code{'hostname'} that have been interrupted +in the middle. After @code{max_connect_errors} failed requests, @code{mysqld} +assumes that something is wrong (like an attack from a cracker), and +blocks the site from further connections until someone executes the command +@code{mysqladmin flush-hosts}. + +By default, @code{mysqld} blocks a host after 10 connection errors. +You can easily adjust this by starting the server like this: + +@example +shell> safe_mysqld -O max_connect_errors=10000 & +@end example + +Note that if you get this error message for a given host, you should first +check that there isn't anything wrong with TCP/IP connections from that +host. If your TCP/IP connections aren't working, it won't do you any good to +increase the value of the @code{max_connect_errors} variable! + + +@node Too many connections, Non-transactional tables, Blocked host, Common errors +@appendixsubsec @code{Too many connections} Error + +If you get the error @code{Too many connections} when you try to connect +to @strong{MySQL}, this means that there is already @code{max_connections} +clients connected to the @code{mysqld} server. + +If you need more connections than the default (100), then you should restart +@code{mysqld} with a bigger value for the @code{max_connections} variable. + +Note that @code{mysqld} actually allows (@code{max_connections}+1) +clients to connect. The last connection is reserved for a user with the +@strong{process} privilege. By not giving this privilege to normal +users (they shouldn't need this), an administrator with this privilege +can log in and use @code{SHOW PROCESSLIST} to find out what could be +wrong. @xref{SHOW}. + +The maximum number of connects @strong{MySQL} is depending on how good +the thread library is on a given platform. Linux or Solaris should be +able to support 500-1000 simultaneous connections, depending on how much +RAM you have and what your clients are doing. + +@node Non-transactional tables, Out of memory, Too many connections, Common errors +@appendixsubsec @code{Some non-transactional changed tables couldn't be rolled back} Error + +@cindex Non-transactional tables + +If you get the error/warning: @code{Warning: Some non-transactional +changed tables couldn't be rolled back} when trying to do a +@code{ROLLBACK}, this means that some of the tables you used in the +transaction didn't support transactions. These non-transactional tables +will not be affected by the @code{ROLLBACK} statement. + +The most typical case when this happens is when you have tried to create +a table of a type that is not supported by your @code{mysqld} binary. +If @code{mysqld} doesn't support a table type (or if the table type is +disabled by a startup option) , it will instead create the table type +with the table type that is most resembles to the one you requested, +probably @code{MyISAM}. + +You can check the table type for a table by doing: + +@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. + +You can check the extensions your @code{mysqld} binary supports by doing: + +@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. + + +@node Out of memory, Packet too large, Non-transactional tables, Common errors +@appendixsubsec @code{Out of memory} Error + +If you issue a query and get something like the following error: + +@example +mysql: Out of memory at line 42, 'malloc.c' +mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) +ERROR 2008: MySQL client ran out of memory +@end example + +note that the error refers to the @strong{MySQL} client @code{mysql}. The +reason for this error is simply that the client does not have enough memory to +store the whole result. + +To remedy the problem, first check that your query is correct. Is it +reasonable that it should return so many rows? If so, +you can use @code{mysql --quick}, which uses @code{mysql_use_result()} +to retrieve the result set. This places less of a load on the client (but +more on the server). + + +@node Packet too large, Communication errors, Out of memory, Common errors +@appendixsubsec @code{Packet too large} Error + +When a @strong{MySQL} client or the @code{mysqld} server gets a packet bigger +than @code{max_allowed_packet} bytes, it issues a @code{Packet too large} +error and closes the connection. + +If you are using the @code{mysql} client, you may specify a bigger buffer by +starting the client with @code{mysql --set-variable=max_allowed_packet=8M}. + +If you are using other clients that do not allow you to specify the maximum +packet size (such as @code{DBI}), you need to set the packet size when you +start the server. You cau use a command-line option to @code{mysqld} to set +@code{max_allowed_packet} to a larger size. For example, if you are +expecting to store the full length of a @code{BLOB} into a table, you'll need +to start the server with the @code{--set-variable=max_allowed_packet=16M} +option. + + +@node Communication errors, Full table, Packet too large, Common errors +@appendixsubsec Communication Errors / Aborted Connection + +@cindex aborted clients +@cindex aborted connection +@cindex connection, aborted + +Starting with @code{MySQL 3.23.40} you only get the @code{Aborted +connection} error of you start @code{mysqld} with @code{--warnings}. + +If you find errors like the following in your error log. + +@example +010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' +@end example + +@xref{Error log}. + +This means that something of the following has happened: + +@itemize @bullet +@item +The client program did not call @code{mysql_close()} before exit. +@item +The client had been sleeping more than @code{wait_timeout} or +@code{interactive_timeout} without doing any requests. @xref{SHOW +VARIABLES}. +@item +The client program ended abruptly in the middle of the transfer. +@end itemize + +When the above happens, the server variable @code{Aborted_clients} is +incremented. + +The server variable @code{Aborted_connects} is incremented when: + +@itemize @bullet +@item +When a connection packet doesn't contain the right information. +@item +When the user didn't have privileges to connect to a database. +@item +When a user uses a wrong password. +@item +When it takes more than @code{connect_timeout} seconds to get +a connect package. +@end itemize + +Note that the above could indicate that someone is trying to break into +your database! + +@xref{SHOW VARIABLES}. + +Other reasons for problems with Aborted clients / Aborted connections. +@itemize @bullet +@item +Usage of duplex Ethernet protocol, both half and full with +Linux. Many Linux Ethernet drivers have this bug. You should test +for this bug by transferring a huge file via ftp between these two +machines. If a transfer goes in burst-pause-burst-pause ... mode then +you are experiencing a Linux duplex syndrome. The only solution to +this problem is switching of both half and full duplexing on hubs +and switches. +@item +Some problem with the thread library that causes interrupts on reads. +@item +Badly configured TCP/IP. +@item +Faulty Ethernets or hubs or switches, cables ... This can be diagnosed +properly only by replacing hardware. +@end itemize + + +@node Full table, Cannot create, Communication errors, Common errors +@appendixsubsec @code{The table is full} Error + +@cindex table is full + +This error occurs in older @strong{MySQL} versions when an in-memory temporary +table becomes larger than @code{tmp_table_size} bytes. To avoid this +problem, you can use the @code{-O tmp_table_size=#} option to +@code{mysqld} to increase the temporary table size or use the SQL +option @code{SQL_BIG_TABLES} before you issue the problematic +query. @xref{SET OPTION, , @code{SET OPTION}}. + +You can also start @code{mysqld} with the @code{--big-tables} option. +This is exactly the same as using @code{SQL_BIG_TABLES} for all queries. + +In @strong{MySQL} Version 3.23, in-memory temporary tables will automatically be +converted to a disk-based @code{MyISAM} table after the table size gets +bigger than @code{tmp_table_size}. + + +@node Cannot create, Commands out of sync, Full table, Common errors +@appendixsubsec @code{Can't create/write to file} Error + +@cindex can't create/write to file + +If you get an error for some queries of type: + +@example +Can't create/write to file '\\sqla3fe_0.ism'. +@end example + +this means that @strong{MySQL} can't create a temporary file for the +result set in the given temporary directory. (The above error is a +typical error message on Windows, and the Unix error message is similar.) +The fix is to start @code{mysqld} with @code{--tmpdir=path} or to add to your option +file: + +@example +[mysqld] +tmpdir=C:/temp +@end example + +assuming that the @file{c:\\temp} directory exists. @xref{Option files}. + +Check also the error code that you get with @code{perror}. One reason +may also be a disk full error; + +@example +shell> perror 28 +Error code 28: No space left on device +@end example + + +@node Commands out of sync, Ignoring user, Cannot create, Common errors +@appendixsubsec @code{Commands out of sync} Error in Client + +@cindex commands out of sync + +If you get @code{Commands out of sync; You can't run this command now} +in your client code, you are calling client functions in the wrong order! + +This can happen, for example, if you are using @code{mysql_use_result()} and +try to execute a new query before you have called @code{mysql_free_result()}. +It can also happen if you try to execute two queries that return data without +a @code{mysql_use_result()} or @code{mysql_store_result()} in between. + + +@node Ignoring user, Cannot find table, Commands out of sync, Common errors +@appendixsubsec @code{Ignoring user} Error + +If you get the following error: + +@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} + +this means that when @code{mysqld} was started or when it reloaded the +permissions tables, it found an entry in the @code{user} table with +an invalid password. As a result, the entry is simply ignored by the +permission system. + +Possible causes of and fixes for this problem: + +@itemize @bullet +@item +You may be running a new version of @code{mysqld} with an old +@code{user} table. +You can check this by executing @code{mysqlshow mysql user} to see if +the password field is shorter than 16 characters. If so, you can correct this +condition by running the @code{scripts/add_long_password} script. + +@item +The user has an old password (8 characters long) and you didn't start +@code{mysqld} with the @code{--old-protocol} option. +Update the user in the @code{user} table with a new password or +restart @code{mysqld} with @code{--old-protocol}. + +@item +@findex PASSWORD() +You have specified a password in the @code{user} table without using the +@code{PASSWORD()} function. Use @code{mysql} to update the user in the +@code{user} table with a new password. Make sure to use the @code{PASSWORD()} +function: + +@example +mysql> update user set password=PASSWORD('your password') + where user='XXX'; +@end example +@end itemize + + +@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors +@appendixsubsec @code{Table 'xxx' doesn't exist} Error + +If you get the error @code{Table 'xxx' doesn't exist} or @code{Can't +find file: 'xxx' (errno: 2)}, this means that no table exists +in the current database with the name @code{xxx}. + +Note that as @strong{MySQL} uses directories and files to store databases and +tables, the database and table names are @strong{case sensitive}! +(On Windows the databases and tables names are not case sensitive, but all +references to a given table within a query must use the same case!) + +You can check which tables you have in the current database with +@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. + + +@node Cannot initialize character set, , Cannot find table, Common errors +@appendixsubsec @code{Can@'t initialize character set xxx} error. + +@cindex multibyte character sets + +If you get an error like: + +@example +MySQL Connection Failed: Can't initialize character set xxx +@end example + +This means one of the following things: + +@itemize @bullet +@item +The character set is a multi-byte character set and you have not support +for the character set in the client. + +In this case you need to recompile the client with +@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. +@xref{configure options}. + +All standard @strong{MySQL} binaries are compiled with +@code{--with-extra-character-sets=complex} which will enable support for +all multi-byte character sets. @xref{Character sets}. + +@item +The character set is a simple character set which is not compiled into +@code{mysqld} and the character set definition files is not in the place +where the client expect to find them. + +In this case you need to: + +@itemize @bullet +@item +Recompile the client with support for the character set. +@xref{configure options}. +@item +Specify to the client where the character set definition files are. For many +client you can do this with the +@code{--character-sets-dir=path-to-charset-dir} option. +@item +Copy the character definition files to the path where the client expect them +to be. +@end itemize +@end itemize + + +@node Full disk, Temporary files, Common errors, Problems +@appendixsec How MySQL Handles a Full Disk + +@cindex full disk +@cindex disk full + +@noindent +When a disk-full condition occurs, @strong{MySQL} does the following: + +@itemize @bullet +@item +It checks once every minute to see whether or not there is enough space to +write the current row. If there is enough space, it continues as if nothing had +happened. +@item +Every 6 minutes it writes an entry to the log file warning about the disk +full condition. +@end itemize + +@noindent +To alleviate the problem, you can take the following actions: + +@itemize @bullet +@item +To continue, you only have to free enough disk space to insert all records. +@item +To abort the thread, you must send a @code{mysqladmin kill} to the thread. +The thread will be aborted the next time it checks the disk (in 1 minute). +@item +Note that other threads may be waiting for the table that caused the disk +full condition. If you have several ``locked'' threads, killing the one +thread that is waiting on the disk-full condition will allow the other +threads to continue. +@end itemize + +Exceptions to the above behaveour is when you use @code{REPAIR} or +@code{OPTIMIZE} or when the indexes are created in a batch after an +@code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. + +All of the above commands may use big temporary files that left to +themself would cause big problems for the rest of the system. If +@strong{MySQL} gets disk full while doing any of the above operations, +it will remove the big temporary files and mark the table as crashed +(except for @code{ALTER TABLE}, in which the old table will be left +unchanged). + + +@node Temporary files, Problems with mysql.sock, Full disk, Problems +@appendixsec Where MySQL Stores Temporary Files + +@strong{MySQL} uses the value of the @code{TMPDIR} environment variable as +the pathname of the directory in which to store temporary files. If you don't +have @code{TMPDIR} set, @strong{MySQL} uses the system default, which is +normally @file{/tmp} or @file{/usr/tmp}. If the file system containing your +temporary file directory is too small, you should edit @code{safe_mysqld} to +set @code{TMPDIR} to point to a directory in a file system where you have +enough space! You can also set the temporary directory using the +@code{--tmpdir} option to @code{mysqld}. + +@strong{MySQL} creates all temporary files as hidden files. This ensures +that the temporary files will be removed if @code{mysqld} is terminated. The +disadvantage of using hidden files is that you will not see a big temporary +file that fills up the file system in which the temporary file directory is +located. + +When sorting (@code{ORDER BY} or @code{GROUP BY}), @strong{MySQL} normally +uses one or two temporary files. The maximum disk-space needed is: + +@example +(length of what is sorted + sizeof(database pointer)) +* number of matched rows +* 2 +@end example + +@code{sizeof(database pointer)} is usually 4, but may grow in the future for +really big tables. + +For some @code{SELECT} queries, @strong{MySQL} also creates temporary SQL +tables. These are not hidden and have names of the form @file{SQL_*}. + +@code{ALTER TABLE} creates a temporary table in the same directory as +the original table. + + +@node Problems with mysql.sock, Changing MySQL user, Temporary files, Problems +@appendixsec How to Protect @file{/tmp/mysql.sock} from Being Deleted + +@cindex @code{mysql.sock}, protection +@cindex deletion, @code{mysql.sock} + +If you have problems with the fact that anyone can delete the +@strong{MySQL} communication socket @file{/tmp/mysql.sock}, you can, +on most versions of Unix, protect your @file{/tmp} file system by setting +the @code{sticky} bit on it. Log in as @code{root} and do the following: + +@example +shell> chmod +t /tmp +@end example + +This will protect your @file{/tmp} file system so that files can be deleted +only by their owners or the superuser (@code{root}). + +You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}. +If the last permission bit is @code{t}, the bit is set. + + +@node Changing MySQL user, Resetting permissions, Problems with mysql.sock, Problems +@appendixsec How to Run MySQL As a Normal User + +@cindex starting, @code{mysqld} +@cindex @code{mysqld}, starting + +The @strong{MySQL} server @code{mysqld} can be started and run by any user. +In order to change @code{mysqld} to run as a Unix user @code{user_name}, you must +do the following: + +@enumerate +@item +Stop the server if it's running (use @code{mysqladmin shutdown}). + +@item +Change the database directories and files so that @code{user_name} has +privileges to read and write files in them (you may need to do this as +the Unix @code{root} user): + +@example +shell> chown -R user_name /path/to/mysql/datadir +@end example + +If directories or files within the @strong{MySQL} data directory are +symlinks, you'll also need to follow those links and change the directories +and files they point to. @code{chown -R} may not follow symlinks for +you. + +@item +Start the server as user @code{user_name}, or, if you are using +@strong{MySQL} Version 3.22 or later, start @code{mysqld} as the Unix @code{root} +user and use the @code{--user=user_name} option. @code{mysqld} will switch +to run as the Unix user @code{user_name} before accepting any connections. + +@item +To start the server as the given user name automatically at system +startup time, add a @code{user} line that specifies the user name to +the @code{[mysqld]} group of the @file{/etc/my.cnf} option file or the +@file{my.cnf} option file in the server's data directory. For example: + +@example +[mysqld] +user=user_name +@end example +@end enumerate + +At this point, your @code{mysqld} process should be running fine and dandy as +the Unix user @code{user_name}. One thing hasn't changed, though: the +contents of the permissions tables. By default (right after running the +permissions table install script @code{mysql_install_db}), the @strong{MySQL} +user @code{root} is the only user with permission to access the @code{mysql} +database or to create or drop databases. Unless you have changed those +permissions, they still hold. This shouldn't stop you from accessing +@strong{MySQL} as the @strong{MySQL} @code{root} user when you're logged in +as a Unix user other than @code{root}; just specify the @code{-u root} option +to the client program. + +Note that accessing @strong{MySQL} as @code{root}, by supplying @code{-u +root} on the command line, has @emph{nothing} to do with @strong{MySQL} running +as the Unix @code{root} user, or, indeed, as another Unix user. The access +permissions and user names of @strong{MySQL} are completely separate from +Unix user names. The only connection with Unix user names is that if you +don't provide a @code{-u} option when you invoke a client program, the client +will try to connect using your Unix login name as your @strong{MySQL} user +name. + +If your Unix box itself isn't secured, you should probably at least put a +password on the @strong{MySQL} @code{root} users in the access tables. +Otherwise, any user with an account on that machine can run @code{mysql -u +root db_name} and do whatever he likes. + + +@node Resetting permissions, File permissions , Changing MySQL user, Problems +@appendixsec How to Reset a Forgotten Password + +@cindex passwords, forgotten +@cindex passwords, resetting +@cindex root user, password resetting + +If you have forgotten the @code{root} user password for @strong{MySQL}, you +can restore it with the following procedure: + +@enumerate +@item +Take down the @code{mysqld} server by sending a @code{kill} (not @code{kill +-9}) to the @code{mysqld} server. The pid is stored in a @code{.pid} +file, which is normally in the @strong{MySQL} database directory: + +@example +kill `cat /mysql-data-directory/hostname.pid` +@end example + +You must be either the Unix @code{root} user or the same user the server +runs as to do this. + +@item +Restart @code{mysqld} with the @code{--skip-grant-tables} option. +@item +Connect to the @code{mysqld} server with @code{mysql -h hostname mysql} and change +the password with a @code{GRANT} command. @xref{GRANT,,@code{GRANT}}. +You can also do this with +@code{mysqladmin -h hostname -u user password 'new password'} +@item +Load the privilege tables with: @code{mysqladmin -h hostname +flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}. +@end enumerate + +Note that after you started @code{mysqld} with @code{--skip-grant-tables}, +any usage of @code{GRANT} commands will give you an @code{Unknown command} +error until you have executed @code{FLUSH PRIVILEGES}. + + +@node File permissions , Not enough file handles, Resetting permissions, Problems +@appendixsec Problems with File Permissions + +@cindex files, permissions +@cindex error mesaages, can't find file +@cindex files, not found message + +If you have problems with file permissions, for example, if @code{mysql} +issues the following error message when you create a table: + +@example +ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) +@end example + +@tindex UMASK environment variable +@tindex Environment variable, UMASK +then the environment variable @code{UMASK} might be set incorrectly when +@code{mysqld} starts up. The default umask value is @code{0660}. You can +change this behavior by starting @code{safe_mysqld} as follows: + +@example +shell> UMASK=384 # = 600 in octal +shell> export UMASK +shell> /path/to/safe_mysqld & +@end example + +@tindex UMASK_DIR environment variable +@tindex Environment variable, UMASK_DIR +By default @strong{MySQL} will create database and @code{RAID} +directories with permission type 0700. You can modify this behavior by +setting the @code{UMASK_DIR} variable. If you set this, new +directories are created with the combined @code{UMASK} and +@code{UMASK_DIR}. For example, if you want to give group access to +all new directories, you can do: + +@example +shell> UMASK_DIR=504 # = 770 in octal +shell> export UMASK_DIR +shell> /path/to/safe_mysqld & +@end example + +In @strong{MySQL} Version 3.23.25 and above, @strong{MySQL} assumes that the +value for @code{UMASK} and @code{UMASK_DIR} is in octal if it starts +with a zero. + +@xref{Environment variables}. + + +@node Not enough file handles, Using DATE, File permissions , Problems +@appendixsec File Not Found + +If you get @code{ERROR '...' not found (errno: 23)}, @code{Can't open +file: ... (errno: 24)}, or any other error with @code{errno 23} or +@code{errno 24} from @strong{MySQL}, it means that you haven't allocated +enough file descriptors for @strong{MySQL}. You can use the +@code{perror} utility to get a description of what the error number +means: + +@example +shell> perror 23 +File table overflow +shell> perror 24 +Too many open files +shell> perror 11 +Resource temporarily unavailable +@end example + +The problem here is that @code{mysqld} is trying to keep open too many +files simultaneously. You can either tell @code{mysqld} not to open so +many files at once or increase the number of file descriptors +available to @code{mysqld}. + +To tell @code{mysqld} to keep open fewer files at a time, you can make +the table cache smaller by using the @code{-O table_cache=32} option to +@code{safe_mysqld} (the default value is 64). Reducing the value of +@code{max_connections} will also reduce the number of open files (the +default value is 90). + +@tindex ulimit +To change the number of file descriptors available to @code{mysqld}, you +can use the option @code{--open-files-limit=#} to @code{safe_mysqld} or +@code{-O open-files-limit=#} to @code{mysqld}. @xref{SHOW VARIABLES}. +The easiest way to do that is to add the option to your option file. +@xref{Option files}. If you have an old @code{mysqld} version that +doesn't support this, you can edit the @code{safe_mysqld} script. There +is a commented-out line @code{ulimit -n 256} in the script. You can +remove the @code{'#'} character to uncomment this line, and change the +number 256 to affect the number of file descriptors available to +@code{mysqld}. + +@code{ulimit} (and @code{open-files-limit}) can increase the number of +file descriptors, but only up to the limit imposed by the operating +system. There is also a 'hard' limit that can only be overrided if you +start @code{safe_mysqld} or @code{mysqld} as root (Just remember that +you need to also use the @code{--user=..} option in this case). If you +need to increase the OS limit on the number of file descriptors +available to each process, consult the documentation for your operating +system. + +Note that if you run the @code{tcsh} shell, @code{ulimit} will not work! +@code{tcsh} will also report incorrect values when you ask for the current +limits! In this case you should start @code{safe_mysqld} with @code{sh}! + + +@node Using DATE, Timezone problems, Not enough file handles, Problems +@appendixsec Problems Using @code{DATE} Columns + +@findex DATE + +@cindex DATE columns, problems +@cindex problems, @code{DATE} columns + +The format of a @code{DATE} value is @code{'YYYY-MM-DD'}. According to ANSI +SQL, no other format is allowed. You should use this format in @code{UPDATE} +expressions and in the WHERE clause of @code{SELECT} statements. For +example: + +@example +mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; +@end example + +As a convenience, @strong{MySQL} automatically converts a date to a number if +the date is used in a numeric context (and vice versa). It is also smart +enough to allow a ``relaxed'' string form when updating and in a @code{WHERE} +clause that compares a date to a @code{TIMESTAMP}, @code{DATE}, or a +@code{DATETIME} column. (Relaxed form means that any punctuation character +may be used as the separator between parts. For example, @code{'1998-08-15'} +and @code{'1998#08#15'} are equivalent.) @strong{MySQL} can also convert a +string containing no separators (such as @code{'19980815'}), provided it +makes sense as a date. + +The special date @code{'0000-00-00'} can be stored and retrieved as +@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through +@strong{MyODBC}, it will automatically be converted to @code{NULL} in +@strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of +date. + +Because @strong{MySQL} performs the conversions described above, the following +statements work: + +@example +mysql> INSERT INTO tbl_name (idate) VALUES (19970505); +mysql> INSERT INTO tbl_name (idate) VALUES ('19970505'); +mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00'); + +mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05'; +mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505; +mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505; +mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505'; +@end example + +@noindent +However, the following will not work: + +@example +mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; +@end example + +@code{STRCMP()} is a string function, so it converts @code{idate} to +a string and performs a string comparison. It does not convert +@code{'19970505'} to a date and perform a date comparison. + +Note that @strong{MySQL} does no checking whether or not the date is +correct. If you store an incorrect date, such as @code{'1998-2-31'}, the +wrong date will be stored. If the date cannot be converted to any reasonable +value, a @code{0} is stored in the @code{DATE} field. This is mainly a speed +issue and we think it is up to the application to check the dates, and not +the server. + + +@node Timezone problems, Case sensitivity, Using DATE, Problems +@appendixsec Time Zone Problems + +@cindex timezone problems +@cindex problems, timezone + +@tindex TZ environment variable +@tindex Environment variable, TZ + +If you have a problem with @code{SELECT NOW()} returning values in GMT and +not your local time, you have to set the @code{TZ} environment variable to +your current time zone. This should be done for the environment in which +the server runs, for example, in @code{safe_mysqld} or @code{mysql.server}. +@xref{Environment variables}. + + +@node Case sensitivity, Problems with NULL, Timezone problems, Problems +@appendixsec Case Sensitivity in Searches + +@cindex case sensitivity, in searches +@cindex searching, and case-sensitivity +@cindex Chinese +@cindex Big5 Chinese character encoding + +By default, @strong{MySQL} searches are case-insensitive (although there are +some character sets that are never case insensitive, such as @code{czech}). +That means that if you search with @code{col_name LIKE 'a%'}, you will get all +column values that start with @code{A} or @code{a}. If you want to make this +search case-sensitive, use something like @code{INDEX(col_name, "A")=0} to +check a prefix. Or use @code{STRCMP(col_name, "A") = 0} if the column value +must be exactly @code{"A"}. + +Simple comparison operations (@code{>=, >, = , < , <=}, sorting and +grouping) are based on each character's ``sort value''. Characters with +the same sort value (like E, e and é) are treated as the same character! + +In older @strong{MySQL} versions @code{LIKE} comparisons where done on +the uppercase value of each character (E == e but E <> é). In newer +@strong{MySQL} versions @code{LIKE} works just like the other comparison +operators. + +If you want a column always to be treated in case-sensitive fashion, +declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{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 Problems with NULL, Problems with alias, Case sensitivity, Problems +@appendixsec Problems with @code{NULL} Values + +@cindex @code{NULL} values, vs. empty values + +@tindex NULL + +The concept of the @code{NULL} value is a common source of confusion for +newcomers to SQL, who often think that @code{NULL} is the same thing as an +empty string @code{''}. This is not the case! For example, the following +statements are completely different: + +@example +mysql> INSERT INTO my_table (phone) VALUES (NULL); +mysql> INSERT INTO my_table (phone) VALUES (""); +@end example + +Both statements insert a value into the @code{phone} column, but the first +inserts a @code{NULL} value and the second inserts an empty string. The +meaning of the first can be regarded as ``phone number is not known'' and the +meaning of the second can be regarded as ``she has no phone''. + +In SQL, the @code{NULL} value is always false in comparison to any +other value, even @code{NULL}. An expression that contains @code{NULL} +always produces a @code{NULL} value unless otherwise indicated in +the documentation for the operators and functions involved in the +expression. All columns in the following example return @code{NULL}: + +@example +mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); +@end example + +If you want to search for column values that are @code{NULL}, you +cannot use the @code{=NULL} test. The following statement returns no +rows, because @code{expr = NULL} is FALSE, for any expression: + +@example +mysql> SELECT * FROM my_table WHERE phone = NULL; +@end example + +To look for @code{NULL} values, you must use the @code{IS NULL} test. +The following shows how to find the @code{NULL} phone number and the +empty phone number: + +@example +mysql> SELECT * FROM my_table WHERE phone IS NULL; +mysql> SELECT * FROM my_table WHERE phone = ""; +@end example + +In @strong{MySQL}, as in many other SQL servers, you can't index +columns that can have @code{NULL} values. You must declare such columns +@code{NOT NULL}. Conversely, you cannot insert @code{NULL} into an indexed +column. + +@findex LOAD DATA INFILE +When reading data with @code{LOAD DATA INFILE}, empty columns are updated +with @code{''}. If you want a @code{NULL} value in a column, you should use +@code{\N} in the text file. The literal word @code{'NULL'} may also be used +under some circumstances. +@xref{LOAD DATA, , @code{LOAD DATA}}. + +When using @code{ORDER BY}, @code{NULL} values are presented first. If you +sort in descending order using @code{DESC}, @code{NULL} values are presented +last. When using @code{GROUP BY}, all @code{NULL} values are regarded as +equal. + +To help with @code{NULL} handling, you can use the @code{IS NULL} and +@code{IS NOT NULL} operators and the @code{IFNULL()} function. + +@cindex @code{TIMESTAMP}, and @code{NULL} values +@cindex @code{AUTO_INCREMENT}, and @code{NULL} values +@cindex @code{NULL} values, and @code{TIMESTAMP} columns +@cindex @code{NULL} values, and @code{AUTO_INCREMENT} columns +For some column types, @code{NULL} values are handled specially. If you +insert @code{NULL} into the first @code{TIMESTAMP} column of a table, the +current date and time is inserted. If you insert @code{NULL} into an +@code{AUTO_INCREMENT} column, the next number in the sequence is inserted. + + +@node Problems with alias, Deleting from related tables, Problems with NULL, Problems +@appendixsec Problems with @code{alias} + +@tindex alias + +You can use an alias to refer to a column in the @code{GROUP BY}, +@code{ORDER BY}, or in the @code{HAVING} part. Aliases can also be used +to give columns better names: + +@example +SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; +SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; +SELECT id AS "Customer identity" FROM table_name; +@end example + +Note that ANSI SQL doesn't allow you to refer to an alias in a +@code{WHERE} clause. This is because when the @code{WHERE} code is +executed the column value may not yet be determined. For example, the +following query is @strong{illegal}: + +@example +SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; +@end example + +The @code{WHERE} statement is executed to determine which rows should +be included in the @code{GROUP BY} part while @code{HAVING} is used to +decide which rows from the result set should be used. + + +@node Deleting from related tables, No matching rows, Problems with alias, Problems +@appendixsec Deleting Rows from Related Tables + +@cindex deleting, rows +@cindex rows, deleting +@cindex tables, deleting rows + +As @strong{MySQL} doesn't support sub-selects or use of more than one table +in the @code{DELETE} statement, you should use the following approach to +delete rows from 2 related tables: + +@enumerate +@item +@code{SELECT} the rows based on some @code{WHERE} condition in the main table. +@item +@code{DELETE} the rows in the main table based on the same condition. +@item +@code{DELETE FROM related_table WHERE related_column IN (selected_rows)}. +@end enumerate + +If the total number of characters in the query with +@code{related_column} is more than 1,048,576 (the default value of +@code{max_allowed_packet}, you should split it into smaller parts and +execute multiple @code{DELETE} statements. You will probably get the +fastest @code{DELETE} by only deleting 100-1000 @code{related_column} +id's per query if the @code{related_column} is an index. If the +@code{related_column} isn't an index, the speed is independent of the +number of arguments in the @code{IN} clause. + +@node No matching rows, ALTER TABLE problems, Deleting from related tables, Problems +@appendixsec Solving Problems with No Matching Rows + +@cindex no matching rows +@cindex rows, matching problems + +If you have a complicated query that has many tables and that doesn't +return any rows, you should use the following procedure to find out what +is wrong with your query: + +@enumerate +@item +Test the query with @code{EXPLAIN} and check if you can find something that is +obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. + +@item +Select only those fields that are used in the @code{WHERE} clause. + +@item +Remove one table at a time from the query until it returns some rows. +If the tables are big, it's a good idea to use @code{LIMIT 10} with the query. + +@item +Do a @code{SELECT} for the column that should have matched a row against +the table that was last removed from the query. + +@item +If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that +have decimals, you can't use @code{=}! This problem is common in most +computer languages because floating-point values are not exact values: + +@example +mysql> SELECT * FROM table_name WHERE float_column=3.5; + -> +mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55; +@end example + +In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! + +@item +If you still can't figure out what's wrong, create a minimal test that can +be run with @code{mysql test < query.sql} that shows your problems. +You can create a test file with @code{mysqldump --quick database tables > query.sql}. Open the file in an editor, remove some insert lines (if there are +too many of these), and add your select statement at the end of the file. + +Test that you still have your problem by doing: + +@example +shell> mysqladmin create test2 +shell> mysql test2 < query.sql +@end example + +Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. +@end enumerate + + +@node ALTER TABLE problems, Change column order, No matching rows, Problems +@appendixsec Problems with @code{ALTER TABLE}. + +@tindex ALTER TABLE + +@code{ALTER TABLE} changes a table to the current character set. +If you during @code{ALTER TABLE} get a duplicate key error, then the cause +is either that the new character sets maps to keys to the same value +or that the table is corrupted, in which case you should run +@code{REPAIR TABLE} on the table. + +If @code{ALTER TABLE} dies with an error like this: + +@example +Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) +@end example + +the problem may be that @strong{MySQL} has crashed in a previous @code{ALTER +TABLE} and there is an old table named @file{A-something} or +@file{B-something} lying around. In this case, go to the @strong{MySQL} data +directory and delete all files that have names starting with @code{A-} or +@code{B-}. (You may want to move them elsewhere instead of deleting them.) + +@code{ALTER TABLE} works the following way: + +@itemize @bullet +@item Create a new table named @file{A-xxx} with the requested changes. +@item All rows from the old table are copied to @file{A-xxx}. +@item The old table is renamed @file{B-xxx}. +@item @file{A-xxx} is renamed to your old table name. +@item @file{B-xxx} is deleted. +@end itemize + +If something goes wrong with the renaming operation, @strong{MySQL} tries to +undo the changes. If something goes seriously wrong (this shouldn't happen, +of course), @strong{MySQL} may leave the old table as @file{B-xxx}, but a +simple rename on the system level should get your data back. + + +@node Change column order, Temporary table problems, ALTER TABLE problems, Problems +@appendixsec How To Change the Order of Columns in a Table + +@cindex reordering, columns +@cindex columns, changing +@cindex changing, column order +@cindex tables, changing column order + +The whole point of SQL is to abstract the application from the data +storage format. You should always specify the order in which you wish to +retrieve your data. For example: + +@example +SELECT col_name1, col_name2, col_name3 FROM tbl_name; +@end example + +will return columns in the order @code{col_name1}, @code{col_name2}, @code{col_name3}, whereas: + +@example +SELECT col_name1, col_name3, col_name2 FROM tbl_name; +@end example + +will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. + +You should @strong{NEVER}, in an application, use @code{SELECT *} and +retrieve the columns based on their position, because the order in which +columns are returned @strong{CANNOT} be guaranteed over time. A simple +change to your database may cause your application to fail rather +dramatically. + +If you want to change the order of columns anyway, you can do it as follows: + +@enumerate +@item +Create a new table with the columns in the right order. +@item +Execute +@code{INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table}. +@item +Drop or rename @code{old_table}. +@item +@code{ALTER TABLE new_table RENAME old_table}. +@end enumerate + + +@node Temporary table problems, , Change column order, Problems +@appendixsec TEMPORARY TABLE problems + +@cindex temporary tables, problems + +The following are a list of the limitations with @code{TEMPORARY TABLES}. + +@itemize @bullet +@item +A temporary table can only be of type @code{HEAP}, @code{ISAM} or +@code{MyISAM}. +@item +You can't use temporary tables more than once in the same query. +For example, the following doesn't work. + +@example +select * from temporary_table, temporary_table as t2; +@end example + +We plan to fix the above in 4.0. +@item +You can't use @code{RENAME} on a @code{TEMPORARY} table. +Note that @code{ALTER TABLE org_name RENAME new_name} works! + +We plan to fix the above in 4.0. +@end itemize + + + + + @page @cindex environment variables, list of -@node Environment variables, Users, MySQL internals, Top +@node Environment variables, Users, Problems, Top @appendix Environment Variables Here is a list of all the environment variables that are used directly or @@ -45672,7 +46141,7 @@ users use this code as the rest of the code and because of this we are not yet 100% confident in this code. @menu -* News-3.23.41:: +* News-3.23.41:: Changes in release 3.23.41 * News-3.23.40:: Changes in release 3.23.40 * News-3.23.39:: Changes in release 3.23.39 * News-3.23.38:: Changes in release 3.23.38 @@ -45720,9 +46189,14 @@ not yet 100% confident in this code. @node News-3.23.41, News-3.23.40, News-3.23.x, News-3.23.x @appendixsubsec Changes in release 3.23.41 @itemize @bullet +@item Added option @code{--sql-mode=option[,option[,option]]}. Please see +@code{mysqld --help} for legal modes. @item Fixed optimizing bug in @code{ORDER BY} where some @code{ORDER BY} parts where wrongly removed. +@item +Fixed bug in @code{SELECT DISTINCT ... HAVING} that casued error message +@code{Can't find record in '#...} @end itemize @node News-3.23.40, News-3.23.39, News-3.23.41, News-3.23.x @@ -50905,8 +51379,8 @@ information even if you haven't compiled @strong{MySQL} for debugging! If the problem is that some tables are getting slower and slower you should try to optimize the table with @code{OPTIMIZE TABLE} or -@code{myisamchk}. @xref{Maintenance}. You should also check the slow -queries with @code{EXPLAIN}. +@code{myisamchk}. @xref{MySQL Database Administration}. You should also +check the slow queries with @code{EXPLAIN}. You should also read the OS-specific section in this manual for problems that may be unique to your environment. @@ -51163,7 +51637,8 @@ repeat the problem! @xref{Bug reports}. @appendixsubsec Using log files to find cause of errors in mysqld Note that before starting @code{mysqld} with @code{--log} you should -check all your tables with @code{myisamchk}. @xref{Maintenance}. +check all your tables with @code{myisamchk}. +@xref{MySQL Database Administration}. If @code{mysqld} dies or hangs, you should start @code{mysqld} with @code{--log}. When @code{mysqld} dies again, you can examine the end of @@ -51186,11 +51661,11 @@ You can find the queries that take a long time to execute by starting If you find the text @code{mysqld restarted} in the error log file (normally named @file{hostname.err}) you have probably found a query that causes @code{mysqld} to fail. If this happens you should check all -your tables with @code{myisamchk} (@pxref{Maintenance}), and test the -queries in the @strong{MySQL} log files to see if one doesn't work. If -you find such a query, try first upgrading to the newest @strong{MySQL} -version. If this doesn't help and you can't find anything in the -@code{mysql} mail archive, you should report the bug to +your tables with @code{myisamchk} (@pxref{MySQL Database Administration}), +and test the queries in the @strong{MySQL} log files to see if one doesn't +work. If you find such a query, try first upgrading to the newest +@strong{MySQL} version. If this doesn't help and you can't find anything +in the @code{mysql} mail archive, you should report the bug to @email{mysql@@lists.mysql.com}. Links to mail archives are available online at the @uref{http://www.mysql.com/documentation/, @strong{MySQL} documentation page}. @@ -52842,11 +53317,11 @@ That's all there is to it! @menu * Installing binary:: -* Building clients:: * Perl support:: +* Group by functions:: @end menu -@node Installing binary, Building clients, Placeholder, Placeholder +@node Installing binary, Perl support, Placeholder, Placeholder @appendixsec Installing a MySQL Binary Distribution @cindex installing, binary distribution @@ -53063,31 +53538,12 @@ shell> bin/safe_mysqld --user=mysql & @xref{Post-installation}. -@node Building clients, Perl support, Installing binary, Placeholder -@appendixsec Building Client Programs - -@cindex client programs, building -@cindex linking -@cindex building, client programs -@cindex programs, client - -If you compile @strong{MySQL} clients that you've written yourself or that -you obtain from a third party, they must be linked using the -@code{-lmysqlclient -lz} option on the link command. You may also need to -specify a @code{-L} option to tell the linker where to find the library. For -example, if the library is installed in @file{/usr/local/mysql/lib}, use -@code{-L/usr/local/mysql/lib -lmysqlclient -lz} on the link command. - -For clients that use @strong{MySQL} header files, you may need to specify a -@code{-I} option when you compile them (for example, -@code{-I/usr/local/mysql/include}), so the compiler can find the header -files. -@node Perl support, , Building clients, Placeholder +@node Perl support, Group by functions, Installing binary, Placeholder @appendixsec Perl Installation Comments @cindex Perl, installing @@ -53376,6 +53832,166 @@ Finally, you should install this new Perl. Again, the output of @code{make perl} indicates the command to use. +@node Group by functions, , Perl support, Placeholder +@appendixsec Functions for Use with @code{GROUP BY} Clauses + +@findex GROUP BY functions +@findex functions, GROUP BY + +If you use a group function in a statement containing no @code{GROUP BY} +clause, it is equivalent to grouping on all rows. + +@table @code +@findex COUNT() +@item COUNT(expr) +Returns a count of the number of non-@code{NULL} values in the rows +retrieved by a @code{SELECT} statement: + +@example +mysql> select student.student_name,COUNT(*) + from student,course + where student.student_id=course.student_id + GROUP BY student_name; + +@end example + +@code{COUNT(*)} is somewhat different in that it returns a count of +the number of rows retrieved, whether or not they contain @code{NULL} +values. + +@code{COUNT(*)} is optimized to +return very quickly if the @code{SELECT} retrieves from one table, no +other columns are retrieved, and there is no @code{WHERE} clause. +For example: + +@example +mysql> select COUNT(*) from student; +@end example + +@findex COUNT(DISTINCT) +@findex DISTINCT +@item COUNT(DISTINCT expr,[expr...]) +Returns a count of the number of different non-@code{NULL} values: + +@example +mysql> select COUNT(DISTINCT results) from student; +@end example + +In @strong{MySQL} you can get the number of distinct expression +combinations that don't contain NULL by giving a list of expressions. +In ANSI SQL you would have to do a concatenation of all expressions +inside @code{CODE(DISTINCT ..)}. + +@findex AVG() +@item AVG(expr) +Returns the average value of @code{expr}: + +@example +mysql> select student_name, AVG(test_score) + from student + GROUP BY student_name; +@end example + +@findex MIN() +@findex MAX() +@item MIN(expr) +@itemx MAX(expr) +Returns the minimum or maximum value of @code{expr}. @code{MIN()} and +@code{MAX()} may take a string argument; in such cases they return the +minimum or maximum string value. @xref{MySQL indexes}. + +@example +mysql> select student_name, MIN(test_score), MAX(test_score) + from student + GROUP BY student_name; +@end example + +@findex SUM() +@item SUM(expr) +Returns the sum of @code{expr}. Note that if the return set has no rows, +it returns NULL! + +@findex STD() +@findex STDDEV() +@cindex Oracle compatibility +@cindex compatibility, with Oracle +@item STD(expr) +@itemx STDDEV(expr) +Returns the standard deviation of @code{expr}. This is an extension to +ANSI SQL. The @code{STDDEV()} form of this function is provided for Oracle +compatibility. + +@findex BIT_OR() +@item BIT_OR(expr) +Returns the bitwise @code{OR} of all bits in @code{expr}. The calculation is +performed with 64-bit (@code{BIGINT}) precision. + +@findex BIT_AND() +@item BIT_AND(expr) +Returns the bitwise @code{AND} of all bits in @code{expr}. The calculation is +performed with 64-bit (@code{BIGINT}) precision. +@end table + +@cindex @code{GROUP BY}, extensions to ANSI SQL +@strong{MySQL} has extended the use of @code{GROUP BY}. You can use columns or +calculations in the @code{SELECT} expressions that don't appear in +the @code{GROUP BY} part. This stands for @emph{any possible value for this +group}. You can use this to get better performance by avoiding sorting and +grouping on unnecessary items. For example, you don't need to group on +@code{customer.name} in the following query: + +@example +mysql> 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 @code{customer.name} to the @code{GROUP +BY} clause. In @strong{MySQL}, the name is redundant if you don't run in +ANSI mode. + +@strong{Don't use this feature} if the columns you omit from the +@code{GROUP BY} part aren't unique in the group! You will get +unpredictable results. + +In some cases, you can use @code{MIN()} and @code{MAX()} to obtain a specific +column value even if it isn't unique. The following gives the value of +@code{column} from the row containing the smallest value in the @code{sort} +column: + +@example +substr(MIN(concat(rpad(sort,6,' '),column)),7) +@end example + +@xref{example-Maximum-column-group-row}. + +@cindex @code{ORDER BY}, aliases in +@cindex aliases, in @code{ORDER BY} clauses +@cindex @code{GROUP BY}, aliases in +@cindex aliases, in @code{GROUP BY} clauses +@cindex expression aliases +@cindex aliases, for expressions +Note that if you are using @strong{MySQL} Version 3.22 (or earlier) or if +you are trying to follow ANSI SQL, you can't use expressions in @code{GROUP +BY} or @code{ORDER BY} clauses. You can work around this limitation by +using an alias for the expression: + +@example +mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name + GROUP BY id,val ORDER BY val; +@end example + +In @strong{MySQL} Version 3.23 you can do: + +@example +mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND(); +@end example + + + + + @node Function Index, Concept Index, Placeholder, Top @unnumbered SQL command, type and function index diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e8ff88c6f4f..47a67d425cd 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -2351,6 +2351,7 @@ btr_estimate_n_rows_in_range( btr_path_t* slot1; btr_path_t* slot2; ibool diverged; + ulint divergence_level; ulint n_rows; ulint i; mtr_t mtr; @@ -2393,6 +2394,7 @@ btr_estimate_n_rows_in_range( n_rows = 1; diverged = FALSE; + divergence_level = 1000000; for (i = 0; ; i++) { ut_ad(i < BTR_PATH_ARRAY_N_SLOTS); @@ -2403,6 +2405,13 @@ btr_estimate_n_rows_in_range( if (slot1->nth_rec == ULINT_UNDEFINED || slot2->nth_rec == ULINT_UNDEFINED) { + if (i > divergence_level + 1) { + /* In trees whose height is > 1 our algorithm + tends to underestimate: multiply the estimate + by 2: */ + + n_rows = n_rows * 2; + } return(n_rows); } @@ -2417,6 +2426,8 @@ btr_estimate_n_rows_in_range( return(10); } + divergence_level = i; + diverged = TRUE; } else if (diverged) { n_rows = (n_rows * (slot1->n_recs + slot2->n_recs)) diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 0f27cee45a5..82b12103c4c 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -21,6 +21,7 @@ Created 11/11/1995 Heikki Tuuri #include "ibuf0ibuf.h" #include "log0log.h" #include "os0file.h" +#include "trx0sys.h" /* When flushed, dirty blocks are searched in neigborhoods of this size, and flushed along with the original page. */ diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 3db20fb13ee..fd7b415551f 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -1698,8 +1698,7 @@ loop: btr_pcur_open_at_rnd_pos(data->index, BTR_SEARCH_LEAF, &pcur, &mtr); - if (data->size == 1 - && 0 == page_get_n_recs(btr_pcur_get_page(&pcur))) { + if (0 == page_get_n_recs(btr_pcur_get_page(&pcur))) { /* This tree is empty */ diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index d339474df61..67a5925a3f5 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -789,8 +789,8 @@ row_upd_store_row( node->row = row_build(ROW_COPY_DATA, clust_index, rec, node->heap); - node->ext_vec = mem_heap_alloc(node->heap, rec_get_n_fields(rec)); - + node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint) + * rec_get_n_fields(rec)); if (node->is_delete) { update = NULL; } else { diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index 032b3ffcf3b..afb83926fa3 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -678,6 +678,8 @@ trx_purge_choose_next_log(void) rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); + min_trx_no = ut_dulint_max; + min_rseg = NULL; while (rseg) { diff --git a/ltmain.sh b/ltmain.sh index eba25223e45..cebed74c167 100644 --- a/ltmain.sh +++ b/ltmain.sh @@ -1798,6 +1798,9 @@ compiler." *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; + *-*-freebsd*) + #FreeBSD needs to handle -lc and -lc_r itself + ;; *-*-rhapsody*) # rhapsody is a little odd... deplibs="$deplibs -framework System" diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 8ea700de789..7bd71363915 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -822,11 +822,11 @@ ha_innobase::open( if (NULL == (ib_table = dict_table_get(norm_name, NULL))) { - fprintf(stderr, "\ -Cannot find table %s from the internal data dictionary\n\ -of InnoDB though the .frm file for the table exists. Maybe you have deleted\n\ -and created again an InnoDB database but forgotten to delete the\n\ -corresponding .frm files of old InnoDB tables?\n", + fprintf(stderr, +"Cannot find table %s from the internal data dictionary\n" +"of InnoDB though the .frm file for the table exists. Maybe you have deleted\n" +"and created again an InnoDB database but forgotten to delete the\n" +"corresponding .frm files of old InnoDB tables?\n", norm_name); free_share(share); @@ -2659,6 +2659,37 @@ ha_innobase::records_in_range( DBUG_RETURN((ha_rows) n_rows); } +/************************************************************************* +Gives an UPPER BOUND to the number of rows in a table. This is used in +filesort.cc and the upper bound must hold. TODO: Since the number of +rows in a table may change after this function is called, we still may +get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to +improve the algorithm of filesort.cc. */ + +ha_rows +ha_innobase::estimate_number_of_rows(void) +/*======================================*/ + /* out: upper bound of rows, currently 32-bit int + or uint */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + dict_table_t* ib_table; + + DBUG_ENTER("info"); + + ib_table = prebuilt->table; + + dict_update_statistics(ib_table); + + data_file_length = ((ulonglong) + ib_table->stat_clustered_index_size) + * UNIV_PAGE_SIZE; + + /* The minimum clustered index record size is 20 bytes */ + + return((ha_rows) (1000 + data_file_length / 20)); +} + /************************************************************************* How many seeks it will take to read through the table. This is to be comparable to the number returned by records_in_range so that we can diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index 4dbff654337..d129e00ba6e 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -137,6 +137,7 @@ class ha_innobase: public handler enum ha_rkey_function start_search_flag, const byte *end_key,uint end_key_len, enum ha_rkey_function end_search_flag); + ha_rows estimate_number_of_rows(); int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 6409ec5d019..8be62920308 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -35,7 +35,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = -{ "DEFAULT", "BACKUP", "FORCE", "QUICK"}; +{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", myisam_recover_names}; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f21c635dbdf..f8c0efd6eb2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -156,8 +156,7 @@ void kill_one_thread(THD *thd, ulong id); #define OPTION_LOW_PRIORITY_UPDATES 8192 #define OPTION_WARNINGS 16384 #define OPTION_AUTO_IS_NULL 32768 -#define OPTION_ANSI_MODE 65536L -#define OPTION_SAFE_UPDATES OPTION_ANSI_MODE*2 +#define OPTION_SAFE_UPDATES 65536L*2 #define OPTION_BUFFER_RESULT OPTION_SAFE_UPDATES*2 #define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2 #define OPTION_NOT_AUTO_COMMIT OPTION_BIN_LOG*2 @@ -173,6 +172,14 @@ void kill_one_thread(THD *thd, ulong id); #define QUERY_NO_INDEX_USED OPTION_STATUS_NO_TRANS_UPDATE*2 #define QUERY_NO_GOOD_INDEX_USED QUERY_NO_INDEX_USED*2 +/* Bits for different SQL modes modes (including ANSI mode) */ +#define MODE_REAL_AS_FLOAT 1 +#define MODE_PIPES_AS_CONCAT 2 +#define MODE_ANSI_QUOTES 4 +#define MODE_IGNORE_SPACE 8 +#define MODE_SERIALIZABLE 16 +#define MODE_ONLY_FULL_GROUP_BY 32 + #define RAID_BLOCK_SIZE 1024 /* BINLOG_DUMP options */ @@ -530,7 +537,7 @@ extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, what_to_log,flush_time, max_tmp_tables,max_heap_table_size,query_buff_size, lower_case_table_names,thread_stack,thread_stack_min, - binlog_cache_size, max_binlog_cache_size; + binlog_cache_size, max_binlog_cache_size, opt_sql_mode; extern ulong specialflag, current_pid; extern bool low_priority_updates, using_update_log; extern bool opt_sql_bin_update, opt_safe_show_db, opt_warnings; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a9771184b4b..36ee127580c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -211,7 +211,7 @@ static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; static pthread_t select_thread; static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, - opt_ansi_mode=0,opt_myisam_log=0, + opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0; FILE *bootstrap_file=0; @@ -307,6 +307,7 @@ char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; const char *first_keyword="first"; const char **errmesg; /* Error messages */ const char *myisam_recover_options_str="OFF"; +const char *sql_mode_str="OFF"; const char *default_tx_isolation_name; enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; @@ -320,6 +321,12 @@ double log_10[32]; /* 10 potences */ I_List threads,thread_cache; time_t start_time; +ulong opt_sql_mode = 0L; +const char *sql_mode_names[] = +{ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", + "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; +TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", + sql_mode_names}; MY_BITMAP temp_pool; bool use_temp_pool=0; @@ -2471,7 +2478,8 @@ enum options { OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, - OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL + OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, + OPT_SQL_MODE }; static struct option long_options[] = { @@ -2604,6 +2612,7 @@ static struct option long_options[] = { {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS}, {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, + {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE}, #include "sslopt-longopts.h" #ifdef __WIN__ {"standalone", no_argument, 0, (int) OPT_STANDALONE}, @@ -2764,7 +2773,6 @@ CHANGEABLE_VAR changeable_vars[] = { struct show_var_st init_vars[]= { - {"ansi_mode", (char*) &opt_ansi_mode, SHOW_BOOL}, {"back_log", (char*) &back_log, SHOW_LONG}, {"basedir", mysql_home, SHOW_CHAR}, #ifdef HAVE_BERKELEY_DB @@ -2866,6 +2874,7 @@ struct show_var_st init_vars[]= { {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG}, {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG}, + {"sql_mode", (char*) &sql_mode_str, SHOW_CHAR_PTR}, {"table_cache", (char*) &table_cache_size, SHOW_LONG}, {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR}, {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG}, @@ -3049,6 +3058,9 @@ static void usage(void) Don't give threads different priorities.\n\ --socket=... Socket file to use for connection\n\ -t, --tmpdir=path Path for temporary files\n\ + --sql-mode=option[,option[,option...]] where option can be one of:\n\ + REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\ + IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY.\n\ --transaction-isolation\n\ Default transaction isolation level\n\ --temp-pool Use a pool of temporary files\n\ @@ -3202,8 +3214,9 @@ static void get_options(int argc,char **argv) opt_warnings=1; break; case 'a': - opt_ansi_mode=1; - thd_startup_options|=OPTION_ANSI_MODE; + opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | + MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE + | MODE_ONLY_FULL_GROUP_BY); default_tx_isolation= ISO_SERIALIZABLE; break; case 'b': @@ -3726,6 +3739,19 @@ static void get_options(int argc,char **argv) ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; break; } + case OPT_SQL_MODE: + { + sql_mode_str = optarg; + if ((opt_sql_mode = + find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0) + { + fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg); + exit(1); + } + if (opt_sql_mode & MODE_SERIALIZABLE) + default_tx_isolation= ISO_SERIALIZABLE; + break; + } case OPT_MASTER_HOST: master_host=optarg; break; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9ea3896fd78..efe0d7864b9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -120,6 +120,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), server_status=SERVER_STATUS_AUTOCOMMIT; update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; options=thd_startup_options; + sql_mode=(uint) opt_sql_mode; inactive_timeout=net_wait_timeout; open_options=ha_open_options; tx_isolation=session_tx_isolation=default_tx_isolation; diff --git a/sql/sql_class.h b/sql/sql_class.h index a092de2602d..4ccbeb6f01f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -232,7 +232,7 @@ public: char *query,*thread_stack; char *host,*user,*priv_user,*db,*ip; const char *proc_info; - uint client_capabilities,max_packet_length; + uint client_capabilities,sql_mode,max_packet_length; uint master_access,db_access; TABLE *open_tables,*temporary_tables; MYSQL_LOCK *lock,*locked_tables; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a78fef62657..20bda932f2f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -121,7 +121,7 @@ void lex_init(void) state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT; state_map[(uchar)'@']= (uchar) STATE_USER_END; state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER; - if (thd_startup_options & OPTION_ANSI_MODE) + if (opt_sql_mode & MODE_ANSI_QUOTES) { state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER; } @@ -149,7 +149,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->ftfunc_list.empty(); lex->convert_set=(lex->thd=thd)->convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; - lex->ignore_space=test(thd->client_capabilities & CLIENT_IGNORE_SPACE); + lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); return lex; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 87fbed47ef1..1c8c917babe 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -412,6 +412,8 @@ check_connections(THD *thd) return(ER_OUT_OF_RESOURCES); thd->client_capabilities=uint2korr(net->read_pos); + if (thd->client_capabilities & CLIENT_IGNORE_SPACE) + thd->sql_mode|= MODE_IGNORE_SPACE; #ifdef HAVE_OPENSSL DBUG_PRINT("info", ("pkt_len:%d, client capabilities: %d", @@ -538,8 +540,6 @@ pthread_handler_decl(handle_one_connection,arg) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) net->compress=1; // Use compression - if (thd->options & OPTION_ANSI_MODE) - thd->client_capabilities|=CLIENT_IGNORE_SPACE; thd->proc_info=0; // Remove 'login' thd->command=COM_SLEEP; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d23a7edd37e..5c3e7516eaf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5425,6 +5425,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, { if ((error=file->delete_row(record))) goto err; + error=file->rnd_next(record); continue; } if (copy_blobs(first_field)) @@ -5936,7 +5937,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List &fields, if (!order) return 0; /* Everything is ok */ - if (thd->options & OPTION_ANSI_MODE) + if (thd->sql_mode & MODE_ONLY_FULL_GROUP_BY) { Item *item; List_iterator li(fields); @@ -5958,7 +5959,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List &fields, return 1; } } - if (thd->options & OPTION_ANSI_MODE) + if (thd->sql_mode & MODE_ONLY_FULL_GROUP_BY) { /* Don't allow one to use fields that is not used in GROUP BY */ Item *item; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c1069d91746..9ab97d52650 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -34,7 +34,7 @@ int yylex(void *yylval); inline Item *or_or_concat(Item* A, Item* B) { - return (current_thd->options & OPTION_ANSI_MODE ? + return (current_thd->sql_mode & MODE_PIPES_AS_CONCAT ? (Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B)); } @@ -915,7 +915,7 @@ int_type: | BIGINT { $$=FIELD_TYPE_LONGLONG; } real_type: - REAL { $$= current_thd->options & OPTION_ANSI_MODE ? + REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }